summaryrefslogtreecommitdiffstats
path: root/daemon
diff options
context:
space:
mode:
Diffstat (limited to 'daemon')
-rw-r--r--daemon/Makefile.am1
-rw-r--r--daemon/actions.h2
-rw-r--r--daemon/initrd.c88
-rw-r--r--daemon/mount.c45
-rw-r--r--daemon/stubs.c60
5 files changed, 196 insertions, 0 deletions
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 2884e936..88c382cf 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -43,6 +43,7 @@ guestfsd_SOURCES = \
guestfsd.c \
headtail.c \
hexdump.c \
+ initrd.c \
ls.c \
lvm.c \
mount.c \
diff --git a/daemon/actions.h b/daemon/actions.h
index 7d87b677..1d412dcc 100644
--- a/daemon/actions.h
+++ b/daemon/actions.h
@@ -148,3 +148,5 @@ extern char **do_tail_n (int nrlines, char *path);
extern char *do_df (void);
extern char *do_df_h (void);
extern int64_t do_du (char *path);
+extern char **do_initrd_list (char *path);
+extern int do_mount_loop (char *file, char *mountpoint);
diff --git a/daemon/initrd.c b/daemon/initrd.c
new file mode 100644
index 00000000..513ed8da
--- /dev/null
+++ b/daemon/initrd.c
@@ -0,0 +1,88 @@
+/* libguestfs - the guestfsd daemon
+ * Copyright (C) 2009 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 "../src/guestfs_protocol.h"
+#include "daemon.h"
+#include "actions.h"
+
+char **
+do_initrd_list (char *path)
+{
+ FILE *fp;
+ int len;
+ char *cmd;
+ char filename[PATH_MAX];
+ char **filenames = NULL;
+ int size = 0, alloc = 0;
+
+ NEED_ROOT (NULL);
+ ABS_PATH (path, NULL);
+
+ /* "zcat /sysroot/<path> | cpio --quiet -it", but path must be quoted. */
+ len = 64 + 2 * strlen (path);
+ cmd = malloc (len);
+ if (!cmd) {
+ reply_with_perror ("malloc");
+ return NULL;
+ }
+
+ strcpy (cmd, "zcat /sysroot");
+ shell_quote (cmd+13, len-13, path);
+ strcat (cmd, " | cpio --quiet -it");
+
+ fprintf (stderr, "%s\n", cmd);
+
+ fp = popen (cmd, "r");
+ if (fp == NULL) {
+ reply_with_perror ("popen: %s", cmd);
+ free (cmd);
+ return NULL;
+ }
+ free (cmd);
+
+ while (fgets (filename, sizeof filename, fp) != NULL) {
+ len = strlen (filename);
+ if (len > 0 && filename[len-1] == '\n')
+ filename[len-1] = '\0';
+
+ if (add_string (&filenames, &size, &alloc, filename) == -1) {
+ pclose (fp);
+ return NULL;
+ }
+ }
+
+ if (add_string (&filenames, &size, &alloc, NULL) == -1) {
+ pclose (fp);
+ return NULL;
+ }
+
+ if (pclose (fp) == -1) {
+ reply_with_perror ("pclose");
+ free_strings (filenames);
+ return NULL;
+ }
+
+ return filenames;
+}
diff --git a/daemon/mount.c b/daemon/mount.c
index 4955fcf3..b0cb496e 100644
--- a/daemon/mount.c
+++ b/daemon/mount.c
@@ -71,6 +71,7 @@ do_mount_vfs (char *options, char *vfstype,
else
r = command (NULL, &error,
"mount", "-o", options, device, mp, NULL);
+ free (mp);
if (r == -1) {
reply_with_error ("mount: %s on %s: %s", device, mountpoint, error);
free (error);
@@ -277,3 +278,47 @@ do_umount_all (void)
return 0;
}
+
+/* Mount using the loopback device. You can't use the generic
+ * do_mount call for this because the first parameter isn't a
+ * device.
+ */
+int
+do_mount_loop (char *file, char *mountpoint)
+{
+ int len, r;
+ char *buf, *mp;
+ char *error;
+
+ NEED_ROOT (-1);
+ ABS_PATH (file, -1);
+
+ /* We have to prefix /sysroot on both the filename and the mountpoint. */
+ len = strlen (mountpoint) + 9;
+ mp = malloc (len);
+ if (!mp) {
+ reply_with_perror ("malloc");
+ return -1;
+ }
+ snprintf (mp, len, "/sysroot%s", mountpoint);
+
+ len = strlen (file) + 9;
+ buf = malloc (len);
+ if (!file) {
+ reply_with_perror ("malloc");
+ free (mp);
+ return -1;
+ }
+ snprintf (buf, len, "/sysroot%s", file);
+
+ r = command (NULL, &error, "mount", "-o", "loop", buf, mp, NULL);
+ free (mp);
+ free (buf);
+ if (r == -1) {
+ reply_with_error ("mount: %s on %s: %s", file, mountpoint, error);
+ free (error);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/daemon/stubs.c b/daemon/stubs.c
index 67e6ef5b..6d7cb0e7 100644
--- a/daemon/stubs.c
+++ b/daemon/stubs.c
@@ -3205,6 +3205,60 @@ done:
xdr_free ((xdrproc_t) xdr_guestfs_du_args, (char *) &args);
}
+static void initrd_list_stub (XDR *xdr_in)
+{
+ char **r;
+ struct guestfs_initrd_list_args args;
+ char *path;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_initrd_list_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "initrd_list");
+ return;
+ }
+ path = args.path;
+
+ r = do_initrd_list (path);
+ if (r == NULL)
+ /* do_initrd_list has already called reply_with_error */
+ goto done;
+
+ struct guestfs_initrd_list_ret ret;
+ ret.filenames.filenames_len = count_strings (r);
+ ret.filenames.filenames_val = r;
+ reply ((xdrproc_t) &xdr_guestfs_initrd_list_ret, (char *) &ret);
+ free_strings (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_initrd_list_args, (char *) &args);
+}
+
+static void mount_loop_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_mount_loop_args args;
+ char *file;
+ char *mountpoint;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_mount_loop_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "mount_loop");
+ return;
+ }
+ file = args.file;
+ mountpoint = args.mountpoint;
+
+ r = do_mount_loop (file, mountpoint);
+ if (r == -1)
+ /* do_mount_loop has already called reply_with_error */
+ goto done;
+
+ reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_mount_loop_args, (char *) &args);
+}
+
void dispatch_incoming_message (XDR *xdr_in)
{
switch (proc_nr) {
@@ -3589,6 +3643,12 @@ void dispatch_incoming_message (XDR *xdr_in)
case GUESTFS_PROC_DU:
du_stub (xdr_in);
break;
+ case GUESTFS_PROC_INITRD_LIST:
+ initrd_list_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_MOUNT_LOOP:
+ mount_loop_stub (xdr_in);
+ break;
default:
reply_with_error ("dispatch_incoming_message: unknown procedure number %d, set LIBGUESTFS_PATH to point to the matching libguestfs appliance directory", proc_nr);
}