kvm tools: Fail if passed initrd is not really an initrd

We recently changed the meaning of "-i" from disk image to initrd. This has
confused many users because kvm just reports:

  Fatal: mmap() failed.

if a disk image is passed as initrd. This patch fixes that by checking for the
first two ID bytes in initrd:

  $ ./kvm run -i ~/images/linux-0.2.qcow
    # kvm run -k ../../arch/x86/boot/bzImage -m 256 -c 1
    Fatal: /home/penberg/images/linux-0.2.qcow is not an initrd

Reported-by: Thomas Heil <heil@terminal-consulting.de>
Suggested-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
This commit is contained in:
Pekka Enberg
2015-06-01 16:39:44 +01:00
committed by Will Deacon
parent 328a03bc3f
commit 7281155810
+24 -3
View File
@@ -1,10 +1,11 @@
#include "kvm/kvm.h"
#include "kvm/cpufeature.h"
#include "kvm/interrupt.h"
#include "kvm/boot-protocol.h"
#include "kvm/util.h"
#include "kvm/cpufeature.h"
#include "kvm/read-write.h"
#include "kvm/interrupt.h"
#include "kvm/mptable.h"
#include "kvm/util.h"
#include <linux/kvm.h>
@@ -422,6 +423,23 @@ static bool load_bzimage(struct kvm *kvm, int fd_kernel,
return true;
}
/* RFC 1952 */
#define GZIP_ID1 0x1f
#define GZIP_ID2 0x8b
static bool initrd_check(int fd)
{
unsigned char id[2];
if (read_in_full(fd, id, ARRAY_SIZE(id)) < 0)
return false;
if (lseek(fd, 0, SEEK_SET) < 0)
die_perror("lseek");
return id[0] == GZIP_ID1 && id[1] == GZIP_ID2;
}
bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
const char *initrd_filename, const char *kernel_cmdline)
{
@@ -436,6 +454,9 @@ bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
fd_initrd = open(initrd_filename, O_RDONLY);
if (fd_initrd < 0)
die("Unable to open initrd %s", initrd_filename);
if (!initrd_check(fd_initrd))
die("%s is not an initrd", initrd_filename);
}
ret = load_bzimage(kvm, fd_kernel, fd_initrd, kernel_cmdline);