Wednesday, September 27, 2017

How to speed up Mac OS's key repeat

Open a terminal and type:
# defaults write -g InitialKeyRepeat -int 10
# defaults write -g KeyRepeat -int 1

Thursday, August 24, 2017

Warning: Fake start-stop-daemon called

If you're running into this issue, it means that the OS installation didn't clean up after itself properly.
All you have to do is
# mv /sbin/start-stop-daemon.REAL /sbin/start-stop-daemon
And the services that require this utility will work properly.

Tuesday, August 1, 2017

Moving a LVM disk between systems

Say you have a LVM volume mounted on system A that you need to move to system B, you first have to umount it from A:
# umount /path-to-volume
Then either power down and remove the physical disk or if it's hot-pluggable, detach that device before moving it to sysetm B. Once it's installed on B:
# mkdir /new-path-to-volume
Look for your volume and its device path, for example
# lvscan
  inactive            '/dev/myvolume-volgroup/myvolume_logical_volume' [223.00 GiB] inherit
It will most likely be 'inactive', you need to activate it:
# vgchange -ay
# lvscan
  ACTIVE            '/dev/myvolume-volgroup/myvolume_logical_volume' [223.00 GiB] inherit
Add an entry to /etc/fstab:
/dev/myvolume-volgroup/myvolume_logical_volume   /new-path-to-volume       brtfs    discard,noatime 0       0
And mount it !
# mount -a

Tuesday, June 20, 2017

Manually installing a driver or module on Linux

This varies slightly depending on your distribution, but the general steps are:

(1) unload the current driver (if it exists)
# rmmod driver_name/code>
(2) copy the driver/module to the kernel's modules directory
# cp driver_name.ko /lib/modules/`uname -r`/kernel/drivers/specific_directory_for_your_driver/code>
(3) load the new driver
# modprobe driver_name
On Debian and Ubuntu, you also need to update the ramdisk so the driver will load automatically after a reboot:
# update-initramfs -u
That's it !

Thursday, June 15, 2017

How to remove the sidebar on a blogger in the Soho theme

Go to Theme > Edit HTML, click somewhere on the code window and do a search for this:
  .page_body {
    margin-$startSide: $(sidebar.width);
  }
  .sticky .centered-top {
    padding-$startSide: $(sidebar.width);
  }
Then delete them ! That should do it. Note that this might not apply to other blog themes.

Thursday, April 27, 2017

Cutting wood with a Dremel tool

Very cool little video of how to cut wood with one of those Dremel accessories, too bad it's limited to 1/8" thick pieces tho.

Friday, April 7, 2017

How to check if you're inside a lxc container

The "usual" way of checking whether your process is running inside a lxc container is to look at /proc/1/cgroup. For example:
# cat /proc/1/cgroup
13:name=systemd:/
12:pids:/
11:perf_event:/
10:net_prio:/
9:net_cls:/
8:memory:/
7:hugetlb:/
6:freezer:/
5:devices:/
4:cpuset:/
3:cpuacct:/
2:cpu:/
1:blkio:/

# lxc-attach -n foo -- cat /proc/1/cgroup
13:name=systemd:/lxc/foo
12:pids:/lxc/foo
11:perf_event:/lxc/foo
10:net_prio:/lxc/foo
9:net_cls:/lxc/foo
8:memory:/lxc/foo
7:hugetlb:/lxc/foo
6:freezer:/lxc/foo
5:devices:/lxc/foo
4:cpuset:/lxc/foo
3:cpuacct:/lxc/foo
2:cpu:/lxc/foo
1:blkio:/lxc/foo
Another way to do it is to check the hostid of the system, that requires some knowledge about what the hostid looks on your system but at least provides a programmatic way of doing so (since you can use the gethostid() and sethostid() library calls instead of running a command). For example:
# hostid
ae031411
# lxc-attach -n foo -- hostid
4487013
Note that it is possible that both hostids are the same, so once again, this method relies on some additional knowledge about the system.

Monday, March 20, 2017

Why should we use assertions when programming ?

Because the only real documentation for the code you're working on is the code itself. Comments become stale over time, test cases aren't always executed and developers come and go. If your code uses assertions or similar mechanisms, it is documenting itself by stating at the onset what are some of its assumptions.

That said, it's important to write readable code. If there's no style enforcement and no care for making code that reads well, it's like reading a book where each paragraph was written by a completely different person.

Friday, March 3, 2017

Simple implementation of a doubly linked list in C

Similarly to the previous blog post, here's a basic implementation of a doubly linked list in the C programming language.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <assert.h>

#define MAX_LEN   10
#define MAX_VAL   30

typedef struct node {
    int val;
    struct node *next;
    struct node *prev;
} node_t;

static int list_len = 0;

void
print_list(node_t *head, node_t *tail)
{
    node_t *node;
    int    cnt;

    node = head;
    cnt = 0;

    printf("printing fwd\n");
    while (node != NULL) {
        printf("[%d] %d\n", cnt++, node->val);
        node = node->next;
    }

    printf("printing bwd\n");
    node = tail;

    while (node != NULL) {
        printf("[%d] %d\n", --cnt, node->val);
        node = node->prev;
    }
}

void
init_list(node_t **head, node_t **tail)
{
    node_t *node, *last;
    int    i;

    do {
        list_len = rand() % MAX_LEN;
    } while (list_len == 0);

    printf("creating list with %d entries\n", list_len);

    for (i = 0; i < list_len; i++) {
        node = calloc(1, sizeof (node_t));
        node->val = rand() % MAX_VAL;
        node->next = *head;
        node->prev = NULL;
        *head = node;

        if (*tail == NULL) {
            *tail = node;
        }

        if (last != NULL) {
            last->prev = node;
        }

        last = node;
    }
}

void
reverse_list(node_t **head, node_t **tail)
{
    node_t *next, *prev, *new_head = NULL, *new_tail = NULL;

    printf("reversing\n");

    if (*head == NULL || *tail == NULL) {
        return;
    }
    if (*head == *tail) {
        printf("nothing to reverse\n");
        return;
    }

    next = *head;
    prev = *tail;

    while (next != NULL) {
        assert(prev != NULL);

        *head = next->next;
        *tail = prev->prev;

        next->next = new_head;
        prev->prev = new_tail;

        new_head = next;
        new_tail = prev;
        next = *head;
        prev = *tail;
    }

    assert(*head == NULL);
    assert(*tail == NULL);
    *head = new_head;
    *tail = new_tail;
}

void
remove_list(node_t **head, node_t **tail)
{
    node_t *prev, *tgt;
    int    item = 0, i, val;

    if (*head == NULL || *tail == NULL) {
        return;
    }

    item = rand() % list_len;

    tgt = *head;

    for (i = 0; i < item; i++) {
        assert(tgt != NULL);
        tgt = tgt->next;
    }

    printf("removing item %d :: %d\n", item, tgt->val);

    if (tgt->prev != NULL) {
        prev = tgt->prev;
        prev->next = tgt->next;
    }

    if (tgt->next != NULL) {
        tgt->next->prev = prev;
    }

    if (*head == tgt) {
        *head = tgt->next;
    }

    if (*tail == tgt) {
        *tail = prev;
    }

    free(tgt);
    list_len--;
}

int
main(int argc, char **argv)
{
    node_t *head, *tail;

    srand(time(NULL));

    init_list(&head, &tail);
    print_list(head, tail);

    reverse_list(&head, &tail);
    print_list(head, tail);

    remove_list(&head, &tail);
    print_list(head, tail);

    return (0);
}

Simple example of linked list operations in C

Here's a quick and simple implementation of basic routines on linked lists in the C programming language. The length or the list is limited to MAX items and each node can have a max value of MAX_VAL.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <assert.h>

#define MIN      1
#define MAX      10
#define MAX_VAL  30

typedef struct node {
    int val;
    struct node *next;
} node_t;

static int list_len = 0;

void
print_list(node_t *head)
{
    node_t *node = head;
    int cnt = 0;

    while (node != NULL) {
        printf("[%d] %d\n", cnt, node->val);
        node = node->next;
        assert(++cnt <= list_len);
    }
}

int
grow_list(node_t **head)
{
    node_t *node;
    int i, len;

    do {
        len = rand() % MAX;
    } while (len < MIN);

    printf("adding %d entries to the list\n", len);

    if (*head != NULL) {
        node = *head;

        do {
            ;
        } while ((node = node->next) != NULL);
    }

    for (i = 0; i < len; i++) {
        node = calloc(1, sizeof (*node));
        node->val = rand() % MAX_VAL;

        node->next = *head;
        *head = node;
    }

    return (len);
}

void
reverse_list(node_t **head)
{
    node_t *node = *head, *new_head = NULL;

    if (*head == NULL) {
        return;
    }

    printf("reversing list\n");

    while (node != NULL) {
        *head = node->next;
        node->next = new_head;
        new_head = node;
        node = *head;
    }

    assert(*head == NULL);

    *head = new_head;
}

void
remove_node(node_t **head)
{
    node_t *node, *prev;
    int idx = 0, i = 0;

    if (*head == NULL) {
        return;
    }

    do {
        idx = rand() % list_len;
    } while (idx == 0);

    printf("removing item %d\n", idx);

    node = *head;

    do {
        prev = node;
    } while ((node = node->next) != NULL && ++i < idx);

    prev->next = node->next;
    free(node);
}

int
main(int argc, char **argv)
{
    node_t *head = NULL;

    srand(time(NULL));

    list_len += grow_list(&head);
    print_list(head);

    reverse_list(&head);
    print_list(head);

    list_len += grow_list(&head);
    print_list(head);

    reverse_list(&head);
    print_list(head);

    remove_node(&head);
    print_list(head);

    return (0);
}

Simple examples of Bubble Sort and Binary Search in C

Using a LEN sized array (default size is 10), here's a quick and simple example of how to implement bubble sort and binary search routines in C.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define    LEN        10
#define    MAX_VAL    20

static int array[LEN];

void
print_array(void)
{
    int i;

    printf("printing\n");

    for (i = 0; i < LEN; i++) {
        printf("[%d] %d\n", i, array[i]);
    }
}

void
init_array(void)
{
    int i;

    for (i = 0; i < LEN; i++) {
        array[i] = rand() % MAX_VAL;
    }
}

void
sort_array(void)
{
    int i, j, tmp;

    printf("sorting\n");

    for (i = 0; i < LEN - 1; i++) {
        for (j = 0; j < LEN - 1 - i; j++) {
            if (array[j] > array[j + 1]) {
                tmp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = tmp;
            }
        }
    }
}

void
binarysearch_array(void)
{
    int l, u, m, val;

    l = 0;
    u = LEN - 1;
    val = array[rand() % LEN];

    printf("searching for %d\n", val);

    while (l <= u) {
        m = (l + u)/2;

        if (array[m] == val) {
            printf("found %d at %d :: %d\n", val, m, array[m]);
            break;
        } else if (array[m] > val) {
            u = m - 1;
        } else if (array[m] < val) {
            l = m + 1;
        }
    }
}

int
main(int argc, char **argv)
{
    srand(time(NULL));

    init_array();
    print_array();

    sort_array();
    print_array();

    binarysearch_array();

    return (0);
}

Friday, February 10, 2017

Showing IPv4 and IPv6 multicast group membership on Linux

The traditional way of listing multicast group memberships on any Unix system is with the netstat(1) command. But on Linux, the ip(1) tool can show both IPv4 and IPv6 groups in a single command:
# ip maddr show
1:    lo
    inet  224.0.0.1
    inet6 ff02::1
    inet6 ff01::1
74:    eth0.2
    link  01:00:5e:00:00:01
    link  33:33:00:00:00:01
    inet  224.0.0.18
    inet  224.0.0.1
    inet6 ff02::1:ff04:4253
    inet6 ff02::1
    inet6 ff01::1

How to list all the included header files in a C program

For a simple C program:
#include <stdlib.h>
#include <stdio.h>

int
main(int argc, char **argc)
{
    printf("foo\n");
    return (0);
}
We can use gcc's preprocessor directive and with a little shell processing we get:
$ gcc -E foo.c | grep include | cut -d'"' -f2 | sort | uniq
/usr/include/alloca.h
/usr/include/endian.h
/usr/include/features.h
/usr/include/_G_config.h
/usr/include/libio.h
/usr/include/stdc-predef.h
/usr/include/stdio.h
/usr/include/stdlib.h
/usr/include/time.h
/usr/include/wchar.h
/usr/include/x86_64-linux-gnu/bits/byteswap-16.h
/usr/include/x86_64-linux-gnu/bits/byteswap.h
/usr/include/x86_64-linux-gnu/bits/endian.h
/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h
/usr/include/x86_64-linux-gnu/bits/select.h
/usr/include/x86_64-linux-gnu/bits/sigset.h
/usr/include/x86_64-linux-gnu/bits/stdio_lim.h
/usr/include/x86_64-linux-gnu/bits/stdlib-float.h
/usr/include/x86_64-linux-gnu/bits/sys_errlist.h
/usr/include/x86_64-linux-gnu/bits/time.h
/usr/include/x86_64-linux-gnu/bits/types.h
/usr/include/x86_64-linux-gnu/bits/typesizes.h
/usr/include/x86_64-linux-gnu/bits/waitflags.h
/usr/include/x86_64-linux-gnu/bits/waitstatus.h
/usr/include/x86_64-linux-gnu/bits/wordsize.h
/usr/include/x86_64-linux-gnu/gnu/stubs-64.h
/usr/include/x86_64-linux-gnu/gnu/stubs.h
/usr/include/x86_64-linux-gnu/sys/cdefs.h
/usr/include/x86_64-linux-gnu/sys/select.h
/usr/include/x86_64-linux-gnu/sys/sysmacros.h
/usr/include/x86_64-linux-gnu/sys/types.h
/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h
/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h<.code>

Friday, January 13, 2017

How to disable iPhone update notifications

The simplest way of removing those annoying iOS update notifications on your iPhone is first to logout of the AppStore in the Music app (or the iTunes app). Go to your profile on the upper left corner and sign out. You'll need to restart your iPhone for the logout to take effect.

Now go to
Settings > General > Storage & iCloud Usage > Manage Storage
and delete any downloaded updates.

Done ! The downside is that you'll need to log back in if you want to update or download a particular app, but that's a small price to get rid of those notifications.

Tuesday, December 13, 2016

How to check for endianness on Linux

Endianness is a simple concept, architectures that store the most significant byte (in a multi-byte data type) at the end are big-endian and the ones that store the least significant byte at the end are little endian.

Don't mix bytes and bits here. There's no big or little endian in a char or any single byte data type.

Here's how you check for it on Linux:
#include <stdio.h>

int
main(int argc, char **argv)
{
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
        printf("little endian\n");
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
        printf("big endian\n");
#endif

        return (0);
}

Tuesday, November 22, 2016

Create playlists from media directory

Here's a quick and simple shell script to create m3u playlists for each directory in your media folder:
#!/bin/bash

for i in `find . -type d`; do
        for j in $i/*.mp3; do
                if [ "$j" != "$i/*.mp3" ]; then
                        file=$(basename $j);
                        directory=$(basename $i);
                        echo $file >> $i/$directory.m3u;
                fi;
        done;
done
Not familiar with shell scripts? Just open a "Terminal" application and copy+paste those lines into it.
If you have wav files or other format, just replace "mp3" with that format's extension.

Friday, November 18, 2016

unregister_netdevice: waiting for eth0 to become free. Usage count = 1

Bumped into this error while removing a veth link on a Docker container recently. It doesn't look like there's a fix for this but I was able to workaround it by putting the link in promiscuous mode before removing it:
# ip link set eth0 promisc on
# ip link delete eth0 type veth
There are reports that this doesn't always work, so YMMV.

Wednesday, November 16, 2016

Friday, November 4, 2016

Listing LWPs sorted by CPU usage on Linux

Here's a quick an simple way of showint the top CPU consumers on Linux:
# while true; do
        sleep 1;
        ps -Leo pcpu,pid,lwp,user,args --no-headers| sort -t. -nk1,2 -k4,4 -r  | head; echo "";
done

Wednesday, October 26, 2016

Can I use Thunderbolt 3 devices on an older iMac or MacBook ?

Unfortunately, no. Thunderbolt 3 has a different connector (and port) than the original Thunderbolt or Thunderbolt 2. Currently there are adapters that allow you to connect a Thunderbird 3 port (latest Macs) to Thunderbolt or Thunderbolt 2 devices. But not the other way around.

Wednesday, September 14, 2016

Debugging PAM issues on Solaris or illumos

First off, add:
debug_flags=0xffff
to /etc/pam_debug

Then tell the system log to use a specific file for PAM debug messages by adding this line to /etc/syslog.conf:
*.debug        /var/log/pam_log
Touch that file so it exists (syslog won't create it):
# touch /var/log/pam_log
And restart the syslog service:
# svcadm restart system-log
You're ready!

Run a command that uses PAM, like passwd(1) and check the output of /var/log/pam_log.

Tuesday, September 13, 2016

Incremental backups with rsync

Here's a simple example of how to use rsync(1) to update a backup directory. This will copy any new files based on timestamp (not checksum) and remove any files that are no longer in the original directory:
# rsync -avh --stats --delete /home/username/data/ /backup/home/user/data/
Note that different versions of rsync(1) may treat the last forward slash in either paths differently. Some require it, some don't. Make sure to check first.

Fastest way to copy data from one directory to another

Using tar(1) or cpio(1) is by and large the fastest way of copying large amounts of data from one place to another, especially when the data is unstructured (many small files as opposed to a few large ones). Setting the block size is key, and here's what generally works the best in my experience:
# cd parent_directory
# tar Ecbf 256 - source_data | (cd /target_directory/ ; tar xf - );
In this example, we're copying /parent_directory/source_data to /target_directory/source_data, where source_data is usually a directory.

Notice that this can easily be converted to a for statement that iterates parent_directory and starts a tar session for each of its subdirectories.

Wednesday, July 13, 2016

DIY speaker or monitor stand

Here's a quick and easy way to build your own speaker/monitor stand. These are very strong and will support a lot of weight. They will wobble a little bit, but as long as you build a large enough base it shouldn't fall over.

Materials (for one stand, repeat as needed):

the complete stand
(2) 16"x12"x1" boards in whatever type of wood you want
(1) 3/4" steel pipes in whatever length you want (3' is usually a good start)
(1) 3/4" flange
(1) 2" flange
(1) 2" to 3/4" reducer (to connect the 3/4" pipe to the 2" flange)
(8) 1" screws with bolts to fit the flanges (sized according to the type of flange you have)

Instructions (for one stand, repeat as needed):

(a) center the flanges on each of the boards, drill holes for the screws and bolt the flanges to the boards. You'll need to countersink the bolts on the flat side of both pieces of wood, so make sure they are not longer than the board you're using

(b) screw the reducer onto the 2" flange and the pipe onto the reducer. Remember: monkey tight, not gorilla tight

(c) "screw" the top board (the one with the 3/4" flange on) onto the pipe

(d)  level as needed

top board with the 3/4" flange
bottom board with the 2" flange


You can modify these in many different ways. For example, I routed the board to countersink the flanges, but that's not a must have. Up to you, just apply common sense.

The pipes could probably have been 1/2", but the price difference was very little. Again, adjust as needed.

How to cut wood veneer without cracking it

I tried cutting a piece of wood veneer with different tools but it always cracked, then I tried tracing with masking (painter's) tape on both sides and then cutting with a scissor on top of it. Worked like a charm.


Thursday, June 23, 2016

What's a I-94 document ?

The I-94 is a USA entry document that states when you entered the country and how long you can stay. The length of stay depends on too many things to list here, but be aware that over staying is not a good thing and should be avoided.

Tuesday, June 21, 2016

How to make assertion failures more useful in C

It's common for a C program to use the assert(3) routine to guarantee that it will abort when an invalid situation happens. For example:
ret = foo();
assert(ret == 0);
If that condition is false, the program will exit, print an error saying that this assertion was hit and generate a core dump (if the system is configured to). It can make life a bit easier if we add an error string to the same check:
ret = foo();
assert(ret == 0 || "foo() returned non-zero when called from bar()");

Tuesday, June 14, 2016

IPMIView for Mac

For a strange reason SuperMicro doesn't document this, but you can use the Linux version of IPMIView on Mac OS (it's just a Java app).

Download it here:
ftp://ftp.supermicro.com/utility/IPMIView/Linux/

After extracting the compressed file, open a terminal and make the 'IPMIView20' file executable
~/Downloads/IPMIView_V2.11.0_bundleJRE_Linux_20151223
$ chmod a+x IPMIView20
And then run it:
~/Downloads/IPMIView_V2.11.0_bundleJRE_Linux_20151223
$ ./IPMIView20
That should do it.

Sunday, June 12, 2016

How to copy a picture or photo from an Instagram post

Quick and easy way to copy a picture or photo posted on an Instagram account:

(1) right click the post and select "view page source"
(2) search for the "display_url" keyword, you'll see something like this
"display_url": "https://instagram.fsnc1-1.fna.fbcdn.net/../../blah.jpg?ig_cache.."
(3) select all the text from "https://..." to ".jpg"
(4) copy and paste it to a new browser tab or window and hit enter, you should see the picture
(5) right click and select "Save as..."

There you go !

Friday, April 1, 2016

Monitoring process creation on Linux

Here's a quick one liner to show a list of running processes, reverse ordered by how long they've been running:
# while true; do sleep 0.5; ps --ppid 2 -p 2 --deselect -o pid,cmd,etime= --sort -etime ; done
You can increase the sleep time if desired, this is waiting half a second between iterations.