From 9297809d5e80e550298bb8c8aeb478b30cf7e0c5 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 5 Jan 2011 19:54:48 +0200 Subject: [PATCH] kvm: Add support for disk images This patch implements "--image" command line option that can be used to specify a disk image. It supports raw images and it needs to be integrated to the hypervisor block layer. Signed-off-by: Pekka Enberg --- tools/kvm/Makefile | 1 + tools/kvm/disk-image.c | 69 ++++++++++++++++++++++++++++++ tools/kvm/include/kvm/disk-image.h | 16 +++++++ tools/kvm/include/kvm/kvm.h | 1 + tools/kvm/main.c | 13 +++++- 5 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 tools/kvm/disk-image.c create mode 100644 tools/kvm/include/kvm/disk-image.h diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile index 4f0b26199bcb..9d6564c82455 100644 --- a/tools/kvm/Makefile +++ b/tools/kvm/Makefile @@ -11,6 +11,7 @@ PROGRAM = kvm OBJS += blk-virtio.o OBJS += cpuid.o +OBJS += disk-image.o OBJS += early_printk.o OBJS += interrupt.o OBJS += ioport.o diff --git a/tools/kvm/disk-image.c b/tools/kvm/disk-image.c new file mode 100644 index 000000000000..92aa83f68ce5 --- /dev/null +++ b/tools/kvm/disk-image.c @@ -0,0 +1,69 @@ +#include "kvm/disk-image.h" + +#include "kvm/util.h" + +#include +#include +#include +#include +#include +#include +#include + +#define SECTOR_SHIFT 9 +#define SECTOR_SIZE (1UL << SECTOR_SHIFT) + +struct disk_image *disk_image__open(const char *filename) +{ + struct disk_image *self; + struct stat st; + + self = malloc(sizeof *self); + if (!self) + return NULL; + + self->fd = open(filename, O_RDONLY); + if (self->fd < 0) + goto failed_free; + + if (fstat(self->fd, &st) < 0) + goto failed_close_fd; + + self->size = st.st_size; + + self->mmap = mmap(NULL, self->size, PROT_READ, MAP_PRIVATE, self->fd, 0); + if (self->mmap == MAP_FAILED) + goto failed_close_fd; + + return self; + +failed_close_fd: + close(self->fd); +failed_free: + free(self); + + return NULL; +} + +void disk_image__close(struct disk_image *self) +{ + if (munmap(self->mmap, self->size) < 0) + warning("munmap() failed"); + + if (close(self->fd) < 0) + warning("close() failed"); + + free(self); +} + +int disk_image__read_sector(struct disk_image *self, uint64_t sector, void *dst) +{ + uint64_t offset = sector << SECTOR_SHIFT; + + if (offset + SECTOR_SIZE > self->size) + return -1; + + memcpy(dst, self->mmap + offset, SECTOR_SIZE); + + return 0; +} diff --git a/tools/kvm/include/kvm/disk-image.h b/tools/kvm/include/kvm/disk-image.h new file mode 100644 index 000000000000..a7698f1d632f --- /dev/null +++ b/tools/kvm/include/kvm/disk-image.h @@ -0,0 +1,16 @@ +#ifndef KVM__DISK_IMAGE_H +#define KVM__DISK_IMAGE_H + +#include + +struct disk_image { + void *mmap; + int fd; + uint64_t size; +}; + +struct disk_image *disk_image__open(const char *filename); +void disk_image__close(struct disk_image *self); +int disk_image__read_sector(struct disk_image *self, uint64_t sector, void *dst); + +#endif /* KVM__DISK_IMAGE_H */ diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h index 9cf2f73a7d19..48f837306dc0 100644 --- a/tools/kvm/include/kvm/kvm.h +++ b/tools/kvm/include/kvm/kvm.h @@ -14,6 +14,7 @@ struct kvm { int vcpu_fd; /* For VCPU ioctls() */ struct kvm_run *kvm_run; + struct disk_image *disk_image; uint64_t ram_size; void *ram_start; diff --git a/tools/kvm/main.c b/tools/kvm/main.c index c12d3d0ad5a0..89c194e17165 100644 --- a/tools/kvm/main.c +++ b/tools/kvm/main.c @@ -2,6 +2,7 @@ #include "kvm/early_printk.h" #include "kvm/blk-virtio.h" +#include "kvm/disk-image.h" #include "kvm/util.h" #include "kvm/pci.h" @@ -19,7 +20,7 @@ static void usage(char *argv[]) fprintf(stderr, " usage: %s " "[--single-step] [--ioport-debug] " "[--kvm-dev=] [--mem=] [--params=] " - "[--initrd=] [--kernel=]\n", + "[--initrd=] [--kernel=] [--image=]\n", argv[0]); exit(1); } @@ -48,6 +49,7 @@ int main(int argc, char *argv[]) { const char *kernel_filename = NULL; const char *initrd_filename = NULL; + const char *image_filename = NULL; const char *kernel_cmdline = NULL; const char *kvm_dev = "/dev/kvm"; unsigned long ram_size = 64UL << 20; @@ -61,6 +63,9 @@ int main(int argc, char *argv[]) if (option_matches(argv[i], "--kernel=")) { kernel_filename = &argv[i][9]; continue; + } else if (option_matches(argv[i], "--image=")) { + image_filename = &argv[i][8]; + continue; } else if (option_matches(argv[i], "--initrd=")) { initrd_filename = &argv[i][9]; continue; @@ -101,6 +106,12 @@ int main(int argc, char *argv[]) kvm = kvm__init(kvm_dev, ram_size); + if (image_filename) { + kvm->disk_image = disk_image__open(image_filename); + if (!kvm->disk_image) + die("unable to load disk image %s", image_filename); + } + kvm__setup_cpuid(kvm); strcpy(real_cmdline, "notsc nolapic nosmp noacpi pci=conf1 earlyprintk=ttyS0,keep "); -- 2.39.5