diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2012-06-09 13:42:13 +0100 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2012-06-09 14:52:39 +0100 |
commit | 4ba6aa3eaeb112a1468ad9189120d12e1df23709 (patch) | |
tree | e2606f99e5d6f69eaeacae3595e24755966feca5 /daemon | |
parent | 4f671c829e33a218309f332621802d8d6f8d5040 (diff) | |
download | libguestfs-4ba6aa3eaeb112a1468ad9189120d12e1df23709.tar.gz libguestfs-4ba6aa3eaeb112a1468ad9189120d12e1df23709.tar.xz libguestfs-4ba6aa3eaeb112a1468ad9189120d12e1df23709.zip |
New API: filesystem-available: tests for filesystem availability.
This also creates an internal filesystem_available function within the
daemon.
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/available.c | 79 | ||||
-rw-r--r-- | daemon/daemon.h | 3 |
2 files changed, 82 insertions, 0 deletions
diff --git a/daemon/available.c b/daemon/available.c index 97f15584..08e72f30 100644 --- a/daemon/available.c +++ b/daemon/available.c @@ -22,9 +22,12 @@ #include <stdlib.h> #include <string.h> +#include "c-ctype.h" + #include "guestfs_protocol.h" #include "daemon.h" #include "actions.h" +#include "optgroups.h" int do_available (char *const *groups) @@ -70,3 +73,79 @@ do_available_all_groups (void) return groups.argv; /* caller frees */ } + +/* Search for filesystem in /proc/filesystems, ignoring "nodev". */ +static int +test_proc_filesystems (const char *filesystem) +{ + size_t len = strlen (filesystem) + 32; + char regex[len]; + char *err; + int r; + + snprintf (regex, len, "^[[:space:]]*%s$", filesystem); + + r = commandr (NULL, &err, "grep", regex, "/proc/filesystems", NULL); + if (r == -1 || r >= 2) { + fprintf (stderr, "grep /proc/filesystems: %s", err); + free (err); + return -1; + } + free (err); + + return r == 0; +} + +/* Do modprobe, ignore any errors. */ +static void +modprobe (const char *module) +{ + command (NULL, NULL, "modprobe", module, NULL); +} + +/* Internal function for testing if a filesystem is available. Note + * this must not call reply_with_error functions. + */ +int +filesystem_available (const char *filesystem) +{ + int r; + + r = test_proc_filesystems (filesystem); + if (r == -1 || r > 0) + return r; + + /* Not found: try to modprobe the module, then test again. */ + if (optgroup_linuxmodules_available ()) { + modprobe (filesystem); + + r = test_proc_filesystems (filesystem); + if (r == -1) + return -1; + } + + return r; +} + +int +do_filesystem_available (const char *filesystem) +{ + size_t i, len = strlen (filesystem); + int r; + + for (i = 0; i < len; ++i) { + if (!c_isalnum (filesystem[i]) && filesystem[i] != '_') { + reply_with_error ("filesystem name contains non-alphanumeric characters"); + return -1; + } + } + + r = filesystem_available (filesystem); + if (r == -1) { + reply_with_error ("error testing for filesystem availability; " + "enable verbose mode and look at preceeding output"); + return -1; + } + + return r; +} diff --git a/daemon/daemon.h b/daemon/daemon.h index 9dfaa4f3..af81a9da 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -151,6 +151,9 @@ struct optgroup { }; extern struct optgroup optgroups[]; +/*-- in available.c --*/ +extern int filesystem_available (const char *filesystem); + /*-- in sync.c --*/ /* Use this as a replacement for sync(2). */ extern int sync_disks (void); |