[CRIU] [PATCH 4/5] userns: parse /proc/PID/{u,g}id_map
Pavel Emelyanov
xemul at parallels.com
Mon Feb 10 20:47:48 PST 2014
On 02/11/2014 12:58 AM, Andrey Vagin wrote:
> Signed-off-by: Andrey Vagin <avagin at openvz.org>
> ---
> namespaces.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 105 insertions(+), 2 deletions(-)
>
> diff --git a/namespaces.c b/namespaces.c
> index 8119d99..524b47b 100644
> --- a/namespaces.c
> +++ b/namespaces.c
> @@ -15,6 +15,7 @@
>
> #include "protobuf.h"
> #include "protobuf/ns.pb-c.h"
> +#include "protobuf/userns.pb-c.h"
>
> static struct ns_desc *ns_desc_array[] = {
> &net_ns_desc,
> @@ -388,12 +389,114 @@ int gen_predump_ns_mask(void)
> return 0;
> }
>
> -static int dump_user_ns(pid_t pid, int ns_id)
> +static int parse_id_map(pid_t pid, char *name, UidGidExtent ***pb_exts)
> {
> - pr_err("User namesapces are not supported yet\n");
> + UidGidExtent *extents = NULL;
> + int len = 0, size = 0, fd, ret, i;
> + FILE *f;
> +
> + fd = open_proc(pid, "%s", name);
fd is left opened.
> + if (fd < 0) {
> + pr_perror("Unable to open %s", name);
> + return -1;
Will it always fail on Fedora with USER_NS turned off?
> + }
> +
> + f = fdopen(fd, "r");
Why not fopen_proc() instead?
> + if (f == NULL) {
> + close(fd);
> + return -1;
> + }
> +
> + ret = -1;
> + while (1) {
> + UidGidExtent *ext;
> +
> + if (len == size) {
> + UidGidExtent *t;
> +
> + size = size * 2 + 1;
> + t = xrealloc(extents, size * sizeof(UidGidExtent));
> + if (t == NULL)
> + break;
> + extents = t;
> + }
> +
> + ext = &extents[len];
> +
> + uid_gid_extent__init(ext);
> + ret = fscanf(f, "%d %d %d", &ext->first,
> + &ext->lower_first, &ext->count);
> + if (ret != 3) {
> + if (errno != 0) {
> + pr_perror("Unable to parse extents");
> + ret = -1;
> + } else
> + ret = 0;
> + break;
> + }
> + pr_err("%d %d %d\n", ext->first, ext->lower_first, ext->count);
> + len++;
> + }
> +
> + fclose(f);
> +
> + if (ret)
> + goto err;
> +
> + if (len) {
> + *pb_exts = xmalloc(sizeof(UidGidExtent *) * len);
> + if (*pb_exts == NULL)
> + goto err;
> +
> + for (i = 0; i < len; i++)
> + *pb_exts[i] = &extents[i];
> + } else {
> + xfree(extents);
> + *pb_exts = NULL;
> + }
> +
> + return len;
> +err:
> + xfree(extents);
> return -1;
> }
>
> +static int dump_user_ns(pid_t pid, int ns_id)
> +{
> + UsernsEntry e = USERNS_ENTRY__INIT;
> + int fd, ret, exit_code = -1;
> +
> + ret = parse_id_map(pid, "uid_map", &e.uid_map);
> + if (ret < 0)
> + goto err;
> + e.n_uid_map = ret;
> +
> + ret = parse_id_map(pid, "gid_map", &e.gid_map);
> + if (ret < 0)
> + goto err;
> + e.n_gid_map = ret;
> +
> + fd = open_image(CR_FD_USERNS, O_DUMP, ns_id);
> + if (fd < 0)
> + goto err;
> + ret = pb_write_one(fd, &e, PB_USERNS);
> + close(fd);
> + if (ret < 0)
> + goto err;
> +
> + exit_code = 0;
> +err:
> + if (e.uid_map) {
> + xfree(e.uid_map[0]);
> + xfree(e.uid_map);
> + }
> + if (e.gid_map) {
> + xfree(e.gid_map[0]);
> + xfree(e.gid_map);
> + }
> + return exit_code;
> +}
> +
> static int do_dump_namespaces(struct ns_id *ns)
> {
> int ret = -1;
>
More information about the CRIU
mailing list