mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
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:
@@ -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.
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user