bookmark_borderHow to expand a disk from the Linux command line

I’ve been frustrated with the number of instructions that involve deleting a partition and then creating a new partition with the same starting block. Totally unnecessary! 

Life has gotten a lot easier thanks to the growpart command. The best part is that with the right filesystem you don’t even need to unmount.  I suggest taking a backup or snapshot first in case something goes wrong.

growpart /dev/device_name partition_number

You can test it first with –dry-run:

growpart --dry-run /dev/sda 3

Once that is done, just run the command for your given filesystem to expand into the rest of the partition.

For btrfs:

btrfs filesystem resize amount mount_point

The amount can be something like +50g or max. To resize the root partition to max simply type:

btrfs filesystem resize max /

For ext4 it is:

resize2fs /dev/device

For example:

resize2fs /dev/sda3

For XFS:

xfs_growfs /mount_point

for example:

xfs_growfs /

bookmark_borderNVME stalls in Linux

I’m putting this here since I haven’t seen it mentioned elsewhere and it took me forever to figure out:

I was getting timeouts on two different NVME drives, 2 different motherboards and two different CPUs, until I extended the timeout and after that I was just getting stalls. The fix was to disable ASPM:

echo performance > /sys/module/pcie_aspm/parameters/policy

Or you can add “pcie_aspm=off” to your kernel command line.

bookmark_borderApache config validater.

This is an Apache config sanitizer, it checks to make sure there are no orphaned files in the Debian style sites-available/sites-enabled type setup and checks to make sure each virtual host has a valid DNS.

#!/bin/bash
# Apache config sanitizer.. Checks to make sure all sites are correctly configured 
# for DNS and checks for orphaned config files.
#
# By Gerhard Mack <gmack@innerfire.net>

function getipaddress {
        if [[ "${1}" == 4 ]]
        then
                getent ahostsv4 "${2}" | grep STREAM | head -n 1 | cut -d ' ' -f 1
                return
        fi

        if [[ "${1}" == 6 ]]
        then
                getent ahostsv6 "${2}" | grep STREAM | head -n 1 | cut -d ' ' -f 1
                return
        fi
}

while read line
do
        name="$(basename $line)"

        #Ignore common standard files
        if [[ "${name}" == "000-default-le-ssl.conf" ]]
        then
                continue
        fi

        if [[ "${name}" == "default-ssl.conf" ]]
        then
                continue
        fi

        if [[ "${name}" == "000-default.conf" ]]
        then
                continue
        fi

        if [[ ! -e "/etc/apache2/sites-enabled/${name}" ]]
        then
                echo orphaned file: ${line}
        fi
done <<< "$(find /etc/apache2/sites-available/ -name '*.conf')"

while read line
do
        array=( $line )

        if [[ "${line:0:1}" == [0-9] ]]
        then
                VIP=$(echo ${array[0]} | cut -d: -f1 )
                IPV=4
                continue
        fi

        if [[ "${line:0:1}" == "[" ]]
        then
                 VIP=$(echo ${array[0]} | cut -d\] -f1 | cut -d \[ -f2)
                 IPV=6
                 continue
        fi

        if [[ "${line:0:1}" == "*" ]] 
        then
                 continue
        fi

        if [[ "${array[0]}" == "port" ]]
        then
                 VHOST="${array[3]}"

                 IP=$(getipaddress ${IPV} ${VHOST})

                 if [[ -z "${IP}" ]]
                 then
                         echo ${VHOST} does not resolve. \(should be \"${VIP}\"\)
                         continue
                 fi

                 if [[ "${IP}" == "::ffff:"* ]]
                 then
                          echo ${VHOST} does not have an IPv6 address. \(should be \"${VIP}\"\)
                          continue
                 fi

                 if [[ "$IP" != "$VIP" ]]
                 then
                          echo vhost ${VHOST} points to \"${IP}\" \(should be \"${VIP}\"\)
                 fi
                 
                 continue
         fi

         if [[ "$array[0]" == "alias[0]" ]]
         then
                 VALIAS="${array[1]}"
                 IP=$(getipaddress ${IPV} ${VALIAS})

         if [[ -z $IP ]] ; then
                 echo ${VHOST} alias ${VALIAS} does not resolve. \(should be \"${VIP}\"\)
                 continue
         fi

         if [[ ${IP} == "::ffff:"* ]]
         then
                 echo ${VHOST} alias ${VALIAS} does not have an IPv6 address. \(should be \"${VIP}\"\)
                 continue
         fi

         if [[ "$IP" != "$VIP" ]] ; then
                echo vhost ${VHOST} alias $VALIAS points to \"${IP}\" \(should be \"${VIP}\"\)
         fi

         continue
         fi
done <<< "$(apachectl -S)"

 

bookmark_borderconst vs static const in C with GCC

Something I’ve been wondering but have yet to see a good explanation for is if there is a difference between the way GCC handles const and static const.  Now in theory the compiler should handle them the same way but does it?  My web search didn’t really come up with much so I decided to test for myself.

A quick test using GCC 4.7.2:

const.c

#include <string.h>
#include <stdio.h>

void test()
{
        const char i[] = "not changed";
        char *j;
        printf("before %s\n", i);

        j = i;

        strcpy(j, "changed");
        printf("after i=%s\n", i);
}

int main()
{
        test();
        test();
}

staticconst.c

#include <string.h>
#include <stdio.h>

void test()
{
        static const char i[] = "not changed";
        char *j;
        printf("before %s\n", i);

        j = i;

        strcpy(j, "changed");
        printf("after i=%s\n", i);
}

int main()
{
        test();
        test();
}

How each turns out:

const.c

~$ gcc const.c -o const -g
const.c: In function ‘test’:
const.c:10:4: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
~$ ./const
before not changed
after i=changed
before not changed
after i=changed

Not only can I change the variable, but it resets it at each function call so this means it is reallocating the variable each time.

staticconst.c

~$ gcc staticconst.c -o staticconst -g
staticconst.c: In function ‘test’:
staticconst.c:10:4: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
./staticconst
before not changed
Segmentation fault (core dumped)

gdb shows the following:

Core was generated by `./staticconst’.
Program terminated with signal 11, Segmentation fault.
#0  0x0000000000400534 in test () at staticconst.c:12
12        strcpy(j, “changed”);

As you can see static const is stored somewhere actually read only and being static it is not being reallocated each time the function is called making this version more efficient.