qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Chrysostomos Nanakos <cnanakos@grnet.gr>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, Chrysostomos Nanakos <cnanakos@grnet.gr>,
	stefanha@redhat.com
Subject: [Qemu-devel] [PATCH v4 2/3] block/archipelago: Add support for creating images
Date: Thu, 19 Jun 2014 17:48:47 +0300	[thread overview]
Message-ID: <1403189328-18457-3-git-send-email-cnanakos@grnet.gr> (raw)
In-Reply-To: <1403189328-18457-1-git-send-email-cnanakos@grnet.gr>

qemu-img archipelago:<volumename>[/mport=<mapperd_port>[:vport=<vlmcd_port>]]
[size]

Signed-off-by: Chrysostomos Nanakos <cnanakos@grnet.gr>
---
 block/archipelago.c |  137 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 137 insertions(+)

diff --git a/block/archipelago.c b/block/archipelago.c
index 3da7a1c..4553b2d 100644
--- a/block/archipelago.c
+++ b/block/archipelago.c
@@ -32,6 +32,7 @@
  * or implied, of GRNET S.A.
  */
 
+#include "qemu-common.h"
 #include "block/block_int.h"
 #include "qemu/error-report.h"
 #include "qemu/thread.h"
@@ -573,6 +574,127 @@ err_exit:
     xseg_leave(s->xseg);
 }
 
+static int qemu_archipelago_create_volume(Error **errp, const char *volname,
+                                          uint64_t size, xport mportno,
+                                          xport vportno)
+{
+    int ret, targetlen;
+    struct xseg *xseg = NULL;
+    struct xseg_request *req;
+    struct xseg_request_clone *xclone;
+    struct xseg_port *port;
+    xport srcport = NoPort, sport = NoPort;
+    char *target;
+
+    /* Try default values if none has been set */
+    if (mportno == (xport) -1) {
+        mportno = 1001;
+    }
+
+    if (vportno == (xport) -1) {
+        vportno = 501;
+    }
+
+    if (xseg_initialize()) {
+        error_setg(errp, "Cannot initialize XSEG");
+        return -1;
+    }
+
+    xseg = xseg_join((char *)"posix", (char *)"archipelago",
+                     (char *)"posixfd", NULL);
+
+    if (!xseg) {
+        error_setg(errp, "Cannot join XSEG shared memory segment");
+        return -1;
+    }
+
+    port = xseg_bind_dynport(xseg);
+    srcport = port->portno;
+    init_local_signal(xseg, sport, srcport);
+
+    req = xseg_get_request(xseg, srcport, mportno, X_ALLOC);
+    if (!req) {
+        error_setg(errp, "Cannot get XSEG request");
+        return -1;
+    }
+
+    targetlen = strlen(volname);
+    ret = xseg_prep_request(xseg, req, targetlen,
+                            sizeof(struct xseg_request_clone));
+    if (ret < 0) {
+        error_setg(errp, "Cannot prepare XSEG request");
+        goto err_exit;
+    }
+
+    target = xseg_get_target(xseg, req);
+    if (!target) {
+        error_setg(errp, "Cannot get XSEG target.\n");
+        goto err_exit;
+    }
+    strncpy(target, volname, targetlen);
+    xclone = (struct xseg_request_clone *) xseg_get_data(xseg, req);
+    memset(xclone->target, 0 , XSEG_MAX_TARGETLEN);
+    xclone->targetlen = 0;
+    xclone->size = size * BDRV_SECTOR_SIZE;
+    req->offset = 0;
+    req->size = req->datalen;
+    req->op = X_CLONE;
+
+    xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
+    if (p == NoPort) {
+        error_setg(errp, "Could not submit XSEG request");
+        goto err_exit;
+    }
+    xseg_signal(xseg, p);
+
+    ret = wait_reply(xseg, srcport, port, req);
+    if (ret < 0) {
+        error_setg(errp, "wait_reply() error.");
+    }
+
+    xseg_put_request(xseg, req, srcport);
+    xseg_leave_dynport(xseg, port);
+    xseg_leave(xseg);
+    return ret;
+
+err_exit:
+    xseg_put_request(xseg, req, srcport);
+    xseg_leave_dynport(xseg, port);
+    xseg_leave(xseg);
+    return -1;
+}
+
+static int qemu_archipelago_create(const char *filename,
+                                   QemuOpts *options,
+                                   Error **errp)
+{
+    int ret = 0;
+    uint64_t total_size = 0;
+    char *volname = NULL;
+    const char *start;
+    xport mport = NoPort, vport = NoPort;
+
+    if (!strstart(filename, "archipelago:", &start)) {
+        error_setg(errp, "File name must start with 'archipelago:'");
+        return -1;
+    }
+
+    if (!strlen(start) || strstart(start, "/", NULL)) {
+        error_setg(errp, "volume name must be specified");
+        return -1;
+    }
+
+    parse_filename_opts(filename, errp, &volname, &mport, &vport);
+    total_size = qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0) / \
+                 BDRV_SECTOR_SIZE;
+
+    /* Create an Archipelago volume */
+    ret = qemu_archipelago_create_volume(errp, volname, total_size, mport,
+                                         vport);
+    g_free(volname);
+    return ret;
+}
+
 static void qemu_archipelago_aio_cancel(BlockDriverAIOCB *blockacb)
 {
     ArchipelagoAIOCB *aio_cb = (ArchipelagoAIOCB *) blockacb;
@@ -1017,6 +1139,19 @@ static int64_t qemu_archipelago_getlength(BlockDriverState *bs)
     return ret;
 }
 
+static QemuOptsList qemu_archipelago_create_opts = {
+    .name = "archipelago-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_archipelago_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        { /* end of list */ }
+    }
+};
+
 static BlockDriverAIOCB *qemu_archipelago_aio_flush(BlockDriverState *bs,
         BlockDriverCompletionFunc *cb, void *opaque)
 {
@@ -1031,11 +1166,13 @@ static BlockDriver bdrv_archipelago = {
     .bdrv_parse_filename = archipelago_parse_filename,
     .bdrv_file_open      = qemu_archipelago_open,
     .bdrv_close          = qemu_archipelago_close,
+    .bdrv_create         = qemu_archipelago_create,
     .bdrv_getlength      = qemu_archipelago_getlength,
     .bdrv_aio_readv      = qemu_archipelago_aio_readv,
     .bdrv_aio_writev     = qemu_archipelago_aio_writev,
     .bdrv_aio_flush      = qemu_archipelago_aio_flush,
     .bdrv_has_zero_init  = bdrv_has_zero_init_1,
+    .create_opts         = &qemu_archipelago_create_opts,
 };
 
 static void bdrv_archipelago_init(void)
-- 
1.7.10.4

  parent reply	other threads:[~2014-06-19 14:50 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-19 14:48 [Qemu-devel] [PATCH v4 0/3] Support Archipelago as a QEMU block backend Chrysostomos Nanakos
2014-06-19 14:48 ` [Qemu-devel] [PATCH v4 1/3] block: " Chrysostomos Nanakos
2014-06-20 14:33   ` Stefan Hajnoczi
2014-06-23  8:17     ` Chrysostomos Nanakos
2014-06-23  8:31       ` Stefan Hajnoczi
2014-06-19 14:48 ` Chrysostomos Nanakos [this message]
2014-06-20 14:35   ` [Qemu-devel] [PATCH v4 2/3] block/archipelago: Add support for creating images Stefan Hajnoczi
2014-06-19 14:48 ` [Qemu-devel] [PATCH v4 3/3] QMP: Add support for Archipelago Chrysostomos Nanakos

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=1403189328-18457-3-git-send-email-cnanakos@grnet.gr \
    --to=cnanakos@grnet.gr \
    --cc=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /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).