From patchwork Thu Jun 19 14:48:47 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chrysostomos Nanakos X-Patchwork-Id: 361897 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id B2429140092 for ; Fri, 20 Jun 2014 00:58:11 +1000 (EST) Received: from localhost ([::1]:36093 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wxdn0-0004PR-1W for incoming@patchwork.ozlabs.org; Thu, 19 Jun 2014 10:58:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33343) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wxdfn-0001LU-8z for qemu-devel@nongnu.org; Thu, 19 Jun 2014 10:50:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Wxdfc-0006AL-Co for qemu-devel@nongnu.org; Thu, 19 Jun 2014 10:50:43 -0400 Received: from averel.grnet-hq.admin.grnet.gr ([195.251.29.3]:17932) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wxdfc-00065T-68 for qemu-devel@nongnu.org; Thu, 19 Jun 2014 10:50:32 -0400 Received: from smtps.admin.grnet.gr ([195.251.28.70]) by averel.grnet-hq.admin.grnet.gr over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Thu, 19 Jun 2014 17:50:09 +0300 Received: from path.grnet-hq.admin.grnet.gr (path.grnet-hq.admin.grnet.gr [195.251.29.52]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: cnanakos@admin.grnet.gr) by smtps.admin.grnet.gr (Postfix) with ESMTPSA id 5A2DA180E0; Thu, 19 Jun 2014 17:50:09 +0300 (EEST) From: Chrysostomos Nanakos To: qemu-devel@nongnu.org Date: Thu, 19 Jun 2014 17:48:47 +0300 Message-Id: <1403189328-18457-3-git-send-email-cnanakos@grnet.gr> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1403189328-18457-1-git-send-email-cnanakos@grnet.gr> References: <1403189328-18457-1-git-send-email-cnanakos@grnet.gr> X-OriginalArrivalTime: 19 Jun 2014 14:50:09.0635 (UTC) FILETIME=[C4620B30:01CF8BCD] X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] X-Received-From: 195.251.29.3 Cc: kwolf@redhat.com, Chrysostomos Nanakos , stefanha@redhat.com Subject: [Qemu-devel] [PATCH v4 2/3] block/archipelago: Add support for creating images X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org qemu-img archipelago:[/mport=[:vport=]] [size] Signed-off-by: Chrysostomos Nanakos --- 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)