munin-monitoring/munin — pull request #159 by grooverdan (2014-01-24 01:28:34+00:00)
Title: remove several race conditions around lock file by opening it once

During a strace of munin-limits and munin-update I saw several race conditions around the locking mechanism:

stat("/usr/local/munin/openquery/var/run/munin-master-processmanager-26029.sock", 0x1e42130) = -1 ENOENT (No such file or directory)
socket(PF_FILE, SOCK_STREAM, 0) = 6
ioctl(6, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffefdb98b0) = -1 ENOTTY (Inappropriate ioctl for device)
lseek(6, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
ioctl(6, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffefdb98b0) = -1 ENOTTY (Inappropriate ioctl for device)
lseek(6, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
fcntl(6, F_SETFD, FD_CLOEXEC) = 0
bind(6, {sa_family=AF_FILE, path="/usr/local/munin/openquery/var/run/munin-master-processmanager-26029.sock"}, 110) = 0
chmod("/usr/local/munin/openquery/var/run/munin-master-processmanager-26029.sock", 0700) = 0

....
....
stat("/usr/local/munin/openquery/var/run/munin-datafile.lock", 0x1e42130) = -1 ENOENT (No such file or directory)
open("/usr/local/munin/openquery/var/run/munin-datafile.lock", O_WRONLY|O_CREAT|O_EXCL, 0666) = 6
....
unlink("/usr/local/munin/openquery/var/run/munin-datafile.lock") = 0

While the comment in munin_getlock reflects one behavior, this may not be the case. I'm currently using munin-update/munin-limits in a ssh forced command after an ssh-rsync across.

# To check this is inteligent and so on. It also makes for a
# nice locking racing-condition. BUT, since munin-* runs from
# cron every 5 minutes this should not be a real threat. This
# ream of code should complete in less than 5 minutes.

The attached code opens the file once for read/write, and closes with the PID written in or fails.