From e2a55139adb3f97043cb6436a11e2f4055a44ddd Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Tue, 18 Jun 2024 22:55:26 +0200 Subject: [PATCH] fixup! Add init groups. --- init/init.c | 2 +- kernel/include/sortix/kernel/syscall.h | 2 +- kernel/process.cpp | 8 +-- libc/Makefile | 2 + libc/include/unistd.h | 2 +- libc/unistd/getinit.2 | 1 + libc/unistd/getinit.c | 7 ++- libc/unistd/setinit.2 | 73 ++++++++++++++++++++++++++ utils/halt.c | 2 +- utils/poweroff.c | 2 +- utils/reboot.c | 2 +- 11 files changed, 90 insertions(+), 13 deletions(-) create mode 120000 libc/unistd/getinit.2 create mode 100644 libc/unistd/setinit.2 diff --git a/init/init.c b/init/init.c index 09fa6522..9b9620eb 100644 --- a/init/init.c +++ b/init/init.c @@ -4297,7 +4297,7 @@ int main(int argc, char* argv[]) } // Prevent recursive init without care. - if ( getinit() != getpid() ) + if ( getinit(0) != getpid() ) fatal("System is already managed by an init process"); // Register handler that shuts down the system when init exits. diff --git a/kernel/include/sortix/kernel/syscall.h b/kernel/include/sortix/kernel/syscall.h index 07ba78bd..a666526d 100644 --- a/kernel/include/sortix/kernel/syscall.h +++ b/kernel/include/sortix/kernel/syscall.h @@ -97,7 +97,7 @@ int sys_getentropy(void*, size_t); uid_t sys_geteuid(void); gid_t sys_getgid(void); int sys_gethostname(char*, size_t); -pid_t sys_getinit(void); +pid_t sys_getinit(pid_t); size_t sys_getpagesize(void); int sys_getpeername(int, void*, size_t*); pid_t sys_getpgid(pid_t); diff --git a/kernel/process.cpp b/kernel/process.cpp index 54de4fc9..0a101bf6 100644 --- a/kernel/process.cpp +++ b/kernel/process.cpp @@ -1624,7 +1624,8 @@ pid_t sys_getpgid(pid_t pid) pid_t sys_getsid(pid_t pid) { ScopedLock lock(&process_family_lock); - Process* process = !pid ? CurrentProcess() : CurrentProcess()->GetPTable()->Get(pid); + Process* process = + !pid ? CurrentProcess() : CurrentProcess()->GetPTable()->Get(pid); if ( !process ) return errno = ESRCH, -1; if ( !process->session ) @@ -1632,10 +1633,11 @@ pid_t sys_getsid(pid_t pid) return process->session->pid; } -pid_t sys_getinit(void) +pid_t sys_getinit(pid_t pid) { ScopedLock lock(&process_family_lock); - Process* process = CurrentProcess(); + Process* process = + !pid ? CurrentProcess() : CurrentProcess()->GetPTable()->Get(pid); if ( !process->init ) return errno = ESRCH, -1; return process->init->pid; diff --git a/libc/Makefile b/libc/Makefile index 6c0e18d3..79f4eb35 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -781,6 +781,8 @@ MANPAGES2=\ scram/scram.2 \ sys/dnsconfig/getdnsconfig.2 \ sys/dnsconfig/setdnsconfig.2 \ +unistd/setinit.2 \ +unistd/getinit.2 \ MANPAGES3=\ time/add_leap_seconds.3 \ diff --git a/libc/include/unistd.h b/libc/include/unistd.h index 783ed7a4..492be007 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -562,7 +562,7 @@ int exit_thread(int, int, const struct exit_thread*); int fchdirat(int, const char*); int fchroot(int); int fchrootat(int, const char*); -pid_t getinit(void); +pid_t getinit(pid_t); int memstat(size_t* memused, size_t* memtotal); int mkpartition(int fd, off_t start, off_t length); pid_t setinit(void); diff --git a/libc/unistd/getinit.2 b/libc/unistd/getinit.2 new file mode 120000 index 00000000..e304056e --- /dev/null +++ b/libc/unistd/getinit.2 @@ -0,0 +1 @@ +setinit.2 \ No newline at end of file diff --git a/libc/unistd/getinit.c b/libc/unistd/getinit.c index 006987d7..23908e98 100644 --- a/libc/unistd/getinit.c +++ b/libc/unistd/getinit.c @@ -21,10 +21,9 @@ #include -DEFN_SYSCALL0(pid_t, sys_getinit, SYSCALL_GETINIT); +DEFN_SYSCALL1(pid_t, sys_getinit, SYSCALL_GETINIT, pid_t); -// TODO: Should this accept a pid like getsid? -pid_t getinit(void) +pid_t getinit(pid_t pid) { - return sys_getinit(); + return sys_getinit(pid); } diff --git a/libc/unistd/setinit.2 b/libc/unistd/setinit.2 new file mode 100644 index 00000000..e2896524 --- /dev/null +++ b/libc/unistd/setinit.2 @@ -0,0 +1,73 @@ +.Dd June 18, 2024 +.Dt SETINIT 2 +.Os +.Sh NAME +.Nm setinit +.Nd become and locate init +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn getinit "pid_t pid" +.Ft int +.Fn setinit void +.Sh DESCRIPTION +.Fn setinit +sets the current process as the init process for itself and its subsequently +created descendant processes. +.Fn setinit +runs +.Xr setsid 2 +to create a new session (and process group) and can fail for the same reasons as +.Xr setsid 2 . +.Pp +.Fn getinit +returns the init process for the process specified in +.Fa pid , +or the current process if +.Fa pid +is zero. +.Pp +Orphaned descendant processes are reparanted to their init process. +If an init process exits, all descendant processes atomically receive the +.Dv SIGKILL +signal and become unable to create new processes and threads. +.Sh RETURN VALUES +.Fn setinit +returns the pid of the init process (the current process) on success, or -1 on +error and +.Va error +is set appropriately. +.Pp +.Fn getinit +returns the returns the pid of the init process, or -1 on +error and +.Va error +is set appropriately. +.Sh ERRORS +.Fn setinit +will fail if: +.Bl -tag -width "12345678" +.It Er EPERM +The process is already a process group leader, a session leader, or an init +process. +.El +.Pp +.Fn getinit +will fail if: +.Bl -tag -width "12345678" +.It Er ESRCH +The process specified in +.Fa pid +does not exist. +.Sh SEE ALSO7 +.Xr getpgrp 2 , +.Xr getsid 2 , +.Xr init 8 +.Xr setpgrp 2 , +.Xr setsid 2 , +.Sh HISTORY +The +.Fn getinit +and +.Fn setinit +system calls originally appeared in Sortix 1.1. diff --git a/utils/halt.c b/utils/halt.c index 25f6a4db..291f8772 100644 --- a/utils/halt.c +++ b/utils/halt.c @@ -39,7 +39,7 @@ int main(int argc, char* argv[]) if ( optind < argc ) errx(1, "extra operand: %s", argv[optind]); - pid_t init_pid = getinit(); + pid_t init_pid = getinit(0); if ( kill(init_pid, SIGQUIT) < 0 ) err(1, "kill: %" PRIdPID, init_pid); diff --git a/utils/poweroff.c b/utils/poweroff.c index a634b677..560d45ef 100644 --- a/utils/poweroff.c +++ b/utils/poweroff.c @@ -39,7 +39,7 @@ int main(int argc, char* argv[]) if ( optind < argc ) errx(1, "extra operand: %s", argv[optind]); - pid_t init_pid = getinit(); + pid_t init_pid = getinit(0); if ( kill(init_pid, SIGTERM) < 0 ) err(1, "kill: %" PRIdPID, init_pid); diff --git a/utils/reboot.c b/utils/reboot.c index dd1bbfaa..1bb7abf0 100644 --- a/utils/reboot.c +++ b/utils/reboot.c @@ -39,7 +39,7 @@ int main(int argc, char* argv[]) if ( optind < argc ) errx(1, "extra operand: %s", argv[optind]); - pid_t init_pid = getinit(); + pid_t init_pid = getinit(0); if ( kill(init_pid, SIGINT) < 0 ) err(1, "kill: %" PRIdPID, init_pid);