diff mbox

[2/2] Dump: add command "fuse-mount"

Message ID 1462663968-26607-3-git-send-email-nli@suse.com (mailing list archive)
State New, archived
Headers show

Commit Message

Nan Li May 7, 2016, 11:32 p.m. UTC
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 <nli@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(+)

Comments

Daniel P. Berrangé May 9, 2016, 4:30 p.m. UTC | #1
On Sun, May 08, 2016 at 07:32:48AM +0800, Nan Li wrote:
> 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 <nli@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 you fork() in a multi-threaded program, then you are restricted to
only use POSIX APIs declared async signal safe, until such time as
you execve().  I've not looked at the code, but I'm not imagining that
fuse_main() is going to be safe in this respect.


Regards,
Daniel
Eric Blake May 9, 2016, 4:48 p.m. UTC | #2
On 05/07/2016 05:32 PM, Nan Li wrote:
> 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 <nli@suse.com>
> ---
> +++ 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

s/umount/unmount/

New QMP commands should favor the use of '-' rather than '_' (as in
'is-mount').  But the name 'is_mount' does not even appear below, so you
aren't documenting reality.

> +#
> +# @mountpoint: the mount point (a path) of fuse system
> +#
> +# Returns: Nothing on success
> +#
> +# Since: 2.6

You've missed 2.6.  This has to be 2.7 or later.

> +##
> +{ 'command': 'fuse-mount', 'data': {'unmount': 'bool', 'mountpoint': 'str'} }
> +
Nan Li May 10, 2016, 11:32 a.m. UTC | #3
>>> On 5/10/2016 at 12:48 AM, Eric Blake <eblake@redhat.com> wrote:
> On 05/07/2016 05:32 PM, Nan Li wrote:
>> 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 <nli@suse.com>
>> ---
>> +++ 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
> 
> s/umount/unmount/
> 
> New QMP commands should favor the use of '-' rather than '_' (as in
> 'is-mount').  But the name 'is_mount' does not even appear below, so you
> aren't documenting reality.
> 
Right. This parameter should be unmount.

>> +#
>> +# @mountpoint: the mount point (a path) of fuse system
>> +#
>> +# Returns: Nothing on success
>> +#
>> +# Since: 2.6
> 
> You've missed 2.6.  This has to be 2.7 or later.
> 

OK. Thanks for pointing it out.

>> +##
>> +{ 'command': 'fuse-mount', 'data': {'unmount': 'bool', 'mountpoint': 'str'} 
> }
>> +
> 
> -- 
> Eric Blake   eblake redhat com    +1-919-301-3266
> Libvirt virtualization library http://libvirt.org 

Nan Li
diff mbox

Patch

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",