On Mon, Nov 12, 2012 at 03:02:24PM +0800, Gao feng wrote: > this patch addes fuse support for libvirt lxc. > we can use fuse filesystem to generate sysinfo dynamically, > So we can isolate /proc/meminfo,cpuinfo and so on through > fuse filesystem. > > we mount fuse filesystem for every container. > the mount name is libvirt,mount point is > localstatedir/run/libvirt/lxc/containername. > > Signed-off-by: Gao feng <gaofeng@xxxxxxxxxxxxxx> > --- > po/POTFILES.in | 1 + > src/Makefile.am | 9 ++- > src/lxc/lxc_cgroup.c | 1 + > src/lxc/lxc_container.h | 3 + > src/lxc/lxc_controller.c | 20 +++++ > src/lxc/lxc_fuse.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++ > src/lxc/lxc_fuse.h | 50 +++++++++++ > src/lxc/lxc_process.c | 1 + > 8 files changed, 285 insertions(+), 2 deletions(-) > create mode 100644 src/lxc/lxc_fuse.c > create mode 100644 src/lxc/lxc_fuse.h > > diff --git a/po/POTFILES.in b/po/POTFILES.in > index 9768528..0199d6f 100644 > --- a/po/POTFILES.in > +++ b/po/POTFILES.in > @@ -50,6 +50,7 @@ src/locking/lock_driver_sanlock.c > src/locking/lock_manager.c > src/locking/sanlock_helper.c > src/lxc/lxc_cgroup.c > +src/lxc/lxc_fuse.c > src/lxc/lxc_container.c > src/lxc/lxc_conf.c > src/lxc/lxc_controller.c > diff --git a/src/Makefile.am b/src/Makefile.am > index 1f32263..4b8e6c0 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -413,6 +413,7 @@ LXC_DRIVER_SOURCES = \ > lxc/lxc_domain.c lxc/lxc_domain.h \ > lxc/lxc_monitor.c lxc/lxc_monitor.h \ > lxc/lxc_process.c lxc/lxc_process.h \ > + lxc/lxc_fuse.c lxc/lxc_fuse.h \ > lxc/lxc_driver.c lxc/lxc_driver.h > > LXC_CONTROLLER_SOURCES = \ > @@ -421,6 +422,7 @@ LXC_CONTROLLER_SOURCES = \ > lxc/lxc_conf.c lxc/lxc_conf.h \ > lxc/lxc_container.c lxc/lxc_container.h \ > lxc/lxc_cgroup.c lxc/lxc_cgroup.h \ > + lxc/lxc_fuse.c lxc/lxc_fuse.h \ > lxc/lxc_controller.c > > SECURITY_DRIVER_APPARMOR_HELPER_SOURCES = \ > @@ -911,8 +913,9 @@ endif > > libvirt_driver_lxc_impl_la_CFLAGS = \ > $(LIBNL_CFLAGS) \ > + $(FUSE_CFLAGS) \ > -I$(top_srcdir)/src/conf $(AM_CFLAGS) > -libvirt_driver_lxc_impl_la_LIBADD = $(CAPNG_LIBS) $(LIBNL_LIBS) > +libvirt_driver_lxc_impl_la_LIBADD = $(CAPNG_LIBS) $(LIBNL_LIBS) $(FUSE_LIBS) > if HAVE_LIBBLKID > libvirt_driver_lxc_impl_la_CFLAGS += $(BLKID_CFLAGS) > libvirt_driver_lxc_impl_la_LIBADD += $(BLKID_LIBS) > @@ -1678,6 +1681,7 @@ libvirt_lxc_SOURCES = \ > libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(AM_LDFLAGS) > libvirt_lxc_LDADD = \ > $(NUMACTL_LIBS) \ > + $(FUSE_LIBS) \ > libvirt-net-rpc-server.la \ > libvirt-net-rpc.la \ > libvirt_security_manager.la \ > @@ -1696,7 +1700,8 @@ endif > libvirt_lxc_CFLAGS = \ > -I$(top_srcdir)/src/conf \ > $(AM_CFLAGS) \ > - $(LIBNL_CFLAGS) > + $(LIBNL_CFLAGS) \ > + $(FUSE_CFLAGS) > if HAVE_LIBBLKID > libvirt_lxc_CFLAGS += $(BLKID_CFLAGS) > libvirt_lxc_LDADD += $(BLKID_LIBS) > diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c > index bdfaa54..9a5ba1a 100644 > --- a/src/lxc/lxc_cgroup.c > +++ b/src/lxc/lxc_cgroup.c > @@ -163,6 +163,7 @@ static int virLXCCgroupSetupDeviceACL(virDomainDefPtr def, > {'c', LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_URANDOM}, > {'c', LXC_DEV_MAJ_TTY, LXC_DEV_MIN_TTY}, > {'c', LXC_DEV_MAJ_TTY, LXC_DEV_MIN_PTMX}, > + {'c', LXC_DEV_MAJ_FUSE, LXC_DEV_MIN_FUSE}, > {0, 0, 0}}; > > rc = virCgroupDenyAllDevices(cgroup); > diff --git a/src/lxc/lxc_container.h b/src/lxc/lxc_container.h > index b1adacb..c8c70e0 100644 > --- a/src/lxc/lxc_container.h > +++ b/src/lxc/lxc_container.h > @@ -46,6 +46,9 @@ enum { > > # define LXC_DEV_MAJ_PTY 136 > > +# define LXC_DEV_MAJ_FUSE 10 > +# define LXC_DEV_MIN_FUSE 229 > + > int lxcContainerSendContinue(int control); > int lxcContainerWaitForContinue(int control); > > diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c > index a41c903..b993fe5 100644 > --- a/src/lxc/lxc_controller.c > +++ b/src/lxc/lxc_controller.c > @@ -60,6 +60,7 @@ > #include "lxc_container.h" > #include "lxc_cgroup.h" > #include "lxc_protocol.h" > +#include "lxc_fuse.h" > #include "virnetdev.h" > #include "virnetdevveth.h" > #include "memory.h" > @@ -127,6 +128,8 @@ struct _virLXCController { > virNetServerProgramPtr prog; > bool inShutdown; > int timerShutdown; > + > + virLXCFusePtr fuse; > }; > > #include "lxc_controller_dispatch.h" > @@ -236,6 +239,13 @@ static void virLXCControllerConsoleClose(virLXCControllerConsolePtr console) > } > > > +static void > +virLXCControllerFreeFuse(virLXCControllerPtr ctrl) > +{ > + return lxcFreeFuse(&ctrl->fuse); > +} > + > + > static void virLXCControllerFree(virLXCControllerPtr ctrl) > { > size_t i; > @@ -266,6 +276,7 @@ static void virLXCControllerFree(virLXCControllerPtr ctrl) > virEventRemoveTimeout(ctrl->timerShutdown); > > virObjectUnref(ctrl->server); > + virLXCControllerFreeFuse(ctrl); > > VIR_FREE(ctrl); > } > @@ -1247,6 +1258,12 @@ cleanup: > > > static int > +virLXCControllerSetupFuse(virLXCControllerPtr ctrl) > +{ > + return lxcSetupFuse(&ctrl->fuse, ctrl->def); > +} > + > +static int > virLXCControllerSetupConsoles(virLXCControllerPtr ctrl, > char **containerTTYPaths) > { > @@ -1388,6 +1405,9 @@ virLXCControllerRun(virLXCControllerPtr ctrl) > if (virLXCControllerSetupDevPTS(ctrl) < 0) > goto cleanup; > > + if (virLXCControllerSetupFuse(ctrl) < 0) > + goto cleanup; > + > if (virLXCControllerSetupConsoles(ctrl, containerTTYPaths) < 0) > goto cleanup; > > diff --git a/src/lxc/lxc_fuse.c b/src/lxc/lxc_fuse.c > new file mode 100644 > index 0000000..6d621ee > --- /dev/null > +++ b/src/lxc/lxc_fuse.c > @@ -0,0 +1,202 @@ > +/* > + * Copyright (C) 2012 Fujitsu Limited. > + * > + * lxc_fuse.c: fuse filesystem support for libvirt lxc > + * > + * Authors: > + * Gao feng <gaofeng at cn.fujitsu.com> > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library. If not, see > + * <http://www.gnu.org/licenses/>. > + */ > + > +#include <config.h> > +#include <fcntl.h> > +#include <stdio.h> > +#include <errno.h> > +#include <string.h> > +#include <sys/mount.h> > +#include <mntent.h> > + > +#include "lxc_fuse.h" > +#include "virterror_internal.h" > +#include "logging.h" > + > +#define VIR_FROM_THIS VIR_FROM_LXC > + > +#if HAVE_FUSE > + > +static int lxcProcGetattr(const char *path, struct stat *stbuf) > +{ > + int res = 0; > + > + memset(stbuf, 0, sizeof(struct stat)); > + > + if (STREQ(path, "/")) { > + stbuf->st_mode = S_IFDIR | 0755; > + stbuf->st_nlink = 2; > + } else { > + res = -ENOENT; > + } > + > + return res; > +} > + > +static int lxcProcReaddir(const char *path, void *buf, > + fuse_fill_dir_t filler, > + off_t offset ATTRIBUTE_UNUSED, > + struct fuse_file_info *fi ATTRIBUTE_UNUSED) > +{ > + if (!STREQ(path, "/")) > + return -ENOENT; > + > + filler(buf, ".", NULL, 0); > + filler(buf, "..", NULL, 0); > + > + return 0; > +} > + > +static int lxcProcOpen(const char *path ATTRIBUTE_UNUSED, > + struct fuse_file_info *fi ATTRIBUTE_UNUSED) > +{ > + return -ENOENT; > +} > + > +static int lxcProcRead(const char *path ATTRIBUTE_UNUSED, > + char *buf ATTRIBUTE_UNUSED, > + size_t size ATTRIBUTE_UNUSED, > + off_t offset ATTRIBUTE_UNUSED, > + struct fuse_file_info *fi ATTRIBUTE_UNUSED) > +{ > + return -ENOENT; > +} > + > +static struct fuse_operations lxcProcOper = { > + .getattr = lxcProcGetattr, > + .readdir = lxcProcReaddir, > + .open = lxcProcOpen, > + .read = lxcProcRead, > +}; > + > +static void lxcFuseDestroy(virLXCFusePtr fuse) > +{ > + virMutexLock(&fuse->lock); > + fuse_unmount(fuse->mountpoint, fuse->ch); > + fuse_destroy(fuse->fuse); > + fuse->fuse = NULL; > + virMutexUnlock(&fuse->lock); > +} > + > +static void lxcFuseRun(void *opaque) > +{ > + virLXCFusePtr fuse = opaque; > + > + if (fuse_loop(fuse->fuse) < 0) > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("fuse_loop failed")); > + > + lxcFuseDestroy(fuse); > +} > + > +int lxcSetupFuse(virLXCFusePtr *f, virDomainDefPtr def) > +{ > + int ret = -1; > + struct fuse_args args = FUSE_ARGS_INIT(0, NULL); > + virLXCFusePtr fuse = NULL; > + > + if (VIR_ALLOC(fuse) < 0) > + goto cleanup; > + > + fuse->def = def; > + > + if (virMutexInit(&fuse->lock) < 0) > + goto cleanup2; > + > + if (virAsprintf(&fuse->mountpoint, "%s/%s/", LXC_STATE_DIR, > + def->name) < 0) { > + virReportOOMError(); > + goto cleanup1; > + } > + > + if (virFileMakePath(fuse->mountpoint) < 0) { > + virReportSystemError(errno, _("Cannot create %s"), > + fuse->mountpoint); > + goto cleanup1; > + } > + > + /* process name is libvirt_lxc */ > + if (fuse_opt_add_arg(&args, "libvirt_lxc") == -1 || > + fuse_opt_add_arg(&args, "-odirect_io") == -1 || > + fuse_opt_add_arg(&args, "-ofsname=libvirt") == -1) > + goto cleanup1; > + > + fuse->ch = fuse_mount(fuse->mountpoint, &args); > + if (fuse->ch == NULL) > + goto cleanup1; > + > + fuse->fuse = fuse_new(fuse->ch, &args, &lxcProcOper, > + sizeof(lxcProcOper), fuse->def); > + if (fuse->fuse == NULL) { > + fuse_unmount(fuse->mountpoint, fuse->ch); > + goto cleanup1; > + } > + > + if (virThreadCreate(&fuse->thread, true, lxcFuseRun, > + (void *)fuse) < 0) { > + lxcFuseDestroy(fuse); > + goto cleanup1; > + } > + > + ret = 0; > +cleanup: > + fuse_opt_free_args(&args); > + *f = fuse; > + return ret; > +cleanup1: > + VIR_FREE(fuse->mountpoint); > + virMutexDestroy(&fuse->lock); > +cleanup2: > + VIR_FREE(fuse); > + goto cleanup; > +} > + > +void lxcFreeFuse(virLXCFusePtr *f) > +{ > + virLXCFusePtr fuse = *f; > + /* lxcFuseRun thread create success */ > + if (fuse) { > + /* exit fuse_loop, lxcFuseRun thread may try to destroy > + * fuse->fuse at the same time,so add a lock here. */ > + virMutexLock(&fuse->lock); > + if (fuse->fuse) > + fuse_exit(fuse->fuse); > + virMutexUnlock(&fuse->lock); > + > + virThreadJoin(&fuse->thread); > + > + VIR_FREE(fuse->mountpoint); > + VIR_FREE(*f); > + } > +} > +#else > +int lxcSetupFuse(virLXCFusePtr *f ATTRIBUTE_UNUSED, > + virDomainDefPtr def ATTRIBUTE_UNUSED) > +{ > + return 0; > +} > + > +void lxcFreeFuse(virLXCFusePtr *f ATTRIBUTE_UNUSED) > +{ > +} > +#endif > diff --git a/src/lxc/lxc_fuse.h b/src/lxc/lxc_fuse.h > new file mode 100644 > index 0000000..f2d2cbb > --- /dev/null > +++ b/src/lxc/lxc_fuse.h > @@ -0,0 +1,50 @@ > +/* > + * Copyright (C) 2012 Fujitsu Limited. > + * > + * lxc_fuse.c: fuse filesystem support for libvirt lxc > + * > + * Authors: > + * Gao feng <gaofeng at cn.fujitsu.com> > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library. If not, see > + * <http://www.gnu.org/licenses/>. > + */ > + > +#ifndef LXC_FUSE_H > +#define LXC_FUSE_H > + > +#define FUSE_USE_VERSION 26 > + > +#include <config.h> > +#if HAVE_FUSE > +#include <fuse.h> > +#endif > + > +#include "lxc_conf.h" > +#include "util.h" > +#include "memory.h" > + > +struct virLXCFuse { > + virDomainDefPtr def; > + virThread thread; > + char *mountpoint; > + struct fuse *fuse; > + struct fuse_chan *ch; > + virMutex lock; > +}; > +typedef struct virLXCFuse *virLXCFusePtr; > + > +extern int lxcSetupFuse(virLXCFusePtr *f, virDomainDefPtr def); > +extern void lxcFreeFuse(virLXCFusePtr *f); > +#endif > diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c > index 079bc3a..a9a0984 100644 > --- a/src/lxc/lxc_process.c > +++ b/src/lxc/lxc_process.c > @@ -28,6 +28,7 @@ > #include "lxc_process.h" > #include "lxc_domain.h" > #include "lxc_container.h" > +#include "lxc_fuse.h" > #include "datatypes.h" > #include "virfile.h" > #include "virpidfile.h" > -- > 1.7.7.6 Yes, this seems better than having the busy wait. ACK. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://libguestfs.org -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list