Add a "fuse-mount" command to support the Filesystem in Userspace (FUSE). It can mount or unmount the filesystem with both hmp and qmp commands. It calls the API function qemu_fuse_main(int argc, char *argv[]).
Signed-off-by: Nan Li <n...@suse.com> --- dump.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ hmp-commands.hx | 19 +++++++++++++++++++ hmp.c | 12 ++++++++++++ hmp.h | 1 + qapi-schema.json | 15 +++++++++++++++ qmp-commands.hx | 31 +++++++++++++++++++++++++++++++ 6 files changed, 126 insertions(+) diff --git a/dump.c b/dump.c index 9726f1f..7599f06 100644 --- a/dump.c +++ b/dump.c @@ -26,6 +26,10 @@ #include "qapi/qmp/qerror.h" #include "qmp-commands.h" #include "qapi-event.h" +#ifdef CONFIG_FUSE +#include <sys/mount.h> +#include "fuse-mem.h" +#endif #include <zlib.h> #ifdef CONFIG_LZO @@ -1846,3 +1850,47 @@ DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp) return cap; } + +#ifdef CONFIG_FUSE +static void *fuse_process(void *data) +{ + pid_t pid; + int argc = 2; + char *argv[2]; + char programname[] = "fuse-mount-process"; + argv[0] = programname; + argv[1] = (char *)data; + int ret; + + if ((pid = fork()) < 0) + perror("fork() is failed"); + else if (pid == 0) { + ret = qemu_fuse_main(argc, argv); + if ( ret != 0 ) + perror("qemu_fuse_main() is failed"); + exit(0); + } + return NULL; +} + +void qmp_fuse_mount(bool unmount, const char *mountpoint, Error **errp) +{ + int ret; + + if (unmount) { + ret = umount(mountpoint); + if (ret < 0) { + error_setg(errp, "umount() is failed"); + } + return; + } + + char * prot = g_strdup(mountpoint); + fuse_process((void *)prot); +} +#else +void qmp_fuse_mount(bool unmount, const char *mountpoint, Error **errp) +{ + abort(); +} +#endif diff --git a/hmp-commands.hx b/hmp-commands.hx index 4f4f60a..746db0c 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1087,6 +1087,25 @@ gdb. Without -z|-l|-s, the dump format is ELF. together with begin. ETEXI +#if defined(CONFIG_FUSE) + { + .name = "fuse-mount", + .args_type = "unmount:-u,mountpoint:s", + .params = "[-u] mountpoint", + .help = "mount(unmount) fuse system on 'mountpoint'.\n\t\t\t" + "-u: unmount.", + .mhandler.cmd = hmp_fuse_mount, + }, + +STEXI +@item fuse-mount [-u] @var{mountpoint} +@findex fuse-mount +Mount(unmount) fuse system to @var{mountpoint}. + -u: unmount. + mountpoint: the mount point (a path) of fuse system. +ETEXI +#endif + #if defined(TARGET_S390X) { .name = "dump-skeys", diff --git a/hmp.c b/hmp.c index d510236..884e8a3 100644 --- a/hmp.c +++ b/hmp.c @@ -1643,6 +1643,18 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict) g_free(prot); } +#ifdef CONFIG_FUSE +void hmp_fuse_mount(Monitor *mon, const QDict *qdict) +{ + Error *err = NULL; + bool unmount = qdict_get_try_bool(qdict, "unmount", false); + const char *mountpoint = qdict_get_str(qdict, "mountpoint"); + + qmp_fuse_mount(unmount, mountpoint, &err); + hmp_handle_error(mon, &err); +} +#endif + void hmp_netdev_add(Monitor *mon, const QDict *qdict) { Error *err = NULL; diff --git a/hmp.h b/hmp.h index 093d65f..f183fe9 100644 --- a/hmp.h +++ b/hmp.h @@ -85,6 +85,7 @@ void hmp_migrate(Monitor *mon, const QDict *qdict); void hmp_device_add(Monitor *mon, const QDict *qdict); void hmp_device_del(Monitor *mon, const QDict *qdict); void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict); +void hmp_fuse_mount(Monitor *mon, const QDict *qdict); void hmp_netdev_add(Monitor *mon, const QDict *qdict); void hmp_netdev_del(Monitor *mon, const QDict *qdict); void hmp_getfd(Monitor *mon, const QDict *qdict); diff --git a/qapi-schema.json b/qapi-schema.json index e58f6a9..d268019 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2283,6 +2283,21 @@ 'returns': 'DumpGuestMemoryCapability' } ## +# @fuse-mount: +# +# mount(unmount) fuse system on 'mountpoint'. +# +# @is_mount: optional if true, umount the fuse system from the mount point +# +# @mountpoint: the mount point (a path) of fuse system +# +# Returns: Nothing on success +# +# Since: 2.6 +## +{ 'command': 'fuse-mount', 'data': {'unmount': 'bool', 'mountpoint': 'str'} } + +## # @dump-skeys # # Dump guest's storage keys diff --git a/qmp-commands.hx b/qmp-commands.hx index de896a5..efcf6c1 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -921,6 +921,37 @@ Example: EQMP +#if defined(CONFIG_FUSE) + { + .name = "fuse-mount", + .args_type = "unmount:b,mountpoint:s", + .params = "[-u] mountpoint", + .help = "mount(unmount) fuse system on 'mountpoint'.\n\t\t\t" + "-u: unmount.", + .mhandler.cmd_new = qmp_marshal_fuse_mount, + }, +SQMP +fuse-mount + +mount(unmount) fuse system on 'mountpoint'. + +Arguments: + +- "unmount": unmount the fuse system (json-bool) +- "mountpoint": the mount point (a path) of fuse system (json-string) + +Example: + +-> { "execute": "fuse-mount", "arguments": { "mountpoint": "/etc/qemu/fuse" } } +<- { "return": {} } + +Notes: + +(1) All boolean arguments default to false + +EQMP +#endif + #if defined TARGET_S390X { .name = "dump-skeys", -- 1.8.4.5