conf: rework lxc_map_ids()

Especially, in case the new{g,u}idmap is used we should try to gather std{err,out} on error to better debug what is going on. Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent ea3a694f
......@@ -3473,16 +3473,35 @@ cleanup:
return fret;
}
int lxc_map_ids_exec_wrapper(void *args)
{
execl("/bin/sh", "sh", "-c", (char *)args, (char *)NULL);
return -1;
}
int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
{
struct id_map *map;
struct lxc_list *iterator;
enum idtype type;
char u_or_g;
char *pos;
int euid;
int ret = 0, use_shadow = 0;
int uidmap = 0, gidmap = 0;
char *buf = NULL;
int euid, fill, left;
char cmd_output[MAXPATHLEN];
/* strlen("new@idmap") = 9
* +
* strlen(" ") = 1
* +
* LXC_NUMSTRLEN64
* +
* strlen(" ") = 1
*
* We add some additional space to make sure that we really have
* LXC_IDMAPLEN bytes available for our the {g,u]id mapping.
*/
char mapbuf[9 + 1 + LXC_NUMSTRLEN64 + 1 + LXC_IDMAPLEN] = {0};
int ret = 0, uidmap = 0, gidmap = 0;
bool use_shadow = false, had_entry = false;
euid = geteuid();
......@@ -3507,17 +3526,12 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
return -1;
}
for (type = ID_TYPE_UID; type <= ID_TYPE_GID; type++) {
int left, fill;
bool had_entry = false;
if (!buf) {
buf = pos = malloc(LXC_IDMAPLEN);
if (!buf)
return -ENOMEM;
}
pos = buf;
for (type = ID_TYPE_UID, u_or_g = 'u'; type <= ID_TYPE_GID;
type++, u_or_g = 'g') {
pos = mapbuf;
if (use_shadow)
pos += sprintf(buf, "new%cidmap %d", type == ID_TYPE_UID ? 'u' : 'g', pid);
pos += sprintf(mapbuf, "new%cidmap %d", u_or_g, pid);
lxc_list_for_each(iterator, idmap) {
/* The kernel only takes <= 4k for writes to
......@@ -3529,7 +3543,7 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
had_entry = true;
left = LXC_IDMAPLEN - (pos - buf);
left = LXC_IDMAPLEN - (pos - mapbuf);
fill = snprintf(pos, left, "%s%lu %lu %lu%s",
use_shadow ? " " : "", map->nsid,
map->hostid, map->range,
......@@ -3542,22 +3556,28 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
if (!had_entry)
continue;
if (!use_shadow) {
ret = write_id_mapping(type, pid, buf, pos - buf);
/* Try to catch the ouput of new{g,u}idmap to make debugging
* easier.
*/
if (use_shadow) {
ret = run_command(cmd_output, sizeof(cmd_output),
lxc_map_ids_exec_wrapper,
(void *)mapbuf);
if (ret < 0) {
ERROR("new%cidmap failed to write mapping: %s",
u_or_g, cmd_output);
return -1;
}
} else {
left = LXC_IDMAPLEN - (pos - buf);
fill = snprintf(pos, left, "\n");
if (fill <= 0 || fill >= left)
SYSERROR("Too many {g,u}id mappings defined.");
pos += fill;
ret = system(buf);
ret = write_id_mapping(type, pid, mapbuf, pos - mapbuf);
if (ret < 0)
return -1;
}
if (ret)
break;
memset(mapbuf, 0, sizeof(mapbuf));
}
free(buf);
return ret;
return 0;
}
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment