From patchwork Wed Jun 4 11:30:03 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chrysostomos Nanakos X-Patchwork-Id: 355837 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 DD3CC14008F for ; Wed, 4 Jun 2014 21:32:08 +1000 (EST) Received: from localhost ([::1]:59720 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ws9QM-0002iZ-Pe for incoming@patchwork.ozlabs.org; Wed, 04 Jun 2014 07:32:06 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58907) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ws9Pd-0001Qw-VC for qemu-devel@nongnu.org; Wed, 04 Jun 2014 07:31:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ws9PV-0001gX-MZ for qemu-devel@nongnu.org; Wed, 04 Jun 2014 07:31:21 -0400 Received: from averel.grnet-hq.admin.grnet.gr ([195.251.29.3]:4455) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ws9PV-0001aA-FD for qemu-devel@nongnu.org; Wed, 04 Jun 2014 07:31:13 -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); Wed, 4 Jun 2014 14:30:50 +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 25A2D180E0; Wed, 4 Jun 2014 14:30:50 +0300 (EEST) From: Chrysostomos Nanakos To: qemu-devel@nongnu.org Date: Wed, 4 Jun 2014 14:30:03 +0300 Message-Id: <1401881404-15823-3-git-send-email-cnanakos@grnet.gr> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1401881404-15823-1-git-send-email-cnanakos@grnet.gr> References: <1401881404-15823-1-git-send-email-cnanakos@grnet.gr> X-OriginalArrivalTime: 04 Jun 2014 11:30:50.0475 (UTC) FILETIME=[6FF8CBB0:01CF7FE8] 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 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 | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/block/archipelago.c b/block/archipelago.c index 5a678ed..d05fa2f 100644 --- a/block/archipelago.c +++ b/block/archipelago.c @@ -573,6 +573,131 @@ 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, + QEMUOptionParameter *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); + + while (options && options->name) { + if (!strcmp(options->name, BLOCK_OPT_SIZE)) { + total_size = options->value.n / BDRV_SECTOR_SIZE; + } + options++; + } + /* 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; @@ -1001,6 +1126,15 @@ static int64_t qemu_archipelago_getlength(BlockDriverState *bs) return ret; } +static QEMUOptionParameter qemu_archipelago_create_options[] = { + { + .name = BLOCK_OPT_SIZE, + .type = OPT_SIZE, + .help = "Virtual disk size" + }, + {NULL} +}; + static BlockDriverAIOCB *qemu_archipelago_aio_flush(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque) { @@ -1015,11 +1149,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_options = qemu_archipelago_create_options, }; static void bdrv_archipelago_init(void)