Recent Entries 10
- pattern minor 112d agoThe dumbest (futex-based) mutexAfter reading Ulrich Drepper's "Futexes are Tricky", I have written the following "dumbest mutex" in C++14 using the Linux `futex` primitives. This mutex is simpler than Drepper's; I believe it to be correct. The reason it gets to be so simple is the same as the reason I'm calling it the "dumbest mutex": it makes a system call on every `unlock`, even if the mutex is not being contended and nobody's waiting for the lock. Therefore this is not a good mutex if you care about performance. My question is: Leaving aside the performance issue, is this a correct mutex? Or does it, like most hand-written concurrency code, have some subtle bug? Stylistic comments are also welcome. ``` #include #include #include #include inline int futex_wait(void *addr, int block_if_value_is) { return syscall(SYS_futex, addr, block_if_value_is, nullptr, nullptr, 0); } inline int futex_wake_one(void *addr) { return syscall(SYS_futex, addr, FUTEX_WAKE, 1, nullptr, nullptr, 0); } class mutex { std::atomic m_state; static constexpr int UNLOCKED = 0; static constexpr int LOCKED = 1; public: constexpr mutex() noexcept : m_state(UNLOCKED) {} bool try_lock() { return m_state.exchange(LOCKED) == UNLOCKED; } void lock() { while (m_state.exchange(LOCKED) != UNLOCKED) { futex_wait(&m_state, LOCKED); } } void unlock() { m_state = UNLOCKED; futex_wake_one(&m_state); } }; ```
- pattern minor 112d agoBash script which downloads the latest linux stable kernelI made this script when I started downloading the latest stable linux kernel's source from https://www.kernel.org to compile it myself, now I have improved it a bit and decided to create a public repo for it on github (https://github.com/Tom1380/latestkernel). This is the code (mind you this is the first time I made bash scripts): lk (stands for latest kernel): ``` #!/usr/bin/env bash cd ~ if [ ! -d "linux-stable" ]; then mkdir linux-stable fi if [ ! -f "/etc/latest_kernel" ]; then if [[ $EUID > 0 ]] ; then echo "/etc/latest_kernel does not exist and you are not running the script as root, " \ "please fix that either by manually running 'sudo create_etc_lk', " \ "or rerun the script as root to automatically fix it." exit else touch /etc/latest_kernel echo "$(uname -r)" > /etc/latest_kernel fi fi wget=$(wget --output-document - --quiet https://www.kernel.org/ | grep -A 1 "latest_link") wget=${wget##*.tar.xz\">} wget=${wget%} latest_acknowledged=$( 0 ]] ; then echo "If you wish to download the latest kernel, rerun the script as root." exit fi # Since there is only a '>', /etc/latest_kernel will be overwritten entirely. echo "$wget" > /etc/latest_kernel echo "Writing latest kernel available in /etc/latest_kernel." echo "Preparing to parse link to latest kernel for wget." wget=$(wget --output-document - --quiet https://www.kernel.org/ | grep -A 1 "latest_link") wget=${wget##**} echo "Done parsing." cd ~/linux-stable echo "Changed cwd to ~/linux-stable to download kernel source." echo "Downloading, this may take up to 10 minutes." wget $wget echo "Finished downloading..." echo "Uncompressing the kernel's source." tar xvfJ linux-$(</etc/latest_kernel).tar.xz echo "Done uncompressing the kernel's source." rm linux-$(</etc/latest_kernel).tar.xz echo "Done removing the old archive, end of the script." ``` create_etc_lk: ``` #!/usr/bin/env bash if [[ $EUID > 0 ]]
- snippet minor 112d agoConvert size_t to big endian on LinuxI see that on Linux there are various built-in functions to convert endianness for specific integer width types, and they are probably faster than anything one can write and compile on their own. But I want to write a `size_t` (under Linux in C), which does not have a specified width, to big-endian array of bytes, as fast as possible. Is this the fastest way? ``` #include // write "from" to array of bytes "to" in big-endian fashion void big_endian_size(unsigned char to[], size_t from) { unsigned char *p = to + (sizeof(size_t) - 1); while (1) { *p = from; if (to == p) break; p--; from >>= CHAR_BIT; } } ```
- pattern minor 112d agoQuery database and check server detailsI have written bash script to query database and check server details. Please let me know if the script is as per best standards: ``` if [ -z "$1" -o -z "$2" ] then echo "FAIL : Put username and password" else fulltoken=`curl -s --insecure -H "Content-Type: application/json" -X POST -d "{\"username\":\"$1\",\"password\":\"$2\"}" https://apiurl` echo $fulltoken | grep -q authToken > /dev/null 2>&1 if [ $? -eq 0 ] then token=`echo $fulltoken | awk -F':' '{print $8}' | awk -F',' '{print $1}' | sed 's/"//g'` hostname=`uname -n | awk -F'.' '{print $1}'` serverdetails=`curl -s --insecure -H "Content-Type: application/json" -H "Authorization: $token" -X GET https://apiurl` echo $serverdetails | grep -iq "applnId" if [ $? -eq 0 ] then exactserverdetails=`echo $serverdetails` appInId=`echo $exactserverdetails | sed 's/,/\n/g' | grep "applnId" | awk -F':' '{print $2}'` if [ -n $appInId ] && [ $appInId != "null" ] then echo "PASS" else echo "FAIL" fi echo $exactserverdetails | sed 's/,/\n/g' | grep "environment_Name" | awk -F':' '{print $2}' | grep -q -e "Dev" if [ $? -eq 0 ] then echo "PASS" else echo "FAIL" fi else echo "sorry server is not present" fi else echo "all good" fi fi ```
- pattern minor 112d agoFetching system info using pythonThe following piece of code does ssh do different servers and fetches the system info and display it to the user: ``` import paramiko #list variables : ["IP_ADDR", "USERNAME", "PASSWD", "ROOT_PASSWD"] ip_list = [ ["192.168.11.44", "root", "****", "****"], ["192.168.11.8", "root", "****", "****"], ["192.168.11.30", "root", "****", "****"], ["192.168.11.6", "****", "****", "****"] ] os_check_list = ["DISTRIB_DESCRIPTION"] hard_disks = [ 'sda', 'sdb', 'sdc', 'sdd', 'sde', 'sdf', 'sdg', 'sdh', 'sdi', 'sdj', 'sdk', 'sdl', 'sdm', 'sdn', 'sdo', 'sdp', 'sdq', 'sdr', 'sds' ] os = None ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) for ip in ip_list: ssh.connect(ip[0], username = ip[1], password = ip[2]) print("\n \n ************************************************************ \ \n IP ADDR = {} SYSTEM INFO \ \n ******************************************************************". format(ip[0])) stdin, stdout, stderr = ssh.exec_command("cat /etc/*release") stdin.write(ip[3]+"\n") for line in stdout.readlines(): if any(x in line for x in os_check_list): os_dist = line.split("=") os = os_dist[1] print(" Operating System is {}" .format(os)) if not os: stdin, stdout, stderr = ssh.exec_command("cat /etc/system-release") for line in stdout.readlines(): os = line print(" Operating System is {}" .format(os)) os = None stdin, stdout, stderr = ssh.exec_command("sudo -k udisksctl status", get_pty = True) stdin.write(ip[3]+"\n") for line in stdout.readlines(): if any(x in line for x in hard_disks): print(line) elif "command not found" in line: print("udisksctl not installed on target server") stdin, stdout, stderr = ssh.exec_command("sudo
- pattern minor 112d agotrash script to alias rmThis script implements a command line level trashcan system. Designed to work around `rm` doing the bits needed to implement a trashcan system at command line level. Any user flags hands the request over to `rm`. This means `rm -f` will still delete a file with no recovery. Prevents execution by root as too many dependencies at superuser level. Deployment by adding aliases `rm=trash` and `rmoops=untrash`. Only implemented on files, does not cater for directories. Appreciate any and all suggestions from formatting, expansion of the idea to glaring issues. Looking for an experienced eye to pin point potential issues. /usr/local/bin/trash `#!/bin/bash # # Trashcan script # alias rm=trash # error() { echo $1 exit 1 } bypass() { exec rm $* } file="$1" trash=~/.trash keep=5 ## bypass scenarios # root user [ "$(id -u)" = "0" ] && error "Please do not run as root user." # special cases case $file in -*) bypass $* ;; $trash/* ) bypass $* ;; esac # only single filename supported [ $# -gt 1 ] && bypass $* # can we access the file? [ -f "$file" ] || error "File not specified." # move existing versions out of the way ls $trash/$file.version.* 2>/dev/null | tac | while read name; do version=$((${name##*.}+1)) # keep the only the last number of versions if [ $version -gt $keep ]; then rm $name || error "Unable to remove file $name." else mv $name $trash/$file.version.$version || error "Unable to move version $version." fi done # move file into trash (volume friendly) cp --preserve $file $trash/$file.version.1 || error "Unable to trash your file." rm -f $file || error "Unable to cleanup the file." exit 0 ` /usr/local/bin/untrash `#!/bin/bash # # Restore files from Trashcan # alias rmoops=untrash # error() { echo $1 exit 1 } file="$1" trash=~/.trash keep=5 ## bypass scenarios # root user [ "$(id -u)" = "0" ] && error "Please do not run as root user." # any flags so rm -rf actually does it case $file in -*) error "Flags are not supp
- pattern minor 112d agoFinding the maximum of a given list of data in GNU Assembly x86 (32 bit)I am following the book Programming from the Ground Up and as an answer to a question in the Use the Concepts section of chapter 4: - Convert the maximum program given in the Section called Finding a Maximum Value in Chapter 3 so that it is a function which takes a pointer to several values and returns their maximum. Write a program that calls maximum with 3 different lists, and returns the result of the last one as the program’s exit status code. I wrote the following code: maxfunc.s ``` # NAME: maxfunc.s # PURPOSE: A modular approach of finding the maximum of lists .section .data # The data section has three lists for testing, change the code # highlighted in the text section to change the list passed. data_1: .long 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 data_2: .long 23, 45, 62, 13, 87, 54, 0 data_3: .long 1, 2, 3, 3, 3, 7, 6, 5, 8, 1, 1, 0 # VARIABLES: # 1. %edi - Will be our index variable, to access the items # 2. %ebx - The element we're looking at currently # 3. %eax - The maximum value we've found so far # 4. %ecx - To store the address of the list .section .text .globl _start _start: # Push the address of the list we want to find the maximum of pushl $data_3 # ^ # +---> Change this to select your list call maximum addl $4, %esp # Reset the stack movl %eax, %ebx movl $1, %eax int $0x80 .type maximum, @function maximum: # Setup pushl %ebp movl %esp, %ebp # The initial setup: # Get the address of the list # Set the index to 0 # Get the first item from the list # The first item is currently the largest movl $0, %edi movl 8(%ebp), %ecx movl (%ecx, %edi, 4), %ebx movl %ebx, %eax max_loop: cmpl $0, %ebx je exit_loop incl %edi movl (%ecx, %edi, 4), %ebx cmpl %eax, %ebx jle max_loop # %ebx is greater than %eax
- pattern minor 112d agoAnsible playbook to install application from tarballI'm doing this, but as I'm the expert here (because no-one else is doing it) I have no real idea how awesome my code actually is. So the code should do the following: - Export the tarball from subversion on the target box - Untar it. - Run the install script, answering questions appropriately. For this review, I'd love input into whether this can be done differently, should generally follow different rules or whether it's just he best code you've ever seen. ``` - hosts: localhost become: true remote_user: root become_user: root become_method: su tasks: - name: Grab the encrypted variables include_vars: file: secret_things name: secrets - name: Grab the non-encrypted variables include_vars: file: mech_cfg.yml name: mech_cfg - name: install pip yum: name: python-pip state: latest - name: install pexpect==3.3 -- required for the expect module pip: name: pexpect version: 3.3 - name: Get the tarball from subversion subversion: repo: https://repo/path dest: /tmp/mechballs username: "{{ secrets.svn_user }}" password: "{{ secrets.svn_pass }}" export: yes force: yes - name: Expand the tarball unarchive: src: /tmp/mechballs/{{ mech_cfg.mech_tarball }}.tar.gz dest: /tmp/mechballs/ remote_src: true - name: Install the tarball expect: chdir: /tmp/mechballs/{{ mech_cfg.mech_tarball }} command: ./doinstall echo: yes responses: "Where do you want to install.*": "/opt/location" "Do you want to proceed with the installation .*" : "y" ```
- pattern minor 112d agoMy own little memory manager in CI have implemented a simple version of `malloc()` and its associated functions, `free()`, `calloc()`, and `realloc()`. - When `free()` is called, my implementation simply puts this memory on its own internal free-list. - When `malloc()` is called, it first checks the internal free-list. Only if the memory is not available there, it calls `sbrk()` to request another chunk. - All block sizes are based on powers of 2. - A best fit strategy is used to allocate from the free-list. Could you please review the same and let me know your suggestions/comments? ``` #include #include #include // a struct representing a memory block struct memoryBlock { // metadata about memory block size_t size; struct memoryBlock *next; }; // function declarations void* malloc(size_t); void free(void*); void* calloc(size_t, size_t); void* realloc(void*, size_t); struct memoryBlock* mymemcpy(void*, const void*, size_t); void fuse_adjacent_freeBlocks(); size_t round_to_next_power_of_two(unsigned int); struct memoryBlock* get_bestFit_freeBlock(size_t size); void print_freelist(); struct memoryBlock head = { 0, 0 }; /* This function allocates a block of memory of size bytes. */ void* malloc(size_t size) { //If size is zero or less, return NULL if (size size = size; return ((char*) p) + sizeof(struct memoryBlock); } // traverse the free-list for a best-fit, if found return it p = get_bestFit_freeBlock(size); if (p != NULL) { return ((char*) p) + sizeof(struct memoryBlock); } // reached only if best-fit not found, sbrk and return p = (struct memoryBlock*) sbrk(size); p->size = size; return ((char*) p) + sizeof(struct memoryBlock); } /* This function frees a block of memory that had previously been allocated. */ void free(void *ptr) { // If ptr is NULL, this function does nothing, just RETURNs if (ptr == NULL) { return; } struct memoryBlock *to_free = (struct memoryBlock*) (((char*) p
- snippet minor 112d agoLXC Bootstrap - A wrapper script around lxc utility scripts to create and set up an LXC container based on settingsSo some background here. I recently discovered the ease of LXC containers on Ubuntu. I've been building some 'test' containers locally for testing things I develop on Ubuntu, but the evil thing is that creating these containers then getting all the software I want in the container and everything set up the way I want it to be set up is not the most trivial of processes. First you have to create the container, then start the container, then run a long `lxc-attach -n CONTAINERNAME -- [command]` string depending on the command you want to execute (unless you want to drop into a shell, in which case you omit the `-- [command]` part), then you have to set up the things by hand with commands in the container. Well, I found this quite annoying, as I need a 'base container' with Ubuntu Server in a userspace-usable format, which there is no 'base template' for. So, I wrote this, what I call `lxc_bootstrap.py`, which creates the container, starts the container, installs the packages I want on the image, sets up users per my needs, and then is done, and the container is running and ready for use. And it's got a set of arguments that can be parsed to override standard bootstrap settings, such as different OSes, different release versions, different architectures, different packages or users to "bootstrap" the system with, etc. It can also run the bootstrapping process on existing containers, without creating a new one, with a specific flag. Any suggestions for improvement are welcome, though I'm definitely using a lot of code that can probably be condensed or otherwise optimized, so such suggestions are most welcome above most other code suggestions. The code is here below. Oh, and since I'm so picky about PEP8 style guidelines, I've got Flake8 running in CI from the repository, so it catches most evils. Note that per PEP8, a team/individual can choose to use a longer line length than 80 but no more than 120; I'm using a max line length of 120 in this case, so please