Re: Patch for rc.d/devd on FreeBSD 9-current

From: M. Warner Losh <imp_at_bsdimp.com>
Date: Mon, 28 Jun 2010 08:14:58 -0600 (MDT)
In message: <86mxuf7eli.fsf_at_ds4.des.no>
            Dag-Erling Smørgrav <des_at_des.no> writes:
: "M. Warner Losh" <imp_at_bsdimp.com> writes:
: > Why not fix pidfile_open to not return a file handle when the PID
: > doesn't match?
: 
: It doesn't.  If it can't lock the file, or if fstat(2) fails after it
: has locked the file, it returns NULL.

Then we have a bug in the locking code.  I've definitely seen things
fail to behave properly after killing devd.  Let me trace out what I
think is going on:

From pidfile_open:
	/*
	 * Open the PID file and obtain exclusive lock.
	 * We truncate PID file here only to remove old PID immediatelly,
	 * PID file will be truncated again in pidfile_write(), so
	 * pidfile_write() can be called multiple times.
	 */
	fd = flopen(pfh->pf_path,
	    O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK, mode);
	if (fd == -1) {
---> We take this path, fd == -1.
		count = 0;
		rqtp.tv_sec = 0;
		rqtp.tv_nsec = 5000000;
		if (errno == EWOULDBLOCK && pidptr != NULL) {
		again:
---> and this one, so errno is EWOULDBLOCK
			errno = pidfile_read(pfh->pf_path, pidptr);
---> errno is 0 here, so
			if (errno == 0)
				errno = EEXIST;
---> We return NULL with errno set toEEXIST 
			else if (errno == EAGAIN) {
				if (++count <= 3) {
					nanosleep(&rqtp, 0);
					goto again;
				}
			}
		}
		free(pfh);
		return (NULL);
	}

So what's going on?

Warner
Received on Mon Jun 28 2010 - 12:20:49 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:05 UTC