[Libguestfs] [PATCH v1] Allow 9p filesystems to be mounted and listed (RHBZ#714981) *UNTESTED*.

Richard W.M. Jones rjones at redhat.com
Wed Jun 22 09:45:01 UTC 2011


The two patches attached allow 9p filesystems to be mounted and
listed.

Note that I did *not* test the new list-9p function, because I don't
have a guest with a new enough kernel handy.

9p filesystems are not included in the output of list-filesystems.
Because a lot of existing code feeds the output of list-filesystems
directly into the input of mount-options, mount-ro or (even worse)
plain old mount, we would need to change all these calls so that the
device parameter was a plain string.  These patches just make the
minimum changes instead, but could be evolved.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-top is 'top' for virtual machines.  Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://et.redhat.com/~rjones/virt-top
-------------- next part --------------
>From 3cfbfdd67e539b9f9a53cabb06eaac490c9f04fe Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones at redhat.com>
Date: Wed, 22 Jun 2011 09:29:18 +0100
Subject: [PATCH 2/3] mount-vfs: Allow 'device' parameter to be any string.

Relax the type of the 'device' parameter so it no longer needs to be
an actual device, but can be any string.  This allows users to mount
9p filesystems where 'device' is a mount tag.
---
 generator/generator_actions.ml |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml
index 74b6515..dfa66e0 100644
--- a/generator/generator_actions.ml
+++ b/generator/generator_actions.ml
@@ -2759,7 +2759,7 @@ If the C<options> parameter is an empty string, then
 no options are passed (all options default to whatever
 the filesystem uses).");
 
-  ("mount_vfs", (RErr, [String "options"; String "vfstype"; Device "device"; String "mountpoint"], []), 75, [],
+  ("mount_vfs", (RErr, [String "options"; String "vfstype"; String "device"; String "mountpoint"], []), 75, [],
    [],
    "mount a guest disk with mount options and vfstype",
    "\
-- 
1.7.5.2

-------------- next part --------------
>From 0fc94839f3e030b12a7c6a1ca7b1f54c96a875e2 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones at redhat.com>
Date: Wed, 22 Jun 2011 10:13:23 +0100
Subject: [PATCH 3/3] New API: list-9p lists 9p filesystem mount tags
 (RHBZ#714981).

---
 daemon/9p.c                    |  170 ++++++++++++++++++++++++++++++++++++++++
 daemon/Makefile.am             |    1 +
 generator/generator_actions.ml |    7 ++
 po/POTFILES.in                 |    1 +
 src/MAX_PROC_NR                |    2 +-
 5 files changed, 180 insertions(+), 1 deletions(-)
 create mode 100644 daemon/9p.c

diff --git a/daemon/9p.c b/daemon/9p.c
new file mode 100644
index 0000000..bc95803
--- /dev/null
+++ b/daemon/9p.c
@@ -0,0 +1,170 @@
+/* libguestfs - the guestfsd daemon
+ * Copyright (C) 2011 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <fcntl.h>
+
+#include "daemon.h"
+#include "actions.h"
+
+#define BUS_PATH "/sys/bus/virtio/drivers/9pnet_virtio"
+
+static char *read_whole_file (const char *filename);
+
+/* https://bugzilla.redhat.com/show_bug.cgi?id=714981#c1 */
+char **
+do_list_9p (void)
+{
+  char **r = NULL;
+  int size = 0, alloc = 0;
+
+  DIR *dir;
+  int err = 0;
+
+  dir = opendir (BUS_PATH);
+  if (!dir) {
+    perror ("opendir: " BUS_PATH);
+    if (errno != ENOENT)
+      return NULL;
+
+    /* If this directory doesn't exist, it probably means that
+     * the virtio driver isn't loaded.  Don't return an error
+     * in this case, but return an empty list.
+     */
+    if (add_string (&r, &size, &alloc, NULL) == -1)
+      return NULL;
+
+    return r;
+  }
+
+  while (1) {
+    errno = 0;
+    struct dirent *d = readdir (dir);
+    if (d == NULL) break;
+
+    if (STRPREFIX (d->d_name, "virtio")) {
+      char mount_tag_path[256];
+      snprintf (mount_tag_path, sizeof mount_tag_path,
+                BUS_PATH "/%s/mount_tag", d->d_name);
+
+      /* A bit unclear, but it looks like the virtio transport allows
+       * the mount tag length to be unlimited (or up to 65536 bytes).
+       * See: linux/include/linux/virtio_9p.h
+       */
+      char *mount_tag = read_whole_file (mount_tag_path);
+      if (mount_tag == 0)
+        continue;
+
+      if (add_string (&r, &size, &alloc, mount_tag) == -1) {
+        free (mount_tag);
+        free_stringslen (r, size);
+        closedir (dir);
+        return NULL;
+      }
+
+      free (mount_tag);
+    }
+  }
+
+  /* Check readdir didn't fail */
+  if (errno != 0) {
+    reply_with_perror ("readdir: /sys/block");
+    free_stringslen (r, size);
+    closedir (dir);
+    return NULL;
+  }
+
+  /* Close the directory handle */
+  if (closedir (dir) == -1) {
+    reply_with_perror ("closedir: /sys/block");
+    free_stringslen (r, size);
+    return NULL;
+  }
+
+  /* Sort the tags.  Note that r might be NULL if there are no tags. */
+  if (r != NULL)
+    sort_strings (r, size);
+
+  /* NULL terminate the list */
+  if (add_string (&r, &size, &alloc, NULL) == -1)
+    return NULL;
+
+  return r;
+}
+
+/* Read whole file into dynamically allocated array.  If there is an
+ * error, DON'T call reply_with_perror, just return NULL.  Returns a
+ * \0-terminated string.
+ */
+static char *
+read_whole_file (const char *filename)
+{
+  char *r = NULL;
+  size_t alloc = 0, size = 0;
+  int fd;
+
+  fd = open (filename, O_RDONLY);
+  if (fd == -1) {
+    perror (filename);
+    return NULL;
+  }
+
+  while (1) {
+    alloc += 256;
+    char *r2 = realloc (r, alloc);
+    if (r2 == NULL) {
+      perror ("realloc");
+      free (r);
+      return NULL;
+    }
+    r = r2;
+
+    /* The '- 1' in the size calculation ensures there is space below
+     * to add \0 to the end of the input.
+     */
+    ssize_t n = read (fd, r + size, alloc - size - 1);
+    if (n == -1) {
+      perror (filename);
+      free (r);
+      return NULL;
+    }
+    if (n == 0)
+      break;
+    size += n;
+  }
+
+  if (close (fd) == -1) {
+    perror (filename);
+    free (r);
+    return NULL;
+  }
+
+  r[size] = '\0';
+
+  return r;
+}
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 8fb070f..78049c9 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -88,6 +88,7 @@ errnostring.h: $(libsrcdir)/errnostring.h
 
 noinst_PROGRAMS = guestfsd
 guestfsd_SOURCES = \
+	9p.c \
 	actions.h \
 	available.c \
 	augeas.c \
diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml
index dfa66e0..651d242 100644
--- a/generator/generator_actions.ml
+++ b/generator/generator_actions.ml
@@ -5960,6 +5960,13 @@ This returns true iff the device exists and contains all zero bytes.
 
 Note that for large devices this can take a long time to run.");
 
+  ("list_9p", (RStringList "mounttags", [], []), 285, [],
+   [],
+   "list 9p filesystems",
+   "\
+List all 9p filesystems attached to the guest.  A list of
+mount tags is returned.");
+
 ]
 
 let all_functions = non_daemon_functions @ daemon_functions
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 7c0df52..da47c91 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,6 +1,7 @@
 cat/virt-cat.c
 cat/virt-filesystems.c
 cat/virt-ls.c
+daemon/9p.c
 daemon/augeas.c
 daemon/available.c
 daemon/base64.c
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index c9716b7..6cf4452 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-284
+285
-- 
1.7.5.2



More information about the Libguestfs mailing list