Index: lib/libutil/libutil.h =================================================================== --- lib/libutil/libutil.h +++ lib/libutil/libutil.h @@ -122,6 +122,7 @@ struct termios *_termp, struct winsize *_winp); int pidfile_close(struct pidfh *_pfh); int pidfile_fileno(const struct pidfh *_pfh); +int pidfile_signal(const char *pathp, int sig, pid_t *pidptr); struct pidfh * pidfile_open(const char *_path, mode_t _mode, pid_t *_pidptr); int pidfile_remove(struct pidfh *_pfh); Index: lib/libutil/pidfile.c =================================================================== --- lib/libutil/pidfile.c +++ lib/libutil/pidfile.c @@ -74,7 +74,7 @@ } static int -pidfile_read(int dirfd, const char *filename, pid_t *pidptr) +pidfile_read_impl(int dirfd, const char *filename, pid_t *pidptr) { char buf[16], *endptr; int error, fd, i; @@ -99,14 +99,33 @@ return (0); } +static int +pidfile_read(int dirfd, const char *filename, pid_t *pidptr) +{ + struct timespec rqtp; + int count; + + count = 20; + rqtp.tv_sec = 0; + rqtp.tv_nsec = 5000000; + for (;;) { + errno = pidfile_read_impl(dirfd, filename, pidptr); + if (errno != EAGAIN || --count == 0) + break; + nanosleep(&rqtp, 0); + } + if (errno == EAGAIN) + *pidptr = -1; + return (errno); +} + struct pidfh * pidfile_open(const char *pathp, mode_t mode, pid_t *pidptr) { char path[MAXPATHLEN]; struct pidfh *pfh; struct stat sb; - int error, fd, dirfd, dirlen, filenamelen, count; - struct timespec rqtp; + int error, fd, dirfd, dirlen, filenamelen; cap_rights_t caprights; pfh = malloc(sizeof(*pfh)); @@ -159,18 +178,8 @@ if (pidptr == NULL) { errno = EEXIST; } else { - count = 20; - rqtp.tv_sec = 0; - rqtp.tv_nsec = 5000000; - for (;;) { - errno = pidfile_read(dirfd, - pfh->pf_filename, pidptr); - if (errno != EAGAIN || --count == 0) - break; - nanosleep(&rqtp, 0); - } - if (errno == EAGAIN) - *pidptr = -1; + errno = pidfile_read(dirfd, + pfh->pf_filename, pidptr); if (errno == 0 || errno == EAGAIN) errno = EEXIST; } @@ -330,3 +339,32 @@ } return (pfh->pf_fd); } + +int +pidfile_signal(const char *pathp, int sig, pid_t *pidptr) +{ + pid_t pid; + int fd; + + fd = flopenat(AT_FDCWD, pathp, + O_RDONLY | O_CLOEXEC | O_NONBLOCK); + if (fd >= 0) { + /* + * The file exists but is not locked, + * so the daemon is dead. Nothing to do. + */ + close(fd); + errno = ENOENT; + return (errno); + } + if (errno != EWOULDBLOCK) { + return (errno); + } + errno = pidfile_read(AT_FDCWD, pathp, &pid); + if (errno != 0) + return (errno); + kill(pid, sig); + if (pidptr != NULL) + *pidptr = pid; + return (errno); +} Index: sbin/mount/mount.c =================================================================== --- sbin/mount/mount.c +++ sbin/mount/mount.c @@ -207,33 +207,8 @@ static void restart_mountd(void) { - struct pidfh *pfh; - pid_t mountdpid; - - mountdpid = 0; - pfh = pidfile_open(_PATH_MOUNTDPID, 0600, &mountdpid); - if (pfh != NULL) { - /* Mountd is not running. */ - pidfile_remove(pfh); - return; - } - if (errno != EEXIST) { - /* Cannot open pidfile for some reason. */ - return; - } - - /* - * Refuse to send broadcast or group signals, this has - * happened due to the bugs in pidfile(3). - */ - if (mountdpid <= 0) { - xo_warnx("mountd pid %d, refusing to send SIGHUP", mountdpid); - return; - } - /* We have mountd(8) PID in mountdpid varible, let's signal it. */ - if (kill(mountdpid, SIGHUP) == -1) - xo_err(1, "signal mountd"); + pidfile_signal(_PATH_MOUNTDPID, SIGHUP, NULL); } int