diff --git a/lib/c/criu.c b/lib/c/criu.c index 75f168799..ddc6e0731 100644 --- a/lib/c/criu.c +++ b/lib/c/criu.c @@ -214,6 +214,18 @@ void criu_local_free_opts(criu_opts *opts) } opts->rpc->n_external = 0; + if (opts->rpc->join_ns) { + for (i = 0; i < opts->rpc->n_join_ns; i++) { + free(opts->rpc->join_ns[i]->ns); + free(opts->rpc->join_ns[i]->ns_file); + if (opts->rpc->join_ns[i]->extra_opt) { + free(opts->rpc->join_ns[i]->extra_opt); + } + free(opts->rpc->join_ns[i]); + } + } + opts->rpc->n_join_ns = 0; + if (opts->rpc->ps) { free(opts->rpc->ps->address); free(opts->rpc->ps); @@ -1804,3 +1816,82 @@ int criu_set_network_lock(enum criu_network_lock_method method) { return criu_local_set_network_lock(global_opts, method); } + +int criu_local_join_ns_add(criu_opts *opts, const char *ns, const char *ns_file, const char *extra_opt) +{ + int n_join_ns; + char *_ns = NULL, *_ns_file = NULL, *_extra_opt = NULL; + JoinNamespace **join_ns_arr, *join_ns = NULL; + + if (!ns) { + fprintf(stderr, "ns parameter for join_ns is not specified"); + goto err; + } + + _ns = strdup(ns); + if (!_ns) { + perror("Can't allocate memory for ns"); + goto err; + } + + if (!ns_file) { + fprintf(stderr, "ns parameter for join_ns is not specified"); + goto err; + } + + _ns_file = strdup(ns_file); + if (!_ns_file) { + perror("Can't allocate memory for ns_file"); + goto err; + } + + if (extra_opt) { + _extra_opt = strdup(extra_opt); + if (!_extra_opt) { + perror("Can't allocate memory for extra_opt"); + goto err; + } + } + + join_ns = malloc(sizeof(JoinNamespace)); + if (!join_ns) { + perror("Can't allocate memory for join_ns"); + goto err; + } + + n_join_ns = opts->rpc->n_join_ns + 1; + join_ns_arr = realloc(opts->rpc->join_ns, n_join_ns * sizeof(join_ns)); + if (!join_ns_arr) { + perror("Can't allocate memory for join_ns_arr"); + goto err; + } + + join_namespace__init(join_ns); + join_ns->ns = _ns; + join_ns->ns_file = _ns_file; + if (_extra_opt) { + join_ns->extra_opt = _extra_opt; + } + + join_ns_arr[n_join_ns - 1] = join_ns; + opts->rpc->join_ns = join_ns_arr; + opts->rpc->n_join_ns = n_join_ns; + + return 0; + +err: + if (_ns) + free(_ns); + if (_ns_file) + free(_ns_file); + if (_extra_opt) + free(_extra_opt); + if (join_ns) + free(join_ns); + return -1; +} + +int criu_join_ns_add(const char *ns, const char *ns_file, const char *extra_opt) +{ + return criu_local_join_ns_add(global_opts, ns, ns_file, extra_opt); +} diff --git a/lib/c/criu.h b/lib/c/criu.h index 258e33a19..c32f66418 100644 --- a/lib/c/criu.h +++ b/lib/c/criu.h @@ -103,6 +103,7 @@ int criu_set_page_server_address_port(const char *address, int port); int criu_set_pre_dump_mode(enum criu_pre_dump_mode mode); void criu_set_pidfd_store_sk(int sk); int criu_set_network_lock(enum criu_network_lock_method method); +int criu_join_ns_add(const char *ns, const char *ns_file, const char *extra_opt); /* * The criu_notify_arg_t na argument is an opaque @@ -263,6 +264,7 @@ int criu_local_set_page_server_address_port(criu_opts *opts, const char *address int criu_local_set_pre_dump_mode(criu_opts *opts, enum criu_pre_dump_mode mode); void criu_local_set_pidfd_store_sk(criu_opts *opts, int sk); int criu_local_set_network_lock(criu_opts *opts, enum criu_network_lock_method method); +int criu_local_join_ns_add(criu_opts *opts, const char *ns, const char *ns_file, const char *extra_opt); void criu_local_set_notify_cb(criu_opts *opts, int (*cb)(char *action, criu_notify_arg_t na));