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 v6 2/5] block/archipelago: Implement bdrv_parse_filename()
Date: Fri, 27 Jun 2014 11:24:09 +0300	[thread overview]
Message-ID: <1403857452-23768-3-git-send-email-cnanakos@grnet.gr> (raw)
In-Reply-To: <1403857452-23768-1-git-send-email-cnanakos@grnet.gr>

VM Image on Archipelago volume can also be specified like this:

file=archipelago:<volumename>[/mport=<mapperd_port>[:vport=<vlmcd_port>][:
segment=<segment_name>]]

Examples:

file=archipelago:my_vm_volume
file=archipelago:my_vm_volume/mport=123
file=archipelago:my_vm_volume/mport=123:vport=1234
file=archipelago:my_vm_volume/mport=123:vport=1234:segment=my_segment

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

diff --git a/block/archipelago.c b/block/archipelago.c
index c56826a..3549454 100644
--- a/block/archipelago.c
+++ b/block/archipelago.c
@@ -40,6 +40,11 @@
 * file.driver=archipelago,file.volume=<volumename>[,file.mport=<mapperd_port>[,
 * file.vport=<vlmcd_port>][,file.segment=<segment_name>]]
 *
+* or
+*
+* file=archipelago:<volumename>[/mport=<mapperd_port>[:vport=<vlmcd_port>][:
+* segment=<segment_name>]]
+*
 * 'archipelago' is the protocol.
 *
 * 'mport' is the port number on which mapperd is listening. This is optional
@@ -57,11 +62,20 @@
 * file.driver=archipelago,file.volume=my_vm_volume
 * file.driver=archipelago,file.volume=my_vm_volume,file.mport=123
 * file.driver=archipelago,file.volume=my_vm_volume,file.mport=123,
-* file.vport=1234
+*  file.vport=1234
 * file.driver=archipelago,file.volume=my_vm_volume,file.mport=123,
-* file.vport=1234,file.segment=my_segment
+*  file.vport=1234,file.segment=my_segment
+*
+* or
+*
+* file=archipelago:my_vm_volume
+* file=archipelago:my_vm_volume/mport=123
+* file=archipelago:my_vm_volume/mport=123:vport=1234
+* file=archipelago:my_vm_volume/mport=123:vport=1234:segment=my_segment
+*
 */
 
+#include "qemu-common.h"
 #include "block/block_int.h"
 #include "qemu/error-report.h"
 #include "qemu/thread.h"
@@ -333,6 +347,126 @@ static void qemu_archipelago_complete_aio(void *opaque)
     g_free(reqdata);
 }
 
+static void xseg_find_port(char *pstr, const char *needle, xport *aport)
+{
+    const char *a;
+    char *endptr = NULL;
+    unsigned long port;
+    if (strstart(pstr, needle, &a)) {
+        if (strlen(a) > 0) {
+            port = strtoul(a, &endptr, 10);
+            if (strlen(endptr)) {
+                *aport = -2;
+                return;
+            }
+            *aport = (xport) port;
+        }
+    }
+}
+
+static void xseg_find_segment(char *pstr, const char *needle,
+                              char **segment_name)
+{
+    const char *a;
+    if (strstart(pstr, needle, &a)) {
+        if (strlen(a) > 0) {
+            *segment_name = g_strdup(a);
+        }
+    }
+}
+
+static void parse_filename_opts(const char *filename, Error **errp,
+                                char **volume, char **segment_name,
+                                xport *mport, xport *vport)
+{
+    const char *start;
+    char *tokens[4], *ds;
+    int idx;
+    xport lmport = NoPort, lvport = NoPort;
+
+    strstart(filename, "archipelago:", &start);
+
+    ds = g_strdup(start);
+    tokens[0] = strtok(ds, "/");
+    tokens[1] = strtok(NULL, ":");
+    tokens[2] = strtok(NULL, ":");
+    tokens[3] = strtok(NULL, "\0");
+
+    if (!strlen(tokens[0])) {
+        error_setg(errp, "volume name must be specified first");
+        g_free(ds);
+        return;
+    }
+
+    for (idx = 1; idx < 4; idx++) {
+        if (tokens[idx] != NULL) {
+            if (strstart(tokens[idx], "mport=", NULL)) {
+                xseg_find_port(tokens[idx], "mport=", &lmport);
+            }
+            if (strstart(tokens[idx], "vport=", NULL)) {
+                xseg_find_port(tokens[idx], "vport=", &lvport);
+            }
+            if (strstart(tokens[idx], "segment=", NULL)) {
+                xseg_find_segment(tokens[idx], "segment=", segment_name);
+            }
+        }
+    }
+
+    if ((lmport == -2) || (lvport == -2)) {
+        error_setg(errp, "mport and/or vport must be set");
+        g_free(ds);
+        return;
+    }
+    *volume = g_strdup(tokens[0]);
+    *mport = lmport;
+    *vport = lvport;
+    g_free(ds);
+}
+
+static void archipelago_parse_filename(const char *filename, QDict *options,
+                                       Error **errp)
+{
+    const char *start;
+    char *volume = NULL, *segment_name = NULL;
+    xport mport = NoPort, vport = NoPort;
+
+    if (qdict_haskey(options, ARCHIPELAGO_OPT_VOLUME)
+            || qdict_haskey(options, ARCHIPELAGO_OPT_SEGMENT)
+            || qdict_haskey(options, ARCHIPELAGO_OPT_MPORT)
+            || qdict_haskey(options, ARCHIPELAGO_OPT_VPORT)) {
+        error_setg(errp, "volume/mport/vport/segment and a file name may not be "
+                         "specified at the same time");
+        return;
+    }
+
+    if (!strstart(filename, "archipelago:", &start)) {
+        error_setg(errp, "File name must start with 'archipelago:'");
+        return;
+    }
+
+    if (!strlen(start) || strstart(start, "/", NULL)) {
+        error_setg(errp, "volume name must be specified");
+        return;
+    }
+
+    parse_filename_opts(filename, errp, &volume, &segment_name, &mport, &vport);
+
+    if (volume) {
+        qdict_put(options, ARCHIPELAGO_OPT_VOLUME, qstring_from_str(volume));
+        g_free(volume);
+    }
+    if (segment_name) {
+        qdict_put(options, ARCHIPELAGO_OPT_SEGMENT, qstring_from_str(segment_name));
+        g_free(segment_name);
+    }
+    if (mport != NoPort) {
+        qdict_put(options, ARCHIPELAGO_OPT_MPORT, qint_from_int(mport));
+    }
+    if (vport != NoPort) {
+        qdict_put(options, ARCHIPELAGO_OPT_VPORT, qint_from_int(vport));
+    }
+}
+
 static QemuOptsList archipelago_runtime_opts = {
     .name = "archipelago",
     .head = QTAILQ_HEAD_INITIALIZER(archipelago_runtime_opts.head),
@@ -802,6 +936,7 @@ static BlockDriver bdrv_archipelago = {
     .format_name         = "archipelago",
     .protocol_name       = "archipelago",
     .instance_size       = sizeof(BDRVArchipelagoState),
+    .bdrv_parse_filename = archipelago_parse_filename,
     .bdrv_file_open      = qemu_archipelago_open,
     .bdrv_close          = qemu_archipelago_close,
     .bdrv_getlength      = qemu_archipelago_getlength,
-- 
1.7.10.4

  parent reply	other threads:[~2014-06-27  8:26 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-27  8:24 [Qemu-devel] [PATCH v6 0/5] Support Archipelago as a QEMU block backend Chrysostomos Nanakos
2014-06-27  8:24 ` [Qemu-devel] [PATCH v6 1/5] block: " Chrysostomos Nanakos
2014-07-02 13:59   ` Eric Blake
2014-07-02 14:18     ` Chrysostomos Nanakos
2014-07-02 14:30       ` Eric Blake
2014-07-10  0:23   ` Jeff Cody
2014-07-10 10:04     ` Chrysostomos Nanakos
2014-07-10 14:02       ` Chrysostomos Nanakos
2014-07-22 12:40       ` Stefan Hajnoczi
2014-07-22 12:35   ` Stefan Hajnoczi
2014-06-27  8:24 ` Chrysostomos Nanakos [this message]
2014-07-21 15:55   ` [Qemu-devel] [PATCH v6 2/5] block/archipelago: Implement bdrv_parse_filename() Stefan Hajnoczi
2014-06-27  8:24 ` [Qemu-devel] [PATCH v6 3/5] block/archipelago: Add support for creating images Chrysostomos Nanakos
2014-07-02 14:01   ` Eric Blake
2014-07-02 14:06     ` Chrysostomos Nanakos
2014-07-21 16:01   ` Stefan Hajnoczi
2014-06-27  8:24 ` [Qemu-devel] [PATCH v6 4/5] QMP: Add support for Archipelago Chrysostomos Nanakos
2014-07-02 13:58   ` Eric Blake
2014-07-02 14:11     ` Chrysostomos Nanakos
2014-07-02 14:22       ` Eric Blake
2014-06-27  8:24 ` [Qemu-devel] [PATCH v6 5/5] qemu-iotests: add support for Archipelago protocol Chrysostomos Nanakos
2014-07-21 16:02   ` Stefan Hajnoczi

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=1403857452-23768-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).