#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"
char **envp;
char *uidmap;
char *gidmap;
+ char *pidfile;
struct sysctl_val **sysctl;
int no_new_privs;
int namespace;
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);
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\
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),
case 'i':
opts.immediately = true;
break;
+ case 'P':
+ opts.pidfile = strdup(optarg);
+ break;
}
}
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));
JAIL_ATTR_CONSOLE,
JAIL_ATTR_REQUIREJAIL,
JAIL_ATTR_IMMEDIATELY,
+ JAIL_ATTR_PIDFILE,
__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 {
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;
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;
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;
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;
free(in->bundle);
free(in->jail.name);
free(in->jail.hostname);
+ free(in->jail.pidfile);
free(in->seccomp);
free(in->capabilities);
free(in->pidfile);
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));