From: Michael Tremer Date: Tue, 2 Aug 2022 11:07:47 +0000 (+0000) Subject: jail: Make the client process wait until the parent has finished initialization X-Git-Tag: 0.9.28~637 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=43dc0e16073ff7d5508ad8a5a9a11b557557a67c;p=pakfire.git jail: Make the client process wait until the parent has finished initialization Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/jail.c b/src/libpakfire/jail.c index e4b4798d2..305a912ab 100644 --- a/src/libpakfire/jail.c +++ b/src/libpakfire/jail.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -284,10 +285,32 @@ static int pakfire_jail_setup_gid_mapping(struct pakfire_jail* jail, pid_t pid) return pakfire_jail_write_uidgid_mapping(jail, path, mapped_gid, length); } +static int pakfire_jail_send_signal(struct pakfire_jail* jail, int fd) { + const int val = 1; + + DEBUG(jail->pakfire, "Sending signal...\n"); + + write(fd, &val, sizeof(val)); + close(fd); + + return 0; +} + +static int pakfire_jail_wait_for_signal(struct pakfire_jail* jail, int fd) { + int val = 0; + + DEBUG(jail->pakfire, "Waiting for signal...\n"); + + read(fd, &val, sizeof(val)); + close(fd); + + return 0; +} + /* Performs the initialisation that needs to happen in the parent part */ -static int pakfire_jail_parent(struct pakfire_jail* jail, pid_t pid) { +static int pakfire_jail_parent(struct pakfire_jail* jail, pid_t pid, int completed_fd) { int r; // Setup UID mapping @@ -300,14 +323,29 @@ static int pakfire_jail_parent(struct pakfire_jail* jail, pid_t pid) { if (r) return r; + // Parent has finished initialisation + DEBUG(jail->pakfire, "Parent has finished initialization\n"); + + // Send signal to client + r = pakfire_jail_send_signal(jail, completed_fd); + if (r) + return r; + return 0; } -static int pakfire_jail_child(struct pakfire_jail* jail, const char* argv[]) { +static int pakfire_jail_child(struct pakfire_jail* jail, const char* argv[], int completed_fd) { + int r; + // XXX do we have to reconfigure logging here? DEBUG(jail->pakfire, "Launched child process in jail with PID %d\n", getpid()); + // Wait for the parent to finish initialization + r = pakfire_jail_wait_for_signal(jail, completed_fd); + if (r) + return r; + return 0; } @@ -317,6 +355,16 @@ int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[]) { DEBUG(jail->pakfire, "Executing jail...\n"); + /* + Setup a file descriptor which can be used to notify the client that the parent + has completed configuration. + */ + int completed_fd = eventfd(0, EFD_CLOEXEC); + if (completed_fd < 0) { + ERROR(jail->pakfire, "eventfd() failed: %m\n"); + return -1; + } + // Configure child process struct clone_args args = { .flags = @@ -337,12 +385,12 @@ int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[]) { // Child process } else if (pid == 0) { - r = pakfire_jail_child(jail, argv); + r = pakfire_jail_child(jail, argv, completed_fd); _exit(r); } // Parent process - r = pakfire_jail_parent(jail, pid); + r = pakfire_jail_parent(jail, pid, completed_fd); if (r) goto ERROR; @@ -369,6 +417,5 @@ int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[]) { return exit; ERROR: - return -1; }