[lxc-devel] [PATCH] define list container api

Serge Hallyn serge.hallyn at ubuntu.com
Thu Oct 10 13:33:28 UTC 2013


Quoting Stéphane Graber (stgraber at ubuntu.com):
> On Wed, Oct 09, 2013 at 07:17:43AM -0500, Serge Hallyn wrote:
> > Two new commands are defined: list_defined_containers() and
> > list_active_containers().  Both take an lxcpath (NULL means
> > use the default lxcpath) and return the number of containers
> > found.  If a lxc_container ** is passed in, then an array of
> > lxc_container's is returned, one for each container found.
> > The caller must then lxc_container_put() each container and
> > free the array, as shown in the new list testcase.
> > 
> > Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
> 
> Overall looks good, thanks!
> 
> I just have one question/comment below that may impact memory/cpu usage
> and performance quite a bit on machines with a lot of containers.
> 
> > ---
> >  src/lxc/lxccontainer.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++
> >  src/lxc/lxccontainer.h |  19 ++++++
> >  src/tests/Makefile.am  |   6 +-
> >  src/tests/list.c       |  57 ++++++++++++++++++
> >  4 files changed, 235 insertions(+), 2 deletions(-)
> >  create mode 100644 src/tests/list.c
> > 
> > diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> > index 13ed4d2..5a0edce 100644
> > --- a/src/lxc/lxccontainer.c
> > +++ b/src/lxc/lxccontainer.c
> > @@ -2744,3 +2744,158 @@ int lxc_get_wait_states(const char **states)
> >  			states[i] = lxc_state2str(i);
> >  	return MAX_STATE;
> >  }
> > +
> > +
> > +bool add_to_clist(struct lxc_container ***list, struct lxc_container *c, int pos)
> > +{
> > +	struct lxc_container **newlist = realloc(*list, pos * sizeof(struct lxc_container *));
> > +	if (!newlist) {
> > +		free(*list);
> > +		*list = NULL;
> > +		ERROR("Out of memory");
> > +		return false;
> > +	}
> > +
> > +	*list = newlist;
> > +	newlist[pos-1] = c;
> > +	return true;
> > +}
> > +
> > +int list_defined_containers(const char *lxcpath, struct lxc_container ***cret)
> > +{
> > +	DIR *dir;
> > +	int nfound = 0;
> > +	struct dirent dirent, *direntp;
> > +
> > +	if (!lxcpath)
> > +		lxcpath = default_lxc_path();
> > +
> > +	process_lock();
> > +	dir = opendir(lxcpath);
> > +	process_unlock();
> > +
> > +	if (!dir) {
> > +		SYSERROR("opendir on lxcpath");
> > +		return -1;
> > +	}
> > +
> > +	if (cret)
> > +		*cret = NULL;
> > +
> > +	while (!readdir_r(dir, &dirent, &direntp)) {
> > +		if (!direntp)
> > +			break;
> > +		if (!strcmp(direntp->d_name, "."))
> > +			continue;
> > +		if (!strcmp(direntp->d_name, ".."))
> > +			continue;
> 
> Is it actually faster or more reliable to load the whole container
> instead of just looking for direntp->d_name/config?
> 
> > +
> > +		struct lxc_container *c = lxc_container_new(direntp->d_name, lxcpath);

Originally I had a comment there to say we might want to just
manually check for the config file.  Originally I also had a
char *** passed in so you could harvest only the container
names without getting the full lxc_container structs.

What I liked about this is the ability to reuse the
lxcapi_is_defined() function and avoid reimplementing
the check - with potential for accidental divergence as
the code evolves.

Should we offer the char *** option?  Or is that just
going to complicate the lua/go/python api exports?

-serge




More information about the lxc-devel mailing list