[Libguestfs] [PATCH] New API: ufs-growfs to grow UFS filesystems.

Richard W.M. Jones rjones at redhat.com
Mon Jun 13 11:29:30 UTC 2011


This simple patch adds support for the BSD "growfs" command, so you
can grow BSD filesystems [in theory -- see below].

It also adds a new optional group called "ufsutils" which indicates if
the libguestfs API supports the guestfs_ufs_growfs call, since it's
not available on Fedora.  (http://libguestfs.org/guestfs.3.html#availability)

I tested this on Debian, and although we appear to be invoking the
growfs.ufs command correctly, the growfs command contains a bug.  It
appears that Debian doesn't implement the BSD DIOCGSECTORSIZE ioctl,
which means that growfs on Debian always dies with this error message:

  bogus sectorsize: 0

This appears to be a Debian bug.  Someone else can do a bit more
investigation on that one and file a bug if necessary.

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 d0702d6ccd519275b7d4c47ae2830120471737ba Mon Sep 17 00:00:00 2001
From: Richard W.M. Jones <rjones at redhat.com>
Date: Mon, 13 Jun 2011 12:16:03 +0100
Subject: [PATCH] New API: ufs-growfs to grow UFS filesystems.

Note that this new API is in the optional group "ufsutils"
which is not enabled on Fedora because the relevant utilities
are not packaged.
---
 daemon/Makefile.am             |    1 +
 daemon/ufs.c                   |   84 ++++++++++++++++++++++++++++++++++++++++
 generator/generator_actions.ml |   12 ++++++
 po/POTFILES.in                 |    3 +
 src/MAX_PROC_NR                |    2 +-
 5 files changed, 101 insertions(+), 1 deletions(-)
 create mode 100644 daemon/ufs.c

diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 8fb070f..77324d5 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -155,6 +155,7 @@ guestfsd_SOURCES = \
 	sync.c \
 	tar.c \
 	truncate.c \
+	ufs.c \
 	umask.c \
 	upload.c \
 	utimens.c \
diff --git a/daemon/ufs.c b/daemon/ufs.c
new file mode 100644
index 0000000..0b05568
--- /dev/null
+++ b/daemon/ufs.c
@@ -0,0 +1,84 @@
+/* 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 <inttypes.h>
+
+#include "guestfs_protocol.h"
+#include "daemon.h"
+#include "actions.h"
+#include "optgroups.h"
+
+/* ufsutils take sizes specified in blocks */
+#define UFS_BLOCKSIZE 512
+
+int
+optgroup_ufsutils_available (void)
+{
+  return prog_exists ("growfs.ufs");
+}
+
+/* Takes optional arguments, consult optargs_bitmask. */
+int
+do_ufs_growfs (const char *device, int64_t size)
+{
+  const char *argv[16];
+  size_t i = 0;
+  char size_str[64];
+  int r;
+  char *err;
+
+  argv[i++] = "growfs.ufs";
+  argv[i++] = "-y";
+
+  /* Is 'size' parameter specified? */
+  if (optargs_bitmask & GUESTFS_UFS_GROWFS_SIZE_BITMASK) {
+    /* Check 'size' parameter makes sense. */
+    if ((size & (UFS_BLOCKSIZE-1)) != 0) {
+      reply_with_error ("size must be a multiple of %d", UFS_BLOCKSIZE);
+      return -1;
+    }
+    if (size <= 0) {
+      reply_with_error ("size must be > 0");
+      return -1;
+    }
+
+    /* -s parameter is size in blocks */
+    size /= UFS_BLOCKSIZE;
+
+    snprintf (size_str, sizeof size_str, "%" PRIi64, size);
+    argv[i++] = "-s";
+    argv[i++] = size_str;
+  }
+
+  argv[i++] = device;
+  argv[i++] = NULL;
+
+  r = commandv (NULL, &err, argv);
+  if (r == -1) {
+    reply_with_error ("%s: %s", device, err);
+    free (err);
+    return -1;
+  }
+
+  free (err);
+  return 0;
+}
diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml
index 74b6515..376c53a 100644
--- a/generator/generator_actions.ml
+++ b/generator/generator_actions.ml
@@ -5960,6 +5960,18 @@ 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.");
 
+  ("ufs_growfs", (RErr, [Device "device"], [Int64 "size"]), 285, [Optional "ufsutils"],
+   [],
+   "grow a UFS filesystem",
+   "\
+This call grows a UFS filesystem.
+
+If the optional C<size> parameter is specified, then it is grown
+to that size (in bytes).  If the C<size> parameter is not specified,
+then the filesystem grows to the size of the underlying device.
+
+Shrinking UFS is not possible.");
+
 ]
 
 let all_functions = non_daemon_functions @ daemon_functions
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 7c0df52..97a190c 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -67,6 +67,7 @@ daemon/swap.c
 daemon/sync.c
 daemon/tar.c
 daemon/truncate.c
+daemon/ufs.c
 daemon/umask.c
 daemon/upload.c
 daemon/utimens.c
@@ -152,8 +153,10 @@ src/match.c
 src/proto.c
 src/virt.c
 test-tool/test-tool.c
+tools/virt-edit.pl
 tools/virt-list-filesystems.pl
 tools/virt-list-partitions.pl
 tools/virt-make-fs.pl
+tools/virt-resize.pl
 tools/virt-tar.pl
 tools/virt-win-reg.pl
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.2.3



More information about the Libguestfs mailing list