Currently /sysroot is hard-coded throughout the daemon code.
This patch turns the path into a variable so that we can change
it in future, for example to allow standalone mode to be implemented.
This patch was tested by running all the C API tests successfully.
{
#ifdef HAVE_AUGEAS
char *buf;
- int len;
NEED_ROOT (-1);
ABS_PATH (root, -1);
aug = NULL;
}
- len = strlen (root) + 9;
- buf = malloc (len);
+ buf = sysroot_path (root);
if (!buf) {
reply_with_perror ("malloc");
return -1;
}
- snprintf (buf, len, "/sysroot%s", root);
aug = aug_init (buf, NULL, flags);
free (buf);
const char *program;
char *buf;
char *out, *err;
- int r, len;
+ int r;
+ int len;
NEED_ROOT (NULL);
ABS_PATH (path, NULL);
}
/* Make the path relative to /sysroot. */
- len = strlen (path) + 9;
- buf = malloc (len);
+ buf = sysroot_path (path);
if (!buf) {
reply_with_perror ("malloc");
return NULL;
}
- snprintf (buf, len, "/sysroot%s", path);
r = command (&out, &err, program, buf, NULL);
free (buf);
do_equal (char *file1, char *file2)
{
char *file1buf, *file2buf;
- int file1len, file2len;
char *err;
int r;
ABS_PATH (file1, -1);
ABS_PATH (file2, -1);
- file1len = strlen (file1) + 32;
- file1buf = malloc (file1len);
+ file1buf = sysroot_path (file1);
if (file1buf == NULL) {
reply_with_perror ("malloc");
return -1;
}
- file2len = strlen (file2) + 32;
- file2buf = malloc (file2len);
+ file2buf = sysroot_path (file2);
if (file2buf == NULL) {
reply_with_perror ("malloc");
free (file1buf);
return -1;
}
- snprintf (file1buf, file1len, "/sysroot%s", file1);
- snprintf (file2buf, file2len, "/sysroot%s", file2);
-
r = commandr (NULL, &err, "cmp", "-s", file1buf, file2buf, NULL);
free (file1buf);
{
char *out, *err;
int r;
+ char *sysroot_proc, *sysroot_dev, *sysroot_dev_pts, *sysroot_sys;
int proc_ok, dev_ok, dev_pts_ok, sys_ok;
/* We need a root filesystem mounted to do this. */
* We deliberately allow these commands to fail silently, BUT
* if a mount fails, don't unmount the corresponding mount.
*/
- r = command (NULL, NULL, "mount", "--bind", "/dev", "/sysroot/dev", NULL);
+ sysroot_dev = sysroot_path ("/dev");
+ sysroot_dev_pts = sysroot_path ("/dev/pts");
+ sysroot_proc = sysroot_path ("/proc");
+ sysroot_sys = sysroot_path ("/sys");
+
+ r = command (NULL, NULL, "mount", "--bind", "/dev", sysroot_dev, NULL);
dev_ok = r != -1;
- r = command (NULL, NULL, "mount", "--bind", "/dev/pts", "/sysroot/dev/pts", NULL);
+ r = command (NULL, NULL, "mount", "--bind", "/dev/pts", sysroot_dev_pts, NULL);
dev_pts_ok = r != -1;
- r = command (NULL, NULL, "mount", "--bind", "/proc", "/sysroot/proc", NULL);
+ r = command (NULL, NULL, "mount", "--bind", "/proc", sysroot_proc, NULL);
proc_ok = r != -1;
- r = command (NULL, NULL, "mount", "--bind", "/sys", "/sysroot/sys", NULL);
+ r = command (NULL, NULL, "mount", "--bind", "/sys", sysroot_sys, NULL);
sys_ok = r != -1;
CHROOT_IN;
r = commandv (&out, &err, argv);
CHROOT_OUT;
- if (sys_ok) command (NULL, NULL, "umount", "/sysroot/sys", NULL);
- if (proc_ok) command (NULL, NULL, "umount", "/sysroot/proc", NULL);
- if (dev_pts_ok) command (NULL, NULL, "umount", "/sysroot/dev/pts", NULL);
- if (dev_ok) command (NULL, NULL, "umount", "/sysroot/dev", NULL);
+ if (sys_ok) command (NULL, NULL, "umount", sysroot_sys, NULL);
+ if (proc_ok) command (NULL, NULL, "umount", sysroot_proc, NULL);
+ if (dev_pts_ok) command (NULL, NULL, "umount", sysroot_dev_pts, NULL);
+ if (dev_ok) command (NULL, NULL, "umount", sysroot_dev, NULL);
+
+ free (sysroot_dev);
+ free (sysroot_dev_pts);
+ free (sysroot_proc);
+ free (sysroot_sys);
if (r == -1) {
reply_with_error ("%s", err);
cpmv_cmd (const char *cmd, const char *flags, const char *src, const char *dest)
{
char *srcbuf, *destbuf;
- int srclen, destlen;
char *err;
int r;
ABS_PATH (src, -1);
ABS_PATH (dest, -1);
- srclen = strlen (src) + 32;
- srcbuf = malloc (srclen);
+ srcbuf = sysroot_path (src);
if (srcbuf == NULL) {
reply_with_perror ("malloc");
return -1;
}
- destlen = strlen (dest) + 32;
- destbuf = malloc (destlen);
+ destbuf = sysroot_path (dest);
if (destbuf == NULL) {
reply_with_perror ("malloc");
free (srcbuf);
return -1;
}
- snprintf (srcbuf, srclen, "/sysroot%s", src);
- snprintf (destbuf, destlen, "/sysroot%s", dest);
-
if (flags)
r = command (NULL, &err, cmd, flags, srcbuf, destbuf, NULL);
else
#include "../src/guestfs_protocol.h"
/*-- in guestfsd.c --*/
+extern int verbose;
+
+extern const char *sysroot;
+extern int sysroot_len;
+
+extern char *sysroot_path (const char *path);
+
extern int xwrite (int sock, const void *buf, size_t len);
extern int xread (int sock, void *buf, size_t len);
extern void udev_settle (void);
-extern int verbose;
-
/*-- in names.c (auto-generated) --*/
extern const char *function_names[];
#define CHROOT_IN \
do { \
int __old_errno = errno; \
- if (chroot ("/sysroot") == -1) \
+ if (chroot (sysroot) == -1) \
perror ("CHROOT_IN: sysroot"); \
errno = __old_errno; \
} while (0)
int
do_rm_rf (char *path)
{
- int r, len;
+ int r;
char *buf, *err;
NEED_ROOT (-1);
return -1;
}
- len = strlen (path) + 9;
- buf = malloc (len);
+ buf = sysroot_path (path);
if (buf == NULL) {
reply_with_perror ("malloc");
return -1;
}
- snprintf (buf, len, "/sysroot%s", path);
-
r = command (NULL, &err, "rm", "-rf", buf, NULL);
free (buf);
int64_t rv;
char *out, *err;
char *buf;
- int len;
NEED_ROOT (-1);
ABS_PATH (path, -1);
/* Make the path relative to /sysroot. */
- len = strlen (path) + 9;
- buf = malloc (len);
+ buf = sysroot_path (path);
if (!buf) {
reply_with_perror ("malloc");
return -1;
}
- snprintf (buf, len, "/sysroot%s", path);
r = command (&out, &err, "du", "-s", buf, NULL);
free (buf);
do_file (char *path)
{
char *out, *err;
- int r, len, freeit = 0;
+ int r, freeit = 0;
char *buf;
+ int len;
NEED_ROOT_OR_IS_DEVICE (path, NULL);
ABS_PATH (path, NULL);
if (strncmp (path, "/dev/", 5) == 0)
buf = (char *) path;
else {
- len = strlen (path) + 9;
- buf = malloc (len);
+ buf = sysroot_path (path);
if (!buf) {
reply_with_perror ("malloc");
return NULL;
}
- snprintf (buf, len, "/sysroot%s", path);
freeit = 1;
}
NEED_ROOT (NULL);
ABS_PATH (path, NULL);
- len = 2 * strlen (path) + 64;
+ len = 2 * strlen (path) + sysroot_len + 64;
cmd = malloc (len);
if (!cmd) {
reply_with_perror ("malloc");
return NULL;
}
- strcat (cmd, " /sysroot");
+ strcat (cmd, " ");
+ strcat (cmd, sysroot);
shell_quote (cmd + strlen (cmd), len - strlen (cmd), path);
strcat (cmd, " | file -bsL -");
FILE *fp;
char **res = NULL;
int size = 0, alloc = 0;
- char sysrootdir[PATH_MAX];
+ char *sysrootdir;
char str[PATH_MAX];
NEED_ROOT (NULL);
ABS_PATH (dir, NULL);
- snprintf (sysrootdir, sizeof sysrootdir, "/sysroot%s", dir);
+ sysrootdir = sysroot_path (dir);
+ if (!sysrootdir) {
+ reply_with_perror ("malloc");
+ return NULL;
+ }
r = stat (sysrootdir, &statbuf);
if (r == -1) {
reply_with_perror ("%s", dir);
+ free (sysrootdir);
return NULL;
}
if (!S_ISDIR (statbuf.st_mode)) {
reply_with_error ("%s: not a directory", dir);
+ free (sysrootdir);
return NULL;
}
cmd = malloc (len);
if (!cmd) {
reply_with_perror ("malloc");
+ free (sysrootdir);
return NULL;
}
strcpy (cmd, "find ");
shell_quote (cmd+5, len-5, sysrootdir);
+ free (sysrootdir);
strcat (cmd, " -print0");
if (verbose)
ABS_PATH (root, -1);
IS_DEVICE (device, -1);
- len = strlen (root) + 64;
+ len = strlen (root) + sysroot_len + 64;
buf = malloc (len);
if (!buf) {
reply_with_perror ("malloc");
return -1;
}
- snprintf (buf, len, "--root-directory=/sysroot%s", root);
+ snprintf (buf, len, "--root-directory=%s%s", sysroot, root);
r = command (NULL, &err, "/sbin/grub-install", buf, device, NULL);
free (buf);
int verbose = 0;
+/* Location to mount root device. */
+const char *sysroot = "/sysroot"; /* No trailing slash. */
+int sysroot_len = 8;
+
int
main (int argc, char *argv[])
{
exit (0);
}
+/* Turn "/path" into "/sysroot/path".
+ *
+ * Caller must check for NULL and call reply_with_perror ("malloc")
+ * if it is. Caller must also free the string.
+ */
+char *
+sysroot_path (const char *path)
+{
+ char *r;
+ int len = strlen (path) + sysroot_len + 1;
+
+ r = malloc (len);
+ if (r == NULL)
+ return NULL;
+
+ snprintf (r, len, "%s%s", sysroot, path);
+ return r;
+}
+
int
xwrite (int sock, const void *buf, size_t len)
{
{
char *buf;
char *out, *err;
- int r, len;
+ int r;
char **lines;
NEED_ROOT (NULL);
ABS_PATH (path, NULL);
/* Make the path relative to /sysroot. */
- len = strlen (path) + 9;
- buf = malloc (len);
+ buf = sysroot_path (path);
if (!buf) {
reply_with_perror ("malloc");
return NULL;
}
- snprintf (buf, len, "/sysroot%s", path);
r = command (&out, &err, prog, flag, n, buf, NULL);
free (buf);
char *
do_hexdump (char *path)
{
- int len;
char *buf;
int r;
char *out, *err;
NEED_ROOT (NULL);
ABS_PATH (path, NULL);
- len = strlen (path) + 9;
- buf = malloc (len);
+ buf = sysroot_path (path);
if (!buf) {
reply_with_perror ("malloc");
return NULL;
}
- snprintf (buf, len, "/sysroot%s", path);
-
r = command (&out, &err, "hexdump", "-C", buf, NULL);
free (buf);
if (r == -1) {
ABS_PATH (path, NULL);
/* "zcat /sysroot/<path> | cpio --quiet -it", but path must be quoted. */
- len = 64 + 2 * strlen (path);
+ len = 64 + sysroot_len + 2 * strlen (path);
cmd = malloc (len);
if (!cmd) {
reply_with_perror ("malloc");
return NULL;
}
- strcpy (cmd, "zcat /sysroot");
+ strcpy (cmd, "zcat ");
+ strcat (cmd, sysroot);
shell_quote (cmd+13, len-13, path);
strcat (cmd, " | cpio --quiet -it");
char *
do_ll (char *path)
{
- int r, len;
+ int r;
char *out, *err;
char *spath;
* interactive sessions. For the same reason, you can also "escape"
* the sysroot (eg. 'll /..').
*/
- len = strlen (path) + 9;
- spath = malloc (len);
+ spath = sysroot_path (path);
if (!spath) {
reply_with_perror ("malloc");
return NULL;
}
- snprintf (spath, len, "/sysroot%s", path);
r = command (&out, &err, "ls", "-la", spath, NULL);
free (spath);
do_mount_vfs (char *options, char *vfstype,
char *device, char *mountpoint)
{
- int len, r, is_root;
+ int r, is_root;
char *mp;
char *error;
return -1;
}
- len = strlen (mountpoint) + 9;
-
- mp = malloc (len);
+ mp = sysroot_path (mountpoint);
if (!mp) {
reply_with_perror ("malloc");
return -1;
}
- snprintf (mp, len, "/sysroot%s", mountpoint);
-
if (vfstype)
r = command (NULL, &error,
"mount", "-o", options, "-t", vfstype, device, mp, NULL);
int
do_umount (char *pathordevice)
{
- int len, freeit = 0, r;
+ int freeit = 0, r;
char *buf;
char *err;
buf = pathordevice;
IS_DEVICE (buf, -1);
} else {
- len = strlen (pathordevice) + 9;
- freeit = 1;
- buf = malloc (len);
+ buf = sysroot_path (pathordevice);
if (buf == NULL) {
reply_with_perror ("malloc");
return -1;
}
- snprintf (buf, len, "/sysroot%s", pathordevice);
+ freeit = 1;
}
r = command (NULL, &err, "umount", buf, NULL);
int size = 0, alloc = 0;
char *p, *pend, *p2;
int len;
+ char matching[5 + sysroot_len];
r = command (&out, &err, "mount", NULL);
if (r == -1) {
free (err);
+ /* Lines have the format:
+ * /dev/foo on /mountpoint type ...
+ */
+ snprintf (matching, 5 + sysroot_len, " on %s", sysroot);
+
p = out;
while (p) {
pend = strchr (p, '\n');
pend++;
}
- /* Lines have the format:
- * /dev/foo on /mountpoint type ...
- */
- p2 = strstr (p, " on /sysroot");
+ p2 = strstr (p, matching);
if (p2 != NULL) {
*p2 = '\0';
if (add_string (&ret, &size, &alloc, p) == -1) {
return NULL;
}
if (mp) {
- p2 += 12; /* skip " on /sysroot" */
+ p2 += 4 + sysroot_len; /* skip " on /sysroot" */
len = strcspn (p2, " ");
if (len == 0) /* .. just /sysroot, so we turn it into "/" */
char **mounts = NULL;
int size = 0, alloc = 0;
char *p, *p2, *p3, *pend;
+ char matching[5 + sysroot_len];
r = command (&out, &err, "mount", NULL);
if (r == -1) {
free (err);
+ /* Lines have the format:
+ * /dev/foo on /mountpoint type ...
+ */
+ snprintf (matching, 5 + sysroot_len, " on %s", sysroot);
+
p = out;
while (p) {
pend = strchr (p, '\n');
pend++;
}
- /* Lines have the format:
- * /dev/foo on /mountpoint type ...
- */
- p2 = strstr (p, " on /sysroot");
+ p2 = strstr (p, matching);
if (p2 != NULL) {
p2 += 4;
p3 = p2 + strcspn (p2, " ");
int
do_mount_loop (char *file, char *mountpoint)
{
- int len, r;
+ int r;
char *buf, *mp;
char *error;
ABS_PATH (file, -1);
/* We have to prefix /sysroot on both the filename and the mountpoint. */
- len = strlen (mountpoint) + 9;
- mp = malloc (len);
+ mp = sysroot_path (mountpoint);
if (!mp) {
reply_with_perror ("malloc");
return -1;
}
- snprintf (mp, len, "/sysroot%s", mountpoint);
- len = strlen (file) + 9;
- buf = malloc (len);
+ buf = sysroot_path (file);
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);
do_scrub_file (char *file)
{
char *buf;
- int len;
char *err;
int r;
ABS_PATH (file, -1);
/* Make the path relative to /sysroot. */
- len = strlen (file) + 9;
- buf = malloc (len);
+ buf = sysroot_path (file);
if (!buf) {
reply_with_perror ("malloc");
return -1;
}
- snprintf (buf, len, "/sysroot%s", file);
r = command (NULL, &err, "scrub", "-r", buf, NULL);
free (buf);
do_scrub_freespace (char *dir)
{
char *buf;
- int len;
char *err;
int r;
ABS_PATH (dir, -1);
/* Make the path relative to /sysroot. */
- len = strlen (dir) + 9;
- buf = malloc (len);
+ buf = sysroot_path (dir);
if (!buf) {
reply_with_perror ("malloc");
return -1;
}
- snprintf (buf, len, "/sysroot%s", dir);
r = command (NULL, &err, "scrub", "-X", buf, NULL);
free (buf);
char **
do_strings_e (char *encoding, char *path)
{
- int len;
char *buf;
int r;
char *out, *err;
NEED_ROOT (NULL);
ABS_PATH (path, NULL);
- len = strlen (path) + 9;
- buf = malloc (len);
+ buf = sysroot_path (path);
if (!buf) {
reply_with_perror ("malloc");
return NULL;
}
- snprintf (buf, len, "/sysroot%s", path);
-
r = command (&out, &err, "strings", "-e", encoding, buf, NULL);
free (buf);
if (r == -1) {
}
/* "tar -C /sysroot%s -xf -" but we have to quote the dir. */
- len = 2 * strlen (dir) + 32;
+ len = 2 * strlen (dir) + sysroot_len + 32;
cmd = malloc (len);
if (!cmd) {
err = errno;
reply_with_perror ("malloc");
return -1;
}
- strcpy (cmd, "tar -C /sysroot");
+ strcpy (cmd, "tar -C ");
+ strcat (cmd, sysroot);
shell_quote (cmd+15, len-15, dir);
strcat (cmd, " -xf -");
ABS_PATH (dir, -1);
/* "tar -C /sysroot%s -cf - ." but we have to quote the dir. */
- len = 2 * strlen (dir) + 32;
+ len = 2 * strlen (dir) + sysroot_len + 32;
cmd = malloc (len);
if (!cmd) {
reply_with_perror ("malloc");
return -1;
}
- strcpy (cmd, "tar -C /sysroot");
+ strcpy (cmd, "tar -C ");
+ strcat (cmd, sysroot);
shell_quote (cmd+15, len-15, dir);
strcat (cmd, " -cf - .");
}
/* "tar -C /sysroot%s -zxf -" but we have to quote the dir. */
- len = 2 * strlen (dir) + 32;
+ len = 2 * strlen (dir) + sysroot_len + 32;
cmd = malloc (len);
if (!cmd) {
err = errno;
reply_with_perror ("malloc");
return -1;
}
- strcpy (cmd, "tar -C /sysroot");
+ strcpy (cmd, "tar -C ");
+ strcat (cmd, sysroot);
shell_quote (cmd+15, len-15, dir);
strcat (cmd, " -zxf -");
ABS_PATH (dir, -1);
/* "tar -C /sysroot%s -zcf - ." but we have to quote the dir. */
- len = 2 * strlen (dir) + 32;
+ len = 2 * strlen (dir) + sysroot_len + 32;
cmd = malloc (len);
if (!cmd) {
reply_with_perror ("malloc");
return -1;
}
- strcpy (cmd, "tar -C /sysroot");
+ strcpy (cmd, "tar -C ");
+ strcat (cmd, sysroot);
shell_quote (cmd+15, len-15, dir);
strcat (cmd, " -zcf - .");
{
char *buf;
char *out, *err;
- int r, len;
+ int r;
NEED_ROOT (-1);
ABS_PATH (path, -1);
/* Make the path relative to /sysroot. */
- len = strlen (path) + 9;
- buf = malloc (len);
+ buf = sysroot_path (path);
if (!buf) {
reply_with_perror ("malloc");
return -1;
}
- snprintf (buf, len, "/sysroot%s", path);
r = command (&out, &err, "wc", flag, buf, NULL);
free (buf);