[CRIU] [PATCH 1/4] join-ns: add join-ns option to criu CLI and RPC
Pavel Emelyanov
xemul at virtuozzo.com
Mon Apr 4 04:19:41 PDT 2016
> @@ -473,6 +479,10 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
> }
> }
>
> + /* check namespace flags here */
This comment is useless.
> + if (check_namespace_opts())
> + goto err;
> +
> return 0;
>
> err:
> diff --git a/criu/crtools.c b/criu/crtools.c
> index 537bcc9..5e9085a 100644
> --- a/criu/crtools.c
> +++ b/criu/crtools.c
> @@ -19,6 +21,24 @@ struct ns_desc {
> size_t len;
> };
>
> +struct user_ns_extra {
> + char *uid;
> + char *gid;
> +};
> +
> +/* struct join_ns is used for storing parameters specified by --join-ns */
> +struct join_ns {
> + struct list_head list;
> + char *ns_file;
> + struct ns_desc *nd; /* namespace descriptor */
> + int ns_fd;
> + /* extra options of --join-ns, like uid&gid in user namespace */
> + union {
> + struct user_ns_extra user_extra;
> + char *common_extra;
> + }extra_opts;
Space is needed after }.
> +};
> +
> enum ns_type {
> NS_UNKNOWN = 0,
> NS_CRIU,
> @@ -70,6 +90,7 @@ extern bool check_ns_proc(struct fd_link *link);
> extern struct ns_desc pid_ns_desc;
> extern struct ns_desc user_ns_desc;
> extern unsigned long root_ns_mask;
> +extern unsigned int join_ns_flags;
>
> extern const struct fdtype_ops nsfile_dump_ops;
> extern struct collect_image_info nsfile_cinfo;
> @@ -100,6 +121,8 @@ extern gid_t userns_gid(gid_t gid);
>
> extern int dump_user_ns(pid_t pid, int ns_id);
> extern void free_userns_maps(void);
> +extern int join_ns_add(const char *type, char *ns_file, char *extra_opts);
> +extern int check_namespace_opts();
>
> typedef int (*uns_call_t)(void *arg, int fd, pid_t pid);
> /*
> diff --git a/criu/namespaces.c b/criu/namespaces.c
> index 724203e..6994cf0 100644
> --- a/criu/namespaces.c
> +++ b/criu/namespaces.c
> @@ -10,7 +10,11 @@
> #include <signal.h>
> #include <sched.h>
> #include <sys/capability.h>
> +#include <sys/stat.h>
> +#include <limits.h>
> +#include <errno.h>
>
> +#include "cr_options.h"
> #include "util.h"
> #include "imgset.h"
> #include "uts_ns.h"
> @@ -35,6 +39,146 @@ static struct ns_desc *ns_desc_array[] = {
> &cgroup_ns_desc,
> };
>
> +unsigned int join_ns_flags = 0;
This variable is only read in patch #3, but the patch itself looks
unneeded (see comment to it), so the whole join_ns_flags becomes
unneeded too.
> +
> +int check_namespace_opts() {
{ should go on separate line. We used Linux kernel coding style, you can
check your patches to fit one with linux/scripts/checkpatch.pl
> + errno = 22;
> + if (join_ns_flags & opts.rst_namespaces_flags) {
> + pr_perror("Conflict flags: -join-ns and -namespace");
> + return -1;
> + }
> + if (join_ns_flags & opts.empty_ns) {
> + pr_perror("Conflict flags: -join-ns and -empty-ns");
> + return -1;
> + }
> + if (opts.empty_ns & opts.rst_namespaces_flags) {
> + pr_perror("Conflict flags: -empty-ns and -namespace");
> + return -1;
> + }
> + errno = 0;
> + return 0;
> +}
> +
> +static int check_int_str(char *str) {
Same here -- { on separate line.
> + if (str == NULL)
> + return 0;
> +
> + if (*str == '\0') {
> + str = NULL;
> + return 0;
> + }
> +
> + char *endptr;
> + long val;
Variable declaration should be done before any code.
> + errno = 22;
> + val = strtol(str, &endptr, 10);
> + if ((errno == ERANGE) || (endptr == str)
> + || (*endptr != '\0')
> + || (val < 0) || (val > 65535)) {
> + str = NULL;
> + return -1;
> + }
> +
> + errno = 0;
> + return 0;
> +}
> +
> +static int check_ns_file(char *ns_file) {
{ on separate line
> + int pid, ret, proc_dir;
> +
> + if (!check_int_str(ns_file)) {
> + pid = atoi(ns_file);
> + if (pid <= 0) {
> + pr_perror("Invalid join_ns pid %s", ns_file);
> + return -1;
> + }
> + proc_dir = open_pid_proc(pid);
> + if (proc_dir < 0) {
> + pr_perror("Invalid join_ns pid: /proc/%s not found", ns_file);
> + return -1;
> + }
> + return 0;
> + }
> +
> + ret = access(ns_file, 0);
> + if (ret < 0) {
> + pr_perror("Can't access join-ns file: %s", ns_file);
> + return -1;
> + }
> + return 0;
> +}
> +
> +static int set_user_extra_opts(struct join_ns *jn, char *extra_opts) {
{ on separate line
> + char *uid, *gid, *aux;
> + if (extra_opts == NULL) {
> + jn->extra_opts.user_extra.uid = NULL;
> + jn->extra_opts.user_extra.gid = NULL;
> + return 0;
> + }
> +
> + uid = extra_opts;
> + aux = strchr(extra_opts, ',');
> + if (aux == NULL) {
> + gid = NULL;
> + } else {
> + *aux = '\0';
> + gid = aux + 1;
> + }
> +
> + if (check_int_str(uid) || check_int_str(gid)) {
> + return -1;
> + }
> + jn->extra_opts.user_extra.uid = uid;
> + jn->extra_opts.user_extra.gid = gid;
> +
> + return 0;
> +}
> +
> +int join_ns_add(const char *type, char *ns_file, char *extra_opts) {
{ on separate line
> + struct join_ns *jn;
> +
> + jn = xmalloc(sizeof(*jn));
> + if (!jn) {
> + return -1;
> + }
> +
> + if (check_ns_file(ns_file)) {
> + return -1;
> + }
> +
> + jn->ns_file = ns_file;
> + if (!strncmp(type, "net", 4)) {
> + jn->nd = &net_ns_desc;
> + join_ns_flags |= CLONE_NEWNET;
> + } else if (!strncmp(type, "uts", 4)) {
> + jn->nd = &uts_ns_desc;
> + join_ns_flags |= CLONE_NEWUTS;
> + } else if (!strncmp(type, "ipc", 4)) {
> + jn->nd = &ipc_ns_desc;
> + join_ns_flags |= CLONE_NEWIPC;
> + } else if (!strncmp(type, "pid", 4)) {
> + jn->nd = &pid_ns_desc;
> + join_ns_flags |= CLONE_NEWPID;
Here we should abort with error, you wrote that joining pidns doesn't work.
> + } else if (!strncmp(type, "user", 5)) {
> + jn->nd = &user_ns_desc;
> + if (set_user_extra_opts(jn, extra_opts)) {
> + pr_perror("invalid user namespace extra_opts %s\n", extra_opts);
> + return -1;
> + }
> + join_ns_flags |= CLONE_NEWUSER;
> + } else if (!strncmp(type, "mnt", 4)) {
> + jn->nd = &mnt_ns_desc;
> + join_ns_flags |= CLONE_NEWNS;
> + } else {
> + pr_perror("invalid namespace type %s\n", type);
> + return -1;
> + }
> +
> + list_add_tail(&jn->list, &opts.join_ns);
> + pr_info("Added %s:%s join namespace\n", type, ns_file);
> + return 0;
> +}
> +
> static unsigned int parse_ns_link(char *link, size_t len, struct ns_desc *d)
> {
> unsigned long kid = 0;
> diff --git a/images/rpc.proto b/images/rpc.proto
> index fac4b9f..9ece4da 100644
> --- a/images/rpc.proto
> +++ b/images/rpc.proto
> @@ -15,6 +15,12 @@ message ext_mount_map {
> required string val = 2;
> };
>
> +message join_namespace {
> + required string ns = 1;
> + required string ns_file = 2;
> + optional string extra_opt = 3;
> +}
> +
> message inherit_fd {
> required string key = 1;
> required int32 fd = 2;
> @@ -90,6 +96,7 @@ message criu_opts {
> repeated string irmap_scan_paths = 36;
> repeated string external = 37;
> optional uint32 empty_ns = 38;
> + repeated join_namespace join_ns = 39;
> }
>
> message criu_dump_resp {
>
More information about the CRIU
mailing list