]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm: Add support for disk images
authorPekka Enberg <penberg@kernel.org>
Wed, 5 Jan 2011 17:54:48 +0000 (19:54 +0200)
committerPekka Enberg <penberg@kernel.org>
Wed, 5 Jan 2011 18:18:52 +0000 (20:18 +0200)
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 <penberg@kernel.org>
tools/kvm/Makefile
tools/kvm/disk-image.c [new file with mode: 0644]
tools/kvm/include/kvm/disk-image.h [new file with mode: 0644]
tools/kvm/include/kvm/kvm.h
tools/kvm/main.c

index 4f0b26199bcb3c761bd527898ab09e43a61503c1..9d6564c824550381a729b6d3c5ac8a45ee04dfa7 100644 (file)
@@ -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 (file)
index 0000000..92aa83f
--- /dev/null
@@ -0,0 +1,69 @@
+#include "kvm/disk-image.h"
+
+#include "kvm/util.h"
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#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 (file)
index 0000000..a7698f1
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef KVM__DISK_IMAGE_H
+#define KVM__DISK_IMAGE_H
+
+#include <stdint.h>
+
+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 */
index 9cf2f73a7d19132333cab02acd76d567390941cb..48f837306dc016d9eeb9b63ee2ea14b06f2cc368 100644 (file)
@@ -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;
 
index c12d3d0ad5a0f3a8c2d367e84694c96d02c3f940..89c194e17165367865cf40643a30f1e019f2e16a 100644 (file)
@@ -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=<device>] [--mem=<size-in-MiB>] [--params=<kernel-params>] "
-               "[--initrd=<initrd>] [--kernel=]<kernel-image>\n",
+               "[--initrd=<initrd>] [--kernel=]<kernel-image> [--image=]<disk-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 ");