From patchwork Thu Dec 7 15:50:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Sementsov-Ogievskiy X-Patchwork-Id: 845650 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yt0Nr3jZTz9rxm for ; Fri, 8 Dec 2017 02:52:27 +1100 (AEDT) Received: from localhost ([::1]:32964 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eMyTI-0003g6-KH for incoming@patchwork.ozlabs.org; Thu, 07 Dec 2017 10:52:24 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47242) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eMySX-0003bq-0U for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eMyST-0008B8-Ux for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:36 -0500 Received: from [195.214.232.25] (port=1321 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eMyST-00089L-KF for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:33 -0500 Received: from kvm.sw.ru ([195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id vB7Fp3Zc005896; Thu, 7 Dec 2017 18:51:04 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Thu, 7 Dec 2017 18:50:57 +0300 Message-Id: <20171207155102.66622-2-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171207155102.66622-1-vsementsov@virtuozzo.com> References: <20171207155102.66622-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v2 1/6] nbd/server: add additional assert to nbd_export_put X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, armbru@redhat.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This place is not obvious, nbd_export_close may theoretically reduce refcount to 0. It may happen if someone calls nbd_export_put on named export not through nbd_export_set_name when refcount is 1. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake Reviewed-by: Max Reitz --- nbd/server.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nbd/server.c b/nbd/server.c index 92c0fdd03b..e817c48087 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1190,6 +1190,12 @@ void nbd_export_put(NBDExport *exp) nbd_export_close(exp); } + /* nbd_export_close() may theoretically reduce refcount to 0. It may happen + * if someone calls nbd_export_put() on named export not through + * nbd_export_set_name() when refcount is 1. So, let's assert that + * it is > 0. + */ + assert(exp->refcount > 0); if (--exp->refcount == 0) { assert(exp->name == NULL); assert(exp->description == NULL); From patchwork Thu Dec 7 15:50:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Sementsov-Ogievskiy X-Patchwork-Id: 845655 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yt0Rv2c4kz9s0g for ; Fri, 8 Dec 2017 02:55:07 +1100 (AEDT) Received: from localhost ([::1]:32980 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eMyVt-0006vH-Fl for incoming@patchwork.ozlabs.org; Thu, 07 Dec 2017 10:55:05 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47241) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eMySX-0003bp-01 for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eMyST-0008BF-W1 for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:36 -0500 Received: from [195.214.232.25] (port=12483 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eMyST-00086d-JL for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:33 -0500 Received: from kvm.sw.ru ([195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id vB7Fp3Zd005896; Thu, 7 Dec 2017 18:51:04 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Thu, 7 Dec 2017 18:50:58 +0300 Message-Id: <20171207155102.66622-3-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171207155102.66622-1-vsementsov@virtuozzo.com> References: <20171207155102.66622-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v2 2/6] qapi: add name parameter to nbd-server-add X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, armbru@redhat.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Allow user to specify name for new export, to not reuse internal node name and to not show it to clients. This also allows creating several exports per device. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- qapi/block.json | 9 +++++++-- blockdev-nbd.c | 14 +++++++++----- hmp.c | 5 +++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/qapi/block.json b/qapi/block.json index f093fa3f27..503d4b287b 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -213,14 +213,19 @@ # # @device: The device name or node name of the node to be exported # +# @name: Export name. If unspecified @device parameter used as export name. +# (Since 2.12) +# # @writable: Whether clients should be able to write to the device via the # NBD connection (default false). # -# Returns: error if the device is already marked for export. +# Returns: error if the server is not running, or export with the same name +# already exists. # # Since: 1.3.0 ## -{ 'command': 'nbd-server-add', 'data': {'device': 'str', '*writable': 'bool'} } +{ 'command': 'nbd-server-add', + 'data': {'device': 'str', '*name': 'str', '*writable': 'bool'} } ## # @nbd-server-stop: diff --git a/blockdev-nbd.c b/blockdev-nbd.c index 28f551a7b0..46c885aa35 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -158,8 +158,8 @@ void qmp_nbd_server_start(SocketAddressLegacy *addr, qapi_free_SocketAddress(addr_flat); } -void qmp_nbd_server_add(const char *device, bool has_writable, bool writable, - Error **errp) +void qmp_nbd_server_add(const char *device, bool has_name, const char *name, + bool has_writable, bool writable, Error **errp) { BlockDriverState *bs = NULL; BlockBackend *on_eject_blk; @@ -170,8 +170,12 @@ void qmp_nbd_server_add(const char *device, bool has_writable, bool writable, return; } - if (nbd_export_find(device)) { - error_setg(errp, "NBD server already exporting device '%s'", device); + if (!has_name) { + name = device; + } + + if (nbd_export_find(name)) { + error_setg(errp, "NBD server already has export named '%s'", name); return; } @@ -195,7 +199,7 @@ void qmp_nbd_server_add(const char *device, bool has_writable, bool writable, return; } - nbd_export_set_name(exp, device); + nbd_export_set_name(exp, name); /* The list of named exports has a strong reference to this export now and * our only way of accessing it is through nbd_export_find(), so we can drop diff --git a/hmp.c b/hmp.c index 35a7041824..0ea9c09b58 100644 --- a/hmp.c +++ b/hmp.c @@ -2203,7 +2203,8 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict) continue; } - qmp_nbd_server_add(info->value->device, true, writable, &local_err); + qmp_nbd_server_add(info->value->device, false, NULL, + true, writable, &local_err); if (local_err != NULL) { qmp_nbd_server_stop(NULL); @@ -2223,7 +2224,7 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict) bool writable = qdict_get_try_bool(qdict, "writable", false); Error *local_err = NULL; - qmp_nbd_server_add(device, true, writable, &local_err); + qmp_nbd_server_add(device, false, NULL, true, writable, &local_err); if (local_err != NULL) { hmp_handle_error(mon, &local_err); From patchwork Thu Dec 7 15:50:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Sementsov-Ogievskiy X-Patchwork-Id: 845656 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yt0V65JWhz9t16 for ; Fri, 8 Dec 2017 02:57:02 +1100 (AEDT) Received: from localhost ([::1]:32991 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eMyXk-0000Z5-QI for incoming@patchwork.ozlabs.org; Thu, 07 Dec 2017 10:57:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47234) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eMySW-0003bj-Uo for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eMySU-0008Bb-2i for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:36 -0500 Received: from [195.214.232.25] (port=17523 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eMyST-00089H-Iy for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:34 -0500 Received: from kvm.sw.ru ([195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id vB7Fp3Ze005896; Thu, 7 Dec 2017 18:51:04 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Thu, 7 Dec 2017 18:50:59 +0300 Message-Id: <20171207155102.66622-4-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171207155102.66622-1-vsementsov@virtuozzo.com> References: <20171207155102.66622-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v2 3/6] qapi: add nbd-server-remove X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, armbru@redhat.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add command for export removing. It is needed for cases when we don't want to keep export after the operation on it was completed. The other example is temporary node, created with blockdev-add. If we want to delete it we should firstly remove corresponding NBD export. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- qapi/block.json | 18 ++++++++++++++++++ include/block/nbd.h | 3 ++- blockdev-nbd.c | 29 ++++++++++++++++++++++++++++- nbd/server.c | 25 ++++++++++++++++++++++--- 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/qapi/block.json b/qapi/block.json index 503d4b287b..f83485c325 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -228,6 +228,24 @@ 'data': {'device': 'str', '*name': 'str', '*writable': 'bool'} } ## +# @nbd-server-remove: +# +# Remove NBD export by name. +# +# @name: Export name. +# +# @force: Whether active connections to the export should be closed. If this +# parameter is false the export only becomes hidden from clients (new +# connections are impossible), and would be automatically freed after +# all clients are disconnected (default false). +# +# Returns: error if the server is not running or export is not found. +# +# Since: 2.12 +## +{ 'command': 'nbd-server-remove', 'data': {'name': 'str', '*force': 'bool'} } + +## # @nbd-server-stop: # # Stop QEMU's embedded NBD server, and unregister all devices previously diff --git a/include/block/nbd.h b/include/block/nbd.h index 113c707a5e..b89d116597 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -261,12 +261,13 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size, bool writethrough, BlockBackend *on_eject_blk, Error **errp); void nbd_export_close(NBDExport *exp); +void nbd_export_hide(NBDExport *exp); void nbd_export_get(NBDExport *exp); void nbd_export_put(NBDExport *exp); BlockBackend *nbd_export_get_blockdev(NBDExport *exp); -NBDExport *nbd_export_find(const char *name); +NBDExport *nbd_export_find(const char *name, bool include_hidden); void nbd_export_set_name(NBDExport *exp, const char *name); void nbd_export_set_description(NBDExport *exp, const char *description); void nbd_export_close_all(void); diff --git a/blockdev-nbd.c b/blockdev-nbd.c index 46c885aa35..2495d38f2c 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -174,7 +174,7 @@ void qmp_nbd_server_add(const char *device, bool has_name, const char *name, name = device; } - if (nbd_export_find(name)) { + if (nbd_export_find(name, true)) { error_setg(errp, "NBD server already has export named '%s'", name); return; } @@ -207,6 +207,33 @@ void qmp_nbd_server_add(const char *device, bool has_name, const char *name, nbd_export_put(exp); } +void qmp_nbd_server_remove(const char *name, bool has_force, bool force, + Error **errp) +{ + NBDExport *exp; + + if (!nbd_server) { + error_setg(errp, "NBD server not running"); + return; + } + + exp = nbd_export_find(name, true); + if (exp == NULL) { + error_setg(errp, "Export '%s' is not found", name); + return; + } + + if (!has_force) { + force = false; + } + + if (force) { + nbd_export_close(exp); + } else { + nbd_export_hide(exp); + } +} + void qmp_nbd_server_stop(Error **errp) { nbd_export_close_all(); diff --git a/nbd/server.c b/nbd/server.c index e817c48087..d85f2dc747 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -78,6 +78,10 @@ struct NBDExport { BlockBackend *eject_notifier_blk; Notifier eject_notifier; + + /* hidden export is not available for new connections and should be removed + * after last client disconnect */ + bool hidden; }; static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); @@ -300,7 +304,7 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, uint32_t length, trace_nbd_negotiate_handle_export_name_request(name); - client->exp = nbd_export_find(name); + client->exp = nbd_export_find(name, false); if (!client->exp) { error_setg(errp, "export not found"); return -EINVAL; @@ -429,7 +433,7 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint32_t length, } assert(length == 0); - exp = nbd_export_find(name); + exp = nbd_export_find(name, false); if (!exp) { return nbd_negotiate_send_rep_err(client->ioc, NBD_REP_ERR_UNKNOWN, opt, errp, "export '%s' not present", @@ -966,6 +970,9 @@ void nbd_client_put(NBDClient *client) if (client->exp) { QTAILQ_REMOVE(&client->exp->clients, client, next); nbd_export_put(client->exp); + if (client->exp->hidden && QTAILQ_EMPTY(&client->exp->clients)) { + nbd_export_close(client->exp); + } } g_free(client); } @@ -1125,10 +1132,14 @@ fail: return NULL; } -NBDExport *nbd_export_find(const char *name) +NBDExport *nbd_export_find(const char *name, bool include_hidden) { NBDExport *exp; QTAILQ_FOREACH(exp, &exports, next) { + if (!include_hidden && exp->hidden) { + continue; + } + if (strcmp(name, exp->name) == 0) { return exp; } @@ -1177,6 +1188,14 @@ void nbd_export_close(NBDExport *exp) nbd_export_put(exp); } +void nbd_export_hide(NBDExport *exp) +{ + exp->hidden = true; + if (QTAILQ_EMPTY(&exp->clients)) { + nbd_export_close(exp); + } +} + void nbd_export_get(NBDExport *exp) { assert(exp->refcount > 0); From patchwork Thu Dec 7 15:51:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Sementsov-Ogievskiy X-Patchwork-Id: 845652 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yt0Ns6W8cz9sCZ for ; Fri, 8 Dec 2017 02:52:29 +1100 (AEDT) Received: from localhost ([::1]:32965 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eMyTL-0003hW-V0 for incoming@patchwork.ozlabs.org; Thu, 07 Dec 2017 10:52:28 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47237) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eMySW-0003bm-VX for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eMySU-0008BW-2J for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:36 -0500 Received: from [195.214.232.25] (port=33163 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eMyST-00086f-Hw for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:34 -0500 Received: from kvm.sw.ru ([195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id vB7Fp3Zf005896; Thu, 7 Dec 2017 18:51:04 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Thu, 7 Dec 2017 18:51:00 +0300 Message-Id: <20171207155102.66622-5-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171207155102.66622-1-vsementsov@virtuozzo.com> References: <20171207155102.66622-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v2 4/6] iotest 147: add cases to test new @name parameter of nbd-server-add X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, armbru@redhat.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- tests/qemu-iotests/147 | 68 +++++++++++++++++++++++++++++++++++++--------- tests/qemu-iotests/147.out | 4 +-- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147 index 90f40ed245..d2081df84b 100755 --- a/tests/qemu-iotests/147 +++ b/tests/qemu-iotests/147 @@ -38,8 +38,8 @@ def flatten_sock_addr(crumpled_address): class NBDBlockdevAddBase(iotests.QMPTestCase): - def blockdev_add_options(self, address, export=None): - options = { 'node-name': 'nbd-blockdev', + def blockdev_add_options(self, address, export, node_name): + options = { 'node-name': node_name, 'driver': 'raw', 'file': { 'driver': 'nbd', @@ -50,23 +50,28 @@ class NBDBlockdevAddBase(iotests.QMPTestCase): options['file']['export'] = export return options - def client_test(self, filename, address, export=None): - bao = self.blockdev_add_options(address, export) + def client_test(self, filename, address, export=None, + node_name='nbd-blockdev', delete=True): + bao = self.blockdev_add_options(address, export, node_name) result = self.vm.qmp('blockdev-add', **bao) self.assert_qmp(result, 'return', {}) + found = False result = self.vm.qmp('query-named-block-nodes') for node in result['return']: - if node['node-name'] == 'nbd-blockdev': + if node['node-name'] == node_name: + found = True if isinstance(filename, str): self.assert_qmp(node, 'image/filename', filename) else: self.assert_json_filename_equal(node['image']['filename'], filename) break + self.assertTrue(found) - result = self.vm.qmp('blockdev-del', node_name='nbd-blockdev') - self.assert_qmp(result, 'return', {}) + if delete: + result = self.vm.qmp('blockdev-del', node_name=node_name) + self.assert_qmp(result, 'return', {}) class QemuNBD(NBDBlockdevAddBase): @@ -125,26 +130,63 @@ class BuiltinNBD(NBDBlockdevAddBase): except OSError: pass - def _server_up(self, address): + def _server_up(self, address, export_name=None, export_name2=None): result = self.server.qmp('nbd-server-start', addr=address) self.assert_qmp(result, 'return', {}) - result = self.server.qmp('nbd-server-add', device='nbd-export') + if export_name is None: + result = self.server.qmp('nbd-server-add', device='nbd-export') + else: + result = self.server.qmp('nbd-server-add', device='nbd-export', + name=export_name) self.assert_qmp(result, 'return', {}) + if export_name2 is not None: + result = self.server.qmp('nbd-server-add', device='nbd-export', + name=export_name2) + self.assert_qmp(result, 'return', {}) + + def _server_down(self): result = self.server.qmp('nbd-server-stop') self.assert_qmp(result, 'return', {}) - def test_inet(self): + def do_test_inet(self, export_name=None): address = { 'type': 'inet', 'data': { 'host': 'localhost', 'port': str(NBD_PORT) } } - self._server_up(address) - self.client_test('nbd://localhost:%i/nbd-export' % NBD_PORT, - flatten_sock_addr(address), 'nbd-export') + self._server_up(address, export_name) + export_name = export_name or 'nbd-export' + self.client_test('nbd://localhost:%i/%s' % (NBD_PORT, export_name), + flatten_sock_addr(address), export_name) + self._server_down() + + def test_inet_default_export_name(self): + self.do_test_inet() + + def test_inet_same_export_name(self): + self.do_test_inet('nbd-export') + + def test_inet_different_export_name(self): + self.do_test_inet('shadow') + + def test_inet_two_exports(self): + address = { 'type': 'inet', + 'data': { + 'host': 'localhost', + 'port': str(NBD_PORT) + } } + self._server_up(address, 'exp1', 'exp2') + self.client_test('nbd://localhost:%i/%s' % (NBD_PORT, 'exp1'), + flatten_sock_addr(address), 'exp1', 'node1', False) + self.client_test('nbd://localhost:%i/%s' % (NBD_PORT, 'exp2'), + flatten_sock_addr(address), 'exp2', 'node2', False) + result = self.vm.qmp('blockdev-del', node_name='node1') + self.assert_qmp(result, 'return', {}) + result = self.vm.qmp('blockdev-del', node_name='node2') + self.assert_qmp(result, 'return', {}) self._server_down() def test_inet6(self): diff --git a/tests/qemu-iotests/147.out b/tests/qemu-iotests/147.out index 3f8a935a08..dae404e278 100644 --- a/tests/qemu-iotests/147.out +++ b/tests/qemu-iotests/147.out @@ -1,5 +1,5 @@ -...... +......... ---------------------------------------------------------------------- -Ran 6 tests +Ran 9 tests OK From patchwork Thu Dec 7 15:51:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Sementsov-Ogievskiy X-Patchwork-Id: 845653 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yt0P02K88z9rxm for ; Fri, 8 Dec 2017 02:52:36 +1100 (AEDT) Received: from localhost ([::1]:32966 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eMyTS-0003ou-BN for incoming@patchwork.ozlabs.org; Thu, 07 Dec 2017 10:52:34 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47239) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eMySW-0003bo-W3 for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eMySU-0008BI-0z for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:36 -0500 Received: from [195.214.232.25] (port=27764 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eMyST-00087I-JI for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:33 -0500 Received: from kvm.sw.ru ([195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id vB7Fp3Zg005896; Thu, 7 Dec 2017 18:51:04 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Thu, 7 Dec 2017 18:51:01 +0300 Message-Id: <20171207155102.66622-6-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171207155102.66622-1-vsementsov@virtuozzo.com> References: <20171207155102.66622-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v2 5/6] iotests: implement QemuIoInteractive class X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, armbru@redhat.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Vladimir Sementsov-Ogievskiy Acked-by: Eric Blake --- tests/qemu-iotests/iotests.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 6f057904a9..a9f312db83 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -93,6 +93,44 @@ def qemu_io(*args): sys.stderr.write('qemu-io received signal %i: %s\n' % (-exitcode, ' '.join(args))) return subp.communicate()[0] + +class QemuIoInteractive: + def __init__(self, *args): + self.args = qemu_io_args + list(args) + self._p = subprocess.Popen(self.args, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + assert self._p.stdout.read(9) == 'qemu-io> ' + + def close(self): + self._p.communicate('q\n') + + def _read_output(self): + pattern = 'qemu-io> ' + n = len(pattern) + pos = 0 + s = [] + while pos != n: + c = self._p.stdout.read(1) + #check unexpected EOF + assert c != '' + s.append(c) + if c == pattern[pos]: + pos += 1 + else: + pos = 0 + + return ''.join(s[:-n]) + + def cmd(self, cmd): + # quit command is in close(), '\n' is added automatically + assert '\n' not in cmd + cmd = cmd.strip() + assert cmd != 'q' and cmd != 'quit' + self._p.stdin.write(cmd + '\n') + return self._read_output() + + def qemu_nbd(*args): '''Run qemu-nbd in daemon mode and return the parent's exit code''' return subprocess.call(qemu_nbd_args + ['--fork'] + list(args)) From patchwork Thu Dec 7 15:51:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Sementsov-Ogievskiy X-Patchwork-Id: 845651 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yt0Nr3jkDz9sCZ for ; Fri, 8 Dec 2017 02:52:28 +1100 (AEDT) Received: from localhost ([::1]:32963 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eMyTJ-0003fG-G0 for incoming@patchwork.ozlabs.org; Thu, 07 Dec 2017 10:52:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47235) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eMySW-0003bk-VV for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eMySU-0008BP-0g for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:37 -0500 Received: from [195.214.232.25] (port=38302 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eMyST-00086c-Gf for qemu-devel@nongnu.org; Thu, 07 Dec 2017 10:51:33 -0500 Received: from kvm.sw.ru ([195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id vB7Fp3Zh005896; Thu, 7 Dec 2017 18:51:04 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Thu, 7 Dec 2017 18:51:02 +0300 Message-Id: <20171207155102.66622-7-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20171207155102.66622-1-vsementsov@virtuozzo.com> References: <20171207155102.66622-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v2 6/6] iotest 201: new test for qmp nbd-server-remove X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, armbru@redhat.com, mreitz@redhat.com, den@openvz.org, pbonzini@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/201 | 130 +++++++++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/201.out | 5 ++ tests/qemu-iotests/group | 1 + 3 files changed, 136 insertions(+) create mode 100644 tests/qemu-iotests/201 create mode 100644 tests/qemu-iotests/201.out diff --git a/tests/qemu-iotests/201 b/tests/qemu-iotests/201 new file mode 100644 index 0000000000..28d0324195 --- /dev/null +++ b/tests/qemu-iotests/201 @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# +# Tests for qmp command nbd-server-remove. +# +# Copyright (c) 2017 Virtuozzo International GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import os +import sys +import iotests +import time +from iotests import qemu_img, qemu_io, filter_qemu_io, QemuIoInteractive + +nbd_port = '10900' +nbd_uri = 'nbd+tcp://localhost:' + nbd_port + '/exp' +disk = os.path.join(iotests.test_dir, 'disk') + +class TestNbdServerRemove(iotests.QMPTestCase): + def setUp(self): + qemu_img('create', '-f', iotests.imgfmt, disk, '1M') + + self.vm = iotests.VM().add_drive(disk) + self.vm.launch() + + address = { + 'type': 'inet', + 'data': { + 'host': 'localhost', + 'port': nbd_port + } + } + + result = self.vm.qmp('nbd-server-start', addr=address) + self.assert_qmp(result, 'return', {}) + result = self.vm.qmp('nbd-server-add', device='drive0', name='exp') + self.assert_qmp(result, 'return', {}) + + def tearDown(self): + self.vm.shutdown() + os.remove(disk) + + def remove_export(self, name, force=None): + if force is None: + result = self.vm.qmp('nbd-server-remove', name=name) + else: + result = self.vm.qmp('nbd-server-remove', name=name, force=force) + self.assert_qmp(result, 'return', {}) + + def assertExportNotFound(self, name): + result = self.vm.qmp('nbd-server-remove', name=name) + self.assert_qmp(result, 'error/desc', "Export 'exp' is not found") + + def assertReadOk(self, qemu_io_output): + self.assertEqual(filter_qemu_io(qemu_io_output).strip(), + 'read 512/512 bytes at offset 0\n' + + '512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)') + + def assertReadFailed(self, qemu_io_output): + self.assertEqual(filter_qemu_io(qemu_io_output).strip(), + 'read failed: Input/output error') + + def assertConnectFailed(self, qemu_io_output): + self.assertEqual(filter_qemu_io(qemu_io_output).strip(), + "can't open device nbd+tcp://localhost:10900/exp: " + + "Requested export not available\nserver reported: " + + "export 'exp' not present") + + def do_test_connect_after_remove(self, force=None): + args = ('-r', '-f', 'raw', '-c', 'read 0 512', nbd_uri) + self.assertReadOk(qemu_io(*args)) + self.remove_export('exp', force) + self.assertExportNotFound('exp') + self.assertConnectFailed(qemu_io(*args)) + + def test_connect_after_remove_default(self): + self.do_test_connect_after_remove() + + def test_connect_after_remove_safe(self): + self.do_test_connect_after_remove(False) + + def test_connect_after_remove_force(self): + self.do_test_connect_after_remove(True) + + def do_test_remove_during_connect(self, force=None): + qio = QemuIoInteractive('-r', '-f', 'raw', nbd_uri) + self.assertReadOk(qio.cmd('read 0 512')) + self.remove_export('exp', force) + if force: + self.assertReadFailed(qio.cmd('read 0 512')) + self.assertExportNotFound('exp') + else: + self.assertReadOk(qio.cmd('read 0 512')) + qio.close() + self.assertExportNotFound('exp') + + def test_remove_during_connect_default(self): + self.do_test_remove_during_connect() + + def test_remove_during_connect_safe(self): + self.do_test_remove_during_connect(False) + + def test_remove_during_connect_force(self): + self.do_test_remove_during_connect(True) + + def test_remove_during_connect_safe_force(self): + qio = QemuIoInteractive('-r', '-f', 'raw', nbd_uri) + self.assertReadOk(qio.cmd('read 0 512')) + self.remove_export('exp', False) + self.assertReadOk(qio.cmd('read 0 512')) + self.remove_export('exp', True) + self.assertExportNotFound('exp') + self.assertReadFailed(qio.cmd('read 0 512')) + qio.close() + + +if __name__ == '__main__': + iotests.main() diff --git a/tests/qemu-iotests/201.out b/tests/qemu-iotests/201.out new file mode 100644 index 0000000000..2f7d3902f2 --- /dev/null +++ b/tests/qemu-iotests/201.out @@ -0,0 +1,5 @@ +....... +---------------------------------------------------------------------- +Ran 7 tests + +OK diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 3e688678dd..15df7678b3 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -197,3 +197,4 @@ 197 rw auto quick 198 rw auto 200 rw auto +201 rw auto quick