于 2012年07月11日 17:30, Daniel P. Berrange 写道: > On Wed, Jul 11, 2012 at 03:58:20PM +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 Lxc-lxcname-fuse. >> >> Signed-off-by: Gao feng <gaofeng@xxxxxxxxxxxxxx> >> --- >> src/Makefile.am | 9 ++- >> src/lxc/lxc_controller.c | 15 +++++ >> src/lxc/lxc_driver.c | 2 + >> src/lxc/lxc_fuse.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++ >> src/lxc/lxc_fuse.h | 38 +++++++++++ >> 5 files changed, 217 insertions(+), 2 deletions(-) >> create mode 100644 src/lxc/lxc_fuse.c >> create mode 100644 src/lxc/lxc_fuse.h >> >> diff --git a/src/Makefile.am b/src/Makefile.am >> index 6c3eaa7..b01b2df 100644 >> --- a/src/Makefile.am >> +++ b/src/Makefile.am >> @@ -349,11 +349,13 @@ endif >> >> LXC_DRIVER_SOURCES = \ >> lxc/lxc_conf.c lxc/lxc_conf.h \ >> + lxc/lxc_fuse.c lxc/lxc_fuse.h \ >> lxc/lxc_container.c lxc/lxc_container.h \ >> lxc/lxc_driver.c lxc/lxc_driver.h >> >> LXC_CONTROLLER_SOURCES = \ >> lxc/lxc_conf.c lxc/lxc_conf.h \ >> + lxc/lxc_fuse.c lxc/lxc_fuse.h \ >> lxc/lxc_container.c lxc/lxc_container.h \ >> lxc/lxc_controller.c >> >> @@ -819,8 +821,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) >> @@ -1523,6 +1526,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_driver_security.la \ >> @@ -1540,7 +1544,8 @@ libvirt_lxc_LDADD += $(APPARMOR_LIBS) >> endif >> libvirt_lxc_CFLAGS = \ >> -I$(top_srcdir)/src/conf \ >> - $(AM_CFLAGS) >> + $(AM_CFLAGS) \ >> + $(FUSE_CFLAGS) >> if HAVE_LIBBLKID >> libvirt_lxc_CFLAGS += $(BLKID_CFLAGS) >> libvirt_lxc_LDADD += $(BLKID_LIBS) >> diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c >> index a4874ea..44ba07c 100644 >> --- a/src/lxc/lxc_controller.c >> +++ b/src/lxc/lxc_controller.c >> @@ -58,6 +58,7 @@ >> >> #include "lxc_conf.h" >> #include "lxc_container.h" >> +#include "lxc_fuse.h" >> #include "virnetdev.h" >> #include "virnetdevveth.h" >> #include "memory.h" >> @@ -1741,6 +1742,20 @@ int main(int argc, char *argv[]) >> } >> } >> >> + if ((pid = fork()) < 0) >> + goto cleanup; >> + >> + if (pid == 0) { >> + if ((pid = fork()) < 0) >> + _exit(-1); >> + >> + if (pid > 0) >> + _exit(0); >> + >> + lxcRegisterFuse(ctrl->def); >> + _exit(0); >> + } > > > This is double forking to daemonize, but you never execve() > anywhere. Thus according to POSIX you are mandated to only > use async signal safe functions. This is clearly impossible > given the functionality you need to use with FUSE. > > So either you need to make this a separate binary that can > be exec()'d, or instead of fork()ing, run this in a thread > of the libvirt_lxc process. I think you can probably make > do with just using a thread. > Get it,thanks for explaining this to me. >> +#if HAVE_FUSE >> + >> +static int lxcProcGetattr(const char *path, struct stat *stbuf) >> +{ >> + int res = 0; >> + >> + memset(stbuf, 0, sizeof(struct stat)); >> + if (strcmp(path, "/") == 0) { > > strcmp() == 0, is not allowed - use STREQ instead - if you > run 'make syntax-check' it should warn you about this. > >> + stbuf->st_mode = S_IFDIR | 0755; >> + stbuf->st_nlink = 2; >> + } else >> + res = -ENOENT; > > You need {} around the else clause, if you use {} > around the if clause (see HACKING) > Yes,will read it,thanks >> + >> + 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 (strcmp(path, "/") != 0) >> + 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, >> +}; >> + >> +int lxcRegisterFuse(virDomainDefPtr def) >> +{ >> + int rc = -1; >> + char *path = NULL; >> + char *name = NULL; >> + int argc = 3; >> + char *argv[argc]; >> + >> + if ((rc = virAsprintf(&name, "Lxc-%s-fuse", def->name)) < 0) { >> + virReportOOMError(); >> + goto cleanup; >> + } >> + >> + if ((rc = virAsprintf(&path, "%s/%s/", LXC_STATE_DIR, def->name)) < 0) { >> + virReportOOMError(); >> + goto cleanup; >> + } >> + >> + if ((rc = virFileMakePath(path)) < 0) { >> + virReportSystemError(errno, _("Cannot create %s"), path); >> + goto cleanup; >> + } >> + >> + argv[0] = name; >> + argv[1] = path; >> + argv[2] = (char *)"-odirect_io"; >> + >> + if ((rc = fuse_main(argc, argv, &lxcProcOper, def)) < 0) { >> + virReportSystemError(errno, "%s", _("Cannot start fuse\n")); >> + goto cleanup; >> + } >> + rc = 0; >> + >> +cleanup: >> + VIR_FREE(name); >> + VIR_FREE(path); >> + VIR_FREE(argv); >> + return rc; >> +} >> + >> +void lxcUnregisterFuse(virDomainDefPtr def) >> +{ >> + char *path = NULL; >> + if (virAsprintf(&path, "%s/%s/", LXC_STATE_DIR, def->name) < 0) { >> + virReportOOMError(); >> + return; >> + } >> + >> + if (umount(path) < 0) >> + virReportSystemError(errno, "%s", _("umount fuse filesystem failed\n")); >> + >> + VIR_FREE(path); >> +} >> + >> +#else >> +int lxcRegisterFuse(virDomainDefPtr def) >> +{ >> + (void) def; >> + return 0; >> +} >> + >> +void lxcUnregisterFuse(virDomainDefPtr def) >> +{ >> + (void) def; >> +} >> +#endif > > Use ATTRIBUTE_UNNUSED annotations instead of casting to (void) > Get it Thanks! Gao -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list