[CRIU] [PATCH 1/5] crtools: preload libraries

Andrew Vagin avagin at parallels.com
Fri Dec 6 01:18:11 PST 2013


On Fri, Dec 06, 2013 at 12:42:45PM +0400, Pavel Emelyanov wrote:
> >>> @@ -0,0 +1,22 @@
> >>> +#ifndef __CR_PLUGIN_H__
> >>> +#define __CR_PLUGIN_H__
> >>> +
> >>> +#include "criu-plugin.h"
> >>> +
> >>> +struct cr_plugin_entry {
> >>> +	union {
> >>> +		cr_plugin_fini_t *cr_fini;
> >>> +	};
> >>> +
> >>> +	struct cr_plugin_entry *next;
> >>> +};
> >>> +
> >>> +struct cr_plugins {
> >>> +	struct cr_plugin_entry *cr_fini;
> >>> +};
> >>> +
> >>> +extern struct cr_plugins cr_plugins;
> >>
> >> Why should this info be public?
> > 
> > criu-plugin.h is public, this one isn't.
> 
> OK, s/public/criu-sources-visible/
> Why?

I see. will fix. Thanks.
> 
> >>
> >>> +
> >>> +void cr_lib_fini(void);
> >>> +int cr_lib_init(void);
> >>> +#endif
> >>> diff --git a/lib.c b/lib.c
> >>> new file mode 100644
> >>> index 0000000..387bb84
> >>> --- /dev/null
> >>> +++ b/lib.c
> >>> @@ -0,0 +1,123 @@
> >>> +#include <stdlib.h>
> >>> +#include <string.h>
> >>> +#include <dirent.h>
> >>> +#include <errno.h>
> >>> +#include <stdio.h>
> >>> +#include <dlfcn.h>
> >>> +
> >>> +#include "cr_options.h"
> >>> +#include "plugin.h"
> >>> +#include "log.h"
> >>> +#include "xmalloc.h"
> >>> +
> >>> +struct cr_plugins cr_plugins;
> >>> +
> >>> +static int cr_lib_load(char *path)
> >>> +{
> >>> +	struct cr_plugin_entry *ce;
> >>> +	cr_plugin_init_t *f_init;
> >>> +	cr_plugin_fini_t *f_fini;
> >>> +	void *h;
> >>> +
> >>> +	h = dlopen(path, RTLD_LAZY);
> >>> +	if (h == NULL) {
> >>> +		pr_err("Unable to load %s: %s", path, dlerror());
> >>> +		return -1;
> >>> +	}
> >>> +
> >>> +	ce = NULL;
> >>> +	f_fini = dlsym(h, "cr_plugin_fini");
> >>> +	if (f_fini) {
> >>> +		ce = xmalloc(sizeof(struct cr_plugin_entry));
> >>> +		if (ce == NULL)
> >>> +			return -1;
> >>> +		ce->cr_fini = f_fini;
> >>
> >> In patch #3 you use some fancy macro for this.
> > 
> > f_fini is a special case.
> >>
> >>> +	}
> >>> +
> >>> +	f_init = dlsym(h, "cr_plugin_init");
> >>> +	if (f_init && f_init()) {
> >>> +		xfree(ce);
> >>> +		return -1;
> >>> +	}
> >>> +
> >>> +	if (ce) {
> >>> +		ce->next = cr_plugins.cr_fini;
> >>> +		cr_plugins.cr_fini = ce;
> >>> +	}
> > 
> > because it's added in the list here
> 
> Why?

It should be added only if cr_plugin_init() doesn't fail.

I can rewrite this codee by using the macros, but I like this version
more.

> 
> >>> +
> >>> +	return 0;
> >>> +}
> >>> +
> >>> +void cr_lib_fini(void)
> >>> +{
> >>> +	struct cr_plugin_entry *ce;
> >>> +
> >>> +	while (cr_plugins.cr_fini) {
> >>> +		ce = cr_plugins.cr_fini;
> >>> +		cr_plugins.cr_fini = cr_plugins.cr_fini->next;
> >>> +
> >>> +		ce->cr_fini();
> >>> +		xfree(ce);
> >>> +	}
> >>> +}
> >>> +
> >>> +int cr_lib_init(void)
> >>> +{
> >>> +	int exit_code = -1;
> >>> +	DIR *d;
> >>> +
> >>> +	memset(&cr_plugins, 0, sizeof(cr_plugins));
> >>> +
> >>> +	if (opts.libdir == NULL) {
> >>> +		char *path;
> >>> +
> >>> +		path = getenv("CRIU_LIBS_DIR");
> >>> +		if (path == NULL)
> >>
> >> I think we should declare some default library for it.
> > 
> > I thought about this. I don't know which path can be default and we can
> > add the default path in any moment.
> 
> Plz, declare the /var/lib/criu/ and use it.

Ok

> 
> > 
> >>
> >>> +			return 0;
> >>> +
> >>> +		opts.libdir = strdup(path);
> >>
> >> Why strdup?
> > 
> > becuase we need to copy the string, when we are parsing options,
> > so we are going to call free(opts.libdir)
> > 
> >>
> >>> +		if (opts.libdir == NULL) {
> >>> +			pr_perror("Can't allocate memory");
> >>> +			return -1;
> >>> +		}
> >>> +	}
> >>> +
> >>> +	d = opendir(opts.libdir);
> >>> +	if (d == 0) {
> >>> +		pr_perror("Unable to open directory %s", opts.libdir);
> >>> +		return -1;
> >>> +	}
> >>> +
> >>> +	while (1) {
> >>> +		char path[PATH_MAX];
> >>> +		struct dirent *de;
> >>> +		int len;
> >>> +
> >>> +		errno = 0;
> >>> +		de = readdir(d);
> >>> +		if (de == NULL) {
> >>> +			if (errno == 0)
> >>> +				break;
> >>> +			pr_perror("Unable to read the libraries directory");
> >>> +			goto err;
> >>> +		}
> >>> +
> >>> +		len = strlen(de->d_name);
> >>> +
> >>> +		if (len < 3 || strncmp(de->d_name + len - 3, ".so", 3))
> >>> +			continue;
> >>> +
> >>> +		snprintf(path, sizeof(path), "%s/%s", opts.libdir, de->d_name);
> >>> +
> >>> +		if (cr_lib_load(path))
> >>> +			goto err;
> >>> +	}
> >>> +
> >>> +	exit_code = 0;
> >>> +err:
> >>> +	closedir(d);
> >>> +
> >>> +	cr_lib_fini();
> >>> +
> >>> +	return exit_code;
> >>> +}
> >>>
> >>
> >>
> > .
> > 
> 
> 


More information about the CRIU mailing list