From nobody Sat Apr 27 13:45:46 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 152855774078663.26458660800188; Sat, 9 Jun 2018 08:22:20 -0700 (PDT) Received: from localhost ([::1]:40646 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRfh6-0005k4-3a for importer@patchew.org; Sat, 09 Jun 2018 11:22:20 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36196) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRfd0-0002y3-JW for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fRfcx-00051z-EH for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:06 -0400 Received: from relay.sw.ru ([195.214.232.25]:51892) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fRfcx-00050X-5R for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:03 -0400 Received: from msk-vpn.virtuozzo.com ([195.214.232.6] helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.90_1) (envelope-from ) id 1fRfct-0006t9-HI; Sat, 09 Jun 2018 18:17:59 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Sat, 9 Jun 2018 18:17:53 +0300 Message-Id: <20180609151758.17343-2-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20180609151758.17343-1-vsementsov@virtuozzo.com> References: <20180609151758.17343-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v5 1/6] nbd/server: fix trace 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Return code =3D 1 doesn't mean that we parsed base:allocation. Use correct traces in both -parsed and -skipped cases. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- nbd/server.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/nbd/server.c b/nbd/server.c index 9e1f227178..8e02e077ec 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -741,7 +741,10 @@ static int nbd_negotiate_send_meta_context(NBDClient *= client, * the current name, after the 'base:' portion has been stripped. * * Return -errno on I/O error, 0 if option was completely handled by - * sending a reply about inconsistent lengths, or 1 on success. */ + * sending a reply about inconsistent lengths, or 1 on success. + * + * Note: return code =3D 1 doesn't mean that we've parsed "base:allocation" + * namespace. It only means that there are no errors.*/ static int nbd_meta_base_query(NBDClient *client, NBDExportMetaContexts *m= eta, uint32_t len, Error **errp) { @@ -768,10 +771,12 @@ static int nbd_meta_base_query(NBDClient *client, NBD= ExportMetaContexts *meta, } =20 if (strncmp(query, "allocation", alen) =3D=3D 0) { + trace_nbd_negotiate_meta_query_parse("base:allocation"); meta->base_allocation =3D true; + } else { + trace_nbd_negotiate_meta_query_skip("not base:allocation"); } =20 - trace_nbd_negotiate_meta_query_parse("base:allocation"); return 1; } =20 --=20 2.11.1 From nobody Sat Apr 27 13:45:46 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1528557609982532.8390912756602; Sat, 9 Jun 2018 08:20:09 -0700 (PDT) Received: from localhost ([::1]:40629 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRfeq-0003sW-RI for importer@patchew.org; Sat, 09 Jun 2018 11:20:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36203) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRfd0-0002y7-LE for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fRfcx-00052X-Pf for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:06 -0400 Received: from relay.sw.ru ([195.214.232.25]:51902) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fRfcx-00050Z-DQ for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:03 -0400 Received: from msk-vpn.virtuozzo.com ([195.214.232.6] helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.90_1) (envelope-from ) id 1fRfct-0006t9-MT; Sat, 09 Jun 2018 18:17:59 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Sat, 9 Jun 2018 18:17:54 +0300 Message-Id: <20180609151758.17343-3-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20180609151758.17343-1-vsementsov@virtuozzo.com> References: <20180609151758.17343-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v5 2/6] nbd/server: refactor NBDExportMetaContexts 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Use NBDExport pointer instead of just export name: there no needs to store duplicated name in the struct, moreover, NBDExport will be used further. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- nbd/server.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/nbd/server.c b/nbd/server.c index 8e02e077ec..567561a77e 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -88,7 +88,7 @@ static QTAILQ_HEAD(, NBDExport) exports =3D QTAILQ_HEAD_I= NITIALIZER(exports); * as selected by NBD_OPT_SET_META_CONTEXT. Also used for * NBD_OPT_LIST_META_CONTEXT. */ typedef struct NBDExportMetaContexts { - char export_name[NBD_MAX_NAME_SIZE + 1]; + NBDExport *exp; bool valid; /* means that negotiation of the option finished without errors */ bool base_allocation; /* export base:allocation context (block status)= */ @@ -399,10 +399,9 @@ static int nbd_negotiate_handle_list(NBDClient *client= , Error **errp) return nbd_negotiate_send_rep(client, NBD_REP_ACK, errp); } =20 -static void nbd_check_meta_export_name(NBDClient *client) +static void nbd_check_meta_export(NBDClient *client) { - client->export_meta.valid &=3D !strcmp(client->exp->name, - client->export_meta.export_name); + client->export_meta.valid &=3D client->exp =3D=3D client->export_meta.= exp; } =20 /* Send a reply to NBD_OPT_EXPORT_NAME. @@ -456,7 +455,7 @@ static int nbd_negotiate_handle_export_name(NBDClient *= client, =20 QTAILQ_INSERT_TAIL(&client->exp->clients, client, next); nbd_export_get(client->exp); - nbd_check_meta_export_name(client); + nbd_check_meta_export(client); =20 return 0; } @@ -650,7 +649,7 @@ static int nbd_negotiate_handle_info(NBDClient *client,= uint16_t myflags, client->exp =3D exp; QTAILQ_INSERT_TAIL(&client->exp->clients, client, next); nbd_export_get(client->exp); - nbd_check_meta_export_name(client); + nbd_check_meta_export(client); rc =3D 1; } return rc; @@ -834,7 +833,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client, NBDExportMetaContexts *meta, Error *= *errp) { int ret; - NBDExport *exp; + char export_name[NBD_MAX_NAME_SIZE + 1]; NBDExportMetaContexts local_meta; uint32_t nb_queries; int i; @@ -853,15 +852,15 @@ static int nbd_negotiate_meta_queries(NBDClient *clie= nt, =20 memset(meta, 0, sizeof(*meta)); =20 - ret =3D nbd_opt_read_name(client, meta->export_name, NULL, errp); + ret =3D nbd_opt_read_name(client, export_name, NULL, errp); if (ret <=3D 0) { return ret; } =20 - exp =3D nbd_export_find(meta->export_name); - if (exp =3D=3D NULL) { + meta->exp =3D nbd_export_find(export_name); + if (meta->exp =3D=3D NULL) { return nbd_opt_drop(client, NBD_REP_ERR_UNKNOWN, errp, - "export '%s' not present", meta->export_name); + "export '%s' not present", export_name); } =20 ret =3D nbd_opt_read(client, &nb_queries, sizeof(nb_queries), errp); @@ -870,7 +869,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client, } cpu_to_be32s(&nb_queries); trace_nbd_negotiate_meta_context(nbd_opt_lookup(client->opt), - meta->export_name, nb_queries); + export_name, nb_queries); =20 if (client->opt =3D=3D NBD_OPT_LIST_META_CONTEXT && !nb_queries) { /* enable all known contexts */ --=20 2.11.1 From nobody Sat Apr 27 13:45:46 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1528557742239613.8367025182994; Sat, 9 Jun 2018 08:22:22 -0700 (PDT) Received: from localhost ([::1]:40647 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRfh7-0005kL-FL for importer@patchew.org; Sat, 09 Jun 2018 11:22:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36200) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRfd0-0002y6-Ko for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fRfcx-000528-FT for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:06 -0400 Received: from relay.sw.ru ([195.214.232.25]:51914) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fRfcx-00050b-5m for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:03 -0400 Received: from msk-vpn.virtuozzo.com ([195.214.232.6] helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.90_1) (envelope-from ) id 1fRfct-0006t9-QE; Sat, 09 Jun 2018 18:17:59 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Sat, 9 Jun 2018 18:17:55 +0300 Message-Id: <20180609151758.17343-4-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20180609151758.17343-1-vsementsov@virtuozzo.com> References: <20180609151758.17343-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v5 3/6] nbd/server: add nbd_meta_empty_or_pattern helper 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add nbd_meta_pattern() and nbd_meta_empty_or_pattern() helpers for metadata query parsing. nbd_meta_pattern() will be reused for "qemu" namespace in following patches. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- nbd/server.c | 86 +++++++++++++++++++++++++++++++++++++++++---------------= ---- 1 file changed, 59 insertions(+), 27 deletions(-) diff --git a/nbd/server.c b/nbd/server.c index 567561a77e..2d762d7289 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -733,52 +733,83 @@ static int nbd_negotiate_send_meta_context(NBDClient = *client, return qio_channel_writev_all(client->ioc, iov, 2, errp) < 0 ? -EIO : = 0; } =20 -/* nbd_meta_base_query - * - * Handle query to 'base' namespace. For now, only base:allocation context= is - * available in it. 'len' is the amount of text remaining to be read from - * the current name, after the 'base:' portion has been stripped. +/* Read strlen(@pattern) bytes, and set @match to true if they match @patt= ern. + * @match is never set to false. * * Return -errno on I/O error, 0 if option was completely handled by * sending a reply about inconsistent lengths, or 1 on success. * - * Note: return code =3D 1 doesn't mean that we've parsed "base:allocation" - * namespace. It only means that there are no errors.*/ -static int nbd_meta_base_query(NBDClient *client, NBDExportMetaContexts *m= eta, - uint32_t len, Error **errp) + * Note: return code =3D 1 doesn't mean that we've read exactly @pattern + * It only means that there are no errors. */ +static int nbd_meta_pattern(NBDClient *client, const char *pattern, bool *= match, + Error **errp) { int ret; - char query[sizeof("allocation") - 1]; - size_t alen =3D strlen("allocation"); + char *query; + int len =3D strlen(pattern); =20 - if (len =3D=3D 0) { - if (client->opt =3D=3D NBD_OPT_LIST_META_CONTEXT) { - meta->base_allocation =3D true; - } - trace_nbd_negotiate_meta_query_parse("base:"); - return 1; - } - - if (len !=3D alen) { - trace_nbd_negotiate_meta_query_skip("not base:allocation"); - return nbd_opt_skip(client, len, errp); - } + assert(len); =20 + query =3D g_malloc(len); ret =3D nbd_opt_read(client, query, len, errp); if (ret <=3D 0) { + g_free(query); return ret; } =20 - if (strncmp(query, "allocation", alen) =3D=3D 0) { - trace_nbd_negotiate_meta_query_parse("base:allocation"); - meta->base_allocation =3D true; + if (strncmp(query, pattern, len) =3D=3D 0) { + trace_nbd_negotiate_meta_query_parse(pattern); + *match =3D true; } else { - trace_nbd_negotiate_meta_query_skip("not base:allocation"); + trace_nbd_negotiate_meta_query_skip(pattern); } + g_free(query); =20 return 1; } =20 +/* Read @len bytes, and set @match to true if they match @pattern, or if @= len + * is 0 and the client is performing _LIST_. @match is never set to false. + * + * Return -errno on I/O error, 0 if option was completely handled by + * sending a reply about inconsistent lengths, or 1 on success. + * + * Note: return code =3D 1 doesn't mean that we've read exactly @pattern + * It only means that there are no errors. */ +static int nbd_meta_empty_or_pattern(NBDClient *client, const char *patter= n, + uint32_t len, bool *match, Error **er= rp) +{ + if (len =3D=3D 0) { + if (client->opt =3D=3D NBD_OPT_LIST_META_CONTEXT) { + *match =3D true; + } + trace_nbd_negotiate_meta_query_parse("empty"); + return 1; + } + + if (len !=3D strlen(pattern)) { + trace_nbd_negotiate_meta_query_skip("different lengths"); + return nbd_opt_skip(client, len, errp); + } + + return nbd_meta_pattern(client, pattern, match, errp); +} + +/* nbd_meta_base_query + * + * Handle query to 'base' namespace. For now, only base:allocation context= is + * available in it. 'len' is the amount of text remaining to be read from + * the current name, after the 'base:' portion has been stripped. + * + * Return -errno on I/O error, 0 if option was completely handled by + * sending a reply about inconsistent lengths, or 1 on success. */ +static int nbd_meta_base_query(NBDClient *client, NBDExportMetaContexts *m= eta, + uint32_t len, Error **errp) +{ + return nbd_meta_empty_or_pattern(client, "allocation", len, + &meta->base_allocation, errp); +} + /* nbd_negotiate_meta_query * * Parse namespace name and call corresponding function to parse body of t= he @@ -822,6 +853,7 @@ static int nbd_negotiate_meta_query(NBDClient *client, return nbd_opt_skip(client, len, errp); } =20 + trace_nbd_negotiate_meta_query_parse("base:"); return nbd_meta_base_query(client, meta, len, errp); } =20 --=20 2.11.1 From nobody Sat Apr 27 13:45:46 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1528557850178800.9417255761504; Sat, 9 Jun 2018 08:24:10 -0700 (PDT) Received: from localhost ([::1]:40654 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRfir-00078C-Ee for importer@patchew.org; Sat, 09 Jun 2018 11:24:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36197) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRfd0-0002y4-Ju for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fRfcx-00052L-JE for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:06 -0400 Received: from relay.sw.ru ([195.214.232.25]:51910) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fRfcx-00050a-5U for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:03 -0400 Received: from msk-vpn.virtuozzo.com ([195.214.232.6] helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.90_1) (envelope-from ) id 1fRfcu-0006t9-1E; Sat, 09 Jun 2018 18:18:00 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Sat, 9 Jun 2018 18:17:56 +0300 Message-Id: <20180609151758.17343-5-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20180609151758.17343-1-vsementsov@virtuozzo.com> References: <20180609151758.17343-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v5 4/6] nbd/server: implement dirty bitmap export 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Handle new NBD meta namespace: "qemu", and corresponding queries: "qemu:dirty-bitmap:". With new metadata context negotiated, BLOCK_STATUS query will reply with dirty-bitmap data, converted to extents. New public function nbd_export_bitmap selects bitmap to export. For now, only one bitmap may be exported. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- include/block/nbd.h | 6 ++ nbd/server.c | 271 ++++++++++++++++++++++++++++++++++++++++++++++++= ---- 2 files changed, 259 insertions(+), 18 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index fcdcd54502..a653d0fba7 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -234,6 +234,10 @@ enum { #define NBD_STATE_HOLE (1 << 0) #define NBD_STATE_ZERO (1 << 1) =20 +/* Flags for extents (NBDExtent.flags) of NBD_REPLY_TYPE_BLOCK_STATUS, + * for qemu:dirty-bitmap:* meta contexts */ +#define NBD_STATE_DIRTY (1 << 0) + static inline bool nbd_reply_type_is_error(int type) { return type & (1 << 15); @@ -315,6 +319,8 @@ void nbd_client_put(NBDClient *client); void nbd_server_start(SocketAddress *addr, const char *tls_creds, Error **errp); =20 +void nbd_export_bitmap(NBDExport *exp, const char *bitmap, + const char *bitmap_export_name, Error **errp); =20 /* nbd_read * Reads @size bytes from @ioc. Returns 0 on success. diff --git a/nbd/server.c b/nbd/server.c index 2d762d7289..569e068fc2 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -23,6 +23,12 @@ #include "nbd-internal.h" =20 #define NBD_META_ID_BASE_ALLOCATION 0 +#define NBD_META_ID_DIRTY_BITMAP 1 + +/* NBD_MAX_BITMAP_EXTENTS: 1 mb of extents data. An empirical constant. If= need + * to increase, note that NBD protocol defines 32 mb as a limit, after whi= ch the + * reply may be considered as a denial of service attack. */ +#define NBD_MAX_BITMAP_EXTENTS (0x100000 / 8) =20 static int system_errno_to_nbd_errno(int err) { @@ -80,6 +86,9 @@ struct NBDExport { =20 BlockBackend *eject_notifier_blk; Notifier eject_notifier; + + BdrvDirtyBitmap *export_bitmap; + char *export_bitmap_context; }; =20 static QTAILQ_HEAD(, NBDExport) exports =3D QTAILQ_HEAD_INITIALIZER(export= s); @@ -92,6 +101,7 @@ typedef struct NBDExportMetaContexts { bool valid; /* means that negotiation of the option finished without errors */ bool base_allocation; /* export base:allocation context (block status)= */ + bool dirty_bitmap; /* export qemu:dirty-bitmap: */ } NBDExportMetaContexts; =20 struct NBDClient { @@ -810,6 +820,55 @@ static int nbd_meta_base_query(NBDClient *client, NBDE= xportMetaContexts *meta, &meta->base_allocation, errp); } =20 +/* nbd_meta_bitmap_query + * + * Handle query to 'qemu:' namespace. + * @len is the amount of text remaining to be read from the current name, = after + * the 'qemu:' portion has been stripped. + * + * Return -errno on I/O error, 0 if option was completely handled by + * sending a reply about inconsistent lengths, or 1 on success. */ +static int nbd_meta_qemu_query(NBDClient *client, NBDExportMetaContexts *m= eta, + uint32_t len, Error **errp) +{ + bool dirty_bitmap =3D false; + int dirty_bitmap_len =3D strlen("dirty-bitmap:"); + int ret; + + if (!meta->exp->export_bitmap) { + return nbd_opt_skip(client, len, errp); + } + + if (len =3D=3D 0) { + if (client->opt =3D=3D NBD_OPT_LIST_META_CONTEXT) { + meta->dirty_bitmap =3D true; + } + trace_nbd_negotiate_meta_query_parse("empty"); + return 1; + } + + if (len < dirty_bitmap_len) { + trace_nbd_negotiate_meta_query_skip("not dirty-bitmap:"); + return nbd_opt_skip(client, len, errp); + } + + len -=3D dirty_bitmap_len; + ret =3D nbd_meta_pattern(client, "dirty-bitmap:", &dirty_bitmap, errp); + if (ret <=3D 0) { + return ret; + } + if (!dirty_bitmap) { + trace_nbd_negotiate_meta_query_skip("not dirty-bitmap:"); + return nbd_opt_skip(client, len, errp); + } + + trace_nbd_negotiate_meta_query_parse("dirty-bitmap:"); + + return nbd_meta_empty_or_pattern( + client, meta->exp->export_bitmap_context + + strlen("qemu:dirty_bitmap:"), len, &meta->dirty_bitmap, errp); +} + /* nbd_negotiate_meta_query * * Parse namespace name and call corresponding function to parse body of t= he @@ -826,8 +885,10 @@ static int nbd_negotiate_meta_query(NBDClient *client, NBDExportMetaContexts *meta, Error **e= rrp) { int ret; - char query[sizeof("base:") - 1]; - size_t baselen =3D strlen("base:"); + size_t ns_len =3D 5; + char ns[5]; /* Both 'qemu' and 'base' namespaces have length =3D 5 inc= luding a + colon. If it's needed to introduce a namespace of the o= ther + length, this should be certainly refactored. */ uint32_t len; =20 ret =3D nbd_opt_read(client, &len, sizeof(len), errp); @@ -836,25 +897,27 @@ static int nbd_negotiate_meta_query(NBDClient *client, } cpu_to_be32s(&len); =20 - /* The only supported namespace for now is 'base'. So query should sta= rt - * with 'base:'. Otherwise, we can ignore it and skip the remainder. */ - if (len < baselen) { + if (len < ns_len) { trace_nbd_negotiate_meta_query_skip("length too short"); return nbd_opt_skip(client, len, errp); } =20 - len -=3D baselen; - ret =3D nbd_opt_read(client, query, baselen, errp); + len -=3D ns_len; + ret =3D nbd_opt_read(client, ns, ns_len, errp); if (ret <=3D 0) { return ret; } - if (strncmp(query, "base:", baselen) !=3D 0) { - trace_nbd_negotiate_meta_query_skip("not for base: namespace"); - return nbd_opt_skip(client, len, errp); + + if (!strncmp(ns, "base:", ns_len)) { + trace_nbd_negotiate_meta_query_parse("base:"); + return nbd_meta_base_query(client, meta, len, errp); + } else if (!strncmp(ns, "qemu:", ns_len)) { + trace_nbd_negotiate_meta_query_parse("qemu:"); + return nbd_meta_qemu_query(client, meta, len, errp); } =20 - trace_nbd_negotiate_meta_query_parse("base:"); - return nbd_meta_base_query(client, meta, len, errp); + trace_nbd_negotiate_meta_query_skip("unknown namespace"); + return nbd_opt_skip(client, len, errp); } =20 /* nbd_negotiate_meta_queries @@ -924,6 +987,16 @@ static int nbd_negotiate_meta_queries(NBDClient *clien= t, } } =20 + if (meta->dirty_bitmap) { + ret =3D nbd_negotiate_send_meta_context(client, + meta->exp->export_bitmap_con= text, + NBD_META_ID_DIRTY_BITMAP, + errp); + if (ret < 0) { + return ret; + } + } + ret =3D nbd_negotiate_send_rep(client, NBD_REP_ACK, errp); if (ret =3D=3D 0) { meta->valid =3D true; @@ -1552,6 +1625,11 @@ void nbd_export_put(NBDExport *exp) exp->blk =3D NULL; } =20 + if (exp->export_bitmap) { + bdrv_dirty_bitmap_set_qmp_locked(exp->export_bitmap, false); + g_free(exp->export_bitmap_context); + } + g_free(exp); } } @@ -1793,6 +1871,9 @@ static int blockstatus_to_extent_be(BlockDriverState = *bs, uint64_t offset, } =20 /* nbd_co_send_extents + * + * NBD_REPLY_FLAG_DONE is not set, don't forget to send it. + * * @extents should be in big-endian */ static int nbd_co_send_extents(NBDClient *client, uint64_t handle, NBDExtent *extents, unsigned nb_extents, @@ -1805,7 +1886,7 @@ static int nbd_co_send_extents(NBDClient *client, uin= t64_t handle, {.iov_base =3D extents, .iov_len =3D nb_extents * sizeof(extents[0= ])} }; =20 - set_be_chunk(&chunk.h, NBD_REPLY_FLAG_DONE, NBD_REPLY_TYPE_BLOCK_STATU= S, + set_be_chunk(&chunk.h, 0, NBD_REPLY_TYPE_BLOCK_STATUS, handle, sizeof(chunk) - sizeof(chunk.h) + iov[1].iov_len); stl_be_p(&chunk.context_id, context_id); =20 @@ -1830,6 +1911,97 @@ static int nbd_co_send_block_status(NBDClient *clien= t, uint64_t handle, return nbd_co_send_extents(client, handle, &extent, 1, context_id, err= p); } =20 +/* Set several extents, describing region of given @length with given @fla= gs. + * Do not set more than @nb_extents, return number of set extents. + */ +static unsigned add_extents(NBDExtent *extents, unsigned nb_extents, + uint64_t length, uint32_t flags) +{ + unsigned i =3D 0; + uint32_t max_extent =3D QEMU_ALIGN_DOWN(INT32_MAX, BDRV_SECTOR_SIZE); + uint32_t max_extent_be =3D cpu_to_be32(max_extent); + uint32_t flags_be =3D cpu_to_be32(flags); + + for (i =3D 0; i < nb_extents && length > max_extent; + i++, length -=3D max_extent) + { + extents[i].length =3D max_extent_be; + extents[i].flags =3D flags_be; + } + + if (length > 0 && i < nb_extents) { + extents[i].length =3D cpu_to_be32(length); + extents[i].flags =3D flags_be; + i++; + } + + return i; +} + +static unsigned bitmap_to_extents(BdrvDirtyBitmap *bitmap, uint64_t offset, + uint64_t length, NBDExtent *extents, + unsigned nb_extents, bool dont_fragment) +{ + uint64_t begin =3D offset, end; + uint64_t overall_end =3D offset + length; + unsigned i =3D 0; + BdrvDirtyBitmapIter *it; + bool dirty; + + bdrv_dirty_bitmap_lock(bitmap); + + it =3D bdrv_dirty_iter_new(bitmap); + dirty =3D bdrv_get_dirty_locked(NULL, bitmap, offset); + + while (begin < overall_end && i < nb_extents) { + if (dirty) { + end =3D bdrv_dirty_bitmap_next_zero(bitmap, begin); + } else { + bdrv_set_dirty_iter(it, begin); + end =3D bdrv_dirty_iter_next(it); + } + if (end =3D=3D -1) { + end =3D bdrv_dirty_bitmap_size(bitmap); + } + if (dont_fragment && end > overall_end) { + /* We MUST not exceed requested region if NBD_CMD_FLAG_REQ_ONE= flag + * is set */ + end =3D overall_end; + } + + i +=3D add_extents(extents + i, nb_extents - i, end - begin, + dirty ? NBD_STATE_DIRTY : 0); + begin =3D end; + dirty =3D !dirty; + } + + bdrv_dirty_iter_free(it); + + bdrv_dirty_bitmap_unlock(bitmap); + + return i; +} + +static int nbd_co_send_bitmap(NBDClient *client, uint64_t handle, + BdrvDirtyBitmap *bitmap, uint64_t offset, + uint64_t length, bool dont_fragment, + uint32_t context_id, Error **errp) +{ + int ret; + unsigned nb_extents =3D dont_fragment ? 1 : NBD_MAX_BITMAP_EXTENTS; + NBDExtent *extents =3D g_new(NBDExtent, nb_extents); + + nb_extents =3D bitmap_to_extents(bitmap, offset, length, extents, nb_e= xtents, + dont_fragment); + + ret =3D nbd_co_send_extents(client, handle, extents, nb_extents, conte= xt_id, + errp); + + g_free(extents); + + return ret; +} + /* nbd_co_receive_request * Collect a client request. Return 0 if request looks valid, -EIO to drop * connection right away, and any other negative value to report an error = to @@ -2043,11 +2215,33 @@ static coroutine_fn int nbd_handle_request(NBDClien= t *client, "discard failed", errp); =20 case NBD_CMD_BLOCK_STATUS: - if (client->export_meta.valid && client->export_meta.base_allocati= on) { - return nbd_co_send_block_status(client, request->handle, - blk_bs(exp->blk), request->fro= m, - request->len, - NBD_META_ID_BASE_ALLOCATION, e= rrp); + if (client->export_meta.valid && + (client->export_meta.base_allocation || + client->export_meta.dirty_bitmap)) + { + if (client->export_meta.base_allocation) { + ret =3D nbd_co_send_block_status(client, request->handle, + blk_bs(exp->blk), request->= from, + request->len, + NBD_META_ID_BASE_ALLOCATION, + errp); + if (ret < 0) { + return ret; + } + } + + if (client->export_meta.dirty_bitmap) { + ret =3D nbd_co_send_bitmap(client, request->handle, + client->exp->export_bitmap, + request->from, request->len, + request->flags & NBD_CMD_FLAG_REQ= _ONE, + NBD_META_ID_DIRTY_BITMAP, errp); + if (ret < 0) { + return ret; + } + } + + return nbd_co_send_structured_done(client, request->handle, er= rp); } else { return nbd_send_generic_reply(client, request->handle, -EINVAL, "CMD_BLOCK_STATUS not negotiated= ", @@ -2199,3 +2393,44 @@ void nbd_client_new(NBDExport *exp, co =3D qemu_coroutine_create(nbd_co_client_start, client); qemu_coroutine_enter(co); } + +void nbd_export_bitmap(NBDExport *exp, const char *bitmap, + const char *bitmap_export_name, Error **errp) +{ + BdrvDirtyBitmap *bm =3D NULL; + BlockDriverState *bs =3D blk_bs(exp->blk); + + if (exp->export_bitmap) { + error_setg(errp, "Export bitmap is already set"); + return; + } + + while (true) { + bm =3D bdrv_find_dirty_bitmap(bs, bitmap); + if (bm !=3D NULL || bs->backing =3D=3D NULL) { + break; + } + + bs =3D bs->backing->bs; + } + + if (bm =3D=3D NULL) { + error_setg(errp, "Bitmap '%s' is not found", bitmap); + return; + } + + if (bdrv_dirty_bitmap_enabled(bm)) { + error_setg(errp, "Bitmap '%s' is enabled", bitmap); + return; + } + + if (bdrv_dirty_bitmap_qmp_locked(bm)) { + error_setg(errp, "Bitmap '%s' is locked", bitmap); + return; + } + + bdrv_dirty_bitmap_set_qmp_locked(bm, true); + exp->export_bitmap =3D bm; + exp->export_bitmap_context =3D + g_strdup_printf("qemu:dirty-bitmap:%s", bitmap_export_name); +} --=20 2.11.1 From nobody Sat Apr 27 13:45:46 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1528557610569123.4398775183588; Sat, 9 Jun 2018 08:20:10 -0700 (PDT) Received: from localhost ([::1]:40630 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRfer-0003t1-1A for importer@patchew.org; Sat, 09 Jun 2018 11:20:01 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36198) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRfd0-0002y5-K6 for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fRfcx-000520-FR for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:06 -0400 Received: from relay.sw.ru ([195.214.232.25]:51904) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fRfcx-00050d-5w for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:03 -0400 Received: from msk-vpn.virtuozzo.com ([195.214.232.6] helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.90_1) (envelope-from ) id 1fRfcu-0006t9-5i; Sat, 09 Jun 2018 18:18:00 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Sat, 9 Jun 2018 18:17:57 +0300 Message-Id: <20180609151758.17343-6-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20180609151758.17343-1-vsementsov@virtuozzo.com> References: <20180609151758.17343-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v5 5/6] qapi: new qmp command nbd-server-add-bitmap 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- qapi/block.json | 23 +++++++++++++++++++++++ blockdev-nbd.c | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/qapi/block.json b/qapi/block.json index c694524002..ddbca2e286 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -269,6 +269,29 @@ 'data': {'name': 'str', '*mode': 'NbdServerRemoveMode'} } =20 ## +# @nbd-server-add-bitmap: +# +# Expose a dirty bitmap associated with the selected export. The bitmap se= arch +# starts at the device attached to the export, and includes all backing fi= les. +# The exported bitmap is then locked until the NBD export is removed. +# +# @name: Export name. +# +# @bitmap: Bitmap name to search for. +# +# @bitmap-export-name: How the bitmap will be seen by nbd clients +# (default @bitmap) +# +# Note: the client must use NBD_OPT_SET_META_CONTEXT with a query of +# "qemu:dirty-bitmap:NAME" (where NAME matches @bitmap-export-name) to acc= ess +# the exposed bitmap. +# +# Since: 3.0 +## + { 'command': 'nbd-server-add-bitmap', + 'data': {'name': 'str', 'bitmap': 'str', '*bitmap-export-name': 'str'}= } + +## # @nbd-server-stop: # # Stop QEMU's embedded NBD server, and unregister all devices previously diff --git a/blockdev-nbd.c b/blockdev-nbd.c index 65a84739ed..6b0c50732c 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -220,3 +220,26 @@ void qmp_nbd_server_stop(Error **errp) nbd_server_free(nbd_server); nbd_server =3D NULL; } + +void qmp_nbd_server_add_bitmap(const char *name, const char *bitmap, + bool has_bitmap_export_name, + const char *bitmap_export_name, + Error **errp) +{ + NBDExport *exp; + + if (!nbd_server) { + error_setg(errp, "NBD server not running"); + return; + } + + exp =3D nbd_export_find(name); + if (exp =3D=3D NULL) { + error_setg(errp, "Export '%s' is not found", name); + return; + } + + nbd_export_bitmap(exp, bitmap, + has_bitmap_export_name ? bitmap_export_name : bitmap, + errp); +} --=20 2.11.1 From nobody Sat Apr 27 13:45:46 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 152855761294763.146110608344884; Sat, 9 Jun 2018 08:20:12 -0700 (PDT) Received: from localhost ([::1]:40628 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRfep-0003s9-IN for importer@patchew.org; Sat, 09 Jun 2018 11:19:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36192) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRfd0-0002y1-Hx for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fRfcx-00052E-G5 for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:06 -0400 Received: from relay.sw.ru ([195.214.232.25]:51908) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fRfcx-00050Y-5r for qemu-devel@nongnu.org; Sat, 09 Jun 2018 11:18:03 -0400 Received: from msk-vpn.virtuozzo.com ([195.214.232.6] helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.90_1) (envelope-from ) id 1fRfcu-0006t9-AO; Sat, 09 Jun 2018 18:18:00 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Sat, 9 Jun 2018 18:17:58 +0300 Message-Id: <20180609151758.17343-7-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20180609151758.17343-1-vsementsov@virtuozzo.com> References: <20180609151758.17343-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v5 6/6] docs/interop: add nbd.txt 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Describe new metadata namespace: "qemu". Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- docs/interop/nbd.txt | 37 +++++++++++++++++++++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 38 insertions(+) create mode 100644 docs/interop/nbd.txt diff --git a/docs/interop/nbd.txt b/docs/interop/nbd.txt new file mode 100644 index 0000000000..7366269fc0 --- /dev/null +++ b/docs/interop/nbd.txt @@ -0,0 +1,37 @@ +Qemu supports NBD protocol, and has internal NBD client (look at +block/nbd.c), internal NBD server (look at blockdev-nbd.c) as well as +external NBD server tool - qemu-nbd.c. The common code is placed in +nbd/*. + +NBD protocol is specified here: +https://github.com/NetworkBlockDevice/nbd/blob/master/doc/proto.md + +This following paragraphs describe some specific properties of NBD +protocol realization in Qemu. + + +=3D Metadata namespaces =3D + +Qemu supports "base:allocation" metadata context as defined in the NBD +protocol specification and defines own metadata namespace: "qemu". + + +=3D=3D "qemu" namespace =3D=3D + +For now, the only type of metadata context in the namespace is dirty +bitmap. All available metadata contexts have the following form: + + qemu:dirty-bitmap: + +Each dirty-bitmap metadata context defines the only one flag for +extents in reply for NBD_CMD_BLOCK_STATUS: + + bit 0: NBD_STATE_DIRTY, means that the extent is "dirty" + +For NBD_OPT_LIST_META_CONTEXT the following queries are supported +additionally to "qemu:dirty-bitmap:": + +* "qemu:" : returns list of all available metadata contexts in the + namespace. +* "qemu:dirty-bitmap:" : returns list of all available dirty-bitmap + metadata contexts. diff --git a/MAINTAINERS b/MAINTAINERS index e187b1f18f..887b479440 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1923,6 +1923,7 @@ F: nbd/ F: include/block/nbd* F: qemu-nbd.* F: blockdev-nbd.c +F: docs/interop/nbd.txt T: git git://repo.or.cz/qemu/ericb.git nbd =20 NFS --=20 2.11.1