вторник, 25 апреля 2017 г.

Hot plug/unplug SATA drives on Linux

From time to time I need these commands.

Before hot-unplugging a disk drive sdX make sure that no file systems from the disk are mounted, no swap active, no LVM volumes active (N - partition number, VG - volume group, LV - logical volume, PV - physical volume):
lsblk /dev/sdX                 # see what's there
swapon -s | grep sdX           # check for active swap
swapoff /dev/sdXN              # deactivate swap if found
mount | grep sdX               # check for mounted FS
umount /dev/sdXN               # umount them if found
pvs | grep sdX                 # check for PVs
pvdisplay -m /dev/sdXN         # find LVs if a PV found
umount /dev/mapper/VG-LV       # umount LVs if found
lvchange -an /dev/mapper/VG-LV # deactivate LVs if any 
If it is the last PV of a volume group, the VG itself should be deactivated:
vgchange -an VG
Then prepare the device for unplugging (it makes the kernel send power down command to the drive and unregister it):
echo 1 > /sys/block/sdX/device/delete
And then unplug it physically.

After hot-plugging a disk drive on a host adapter X:
echo - - - > /sys/class/scsi_host/hostX/scan 
Then you can mount file systems, activate swap, activate LVs and mount them if needed.

вторник, 18 апреля 2017 г.

Hanoi tower algorithm to move from any to any state (1993)

In the year 1993 I have developed an algorithm to solve a generalized Hanoi tower problem: move from any state to any state.

The algorithm is very simple and uses a nice state representation: a ternary number. The right digit represents the number of rod where the largest disk resides, then the number of the next disk and so on to the number of rod of the smallest disk. 64 bit unsigned integer can hold state of up to 40 disks.

For the original Hanoi tower problem we have this encoding: source=0000...0, destination=2222...2.

It was also possible to use strings (with the largest disk at the left), but it was harder to allocate memory in this case, so I chose the integer representation.

It is easy to note that for moving a large disk it is required to move all smaller disks to an intermediate rod. So the algorithm first reduces the source and destination states if some large disks are on their target positions, then recursively moves the smaller disks to an intermediate rod, then moves the large disk, then recursively moves the smaller disks to their final destinations.

Here is the algorithm encoded in C (written in 1993, adapted now for ANSI C):

#include <stdio.h>
 
void Move(int f,int t)
{
        printf("%c%c  ",f+'0',t+'0');
}

void Hanoi3(unsigned from,unsigned to,int n)
{
        unsigned via,f,t,v;
        int i;

        if(n==0)
                return; /* nothing to do */
 
        /* reduce equal positions of largest disks */
        do
        {
                f=from%3;
                t=to%3;
                from/=3;
                to/=3;
                n--;
        }
        while(f==t && n>=0);
 
        if(n<0)
                return; /* nothing to do */

        /* now f is the source position of the largest disk,
           and t is its target position */

        v=3-f-t; /* intermediate rod */
        via=0; /* intermediate state */
        for(i=0; i<n; i++)
                via=via*3+v;

        Hanoi3(from,via,n);
        Move(f,t);
        Hanoi3(via,to,n);
}

среда, 22 февраля 2017 г.

Recovering after loss of a physical volume with LVM2 on Linux

Recently I have lost a hard drive which contained a physical volume of LVM2.

It contained an insignificant file system with scratch data and a part of a RAID1 logical volume.

To recover, it was necessary to repair the RAID1 LV and remove other partial LV. I was surprised that the network lacked information on how to repair a RAID1 LV.

So here are the commands:

lvconvert --repair /dev/mapper/VG-LVraid1
lvremove /dev/mapper/VG-LVpartial
vgreduce --removemissing VG

четверг, 16 февраля 2017 г.

A few glitches with Fedora 24 installations

I have noticed multiple times that when a process seems to hang, strace sometimes can kick it forward and cause it to proceed and either terminate as it should or fail with a signal.

There was a strange hang within systemd (PID 1), it apparently created a forked copy of itself which hung, and when I tried to strace the child process it failed with a signal. Then the parent (PID 1) ran pause() but any tries to send it SIGTERM or SIGUSR1 caused nothing, the pause() system call did not interrupt. I think that all signals were blocked. The systemd (PID 1) did not process parentless zombies either. Reboot was required.

One time when restarting mysqld it took forever to terminate, but finished in a second when I ran strace on it.

Another time, df hung due to unresponsive nfs. After I had unmounted the nfs filesystem using "umount -l -f" the df still lingered for minutes until I ran strace on it.

I suspect there is a bug in the kernel. And a bug in systemd.

kernel-4.9.9-100.fc24.x86_64
systemd-229-18.fc24.x86_64

вторник, 6 декабря 2016 г.

Graceful squid restart

Squid is a well-known open source http proxy server.

Sometimes it is necessary to change its configuration, for example to update ACL lists. Fortunately it has the command "squid -k reconfigure". Unfortunately, during reconfiguration squid refuses new connections. If the configuration is complex and ACLs are large it can take several seconds.

Some people recommend setting up multiple squid servers with a load balancer to solve the problem, but I believe it's an overkill for small installations.

So here is my approach.

To avoid service disruption, start another copy of squid on the same machine with identical configuration but with different TCP ports and without persistent storage:
a_conf=/etc/squid/squid.conf
b_conf=/etc/squid/squid-b.conf
b_pid=/var/run/squid-b.pid

sed -e 's/^http_port \([0-9]\+\)/http_port 1\1/' \
    -e
'/^cache_dir/d' < $a_conf > $b_conf
echo "pid_filename $b_pid" >> $b_conf

squid -f $b_conf
Then redirect new connections to the new port (i.e. 13128 by default) using iptables NAT.

Reconfigure the first copy of squid using "squid -k reconf", then remove NAT redirection and shutdown the second copy of squid using "squid -f $b_conf -k shutdown".

воскресенье, 13 ноября 2016 г.

Port scan reporting

Internet worms scan the internet infecting new hosts, creating botnets, abusing services.

For a long time I have had implemented port scan detection and blocking script for our local users. The perl script analyzed netflow information and when a certain level was exceeded it informed the user by e-mail and blocked the port.

It had to handle a few special cases, for example smtp servers (MTA) easily exceeded threshold on ports 25 and 113, so the script probed the port 25 on the suspected host before taking an action. A few IP addresses were added to a white list.

Recently an idea to inform other providers came to me. Remote scanners were detected anyway, I had just to add an action. Whois service gives an abuse e-mail address, so composing a letter template was the only really creative task.

To avoid sending the letter too often I have added dynamic firewall rules with a timeout to block the scan traffic. So the warnings are sent in 1, 2, 4, 8 ... 32 days if the activity does not stop.

The script works and while Chinese internet providers largely ignore the warnings, I've received many replies which indicate that a real problem was noticed and fixed due to my messages.

It would be nice though if all ISP implemented local scan detection themselves.