diff options
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/Makefile.am | 2 | ||||
-rw-r--r-- | daemon/augeas.c | 52 | ||||
-rw-r--r-- | daemon/available.c | 23 | ||||
-rw-r--r-- | daemon/configure.ac | 24 | ||||
-rw-r--r-- | daemon/daemon.h | 17 | ||||
-rw-r--r-- | daemon/inotify.c | 31 | ||||
-rw-r--r-- | daemon/lvm.c | 8 | ||||
-rw-r--r-- | daemon/mknod.c | 18 | ||||
-rw-r--r-- | daemon/modprobe.c | 8 | ||||
-rw-r--r-- | daemon/ntfs.c | 8 | ||||
-rw-r--r-- | daemon/scrub.c | 8 | ||||
-rw-r--r-- | daemon/selinux.c | 21 | ||||
-rw-r--r-- | daemon/swap.c | 19 | ||||
-rw-r--r-- | daemon/xattr.c | 47 | ||||
-rw-r--r-- | daemon/zerofree.c | 8 |
15 files changed, 214 insertions, 80 deletions
diff --git a/daemon/Makefile.am b/daemon/Makefile.am index d851e527..9fa8ddab 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -81,6 +81,8 @@ guestfsd_SOURCES = \ mount.c \ names.c \ ntfs.c \ + optgroups.c \ + optgroups.h \ parted.c \ pingdaemon.c \ proto.c \ diff --git a/daemon/augeas.c b/daemon/augeas.c index b56012cd..be53d294 100644 --- a/daemon/augeas.c +++ b/daemon/augeas.c @@ -29,6 +29,7 @@ #include "daemon.h" #include "actions.h" +#include "optgroups.h" #ifdef HAVE_AUGEAS /* The Augeas handle. We maintain a single handle per daemon, which @@ -45,6 +46,18 @@ static augeas *aug = NULL; } \ } \ while (0) + +int +optgroup_augeas_available (void) +{ + return 1; +} +#else /* !HAVE_AUGEAS */ +int +optgroup_augeas_available (void) +{ + return 0; +} #endif /* We need to rewrite the root path so it is based at /sysroot. */ @@ -75,8 +88,7 @@ do_aug_init (const char *root, int flags) return 0; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } @@ -91,8 +103,7 @@ do_aug_close (void) return 0; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } @@ -111,8 +122,7 @@ do_aug_defvar (const char *name, const char *expr) } return r; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } @@ -133,8 +143,7 @@ do_aug_defnode (const char *name, const char *expr, const char *val) r.b = created; return &r; #else - reply_with_error ("%s is not available", __func__); - return NULL; + NOT_AVAILABLE (-1); #endif } @@ -176,8 +185,7 @@ do_aug_get (const char *path) return v; /* Caller frees. */ #else - reply_with_error ("%s is not available", __func__); - return NULL; + NOT_AVAILABLE (NULL); #endif } @@ -197,8 +205,7 @@ do_aug_set (const char *path, const char *val) return 0; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } @@ -218,8 +225,7 @@ do_aug_insert (const char *path, const char *label, int before) return 0; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } @@ -239,8 +245,7 @@ do_aug_rm (const char *path) return r; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } @@ -260,8 +265,7 @@ do_aug_mv (const char *src, const char *dest) return 0; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } @@ -295,8 +299,7 @@ do_aug_match (const char *path) return matches; /* Caller frees. */ #else - reply_with_error ("%s is not available", __func__); - return NULL; + NOT_AVAILABLE (NULL); #endif } @@ -313,8 +316,7 @@ do_aug_save (void) return 0; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } @@ -331,8 +333,7 @@ do_aug_load (void) return 0; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } @@ -379,7 +380,6 @@ do_aug_ls (const char *path) sort_strings (matches, count_strings ((void *) matches)); return matches; /* Caller frees. */ #else - reply_with_error ("%s is not available", __func__); - return NULL; + NOT_AVAILABLE (NULL); #endif } diff --git a/daemon/available.c b/daemon/available.c index b43d1820..77fdfa2c 100644 --- a/daemon/available.c +++ b/daemon/available.c @@ -29,9 +29,26 @@ int do_available (char *const *groups) { - if (groups[0] != NULL) { - reply_with_error ("%s: unknown group", groups[0]); - return -1; + int av; + size_t i, j; + + for (i = 0; groups[i] != NULL; ++i) { + for (j = 0; optgroups[j].group != NULL; ++j) { + if (STREQ (groups[i], optgroups[j].group)) { + av = optgroups[j].available (); + if (!av) { + reply_with_error ("%s: group not available", optgroups[j].group); + return -1; + } + break; /* out of for (j) loop */ + } + } + + /* Unknown group? */ + if (optgroups[j].group == NULL) { + reply_with_error ("%s: unknown group", groups[i]); + return -1; + } } return 0; diff --git a/daemon/configure.ac b/daemon/configure.ac index a1f54a3b..c6d9d98f 100644 --- a/daemon/configure.ac +++ b/daemon/configure.ac @@ -133,7 +133,7 @@ AC_STRUCT_DIRENT_D_TYPE dnl Check if stat has the required fields. AC_STRUCT_ST_BLOCKS AC_CHECK_MEMBER([struct stat.st_blksize],[ - AC_DEFINE([HAVE_STRUCT_STAT_ST_BLKSIZE],[1],[Define to 1 if 'st_blksize' is a member of 'struct stat'])]) + AC_DEFINE([HAVE_STRUCT_STAT_ST_BLKSIZE],[1],[Define to 1 if 'st_blksize' is a member of 'struct stat'])]) dnl Check for Augeas (now optional). AC_CHECK_LIB([augeas],[aug_match],[ @@ -164,17 +164,17 @@ AC_CHECK_LIB([portablexdr],[xdrmem_create],[],[ dnl Functions which may not be available in older distributions. AC_CHECK_FUNCS([\ - futimens \ - getxattr \ - inotify_init1 \ - lgetxattr \ - listxattr \ - llistxattr \ - lsetxattr \ - lremovexattr \ - mknod \ - removexattr \ - setxattr]) + futimens \ + getxattr \ + inotify_init1 \ + lgetxattr \ + listxattr \ + llistxattr \ + lsetxattr \ + lremovexattr \ + mknod \ + removexattr \ + setxattr]) dnl Headers. AC_CHECK_HEADERS([\ diff --git a/daemon/daemon.h b/daemon/daemon.h index 120c86cc..7ba75990 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -105,6 +105,13 @@ extern guestfs_int_lvm_lv_list *parse_command_line_lvs (void); /*-- in proto.c --*/ extern void main_loop (int sock) __attribute__((noreturn)); +/*-- in optgroups.c (auto-generated) --*/ +struct optgroup { + const char *group; /* Name of the optional group. */ + int (*available) (void); /* Function to test availability. */ +}; +extern struct optgroup optgroups[]; + /* ordinary daemon functions use these to indicate errors */ extern void reply_with_error (const char *fs, ...) __attribute__((format (printf,1,2))); @@ -225,6 +232,16 @@ extern void reply (xdrproc_t xdrp, char *ret); } \ while (0) +/* Marks functions which are not available. + * NB. Cannot be used for FileIn functions. + */ +#define NOT_AVAILABLE(errcode) \ + do { \ + reply_with_error ("%s: function not available", __func__); \ + return (errcode); \ + } \ + while (0) + #ifndef __attribute__ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) # define __attribute__(x) /* empty */ diff --git a/daemon/inotify.c b/daemon/inotify.c index 465d0b6e..24ce76e2 100644 --- a/daemon/inotify.c +++ b/daemon/inotify.c @@ -31,6 +31,7 @@ #include "../src/guestfs_protocol.h" #include "daemon.h" #include "actions.h" +#include "optgroups.h" #ifdef HAVE_SYS_INOTIFY_H /* Currently open inotify handle, or -1 if not opened. */ @@ -38,6 +39,18 @@ static int inotify_fd = -1; static char inotify_buf[64*1024*1024]; /* Event buffer, [0..posn-1] is valid */ static size_t inotify_posn = 0; + +int +optgroup_inotify_available (void) +{ + return 1; +} +#else /* !HAVE_SYS_INOTIFY_H */ +int +optgroup_inotify_available (void) +{ + return 0; +} #endif /* Because inotify_init does NEED_ROOT, NEED_INOTIFY implies NEED_ROOT. */ @@ -106,8 +119,7 @@ do_inotify_init (int max_events) return 0; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } @@ -132,8 +144,7 @@ do_inotify_close (void) return 0; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } @@ -161,8 +172,7 @@ do_inotify_add_watch (const char *path, int mask) return r; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } @@ -179,8 +189,7 @@ do_inotify_rm_watch (int wd) return 0; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } @@ -294,8 +303,7 @@ do_inotify_read (void) free (ret); return NULL; #else - reply_with_error ("%s is not available", __func__); - return NULL; + NOT_AVAILABLE (NULL); #endif } @@ -371,7 +379,6 @@ do_inotify_files (void) unlink ("/tmp/inotify"); return NULL; #else - reply_with_error ("%s is not available", __func__); - return NULL; + NOT_AVAILABLE (NULL); #endif } diff --git a/daemon/lvm.c b/daemon/lvm.c index 3920e95b..564517c5 100644 --- a/daemon/lvm.c +++ b/daemon/lvm.c @@ -26,6 +26,14 @@ #include "daemon.h" #include "c-ctype.h" #include "actions.h" +#include "optgroups.h" + +int +optgroup_lvm2_available (void) +{ + int r = access ("/sbin/lvm", X_OK); + return r == 0; +} /* LVM actions. Keep an eye on liblvm, although at the time * of writing it hasn't progressed very far. diff --git a/daemon/mknod.c b/daemon/mknod.c index 6ff88efa..46a18392 100644 --- a/daemon/mknod.c +++ b/daemon/mknod.c @@ -29,6 +29,21 @@ #include "../src/guestfs_protocol.h" #include "daemon.h" #include "actions.h" +#include "optgroups.h" + +#ifdef HAVE_MKNOD +int +optgroup_mknod_available (void) +{ + return 1; +} +#else +int +optgroup_mknod_available (void) +{ + return 0; +} +#endif int do_mknod (int mode, int devmajor, int devminor, const char *path) @@ -47,8 +62,7 @@ do_mknod (int mode, int devmajor, int devminor, const char *path) return 0; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } diff --git a/daemon/modprobe.c b/daemon/modprobe.c index 7e3d1b70..ac62b349 100644 --- a/daemon/modprobe.c +++ b/daemon/modprobe.c @@ -23,6 +23,14 @@ #include "daemon.h" #include "actions.h" +#include "optgroups.h" + +int +optgroup_linuxmodules_available (void) +{ + int r = access ("/sbin/modprobe", X_OK); + return r == 0; +} int do_modprobe (const char *module) diff --git a/daemon/ntfs.c b/daemon/ntfs.c index 85deb654..b3530084 100644 --- a/daemon/ntfs.c +++ b/daemon/ntfs.c @@ -25,6 +25,14 @@ #include "daemon.h" #include "actions.h" +#include "optgroups.h" + +int +optgroup_ntfs3g_available (void) +{ + int r = access ("/bin/ntfs-3g.probe", X_OK); + return r == 0; +} int do_ntfs_3g_probe (int rw, const char *device) diff --git a/daemon/scrub.c b/daemon/scrub.c index 15c8b6c2..e37a1e11 100644 --- a/daemon/scrub.c +++ b/daemon/scrub.c @@ -26,6 +26,14 @@ #include "daemon.h" #include "actions.h" +#include "optgroups.h" + +int +optgroup_scrub_available (void) +{ + int r = access ("/usr/bin/scrub", X_OK); + return r == 0; +} int do_scrub_device (const char *device) diff --git a/daemon/selinux.c b/daemon/selinux.c index 3b4b9ba6..e49e657b 100644 --- a/daemon/selinux.c +++ b/daemon/selinux.c @@ -29,6 +29,21 @@ #include "../src/guestfs_protocol.h" #include "daemon.h" #include "actions.h" +#include "optgroups.h" + +#if defined(HAVE_LIBSELINUX) +int +optgroup_selinux_available (void) +{ + return 1; +} +#else /* !HAVE_LIBSELINUX */ +int +optgroup_selinux_available (void) +{ + return 0; +} +#endif /* !HAVE_LIBSELINUX */ /* setcon is only valid under the following circumstances: * - single threaded @@ -45,8 +60,7 @@ do_setcon (const char *context) return 0; #else - reply_with_error ("%s is not available", __func__); - return -1; + NOT_AVAILABLE (-1); #endif } @@ -71,7 +85,6 @@ do_getcon (void) return r; /* caller frees */ #else - reply_with_error ("%s is not available", __func__); - return NULL; + NOT_AVAILABLE (NULL); #endif } diff --git a/daemon/swap.c b/daemon/swap.c index bcc5f1b1..2d3d9ff4 100644 --- a/daemon/swap.c +++ b/daemon/swap.c @@ -26,6 +26,25 @@ #include "../src/guestfs_protocol.h" #include "daemon.h" #include "actions.h" +#include "optgroups.h" + +/* Convenient place to test for the later version of e2fsprogs + * and util-linux which supports -U parameters to specify UUIDs. + * (Not supported in RHEL 5). + */ +int +optgroup_linuxfsuuid_available (void) +{ + char *err; + int av; + + /* Ignore return code - mkswap --help *will* fail. */ + command (NULL, &err, "/sbin/mkswap", "--help", NULL); + + av = strstr (err, "-U") != NULL; + free (err); + return av; +} static int mkswap (const char *device, const char *flag, const char *value) diff --git a/daemon/xattr.c b/daemon/xattr.c index c218dea1..e58dc7ea 100644 --- a/daemon/xattr.c +++ b/daemon/xattr.c @@ -24,16 +24,23 @@ #include "../src/guestfs_protocol.h" #include "daemon.h" #include "actions.h" +#include "optgroups.h" #if defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_XATTR_H) -#ifdef HAVE_ATTR_XATTR_H -#include <attr/xattr.h> -#else -#ifdef HAVE_SYS_XATTR_H -#include <sys/xattr.h> -#endif -#endif +# ifdef HAVE_ATTR_XATTR_H +# include <attr/xattr.h> +# else +# ifdef HAVE_SYS_XATTR_H +# include <sys/xattr.h> +# endif +# endif + +int +optgroup_linuxxattrs_available (void) +{ + return 1; +} static guestfs_int_xattr_list *getxattrs (const char *path, ssize_t (*listxattr) (const char *path, char *list, size_t size), ssize_t (*getxattr) (const char *path, const char *name, void *value, size_t size)); static int _setxattr (const char *xattr, const char *val, int vallen, const char *path, int (*setxattr) (const char *path, const char *name, const void *value, size_t size, int flags)); @@ -442,54 +449,52 @@ do_lxattrlist (const char *path, char *const *names) } #else /* no xattr.h */ +int +optgroup_linuxxattrs_available (void) +{ + return 0; +} guestfs_int_xattr_list * do_getxattrs (const char *path) { - reply_with_error ("getxattrs: no support for xattrs"); - return NULL; + NOT_AVAILABLE (NULL); } guestfs_int_xattr_list * do_lgetxattrs (const char *path) { - reply_with_error ("lgetxattrs: no support for xattrs"); - return NULL; + NOT_AVAILABLE (NULL); } int do_setxattr (const char *xattr, const char *val, int vallen, const char *path) { - reply_with_error ("setxattr: no support for xattrs"); - return -1; + NOT_AVAILABLE (-1); } int do_lsetxattr (const char *xattr, const char *val, int vallen, const char *path) { - reply_with_error ("lsetxattr: no support for xattrs"); - return -1; + NOT_AVAILABLE (-1); } int do_removexattr (const char *xattr, const char *path) { - reply_with_error ("removexattr: no support for xattrs"); - return -1; + NOT_AVAILABLE (-1); } int do_lremovexattr (const char *xattr, const char *path) { - reply_with_error ("lremovexattr: no support for xattrs"); - return -1; + NOT_AVAILABLE (-1); } guestfs_int_xattr_list * do_lxattrlist (const char *path, char *const *names) { - reply_with_error ("lxattrlist: no support for xattrs"); - return NULL; + NOT_AVAILABLE (NULL); } #endif /* no xattr.h */ diff --git a/daemon/zerofree.c b/daemon/zerofree.c index ffb9b70b..05a547bd 100644 --- a/daemon/zerofree.c +++ b/daemon/zerofree.c @@ -26,6 +26,14 @@ #include "daemon.h" #include "actions.h" +#include "optgroups.h" + +int +optgroup_zerofree_available (void) +{ + int r = access ("/usr/sbin/zerofree", X_OK); + return r == 0; +} int do_zerofree (const char *device) |