Re: /etc/rc.d locking devd.pid (was Re: Restarting devd)

From: Kostik Belousov <kostikbel_at_gmail.com>
Date: Mon, 19 Oct 2009 01:09:35 +0300
On Sun, Oct 18, 2009 at 03:54:52PM -0600, Warren Block wrote:
> On Sat, 17 Oct 2009, Warren Block wrote:
> 
> >Immediately after boot, devd restart fails:
> >
> ># /etc/rc.d/devd restart
> >Stopping devd.
> >Starting devd.
> >devd: devd already running, pid: 398
> >/etc/rc.d/devd: WARNING: failed to start devd
> >
> >And it's right, devd is not running.  Remove the stale pidfile 
> >/var/run/devd.pid, and '/etc/rc.d/devd start' goes fine.
> 
> ...and this is due to dhclient, run from /etc/rc.d at startup, locking 
> /var/run/devd.pid:
> 
> lightning% lsof /var/run/devd.pid
> COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
> devd      400  root    6w  VREG  0,101        3 47124 /var/run/devd.pid
> dhclient  865  root    6w  VREG  0,101        3 47124 /var/run/devd.pid
> dhclient 1024 _dhcp    6w  VREG  0,101        3 47124 /var/run/devd.pid
> 
> This is a regression from 7-STABLE, where devd.pid is only locked by 
> devd after startup.

Devd forks to spawn dhclient, it seems, and opened file descriptor for
the lock file is leaking to the child. Since pidfile(3) uses flock(2),
the lock survives devd death.

I think that this is a generic issue with pidfile/fork interaction.
It is not obvious whether setting FD_CLOEXEC flag is right thing to
do there.

Anyway, please test.

diff --git a/lib/libutil/flopen.c b/lib/libutil/flopen.c
index 754c9c0..a5e436e 100644
--- a/lib/libutil/flopen.c
+++ b/lib/libutil/flopen.c
_at__at_ -100,6 +100,12 _at__at_ flopen(const char *path, int flags, ...)
 			errno = serrno;
 			return (-1);
 		}
+		if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
+			serrno = errno;
+			(void)close(fd);
+			errno = serrno;
+			return (-1);
+		}
 		return (fd);
 	}
 }

Received on Sun Oct 18 2009 - 20:09:40 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:57 UTC