jail: add option for pidfile
authorDaniel Golle <daniel@makrotopia.org>
Wed, 28 Oct 2020 00:09:51 +0000 (00:09 +0000)
committerDaniel Golle <daniel@makrotopia.org>
Wed, 28 Oct 2020 13:45:52 +0000 (13:45 +0000)
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
jail/jail.c
service/instance.c
service/instance.h

index 757f6cfc1a5824c85309ed295787294180056481..77315d23a30c9faede3a2d22c7d8b32073e543e9 100644 (file)
@@ -67,7 +67,7 @@
 #endif
 
 #define STACK_SIZE     (1024 * 1024)
-#define OPT_ARGS       "S:C:n:h:r:w:d:psulocU:G:NR:fFO:T:EyJ:i"
+#define OPT_ARGS       "S:C:n:h:r:w:d:psulocU:G:NR:fFO:T:EyJ:iP:"
 
 #define OCI_VERSION_STRING "1.0.2"
 
@@ -108,6 +108,7 @@ static struct {
        char **envp;
        char *uidmap;
        char *gidmap;
+       char *pidfile;
        struct sysctl_val **sysctl;
        int no_new_privs;
        int namespace;
@@ -276,6 +277,7 @@ static void free_opts(bool parent) {
        free(opts.gidmap);
        free(opts.annotations);
        free(opts.ocibundle);
+       free(opts.pidfile);
        free_hooklist(opts.hooks.createRuntime);
        free_hooklist(opts.hooks.createContainer);
        free_hooklist(opts.hooks.startContainer);
@@ -958,6 +960,7 @@ static void usage(void)
        fprintf(stderr, "  -y\t\tprovide jail console\n");
        fprintf(stderr, "  -J <dir>\tcreate container from OCI bundle\n");
        fprintf(stderr, "  -j\t\tstart container immediately\n");
+       fprintf(stderr, "  -P <pidfile>\tcreate <pidfile>\n");
        fprintf(stderr, "\nWarning: by default root inside the jail is the same\n\
 and he has the same powers as root outside the jail,\n\
 thus he can escape the jail and/or break stuff.\n\
@@ -2353,6 +2356,29 @@ container_handle_kill(struct ubus_context *ctx, struct ubus_object *obj,
        return UBUS_STATUS_UNKNOWN_ERROR;
 }
 
+static int
+jail_writepid(pid_t pid)
+{
+       FILE *_pidfile;
+
+       if (!opts.pidfile)
+               return 0;
+
+       _pidfile = fopen(opts.pidfile, "w");
+       if (_pidfile == NULL)
+               return errno;
+
+       if (fprintf(_pidfile, "%d\n", pid) < 0) {
+               fclose(_pidfile);
+               return errno;
+       }
+
+       if (fclose(_pidfile))
+               return errno;
+
+       return 0;
+}
+
 static struct ubus_method container_methods[] = {
        UBUS_METHOD_NOARG("start", handle_start),
        UBUS_METHOD_NOARG("state", handle_state),
@@ -2480,6 +2506,9 @@ int main(int argc, char **argv)
                case 'i':
                        opts.immediately = true;
                        break;
+               case 'P':
+                       opts.pidfile = strdup(optarg);
+                       break;
                }
        }
 
@@ -2751,6 +2780,10 @@ static void post_main(struct uloop_timeout *t)
                        netns_fd = ns_open_pid("net", jail_process.pid);
                        netns_updown(jail_process.pid, true);
                }
+               if (jail_writepid(jail_process.pid)) {
+                       ERROR("failed to write pidfile: %m\n");
+                       exit(-1);
+               }
        } else if (jail_process.pid == 0) {
                /* fork child process */
                exit(exec_jail(NULL));
index a57fe30b1045c3e34ebacbc56715a3cb2c95796c..f1242d6a5b7fa50b1f11db9bc4cf54f233ff2fac 100644 (file)
@@ -119,6 +119,7 @@ enum {
        JAIL_ATTR_CONSOLE,
        JAIL_ATTR_REQUIREJAIL,
        JAIL_ATTR_IMMEDIATELY,
+       JAIL_ATTR_PIDFILE,
        __JAIL_ATTR_MAX,
 };
 
@@ -137,6 +138,7 @@ static const struct blobmsg_policy jail_attr[__JAIL_ATTR_MAX] = {
        [JAIL_ATTR_CONSOLE] = { "console", BLOBMSG_TYPE_BOOL },
        [JAIL_ATTR_REQUIREJAIL] = { "requirejail", BLOBMSG_TYPE_BOOL },
        [JAIL_ATTR_IMMEDIATELY] = { "immediately", BLOBMSG_TYPE_BOOL },
+       [JAIL_ATTR_PIDFILE] = { "pidfile", BLOBMSG_TYPE_STRING },
 };
 
 struct instance_netdev {
@@ -311,6 +313,11 @@ jail_run(struct service_instance *in, char **argv)
        if (in->immediately)
                argv[argc++] = "-i";
 
+       if (jail->pidfile) {
+               argv[argc++] = "-P";
+               argv[argc++] = jail->pidfile;
+       }
+
        if (in->bundle) {
                argv[argc++] = "-J";
                argv[argc++] = in->bundle;
@@ -928,6 +935,9 @@ instance_config_changed(struct service_instance *in, struct service_instance *in
        if (string_changed(in->jail.hostname, in_new->jail.hostname))
                return true;
 
+       if (string_changed(in->jail.pidfile, in_new->jail.pidfile))
+               return true;
+
        if (in->jail.procfs != in_new->jail.procfs)
                return true;
 
@@ -1117,6 +1127,10 @@ instance_jail_parse(struct service_instance *in, struct blob_attr *attr)
                jail->console = true;
                jail->argc++;
        }
+       if (tb[JAIL_ATTR_PIDFILE]) {
+               jail->pidfile = strdup(blobmsg_get_string(tb[JAIL_ATTR_PIDFILE]));
+               jail->argc += 2;
+       }
 
        if (tb[JAIL_ATTR_MOUNT]) {
                struct blob_attr *cur;
@@ -1447,6 +1461,7 @@ instance_config_move(struct service_instance *in, struct service_instance *in_sr
        instance_config_move_strdup(&in->group, in_src->group);
        instance_config_move_strdup(&in->jail.name, in_src->jail.name);
        instance_config_move_strdup(&in->jail.hostname, in_src->jail.hostname);
+       instance_config_move_strdup(&in->jail.pidfile, in_src->jail.pidfile);
 
        free(in->config);
        in->config = in_src->config;
@@ -1490,6 +1505,7 @@ instance_free(struct service_instance *in)
        free(in->bundle);
        free(in->jail.name);
        free(in->jail.hostname);
+       free(in->jail.pidfile);
        free(in->seccomp);
        free(in->capabilities);
        free(in->pidfile);
@@ -1640,6 +1656,9 @@ void instance_dump(struct blob_buf *b, struct service_instance *in, int verbose)
                        blobmsg_add_u8(b, "userns", in->jail.userns);
                        blobmsg_add_u8(b, "cgroupsns", in->jail.cgroupsns);
                } else {
+                       if (in->jail.pidfile)
+                               blobmsg_add_string(b, "pidfile", in->jail.pidfile);
+
                        blobmsg_add_u8(b, "immediately", in->immediately);
                }
                blobmsg_add_u8(b, "console", (in->console.fd.fd > -1));
index 09fbb5d0c65133438dbff487ede04366d6321e4b..bbd943c28ac2965f9f221db893b214b4815033f5 100644 (file)
@@ -35,6 +35,7 @@ struct jail {
        bool console;
        char *name;
        char *hostname;
+       char *pidfile;
        struct blobmsg_list mount;
        int argc;
 };