From patchwork Fri Jun 27 08:24:10 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chrysostomos Nanakos X-Patchwork-Id: 364823 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 978D61400D2 for ; Fri, 27 Jun 2014 18:29:41 +1000 (EST) Received: from localhost ([::1]:48634 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X0RXP-0006b5-BM for incoming@patchwork.ozlabs.org; Fri, 27 Jun 2014 04:29:39 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58728) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X0RU0-0001ID-NO for qemu-devel@nongnu.org; Fri, 27 Jun 2014 04:26:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X0RTp-0006wS-7w for qemu-devel@nongnu.org; Fri, 27 Jun 2014 04:26:08 -0400 Received: from averel.grnet-hq.admin.grnet.gr ([195.251.29.3]:47515) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X0RTp-0006vw-0w for qemu-devel@nongnu.org; Fri, 27 Jun 2014 04:25:57 -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); Fri, 27 Jun 2014 11:25:53 +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 5E170180E1; Fri, 27 Jun 2014 11:25:53 +0300 (EEST) From: Chrysostomos Nanakos To: qemu-devel@nongnu.org Date: Fri, 27 Jun 2014 11:24:10 +0300 Message-Id: <1403857452-23768-4-git-send-email-cnanakos@grnet.gr> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1403857452-23768-1-git-send-email-cnanakos@grnet.gr> References: <1403857452-23768-1-git-send-email-cnanakos@grnet.gr> X-OriginalArrivalTime: 27 Jun 2014 08:25:53.0634 (UTC) FILETIME=[693D7C20:01CF91E1] 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 v6 3/5] 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=] [:segment=]] [size] Signed-off-by: Chrysostomos Nanakos --- block/archipelago.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/block/archipelago.c b/block/archipelago.c index 3549454..3d5aff1 100644 --- a/block/archipelago.c +++ b/block/archipelago.c @@ -613,6 +613,140 @@ err_exit: xseg_leave(s->xseg); } +static int qemu_archipelago_create_volume(Error **errp, const char *volname, + char *segment_name, + 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 (segment_name == NULL) { + segment_name = g_strdup("archipelago"); + } + + if (xseg_initialize()) { + error_setg(errp, "Cannot initialize XSEG"); + return -1; + } + + xseg = xseg_join((char *)"posix", segment_name, + (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; + } + memcpy(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; + 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_quit_local_signal(xseg, srcport); + xseg_leave_dynport(xseg, port); + xseg_leave(xseg); + return ret; + +err_exit: + xseg_put_request(xseg, req, srcport); + xseg_quit_local_signal(xseg, 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, *segment_name = 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, &segment_name, &mport, &vport); + total_size = qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0); + + /* Create an Archipelago volume */ + ret = qemu_archipelago_create_volume(errp, volname, segment_name, + total_size, mport, + vport); + + if (volname) { + g_free(volname); + } + if (segment_name) { + g_free(segment_name); + } + return ret; +} + static void qemu_archipelago_aio_cancel(BlockDriverAIOCB *blockacb) { ArchipelagoAIOCB *aio_cb = (ArchipelagoAIOCB *) blockacb; @@ -925,6 +1059,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) { @@ -939,11 +1086,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)