diff --git a/lib/libfrr.c b/lib/libfrr.c index 821c57f37b..115c70f7c9 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -262,12 +262,39 @@ bool frr_zclient_addr(struct sockaddr_storage *sa, socklen_t *sa_len, static struct frr_daemon_info *di = NULL; +static void frr_guard_daemon(void) +{ + int fd; + struct flock lock; + + const char *path = di->pid_file; + fd = open(path, O_RDWR); + if (fd != -1) { + memset(&lock, 0, sizeof(lock)); + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + if (fcntl(fd, F_GETLK, &lock) < 0) { + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "Could not do F_GETLK pid_file %s (%s), exiting", + path, safe_strerror(errno)); + exit(1); + } else if (lock.l_type == F_WRLCK) { + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "Process %d has a write lock on file %s already! Error : ( %s)", + lock.l_pid, path, safe_strerror(errno)); + exit(1); + } + close(fd); + } +} + void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv) { di = daemon; /* basename(), opencoded. */ char *p = strrchr(argv[0], '/'); + di->progname = p ? p + 1 : argv[0]; umask(0027); @@ -589,6 +616,9 @@ struct thread_master *frr_init(void) zprivs_init(di->privs); + /* Guard to prevent a second instance of this daemon */ + frr_guard_daemon(); + master = thread_master_create(NULL); signal_init(master, di->n_signals, di->signals);