qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Saggi Mizrahi <smizrahi@redhat.com>
To: qemu-devel@nongnu.org
Cc: Saggi Mizrahi <smizrahi@redhat.com>
Subject: [Qemu-devel] [PATCH 2/2] [WIP]Added target to build libvdisk
Date: Sun, 30 Oct 2011 18:51:59 +0200	[thread overview]
Message-ID: <1319993519-865-2-git-send-email-smizrahi@redhat.com> (raw)
In-Reply-To: <1319993519-865-1-git-send-email-smizrahi@redhat.com>

RFC: This is my suggestion for wrapping the block layer with another
supported API. I added only the bare bones verbs I think we can all agree
on.

Apart from the API please also comment on the Makefile. I kinda stitched
it up and I will appreciate comments on it as well.

libvdisk is a library that packages qemu's handling of disk images. This
allows for other programs to link to it and get access to qemu image
file abstractions.

To use install the lib and #include <vdisk.h>

Signed-off-by: Saggi Mizrahi <smizrahi@redhat.com>
---
 .gitignore        |    3 +-
 Makefile.objs     |    9 ++++
 libvdisk/Makefile |   53 +++++++++++++++++++++
 libvdisk/vdisk.c  |  134 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 libvdisk/vdisk.h  |   27 +++++++++++
 5 files changed, 224 insertions(+), 2 deletions(-)
 create mode 100644 libvdisk/Makefile
 create mode 100644 libvdisk/vdisk.c
 create mode 100644 libvdisk/vdisk.h

diff --git a/.gitignore b/.gitignore
index 6d2acab..7221431 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
-config-devices.*
-config-all-devices.*
+config-devices.* config-all-devices.*
 config-host.*
 config-target.*
 trace.h
diff --git a/Makefile.objs b/Makefile.objs
index 01587c8..a355061 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -171,6 +171,15 @@ common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o
 common-obj-$(CONFIG_XEN_BACKEND) += xen_console.o xenfb.o xen_disk.o xen_nic.o
 
 ######################################################################
+# libvdisk
+
+vdisk-obj-y = $(block-obj-y)
+
+vdisk-obj-y += qemu-tool.o qemu-error.o vdisk.o
+vdisk-obj-y += $(oslib-obj-y) $(trace-obj-y) $(block-obj-y)
+vdisk-obj-y += $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
+
+######################################################################
 # libuser
 
 user-obj-y =
diff --git a/libvdisk/Makefile b/libvdisk/Makefile
new file mode 100644
index 0000000..6b0a28f
--- /dev/null
+++ b/libvdisk/Makefile
@@ -0,0 +1,53 @@
+# Makefile for libvdisk.
+
+include ../config-host.mak
+include $(SRC_PATH)/rules.mak
+BUILD_DIR=$(CURDIR)
+
+.PHONY: all libvdisk block trace install uninstall
+
+$(call set-vpath, $(SRC_PATH))
+
+QEMU_CFLAGS+=-I.. -fPIC -I$(BUILD_DIR)
+
+include $(SRC_PATH)/Makefile.objs
+
+libvdisk: block block.o libvdisk.so.1.0
+
+$(BUILD_DIR)/config-host.mak: ../config-host.mak
+	ln -sf $< $@
+
+# Copy because I build the obj with -fPIC which is not needed
+# for regular qemu build
+block: trace
+	mkdir -p block
+	ln -sf $(SRC_PATH)/block/*.[ch] block
+trace: trace.h
+	mkdir -p trace
+	ln -sf $(SRC_PATH)/trace/*.[chd] trace
+
+libvdisk.so.1.0: $(vdisk-obj-y)
+	$(LD) -shared -soname $@ -o $@ -lc $^
+
+install: libvdisk
+	$(INSTALL) vdisk.h $(PREFIX)$(includedir)
+	$(INSTALL) libvdisk.so.1.0 $(PREFIX)$(libdir)
+	ln -sf $(PREFIX)$(libdir)/libvdisk.so.1.0 $(PREFIX)$(libdir)/libvdisk.so.1
+	ln -sf $(PREFIX)$(libdir)/libvdisk.so.1.0 $(PREFIX)$(libdir)/libvdisk.so
+
+uninstall:
+	rm -rf $(PREFIX)$(includedir)/vdisk
+	rm -f $(PREFIX)$(libdir)/libvdisk.so.*
+
+all: libvdisk
+
+clean:
+	rm -rf block/
+	rm -rf trace/
+	rm -f *.[od]
+	rm -f *.mak
+	rm -f trace*
+	rm -f libvdisk.so.*
+
+# Include automatically generated dependency files
+-include $(wildcard *.d */*.d)
diff --git a/libvdisk/vdisk.c b/libvdisk/vdisk.c
new file mode 100644
index 0000000..d28862d
--- /dev/null
+++ b/libvdisk/vdisk.c
@@ -0,0 +1,134 @@
+#include "vdisk.h"
+
+#include <pthread.h>
+#include "block.h"
+
+typedef struct t_virtual_disk {
+    BlockDriverState *bs;
+    pthread_mutex_t mtx;
+
+} VirtualDisk;
+
+void vdisk_init(void) {
+    bdrv_init();
+}
+
+static int open_bdrv_from_path(const char* path, BlockDriverState** bs,
+        int flags, const char* format) {
+    int rc;
+    BlockDriver* driver;
+
+    *bs = bdrv_new(path);
+    if (format == NULL) {
+        driver = NULL;
+    } else {
+        driver = bdrv_find_format(format);
+        if (driver == NULL) {
+            return -EINVAL;
+        }
+    }
+
+    rc = bdrv_open(*bs, path, flags, driver);
+    if (rc < 0) {
+        bdrv_delete(*bs);
+    }
+    return rc;
+}
+
+int vdisk_create(const char *filename, const char *fmt,
+                 const char *base_filename, const char *base_fmt,
+                 char *options, uint64_t img_size, int flags) {
+
+    return bdrv_img_create(filename, fmt, base_filename, base_fmt,
+            options, img_size, flags);
+}
+
+int vdisk_open(VDD* vdd, const char* pathname, int flags, const char* format) {
+    int rc;
+    VirtualDisk* vd = malloc(sizeof(VirtualDisk));
+    if (!vd) { return -ENOMEM; }
+
+    rc = open_bdrv_from_path(pathname, &vd->bs, flags, format);
+    if (rc < 0) {
+        goto free_vd;
+    }
+
+    rc = pthread_mutex_init(&vd->mtx, NULL);
+    if (rc != 0) {
+        rc = -rc;
+        goto free_bs;
+    }
+
+    vdd->virtual_disk = vd;
+
+    return 0;
+
+free_bs:
+    bdrv_delete(vd->bs);
+free_vd:
+    free(vd);
+    return rc;
+}
+
+ssize_t vdisk_pread(VDD* vdd, void *buf, size_t count, off_t offset) {
+    int rc;
+    uint64_t totalSectors;
+    VirtualDisk* vd = vdd->virtual_disk;
+    if (!vd) {
+        return -EBADF;
+    }
+
+    pthread_mutex_lock(&vd->mtx);
+    bdrv_get_geometry(vd->bs, &totalSectors);
+    if ((totalSectors * 512) <= offset) {
+        rc = 0;
+        goto end;
+    }
+
+    rc = bdrv_pread(vd->bs, offset, buf, count);
+end:
+    pthread_mutex_unlock(&vd->mtx);
+    return rc;
+}
+
+ssize_t vdisk_pwrite(VDD* vdd, const void *buf, size_t count, off_t offset) {
+    int rc;
+    uint64_t totalSectors;
+    VirtualDisk* vd = vdd->virtual_disk;
+    if (!vd) {
+        return -EBADF;
+    }
+
+    pthread_mutex_lock(&vd->mtx);
+    bdrv_get_geometry(vd->bs, &totalSectors);
+    if ((totalSectors * 512) <= offset) {
+        rc = 0;
+        goto end;
+    }
+
+    rc = bdrv_pwrite(vd->bs, offset, buf, count);
+end:
+    pthread_mutex_unlock(&vd->mtx);
+    return rc;
+}
+
+int vdisk_flush(VDD* vdd) {
+    VirtualDisk* vd = vdd->virtual_disk;
+    if (!vd) {
+        return -EBADF;
+    }
+
+    return bdrv_flush(vd->bs);
+}
+
+int vdisk_close(VDD* vdd) {
+    VirtualDisk* vd = vdd->virtual_disk;
+    if (!vd) {
+        return -EBADF;
+    }
+
+    bdrv_flush(vd->bs);
+    bdrv_delete(vd->bs);
+    memset(vdd, 0, sizeof(VDD));
+    return 0;
+}
diff --git a/libvdisk/vdisk.h b/libvdisk/vdisk.h
new file mode 100644
index 0000000..6dba7a3
--- /dev/null
+++ b/libvdisk/vdisk.h
@@ -0,0 +1,27 @@
+#include <unistd.h>
+#include <inttypes.h>
+
+#define VDISK_O_RDWR        0x0002
+#define VDISK_O_SNAPSHOT    0x0008 /* open the file read only and save writes in a snapshot */
+#define VDISK_O_NOCACHE     0x0020 /* do not use the host page cache */
+#define VDISK_O_CACHE_WB    0x0040 /* use write-back caching */
+#define VDISK_O_NATIVE_AIO  0x0080 /* use native AIO instead of the thread pool */
+#define VDISK_O_NO_BACKING  0x0100 /* don't open the backing file */
+#define VDISK_O_NO_FLUSH    0x0200 /* disable flushing on this disk */
+
+#define DEFAULT_MAX_DESCIPTORS 1000
+
+typedef struct t_virtual_disk_descriptor {
+    void* virtual_disk;
+} VDD;
+
+void vdisk_init(void);
+
+int vdisk_create(const char *filename, const char *fmt,
+                 const char *base_filename, const char *base_fmt,
+                 char *options, uint64_t img_size, int flags);
+int vdisk_open(VDD* vdd, const char* pathname, int flags, const char* format);
+ssize_t vdisk_pread(VDD* vdd, void *buf, size_t count, off_t offset);
+ssize_t vdisk_pwrite(VDD* vdd, const void *buf, size_t count, off_t offset);
+int vdisk_flush(VDD* vdd);
+int vdisk_close(VDD* vdd);
-- 
1.7.7

  reply	other threads:[~2011-10-30 16:52 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-10-30 16:51 [Qemu-devel] [PATCH 1/2] Better support for distros using /lib64 directories Saggi Mizrahi
2011-10-30 16:51 ` Saggi Mizrahi [this message]
2011-10-30 17:21   ` [Qemu-devel] [PATCH 2/2] [WIP]Added target to build libvdisk Blue Swirl
2011-10-30 18:04     ` Saggi Mizrahi
2011-10-31 10:01       ` Paolo Bonzini
2011-10-31 10:04 ` [Qemu-devel] [PATCH 1/2] Better support for distros using /lib64 directories Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1319993519-865-2-git-send-email-smizrahi@redhat.com \
    --to=smizrahi@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).