[libvirt] [RFC] [PATCH 2/5] add fuse support for libvirt lxc
Gao feng
gaofeng at cn.fujitsu.com
Thu Jul 12 01:33:14 UTC 2012
于 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 at cn.fujitsu.com>
>> ---
>> 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
More information about the libvir-list
mailing list