qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Re: [kvm-devel] [PATCH] Memory Based Block Device


From: Anthony Liguori
Subject: [Qemu-devel] Re: [kvm-devel] [PATCH] Memory Based Block Device
Date: Wed, 25 Jul 2007 13:39:21 -0500
User-agent: Thunderbird 1.5.0.12 (X11/20070604)

Evan Felix wrote:
Folks here is a patch i've made for qemu that adds a memory based
block device, it utilizes memory on the Host side to emulate a block
device.

I often use -hda /dev/null for -kernel/-append.

If you really want to implement a "proper" solution for -kernel/-append, I think the right thing to do would be to use an option ROM instead of a fake boot sector.

Regards,

Anthony Liguori

I've tested this on a few boxes to allow a kernel/initramfs system to
boot without needing a specified block device(it automatically creates
a small one) and for installing a usable system on.  One note you can
never shut down the running system, but seems to work fine when only
re-boots are required.  I've installed debian on it a few times.

Some Things I'd like comments on:
- The auto-detection code in the block code causes the code to
allocate the memory used twice, even though it only gets used the
second time.
- using qemu_mallocz seems to pre-allocate all the memory used, which
is fine, but my early code with calloc only allocated what blocks were
actually used. Does this bother people.

Evan Felix


diff -urNp -x '*~' -x '*html' -x '*.mak' -x '*.1'
kvm-28/qemu.orig/block.c kvm-28/qemu/block.c
--- kvm-28/qemu.orig/block.c    2007-06-07 08:13:47.000000000 -0700
+++ kvm-28/qemu/block.c 2007-07-11 13:29:02.000000000 -0700
@@ -1244,6 +1244,7 @@ static int bdrv_write_em(BlockDriverStat
 void bdrv_init(void)
 {
     bdrv_register(&bdrv_raw);
+    bdrv_register(&bdrv_mem);
     bdrv_register(&bdrv_host_device);
 #ifndef _WIN32
     bdrv_register(&bdrv_cow);
diff -urNp -x '*~' -x '*html' -x '*.mak' -x '*.1'
kvm-28/qemu.orig/block-mem.c kvm-28/qemu/block-mem.c
--- kvm-28/qemu.orig/block-mem.c        1969-12-31 16:00:00.000000000 -0800
+++ kvm-28/qemu/block-mem.c     2007-07-09 13:46:39.000000000 -0700
@@ -0,0 +1,129 @@
+/*
+ *  Block Driver for a Memory disk on the host side.
+ *
+ *  Copyright (c) 2007 Pacific Northwest National Laboratory
+ *                     and Evan Felix <address@hidden>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "vl.h"
+#include "block_int.h"
+
+//I took this from block-raw.c
+#ifdef __sun__
+#define _POSIX_PTHREAD_SEMANTICS 1
+#include <signal.h>
+#include <sys/dkio.h>
+#endif
+#ifdef __linux__
+#include <sys/ioctl.h>
+#include <linux/cdrom.h>
+#include <linux/fd.h>
+#endif
+#ifdef __FreeBSD__
+#include <sys/disk.h>
+#endif
+
+#define DEBUG_MEM 0
+
+#ifdef DEBUG_MEM
+#define DEBUG(fmt,a...) printf("D:%s:%d> " fmt "\n",__FILE__,__LINE__,##a)
+#else
+#define DEBUG(fmt,a...)
+#endif
+
+typedef struct BDRVMemState {
+       void *memory;
+       int64_t length;
+} BDRVMemState;
+
+static int mem_open(BlockDriverState *bs, const char *filename, int flags)
+{
+       BDRVMemState *s = bs->opaque;
+       
+       bs->locked = 1;
+       bs->type   = BDRV_TYPE_HD;
+       //Try to parse the filename as a number of bytes.  add recognize M,K,G 
laterz.
+       s->length = strtol(filename+4,NULL,0);
+       DEBUG("mem_open:Raw Image size: %s -> %ld\n",filename,s->length);
+       
+       s->memory=qemu_mallocz(s->length);
+       if (! s->memory)
+               return -ENOMEM;
+       return 0;
+}
+
+static void mem_close(BlockDriverState *bs) {
+       
+       BDRVMemState *s = bs->opaque;
+       DEBUG("mem_close: %lld\n",s->length);
+       qemu_free(s->memory);
+       s->length=0;
+}
+
+static int mem_pread(BlockDriverState *bs, int64_t offset,
+                     uint8_t *buf, int count)
+{
+    BDRVMemState *s = bs->opaque;
+       
+       if (offset < 0 || (offset + count)>s->length) {
+               return -EINVAL; 
+       }
+       
+    memcpy(buf,(s->memory+offset),count);
+       return count;
+}
+
+static int mem_pwrite(BlockDriverState *bs, int64_t offset,
+                      const uint8_t *buf, int count)
+{
+       BDRVMemState *s = bs->opaque;
+       
+       if (offset < 0 || (offset + count)>s->length) {
+               return -EINVAL; 
+       }
+       
+       memcpy((s->memory+offset),buf,count);
+       return count;
+}
+
+static void mem_flush(BlockDriverState *bs)
+{
+       //Do Nothing for now
+       DEBUG("mem_flush\n");
+}
+
+static int64_t  mem_getlength(BlockDriverState *bs)
+{
+    BDRVMemState *s = bs->opaque;
+
+       return s->length;
+}
+
+BlockDriver bdrv_mem = {
+       .format_name     = "mem",
+       .instance_size   = sizeof(BDRVMemState),
+       .protocol_name   = "mem",
+       
+       .bdrv_open       = mem_open,
+       .bdrv_close      = mem_close,
+       .bdrv_flush      = mem_flush,
+       
+       .bdrv_pread = mem_pread,
+    .bdrv_pwrite = mem_pwrite,
+    .bdrv_getlength = mem_getlength,
+};
diff -urNp -x '*~' -x '*html' -x '*.mak' -x '*.1'
kvm-28/qemu.orig/hw/pc.c kvm-28/qemu/hw/pc.c
--- kvm-28/qemu.orig/hw/pc.c    2007-06-07 08:13:47.000000000 -0700
+++ kvm-28/qemu/hw/pc.c 2007-07-06 16:48:12.000000000 -0700
@@ -583,8 +583,13 @@ static void pc_init1(int ram_size, int v
         uint8_t old_bootsect[512];

         if (bs_table[0] == NULL) {
-            fprintf(stderr, "A disk image must be given for 'hda'
when booting a Linux kernel\n");
-            exit(1);
+            fprintf(stderr, "A disk image must be given when booting
a Linux kernel....\n\tCreating Simple memory backed Disk\n");
+            bs_table[i] = bdrv_new("hda");
+            if (bdrv_open(bs_table[0], "mem:4096", 0) < 0) {
+                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
+                        "mem:512");
+                exit(1);
+            }
         }
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUX_BOOT_FILENAME);
         ret = load_image(buf, bootsect);
diff -urNp -x '*~' -x '*html' -x '*.mak' -x '*.1'
kvm-28/qemu.orig/Makefile kvm-28/qemu/Makefile
--- kvm-28/qemu.orig/Makefile   2007-06-07 08:13:47.000000000 -0700
+++ kvm-28/qemu/Makefile        2007-07-06 14:24:44.000000000 -0700
@@ -39,7 +39,7 @@ subdir-%: dyngen$(EXESUF)

 recurse-all: $(patsubst %,subdir-%, $(TARGET_DIRS))

-qemu-img$(EXESUF): qemu-img.c cutils.c block.c block-raw.c
block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c block-dmg.c
block-bochs.c block-vpc.c block-vvfat.c block-qcow2.c
+qemu-img$(EXESUF): qemu-img.c cutils.c block.c block-raw.c
block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c block-dmg.c
block-bochs.c block-vpc.c block-vvfat.c block-qcow2.c block-mem.c
        $(CC) -DQEMU_TOOL $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $(LDFLAGS)
$(BASE_LDFLAGS) -o $@ $^ -lz $(LIBS)

 dyngen$(EXESUF): dyngen.c
diff -urNp -x '*~' -x '*html' -x '*.mak' -x '*.1'
kvm-28/qemu.orig/Makefile.target kvm-28/qemu/Makefile.target
--- kvm-28/qemu.orig/Makefile.target    2007-06-07 08:13:47.000000000 -0700
+++ kvm-28/qemu/Makefile.target 2007-07-06 13:43:31.000000000 -0700
@@ -326,7 +326,7 @@ endif
 VL_OBJS=vl.o osdep.o readline.o monitor.o pci.o console.o loader.o isa_mmio.o
 VL_OBJS+=cutils.o migration.o
 VL_OBJS+=block.o block-raw.o
-VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o
block-dmg.o block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o
+VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o
block-dmg.o block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o
block-mem.o
 ifdef CONFIG_WIN32
 VL_OBJS+=tap-win32.o
 endif
diff -urNp -x '*~' -x '*html' -x '*.mak' -x '*.1'
kvm-28/qemu.orig/vl.h kvm-28/qemu/vl.h
--- kvm-28/qemu.orig/vl.h       2007-06-07 08:13:47.000000000 -0700
+++ kvm-28/qemu/vl.h    2007-07-06 14:23:50.000000000 -0700
@@ -561,6 +561,7 @@ typedef struct BlockDriverState BlockDri
 typedef struct BlockDriver BlockDriver;

 extern BlockDriver bdrv_raw;
+extern BlockDriver bdrv_mem;
 extern BlockDriver bdrv_host_device;
 extern BlockDriver bdrv_cow;
 extern BlockDriver bdrv_qcow;

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
kvm-devel mailing list
address@hidden
https://lists.sourceforge.net/lists/listinfo/kvm-devel






reply via email to

[Prev in Thread] Current Thread [Next in Thread]