19 March 2014

Unsetting a trap

Quick one: catching a trap in bash is fairly easy with bash' trap command (search for 'trap \[' in bash' man page) but how to clear a set one?
It's in the man page, of course, but who reads those, right? I'm betting the answer is bound to be found on some blog through Google in 0.76 seconds flat ;)
"If arg is absent (and there is a single sigspec) or -, each specified signal is reset to its original disposition (the value it had upon entrance to the shell)."
So it turns out it's fairly simple and this demonstrates it:
root@mgmtsrv:~# cat test.sh
#!/bin/bash
trap 'echo TRAPPED!; break' SIGINT
while [ True ]; do
        sleep 1
done
echo 'end of script'
exit 0
root@mgmtsrv:~# ./test.sh
^CTRAPPED!
end of script
root@mgmtsrv:~#
Now, let's unset the trap:

root@mgmtsrv:~# cat test.sh
#!/bin/bash
trap 'echo TRAPPED!; break' SIGINT
while [ True ]; do
        sleep 1
done
trap - SIGINT
while [ True ]; do
        sleep 1
done
echo 'end of script'
exit 0
root@mgmtsrv:~# ./test.sh
^CTRAPPED!
^C
root@mgmtsrv:~#
So, in short: the 'trap - SIGINT' line clears the set trap :)

05 February 2014

On loopback device creation

I was having some problems with loop back device creating & almost immediately detaching; it seems sometimes a kernel thread holds on to the device and the detach fails.
I decided to have a look what's going on so I created a script which automates the creation, attaching and detaching of loopback devices:


# ./test.sh

Creating sparse 4TB file: Done
----START----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
----NEXT PASS----
Loopback devices currently in use:
/dev/loop0
Checking for free loopback device: /dev/loop1
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
----NEXT PASS----
Loopback devices currently in use:
/dev/loop0
/dev/loop1
Checking for free loopback device: /dev/loop2
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
----NEXT PASS----
Loopback devices currently in use:
/dev/loop0
/dev/loop1
/dev/loop2
Checking for free loopback device: /dev/loop3
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
----NEXT PASS----
Loopback devices currently in use:
/dev/loop0
/dev/loop1
/dev/loop2
/dev/loop3
Checking for free loopback device: /dev/loop4
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
----NEXT PASS----
Loopback devices currently in use:
/dev/loop0
/dev/loop1
/dev/loop2
/dev/loop3
/dev/loop4
Checking for free loopback device: /dev/loop5
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
----NEXT PASS----
Loopback devices currently in use:
/dev/loop0
/dev/loop1
/dev/loop2
/dev/loop3
/dev/loop4
/dev/loop5
Checking for free loopback device: /dev/loop6
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
----NEXT PASS----
Loopback devices currently in use:
/dev/loop0
/dev/loop1
/dev/loop2
/dev/loop3
/dev/loop4
/dev/loop5
/dev/loop6
Checking for free loopback device: /dev/loop7
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
----NEXT PASS----
Loopback devices currently in use:
/dev/loop0
/dev/loop1
/dev/loop2
/dev/loop3
/dev/loop4
/dev/loop5
/dev/loop6
/dev/loop7
Checking for free loopback device: losetup: could not find any free loop device
Exiting, couldn't find any free device any more.
So if done fast enough the pool quickly gets depleted as giving back (detaching) the device fails. A second or so later it might work, though. But let's test how much time exactly is needed to free the device? I modified the script to keep trying to detach/free the loopback device and see what happens:

Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 4 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 2 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 6 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 1 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 3 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 3 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.

Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 2 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 3 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 2 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 4 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 4 tries.
----NEXT PASS----
Loopback devices currently in use:

Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 1 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 5 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 10 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 2 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 4 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 4 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 3 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
Loopback device broken down after 0 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 4 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 3 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 2 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
Loopback device broken down after 0 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 1 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 3 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 2 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 1 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 2 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 1 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
Loopback device broken down after 1 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: ^C
So it varies. The device might get released instantaneously, but that doesn't happen too often, or it might take 10 consecutive tries. Let's see if allowing half a second's worth of pause in between creating and detaching fix the problem,

# ./test.sh
Creating sparse 4TB file: Done
----START----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0.5 seconds.
Breaking down loopback device:
Loopback device broken down after 0 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0.5 seconds.
Breaking down loopback device:
Loopback device broken down after 0 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0.5 seconds.
Breaking down loopback device:
Loopback device broken down after 0 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0.5 seconds.
Breaking down loopback device:
Loopback device broken down after 0 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0.5 seconds.

^C
It does, but what's holding on to the device exactly? I modified the script again to look up the did in the process table. This takes time of course, so the detaching phase took less tries to complete:

# ./test.sh
Creating sparse 4TB file: Done
----START----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
root     25417  0.0  0.0      0     0 ?        S<   13:25   0:00 [loop0]
Loopback device broken down after 1 tries.
----NEXT PASS----
Loopback devices currently in use:
Checking for free loopback device: /dev/loop0
Setting up loopback device: Done
Sleeping for 0 seconds.
Breaking down loopback device:
loop: can't delete device /dev/loop0: Device or resource busy
root     25437  0.0  0.0      0     0 ?        S<   13:25   0:00 [loop0]
Loopback device broken down after 1 tries.
----NEXT PASS----
Loopback devices currently in use:
^C
Right, so it's Linux that's holding on to it and I'm not sure if I like this behavior. I realize losetup can only request Linux to free up the device and it does cleanly report a 'Device or resource busy' but I don't understand why it just doesn't wait a bit until the resource is cleared from the kernel, or at least provides the option to the user to do so. I thought about pathing losetup but now I can't be bothered anymore, so I'm just putting it out there :)

18 December 2013

On bypassing mdadm's interactive mode

So I wanted mdadm to not go interactive, ever, but instead just bail out whenever something happens it doesn't understand; you'd think the developers would have thought of that, right? Turns out they haven't.
The 'fix' is easy enough though: pipe /bin/false through mdadm by default so it'll get a 'false' every time it would be looking for user input; effectively making it bail out whenever something's off:

alias mdadm="/bin/false | /sbin/mdadm"

04 December 2013

On quickly creating sparse and large files

I've been using dd(1) for as long as I can remember to create sparse files but for some reason I keep forgetting how to use dd's argument options so I set out to find something better... and found it: truncate(1):

From the man page: "Shrink or extend the size of each FILE to the specified size. A FILE argument that does not exist is created." -looking good:

root@debian64:~# time truncate -s 10T testfile

real0m0.003s
user0m0.000s
sys 0m0.004s

root@debian64:~# ls -l testfile
-rw-r--r-- 1 root root 10995116277760 Dec4 10:27 testfile

root@debian64:~# du -hs testfile
0 testfile

Awesome!
So then I set out to find me something to quickly allocate 'real' files:

fallocate(1):
"fallocate  is used to preallocate blocks to a file.  For filesystems which support the fallocate system call, this is done quickly by allocating blocks and marking them as uninitialized, requiring no IO to the data blocks.  This is much faster than creating a file by filling it with zeros."

And it truly is fast:


root@debian64:~# time fallocate -l 1G testfile

real    0m0.004s
user    0m0.000s
sys     0m0.000s

root@debian64:~# du -hs testfile
1.1G    testfile

root@debian64:~# ls -l testfile
-rw-r--r-- 1 root root 1073741824 Dec  4 10:34 testfile


01 October 2013

On OverlayFS and distilling patches (or: how to get OverlayFS)

So, I was looking at unionfs alternatives and I wanted to try overlayfs.
You'd think a project almost begging to be merged into mainline Linux would be interested in getting some traction amongst the "regular" Linux crowd and actually provide some patches making it relatively easy to try out the code until the time finally comes they're part of mainline, right?
Well, apparently you'd be wrong assuming that: getting a clean OverlayFS patch requires distilling a diff from a patched Linux source tree on git and that is left as an exercise to the user... or simply use Ubuntu's or SuSE's kernels (no...fucking...way) as those are already patched it seems.
Anyways, this is how to do it:

Branch overlayfs.v18 is intended to work with Linux 3.10.x:
https://git.kernel.org/cgit/linux/kernel/git/mszeredi/vfs.git/tree/Makefile?h=overlayfs.v18
Git clone the overlayfs.v18 branch:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git -b overlayfs.v18 overlayfs.v18
From the git log I got they merged Linux 3.10-rc7 so that's the branch we're going to diff to. Adding a new remote repo to the overlayfs.v18 local repo and fetching the v3.10-rc7 branch from it (git fetching won't actually change the local code!):
cd overlayfs.v18
git remote add v3.10-rc7 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux
git fetch v3.10-rc7
Now all we have to do is the actual git diff:
git diff v3.10-rc7/master...HEAD > ../overlayfs-v18.patch
So let's try to patch our Linux 3.10.12 tree :
root@bob:/usr/src/linux# patch -p1 --dry-run < ../overlayfs-v18.patch 
patching file Documentation/filesystems/Locking
patching file Documentation/filesystems/overlayfs.txt
patching file Documentation/filesystems/vfs.txt
patching file MAINTAINERS
patching file fs/Kconfig
patching file fs/Makefile
patching file fs/ecryptfs/main.c
patching file fs/internal.h
patching file fs/namei.c
patching file fs/namespace.c
patching file fs/open.c
patching file fs/overlayfs/Kconfig
patching file fs/overlayfs/Makefile
patching file fs/overlayfs/copy_up.c
patching file fs/overlayfs/dir.c
patching file fs/overlayfs/inode.c
patching file fs/overlayfs/overlayfs.h
patching file fs/overlayfs/readdir.c
patching file fs/overlayfs/super.c
patching file fs/splice.c
Hunk #1 succeeded at 1313 (offset 1 line).
patching file include/linux/fs.h
patching file include/linux/mount.h
root@bob:/usr/src/linux#

Lookin' good, w00t!

31 July 2013

On Linux patches and diffs

So you're running your own customized Linux, and want to stay up-to-date a bit, right?

root@box:/usr/src/linux# patch -p1 --dry-run < ../patch-3.10.4
patching file Documentation/i2c/busses/i2c-piix4
Reversed (or previously applied) patch detected!  Assume -R? [n] ^C

So what's happening here is that 'patch-3.10.4' from kernel.org actually is a diff from 3.10 to 3.10.4, not from 3.10.3 to 3.10.4.
This'd be fine except that you've already applied patch-3.10.3 the day before yesterday and you don't want to keep track of which patches are already applied and stuff, you just want to see whether or not the new 3.10.4 patches apply without problems.
Plus you've got other patches applied as well so you really just want to have a patch with the changes form one minor release to the other, right?
So that's where interdiff comes into play:

interdiff patch-3.10.3 patch-3.10.4 > patch-3.10.3-to-3.10.4

Now we have a patch that only includes the changes from 3.10.3 to 3.10.4 and that can be applied directly and cleanly to our already patched-with-the-previous-version-and-other-stuff-as-well Linux tree.

On apache's mod_proxy

Another short one, a warning; a 'heads up' if you will.
Took me some time to figure out that Apache's mod_proxy actually requires the proxied service to be accessible when Apache itself starts.
It seems logical enough writing it down now, but when I was configuring mod_proxy to work with apt-cacher it sure wasn't clear looking at the log files.
So when you're playing around with mod_proxy and a random to-be-proxied service, make sure to reload/restart the service first (and verify everything working alright) and only then reload Apache to take the new mod_proxy settings into effect.