summaryrefslogtreecommitdiffstats
path: root/daemon
diff options
context:
space:
mode:
Diffstat (limited to 'daemon')
-rw-r--r--daemon/Makefile.am2
-rw-r--r--daemon/augeas.c52
-rw-r--r--daemon/available.c23
-rw-r--r--daemon/configure.ac24
-rw-r--r--daemon/daemon.h17
-rw-r--r--daemon/inotify.c31
-rw-r--r--daemon/lvm.c8
-rw-r--r--daemon/mknod.c18
-rw-r--r--daemon/modprobe.c8
-rw-r--r--daemon/ntfs.c8
-rw-r--r--daemon/scrub.c8
-rw-r--r--daemon/selinux.c21
-rw-r--r--daemon/swap.c19
-rw-r--r--daemon/xattr.c47
-rw-r--r--daemon/zerofree.c8
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)