On 12/06/2012 07:41 PM, Serge Hallyn wrote: > set_cgroup_item takes a pointer to a running container, a cgroup subsystem > name, and a char *value and it mimicks > 'lxc-cgroup -n containername subsys value' > get_cgroup_item takes a pointer to a running container, a a cgroup > subsystem name, a destination value * and the length of the value being > sent in, and returns the length of what was read from the cgroup file. > If a 0 len is passed in, then the length of the file is returned. So > you can do > > len = c->get_cgroup_item(c, "devices.list", NULL, 0); > v = malloc(len+1); > ret = c->get_cgroup_item(c, "devices.list", v, len); > > to read the whole file. > > This patch also disables the lxc-init part of the startone test, which > was failing because lxc-init has been moved due to multiarch issues. > The test is salvagable, but saving it was beyond this effort. > > Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com>
Looks good. I'll apply it now and test it thoroughly when updating the python binding later today. Acked-by: Stéphane Graber <stgra...@ubuntu.com> > --- > src/lxc/cgroup.c | 20 ++++++++++++++++++- > src/lxc/lxccontainer.c | 52 > ++++++++++++++++++++++++++++++++++++++++++++++++ > src/lxc/lxccontainer.h | 9 +++++++++ > src/tests/startone.c | 47 +++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 127 insertions(+), 1 deletion(-) > > diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c > index 532d638..b6c948b 100644 > --- a/src/lxc/cgroup.c > +++ b/src/lxc/cgroup.c > @@ -789,6 +789,13 @@ out: > return ret; > } > > +/* > + * If you pass in NULL value or 0 len, then you are asking for the size > + * of the file. Note that we can't get the file size quickly through stat > + * or lseek. Therefore if you pass in len > 0 but less than the file size, > + * your only indication will be that the return value will be equal to the > + * passed-in ret. We will not return the actual full file size. > + */ > int lxc_cgroup_get(const char *name, const char *filename, > char *value, size_t len) > { > @@ -813,7 +820,18 @@ int lxc_cgroup_get(const char *name, const char > *filename, > return -1; > } > > - ret = read(fd, value, len); > + if (!len || !value) { > + char buf[100]; > + int count = 0; > + while ((ret = read(fd, buf, 100)) > 0) > + count += ret; > + if (ret >= 0) > + ret = count; > + } else { > + memset(value, 0, len); > + ret = read(fd, value, len); > + } > + > if (ret < 0) > ERROR("read %s : %s", path, strerror(errno)); > > diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c > index d25b848..1345ab5 100644 > --- a/src/lxc/lxccontainer.c > +++ b/src/lxc/lxccontainer.c > @@ -163,6 +163,13 @@ static const char *lxcapi_state(struct lxc_container *c) > return ret; > } > > +static bool is_stopped_nolock(struct lxc_container *c) > +{ > + lxc_state_t s; > + s = lxc_getstate(c->name); > + return (s == STOPPED); > +} > + > static bool lxcapi_is_running(struct lxc_container *c) > { > const char *s; > @@ -850,6 +857,49 @@ static char *lxcapi_config_file_name(struct > lxc_container *c) > return strdup(c->configfile); > } > > +static bool lxcapi_set_cgroup_item(struct lxc_container *c, const char > *subsys, const char *value) > +{ > + int ret; > + bool b = false; > + > + if (!c) > + return false; > + > + if (lxclock(c->privlock, 0)) > + return false; > + > + if (is_stopped_nolock(c)) > + goto err; > + > + ret = lxc_cgroup_set(c->name, subsys, value); > + if (!ret) > + b = true; > +err: > + lxcunlock(c->privlock); > + return b; > +} > + > +static int lxcapi_get_cgroup_item(struct lxc_container *c, const char > *subsys, char *retv, int inlen) > +{ > + int ret = -1; > + > + if (!c || !c->lxc_conf) > + return -1; > + > + if (lxclock(c->privlock, 0)) > + return -1; > + > + if (is_stopped_nolock(c)) > + goto out; > + > + ret = lxc_cgroup_get(c->name, subsys, retv, inlen); > + > +out: > + lxcunlock(c->privlock); > + return ret; > +} > + > + > struct lxc_container *lxc_container_new(const char *name) > { > struct lxc_container *c; > @@ -920,6 +970,8 @@ struct lxc_container *lxc_container_new(const char *name) > c->shutdown = lxcapi_shutdown; > c->clear_config_item = lxcapi_clear_config_item; > c->get_config_item = lxcapi_get_config_item; > + c->get_cgroup_item = lxcapi_get_cgroup_item; > + c->set_cgroup_item = lxcapi_set_cgroup_item; > > /* we'll allow the caller to update these later */ > if (lxc_log_init(NULL, NULL, "lxc_container", 0)) { > diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h > index 9c9296c..a6fdb2b 100644 > --- a/src/lxc/lxccontainer.h > +++ b/src/lxc/lxccontainer.h > @@ -48,6 +48,15 @@ struct lxc_container { > * the length which was our would be printed. */ > int (*get_config_item)(struct lxc_container *c, const char *key, char > *retv, int inlen); > int (*get_keys)(struct lxc_container *c, const char *key, char *retv, > int inlen); > + /* > + * get_cgroup_item returns the number of bytes read, or an error (<0). > + * If retv NULL or inlen 0 is passed in, then the length of the cgroup > + * file will be returned. * Otherwise it will return the # of bytes > read. > + * If inlen is less than the number of bytes available, then the > returned > + * value will be inlen, not the full available size of the file. > + */ > + int (*get_cgroup_item)(struct lxc_container *c, const char *subsys, > char *retv, int inlen); > + bool (*set_cgroup_item)(struct lxc_container *c, const char *subsys, > const char *value); > > #if 0 > bool (*commit_cgroups)(struct lxc_container *c); > diff --git a/src/tests/startone.c b/src/tests/startone.c > index 81a6bfb..325942e 100644 > --- a/src/tests/startone.c > +++ b/src/tests/startone.c > @@ -98,6 +98,8 @@ int main(int argc, char *argv[]) > int ret = 0; > const char *s; > bool b; > + char buf[201]; > + int len; > > ret = 1; > /* test a real container */ > @@ -125,6 +127,19 @@ int main(int argc, char *argv[]) > 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"); > @@ -172,12 +187,43 @@ int main(int argc, char *argv[]) > 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 */ > + 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/"); > @@ -204,6 +250,7 @@ int main(int argc, char *argv[]) > } > // auto-check result? ('bobo' is printed on stdout) > > +ok: > fprintf(stderr, "all lxc_container tests passed for %s\n", c->name); > ret = 0; > > -- Stéphane Graber Ubuntu developer http://www.ubuntu.com
signature.asc
Description: OpenPGP digital signature
------------------------------------------------------------------------------ LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial Remotely access PCs and mobile devices and provide instant support Improve your efficiency, and focus on delivering more value-add services Discover what IT Professionals Know. Rescue delivers http://p.sf.net/sfu/logmein_12329d2d
_______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel