示例#1
0
文件: lxcpath.c 项目: 4b42/lxc
int main()
{
	struct lxc_container *c;
	const char *p1, *p2;
	int retval = -1;

	c = lxc_container_new(MYNAME, NULL);
	if (!c) {
		TSTERR("create using default path");
		goto err;
	}
	p1 = c->get_config_path(c);
	p2 = c->config_file_name(c);
	if (!p1 || !p2 || strncmp(p1, p2, strlen(p1))) {
		TSTERR("Bad result for path names");
		goto err;
	}

#define CPATH "/boo"
#define FPATH "/boo/lxctest1/config"
	if (!c->set_config_path(c, "/boo")) {
		TSTERR("Error setting custom path");
		goto err;
	}
	p1 = c->get_config_path(c);
	p2 = c->config_file_name(c);
	if (strcmp(p1, CPATH) || strcmp(p2, FPATH)) {
		TSTERR("Bad result for path names after set_config_path()");
		goto err;
	}
	lxc_container_put(c);

	c = lxc_container_new(MYNAME, CPATH);
	if (!c) {
		TSTERR("create using custom path");
		goto err;
	}

	p1 = c->get_config_path(c);
	p2 = c->config_file_name(c);
	if (strcmp(p1, CPATH) || strcmp(p2, FPATH)) {
		TSTERR("Bad result for path names after create with custom path");
		goto err;
	}

	retval = 0;

err:
	lxc_container_put(c);
	return retval;
}
示例#2
0
文件: lxc.c 项目: asmundg/lxc
static int
Container_init(Container *self, PyObject *args, PyObject *kwds)
{
    static char *kwlist[] = {"name", "config_path", NULL};
    char *name = NULL;
    PyObject *fs_config_path = NULL;
    char *config_path = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|O&", kwlist,
                                      &name,
                                      PyUnicode_FSConverter, &fs_config_path))
        return -1;

    if (fs_config_path != NULL) {
        config_path = PyBytes_AS_STRING(fs_config_path);
        assert(config_path != NULL);
    }

    self->container = lxc_container_new(name, config_path);
    if (!self->container) {
        Py_XDECREF(fs_config_path);
        fprintf(stderr, "%d: error creating container %s\n", __LINE__, name);
        return -1;
    }

    Py_XDECREF(fs_config_path);
    return 0;
}
示例#3
0
文件: cgmanager.c 项目: skizhak/lxc
/*
 * TODO: this should be re-written to use the get_config_item("lxc.id_map")
 * cmd api instead of getting the idmap from c->lxc_conf.  The reason is
 * that the id_maps may be different if the container was started with a
 * -f or -s argument.
 * The reason I'm punting on that is because we'll need to parse the
 * idmap results.
 */
static bool cgm_attach(const char *name, const char *lxcpath, pid_t pid)
{
	bool pass = false;
	char *cgroup = NULL;
	struct lxc_container *c;

	c = lxc_container_new(name, lxcpath);
	if (!c) {
		ERROR("Could not load container %s:%s", lxcpath, name);
		return false;
	}
	if (!collect_subsytems()) {
		ERROR("Error collecting cgroup subsystems");
		goto out;
	}
	// cgm_create makes sure that we have the same cgroup name for all
	// subsystems, so since this is a slow command over the cmd socket,
	// just get the cgroup name for the first one.
	cgroup = lxc_cmd_get_cgroup_path(name, lxcpath, subsystems[0]);
	if (!cgroup) {
		ERROR("Failed to get cgroup for controller %s", subsystems[0]);
		goto out;
	}

	if (!(pass = do_cgm_enter(pid, cgroup)))
		ERROR("Failed to enter group %s", cgroup);

out:
	free(cgroup);
	lxc_container_put(c);
	return pass;
}
示例#4
0
static int pid_from_lxcname(const char *lxcname_or_pid, const char *lxcpath) {
	char *eptr;
	int pid = strtol(lxcname_or_pid, &eptr, 10);
	if (*eptr != '\0' || pid < 1) {
		struct lxc_container *s;
		s = lxc_container_new(lxcname_or_pid, lxcpath);
		if (!s) {
			SYSERROR("'%s' is not a valid pid nor a container name", lxcname_or_pid);
			return -1;
		}

		if (!s->may_control(s)) {
			SYSERROR("Insufficient privileges to control container '%s'", s->name);
			lxc_container_put(s);
			return -1;
		}

		pid = s->init_pid(s);
		if (pid < 1) {
			SYSERROR("Is container '%s' running?", s->name);
			lxc_container_put(s);
			return -1;
		}

		lxc_container_put(s);
	}
	if (kill(pid, 0) < 0) {
		SYSERROR("Can't send signal to pid %d", pid);
		return -1;
	}

	return pid;
}
示例#5
0
文件: lxc_stop.c 项目: ChaosCloud/lxc
int main(int argc, char *argv[])
{
	struct lxc_container *c;
	bool s;
	int ret = 1;

	if (lxc_arguments_parse(&my_args, argc, argv))
		return 1;

	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
		return 1;

	/* shortcut - if locking is bogus, we should be able to kill
	 * containers at least */
	if (my_args.nolock)
		return lxc_cmd_stop(my_args.name, my_args.lxcpath[0]);

	c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
	if (!c) {
		fprintf(stderr, "Error opening container\n");
		goto out;
	}

	if (!c->may_control(c)) {
		fprintf(stderr, "Insufficent privileges to control %s\n", c->name);
		goto out;
	}

	if (!c->is_running(c)) {
		fprintf(stderr, "%s is not running\n", c->name);
		ret = 2;
		goto out;
	}

	if (my_args.hardstop) {
		ret = c->stop(c) ? 0 : 1;
		goto out;
	}
	if (my_args.reboot) {
		ret = do_reboot_and_check(&my_args, c);
		goto out;
	}

	if (my_args.shutdown)
		my_args.timeout = 0;

	s = c->shutdown(c, my_args.timeout);
	if (!s) {
		if (!my_args.shutdown)
			ret = c->wait(c, "STOPPED", -1) ? 0 : 1;
		else
			ret = 1; // fail
	} else
		ret = 0;

out:
	lxc_container_put(c);
	return ret;
}
示例#6
0
文件: zone.cpp 项目: hallor/vasum
void LxcZone::refresh()
{
    //TODO Consider make LxcZone state-less
    std::string zoneName = mLxcContainer->name;
    std::string lxcPath = mLxcContainer->config_path;
    lxc_container_put(mLxcContainer);
    mLxcContainer = lxc_container_new(zoneName.c_str(), lxcPath.c_str());
}
示例#7
0
int main(int argc, char *argv[])
{
	struct lxc_container *c;
	int ret = 1;

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

	if (c->is_defined(c)) {
		fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
		goto out;
	}

	if (create_container()) {
		fprintf(stderr, "%d: failed to create a container\n", __LINE__);
		goto out;
	}

	if (!c->is_defined(c)) {
		fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME);
		goto out;
	}

	c->load_config(c, NULL);
	unlink("/tmp/lxctest1");
	if (!c->save_config(c, "/tmp/lxctest1")) {
		fprintf(stderr, "%d: failed writing config file /tmp/lxctest1\n", __LINE__);
		goto out;
	}
	rename(LXCPATH "/" MYNAME "/config", LXCPATH "/" MYNAME "/config.bak");
	if (!c->save_config(c, NULL)) {
		fprintf(stderr, "%d: failed writing config file\n", __LINE__);
		goto out;
	}

	if (!c->destroy(c)) {
		fprintf(stderr, "%d: error deleting %s\n", __LINE__, MYNAME);
		goto out;
	}

	if (c->is_defined(c)) {
		fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
		goto out;
	}

	fprintf(stderr, "all lxc_container tests passed for %s\n", c->name);
	ret = 0;
out:
	lxc_container_put(c);
	exit(ret);
}
示例#8
0
文件: snapshot.c 项目: brsyuksel/lxc
static void try_to_remove(void)
{
	struct lxc_container *c;
	c = lxc_container_new(RESTNAME, NULL);
	if (c) {
		c->snapshot_destroy_all(c);
		if (c->is_defined(c))
			c->destroy(c);
		lxc_container_put(c);
	}
	c = lxc_container_new(MYNAME2, NULL);
	if (c) {
		c->destroy_with_snapshots(c);
		lxc_container_put(c);
	}
	c = lxc_container_new(MYNAME, NULL);
	if (c) {
		c->snapshot_destroy_all(c);
		if (c->is_defined(c))
			c->destroy(c);
		lxc_container_put(c);
	}
}
示例#9
0
文件: snapshot.c 项目: angushe/lxc
void try_to_remove()
{
	struct lxc_container *c;
	char snappath[1024];
	c = lxc_container_new(RESTNAME, NULL);
	if (c) {
		if (c->is_defined(c))
			c->destroy(c);
		lxc_container_put(c);
	}
	snprintf(snappath, 1024, "%ssnaps/%s", lxc_get_default_config_path(), MYNAME);
	c = lxc_container_new("snap0", snappath);
	if (c) {
		if (c->is_defined(c))
			c->destroy(c);
		lxc_container_put(c);
	}
	c = lxc_container_new(MYNAME, NULL);
	if (c) {
		if (c->is_defined(c))
			c->destroy(c);
		lxc_container_put(c);
	}
}
示例#10
0
文件: may_control.c 项目: 4b42/lxc
int main(int argc, char *argv[])
{
	const char *lxcpath = NULL, *name;
	bool may = false;
	struct lxc_container *c;

	if (argc < 2)
		usage(argv[0]);
	name = argv[1];
	if (argc == 3)
		lxcpath = argv[2];
	c = lxc_container_new(name, lxcpath);
	if (c)
		may = c->may_control(c);
	printf("You may%s control %s\n", may ? "" : " not", name);
	exit(may ? 0 : 1);
}
示例#11
0
int main(int argc, char *argv[])
{
	struct lxc_container *c;
	bool ret;

	if (lxc_arguments_parse(&my_args, argc, argv))
		exit(1);

	if (!my_args.log_file)
		my_args.log_file = "none";

	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
		exit(1);

	lxc_log_options_no_override();

	c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
	if (!c) {
		fprintf(stderr, "System error loading %s\n", my_args.name);
		exit(1);
	}

	if (!c->may_control(c)) {
		fprintf(stderr, "Insufficent privileges to control %s\n", my_args.name);
		lxc_container_put(c);
		exit(1);
	}

	if (!c->is_defined(c)) {
		fprintf(stderr, "%s is not defined\n", my_args.name);
		lxc_container_put(c);
		exit(1);
	}


	if (do_restore)
		ret = restore(c);
	else if (do_pre_checkpoint)
		ret = pre_checkpoint(c);
	else
		ret = checkpoint(c);

	return !ret;
}
示例#12
0
文件: core.c 项目: Altiscale/lxc
static int container_new(lua_State *L)
{
    struct lxc_container *c;
    const char *name = luaL_checkstring(L, 1);
    const char *configpath = NULL;
    int argc = lua_gettop(L);

    if (argc > 1)
	configpath = luaL_checkstring(L, 2);

    c = lxc_container_new(name, configpath);
    if (c) {
	lua_boxpointer(L, c);
	luaL_getmetatable(L, CONTAINER_TYPENAME);
	lua_setmetatable(L, -2);
    } else {
	lua_pushnil(L);
    }
    return 1;
}
示例#13
0
文件: attach.c 项目: Red54/lxc
static bool fetch_seccomp(const char *name, const char *lxcpath,
		struct lxc_proc_context_info *i, lxc_attach_options_t *options)
{
	struct lxc_container *c;

	if (!(options->namespaces & CLONE_NEWNS) || !(options->attach_flags & LXC_ATTACH_LSM))
		return true;

	c = lxc_container_new(name, lxcpath);
	if (!c)
		return false;
	i->container = c;
	if (!c->lxc_conf)
		return false;
	if (lxc_read_seccomp_config(c->lxc_conf) < 0) {
		ERROR("Error reading seccomp policy");
		return false;
	}

	return true;
}
示例#14
0
文件: attach.c 项目: Archer-sys/lxc
static bool fetch_seccomp(const char *name, const char *lxcpath,
		struct lxc_proc_context_info *i, lxc_attach_options_t *options)
{
	struct lxc_container *c;
	char *path;

	if (!(options->namespaces & CLONE_NEWNS) || !(options->attach_flags & LXC_ATTACH_LSM))
		return true;

	c = lxc_container_new(name, lxcpath);
	if (!c)
		return false;
	i->container = c;

	/* Initialize an empty lxc_conf */
	if (!c->set_config_item(c, "lxc.seccomp", "")) {
		return false;
	}

	/* Fetch the current profile path over the cmd interface */
	path = c->get_running_config_item(c, "lxc.seccomp");
	if (!path) {
		return true;
	}

	/* Copy the value into the new lxc_conf */
	if (!c->set_config_item(c, "lxc.seccomp", path)) {
		free(path);
		return false;
	}
	free(path);

	/* Attempt to parse the resulting config */
	if (lxc_read_seccomp_config(c->lxc_conf) < 0) {
		ERROR("Error reading seccomp policy");
		return false;
	}

	return true;
}
示例#15
0
文件: get_item.c 项目: MSylvia/koding
int main(int argc, char *argv[])
{
	struct lxc_container *c;
	int ret;
	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);
		ret = 1;
		goto out;
	}

	if (!c->set_config_item(c, "lxc.hook.pre-start", "hi there")) {
		fprintf(stderr, "%d: failed to set hook.pre-start\n", __LINE__);
		ret = 1;
		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);
		ret = 1;
		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);
		ret = 1;
		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__);
		ret = 1;
		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);
		ret = 1;
		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__);
		ret = 1;
		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);
		ret = 1;
		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__);
		ret = 1;
		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);
		ret = 1;
		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__);
		ret = 1;
		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);
		ret = 1;
		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__);
		ret = 1;
		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);
		ret = 1;
		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);
		ret = 1;
		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);
		ret = 1;
		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);
		ret = 1;
		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__);
		ret = 1;
		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);
		ret = 1;
		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__);
		ret = 1;
		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);
		ret = 1;
		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);
		ret = 1;
		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);
		ret = 1;
		goto out;
	}
	if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) {
		fprintf(stderr, "%d: failed to create a trusty container\n", __LINE__);
		ret = 1;
		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);
		ret = 1;
		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);
		ret = 1;
		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);
		ret = 1;
		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);
		ret = 1;
		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);
		ret = 1;
		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__);
		ret = 1;
		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);
		ret = 1;
		goto out;
	}
	if (!c->clear_config_item(c, "lxc.network.0.ipv4")) {
		fprintf(stderr, "%d: failed clearing all ipv4 entries\n", __LINE__);
		ret = 1;
		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);
		ret = 1;
		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__);
		ret = 1;
		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);
		ret = 1;
		goto out;
	}
	if (!c->set_config_item(c, "lxc.network.0.ipv4.gateway", "")) {
		fprintf(stderr, "%d: failed clearing ipv4.gateway\n", __LINE__);
		ret = 1;
		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);
		ret = 1;
		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);
		ret = 1;
		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);
		ret = 1;
		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__);
		ret = 1;
		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);
		ret = 1;
		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);
		ret = 1;
		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);
		ret = 1;
		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__);
		ret = 1;
		goto out;
	}
	if (!c->clear_config_item(c, "lxc.cap.drop")) {
		fprintf(stderr, "%d: failed clearing lxc.cap.drop\n", __LINE__);
		ret = 1;
		goto out;
	}
	if (!c->clear_config_item(c, "lxc.mount.entries")) {
		fprintf(stderr, "%d: failed clearing lxc.mount.entries\n", __LINE__);
		ret = 1;
		goto out;
	}
	if (!c->clear_config_item(c, "lxc.hook")) {
		fprintf(stderr, "%d: failed clearing lxc.hook\n", __LINE__);
		ret = 1;
		goto out;
	}
	c->destroy(c);
	printf("All get_item tests passed\n");
	ret = 0;
out:
	lxc_container_put(c);
	exit(ret);
};
示例#16
0
文件: lxc_stop.c 项目: Blub/lxc
int main(int argc, char *argv[])
{
	struct lxc_container *c;
	bool s;
	int ret = EXIT_FAILURE;

	if (lxc_arguments_parse(&my_args, argc, argv))
		exit(ret);

	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
		exit(ret);
	lxc_log_options_no_override();

	/* Set default timeout */
	if (my_args.timeout == -2) {
		if (my_args.hardstop)
			my_args.timeout = 0;
		else
			my_args.timeout = 60;
	}

	if (my_args.nowait)
		my_args.timeout = 0;

	/* some checks */
	if (!my_args.hardstop && my_args.timeout < -1) {
		fprintf(stderr, "invalid timeout\n");
		exit(ret);
	}

	if (my_args.hardstop && my_args.nokill) {
		fprintf(stderr, "-k can't be used with --nokill\n");
		exit(ret);
	}

	if (my_args.hardstop && my_args.reboot) {
		fprintf(stderr, "-k can't be used with -r\n");
		exit(ret);
	}

	if (my_args.hardstop && my_args.timeout) {
		fprintf(stderr, "-k doesn't allow timeouts\n");
		exit(ret);
	}

	if (my_args.nolock && !my_args.hardstop) {
		fprintf(stderr, "--nolock may only be used with -k\n");
		exit(ret);
	}

	/* shortcut - if locking is bogus, we should be able to kill
	 * containers at least */
	if (my_args.nolock) {
		ret = lxc_cmd_stop(my_args.name, my_args.lxcpath[0]);
		exit(ret);
	}

	c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
	if (!c) {
		fprintf(stderr, "Error opening container\n");
		goto out;
	}

	if (my_args.rcfile) {
		c->clear_config(c);
		if (!c->load_config(c, my_args.rcfile)) {
			fprintf(stderr, "Failed to load rcfile\n");
			goto out;
		}
		c->configfile = strdup(my_args.rcfile);
		if (!c->configfile) {
			fprintf(stderr, "Out of memory setting new config filename\n");
			goto out;
		}
	}

	if (!c->may_control(c)) {
		fprintf(stderr, "Insufficent privileges to control %s\n", c->name);
		goto out;
	}

	if (!c->is_running(c)) {
		fprintf(stderr, "%s is not running\n", c->name);
		/* Per our manpage we need to exit with exit code:
		 * 2: The specified container exists but was not running.
		 */
		ret = 2;
		goto out;
	}

	/* kill */
	if (my_args.hardstop) {
		ret = c->stop(c) ? EXIT_SUCCESS : EXIT_FAILURE;
		goto out;
	}

	/* reboot */
	if (my_args.reboot) {
		ret = do_reboot_and_check(&my_args, c) < 0 ? EXIT_SUCCESS : EXIT_FAILURE;
		goto out;
	}

	/* shutdown */
	s = c->shutdown(c, my_args.timeout);
	if (!s) {
		if (my_args.timeout == 0)
			ret = EXIT_SUCCESS;
		else if (my_args.nokill)
			ret = EXIT_FAILURE;
		else
			ret = c->stop(c) ? EXIT_SUCCESS : EXIT_FAILURE;
	} else {
		ret = EXIT_SUCCESS;
	}

out:
	lxc_container_put(c);
	exit(ret);
}
示例#17
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);
}
示例#18
0
文件: lxc_stop.c 项目: Kousalyakg/lxc
int main(int argc, char *argv[])
{
	struct lxc_container *c;
	bool s;
	int ret = 1;

	if (lxc_arguments_parse(&my_args, argc, argv))
		return 1;

	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
		return 1;
	lxc_log_options_no_override();

	/* Set default timeout */
	if (my_args.timeout == -2) {
		if (my_args.hardstop) {
			my_args.timeout = 0;
		}
		else {
			my_args.timeout = 60;
		}
	}

	if (my_args.nowait) {
		my_args.timeout = 0;
	}

	/* some checks */
	if (!my_args.hardstop && my_args.timeout < -1) {
		fprintf(stderr, "invalid timeout\n");
		return 1;
	}

	if (my_args.hardstop && my_args.nokill) {
		fprintf(stderr, "-k can't be used with --nokill\n");
		return 1;
	}

	if (my_args.hardstop && my_args.reboot) {
		fprintf(stderr, "-k can't be used with -r\n");
		return 1;
	}

	if (my_args.hardstop && my_args.timeout) {
		fprintf(stderr, "-k doesn't allow timeouts\n");
		return 1;
	}

	if (my_args.nolock && !my_args.hardstop) {
		fprintf(stderr, "--nolock may only be used with -k\n");
		return 1;
	}

	/* shortcut - if locking is bogus, we should be able to kill
	 * containers at least */
	if (my_args.nolock)
		return lxc_cmd_stop(my_args.name, my_args.lxcpath[0]);

	c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
	if (!c) {
		fprintf(stderr, "Error opening container\n");
		goto out;
	}

	if (!c->may_control(c)) {
		fprintf(stderr, "Insufficent privileges to control %s\n", c->name);
		goto out;
	}

	if (!c->is_running(c)) {
		fprintf(stderr, "%s is not running\n", c->name);
		ret = 2;
		goto out;
	}

	/* kill */
	if (my_args.hardstop) {
		ret = c->stop(c) ? 0 : 1;
		goto out;
	}

	/* reboot */
	if (my_args.reboot) {
		ret = do_reboot_and_check(&my_args, c);
		goto out;
	}

	/* shutdown */
	s = c->shutdown(c, my_args.timeout);
	if (!s) {
		if (my_args.timeout == 0)
			ret = 0;
		else if (my_args.nokill)
			ret = 1;
		else
			ret = c->stop(c) ? 0 : 1;
	} else
		ret = 0;

out:
	lxc_container_put(c);
	return ret;
}
示例#19
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);
}
示例#20
0
文件: attach.c 项目: LynxChaus/lxc
int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_function, void* exec_payload, lxc_attach_options_t* options, pid_t* attached_process)
{
	int ret, status;
	pid_t init_pid, pid, attached_pid, expected;
	struct lxc_proc_context_info *init_ctx;
	char* cwd;
	char* new_cwd;
	int ipc_sockets[2];
	signed long personality;

	if (!options)
		options = &attach_static_default_options;

	init_pid = lxc_cmd_get_init_pid(name, lxcpath);
	if (init_pid < 0) {
		ERROR("Failed to get init pid.");
		return -1;
	}

	init_ctx = lxc_proc_get_context_info(init_pid);
	if (!init_ctx) {
		ERROR("Failed to get context of init process: %ld.",
		      (long)init_pid);
		return -1;
	}

	personality = get_personality(name, lxcpath);
	if (init_ctx->personality < 0) {
		ERROR("Failed to get personality of the container.");
		lxc_proc_put_context_info(init_ctx);
		return -1;
	}
	init_ctx->personality = personality;

	init_ctx->container = lxc_container_new(name, lxcpath);
	if (!init_ctx->container)
		return -1;

	if (!fetch_seccomp(init_ctx->container, options))
		WARN("Failed to get seccomp policy.");

	if (!no_new_privs(init_ctx->container, options))
		WARN("Could not determine whether PR_SET_NO_NEW_PRIVS is set.");

	cwd = getcwd(NULL, 0);

	/* Determine which namespaces the container was created with
	 * by asking lxc-start, if necessary.
	 */
	if (options->namespaces == -1) {
		options->namespaces = lxc_cmd_get_clone_flags(name, lxcpath);
		/* call failed */
		if (options->namespaces == -1) {
			ERROR("Failed to automatically determine the "
			      "namespaces which the container uses.");
			free(cwd);
			lxc_proc_put_context_info(init_ctx);
			return -1;
		}
	}

	/* Create a socket pair for IPC communication; set SOCK_CLOEXEC in order
	 * to make sure we don't irritate other threads that want to fork+exec
	 * away
	 *
	 * IMPORTANT: if the initial process is multithreaded and another call
	 * just fork()s away without exec'ing directly after, the socket fd will
	 * exist in the forked process from the other thread and any close() in
	 * our own child process will not really cause the socket to close
	 * properly, potentiall causing the parent to hang.
	 *
	 * For this reason, while IPC is still active, we have to use shutdown()
	 * if the child exits prematurely in order to signal that the socket is
	 * closed and cannot assume that the child exiting will automatically do
	 * that.
	 *
	 * IPC mechanism: (X is receiver)
	 *   initial process        intermediate          attached
	 *        X           <---  send pid of
	 *                          attached proc,
	 *                          then exit
	 *    send 0 ------------------------------------>    X
	 *                                              [do initialization]
	 *        X  <------------------------------------  send 1
	 *   [add to cgroup, ...]
	 *    send 2 ------------------------------------>    X
	 *						[set LXC_ATTACH_NO_NEW_PRIVS]
	 *        X  <------------------------------------  send 3
	 *   [open LSM label fd]
	 *    send 4 ------------------------------------>    X
	 *   						[set LSM label]
	 *   close socket                                 close socket
	 *                                                run program
	 */
	ret = socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
	if (ret < 0) {
		SYSERROR("Could not set up required IPC mechanism for attaching.");
		free(cwd);
		lxc_proc_put_context_info(init_ctx);
		return -1;
	}

	/* Create intermediate subprocess, three reasons:
	 *       1. Runs all pthread_atfork handlers and the child will no
	 *          longer be threaded (we can't properly setns() in a threaded
	 *          process).
	 *       2. We can't setns() in the child itself, since we want to make
	 *          sure we are properly attached to the pidns.
	 *       3. Also, the initial thread has to put the attached process
	 *          into the cgroup, which we can only do if we didn't already
	 *          setns() (otherwise, user namespaces will hate us).
	 */
	pid = fork();

	if (pid < 0) {
		SYSERROR("Failed to create first subprocess.");
		free(cwd);
		lxc_proc_put_context_info(init_ctx);
		return -1;
	}

	if (pid) {
		int procfd = -1;
		pid_t to_cleanup_pid = pid;

		/* Initial thread, we close the socket that is for the
		 * subprocesses.
		 */
		close(ipc_sockets[1]);
		free(cwd);

		/* Attach to cgroup, if requested. */
		if (options->attach_flags & LXC_ATTACH_MOVE_TO_CGROUP) {
			if (!cgroup_attach(name, lxcpath, pid))
				goto on_error;
		}

		/* Setup resource limits */
		if (!lxc_list_empty(&init_ctx->container->lxc_conf->limits) && setup_resource_limits(&init_ctx->container->lxc_conf->limits, pid)) {
			goto on_error;
		}

		/* Open /proc before setns() to the containers namespace so we
		 * don't rely on any information from inside the container.
		 */
		procfd = open("/proc", O_DIRECTORY | O_RDONLY | O_CLOEXEC);
		if (procfd < 0) {
			SYSERROR("Unable to open /proc.");
			goto on_error;
		}

		/* Let the child process know to go ahead. */
		status = 0;
		ret = lxc_write_nointr(ipc_sockets[0], &status, sizeof(status));
		if (ret <= 0) {
			ERROR("Intended to send sequence number 0: %s.",
			      strerror(errno));
			goto on_error;
		}

		/* Get pid of attached process from intermediate process. */
		ret = lxc_read_nointr_expect(ipc_sockets[0], &attached_pid, sizeof(attached_pid), NULL);
		if (ret <= 0) {
			if (ret != 0)
				ERROR("Expected to receive pid: %s.", strerror(errno));
			goto on_error;
		}

		/* Ignore SIGKILL (CTRL-C) and SIGQUIT (CTRL-\) - issue #313. */
		if (options->stdin_fd == 0) {
			signal(SIGINT, SIG_IGN);
			signal(SIGQUIT, SIG_IGN);
		}

		/* Reap intermediate process. */
		ret = wait_for_pid(pid);
		if (ret < 0)
			goto on_error;

		/* We will always have to reap the attached process now. */
		to_cleanup_pid = attached_pid;

		/* Tell attached process it may start initializing. */
		status = 0;
		ret = lxc_write_nointr(ipc_sockets[0], &status, sizeof(status));
		if (ret <= 0) {
			ERROR("Intended to send sequence number 0: %s.", strerror(errno));
			goto on_error;
		}

		/* Wait for the attached process to finish initializing. */
		expected = 1;
		ret = lxc_read_nointr_expect(ipc_sockets[0], &status, sizeof(status), &expected);
		if (ret <= 0) {
			if (ret != 0)
				ERROR("Expected to receive sequence number 1: %s.", strerror(errno));
			goto on_error;
		}

		/* Tell attached process we're done. */
		status = 2;
		ret = lxc_write_nointr(ipc_sockets[0], &status, sizeof(status));
		if (ret <= 0) {
			ERROR("Intended to send sequence number 2: %s.", strerror(errno));
			goto on_error;
		}

		/* Wait for the (grand)child to tell us that it's ready to set
		 * up its LSM labels.
		 */
		expected = 3;
		ret = lxc_read_nointr_expect(ipc_sockets[0], &status, sizeof(status), &expected);
		if (ret <= 0) {
			ERROR("Expected to receive sequence number 3: %s.",
			      strerror(errno));
			goto on_error;
		}

		/* Open LSM fd and send it to child. */
		if ((options->namespaces & CLONE_NEWNS) && (options->attach_flags & LXC_ATTACH_LSM) && init_ctx->lsm_label) {
			int on_exec, saved_errno;
			int labelfd = -1;
			on_exec = options->attach_flags & LXC_ATTACH_LSM_EXEC ? 1 : 0;
			/* Open fd for the LSM security module. */
			labelfd = lsm_openat(procfd, attached_pid, on_exec);
			if (labelfd < 0)
				goto on_error;

			/* Send child fd of the LSM security module to write to. */
			ret = lxc_abstract_unix_send_fds(ipc_sockets[0], &labelfd, 1, NULL, 0);
			saved_errno = errno;
			close(labelfd);
			if (ret <= 0) {
				ERROR("Intended to send file descriptor %d: %s.", labelfd, strerror(saved_errno));
				goto on_error;
			}
		}

		if (procfd >= 0)
			close(procfd);
		/* Now shut down communication with child, we're done. */
		shutdown(ipc_sockets[0], SHUT_RDWR);
		close(ipc_sockets[0]);
		lxc_proc_put_context_info(init_ctx);

		/* We're done, the child process should now execute whatever it
		 * is that the user requested. The parent can now track it with
		 * waitpid() or similar.
		 */

		*attached_process = attached_pid;
		return 0;

	on_error:
		/* First shut down the socket, then wait for the pid, otherwise
		 * the pid we're waiting for may never exit.
		 */
		if (procfd >= 0)
			close(procfd);
		shutdown(ipc_sockets[0], SHUT_RDWR);
		close(ipc_sockets[0]);
		if (to_cleanup_pid)
			(void) wait_for_pid(to_cleanup_pid);
		lxc_proc_put_context_info(init_ctx);
		return -1;
	}

	/* First subprocess begins here, we close the socket that is for the
	 * initial thread.
	 */
	close(ipc_sockets[0]);

	/* Wait for the parent to have setup cgroups. */
	expected = 0;
	status = -1;
	ret = lxc_read_nointr_expect(ipc_sockets[1], &status, sizeof(status), &expected);
	if (ret <= 0) {
		ERROR("Expected to receive sequence number 0: %s.", strerror(errno));
		shutdown(ipc_sockets[1], SHUT_RDWR);
		rexit(-1);
	}

	if ((options->attach_flags & LXC_ATTACH_MOVE_TO_CGROUP) && cgns_supported())
		options->namespaces |= CLONE_NEWCGROUP;

	/* Attach now, create another subprocess later, since pid namespaces
	 * only really affect the children of the current process.
	 */
	ret = lxc_attach_to_ns(init_pid, options->namespaces);
	if (ret < 0) {
		ERROR("Failed to enter namespaces.");
		shutdown(ipc_sockets[1], SHUT_RDWR);
		rexit(-1);
	}

	/* Attach succeeded, try to cwd. */
	if (options->initial_cwd)
		new_cwd = options->initial_cwd;
	else
		new_cwd = cwd;
	ret = chdir(new_cwd);
	if (ret < 0)
		WARN("Could not change directory to \"%s\".", new_cwd);
	free(cwd);

	/* Now create the real child process. */
	{
		struct attach_clone_payload payload = {
			.ipc_socket = ipc_sockets[1],
			.options = options,
			.init_ctx = init_ctx,
			.exec_function = exec_function,
			.exec_payload = exec_payload,
		};
		/* We use clone_parent here to make this subprocess a direct
		 * child of the initial process. Then this intermediate process
		 * can exit and the parent can directly track the attached
		 * process.
		 */
		pid = lxc_clone(attach_child_main, &payload, CLONE_PARENT);
	}

	/* Shouldn't happen, clone() should always return positive pid. */
	if (pid <= 0) {
		SYSERROR("Failed to create subprocess.");
		shutdown(ipc_sockets[1], SHUT_RDWR);
		rexit(-1);
	}

	/* Tell grandparent the pid of the pid of the newly created child. */
	ret = lxc_write_nointr(ipc_sockets[1], &pid, sizeof(pid));
	if (ret != sizeof(pid)) {
		/* If this really happens here, this is very unfortunate, since
		 * the parent will not know the pid of the attached process and
		 * will not be able to wait for it (and we won't either due to
		 * CLONE_PARENT) so the parent won't be able to reap it and the
		 * attached process will remain a zombie.
		 */
		ERROR("Intended to send pid %d: %s.", pid, strerror(errno));
		shutdown(ipc_sockets[1], SHUT_RDWR);
		rexit(-1);
	}

	/* The rest is in the hands of the initial and the attached process. */
	rexit(0);
}
示例#21
0
int main(int argc, char *argv[])
{
	struct lxc_container *c;
	int ret = 1;

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

	if (c->is_defined(c)) {
		fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
		goto out;
	}

	if (!c->set_config_item(c, "lxc.network.type", "veth")) {
		fprintf(stderr, "%d: failed to set network type\n", __LINE__);
		goto out;
	}
	c->set_config_item(c, "lxc.network.link", "lxcbr0");
	c->set_config_item(c, "lxc.network.flags", "up");
	if (!c->createl(c, "ubuntu", NULL, NULL, "-r", "lucid", NULL)) {
		fprintf(stderr, "%d: failed to create a lucid container\n", __LINE__);
		goto out;
	}

	if (!c->is_defined(c)) {
		fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME);
		goto out;
	}

	c->load_config(c, NULL);
	c->want_daemonize(c);
	if (!c->startl(c, 0, NULL)) {
		fprintf(stderr, "%d: failed to start %s\n", __LINE__, MYNAME);
		goto out;
	}
	fprintf(stderr, "%d: %s started, you have 60 seconds to test a console\n", __LINE__, MYNAME);
	sleep(60);  // wait a minute to let user connect to console

	if (!c->shutdown(c, 60)) {
		fprintf(stderr, "%d: failed to shut down %s\n", __LINE__, MYNAME);
		goto out;
	}

	if (!c->destroy(c)) {
		fprintf(stderr, "%d: error deleting %s\n", __LINE__, MYNAME);
		goto out;
	}

	if (c->is_defined(c)) {
		fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
		goto out;
	}

	fprintf(stderr, "all lxc_container tests passed for %s\n", c->name);
	ret = 0;
out:
	lxc_container_put(c);
	exit(ret);
}
示例#22
0
文件: state_server.c 项目: hallyn/lxc
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);
}
示例#23
0
int main(int argc, char *argv[])
{
	struct lxc_container *c;
	int ret = 0;
	const char *s;
	bool b;
	char buf[201];
	int len;

	ret = 1;
	/* test a real container */
	c = lxc_container_new(MYNAME, NULL);
	if (!c) {
		fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, MYNAME);
		ret = 1;
		goto out;
	}

	if (c->is_defined(c)) {
		fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
		goto out;
	}

	ret = create_ubuntu();
	if (ret) {
		fprintf(stderr, "%d: failed to create a ubuntu container\n", __LINE__);
		goto out;
	}

	b = c->is_defined(c);
	if (!b) {
		fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME);
		goto out;
	}

	len = c->get_cgroup_item(c, "cpuset.cpus", buf, 200);
	if (len >= 0) {
		fprintf(stderr, "%d: %s not running but had cgroup settings\n", __LINE__, MYNAME);
		goto out;
	}

	sprintf(buf, "0");
	b = c->set_cgroup_item(c, "cpuset.cpus", buf);
	if (b) {
		fprintf(stderr, "%d: %s not running but coudl set cgroup settings\n", __LINE__, MYNAME);
		goto out;
	}

	s = c->state(c);
	if (!s || strcmp(s, "STOPPED")) {
		fprintf(stderr, "%d: %s is in state %s, not in STOPPED.\n", __LINE__, c->name, s ? s : "undefined");
		goto out;
	}

	b = c->load_config(c, NULL);
	if (!b) {
		fprintf(stderr, "%d: %s failed to read its config\n", __LINE__, c->name);
		goto out;
	}

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

	printf("hit return to start container");
	char mychar;
	ret = scanf("%c", &mychar);
	if (ret < 0)
		goto out;

	if (!lxc_container_get(c)) {
		fprintf(stderr, "%d: failed to get extra ref to container\n", __LINE__);
		exit(1);
	}
	pid_t pid = fork();
	if (pid < 0) {
		fprintf(stderr, "%d: fork failed\n", __LINE__);
		goto out;
	}
	if (pid == 0) {
		b = c->startl(c, 0, NULL);
		if (!b)
			fprintf(stderr, "%d: %s failed to start\n", __LINE__, c->name);
		lxc_container_put(c);
		exit(!b);
	}

	sleep(3);
	s = c->state(c);
	if (!s || strcmp(s, "RUNNING")) {
		fprintf(stderr, "%d: %s is in state %s, not in RUNNING.\n", __LINE__, c->name, s ? s : "undefined");
		goto out;
	}

	len = c->get_cgroup_item(c, "cpuset.cpus", buf, 0);
	if (len <= 0) {
		fprintf(stderr, "%d: not able to get length of cpuset.cpus (ret %d)\n", __LINE__, len);
		goto out;
	}

	len = c->get_cgroup_item(c, "cpuset.cpus", buf, 200);
	if (len <= 0 || strcmp(buf, "0\n")) {
		fprintf(stderr, "%d: not able to get cpuset.cpus (len %d buf %s)\n", __LINE__, len, buf);
		goto out;
	}

	sprintf(buf, "FROZEN");
	b = c->set_cgroup_item(c, "freezer.state", buf);
	if (!b) {
		fprintf(stderr, "%d: not able to set freezer.state.\n", __LINE__);
		goto out;
	}

    sprintf(buf, "XXX");
	len = c->get_cgroup_item(c, "freezer.state", buf, 200);
	if (len <= 0 || (strcmp(buf, "FREEZING\n") && strcmp(buf, "FROZEN\n"))) {
		fprintf(stderr, "%d: not able to get freezer.state (len %d buf %s)\n", __LINE__, len, buf);
		goto out;
	}

	c->set_cgroup_item(c, "freezer.state", "THAWED");

	printf("hit return to finish");
	ret = scanf("%c", &mychar);
	if (ret < 0)
		goto out;
	c->stop(c);

    /* feh - multilib has moved the lxc-init crap */
#if 0
    goto ok;

	ret = system("mkdir -p " LXCPATH "/lxctest1/rootfs//usr/local/libexec/lxc");
	if (!ret)
		ret = system("mkdir -p " LXCPATH "/lxctest1/rootfs/usr/lib/lxc/");
	if (!ret)
		ret = system("cp src/lxc/lxc-init " LXCPATH "/lxctest1/rootfs//usr/local/libexec/lxc");
	if (!ret)
		ret = system("cp src/lxc/liblxc.so " LXCPATH "/lxctest1/rootfs/usr/lib/lxc");
	if (!ret)
		ret = system("cp src/lxc/liblxc.so " LXCPATH "/lxctest1/rootfs/usr/lib/lxc/liblxc.so.0");
	if (!ret)
		ret = system("cp src/lxc/liblxc.so " LXCPATH "/lxctest1/rootfs/usr/lib");
	if (!ret)
		ret = system("mkdir -p " LXCPATH "/lxctest1/rootfs/dev/shm");
	if (!ret)
		ret = system("chroot " LXCPATH "/lxctest1/rootfs apt-get install --no-install-recommends lxc");
	if (ret) {
		fprintf(stderr, "%d: failed to installing lxc-init in container\n", __LINE__);
		goto out;
	}
	// next write out the config file;  does it match?
	if (!c->startl(c, 1, "/bin/hostname", NULL)) {
		fprintf(stderr, "%d: failed to lxc-execute /bin/hostname\n", __LINE__);
		goto out;
	}
	//  auto-check result?  ('bobo' is printed on stdout)

ok:
#endif
	fprintf(stderr, "all lxc_container tests passed for %s\n", c->name);
	ret = 0;

out:
	if (c) {
		c->stop(c);
		destroy_ubuntu();
	}
	lxc_container_put(c);
	exit(ret);
}
示例#24
0
文件: lxc_device.c 项目: 4b42/lxc
int main(int argc, char *argv[])
{
	struct lxc_container *c;
	char *cmd, *dev_name, *dst_name;
	int ret = 1;

	if (geteuid() != 0) {
		ERROR("%s must be run as root", argv[0]);
		exit(1);
	}

	if (lxc_arguments_parse(&my_args, argc, argv))
		goto err;

	if (!my_args.log_file)
		my_args.log_file = "none";

	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
		goto err;
	lxc_log_options_no_override();

	c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
	if (!c) {
		ERROR("%s doesn't exist", my_args.name);
		goto err;
	}

	if (!c->is_running(c)) {
		ERROR("Container %s is not running.", c->name);
		goto err1;
	}

	if (my_args.argc < 2) {
		ERROR("Error: no command given (Please see --help output)");
		goto err1;
	}

	cmd = my_args.argv[0];
	dev_name = my_args.argv[1];
	if (my_args.argc < 3)
		dst_name = dev_name;
	else
		dst_name = my_args.argv[2];

	if (strcmp(cmd, "add") == 0) {
		if (is_interface(dev_name, 1)) {
			ret = c->attach_interface(c, dev_name, dst_name);
		} else {
			ret = c->add_device_node(c, dev_name, dst_name);
		}
		if (ret != true) {
			ERROR("Failed to add %s to %s.", dev_name, c->name);
			ret = 1;
			goto err1;
		}
		INFO("Add %s to %s.", dev_name, c->name);
	} else if (strcmp(cmd, "del") == 0) {
		if (is_interface(dev_name, c->init_pid(c))) {
			ret = c->detach_interface(c, dev_name, dst_name);
		} else {
			ret = c->remove_device_node(c, dev_name, dst_name);
		}
		if (ret != true) {
			ERROR("Failed to del %s from %s.", dev_name, c->name);
			ret = 1;
			goto err1;
		}
		INFO("Delete %s from %s.", dev_name, c->name);
	} else {
		ERROR("Error: Please use add or del (Please see --help output)");
		goto err1;
	}
	exit(0);
err1:
	lxc_container_put(c);
err:
	exit(ret);
}
示例#25
0
文件: containertests.c 项目: 4b42/lxc
int main(int argc, char *argv[])
{
	struct lxc_container *c;
	int ret = 0;
	const char *s;
	bool b;
	char *str;

	ret = 1;
	/* test refcounting */
	c = lxc_container_new(MYNAME, NULL);
	if (!c) {
		fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, MYNAME);
		goto out;
	}
	if (!lxc_container_get(c)) {
		fprintf(stderr, "%d: error getting refcount\n", __LINE__);
		goto out;
	}
	/* peek in, inappropriately, make sure refcount is a we'd like */
	if (c->numthreads != 2) {
		fprintf(stderr, "%d: refcount is %d, not %d\n", __LINE__, c->numthreads, 2);
		goto out;
	}
	if (strcmp(c->name, MYNAME) != 0) {
		fprintf(stderr, "%d: container has wrong name (%s not %s)\n", __LINE__, c->name, MYNAME);
		goto out;
	}
	str = c->config_file_name(c);
#define CONFIGFNAM LXCPATH "/" MYNAME "/config"
	if (!str || strcmp(str, CONFIGFNAM)) {
		fprintf(stderr, "%d: got wrong config file name (%s, not %s)\n", __LINE__, str, CONFIGFNAM);
		goto out;
	}
	free(str);
	free(c->configfile);
	c->configfile = NULL;
	str = c->config_file_name(c);
	if (str) {
		fprintf(stderr, "%d: config file name was not NULL as it should have been\n", __LINE__);
		goto out;
	}
	if (lxc_container_put(c) != 0) {
		fprintf(stderr, "%d: c was freed on non-final put\n", __LINE__);
		goto out;
	}
	if (c->numthreads != 1) {
		fprintf(stderr, "%d: refcount is %d, not %d\n", __LINE__, c->numthreads, 1);
		goto out;
	}
	if (lxc_container_put(c) != 1) {
		fprintf(stderr, "%d: c was not freed on final put\n", __LINE__);
		goto out;
	}

	/* test a real container */
	c = lxc_container_new(MYNAME, NULL);
	if (!c) {
		fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, MYNAME);
		ret = 1;
		goto out;
	}

	b = c->is_defined(c);
	if (b) {
		fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
		goto out;
	}

	s = c->state(c);
	if (s && strcmp(s, "STOPPED") != 0) {
	// liblxc says a container is STOPPED if it doesn't exist.  That's because
	// the container may be an application container - it's not wrong, just
	// sometimes unintuitive.
		fprintf(stderr, "%d: %s thinks it is in state %s\n", __LINE__, c->name, s);
		goto out;
	}

	// create a container
	// the liblxc api does not support creation - it probably will eventually,
	// but not yet.
	// So we just call out to lxc-create.  We'll create a busybox container.
	ret = create_busybox();
	if (ret) {
		fprintf(stderr, "%d: failed to create a busybox container\n", __LINE__);
		goto out;
	}

	b = c->is_defined(c);
	if (!b) {
		fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME);
		goto out;
	}

	s = c->state(c);
	if (!s || strcmp(s, "STOPPED")) {
		fprintf(stderr, "%d: %s is in state %s, not in STOPPED.\n", __LINE__, c->name, s ? s : "undefined");
		goto out;
	}

	b = c->load_config(c, NULL);
	if (!b) {
		fprintf(stderr, "%d: %s failed to read its config\n", __LINE__, c->name);
		goto out;
	}

	// test wait states
	int numstates = lxc_get_wait_states(NULL);
	if (numstates != MAX_STATE) {
		fprintf(stderr, "%d: lxc_get_wait_states gave %d not %d\n", __LINE__, numstates, MAX_STATE);
		goto out;
	}
	const char **sstr = malloc(numstates * sizeof(const char *));
	numstates = lxc_get_wait_states(sstr);
	int i;
	for (i=0; i<numstates; i++) {
		fprintf(stderr, "got state %d %s\n", i, sstr[i]);
	}
	free(sstr);

	/* non-daemonized is tested in 'startone' */
	c->want_daemonize(c, true);
	if (!c->startl(c, 0, NULL, NULL)) {
		fprintf(stderr, "%d: %s failed to start daemonized\n", __LINE__, c->name);
		goto out;
	}

	if (!c->wait(c, "RUNNING", -1)) {
		fprintf(stderr, "%d: failed waiting for state RUNNING\n", __LINE__);
		goto out;
	}

	sleep(3);
	s = c->state(c);
	if (!s || strcmp(s, "RUNNING")) {
		fprintf(stderr, "%d: %s is in state %s, not in RUNNING.\n", __LINE__, c->name, s ? s : "undefined");
		goto out;
	}

	fprintf(stderr, "all lxc_container tests passed for %s\n", c->name);
	ret = 0;

out:
	if (c) {
		c->stop(c);
		destroy_busybox();
	}
	lxc_container_put(c);
	exit(ret);
}
示例#26
0
文件: cgpath.c 项目: 4b42/lxc
/*
 * test_running_container: test cgroup functions against a running container
 *
 * @group : name of the container group or NULL for default "lxc"
 * @name  : name of the container
 */
static int test_running_container(const char *lxcpath,
				  const char *group, const char *name)
{
	int ret = -1;
	struct lxc_container *c = NULL;
	char *cgrelpath;
	char  relpath[PATH_MAX+1];
	char  value[NAME_MAX], value_save[NAME_MAX];

	sprintf(relpath, "%s/%s", group ? group : "lxc", name);

	if ((c = lxc_container_new(name, lxcpath)) == NULL) {
		TSTERR("container %s couldn't instantiate", name);
		goto err1;
	}
	if (!c->is_defined(c)) {
		TSTERR("container %s does not exist", name);
		goto err2;
	}

	cgrelpath = lxc_cmd_get_cgroup_path(c->name, c->config_path, "freezer");
	if (!cgrelpath) {
		TSTERR("lxc_cmd_get_cgroup_path returned NULL");
		goto err2;
	}
	if (!strstr(cgrelpath, relpath)) {
		TSTERR("lxc_cmd_get_cgroup_path %s not in %s", relpath, cgrelpath);
		goto err3;
	}

	/* test get/set value using memory.soft_limit_in_bytes file */
	ret = lxc_cgroup_get("memory.soft_limit_in_bytes", value, sizeof(value),
			     c->name, c->config_path);
	if (ret < 0) {
		TSTERR("lxc_cgroup_get failed");
		goto err3;
	}
	strcpy(value_save, value);

	ret = lxc_cgroup_set("memory.soft_limit_in_bytes", "512M", c->name, c->config_path);
	if (ret < 0) {
		TSTERR("lxc_cgroup_set failed %d %d", ret, errno);
		goto err3;
	}
	ret = lxc_cgroup_get("memory.soft_limit_in_bytes", value, sizeof(value),
			     c->name, c->config_path);
	if (ret < 0) {
		TSTERR("lxc_cgroup_get failed");
		goto err3;
	}
	if (strcmp(value, "536870912\n")) {
		TSTERR("lxc_cgroup_set_bypath failed to set value >%s<", value);
		goto err3;
	}

	/* restore original value */
	ret = lxc_cgroup_set("memory.soft_limit_in_bytes", value_save,
			     c->name, c->config_path);
	if (ret < 0) {
		TSTERR("lxc_cgroup_set failed");
		goto err3;
	}

	ret = 0;

err3:
	free(cgrelpath);
err2:
	lxc_container_put(c);
err1:
	return ret;
}
示例#27
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);
}
示例#28
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;
}