launch: direct: Calculate appliance root correctly when iface drives are added (RHBZ#975797).

This also changes guestfs___appliance_command_line to allow
appliance_dev parameter to be NULL.  Previously a bogus root=
parameter could be passed.
This commit is contained in:
Richard W.M. Jones
2013-06-19 14:40:51 +01:00
parent e7f83f2ecc
commit f7fe7e8db0
2 changed files with 43 additions and 6 deletions

View File

@@ -76,6 +76,7 @@ free_regexps (void)
}
static int is_openable (guestfs_h *g, const char *path, int flags);
static char *make_appliance_dev (guestfs_h *g, int virtio_scsi);
static void print_qemu_command_line (guestfs_h *g, char **argv);
static int qemu_supports (guestfs_h *g, const char *option);
static int qemu_supports_device (guestfs_h *g, const char *device_name);
@@ -175,6 +176,7 @@ launch_direct (guestfs_h *g, const char *arg)
struct sockaddr_un addr;
CLEANUP_FREE char *kernel = NULL, *initrd = NULL, *appliance = NULL;
int has_appliance_drive;
CLEANUP_FREE char *appliance_dev = NULL;
uint32_t size;
CLEANUP_FREE void *buf = NULL;
@@ -313,8 +315,6 @@ launch_direct (guestfs_h *g, const char *arg)
}
}
char appliance_dev[64] = "/dev/Xd";
/* Add the ext2 appliance drive (after all the drives). */
if (has_appliance_drive) {
const char *cachemode = "";
@@ -337,8 +337,7 @@ launch_direct (guestfs_h *g, const char *arg)
add_cmdline (g, "scsi-hd,drive=appliance");
}
appliance_dev[5] = virtio_scsi ? 's' : 'v';
guestfs___drive_name (g->nr_drives, &appliance_dev[7]);
appliance_dev = make_appliance_dev (g, virtio_scsi);
}
/* The qemu -machine option (added 2010-12) is a bit more sane
@@ -696,6 +695,40 @@ launch_direct (guestfs_h *g, const char *arg)
return -1;
}
/* Calculate the appliance device name.
*
* The easy thing would be to use g->nr_drives (indeed, that's what we
* used to do). However this breaks if some of the drives being added
* use the deprecated 'iface' parameter. To further add confusion,
* the format of the 'iface' parameter has never been defined, but
* given existing usage we can assume it has one of only three values:
* NULL, "ide" or "virtio" (which means virtio-blk). See RHBZ#975797.
*/
static char *
make_appliance_dev (guestfs_h *g, int virtio_scsi)
{
size_t i, index = 0;
struct drive *drv;
char dev[64] = "/dev/Xd";
/* Calculate the index of the drive. */
ITER_DRIVES (g, i, drv) {
if (virtio_scsi) {
if (drv->iface == NULL || STREQ (drv->iface, "ide"))
index++;
}
else /* virtio-blk */ {
if (drv->iface == NULL || STRNEQ (drv->iface, "virtio"))
index++;
}
}
dev[5] = virtio_scsi ? 's' : 'v';
guestfs___drive_name (index, &dev[7]);
return safe_strdup (g, dev); /* Caller frees. */
}
/* This is called from the forked subprocess just before qemu runs, so
* it can just print the message straight to stderr, where it will be
* picked up and funnelled through the usual appliance event API.

View File

@@ -302,11 +302,15 @@ char *
guestfs___appliance_command_line (guestfs_h *g, const char *appliance_dev,
int flags)
{
char root[64] = "";
char *term = getenv ("TERM");
char *ret;
bool tcg = flags & APPLIANCE_COMMAND_LINE_IS_TCG;
char lpj_s[64] = "";
if (appliance_dev)
snprintf (root, sizeof root, " root=%s", appliance_dev);
if (tcg) {
int lpj = guestfs___get_lpj (g);
if (lpj > 0)
@@ -326,13 +330,13 @@ guestfs___appliance_command_line (guestfs_h *g, const char *appliance_dev,
" acpi=off" /* we don't need ACPI, turn it off */
" printk.time=1" /* display timestamp before kernel messages */
" cgroup_disable=memory" /* saves us about 5 MB of RAM */
" root=%s" /* root (appliance_dev) */
"%s" /* root=appliance_dev */
" %s" /* selinux */
"%s" /* verbose */
" TERM=%s" /* TERM environment variable */
"%s%s", /* append */
lpj_s,
appliance_dev,
root,
g->selinux ? "selinux=1 enforcing=0" : "selinux=0",
g->verbose ? " guestfs_verbose=1" : "",
term ? term : "linux",