From 7281155810d678e0850e9436067f41fa681e8080 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 18 May 2011 22:19:40 +0300 Subject: [PATCH] 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 Suggested-by: Ingo Molnar Signed-off-by: Pekka Enberg --- kvm.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/kvm.c b/kvm.c index 815cacf..4393a41 100644 --- a/kvm.c +++ b/kvm.c @@ -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 @@ -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);