diff --git a/conf.c b/conf.c index 4960c68..db9c350 100644 --- a/conf.c +++ b/conf.c @@ -565,6 +565,7 @@ static void usage(const char *name) else info(" /tmp/passt_ISO8601-TIMESTAMP_INSTANCE-NUMBER.pcap"); + info( " -P, --pid FILE Write own PID to the given file"); info( " -m, --mtu MTU Assign MTU via DHCP/NDP"); info( " a zero value disables assignment"); info( " default: 65520: maximum 802.3 MTU minus 802.3 header"); @@ -764,6 +765,7 @@ void conf(struct ctx *c, int argc, char **argv) {"socket", required_argument, NULL, 's' }, {"ns-ifname", required_argument, NULL, 'I' }, {"pcap", optional_argument, NULL, 'p' }, + {"pid", required_argument, NULL, 'P' }, {"mtu", required_argument, NULL, 'm' }, {"address", required_argument, NULL, 'a' }, {"netmask", required_argument, NULL, 'n' }, @@ -807,9 +809,9 @@ void conf(struct ctx *c, int argc, char **argv) const char *optstring; if (c->mode == MODE_PASST) - optstring = "dqfehs:p::m:a:n:M:g:i:D::S::46t:u:"; + optstring = "dqfehs:p::P:m:a:n:M:g:i:D::S::46t:u:"; else - optstring = "dqfehI:p::m:a:n:M:g:i:D::S::46t:u:T:U:"; + optstring = "dqfehI:p::P:m:a:n:M:g:i:D::S::46t:u:T:U:"; name = getopt_long(argc, argv, optstring, options, NULL); @@ -949,6 +951,19 @@ void conf(struct ctx *c, int argc, char **argv) usage(argv[0]); } break; + case 'P': + if (*c->pid_file) { + err("Multiple --pid options given"); + usage(argv[0]); + } + + ret = snprintf(c->pid_file, sizeof(c->pid_file), "%s", + optarg); + if (ret <= 0 || ret >= (int)sizeof(c->pid_file)) { + err("Invalid PID file: %s", optarg); + usage(argv[0]); + } + break; case 'm': if (c->mtu) { err("Multiple --mtu options given"); diff --git a/passt.1 b/passt.1 index 3355bff..c161586 100644 --- a/passt.1 +++ b/passt.1 @@ -106,6 +106,11 @@ in \fBpasst\fR mode and to in \fBpasta\fR mode, where \fIinstance-number\fR is a progressive count of other detected instances running on the same host. +.TP +.BR \-P ", " \-\-pid " " \fIfile +Write own PID to \fIfile\fR once initialisation is done, before forking to +background (if configured to do so). + .TP .BR \-m ", " \-\-mtu " " \fImtu Assign \fImtu\fR via DHCP (option 26) and NDP (option type 5). diff --git a/passt.c b/passt.c index 48c2649..2217dd7 100644 --- a/passt.c +++ b/passt.c @@ -227,6 +227,27 @@ static void drop_caps(void) } } +/** + * pid_file() - Write own PID to file, if configured + * @c: Execution context + */ +static void pid_file(struct ctx *c) { + char pid_buf[12]; + int pid_fd, n; + + if (!c->pid_file) + return; + + pid_fd = open(c->pid_file, O_CREAT | O_WRONLY); + if (pid_fd < 0) + return; + + n = snprintf(pid_buf, sizeof(pid_buf), "%i\n", getpid()); + + write(pid_fd, pid_buf, n); + close(pid_fd); +} + /** * main() - Entry point and main loop * @argc: Argument count @@ -237,7 +258,7 @@ static void drop_caps(void) * #syscalls read write open close fork dup2 exit chdir ioctl writev syslog * #syscalls prlimit64 epoll_ctl epoll_create1 epoll_wait accept4 accept listen * #syscalls socket bind connect getsockopt setsockopt recvfrom sendto shutdown - * #syscalls openat fstat fcntl lseek clone setsid exit_group + * #syscalls openat fstat fcntl lseek clone setsid exit_group getpid * #syscalls:pasta rt_sigreturn */ int main(int argc, char **argv) @@ -327,6 +348,8 @@ int main(int argc, char **argv) if (isatty(fileno(stdout)) && !c.foreground) daemon(0, 0); + pid_file(&c); + timer_init(&c, &now); loop: nfds = epoll_wait(c.epollfd, events, EPOLL_EVENTS, TIMER_INTERVAL); diff --git a/passt.h b/passt.h index e2bfe9d..9e33436 100644 --- a/passt.h +++ b/passt.h @@ -91,6 +91,7 @@ enum passt_modes { * @stderr: Force logging to stderr * @sock_path: Path for UNIX domain socket * @pcap: Path for packet capture file + * @pid_file: Path to PID file, empty string if not configured * @pasta_netns_fd: File descriptor for network namespace in pasta mode * @pasta_userns_fd: File descriptor for user namespace in pasta mode * @netns_only: In pasta mode, don't join or create a user namespace @@ -142,6 +143,7 @@ struct ctx { int stderr; char sock_path[UNIX_PATH_MAX]; char pcap[PATH_MAX]; + char pid_file[PATH_MAX]; int pasta_netns_fd; int pasta_userns_fd;