lxc_config_define(init_cwd);
lxc_config_define(init_gid);
lxc_config_define(init_uid);
+lxc_config_define(init_groups);
lxc_config_define(keyring_session);
lxc_config_define(log_file);
lxc_config_define(log_level);
{ "lxc.include", set_config_includefiles, get_config_includefiles, clr_config_includefiles, },
{ "lxc.init.cmd", set_config_init_cmd, get_config_init_cmd, clr_config_init_cmd, },
{ "lxc.init.gid", set_config_init_gid, get_config_init_gid, clr_config_init_gid, },
+ { "lxc.init.groups", set_config_init_groups, get_config_init_groups, clr_config_init_groups, },
{ "lxc.init.uid", set_config_init_uid, get_config_init_uid, clr_config_init_uid, },
{ "lxc.init.cwd", set_config_init_cwd, get_config_init_cwd, clr_config_init_cwd, },
{ "lxc.keyring.session", set_config_keyring_session, get_config_keyring_session, clr_config_keyring_session },
return 0;
}
+static int set_config_init_groups(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ __do_free char *value_dup = NULL;
+ __do_free gid_t *init_groups = NULL;
+ int num_groups = 0;
+ int iter = 0;
+ char *token;
+
+ if (lxc_config_value_empty(value))
+ return clr_config_init_groups(key, lxc_conf, NULL);
+
+ value_dup = strdup(value);
+ if (!value_dup)
+ return -ENOMEM;
+
+ lxc_iterate_parts(token, value_dup, ",")
+ num_groups++;
+
+ if (num_groups == 0)
+ return clr_config_init_groups(key, lxc_conf, NULL);
+
+ init_groups = zalloc(sizeof(gid_t) * num_groups);
+ if (!init_groups)
+ return ret_errno(ENOMEM);
+
+ /* Restore duplicated value so we can call lxc_iterate_parts() again. */
+ strcpy(value_dup, value);
+
+ lxc_iterate_parts(token, value_dup, ",") {
+ int ret;
+
+ gid_t group;
+
+ ret = lxc_safe_uint(token, &group);
+ if (ret)
+ return ret;
+
+ init_groups[iter++] = group;
+ }
+
+ lxc_conf->init_groups.size = num_groups;
+ lxc_conf->init_groups.list = move_ptr(init_groups);
+
+ return 0;
+}
+
static int set_config_hooks(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
return lxc_get_conf_int(c, retv, inlen, c->init_gid);
}
+static int get_config_init_groups(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ int fulllen = 0, len;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ if (c->init_groups.size == 0)
+ return 0;
+
+ for (int i = 0; i < c->init_groups.size; i++)
+ strprint(retv, inlen, "%s%d", (i > 0) ? "," : "",
+ c->init_groups.list[i]);
+
+ return fulllen;
+}
+
static int get_config_ephemeral(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
return 0;
}
+static inline int clr_config_init_groups(const char *key, struct lxc_conf *c,
+ void *data)
+{
+ free_disarm(c->init_groups.list);
+ c->init_groups.size = 0;
+ return 0;
+}
+
static inline int clr_config_ephemeral(const char *key, struct lxc_conf *c,
void *data)
{
}
printf("lxc.init_gid returned %d %s\n", ret, v2);
+ if (!c->set_config_item(c, "lxc.init.groups", "")) {
+ fprintf(stderr, "%d: failed to set init_groups\n", __LINE__);
+ goto out;
+ }
+
+ if (!c->set_config_item(c, "lxc.init.groups", "10,20,foo,40")) {
+ printf("failed to set init_groups to '10,20,foo,40' as expected\n");
+ } else {
+ goto out;
+ }
+
+ if (!c->set_config_item(c, "lxc.init.groups", "10,20,30,40")) {
+ fprintf(stderr, "%d: failed to set init_groups\n", __LINE__);
+ goto out;
+ }
+
+ ret = c->get_config_item(c, "lxc.init.groups", v2, 255);
+ if (ret < 0) {
+ fprintf(stderr, "%d: get_config_item(lxc.init_gid) returned %d\n",
+ __LINE__, ret);
+ goto out;
+ }
+ ret = strcmp("10,20,30,40", v2);
+ printf("lxc.init_groups returned %d %s\n", ret, v2);
+ if (ret != 0) {
+ goto out;
+ }
+
#define HNAME "hostname1"
// demonstrate proper usage:
char *alloced;