Beispiel #1
0
static int my_checker(const struct lxc_arguments *args)
{
	if (do_restore && stop) {
		lxc_error(args, "-s not compatible with -r.");
		return -1;

	} else if (!do_restore && daemonize_set) {
		lxc_error(args, "-d/-F not compatible with -r.");
		return -1;
	}

	if (checkpoint_dir == NULL) {
		lxc_error(args, "-D is required.");
		return -1;
	}

	return 0;
}
static int my_checker(const struct lxc_arguments* args)
{
	if (!args->argc) {
		lxc_error(args, "missing command to execute !");
		return -1;
	}

	return 0;
}
Beispiel #3
0
int lxc_arguments_str_to_int(struct lxc_arguments *args, const char *str)
{
	long val;
	char *endptr;

	errno = 0;
	val = strtol(str, &endptr, 10);
	if (errno) {
		lxc_error(args, "invalid statefd '%s' : %m", str);
		return -1;
	}

	if (*endptr) {
		lxc_error(args, "invalid digit for statefd '%s'", str);
		return -1;
	}

	return (int)val;
}
Beispiel #4
0
static int set_invalid_netdev(struct lxc_container *c) {
	if (c->set_config_item(c, "lxc.net.0.asdf", "veth")) {
		lxc_error("%s\n", "lxc.net.0.asdf should be invalid");
		return -1;
	}

	if (c->set_config_item(c, "lxc.net.2147483647.type", "veth")) {
		lxc_error("%s\n", "lxc.net.2147483647.type should be invalid");
		return -1;
	}

	if (c->set_config_item(c, "lxc.net.0.", "veth")) {
		lxc_error("%s\n", "lxc.net.0. should be invalid");
		return -1;
	}

	c->clear_config(c);
	c->lxc_conf = NULL;

	return 0;
}
Beispiel #5
0
int test_idmap_parser(void)
{
	size_t i;
	struct idmap_check {
		bool is_valid;
		const char *idmap;
	};
	static struct idmap_check idmaps[] = {
	    /* valid idmaps */
	    { true, "u 0 0 1"                           },
	    { true, "g 0 0 1"                           },
	    { true, "u 1 100001 999999999"              },
	    { true, "g 1 100001 999999999"              },
	    { true, "u 0 0 0"                           },
	    { true, "g 0 0 0"                           },
	    { true, "u 1000 165536 65536"               },
	    { true, "g 999 999 1"                       },
	    { true, "u    0		5000	100000" },
	    { true, "g		577	789 5"          },
	    { true, "u 65536 65536 1	"               },
	    /* invalid idmaps */
	    { false, "1u 0 0 0"                         },
	    { false, "1g 0 0 0a"                        },
	    { false, "1 u 0 0 0"                        },
	    { false, "1g 0 0 0 1"                       },
	    { false, "1u a0 b0 c0 d1"                   },
	    { false, "1g 0 b0 0 d1"                     },
	    { false, "1u a0 0 c0 1"                     },
	    { false, "g -1 0 -10"                       },
	    { false, "a 1 0 10"                         },
	    { false, "u 1 1 0 10"                       },
	    { false, "g 1 0 10	 z "                    },
	};

	for (i = 0; i < sizeof(idmaps) / sizeof(struct idmap_check); i++) {
		unsigned long hostid, nsid, range;
		char type;
		int ret;
		ret = parse_idmaps(idmaps[i].idmap, &type, &nsid, &hostid,
				   &range);
		if ((ret < 0 && idmaps[i].is_valid) ||
		    (ret == 0 && !idmaps[i].is_valid)) {
			lxc_error("failed to parse idmap \"%s\"\n",
				  idmaps[i].idmap);
			return -1;
		}
	}

	return 0;
}
Beispiel #6
0
static int set_get_compare_clear_save_load(struct lxc_container *c,
					   const char *key, const char *value,
					   const char *config_file,
					   bool compare)
{
	char retval[4096] = {0};
	int ret;

	if (!c->set_config_item(c, key, value)) {
		lxc_error("failed to set config item \"%s\" to \"%s\"\n", key,
			  value);
		return -1;
	}

	ret = c->get_config_item(c, key, retval, sizeof(retval));
	if (ret < 0) {
		lxc_error("failed to get config item \"%s\"\n", key);
		return -1;
	}

	if (compare) {
		ret = strcmp(retval, value);
		if (ret != 0) {
			lxc_error(
			    "expected value \"%s\" and retrieved value \"%s\" "
			    "for config key \"%s\" do not match\n",
			    value, retval, key);
			return -1;
		}
	}

	if (config_file) {
		if (!c->save_config(c, config_file)) {
			lxc_error("%s\n", "failed to save config file");
			return -1;
		}

		c->clear_config(c);
		c->lxc_conf = NULL;

		if (!c->load_config(c, config_file)) {
			lxc_error("%s\n", "failed to load config file");
			return -1;
		}
	}

	if (!c->clear_config_item(c, key)) {
		lxc_error("failed to clear config item \"%s\"\n", key);
		return -1;
	}

	c->clear_config(c);
	c->lxc_conf = NULL;

	return 0;
}
Beispiel #7
0
static int lxc_arguments_lxcpath_add(struct lxc_arguments *args,
				     const char *lxcpath)
{
	if (args->lxcpath_additional != -1 &&
	    args->lxcpath_cnt > args->lxcpath_additional) {
		fprintf(stderr, "This command only accepts %d -P,--lxcpath arguments\n",
			args->lxcpath_additional + 1);
		exit(EXIT_FAILURE);
	}

	args->lxcpath = realloc(args->lxcpath, (args->lxcpath_cnt + 1) *
				 sizeof(args->lxcpath[0]));
	if (args->lxcpath == NULL) {
		lxc_error(args, "no memory");
		return -ENOMEM;
	}
	args->lxcpath[args->lxcpath_cnt++] = lxcpath;
	return 0;
}
Beispiel #8
0
extern int lxc_arguments_parse(struct lxc_arguments *args, int argc,
			       char *const argv[])
{
	int ret = 0;
	char shortopts[256];

	ret = build_shortopts(args->options, shortopts, sizeof(shortopts));
	if (ret < 0) {
		lxc_error(args, "build_shortopts() failed : %s",
			  strerror(errno));
		return ret;
	}

	while (true) {
		int c;
		int index = 0;

		c = getopt_long(argc, argv, shortopts, args->options, &index);
		if (c == -1)
			break;
		switch (c) {
		case 'n':
			args->name = optarg;
			break;
		case 'o':
			args->log_file = optarg;
			break;
		case 'l':
			args->log_priority = optarg;
			break;
		case 'q':
			args->quiet = 1;
			break;
		case OPT_RCFILE:
			args->rcfile = optarg;
			break;
		case 'P':
			remove_trailing_slashes(optarg);
			ret = lxc_arguments_lxcpath_add(args, optarg);
			if (ret < 0)
				return ret;
			break;
		case OPT_USAGE:
			print_usage(args->options, args);
		case OPT_VERSION:
			print_version();
		case '?':
			print_help(args, 1);
		case 'h':
			print_help(args, 0);
		default:
			if (args->parser) {
				ret = args->parser(args, c, optarg);
				if (ret)
					goto error;
			}
		}
	}

	/*
	 * Reclaim the remaining command arguments
	 */
	args->argv = &argv[optind];
	args->argc = argc - optind;

	/* If no lxcpaths were given, use default */
	if (!args->lxcpath_cnt) {
		ret = lxc_arguments_lxcpath_add(
		    args, lxc_global_config_value("lxc.lxcpath"));
		if (ret < 0)
			return ret;
	}

	/* Check the command options */

	if (!args->name && strcmp(args->progname, "lxc-autostart") != 0) {
		lxc_error(args, "missing container name, use --name option");
		return -1;
	}

	if (args->checker)
		ret = args->checker(args);
error:
	if (ret)
		lxc_error(args, "could not parse command line");
	return ret;
}
Beispiel #9
0
void test_detect_ramfs_rootfs(void)
{
	size_t i;
	int ret;
	int fret = EXIT_FAILURE;
	char path[__MNTNS_LEN];
	int init_ns = -1;
	char tmpf1[] = "lxc-test-utils-XXXXXX";
	char tmpf2[] = "lxc-test-utils-XXXXXX";
	int fd1 = -1, fd2 = -1;
	FILE *fp1 = NULL, *fp2 = NULL;
	char *mountinfo[] = {
		"18 24 0:17 / /sys rw,nosuid,nodev,noexec,relatime shared:7 - sysfs sysfs rw",
		"19 24 0:4 / /proc rw,nosuid,nodev,noexec,relatime shared:13 - proc proc rw",
		"20 24 0:6 / /dev rw,nosuid,relatime shared:2 - devtmpfs udev rw,size=4019884k,nr_inodes=1004971,mode=755",
		"21 20 0:14 / /dev/pts rw,nosuid,noexec,relatime shared:3 - devpts devpts rw,gid=5,mode=620,ptmxmode=000",
		"22 24 0:18 / /run rw,nosuid,noexec,relatime shared:5 - tmpfs tmpfs rw,size=807912k,mode=755",

		/* This is what we care about. */
		"24 0 8:2 / / rw - rootfs rootfs rw,size=1004396k,nr_inodes=251099",

		"25 18 0:12 / /sys/kernel/security rw,nosuid,nodev,noexec,relatime shared:8 - securityfs securityfs rw",
		"26 20 0:20 / /dev/shm rw,nosuid,nodev shared:4 - tmpfs tmpfs rw",
		"27 22 0:21 / /run/lock rw,nosuid,nodev,noexec,relatime shared:6 - tmpfs tmpfs rw,size=5120k",
		"28 18 0:22 / /sys/fs/cgroup ro,nosuid,nodev,noexec shared:9 - tmpfs tmpfs ro,mode=755",
		"29 28 0:23 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime shared:10 - cgroup cgroup rw,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd",
		"30 18 0:24 / /sys/fs/pstore rw,nosuid,nodev,noexec,relatime shared:11 - pstore pstore rw",
		"31 18 0:25 / /sys/firmware/efi/efivars rw,nosuid,nodev,noexec,relatime shared:12 - efivarfs efivarfs rw",
		"32 28 0:26 / /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:14 - cgroup cgroup rw,cpu,cpuacct",
		"33 28 0:27 / /sys/fs/cgroup/net_cls,net_prio rw,nosuid,nodev,noexec,relatime shared:15 - cgroup cgroup rw,net_cls,net_prio",
		"34 28 0:28 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,blkio",
		"35 28 0:29 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime shared:17 - cgroup cgroup rw,freezer",
		"36 28 0:30 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:18 - cgroup cgroup rw,memory",
		"37 28 0:31 / /sys/fs/cgroup/hugetlb rw,nosuid,nodev,noexec,relatime shared:19 - cgroup cgroup rw,hugetlb",
		"38 28 0:32 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime shared:20 - cgroup cgroup rw,cpuset",
		"39 28 0:33 / /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime shared:21 - cgroup cgroup rw,devices",
		"40 28 0:34 / /sys/fs/cgroup/pids rw,nosuid,nodev,noexec,relatime shared:22 - cgroup cgroup rw,pids",
		"41 28 0:35 / /sys/fs/cgroup/perf_event rw,nosuid,nodev,noexec,relatime shared:23 - cgroup cgroup rw,perf_event",
		"42 19 0:36 / /proc/sys/fs/binfmt_misc rw,relatime shared:24 - autofs systemd-1 rw,fd=32,pgrp=1,timeout=0,minproto=5,maxproto=5,direct",
		"43 18 0:7 / /sys/kernel/debug rw,relatime shared:25 - debugfs debugfs rw",
		"44 20 0:37 / /dev/hugepages rw,relatime shared:26 - hugetlbfs hugetlbfs rw",
		"45 20 0:16 / /dev/mqueue rw,relatime shared:27 - mqueue mqueue rw",
		"46 43 0:9 / /sys/kernel/debug/tracing rw,relatime shared:28 - tracefs tracefs rw",
		"76 18 0:38 / /sys/fs/fuse/connections rw,relatime shared:29 - fusectl fusectl rw",
		"78 24 8:1 / /boot/efi rw,relatime shared:30 - vfat /dev/sda1 rw,fmask=0077,dmask=0077,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro",
	};

	ret = snprintf(path, __MNTNS_LEN, "/proc/self/ns/mnt");
	if (ret < 0 || (size_t)ret >= __MNTNS_LEN) {
		lxc_error("%s\n", "Failed to create path with snprintf().");
		goto non_test_error;
	}

	init_ns = open(path, O_RDONLY | O_CLOEXEC);
	if (init_ns < 0) {
		lxc_error("%s\n", "Failed to open initial mount namespace.");
		goto non_test_error;
	}

	if (unshare(CLONE_NEWNS) < 0) {
		lxc_error("%s\n", "Could not unshare mount namespace.");
		close(init_ns);
		init_ns = -1;
		goto non_test_error;
	}

	if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, 0) < 0) {
		lxc_error("Failed to remount / private: %s.\n", strerror(errno));
		goto non_test_error;
	}

	fd1 = mkstemp(tmpf1);
	if (fd1 < 0) {
		lxc_error("%s\n", "Could not create temporary file.");
		goto non_test_error;
	}

	fd2 = mkstemp(tmpf2);
	if (fd2 < 0) {
		lxc_error("%s\n", "Could not create temporary file.");
		goto non_test_error;
	}

	fp1 = fdopen(fd1, "r+");
	if (!fp1) {
		lxc_error("%s\n", "Could not fdopen() temporary file.");
		goto non_test_error;
	}

	fp2 = fdopen(fd2, "r+");
	if (!fp2) {
		lxc_error("%s\n", "Could not fdopen() temporary file.");
		goto non_test_error;
	}

	/* Test if it correctly detects - rootfs rootfs */
	for (i = 0; i < sizeof(mountinfo) / sizeof(mountinfo[0]); i++) {
		if (fprintf(fp1, "%s\n", mountinfo[i]) < 0) {
			lxc_error("Could not write \"%s\" to temporary file.", mountinfo[i]);
			goto non_test_error;
		}
	}
	fclose(fp1);
	fp1 = NULL;
	fd1 = -1;

	/* Test if it correctly fails to detect when no - rootfs rootfs */
	for (i = 0; i < sizeof(mountinfo) / sizeof(mountinfo[0]); i++) {
		if (strcmp(mountinfo[i], "24 0 8:2 / / rw - rootfs rootfs rw,size=1004396k,nr_inodes=251099") == 0)
			continue;
		if (fprintf(fp2, "%s\n", mountinfo[i]) < 0) {
			lxc_error("Could not write \"%s\" to temporary file.", mountinfo[i]);
			goto non_test_error;
		}
	}
	fclose(fp2);
	fp2 = NULL;
	fd2 = -1;

	if (mount(tmpf1, "/proc/self/mountinfo", NULL, MS_BIND, 0) < 0) {
		lxc_error("%s\n", "Could not overmount \"/proc/self/mountinfo\".");
		goto non_test_error;
	}

	lxc_test_assert_abort(detect_ramfs_rootfs());

	if (mount(tmpf2, "/proc/self/mountinfo", NULL, MS_BIND, 0) < 0) {
		lxc_error("%s\n", "Could not overmount \"/proc/self/mountinfo\".");
		goto non_test_error;
	}

	lxc_test_assert_abort(!detect_ramfs_rootfs());
	fret = EXIT_SUCCESS;

non_test_error:
	if (fp1)
		fclose(fp1);
	else if (fd1 > 0)
		close(fd1);
	if (fp2)
		fclose(fp2);
	else if (fd2 > 0)
		close(fd2);

	if (init_ns > 0) {
		if (setns(init_ns, 0) < 0) {
			lxc_error("Failed to switch back to initial mount namespace: %s.\n", strerror(errno));
			fret = EXIT_FAILURE;
		}
		close(init_ns);
	}
	if (fret == EXIT_SUCCESS)
		return;
	exit(fret);
}
Beispiel #10
0
static int set_and_clear_complete_netdev(struct lxc_container *c)
{
	if (!c->set_config_item(c, "lxc.net.1.type", "veth")) {
		lxc_error("%s\n", "lxc.net.1.type");
		return -1;
	}

	if (!c->set_config_item(c, "lxc.net.1.ipv4.address", "10.0.2.3/24")) {
		lxc_error("%s\n", "lxc.net.1.ipv4.address");
		return -1;
	}

	if (!c->set_config_item(c, "lxc.net.1.ipv4.gateway", "10.0.2.2")) {
		lxc_error("%s\n", "lxc.net.1.ipv4.gateway");
		return -1;
	}

	if (!c->set_config_item(c, "lxc.net.1.ipv6.address",
				"2003:db8:1:0:214:1234:fe0b:3596/64")) {
		lxc_error("%s\n", "lxc.net.1.ipv6.address");
		return -1;
	}

	if (!c->set_config_item(c, "lxc.net.1.ipv6.gateway",
				"2003:db8:1:0::1")) {
		lxc_error("%s\n", "lxc.net.1.ipv6.gateway");
		return -1;
	}

	if (!c->set_config_item(c, "lxc.net.1.flags", "up")) {
		lxc_error("%s\n", "lxc.net.1.flags");
		return -1;
	}

	if (!c->set_config_item(c, "lxc.net.1.link", "br0")) {
		lxc_error("%s\n", "lxc.net.1.link");
		return -1;
	}

	if (!c->set_config_item(c, "lxc.net.1.veth.pair", "bla")) {
		lxc_error("%s\n", "lxc.net.1.veth.pair");
		return -1;
	}

	if (!c->set_config_item(c, "lxc.net.1.veth.ipv4.route", "192.0.2.1/32")) {
		lxc_error("%s\n", "lxc.net.1.veth.ipv4.route");
		return -1;
	}

	if (!c->set_config_item(c, "lxc.net.1.veth.ipv6.route", "2001:db8::1/128")) {
		lxc_error("%s\n", "lxc.net.1.veth.ipv6.route");
		return -1;
	}

	if (!c->set_config_item(c, "lxc.net.1.hwaddr",
				"52:54:00:80:7a:5d")) {
		lxc_error("%s\n", "lxc.net.1.hwaddr");
		return -1;
	}

	if (!c->set_config_item(c, "lxc.net.1.mtu", "2000")) {
		lxc_error("%s\n", "lxc.net.1.mtu");
		return -1;
	}

	if (!c->clear_config_item(c, "lxc.net.1")) {
		lxc_error("%s", "failed to clear \"lxc.net.1\"\n");
		return -1;
	}

	c->clear_config(c);
	c->lxc_conf = NULL;

	return 0;
}
Beispiel #11
0
int main(int argc, char *argv[])
{
	int ret;
	struct lxc_container *c;
	int fd = -1, fret = EXIT_FAILURE;
	char tmpf[] = "lxc-parse-config-file-XXXXXX";
	char retval[4096] = {0};

	fd = lxc_make_tmpfile(tmpf, false);
	if (fd < 0) {
		lxc_error("%s\n", "Could not create temporary file");
		exit(fret);
	}
	close(fd);

	c = lxc_container_new(tmpf, NULL);
	if (!c) {
		lxc_error("%s\n", "Failed to create new container");
		exit(EXIT_FAILURE);
	}

	if (set_get_compare_clear_save_load(c, "lxc.arch", "x86_64", tmpf,
					    true) < 0) {
		lxc_error("%s\n", "lxc.arch");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.pty.max", "1000", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.pty.max");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.tty.max", "4", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.tty.max");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.tty.dir", "not-dev", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.tty.dir");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.apparmor.profile", "unconfined", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.apparmor.profile");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.apparmor.allow_incomplete", "1", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.apparmor.allow_incomplete");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.selinux.context", "system_u:system_r:lxc_t:s0:c22", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.selinux.context");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.cgroup.cpuset.cpus",
					    "1-100", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.cgroup.cpuset.cpus");
		goto non_test_error;
	}

	if (!c->set_config_item(c, "lxc.cgroup.cpuset.cpus", "1-100")) {
		lxc_error("%s\n", "failed to set config item \"lxc.cgroup.cpuset.cpus\" to \"1-100\"");
		return -1;
	}

	if (!c->set_config_item(c, "lxc.cgroup.memory.limit_in_bytes", "123456789")) {
		lxc_error("%s\n", "failed to set config item \"lxc.cgroup.memory.limit_in_bytes\" to \"123456789\"");
		return -1;
	}

	if (!c->get_config_item(c, "lxc.cgroup", retval, sizeof(retval))) {
		lxc_error("%s\n", "failed to get config item \"lxc.cgroup\"");
		return -1;
	}

	c->clear_config(c);
	c->lxc_conf = NULL;

	/* lxc.idmap
	 * We can't really save the config here since save_config() wants to
	 * chown the container's directory but we haven't created an on-disk
	 * container. So let's test set-get-clear.
	 */
	if (set_get_compare_clear_save_load(c, "lxc.idmap", "u 0 100000 1000000000", NULL, false) < 0) {
		lxc_error("%s\n", "lxc.idmap");
		goto non_test_error;
	}

	if (!c->set_config_item(c, "lxc.idmap", "u 1 100000 10000000")) {
		lxc_error("%s\n", "failed to set config item \"lxc.idmap\" to \"u 1 100000 10000000\"");
		return -1;
	}

	if (!c->set_config_item(c, "lxc.idmap", "g 1 100000 10000000")) {
		lxc_error("%s\n", "failed to set config item \"lxc.idmap\" to \"g 1 100000 10000000\"");
		return -1;
	}

	if (!c->get_config_item(c, "lxc.idmap", retval, sizeof(retval))) {
		lxc_error("%s\n", "failed to get config item \"lxc.idmap\"");
		return -1;
	}

	c->clear_config(c);
	c->lxc_conf = NULL;

	if (set_get_compare_clear_save_load(c, "lxc.log.level", "DEBUG", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.log.level");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.log.file", "/some/path", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.log.file");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.mount.fstab", "/some/path", NULL, true) < 0) {
		lxc_error("%s\n", "lxc.mount.fstab");
		goto non_test_error;
	}

	/* lxc.mount.auto
	 * Note that we cannot compare the values since the getter for
	 * lxc.mount.auto does not preserve ordering.
	 */
	if (set_get_compare_clear_save_load(c, "lxc.mount.auto", "proc:rw sys:rw cgroup-full:rw", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.mount.auto");
		goto non_test_error;
	}

	/* lxc.mount.entry
	 * Note that we cannot compare the values since the getter for
	 * lxc.mount.entry appends newlines.
	 */
	if (set_get_compare_clear_save_load(c, "lxc.mount.entry", "/dev/dri dev/dri none bind,optional,create=dir", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.mount.entry");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.rootfs.path", "/some/path", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.rootfs.path");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.rootfs.mount", "/some/path", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.rootfs.mount");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.rootfs.options", "ext4,discard", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.rootfs.options");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.uts.name", "the-shire", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.uts.name");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(
		c, "lxc.hook.pre-start", "/some/pre-start", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.hook.pre-start");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(
		c, "lxc.hook.pre-mount", "/some/pre-mount", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.hook.pre-mount");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.hook.mount", "/some/mount", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.hook.mount");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.hook.autodev", "/some/autodev", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.hook.autodev");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.hook.start", "/some/start", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.hook.start");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.hook.stop", "/some/stop", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.hook.stop");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.hook.post-stop", "/some/post-stop", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.hook.post-stop");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.hook.clone", "/some/clone", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.hook.clone");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.hook.destroy", "/some/destroy", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.hook.destroy");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.cap.drop", "sys_module mknod setuid net_raw", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.cap.drop");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.cap.keep", "sys_module mknod setuid net_raw", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.cap.keep");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.console.path", "none", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.console.path");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.console.logfile", "/some/logfile", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.console.logfile");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.seccomp.profile", "/some/seccomp/file", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.seccomp.profile");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.autodev", "1", tmpf, true) <
	    0) {
		lxc_error("%s\n", "lxc.autodev");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.signal.halt", "1", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.signal.halt");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.signal.reboot", "1", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.signal.reboot");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.signal.stop", "1", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.signal.stop");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.start.auto", "1", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.start.auto");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.start.delay", "5", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.start.delay");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.start.order", "1", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.start.order");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.log.syslog", "local0", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.log.syslog");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.monitor.unshare", "1", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.monitor.unshare");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.group", "some,container,groups", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.group");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.environment", "FOO=BAR", tmpf, false) < 0) {
		lxc_error("%s\n", "lxc.environment");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.init.cmd", "/bin/bash", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.init.cmd");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.init.uid", "1000", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.init.uid");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.init.gid", "1000", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.init.gid");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.ephemeral", "1", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.ephemeral");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.no_new_privs", "1", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.no_new_privs");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.sysctl.net.core.somaxconn", "256", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.sysctl.net.core.somaxconn");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.proc.oom_score_adj", "10", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.proc.oom_score_adj");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.prlimit.nofile", "65536", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.prlimit.nofile");
		goto non_test_error;
	}

	if (test_idmap_parser() < 0) {
		lxc_error("%s\n", "failed to test parser for \"lxc.id_map\"");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.0.type", "veth", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.0.type");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.2.type", "none", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.2.type");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.3.type", "empty", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.3.type");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.4.type", "vlan", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.4.type");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.0.type", "macvlan", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.0.type");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.0.type", "ipvlan", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.0.type");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.1000.type", "phys", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.1000.type");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.0.flags", "up", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.0.flags");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.0.name", "eth0", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.0.name");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.0.link", "bla", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.0.link");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load_network(c, "lxc.net.0.macvlan.mode", "private", tmpf, true, "macvlan")) {
		lxc_error("%s\n", "lxc.net.0.macvlan.mode");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load_network(c, "lxc.net.0.macvlan.mode", "vepa", tmpf, true, "macvlan")) {
		lxc_error("%s\n", "lxc.net.0.macvlan.mode");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load_network(c, "lxc.net.0.macvlan.mode", "bridge", tmpf, true, "macvlan")) {
		lxc_error("%s\n", "lxc.net.0.macvlan.mode");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load_network(c, "lxc.net.0.ipvlan.mode", "l3", tmpf, true, "ipvlan")) {
		lxc_error("%s\n", "lxc.net.0.ipvlan.mode");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load_network(c, "lxc.net.0.ipvlan.mode", "l3s", tmpf, true, "ipvlan")) {
		lxc_error("%s\n", "lxc.net.0.ipvlan.mode");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load_network(c, "lxc.net.0.ipvlan.mode", "l2", tmpf, true, "ipvlan")) {
		lxc_error("%s\n", "lxc.net.0.ipvlan.mode");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load_network(c, "lxc.net.0.ipvlan.isolation", "bridge", tmpf, true, "ipvlan")) {
		lxc_error("%s\n", "lxc.net.0.ipvlan.isolation");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load_network(c, "lxc.net.0.ipvlan.isolation", "private", tmpf, true, "ipvlan")) {
		lxc_error("%s\n", "lxc.net.0.ipvlan.isolation");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load_network(c, "lxc.net.0.ipvlan.isolation", "vepa", tmpf, true, "ipvlan")) {
		lxc_error("%s\n", "lxc.net.0.ipvlan.isolation");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load_network(c, "lxc.net.0.veth.pair", "clusterfuck", tmpf, true, "veth")) {
		lxc_error("%s\n", "lxc.net.0.veth.pair");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load_network(c, "lxc.net.0.veth.ipv4.route", "192.0.2.1/32", tmpf, true, "veth")) {
		lxc_error("%s\n", "lxc.net.0.veth.ipv4.route");
		return -1;
	}

	if (set_get_compare_clear_save_load_network(c, "lxc.net.0.veth.ipv6.route", "2001:db8::1/128", tmpf, true, "veth")) {
		lxc_error("%s\n", "lxc.net.0.veth.ipv6.route");
		return -1;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.0.script.up", "/some/up/path", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.0.script.up");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.0.script.down", "/some/down/path", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.0.script.down");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.0.hwaddr", "52:54:00:80:7a:5d", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.0.hwaddr");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.0.mtu", "2000", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.0.mtu");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load_network(c, "lxc.net.0.vlan.id", "2", tmpf, true, "vlan")) {
		lxc_error("%s\n", "lxc.net.0.vlan.id");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.0.ipv4.gateway", "10.0.2.2", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.0.ipv4.gateway");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.0.ipv6.gateway", "2003:db8:1::1", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.0.ipv6.gateway");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.0.ipv4.address", "10.0.2.3/24", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.0.ipv4.address");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.net.0.ipv6.address", "2003:db8:1:0:214:1234:fe0b:3596/64", tmpf, true)) {
		lxc_error("%s\n", "lxc.net.0.ipv6.address");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.cgroup.dir", "lxd", tmpf, true)) {
		lxc_error("%s\n", "lxc.cgroup.dir");
		goto non_test_error;
	}

	if (set_and_clear_complete_netdev(c) < 0) {
		lxc_error("%s\n", "failed to clear whole network");
		goto non_test_error;
	}

	if (set_invalid_netdev(c) < 0) {
		lxc_error("%s\n", "failed to reject invalid configuration");
		goto non_test_error;
	}

	ret = set_get_compare_clear_save_load(c, "lxc.hook.version", "1", tmpf, true);
	if (ret < 0) {
		lxc_error("%s\n", "lxc.hook.version");
		goto non_test_error;
	}

	ret = set_get_compare_clear_save_load(c, "lxc.hook.version", "2", tmpf, true);
	if (ret == 0) {
		lxc_error("%s\n", "lxc.hook.version");
		goto non_test_error;
	}

	ret = set_get_compare_clear_save_load(c, "lxc.monitor.signal.pdeath", "SIGKILL", tmpf, true);
	if (ret == 0) {
		lxc_error("%s\n", "lxc.hook.version");
		goto non_test_error;
	}

	if (set_get_compare_clear_save_load(c, "lxc.rootfs.managed", "1", tmpf, true) < 0) {
		lxc_error("%s\n", "lxc.rootfs.managed");
		goto non_test_error;
	}

	if (c->set_config_item(c, "lxc.notaconfigkey", "invalid")) {
		lxc_error("%s\n", "Managed to set to set invalid config item \"lxc.notaconfigkey\" to \"invalid\"");
		return -1;
	}

	fret = EXIT_SUCCESS;

non_test_error:
	(void)unlink(tmpf);
	(void)rmdir(dirname(c->configfile));
	lxc_container_put(c);
	exit(fret);
}
Beispiel #12
0
int main(int argc, char *argv[])
{
	int ret;
	struct lxc_container *c;
	int fret = EXIT_FAILURE;
	char v1[2], v2[256], v3[2048];

	if ((c = lxc_container_new("testxyz", NULL)) == NULL) {
		fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
		exit(EXIT_FAILURE);
	}

	/* EXPECT SUCCESS: lxc.log.syslog with valid value. */
	if (!c->set_config_item(c, "lxc.log.syslog", "local0")) {
		lxc_error("%s\n", "Failed to set lxc.log.syslog.\n");
		goto out;
	}

	ret = c->get_config_item(c, "lxc.log.syslog", v2, 255);
	if (ret < 0) {
		lxc_error("Failed to retrieve lxc.log.syslog: %d.\n", ret);
		goto out;
	}

	if (strcmp(v2, "local0") != 0) {
		lxc_error("Expected: local0 == %s.\n", v2);
		goto out;
	}
	lxc_debug("Retrieving value for lxc.log.syslog correctly returned: %s.\n", v2);

	/* EXPECT FAILURE: lxc.log.syslog with invalid value. */
	if (c->set_config_item(c, "lxc.log.syslog", "NONSENSE")) {
		lxc_error("%s\n", "Succeeded int setting lxc.log.syslog to invalid value \"NONSENSE\".\n");
		goto out;
	}
	lxc_debug("%s\n", "Successfully failed to set lxc.log.syslog to invalid value.\n");

	if (!c->set_config_item(c, "lxc.hook.pre-start", "hi there")) {
		fprintf(stderr, "%d: failed to set hook.pre-start\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.hook.pre-start", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.hook.pre-start) returned %d\n", __LINE__, ret);
		goto out;
	}
	fprintf(stderr, "lxc.hook.pre-start returned %d %s\n", ret, v2);

	ret = c->get_config_item(c, "lxc.net", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret);
		goto out;
	}
	fprintf(stderr, "%d: get_config_item(lxc.net) returned %d %s\n", __LINE__, ret, v2);

	if (!c->set_config_item(c, "lxc.tty.max", "4")) {
		fprintf(stderr, "%d: failed to set tty\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.tty.max", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.tty) returned %d\n", __LINE__, ret);
		goto out;
	}
	fprintf(stderr, "lxc.tty returned %d %s\n", ret, v2);

	if (!c->set_config_item(c, "lxc.arch", "x86")) {
		fprintf(stderr, "%d: failed to set arch\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.arch", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.arch) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("lxc.arch returned %d %s\n", ret, v2);

	if (!c->set_config_item(c, "lxc.init.uid", "100")) {
		fprintf(stderr, "%d: failed to set init_uid\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.init.uid", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.init_uid) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("lxc.init_uid returned %d %s\n", ret, v2);

	if (!c->set_config_item(c, "lxc.init.gid", "100")) {
		fprintf(stderr, "%d: failed to set init_gid\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.init.gid", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.init_gid) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("lxc.init_gid returned %d %s\n", ret, v2);

#define HNAME "hostname1"
	// demonstrate proper usage:
	char *alloced;
	int len;

	if (!c->set_config_item(c, "lxc.uts.name", HNAME)) {
		fprintf(stderr, "%d: failed to set utsname\n", __LINE__);
		goto out;
	}

	len = c->get_config_item(c, "lxc.uts.name", NULL, 0);  // query the size of the string
	if (len < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.utsname) returned %d\n", __LINE__, len);
		goto out;
	}
	printf("lxc.utsname returned %d\n", len);

	// allocate the length of string + 1 for trailing \0
	alloced = malloc(len+1);
	if (!alloced) {
		fprintf(stderr, "%d: failed to allocate %d bytes for utsname\n", __LINE__, len);
		goto out;
	}

	// now pass in the malloc'd array, and pass in length of string + 1: again
	// because we need room for the trailing \0
	ret = c->get_config_item(c, "lxc.uts.name", alloced, len+1);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.utsname) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (strcmp(alloced, HNAME) != 0 || ret != len) {
		fprintf(stderr, "lxc.utsname returned wrong value: %d %s not %d %s\n", ret, alloced, len, HNAME);
		goto out;
	}
	printf("lxc.utsname returned %d %s\n", len, alloced);
	free(alloced);

	if (!c->set_config_item(c, "lxc.mount.entry", "hi there")) {
		fprintf(stderr, "%d: failed to set mount.entry\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.mount.entry", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.mount.entry) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("lxc.mount.entry returned %d %s\n", ret, v2);

	ret = c->get_config_item(c, "lxc.prlimit", v3, 2047);
	if (ret != 0) {
		fprintf(stderr, "%d: get_config_item(limit) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (!c->set_config_item(c, "lxc.prlimit.nofile", "1234:unlimited")) {
		fprintf(stderr, "%d: failed to set limit.nofile\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.prlimit.nofile", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.prlimit.nofile) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (strcmp(v2, "1234:unlimited")) {
		fprintf(stderr, "%d: lxc.prlimit.nofile returned wrong value: %d %s not 14 1234:unlimited\n", __LINE__, ret, v2);
		goto out;
	}
	printf("lxc.prlimit.nofile returned %d %s\n", ret, v2);

	if (!c->set_config_item(c, "lxc.prlimit.stack", "unlimited")) {
		fprintf(stderr, "%d: failed to set limit.stack\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.prlimit.stack", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.prlimit.stack) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (strcmp(v2, "unlimited")) {
		fprintf(stderr, "%d: lxc.prlimit.stack returned wrong value: %d %s not 9 unlimited\n", __LINE__, ret, v2);
		goto out;
	}
	printf("lxc.prlimit.stack returned %d %s\n", ret, v2);

#define LIMIT_STACK "lxc.prlimit.stack = unlimited\n"
#define ALL_LIMITS "lxc.prlimit.nofile = 1234:unlimited\n" LIMIT_STACK
	ret = c->get_config_item(c, "lxc.prlimit", v3, 2047);
	if (ret != sizeof(ALL_LIMITS)-1) {
		fprintf(stderr, "%d: get_config_item(limit) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (strcmp(v3, ALL_LIMITS)) {
		fprintf(stderr, "%d: lxc.prlimit returned wrong value: %d %s not %d %s\n", __LINE__, ret, v3, (int)sizeof(ALL_LIMITS)-1, ALL_LIMITS);
		goto out;
	}
	printf("lxc.prlimit returned %d %s\n", ret, v3);

	if (!c->clear_config_item(c, "lxc.prlimit.nofile")) {
		fprintf(stderr, "%d: failed clearing limit.nofile\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.prlimit", v3, 2047);
	if (ret != sizeof(LIMIT_STACK)-1) {
		fprintf(stderr, "%d: get_config_item(limit) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (strcmp(v3, LIMIT_STACK)) {
		fprintf(stderr, "%d: lxc.prlimit returned wrong value: %d %s not %d %s\n", __LINE__, ret, v3, (int)sizeof(LIMIT_STACK)-1, LIMIT_STACK);
		goto out;
	}
	printf("lxc.prlimit returned %d %s\n", ret, v3);

#define SYSCTL_SOMAXCONN "lxc.sysctl.net.core.somaxconn = 256\n"
#define ALL_SYSCTLS "lxc.sysctl.net.ipv4.ip_forward = 1\n" SYSCTL_SOMAXCONN

	ret = c->get_config_item(c, "lxc.sysctl", v3, 2047);
	if (ret != 0) {
		fprintf(stderr, "%d: get_config_item(sysctl) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (!c->set_config_item(c, "lxc.sysctl.net.ipv4.ip_forward", "1")) {
		fprintf(stderr, "%d: failed to set lxc.sysctl.net.ipv4.ip_forward\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.sysctl.net.ipv4.ip_forward", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.sysctl.net.ipv4.ip_forward) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (strcmp(v2, "1")) {
		fprintf(stderr, "%d: lxc.sysctl.net.ipv4.ip_forward returned wrong value: %d %s not 1\n", __LINE__, ret, v2);
		goto out;
	}
	printf("lxc.sysctl.net.ipv4.ip_forward returned %d %s\n", ret, v2);

	if (!c->set_config_item(c, "lxc.sysctl.net.core.somaxconn", "256")) {
		fprintf(stderr, "%d: failed to set lxc.sysctl.net.core.somaxconn\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.sysctl.net.core.somaxconn", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.sysctl.net.core.somaxconn) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (strcmp(v2, "256")) {
		fprintf(stderr, "%d: lxc.sysctl.net.core.somaxconn returned wrong value: %d %s not 256\n", __LINE__, ret, v2);
		goto out;
	}
	printf("lxc.sysctl.net.core.somaxconn returned %d %s\n", ret, v2);

	ret = c->get_config_item(c, "lxc.sysctl", v3, 2047);
	if (ret != sizeof(ALL_SYSCTLS)-1) {
		fprintf(stderr, "%d: get_config_item(sysctl) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (strcmp(v3, ALL_SYSCTLS)) {
		fprintf(stderr, "%d: lxc.sysctl returned wrong value: %d %s not %d %s\n", __LINE__, ret, v3, (int)sizeof(ALL_SYSCTLS) - 1, ALL_SYSCTLS);
		goto out;
	}
	printf("lxc.sysctl returned %d %s\n", ret, v3);

	if (!c->clear_config_item(c, "lxc.sysctl.net.ipv4.ip_forward")) {
		fprintf(stderr, "%d: failed clearing lxc.sysctl.net.ipv4.ip_forward\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.sysctl", v3, 2047);
	if (ret != sizeof(SYSCTL_SOMAXCONN) - 1) {
		fprintf(stderr, "%d: get_config_item(sysctl) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (strcmp(v3, SYSCTL_SOMAXCONN)) {
		fprintf(stderr, "%d: lxc.sysctl returned wrong value: %d %s not %d %s\n", __LINE__, ret, v3, (int)sizeof(SYSCTL_SOMAXCONN) - 1, SYSCTL_SOMAXCONN);
		goto out;
	}
	printf("lxc.sysctl returned %d %s\n", ret, v3);

#define PROC_OOM_SCORE_ADJ "lxc.proc.oom_score_adj = 10\n"
#define ALL_PROCS "lxc.proc.setgroups = allow\n" PROC_OOM_SCORE_ADJ

	ret = c->get_config_item(c, "lxc.proc", v3, 2047);
	if (ret != 0) {
		fprintf(stderr, "%d: get_config_item(proc) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (!c->set_config_item(c, "lxc.proc.setgroups", "allow")) {
		fprintf(stderr, "%d: failed to set lxc.proc.setgroups\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.proc.setgroups", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.proc.setgroups) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (strcmp(v2, "allow")) {
		fprintf(stderr, "%d: lxc.proc.setgroups returned wrong value: %d %s not 10\n", __LINE__, ret, v2);
		goto out;
	}
	printf("lxc.proc.setgroups returned %d %s\n", ret, v2);

	if (!c->set_config_item(c, "lxc.proc.oom_score_adj", "10")) {
		fprintf(stderr, "%d: failed to set lxc.proc.oom_score_adj\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.proc.oom_score_adj", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.proc.oom_score_adj) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (strcmp(v2, "10")) {
		fprintf(stderr, "%d: lxc.proc.oom_score_adj returned wrong value: %d %s not 10\n", __LINE__, ret, v2);
		goto out;
	}
	printf("lxc.proc.oom_score_adj returned %d %s\n", ret, v2);

	ret = c->get_config_item(c, "lxc.proc", v3, 2047);
	if (ret != sizeof(ALL_PROCS)-1) {
		fprintf(stderr, "%d: get_config_item(proc) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (strcmp(v3, ALL_PROCS)) {
		fprintf(stderr, "%d: lxc.proc returned wrong value: %d %s not %d %s\n", __LINE__, ret, v3, (int)sizeof(ALL_PROCS) - 1, ALL_PROCS);
		goto out;
	}
	printf("lxc.proc returned %d %s\n", ret, v3);

	if (!c->clear_config_item(c, "lxc.proc.setgroups")) {
		fprintf(stderr, "%d: failed clearing lxc.proc.setgroups\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.proc", v3, 2047);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(proc) returned %d\n", __LINE__, ret);
		goto out;
	}

	if (strcmp(v3, PROC_OOM_SCORE_ADJ)) {
		fprintf(stderr, "%d: lxc.proc returned wrong value: %d %s not %d %s\n", __LINE__, ret, v3, (int)sizeof(PROC_OOM_SCORE_ADJ) - 1, PROC_OOM_SCORE_ADJ);
		goto out;
	}
	printf("lxc.proc returned %d %s\n", ret, v3);

	if (!c->set_config_item(c, "lxc.apparmor.profile", "unconfined")) {
		fprintf(stderr, "%d: failed to set aa_profile\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.apparmor.profile", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.aa_profile) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("lxc.aa_profile returned %d %s\n", ret, v2);

	lxc_container_put(c);

	// new test with real container
	if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
		fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
		goto out;
	}
	c->destroy(c);
	lxc_container_put(c);

	if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
		fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
		goto out;
	}

	if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) {
		fprintf(stderr, "%d: failed to create a trusty container\n", __LINE__);
		goto out;
	}
	lxc_container_put(c);

	/* XXX TODO load_config needs to clear out any old config first */
	if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
		fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.cap.drop", NULL, 300);
	if (ret < 5 || ret > 255) {
		fprintf(stderr, "%d: get_config_item(lxc.cap.drop) with NULL returned %d\n", __LINE__, ret);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.cap.drop", v1, 1);
	if (ret < 5 || ret > 255) {
		fprintf(stderr, "%d: get_config_item(lxc.cap.drop) returned %d\n", __LINE__, ret);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.cap.drop", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.cap.drop) returned %d %s\n", __LINE__, ret, v2);
		goto out;
	}
	printf("%d: get_config_item(lxc.cap.drop) returned %d %s\n", __LINE__, ret, v2);

	ret = c->get_config_item(c, "lxc.net", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.net) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("%d: get_config_item(lxc.net) returned %d %s\n", __LINE__, ret, v2);

	if (!c->set_config_item(c, "lxc.net.0.type", "veth")) {
		fprintf(stderr, "%d: failed to set lxc.net.0.type\n", __LINE__);
		goto out;
	}

	if (!c->set_config_item(c, "lxc.net.0.link", "lxcbr0")) {
		fprintf(stderr, "%d: failed to set network.link\n", __LINE__);
		goto out;
	}

	if (!c->set_config_item(c, "lxc.net.0.flags", "up")) {
		fprintf(stderr, "%d: failed to set network.flags\n", __LINE__);
		goto out;
	}

	if (!c->set_config_item(c, "lxc.net.0.hwaddr", "00:16:3e:xx:xx:xx")) {
		fprintf(stderr, "%d: failed to set network.hwaddr\n", __LINE__);
		goto out;
	}

	if (!c->set_config_item(c, "lxc.net.0.ipv4.address", "10.2.3.4")) {
		fprintf(stderr, "%d: failed to set ipv4\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.net.0.ipv4.address", v2, 255);
	if (ret <= 0) {
		fprintf(stderr, "%d: lxc.net.0.ipv4 returned %d\n", __LINE__, ret);
		goto out;
	}

	if (!c->clear_config_item(c, "lxc.net.0.ipv4.address")) {
		fprintf(stderr, "%d: failed clearing all ipv4 entries\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.net.0.ipv4.address", v2, 255);
	if (ret != 0) {
		fprintf(stderr, "%d: after clearing ipv4 entries get_item(lxc.network.0.ipv4 returned %d\n", __LINE__, ret);
		goto out;
	}

	if (!c->set_config_item(c, "lxc.net.0.ipv4.gateway", "10.2.3.254")) {
		fprintf(stderr, "%d: failed to set ipv4.gateway\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.net.0.ipv4.gateway", v2, 255);
	if (ret <= 0) {
		fprintf(stderr, "%d: lxc.net.0.ipv4.gateway returned %d\n", __LINE__, ret);
		goto out;
	}

	if (!c->set_config_item(c, "lxc.net.0.ipv4.gateway", "")) {
		fprintf(stderr, "%d: failed clearing ipv4.gateway\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.net.0.ipv4.gateway", v2, 255);
	if (ret != 0) {
		fprintf(stderr, "%d: after clearing ipv4.gateway get_item(lxc.network.0.ipv4.gateway returned %d\n", __LINE__, ret);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.net.0.link", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("%d: get_config_item (link) returned %d %s\n", __LINE__, ret, v2);

	ret = c->get_config_item(c, "lxc.net.0.name", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("%d: get_config_item (name) returned %d %s\n", __LINE__, ret, v2);

	if (!c->clear_config_item(c, "lxc.net")) {
		fprintf(stderr, "%d: clear_config_item failed\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.net", v2, 255);
	if (ret != 0) {
		fprintf(stderr, "%d: network was not actually cleared (get_network returned %d)\n", __LINE__, ret);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.cgroup", v3, 2047);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(cgroup.devices) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("%d: get_config_item (cgroup.devices) returned %d %s\n", __LINE__, ret, v3);

	ret = c->get_config_item(c, "lxc.cgroup.devices.allow", v3, 2047);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(cgroup.devices.devices.allow) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("%d: get_config_item (cgroup.devices.devices.allow) returned %d %s\n", __LINE__, ret, v3);

	if (!c->clear_config_item(c, "lxc.cgroup")) {
		fprintf(stderr, "%d: failed clearing lxc.cgroup\n", __LINE__);
		goto out;
	}

	if (!c->clear_config_item(c, "lxc.cap.drop")) {
		fprintf(stderr, "%d: failed clearing lxc.cap.drop\n", __LINE__);
		goto out;
	}

	if (!c->clear_config_item(c, "lxc.mount.entry")) {
		fprintf(stderr, "%d: failed clearing lxc.mount.entry\n", __LINE__);
		goto out;
	}

	if (!c->clear_config_item(c, "lxc.hook")) {
		fprintf(stderr, "%d: failed clearing lxc.hook\n", __LINE__);
		goto out;
	}

	if (!lxc_config_item_is_supported("lxc.arch")) {
		fprintf(stderr, "%d: failed to report \"lxc.arch\" as supported configuration item\n", __LINE__);
		goto out;
	}

	if (lxc_config_item_is_supported("lxc.nonsense")) {
		fprintf(stderr, "%d: failed to detect \"lxc.nonsense\" as unsupported configuration item\n", __LINE__);
		goto out;
	}

	if (c->set_config_item(c, "lxc.notaconfigkey", "invalid")) {
		fprintf(stderr, "%d: Managed to set \"lxc.notaconfigkey\"\n", __LINE__);
		goto out;
	}


	printf("All get_item tests passed\n");
	fret = EXIT_SUCCESS;

out:
	if (c) {
		c->destroy(c);
		lxc_container_put(c);
	}

	exit(fret);
}
Beispiel #13
0
int main(int argc, char *argv[])
{
	int i, j;
	pthread_attr_t attr;
	pthread_t threads[10];
	struct thread_args args[10];
	struct lxc_container *c;
	int ret = EXIT_FAILURE;

	c = lxc_container_new("state-server", NULL);
	if (!c) {
		lxc_error("%s", "Failed to create container \"state-server\"");
		exit(ret);
	}

	if (c->is_defined(c)) {
		lxc_error("%s\n", "Container \"state-server\" is defined");
		goto on_error_put;
	}

	if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) {
		lxc_error("%s\n", "Failed to create busybox container \"state-server\"");
		goto on_error_put;
	}

	if (!c->is_defined(c)) {
		lxc_error("%s\n", "Container \"state-server\" is not defined");
		goto on_error_put;
	}

	c->clear_config(c);

	if (!c->load_config(c, NULL)) {
		lxc_error("%s\n", "Failed to load config for container \"state-server\"");
		goto on_error_stop;
	}

	if (!c->want_daemonize(c, true)) {
		lxc_error("%s\n", "Failed to mark container \"state-server\" daemonized");
		goto on_error_stop;
	}

	pthread_attr_init(&attr);

	for (j = 0; j < 10; j++) {
		lxc_debug("Starting state server test iteration %d\n", j);

		if (!c->startl(c, 0, NULL)) {
			lxc_error("%s\n", "Failed to start container \"state-server\" daemonized");
			goto on_error_stop;
		}

		sleep(5);

		for (i = 0; i < 10; i++) {
			int ret;

			args[i].thread_id = i;
			args[i].c = c;
			args[i].timeout = -1;
			/* test non-blocking shutdown request */
			if (i == 0)
				args[i].timeout = 0;

			ret = pthread_create(&threads[i], &attr, state_wrapper, (void *) &args[i]);
			if (ret != 0)
				goto on_error_stop;
		}

		for (i = 0; i < 10; i++) {
			int ret;

			ret = pthread_join(threads[i], NULL);
			if (ret != 0)
				goto on_error_stop;

			if (!args[i].success) {
				lxc_error("State server thread %d failed\n", args[i].thread_id);
				goto on_error_stop;
			}
		}
	}

	ret = EXIT_SUCCESS;

on_error_stop:
	if (c->is_running(c) && !c->stop(c))
		lxc_error("%s\n", "Failed to stop container \"state-server\"");

	if (!c->destroy(c))
		lxc_error("%s\n", "Failed to destroy container \"state-server\"");

on_error_put:
	lxc_container_put(c);
	if (ret == EXIT_SUCCESS)
		lxc_debug("%s\n", "All state server tests passed");
	exit(ret);
}
Beispiel #14
0
void *ns_sharing_wrapper(void *data)
{
	int init_pid;
	ssize_t ret;
	char name[100];
	char owning_ns_init_pid[100];
	char proc_ns_path[4096];
	char ns_buf[4096];
	struct lxc_container *c;
	struct thread_args *args = data;

	lxc_debug("Starting namespace sharing thread %d\n", args->thread_id);

	sprintf(name, "share-ns-%d", args->thread_id);
	c = lxc_container_new(name, NULL);
	if (!c) {
		lxc_error("Failed to create container \"%s\"\n", name);
		return NULL;
	}

	if (c->is_defined(c)) {
		lxc_error("Container \"%s\" is defined\n", name);
		goto out;
	}

	if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) {
		lxc_error("Failed to create busybox container \"%s\"\n", name);
		goto out;
	}

	if (!c->is_defined(c)) {
		lxc_error("Container \"%s\" is not defined\n", name);
		goto out;
	}

	if (!c->load_config(c, NULL)) {
		lxc_error("Failed to load config for container \"%s\"\n", name);
		goto out;
	}

	/* share ipc namespace by container name */
	if (!c->set_config_item(c, "lxc.namespace.share.ipc", "owning-ns")) {
		lxc_error("Failed to set \"lxc.namespace.share.ipc=owning-ns\" for container \"%s\"\n", name);
		goto out;
	}

	/* clear all network configuration */
	if (!c->set_config_item(c, "lxc.net", "")) {
		lxc_error("Failed to set \"lxc.namespace.share.ipc=owning-ns\" for container \"%s\"\n", name);
		goto out;
	}

	if (!c->set_config_item(c, "lxc.net.0.type", "empty")) {
		lxc_error("Failed to set \"lxc.net.0.type=empty\" for container \"%s\"\n", name);
		goto out;
	}

	sprintf(owning_ns_init_pid, "%d", args->init_pid);
	/* share net namespace by pid */
	if (!c->set_config_item(c, "lxc.namespace.share.net", owning_ns_init_pid)) {
		lxc_error("Failed to set \"lxc.namespace.share.net=%s\" for container \"%s\"\n", owning_ns_init_pid, name);
		goto out;
	}

	if (!c->want_daemonize(c, true)) {
		lxc_error("Failed to mark container \"%s\" daemonized\n", name);
		goto out;
	}

	if (!c->startl(c, 0, NULL)) {
		lxc_error("Failed to start container \"%s\" daemonized\n", name);
		goto out;
	}

	init_pid = c->init_pid(c);
	if (init_pid < 0) {
		lxc_error("Failed to retrieve init pid of container \"%s\"\n", name);
		goto out;
	}

	/* Check whether we correctly inherited the ipc namespace. */
	ret = snprintf(proc_ns_path, sizeof(proc_ns_path), "/proc/%d/ns/ipc", init_pid);
	if (ret < 0 || (size_t)ret >= sizeof(proc_ns_path)) {
		lxc_error("Failed to create string for container \"%s\"\n", name);
		goto out;
	}

	ret = readlink(proc_ns_path, ns_buf, sizeof(ns_buf));
	if (ret < 0 || (size_t)ret >= sizeof(ns_buf)) {
		lxc_error("Failed to retrieve ipc namespace for container \"%s\"\n", name);
		goto out;
	}
	ns_buf[ret] = '\0';

	if (strcmp(args->inherited_ipc_ns, ns_buf) != 0) {
		lxc_error("Failed to inherit ipc namespace from container \"owning-ns\": %s != %s\n", args->inherited_ipc_ns, ns_buf);
		goto out;
	}
	lxc_debug("Inherited ipc namespace from container \"owning-ns\": %s == %s\n", args->inherited_ipc_ns, ns_buf);

	/* Check whether we correctly inherited the net namespace. */
	ret = snprintf(proc_ns_path, sizeof(proc_ns_path), "/proc/%d/ns/net", init_pid);
	if (ret < 0 || (size_t)ret >= sizeof(proc_ns_path)) {
		lxc_error("Failed to create string for container \"%s\"\n", name);
		goto out;
	}

	ret = readlink(proc_ns_path, ns_buf, sizeof(ns_buf));
	if (ret < 0 || (size_t)ret >= sizeof(ns_buf)) {
		lxc_error("Failed to retrieve ipc namespace for container \"%s\"\n", name);
		goto out;
	}
	ns_buf[ret] = '\0';

	if (strcmp(args->inherited_net_ns, ns_buf) != 0) {
		lxc_error("Failed to inherit net namespace from container \"owning-ns\": %s != %s\n", args->inherited_net_ns, ns_buf);
		goto out;
	}
	lxc_debug("Inherited net namespace from container \"owning-ns\": %s == %s\n", args->inherited_net_ns, ns_buf);

	args->success = true;

out:
	if (c->is_running(c) && !c->stop(c)) {
		lxc_error("Failed to stop container \"%s\"\n", name);
		goto out;
	}

	if (!c->destroy(c)) {
		lxc_error("Failed to destroy container \"%s\"\n", name);
		goto out;
	}

	pthread_exit(NULL);
	return NULL;
}
Beispiel #15
0
int main(int argc, char *argv[])
{
	int i, init_pid, j;
	char proc_ns_path[4096];
	char ipc_ns_buf[4096];
	char net_ns_buf[4096];
	pthread_attr_t attr;
	pthread_t threads[10];
	struct thread_args args[10];
	struct lxc_container *c;
	int ret = EXIT_FAILURE;

	c = lxc_container_new("owning-ns", NULL);
	if (!c) {
		lxc_error("%s", "Failed to create container \"owning-ns\"");
		exit(ret);
	}

	if (c->is_defined(c)) {
		lxc_error("%s\n", "Container \"owning-ns\" is defined");
		goto on_error_put;
	}

	if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) {
		lxc_error("%s\n", "Failed to create busybox container \"owning-ns\"");
		goto on_error_put;
	}

	if (!c->is_defined(c)) {
		lxc_error("%s\n", "Container \"owning-ns\" is not defined");
		goto on_error_put;
	}

	c->clear_config(c);

	if (!c->load_config(c, NULL)) {
		lxc_error("%s\n", "Failed to load config for container \"owning-ns\"");
		goto on_error_stop;
	}

	if (!c->want_daemonize(c, true)) {
		lxc_error("%s\n", "Failed to mark container \"owning-ns\" daemonized");
		goto on_error_stop;
	}

	if (!c->startl(c, 0, NULL)) {
		lxc_error("%s\n", "Failed to start container \"owning-ns\" daemonized");
		goto on_error_stop;
	}

	init_pid = c->init_pid(c);
	if (init_pid < 0) {
		lxc_error("%s\n", "Failed to retrieve init pid of container \"owning-ns\"");
		goto on_error_stop;
	}

	/* record our ipc namespace */
	ret = snprintf(proc_ns_path, sizeof(proc_ns_path), "/proc/%d/ns/ipc", init_pid);
	if (ret < 0 || (size_t)ret >= sizeof(proc_ns_path)) {
		lxc_error("%s\n", "Failed to create string for container \"owning-ns\"");
		goto on_error_stop;
	}

	ret = readlink(proc_ns_path, ipc_ns_buf, sizeof(ipc_ns_buf));
	if (ret < 0 || (size_t)ret >= sizeof(ipc_ns_buf)) {
		lxc_error("%s\n", "Failed to retrieve ipc namespace for container \"owning-ns\"");
		goto on_error_stop;

	}
	ipc_ns_buf[ret] = '\0';

	/* record our net namespace */
	ret = snprintf(proc_ns_path, sizeof(proc_ns_path), "/proc/%d/ns/net", init_pid);
	if (ret < 0 || (size_t)ret >= sizeof(proc_ns_path)) {
		lxc_error("%s\n", "Failed to create string for container \"owning-ns\"");
		goto on_error_stop;
	}

	ret = readlink(proc_ns_path, net_ns_buf, sizeof(net_ns_buf));
	if (ret < 0 || (size_t)ret >= sizeof(net_ns_buf)) {
		lxc_error("%s\n", "Failed to retrieve ipc namespace for container \"owning-ns\"");
		goto on_error_stop;
	}
	net_ns_buf[ret] = '\0';

	sleep(5);

	pthread_attr_init(&attr);

	for (j = 0; j < 10; j++) {
		lxc_debug("Starting namespace sharing test iteration %d\n", j);

		for (i = 0; i < 10; i++) {
			int ret;

			args[i].thread_id = i;
			args[i].success = false;
			args[i].init_pid = init_pid;
			args[i].inherited_ipc_ns = ipc_ns_buf;
			args[i].inherited_net_ns = net_ns_buf;

			ret = pthread_create(&threads[i], &attr, ns_sharing_wrapper, (void *) &args[i]);
			if (ret != 0)
				goto on_error_stop;
		}

		for (i = 0; i < 10; i++) {
			int ret;

			ret = pthread_join(threads[i], NULL);
			if (ret != 0)
				goto on_error_stop;

			if (!args[i].success) {
				lxc_error("ns sharing thread %d failed\n", args[i].thread_id);
				goto on_error_stop;
			}
		}
	}

	ret = EXIT_SUCCESS;

on_error_stop:
	if (c->is_running(c) && !c->stop(c))
		lxc_error("%s\n", "Failed to stop container \"owning-ns\"");

	if (!c->destroy(c))
		lxc_error("%s\n", "Failed to destroy container \"owning-ns\"");

on_error_put:
	lxc_container_put(c);
	if (ret == EXIT_SUCCESS)
		lxc_debug("%s\n", "All state namespace sharing tests passed");
	exit(ret);
}
Beispiel #16
0
int main(int argc, char *argv[])
{
	int ret = EXIT_FAILURE;
	struct lxc_container *c;
	char v1[2], v2[256], v3[2048];

	if ((c = lxc_container_new("testxyz", NULL)) == NULL) {
		fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
		exit(EXIT_FAILURE);
	}

	/* EXPECT SUCCESS: lxc.syslog with valid value. */
	if (!c->set_config_item(c, "lxc.syslog", "local0")) {
		lxc_error("%s\n", "Failed to set lxc.syslog.\n");
		goto out;
	}
	ret = c->get_config_item(c, "lxc.syslog", v2, 255);
	if (ret < 0) {
		lxc_error("Failed to retrieve lxc.syslog: %d.\n", ret);
		goto out;
	}
	if (strcmp(v2, "local0") != 0) {
		lxc_error("Expected: local0 == %s.\n", v2);
		goto out;
	}
	lxc_debug("Retrieving value for lxc.syslog correctly returned: %s.\n", v2);

	/* EXPECT FAILURE: lxc.syslog with invalid value. */
	if (c->set_config_item(c, "lxc.syslog", "NONSENSE")) {
		lxc_error("%s\n", "Succeeded int setting lxc.syslog to invalid value \"NONSENSE\".\n");
		goto out;
	}
	lxc_debug("%s\n", "Successfully failed to set lxc.syslog to invalid value.\n");

	if (!c->set_config_item(c, "lxc.hook.pre-start", "hi there")) {
		fprintf(stderr, "%d: failed to set hook.pre-start\n", __LINE__);
		goto out;
	}
	ret = c->get_config_item(c, "lxc.hook.pre-start", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.hook.pre-start) returned %d\n", __LINE__, ret);
		goto out;
	}
	fprintf(stderr, "lxc.hook.pre-start returned %d %s\n", ret, v2);

	ret = c->get_config_item(c, "lxc.network", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret);
		goto out;
	}
	fprintf(stderr, "%d: get_config_item(lxc.network) returned %d %s\n", __LINE__, ret, v2);
	if (!c->set_config_item(c, "lxc.tty", "4")) {
		fprintf(stderr, "%d: failed to set tty\n", __LINE__);
		goto out;
	}
	ret = c->get_config_item(c, "lxc.tty", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.tty) returned %d\n", __LINE__, ret);
		goto out;
	}
	fprintf(stderr, "lxc.tty returned %d %s\n", ret, v2);

	if (!c->set_config_item(c, "lxc.arch", "x86")) {
		fprintf(stderr, "%d: failed to set arch\n", __LINE__);
		goto out;
	}
	ret = c->get_config_item(c, "lxc.arch", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.arch) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("lxc.arch returned %d %s\n", ret, v2);

	if (!c->set_config_item(c, "lxc.init_uid", "100")) {
		fprintf(stderr, "%d: failed to set init_uid\n", __LINE__);
		goto out;
	}
	ret = c->get_config_item(c, "lxc.init_uid", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.init_uid) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("lxc.init_uid returned %d %s\n", ret, v2);

	if (!c->set_config_item(c, "lxc.init_gid", "100")) {
		fprintf(stderr, "%d: failed to set init_gid\n", __LINE__);
		goto out;
	}
	ret = c->get_config_item(c, "lxc.init_gid", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.init_gid) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("lxc.init_gid returned %d %s\n", ret, v2);

#define HNAME "hostname1"
	// demonstrate proper usage:
	char *alloced;
	if (!c->set_config_item(c, "lxc.utsname", HNAME)) {
		fprintf(stderr, "%d: failed to set utsname\n", __LINE__);
		goto out;
	}

	int len;
	len = c->get_config_item(c, "lxc.utsname", NULL, 0);  // query the size of the string
	if (len < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.utsname) returned %d\n", __LINE__, len);
		goto out;
	}
	printf("lxc.utsname returned %d\n", len);

	// allocate the length of string + 1 for trailing \0
	alloced = malloc(len+1);
	if (!alloced) {
		fprintf(stderr, "%d: failed to allocate %d bytes for utsname\n", __LINE__, len);
		goto out;
	}
	// now pass in the malloc'd array, and pass in length of string + 1: again
	// because we need room for the trailing \0
	ret = c->get_config_item(c, "lxc.utsname", alloced, len+1);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.utsname) returned %d\n", __LINE__, ret);
		goto out;
	}
	if (strcmp(alloced, HNAME) != 0 || ret != len) {
		fprintf(stderr, "lxc.utsname returned wrong value: %d %s not %d %s\n", ret, alloced, len, HNAME);
		goto out;
	}
	printf("lxc.utsname returned %d %s\n", len, alloced);
	free(alloced);

	if (!c->set_config_item(c, "lxc.mount.entry", "hi there")) {
		fprintf(stderr, "%d: failed to set mount.entry\n", __LINE__);
		goto out;
	}
	ret = c->get_config_item(c, "lxc.mount.entry", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.mount.entry) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("lxc.mount.entry returned %d %s\n", ret, v2);

	if (!c->set_config_item(c, "lxc.aa_profile", "unconfined")) {
		fprintf(stderr, "%d: failed to set aa_profile\n", __LINE__);
		goto out;
	}
	ret = c->get_config_item(c, "lxc.aa_profile", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.aa_profile) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("lxc.aa_profile returned %d %s\n", ret, v2);

	lxc_container_put(c);

	// new test with real container
	if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
		fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
		goto out;
	}
	c->destroy(c);
	lxc_container_put(c);

	if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
		fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
		goto out;
	}
	if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) {
		fprintf(stderr, "%d: failed to create a trusty container\n", __LINE__);
		goto out;
	}
	lxc_container_put(c);

	/* XXX TODO load_config needs to clear out any old config first */
	if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
		fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.cap.drop", NULL, 300);
	if (ret < 5 || ret > 255) {
		fprintf(stderr, "%d: get_config_item(lxc.cap.drop) with NULL returned %d\n", __LINE__, ret);
		goto out;
	}
	ret = c->get_config_item(c, "lxc.cap.drop", v1, 1);
	if (ret < 5 || ret > 255) {
		fprintf(stderr, "%d: get_config_item(lxc.cap.drop) returned %d\n", __LINE__, ret);
		goto out;
	}
	ret = c->get_config_item(c, "lxc.cap.drop", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(lxc.cap.drop) returned %d %s\n", __LINE__, ret, v2);
		goto out;
	}
	printf("%d: get_config_item(lxc.cap.drop) returned %d %s\n", __LINE__, ret, v2);
	ret = c->get_config_item(c, "lxc.network", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("%d: get_config_item(lxc.network) returned %d %s\n", __LINE__, ret, v2);

	if (!c->set_config_item(c, "lxc.network.ipv4", "10.2.3.4")) {
		fprintf(stderr, "%d: failed to set ipv4\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.network.0.ipv4", v2, 255);
	if (ret <= 0) {
		fprintf(stderr, "%d: lxc.network.0.ipv4 returned %d\n", __LINE__, ret);
		goto out;
	}
	if (!c->clear_config_item(c, "lxc.network.0.ipv4")) {
		fprintf(stderr, "%d: failed clearing all ipv4 entries\n", __LINE__);
		goto out;
	}
	ret = c->get_config_item(c, "lxc.network.0.ipv4", v2, 255);
	if (ret != 0) {
		fprintf(stderr, "%d: after clearing ipv4 entries get_item(lxc.network.0.ipv4 returned %d\n", __LINE__, ret);
		goto out;
	}

	if (!c->set_config_item(c, "lxc.network.ipv4.gateway", "10.2.3.254")) {
		fprintf(stderr, "%d: failed to set ipv4.gateway\n", __LINE__);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.network.0.ipv4.gateway", v2, 255);
	if (ret <= 0) {
		fprintf(stderr, "%d: lxc.network.0.ipv4.gateway returned %d\n", __LINE__, ret);
		goto out;
	}
	if (!c->set_config_item(c, "lxc.network.0.ipv4.gateway", "")) {
		fprintf(stderr, "%d: failed clearing ipv4.gateway\n", __LINE__);
		goto out;
	}
	ret = c->get_config_item(c, "lxc.network.0.ipv4.gateway", v2, 255);
	if (ret != 0) {
		fprintf(stderr, "%d: after clearing ipv4.gateway get_item(lxc.network.0.ipv4.gateway returned %d\n", __LINE__, ret);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.network.0.link", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("%d: get_config_item (link) returned %d %s\n", __LINE__, ret, v2);
	ret = c->get_config_item(c, "lxc.network.0.name", v2, 255);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("%d: get_config_item (name) returned %d %s\n", __LINE__, ret, v2);

	if (!c->clear_config_item(c, "lxc.network")) {
		fprintf(stderr, "%d: clear_config_item failed\n", __LINE__);
		goto out;
	}
	ret = c->get_config_item(c, "lxc.network", v2, 255);
	if (ret != 0) {
		fprintf(stderr, "%d: network was not actually cleared (get_network returned %d)\n", __LINE__, ret);
		goto out;
	}

	ret = c->get_config_item(c, "lxc.cgroup", v3, 2047);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(cgroup.devices) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("%d: get_config_item (cgroup.devices) returned %d %s\n", __LINE__, ret, v3);

	ret = c->get_config_item(c, "lxc.cgroup.devices.allow", v3, 2047);
	if (ret < 0) {
		fprintf(stderr, "%d: get_config_item(cgroup.devices.devices.allow) returned %d\n", __LINE__, ret);
		goto out;
	}
	printf("%d: get_config_item (cgroup.devices.devices.allow) returned %d %s\n", __LINE__, ret, v3);

	if (!c->clear_config_item(c, "lxc.cgroup")) {
		fprintf(stderr, "%d: failed clearing lxc.cgroup\n", __LINE__);
		goto out;
	}
	if (!c->clear_config_item(c, "lxc.cap.drop")) {
		fprintf(stderr, "%d: failed clearing lxc.cap.drop\n", __LINE__);
		goto out;
	}
	if (!c->clear_config_item(c, "lxc.mount.entry")) {
		fprintf(stderr, "%d: failed clearing lxc.mount.entry\n", __LINE__);
		goto out;
	}
	if (!c->clear_config_item(c, "lxc.hook")) {
		fprintf(stderr, "%d: failed clearing lxc.hook\n", __LINE__);
		goto out;
	}
	printf("All get_item tests passed\n");
	ret = EXIT_SUCCESS;
out:
	c->destroy(c);
	lxc_container_put(c);
	exit(ret);
}