From patchwork Thu Oct 15 14:49:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 11839477 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3126061C for ; Thu, 15 Oct 2020 14:53:04 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D37D421D7F for ; Thu, 15 Oct 2020 14:53:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="WACCL2sM" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D37D421D7F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:40770 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kT4co-0008AG-PL for patchwork-qemu-devel@patchwork.kernel.org; Thu, 15 Oct 2020 10:53:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42112) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kT4Zw-0004CA-OL for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:04 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:41478) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kT4Zu-0001fV-T1 for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1602773401; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aLpNJpWPYwwF01s/Lhok3fVvRwYNbm36mgvYFogFwDM=; b=WACCL2sMyW52pkpFGsBDbB8gqDSpopja1CmJAdHbaaGeMOE/gQTkJwTilcO2FgbBPEabYs 8U+2bs/iK34j6XWxSQQxX6ZuTOKba9yL0pxtNw8wBzy7v9Cz1YZ7k8Yb2TO/7I5d4LZERH NSm46dFA2jODmI796RKA6vDQK426z4k= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-284-2qn1dOYcMbKRcrJbJgffcA-1; Thu, 15 Oct 2020 10:49:59 -0400 X-MC-Unique: 2qn1dOYcMbKRcrJbJgffcA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 935F780F05B; Thu, 15 Oct 2020 14:49:58 +0000 (UTC) Received: from merkur.redhat.com (ovpn-114-163.ams2.redhat.com [10.36.114.163]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9CACF610F3; Thu, 15 Oct 2020 14:49:57 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PULL 01/10] keyval: Fix and clarify grammar Date: Thu, 15 Oct 2020 16:49:43 +0200 Message-Id: <20201015144952.388043-2-kwolf@redhat.com> In-Reply-To: <20201015144952.388043-1-kwolf@redhat.com> References: <20201015144952.388043-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/15 02:10:02 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Markus Armbruster The grammar has a few issues: * key-fragment = / [^=,.]* / Prose restricts key fragments: they "must be valid QAPI names or consist only of decimal digits". Technically, '' consists only of decimal digits. The code rejects that. Fix the grammar. * val = { / [^,]* / | ',,' } Use + instead of *. Accepts the same language. * val-no-key = / [^=,]* / The code rejects an empty value. Fix the grammar. * Section "Additional syntax for use with an implied key" is confusing. Rewrite it. Signed-off-by: Markus Armbruster Message-Id: <20201011073505.1185335-2-armbru@redhat.com> Reviewed-by: Eric Blake Signed-off-by: Kevin Wolf --- util/keyval.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/util/keyval.c b/util/keyval.c index 13def4af54..82d8497c71 100644 --- a/util/keyval.c +++ b/util/keyval.c @@ -16,8 +16,8 @@ * key-vals = [ key-val { ',' key-val } [ ',' ] ] * key-val = key '=' val * key = key-fragment { '.' key-fragment } - * key-fragment = / [^=,.]* / - * val = { / [^,]* / | ',,' } + * key-fragment = / [^=,.]+ / + * val = { / [^,]+ / | ',,' } * * Semantics defined by reduction to JSON: * @@ -71,12 +71,16 @@ * Awkward. Note that we carefully restrict alternate types to avoid * similar ambiguity. * - * Additional syntax for use with an implied key: + * Alternative syntax for use with an implied key: * - * key-vals-ik = val-no-key [ ',' key-vals ] - * val-no-key = / [^=,]* / + * key-vals = [ key-val-1st { ',' key-val } [ ',' ] ] + * key-val-1st = val-no-key | key-val + * val-no-key = / [^=,]+ / * - * where no-key is syntactic sugar for implied-key=val-no-key. + * where val-no-key is syntactic sugar for implied-key=val-no-key. + * + * Note that you can't use the sugared form when the value contains + * '=' or ','. */ #include "qemu/osdep.h" From patchwork Thu Oct 15 14:49:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 11839483 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7D7381744 for ; Thu, 15 Oct 2020 14:55:35 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2CC6F21D7F for ; Thu, 15 Oct 2020 14:55:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Aja3fcRS" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2CC6F21D7F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:49800 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kT4fF-0003TI-Rk for patchwork-qemu-devel@patchwork.kernel.org; Thu, 15 Oct 2020 10:55:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42134) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kT4Zy-0004GU-9N for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:06 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:47177) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kT4Zw-0001ft-EX for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1602773403; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CAzM3xN0eH5jPpu7uj/EOlr7aJNHU+juElBpoQ+Xkog=; b=Aja3fcRStS/0abTMzCViqZFPHMdcCfXjqdqZPx0/svccAV17pRwHouMR8lQPiir381DTXO JwqK/g2T+DxI8dzRO4Xn9hxshc+lVhIUz3ntWzggpCODDbDET/b6bCZZK17HZ20489TxWM JJMmSYusApl694JYzOv6fhRlnPRPqJ4= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-382-QRMOW4GqOgCIcgjuCB0Jqw-1; Thu, 15 Oct 2020 10:50:01 -0400 X-MC-Unique: QRMOW4GqOgCIcgjuCB0Jqw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E8918108E1A2; Thu, 15 Oct 2020 14:49:59 +0000 (UTC) Received: from merkur.redhat.com (ovpn-114-163.ams2.redhat.com [10.36.114.163]) by smtp.corp.redhat.com (Postfix) with ESMTP id DCFD5610F3; Thu, 15 Oct 2020 14:49:58 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PULL 02/10] test-keyval: Demonstrate misparse of ', ' with implied key Date: Thu, 15 Oct 2020 16:49:44 +0200 Message-Id: <20201015144952.388043-3-kwolf@redhat.com> In-Reply-To: <20201015144952.388043-1-kwolf@redhat.com> References: <20201015144952.388043-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/15 02:10:02 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Markus Armbruster Add a test for "val,,ue" with implied key. Documentation says this should parse as implied key with value "val", then fail. The code parses it as implied key with value "val,ue", then succeeds. The next commit will fix it. Signed-off-by: Markus Armbruster Message-Id: <20201011073505.1185335-3-armbru@redhat.com> Reviewed-by: Eric Blake Signed-off-by: Kevin Wolf --- tests/test-keyval.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test-keyval.c b/tests/test-keyval.c index e331a84149..f02bdf7029 100644 --- a/tests/test-keyval.c +++ b/tests/test-keyval.c @@ -182,6 +182,13 @@ static void test_keyval_parse(void) error_free_or_abort(&err); g_assert(!qdict); + /* Implied key's value can't have comma (qemu_opts_parse(): it can) */ + /* BUG: it can */ + qdict = keyval_parse("val,,ue", "implied", &error_abort); + g_assert_cmpuint(qdict_size(qdict), ==, 1); + g_assert_cmpstr(qdict_get_try_str(qdict, "implied"), ==, "val,ue"); + qobject_unref(qdict); + /* Empty key is not an implied key */ qdict = keyval_parse("=val", "implied", &err); error_free_or_abort(&err); From patchwork Thu Oct 15 14:49:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 11839471 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D477561C for ; Thu, 15 Oct 2020 14:51:23 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7D17D218AC for ; Thu, 15 Oct 2020 14:51:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="WuH51WG8" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7D17D218AC Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:36464 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kT4bC-0006Mc-2I for patchwork-qemu-devel@patchwork.kernel.org; Thu, 15 Oct 2020 10:51:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42198) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kT4a3-0004Rj-3b for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:11 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:55811) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kT4a0-0001gb-Oh for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1602773407; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/SXUmCEhY1AzXAp8XV7L9M0SIngTLHvxTqdy/zzvKo0=; b=WuH51WG8A2Ujvsu/8XiYVArm83ij9PoRKjNS3SjQfosEDwi8j27wIgZR7GwL4WALdIh7KI Cds3lQIDJw5s9u39z4KpxZkv1MrzMczqs+QUnaC1vy71HlO8caHlCFXgRm7DN6A06FRrBc vK6eyOUlIadDpaNuqxzb8kmOpBLldFk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-419-nQdkb35rOYqg8bAsic7HQw-1; Thu, 15 Oct 2020 10:50:05 -0400 X-MC-Unique: nQdkb35rOYqg8bAsic7HQw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 5985C18C520C; Thu, 15 Oct 2020 14:50:04 +0000 (UTC) Received: from merkur.redhat.com (ovpn-114-163.ams2.redhat.com [10.36.114.163]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3E29E610F3; Thu, 15 Oct 2020 14:50:00 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PULL 03/10] keyval: Fix parsing of ',' in value of implied key Date: Thu, 15 Oct 2020 16:49:45 +0200 Message-Id: <20201015144952.388043-4-kwolf@redhat.com> In-Reply-To: <20201015144952.388043-1-kwolf@redhat.com> References: <20201015144952.388043-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/15 02:38:26 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Markus Armbruster The previous commit demonstrated documentation and code disagree on parsing of ',' in the value of an implied key. Fix the code to match the documentation. This breaks uses of keyval_parse() that pass an implied key and accept a value containing ','. None of the existing uses does: * audiodev: implied key "driver" is enum AudiodevDriver, none of the values contains ',' * display: implied key "type" is enum DisplayType, none of the values contains ',' * blockdev: implied key "driver is enum BlockdevDriver, none of the values contains ',' * export: implied key "type" is enum BlockExportType, none of the values contains ',' * monitor: implied key "mode" is enum MonitorMode, none of the values contains ',' * nbd-server: no implied key. Signed-off-by: Markus Armbruster Message-Id: <20201011073505.1185335-4-armbru@redhat.com> Reviewed-by: Eric Blake Signed-off-by: Kevin Wolf --- tests/test-keyval.c | 8 +++----- util/keyval.c | 28 +++++++++++++++++----------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/tests/test-keyval.c b/tests/test-keyval.c index f02bdf7029..04c62cf045 100644 --- a/tests/test-keyval.c +++ b/tests/test-keyval.c @@ -183,11 +183,9 @@ static void test_keyval_parse(void) g_assert(!qdict); /* Implied key's value can't have comma (qemu_opts_parse(): it can) */ - /* BUG: it can */ - qdict = keyval_parse("val,,ue", "implied", &error_abort); - g_assert_cmpuint(qdict_size(qdict), ==, 1); - g_assert_cmpstr(qdict_get_try_str(qdict, "implied"), ==, "val,ue"); - qobject_unref(qdict); + qdict = keyval_parse("val,,ue", "implied", &err); + error_free_or_abort(&err); + g_assert(!qdict); /* Empty key is not an implied key */ qdict = keyval_parse("=val", "implied", &err); diff --git a/util/keyval.c b/util/keyval.c index 82d8497c71..8f33a36a7c 100644 --- a/util/keyval.c +++ b/util/keyval.c @@ -173,7 +173,7 @@ static const char *keyval_parse_one(QDict *qdict, const char *params, const char *implied_key, Error **errp) { - const char *key, *key_end, *s, *end; + const char *key, *key_end, *val_end, *s, *end; size_t len; char key_in_cur[128]; QDict *cur; @@ -182,10 +182,12 @@ static const char *keyval_parse_one(QDict *qdict, const char *params, QString *val; key = params; + val_end = NULL; len = strcspn(params, "=,"); if (implied_key && len && key[len] != '=') { /* Desugar implied key */ key = implied_key; + val_end = params + len; len = strlen(implied_key); } key_end = key + len; @@ -241,7 +243,11 @@ static const char *keyval_parse_one(QDict *qdict, const char *params, if (key == implied_key) { assert(!*s); - s = params; + val = qstring_from_substr(params, 0, val_end - params); + s = val_end; + if (*s == ',') { + s++; + } } else { if (*s != '=') { error_setg(errp, "Expected '=' after parameter '%.*s'", @@ -249,19 +255,19 @@ static const char *keyval_parse_one(QDict *qdict, const char *params, return NULL; } s++; - } - val = qstring_new(); - for (;;) { - if (!*s) { - break; - } else if (*s == ',') { - s++; - if (*s != ',') { + val = qstring_new(); + for (;;) { + if (!*s) { break; + } else if (*s == ',') { + s++; + if (*s != ',') { + break; + } } + qstring_append_chr(val, *s++); } - qstring_append_chr(val, *s++); } if (!keyval_parse_put(cur, key_in_cur, val, key, key_end, errp)) { From patchwork Thu Oct 15 14:49:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 11839485 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 188561752 for ; Thu, 15 Oct 2020 14:55:36 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A52B321D7F for ; Thu, 15 Oct 2020 14:55:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="WOuGnA2O" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A52B321D7F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:49772 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kT4fG-0003Sj-JQ for patchwork-qemu-devel@patchwork.kernel.org; Thu, 15 Oct 2020 10:55:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42298) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kT4a8-0004dR-1U for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:16 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:26721) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kT4a3-0001hJ-AX for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1602773410; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rEHVeB1MRDz5mIlipstzuXM1kZNAzZh+p+jLRdkU+Gw=; b=WOuGnA2O4IR40JPvGS9CLkU1tFNYsgcepnsFSExIIckW0ZtAD1Wf+CzfZ4xMdkWEUhowB6 z3GTPcIpo+RyzDTt0D+vyNRtZ/3T7hgFVSkII0bP0HrVpdtytKgD4wQilpuBsbACaECMnb pQUjJi+FhPoVPC5uW/27hS+Di/INA+c= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-553-2kWoZkubO6So8ku9ZbQCNQ-1; Thu, 15 Oct 2020 10:50:07 -0400 X-MC-Unique: 2kWoZkubO6So8ku9ZbQCNQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BD7B91021203; Thu, 15 Oct 2020 14:50:05 +0000 (UTC) Received: from merkur.redhat.com (ovpn-114-163.ams2.redhat.com [10.36.114.163]) by smtp.corp.redhat.com (Postfix) with ESMTP id A181160C07; Thu, 15 Oct 2020 14:50:04 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PULL 04/10] keyval: Parse help options Date: Thu, 15 Oct 2020 16:49:46 +0200 Message-Id: <20201015144952.388043-5-kwolf@redhat.com> In-Reply-To: <20201015144952.388043-1-kwolf@redhat.com> References: <20201015144952.388043-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/15 02:38:26 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This adds a special meaning for 'help' and '?' as options to the keyval parser. Instead of being an error (because of a missing value) or a value for an implied key, they now request help, which is a new boolean output of the parser in addition to the QDict. A new parameter 'p_help' is added to keyval_parse() that contains on return whether help was requested. If NULL is passed, requesting help results in an error and all other cases work like before. Turning previous error cases into help is a compatible extension. The behaviour potentially changes for implied keys: They could previously get 'help' as their value, which is now interpreted as requesting help. This is not a problem in practice because 'help' and '?' are not a valid values for the implied key of any option parsed with keyval_parse(): * audiodev: union Audiodev, implied key "driver" is enum AudiodevDriver, "help" and "?" are not among its values * display: union DisplayOptions, implied key "type" is enum DisplayType, "help" and "?" are not among its values * blockdev: union BlockdevOptions, implied key "driver is enum BlockdevDriver, "help" and "?" are not among its values * export: union BlockExport, implied key "type" is enum BlockExportType, "help" and "?" are not among its values * monitor: struct MonitorOptions, implied key "mode" is enum MonitorMode, "help" and "?" are not among its values * nbd-server: struct NbdServerOptions, no implied key. Signed-off-by: Kevin Wolf Signed-off-by: Markus Armbruster Message-Id: <20201011073505.1185335-5-armbru@redhat.com> Reviewed-by: Eric Blake Signed-off-by: Kevin Wolf --- include/qemu/help_option.h | 11 ++ include/qemu/option.h | 2 +- qapi/qobject-input-visitor.c | 2 +- storage-daemon/qemu-storage-daemon.c | 2 +- tests/test-keyval.c | 183 ++++++++++++++++++--------- util/keyval.c | 63 +++++++-- 6 files changed, 185 insertions(+), 78 deletions(-) diff --git a/include/qemu/help_option.h b/include/qemu/help_option.h index 328d2a89fd..ca6389a154 100644 --- a/include/qemu/help_option.h +++ b/include/qemu/help_option.h @@ -19,4 +19,15 @@ static inline bool is_help_option(const char *s) return !strcmp(s, "?") || !strcmp(s, "help"); } +static inline int starts_with_help_option(const char *s) +{ + if (*s == '?') { + return 1; + } + if (g_str_has_prefix(s, "help")) { + return 4; + } + return 0; +} + #endif diff --git a/include/qemu/option.h b/include/qemu/option.h index 05e8a15c73..ac69352e0e 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -149,6 +149,6 @@ void qemu_opts_free(QemuOptsList *list); QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list); QDict *keyval_parse(const char *params, const char *implied_key, - Error **errp); + bool *help, Error **errp); #endif diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c index f918a05e5f..7b184b50a7 100644 --- a/qapi/qobject-input-visitor.c +++ b/qapi/qobject-input-visitor.c @@ -757,7 +757,7 @@ Visitor *qobject_input_visitor_new_str(const char *str, assert(args); v = qobject_input_visitor_new(QOBJECT(args)); } else { - args = keyval_parse(str, implied_key, errp); + args = keyval_parse(str, implied_key, NULL, errp); if (!args) { return NULL; } diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c index 1ae1cda481..6f0e0cfb36 100644 --- a/storage-daemon/qemu-storage-daemon.c +++ b/storage-daemon/qemu-storage-daemon.c @@ -278,7 +278,7 @@ static void process_options(int argc, char *argv[]) } qemu_opts_del(opts); - args = keyval_parse(optarg, "qom-type", &error_fatal); + args = keyval_parse(optarg, "qom-type", NULL, &error_fatal); user_creatable_add_dict(args, true, &error_fatal); qobject_unref(args); break; diff --git a/tests/test-keyval.c b/tests/test-keyval.c index 04c62cf045..ee927fe4e4 100644 --- a/tests/test-keyval.c +++ b/tests/test-keyval.c @@ -27,27 +27,28 @@ static void test_keyval_parse(void) QDict *qdict, *sub_qdict; char long_key[129]; char *params; + bool help; /* Nothing */ - qdict = keyval_parse("", NULL, &error_abort); + qdict = keyval_parse("", NULL, NULL, &error_abort); g_assert_cmpuint(qdict_size(qdict), ==, 0); qobject_unref(qdict); /* Empty key (qemu_opts_parse() accepts this) */ - qdict = keyval_parse("=val", NULL, &err); + qdict = keyval_parse("=val", NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); /* Empty key fragment */ - qdict = keyval_parse(".", NULL, &err); + qdict = keyval_parse(".", NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); - qdict = keyval_parse("key.", NULL, &err); + qdict = keyval_parse("key.", NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); /* Invalid non-empty key (qemu_opts_parse() doesn't care) */ - qdict = keyval_parse("7up=val", NULL, &err); + qdict = keyval_parse("7up=val", NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); @@ -56,25 +57,25 @@ static void test_keyval_parse(void) long_key[127] = 'z'; long_key[128] = 0; params = g_strdup_printf("k.%s=v", long_key); - qdict = keyval_parse(params + 2, NULL, &err); + qdict = keyval_parse(params + 2, NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); /* Overlong key fragment */ - qdict = keyval_parse(params, NULL, &err); + qdict = keyval_parse(params, NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); g_free(params); /* Long key (qemu_opts_parse() accepts and truncates silently) */ params = g_strdup_printf("k.%s=v", long_key + 1); - qdict = keyval_parse(params + 2, NULL, &error_abort); + qdict = keyval_parse(params + 2, NULL, NULL, &error_abort); g_assert_cmpuint(qdict_size(qdict), ==, 1); g_assert_cmpstr(qdict_get_try_str(qdict, long_key + 1), ==, "v"); qobject_unref(qdict); /* Long key fragment */ - qdict = keyval_parse(params, NULL, &error_abort); + qdict = keyval_parse(params, NULL, NULL, &error_abort); g_assert_cmpuint(qdict_size(qdict), ==, 1); sub_qdict = qdict_get_qdict(qdict, "k"); g_assert(sub_qdict); @@ -84,25 +85,25 @@ static void test_keyval_parse(void) g_free(params); /* Crap after valid key */ - qdict = keyval_parse("key[0]=val", NULL, &err); + qdict = keyval_parse("key[0]=val", NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); /* Multiple keys, last one wins */ - qdict = keyval_parse("a=1,b=2,,x,a=3", NULL, &error_abort); + qdict = keyval_parse("a=1,b=2,,x,a=3", NULL, NULL, &error_abort); g_assert_cmpuint(qdict_size(qdict), ==, 2); g_assert_cmpstr(qdict_get_try_str(qdict, "a"), ==, "3"); g_assert_cmpstr(qdict_get_try_str(qdict, "b"), ==, "2,x"); qobject_unref(qdict); /* Even when it doesn't in qemu_opts_parse() */ - qdict = keyval_parse("id=foo,id=bar", NULL, &error_abort); + qdict = keyval_parse("id=foo,id=bar", NULL, NULL, &error_abort); g_assert_cmpuint(qdict_size(qdict), ==, 1); g_assert_cmpstr(qdict_get_try_str(qdict, "id"), ==, "bar"); qobject_unref(qdict); /* Dotted keys */ - qdict = keyval_parse("a.b.c=1,a.b.c=2,d=3", NULL, &error_abort); + qdict = keyval_parse("a.b.c=1,a.b.c=2,d=3", NULL, NULL, &error_abort); g_assert_cmpuint(qdict_size(qdict), ==, 2); sub_qdict = qdict_get_qdict(qdict, "a"); g_assert(sub_qdict); @@ -115,48 +116,48 @@ static void test_keyval_parse(void) qobject_unref(qdict); /* Inconsistent dotted keys */ - qdict = keyval_parse("a.b=1,a=2", NULL, &err); + qdict = keyval_parse("a.b=1,a=2", NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); - qdict = keyval_parse("a.b=1,a.b.c=2", NULL, &err); + qdict = keyval_parse("a.b=1,a.b.c=2", NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); /* Trailing comma is ignored */ - qdict = keyval_parse("x=y,", NULL, &error_abort); + qdict = keyval_parse("x=y,", NULL, NULL, &error_abort); g_assert_cmpuint(qdict_size(qdict), ==, 1); g_assert_cmpstr(qdict_get_try_str(qdict, "x"), ==, "y"); qobject_unref(qdict); /* Except when it isn't */ - qdict = keyval_parse(",", NULL, &err); + qdict = keyval_parse(",", NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); /* Value containing ,id= not misinterpreted as qemu_opts_parse() does */ - qdict = keyval_parse("x=,,id=bar", NULL, &error_abort); + qdict = keyval_parse("x=,,id=bar", NULL, NULL, &error_abort); g_assert_cmpuint(qdict_size(qdict), ==, 1); g_assert_cmpstr(qdict_get_try_str(qdict, "x"), ==, ",id=bar"); qobject_unref(qdict); /* Anti-social ID is left to caller (qemu_opts_parse() rejects it) */ - qdict = keyval_parse("id=666", NULL, &error_abort); + qdict = keyval_parse("id=666", NULL, NULL, &error_abort); g_assert_cmpuint(qdict_size(qdict), ==, 1); g_assert_cmpstr(qdict_get_try_str(qdict, "id"), ==, "666"); qobject_unref(qdict); /* Implied value not supported (unlike qemu_opts_parse()) */ - qdict = keyval_parse("an,noaus,noaus=", NULL, &err); + qdict = keyval_parse("an,noaus,noaus=", NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); /* Implied value, key "no" (qemu_opts_parse(): negated empty key) */ - qdict = keyval_parse("no", NULL, &err); + qdict = keyval_parse("no", NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); /* Implied key */ - qdict = keyval_parse("an,aus=off,noaus=", "implied", &error_abort); + qdict = keyval_parse("an,aus=off,noaus=", "implied", NULL, &error_abort); g_assert_cmpuint(qdict_size(qdict), ==, 3); g_assert_cmpstr(qdict_get_try_str(qdict, "implied"), ==, "an"); g_assert_cmpstr(qdict_get_try_str(qdict, "aus"), ==, "off"); @@ -164,7 +165,7 @@ static void test_keyval_parse(void) qobject_unref(qdict); /* Implied dotted key */ - qdict = keyval_parse("val", "eins.zwei", &error_abort); + qdict = keyval_parse("val", "eins.zwei", NULL, &error_abort); g_assert_cmpuint(qdict_size(qdict), ==, 1); sub_qdict = qdict_get_qdict(qdict, "eins"); g_assert(sub_qdict); @@ -173,24 +174,81 @@ static void test_keyval_parse(void) qobject_unref(qdict); /* Implied key with empty value (qemu_opts_parse() accepts this) */ - qdict = keyval_parse(",", "implied", &err); + qdict = keyval_parse(",", "implied", NULL, &err); error_free_or_abort(&err); g_assert(!qdict); /* Likewise (qemu_opts_parse(): implied key with comma value) */ - qdict = keyval_parse(",,,a=1", "implied", &err); + qdict = keyval_parse(",,,a=1", "implied", NULL, &err); error_free_or_abort(&err); g_assert(!qdict); /* Implied key's value can't have comma (qemu_opts_parse(): it can) */ - qdict = keyval_parse("val,,ue", "implied", &err); + qdict = keyval_parse("val,,ue", "implied", NULL, &err); error_free_or_abort(&err); g_assert(!qdict); /* Empty key is not an implied key */ - qdict = keyval_parse("=val", "implied", &err); + qdict = keyval_parse("=val", "implied", NULL, &err); error_free_or_abort(&err); g_assert(!qdict); + + /* "help" by itself, without implied key */ + qdict = keyval_parse("help", NULL, &help, &error_abort); + g_assert_cmpuint(qdict_size(qdict), ==, 0); + g_assert(help); + qobject_unref(qdict); + + /* "help" by itself, with implied key */ + qdict = keyval_parse("help", "implied", &help, &error_abort); + g_assert_cmpuint(qdict_size(qdict), ==, 0); + g_assert(help); + qobject_unref(qdict); + + /* "help" when no help is available, without implied key */ + qdict = keyval_parse("help", NULL, NULL, &err); + error_free_or_abort(&err); + g_assert(!qdict); + + /* "help" when no help is available, with implied key */ + qdict = keyval_parse("help", "implied", NULL, &err); + error_free_or_abort(&err); + g_assert(!qdict); + + /* Key "help" */ + qdict = keyval_parse("help=on", NULL, &help, &error_abort); + g_assert_cmpuint(qdict_size(qdict), ==, 1); + g_assert_cmpstr(qdict_get_try_str(qdict, "help"), ==, "on"); + g_assert(!help); + qobject_unref(qdict); + + /* "help" followed by crap, without implied key */ + qdict = keyval_parse("help.abc", NULL, &help, &err); + error_free_or_abort(&err); + g_assert(!qdict); + + /* "help" followed by crap, with implied key */ + qdict = keyval_parse("help.abc", "implied", &help, &err); + g_assert_cmpuint(qdict_size(qdict), ==, 1); + g_assert_cmpstr(qdict_get_try_str(qdict, "implied"), ==, "help.abc"); + g_assert(!help); + qobject_unref(qdict); + + /* "help" with other stuff, without implied key */ + qdict = keyval_parse("number=42,help,foo=bar", NULL, &help, &error_abort); + g_assert_cmpuint(qdict_size(qdict), ==, 2); + g_assert_cmpstr(qdict_get_try_str(qdict, "number"), ==, "42"); + g_assert_cmpstr(qdict_get_try_str(qdict, "foo"), ==, "bar"); + g_assert(help); + qobject_unref(qdict); + + /* "help" with other stuff, with implied key */ + qdict = keyval_parse("val,help,foo=bar", "implied", &help, &error_abort); + g_assert_cmpuint(qdict_size(qdict), ==, 2); + g_assert_cmpstr(qdict_get_try_str(qdict, "implied"), ==, "val"); + g_assert_cmpstr(qdict_get_try_str(qdict, "foo"), ==, "bar"); + g_assert(help); + qobject_unref(qdict); } static void check_list012(QList *qlist) @@ -215,26 +273,26 @@ static void test_keyval_parse_list(void) QDict *qdict, *sub_qdict; /* Root can't be a list */ - qdict = keyval_parse("0=1", NULL, &err); + qdict = keyval_parse("0=1", NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); /* List elements need not be in order */ - qdict = keyval_parse("list.0=null,list.2=zwei,list.1=eins", - NULL, &error_abort); + qdict = keyval_parse("list.0=null,list.2=zwei,list.1=eins", NULL, NULL, + &error_abort); g_assert_cmpint(qdict_size(qdict), ==, 1); check_list012(qdict_get_qlist(qdict, "list")); qobject_unref(qdict); /* Multiple indexes, last one wins */ qdict = keyval_parse("list.1=goner,list.0=null,list.01=eins,list.2=zwei", - NULL, &error_abort); + NULL, NULL, &error_abort); g_assert_cmpint(qdict_size(qdict), ==, 1); check_list012(qdict_get_qlist(qdict, "list")); qobject_unref(qdict); /* List at deeper nesting */ - qdict = keyval_parse("a.list.1=eins,a.list.00=null,a.list.2=zwei", + qdict = keyval_parse("a.list.1=eins,a.list.00=null,a.list.2=zwei", NULL, NULL, &error_abort); g_assert_cmpint(qdict_size(qdict), ==, 1); sub_qdict = qdict_get_qdict(qdict, "a"); @@ -243,18 +301,19 @@ static void test_keyval_parse_list(void) qobject_unref(qdict); /* Inconsistent dotted keys: both list and dictionary */ - qdict = keyval_parse("a.b.c=1,a.b.0=2", NULL, &err); + qdict = keyval_parse("a.b.c=1,a.b.0=2", NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); - qdict = keyval_parse("a.0.c=1,a.b.c=2", NULL, &err); + qdict = keyval_parse("a.0.c=1,a.b.c=2", NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); /* Missing list indexes */ - qdict = keyval_parse("list.1=lonely", NULL, &err); + qdict = keyval_parse("list.1=lonely", NULL, NULL, &err); error_free_or_abort(&err); g_assert(!qdict); - qdict = keyval_parse("list.0=null,list.2=eins,list.02=zwei", NULL, &err); + qdict = keyval_parse("list.0=null,list.2=eins,list.02=zwei", NULL, NULL, + &err); error_free_or_abort(&err); g_assert(!qdict); } @@ -266,7 +325,7 @@ static void test_keyval_visit_bool(void) QDict *qdict; bool b; - qdict = keyval_parse("bool1=on,bool2=off", NULL, &error_abort); + qdict = keyval_parse("bool1=on,bool2=off", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -278,7 +337,7 @@ static void test_keyval_visit_bool(void) visit_end_struct(v, NULL); visit_free(v); - qdict = keyval_parse("bool1=offer", NULL, &error_abort); + qdict = keyval_parse("bool1=offer", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -296,7 +355,7 @@ static void test_keyval_visit_number(void) uint64_t u; /* Lower limit zero */ - qdict = keyval_parse("number1=0", NULL, &error_abort); + qdict = keyval_parse("number1=0", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -307,7 +366,7 @@ static void test_keyval_visit_number(void) visit_free(v); /* Upper limit 2^64-1 */ - qdict = keyval_parse("number1=18446744073709551615,number2=-1", + qdict = keyval_parse("number1=18446744073709551615,number2=-1", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); @@ -321,8 +380,8 @@ static void test_keyval_visit_number(void) visit_free(v); /* Above upper limit */ - qdict = keyval_parse("number1=18446744073709551616", - NULL, &error_abort); + qdict = keyval_parse("number1=18446744073709551616", NULL, NULL, + &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -332,8 +391,8 @@ static void test_keyval_visit_number(void) visit_free(v); /* Below lower limit */ - qdict = keyval_parse("number1=-18446744073709551616", - NULL, &error_abort); + qdict = keyval_parse("number1=-18446744073709551616", NULL, NULL, + &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -343,8 +402,7 @@ static void test_keyval_visit_number(void) visit_free(v); /* Hex and octal */ - qdict = keyval_parse("number1=0x2a,number2=052", - NULL, &error_abort); + qdict = keyval_parse("number1=0x2a,number2=052", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -357,8 +415,7 @@ static void test_keyval_visit_number(void) visit_free(v); /* Trailing crap */ - qdict = keyval_parse("number1=3.14,number2=08", - NULL, &error_abort); + qdict = keyval_parse("number1=3.14,number2=08", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -378,7 +435,7 @@ static void test_keyval_visit_size(void) uint64_t sz; /* Lower limit zero */ - qdict = keyval_parse("sz1=0", NULL, &error_abort); + qdict = keyval_parse("sz1=0", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -394,7 +451,7 @@ static void test_keyval_visit_size(void) qdict = keyval_parse("sz1=9007199254740991," "sz2=9007199254740992," "sz3=9007199254740993", - NULL, &error_abort); + NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -411,7 +468,7 @@ static void test_keyval_visit_size(void) /* Close to signed upper limit 0x7ffffffffffffc00 (53 msbs set) */ qdict = keyval_parse("sz1=9223372036854774784," /* 7ffffffffffffc00 */ "sz2=9223372036854775295", /* 7ffffffffffffdff */ - NULL, &error_abort); + NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -426,7 +483,7 @@ static void test_keyval_visit_size(void) /* Close to actual upper limit 0xfffffffffffff800 (53 msbs set) */ qdict = keyval_parse("sz1=18446744073709549568," /* fffffffffffff800 */ "sz2=18446744073709550591", /* fffffffffffffbff */ - NULL, &error_abort); + NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -441,7 +498,7 @@ static void test_keyval_visit_size(void) /* Beyond limits */ qdict = keyval_parse("sz1=-1," "sz2=18446744073709550592", /* fffffffffffffc00 */ - NULL, &error_abort); + NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -454,7 +511,7 @@ static void test_keyval_visit_size(void) /* Suffixes */ qdict = keyval_parse("sz1=8b,sz2=1.5k,sz3=2M,sz4=0.1G,sz5=16777215T", - NULL, &error_abort); + NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -473,7 +530,7 @@ static void test_keyval_visit_size(void) visit_free(v); /* Beyond limit with suffix */ - qdict = keyval_parse("sz1=16777216T", NULL, &error_abort); + qdict = keyval_parse("sz1=16777216T", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -483,7 +540,7 @@ static void test_keyval_visit_size(void) visit_free(v); /* Trailing crap */ - qdict = keyval_parse("sz1=0Z,sz2=16Gi", NULL, &error_abort); + qdict = keyval_parse("sz1=0Z,sz2=16Gi", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -502,7 +559,7 @@ static void test_keyval_visit_dict(void) QDict *qdict; int64_t i; - qdict = keyval_parse("a.b.c=1,a.b.c=2,d=3", NULL, &error_abort); + qdict = keyval_parse("a.b.c=1,a.b.c=2,d=3", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -520,7 +577,7 @@ static void test_keyval_visit_dict(void) visit_end_struct(v, NULL); visit_free(v); - qdict = keyval_parse("a.b=", NULL, &error_abort); + qdict = keyval_parse("a.b=", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -542,7 +599,7 @@ static void test_keyval_visit_list(void) QDict *qdict; char *s; - qdict = keyval_parse("a.0=,a.1=I,a.2.0=II", NULL, &error_abort); + qdict = keyval_parse("a.0=,a.1=I,a.2.0=II", NULL, NULL, &error_abort); /* TODO empty list */ v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); @@ -566,7 +623,7 @@ static void test_keyval_visit_list(void) visit_end_struct(v, NULL); visit_free(v); - qdict = keyval_parse("a.0=,b.0.0=head", NULL, &error_abort); + qdict = keyval_parse("a.0=,b.0.0=head", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -595,7 +652,7 @@ static void test_keyval_visit_optional(void) bool present; int64_t i; - qdict = keyval_parse("a.b=1", NULL, &error_abort); + qdict = keyval_parse("a.b=1", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -631,7 +688,7 @@ static void test_keyval_visit_alternate(void) * the string variant if there is one, else an error. * TODO make it work for unambiguous cases like AltEnumBool below */ - qdict = keyval_parse("a=1,b=2,c=on", NULL, &error_abort); + qdict = keyval_parse("a=1,b=2,c=on", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -655,7 +712,7 @@ static void test_keyval_visit_any(void) QList *qlist; QString *qstr; - qdict = keyval_parse("a.0=null,a.1=1", NULL, &error_abort); + qdict = keyval_parse("a.0=null,a.1=1", NULL, NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); qobject_unref(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); diff --git a/util/keyval.c b/util/keyval.c index 8f33a36a7c..7f625ad33c 100644 --- a/util/keyval.c +++ b/util/keyval.c @@ -14,10 +14,11 @@ * KEY=VALUE,... syntax: * * key-vals = [ key-val { ',' key-val } [ ',' ] ] - * key-val = key '=' val + * key-val = key '=' val | help * key = key-fragment { '.' key-fragment } * key-fragment = / [^=,.]+ / * val = { / [^,]+ / | ',,' } + * help = 'help' | '?' * * Semantics defined by reduction to JSON: * @@ -54,6 +55,9 @@ * * The length of any key-fragment must be between 1 and 127. * + * If any key-val is help, the object is to be treated as a help + * request. + * * Design flaw: there is no way to denote an empty array or non-root * object. While interpreting "key absent" as empty seems natural * (removing a key-val from the input string removes the member when @@ -75,7 +79,7 @@ * * key-vals = [ key-val-1st { ',' key-val } [ ',' ] ] * key-val-1st = val-no-key | key-val - * val-no-key = / [^=,]+ / + * val-no-key = / [^=,]+ / - help * * where val-no-key is syntactic sugar for implied-key=val-no-key. * @@ -89,6 +93,7 @@ #include "qapi/qmp/qlist.h" #include "qapi/qmp/qstring.h" #include "qemu/cutils.h" +#include "qemu/help_option.h" #include "qemu/option.h" /* @@ -162,15 +167,20 @@ static QObject *keyval_parse_put(QDict *cur, } /* - * Parse one KEY=VALUE from @params, store result in @qdict. + * Parse one parameter from @params. + * + * If we're looking at KEY=VALUE, store result in @qdict. * The first fragment of KEY applies to @qdict. Subsequent fragments * apply to nested QDicts, which are created on demand. @implied_key * is as in keyval_parse(). - * On success, return a pointer to the next KEY=VALUE, or else to '\0'. + * + * If we're looking at "help" or "?", set *help to true. + * + * On success, return a pointer to the next parameter, or else to '\0'. * On failure, return NULL. */ static const char *keyval_parse_one(QDict *qdict, const char *params, - const char *implied_key, + const char *implied_key, bool *help, Error **errp) { const char *key, *key_end, *val_end, *s, *end; @@ -184,11 +194,21 @@ static const char *keyval_parse_one(QDict *qdict, const char *params, key = params; val_end = NULL; len = strcspn(params, "=,"); - if (implied_key && len && key[len] != '=') { - /* Desugar implied key */ - key = implied_key; - val_end = params + len; - len = strlen(implied_key); + if (len && key[len] != '=') { + if (starts_with_help_option(key) == len) { + *help = true; + s = key + len; + if (*s == ',') { + s++; + } + return s; + } + if (implied_key) { + /* Desugar implied key */ + key = implied_key; + val_end = params + len; + len = strlen(implied_key); + } } key_end = key + len; @@ -398,21 +418,32 @@ static QObject *keyval_listify(QDict *cur, GSList *key_of_cur, Error **errp) /* * Parse @params in QEMU's traditional KEY=VALUE,... syntax. + * * If @implied_key, the first KEY= can be omitted. @implied_key is * implied then, and VALUE can't be empty or contain ',' or '='. + * + * A parameter "help" or "?" without a value isn't added to the + * resulting dictionary, but instead is interpreted as help request. + * All other options are parsed and returned normally so that context + * specific help can be printed. + * + * If @p_help is not NULL, store whether help is requested there. + * If @p_help is NULL and help is requested, fail. + * * On success, return a dictionary of the parsed keys and values. * On failure, store an error through @errp and return NULL. */ QDict *keyval_parse(const char *params, const char *implied_key, - Error **errp) + bool *p_help, Error **errp) { QDict *qdict = qdict_new(); QObject *listified; const char *s; + bool help = false; s = params; while (*s) { - s = keyval_parse_one(qdict, s, implied_key, errp); + s = keyval_parse_one(qdict, s, implied_key, &help, errp); if (!s) { qobject_unref(qdict); return NULL; @@ -420,6 +451,14 @@ QDict *keyval_parse(const char *params, const char *implied_key, implied_key = NULL; } + if (p_help) { + *p_help = help; + } else if (help) { + error_setg(errp, "Help is not available for this option"); + qobject_unref(qdict); + return NULL; + } + listified = keyval_listify(qdict, NULL, errp); if (!listified) { qobject_unref(qdict); From patchwork Thu Oct 15 14:49:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 11839475 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E6BC71744 for ; Thu, 15 Oct 2020 14:53:00 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7EBA621D7F for ; Thu, 15 Oct 2020 14:53:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="A7Mc68B+" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7EBA621D7F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:40394 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kT4cl-00080V-Ed for patchwork-qemu-devel@patchwork.kernel.org; Thu, 15 Oct 2020 10:52:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42290) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kT4a7-0004cs-NP for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:15 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:49387) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kT4a5-0001i8-4A for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1602773412; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sYyqaW7pTGseV1pH/a101zWKPH2l94EMzBlNNFz+pOE=; b=A7Mc68B+tQnxIofHvGInE3Phr9h5N8tNhLW1tWagMYzz7nvvya/TQXnn622ZoDetDhUfE7 s1pG+BlVTMSf42xovGsSSVt6kmPhaF/JSzhZF12uy9ZpHUaJHF0PWg44pNRNG0KP8y324B izWbr/BwLUVzUj///s5Lj3AQ8CfzNJY= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-579-hKrlVgxiOdan66nSNfmkPA-1; Thu, 15 Oct 2020 10:50:08 -0400 X-MC-Unique: hKrlVgxiOdan66nSNfmkPA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0D177ADC2D; Thu, 15 Oct 2020 14:50:07 +0000 (UTC) Received: from merkur.redhat.com (ovpn-114-163.ams2.redhat.com [10.36.114.163]) by smtp.corp.redhat.com (Postfix) with ESMTP id 13837610F3; Thu, 15 Oct 2020 14:50:05 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PULL 05/10] qom: Factor out helpers from user_creatable_print_help() Date: Thu, 15 Oct 2020 16:49:47 +0200 Message-Id: <20201015144952.388043-6-kwolf@redhat.com> In-Reply-To: <20201015144952.388043-1-kwolf@redhat.com> References: <20201015144952.388043-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/15 02:38:26 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This creates separate helper functions for printing a list of user creatable object types and for printing a list of properties of a given type. This will allow using these parts without having a QemuOpts. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake Reviewed-by: Markus Armbruster Message-Id: <20201007164903.282198-3-kwolf@redhat.com> Signed-off-by: Kevin Wolf --- qom/object_interfaces.c | 90 ++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c index e8e1523960..3fd1da157e 100644 --- a/qom/object_interfaces.c +++ b/qom/object_interfaces.c @@ -214,54 +214,68 @@ char *object_property_help(const char *name, const char *type, return g_string_free(str, false); } -bool user_creatable_print_help(const char *type, QemuOpts *opts) +static void user_creatable_print_types(void) +{ + GSList *l, *list; + + printf("List of user creatable objects:\n"); + list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false); + for (l = list; l != NULL; l = l->next) { + ObjectClass *oc = OBJECT_CLASS(l->data); + printf(" %s\n", object_class_get_name(oc)); + } + g_slist_free(list); +} + +static bool user_creatable_print_type_properites(const char *type) { ObjectClass *klass; + ObjectPropertyIterator iter; + ObjectProperty *prop; + GPtrArray *array; + int i; - if (is_help_option(type)) { - GSList *l, *list; + klass = object_class_by_name(type); + if (!klass) { + return false; + } - printf("List of user creatable objects:\n"); - list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false); - for (l = list; l != NULL; l = l->next) { - ObjectClass *oc = OBJECT_CLASS(l->data); - printf(" %s\n", object_class_get_name(oc)); + array = g_ptr_array_new(); + object_class_property_iter_init(&iter, klass); + while ((prop = object_property_iter_next(&iter))) { + if (!prop->set) { + continue; } - g_slist_free(list); - return true; + + g_ptr_array_add(array, + object_property_help(prop->name, prop->type, + prop->defval, prop->description)); } + g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0); + if (array->len > 0) { + printf("%s options:\n", type); + } else { + printf("There are no options for %s.\n", type); + } + for (i = 0; i < array->len; i++) { + printf("%s\n", (char *)array->pdata[i]); + } + g_ptr_array_set_free_func(array, g_free); + g_ptr_array_free(array, true); + return true; +} - klass = object_class_by_name(type); - if (klass && qemu_opt_has_help_opt(opts)) { - ObjectPropertyIterator iter; - ObjectProperty *prop; - GPtrArray *array = g_ptr_array_new(); - int i; - - object_class_property_iter_init(&iter, klass); - while ((prop = object_property_iter_next(&iter))) { - if (!prop->set) { - continue; - } - - g_ptr_array_add(array, - object_property_help(prop->name, prop->type, - prop->defval, prop->description)); - } - g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0); - if (array->len > 0) { - printf("%s options:\n", type); - } else { - printf("There are no options for %s.\n", type); - } - for (i = 0; i < array->len; i++) { - printf("%s\n", (char *)array->pdata[i]); - } - g_ptr_array_set_free_func(array, g_free); - g_ptr_array_free(array, true); +bool user_creatable_print_help(const char *type, QemuOpts *opts) +{ + if (is_help_option(type)) { + user_creatable_print_types(); return true; } + if (qemu_opt_has_help_opt(opts)) { + return user_creatable_print_type_properites(type); + } + return false; } From patchwork Thu Oct 15 14:49:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 11839479 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A31A41744 for ; Thu, 15 Oct 2020 14:54:42 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5952222240 for ; Thu, 15 Oct 2020 14:54:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="CMk37vwl" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5952222240 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:44994 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kT4eP-0001V3-Bh for patchwork-qemu-devel@patchwork.kernel.org; Thu, 15 Oct 2020 10:54:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42306) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kT4a8-0004eY-Cf for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:16 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:60070) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kT4a6-0001iV-8s for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1602773413; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=stV52gVCaiFh9WEkxR8O3GXle/EMo4IaLgXYIaMTEBY=; b=CMk37vwlSTuhjmoay41VL2KtBShYLdXYvquMkxPTo9sEo6fK7abHbvLniJvlHWl3JNknDk JMxQ0yyf7v41Lqxf8tt45NTNG3JeTovX9heOmabJUWfuH8ghnQbD3mazQHmg58DbPnUJZv HhfAYslW5AJq+B0RNapFapGLS1g+DFc= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-148-o8BrDN52Od2ZgcQiZSW3lQ-1; Thu, 15 Oct 2020 10:50:09 -0400 X-MC-Unique: o8BrDN52Od2ZgcQiZSW3lQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4E9CEADC34; Thu, 15 Oct 2020 14:50:08 +0000 (UTC) Received: from merkur.redhat.com (ovpn-114-163.ams2.redhat.com [10.36.114.163]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5367160C07; Thu, 15 Oct 2020 14:50:07 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PULL 06/10] qom: Add user_creatable_print_help_from_qdict() Date: Thu, 15 Oct 2020 16:49:48 +0200 Message-Id: <20201015144952.388043-7-kwolf@redhat.com> In-Reply-To: <20201015144952.388043-1-kwolf@redhat.com> References: <20201015144952.388043-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/15 02:10:02 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This adds a function that, given a QDict of non-help options, prints help for user creatable objects. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake Reviewed-by: Markus Armbruster Message-Id: <20201007164903.282198-4-kwolf@redhat.com> Signed-off-by: Kevin Wolf --- include/qom/object_interfaces.h | 21 ++++++++++++++++++--- qom/object_interfaces.c | 9 +++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h index f118fb516b..07d5cc8832 100644 --- a/include/qom/object_interfaces.h +++ b/include/qom/object_interfaces.h @@ -154,13 +154,28 @@ int user_creatable_add_opts_foreach(void *opaque, * @type: the QOM type to be added * @opts: options to create * - * Prints help if requested in @opts. + * Prints help if requested in @type or @opts. Note that if @type is neither + * "help"/"?" nor a valid user creatable type, no help will be printed + * regardless of @opts. * - * Returns: true if @opts contained a help option and help was printed, false - * if no help option was found. + * Returns: true if a help option was found and help was printed, false + * otherwise. */ bool user_creatable_print_help(const char *type, QemuOpts *opts); +/** + * user_creatable_print_help_from_qdict: + * @args: options to create + * + * Prints help considering the other options given in @args (if "qom-type" is + * given and valid, print properties for the type, otherwise print valid types) + * + * In contrast to user_creatable_print_help(), this function can't return that + * no help was requested. It should only be called if we know that help is + * requested and it will always print some help. + */ +void user_creatable_print_help_from_qdict(QDict *args); + /** * user_creatable_del: * @id: the unique ID for the object diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c index 3fd1da157e..ed896fe764 100644 --- a/qom/object_interfaces.c +++ b/qom/object_interfaces.c @@ -279,6 +279,15 @@ bool user_creatable_print_help(const char *type, QemuOpts *opts) return false; } +void user_creatable_print_help_from_qdict(QDict *args) +{ + const char *type = qdict_get_try_str(args, "qom-type"); + + if (!type || !user_creatable_print_type_properites(type)) { + user_creatable_print_types(); + } +} + bool user_creatable_del(const char *id, Error **errp) { Object *container; From patchwork Thu Oct 15 14:49:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 11839489 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 23F3761C for ; Thu, 15 Oct 2020 14:57:48 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C680021D7F for ; Thu, 15 Oct 2020 14:57:47 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="FDRYkGFf" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C680021D7F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:57970 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kT4hO-0006yO-KS for patchwork-qemu-devel@patchwork.kernel.org; Thu, 15 Oct 2020 10:57:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42386) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kT4aA-0004kr-UU for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:18 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:53570) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kT4a8-0001ja-9f for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1602773415; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=l9x0ztDDUCpVHnWy5WWelBVfSA1tGwBdfYTlbsr8+oA=; b=FDRYkGFforB7IHA7UBUyEDkqCn3I25++uw5/2RgZ+vwp3Slb89Z+rOx+ygTL3fE2zM4WRp 6FaBwXbRaE7i1hGWl8Pd/uYlQ1h3L7O4aiLIrezJ3Opt5lwqJCoreQz1P2tS9BYiApnQWl yxLUQk7uuG/3EDdCA9ok/p+Yqkh1g10= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-346-rAKBvJ7_O7OGJvnEFmbvBw-1; Thu, 15 Oct 2020 10:50:10 -0400 X-MC-Unique: rAKBvJ7_O7OGJvnEFmbvBw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 95D4C8015B1; Thu, 15 Oct 2020 14:50:09 +0000 (UTC) Received: from merkur.redhat.com (ovpn-114-163.ams2.redhat.com [10.36.114.163]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9832360C07; Thu, 15 Oct 2020 14:50:08 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PULL 07/10] qemu-storage-daemon: Remove QemuOpts from --object parser Date: Thu, 15 Oct 2020 16:49:49 +0200 Message-Id: <20201015144952.388043-8-kwolf@redhat.com> In-Reply-To: <20201015144952.388043-1-kwolf@redhat.com> References: <20201015144952.388043-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/15 02:10:02 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" The command line parser for --object parses the input twice: Once into QemuOpts just for detecting help options, and then again into a QDict using the keyval parser for actually creating the object. Now that the keyval parser can also detect help options, we can simplify this and remove the QemuOpts part. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake Reviewed-by: Markus Armbruster Message-Id: <20201007164903.282198-5-kwolf@redhat.com> Signed-off-by: Kevin Wolf --- storage-daemon/qemu-storage-daemon.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c index 6f0e0cfb36..e419ba9f19 100644 --- a/storage-daemon/qemu-storage-daemon.c +++ b/storage-daemon/qemu-storage-daemon.c @@ -264,21 +264,14 @@ static void process_options(int argc, char *argv[]) } case OPTION_OBJECT: { - QemuOpts *opts; - const char *type; QDict *args; + bool help; - /* FIXME The keyval parser rejects 'help' arguments, so we must - * unconditionall try QemuOpts first. */ - opts = qemu_opts_parse(&qemu_object_opts, - optarg, true, &error_fatal); - type = qemu_opt_get(opts, "qom-type"); - if (type && user_creatable_print_help(type, opts)) { + args = keyval_parse(optarg, "qom-type", &help, &error_fatal); + if (help) { + user_creatable_print_help_from_qdict(args); exit(EXIT_SUCCESS); } - qemu_opts_del(opts); - - args = keyval_parse(optarg, "qom-type", NULL, &error_fatal); user_creatable_add_dict(args, true, &error_fatal); qobject_unref(args); break; From patchwork Thu Oct 15 14:49:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 11839487 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8099E61C for ; Thu, 15 Oct 2020 14:56:17 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2E00421D7F for ; Thu, 15 Oct 2020 14:56:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="WH6H4s82" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2E00421D7F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:53134 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kT4fu-0004s8-Pe for patchwork-qemu-devel@patchwork.kernel.org; Thu, 15 Oct 2020 10:56:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42414) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kT4aB-0004mK-ER for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:19 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:60506) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kT4a8-0001jm-IC for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1602773415; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rivrn/+u97DL/RkpoC7pMjoyj+jh4RhPxUF/gNKePZE=; b=WH6H4s823yC0L37r4Tn6QkFN7d8UopvFYYJHThp6eLU9L6dXBNQKDUtUdTTSf0kDYwSK02 KzGEWkUqakDdHhiKIHrDlm7nzL066h1+gLoy2ZuVzqnhnQFiR5Sv69dqXqTIGYb6UC+aLi MQfAOR/bqpxivkdaHbCvAst4A4wRiRQ= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-454-n-R60lu_PiO0Sk7iYhofjw-1; Thu, 15 Oct 2020 10:50:12 -0400 X-MC-Unique: n-R60lu_PiO0Sk7iYhofjw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D8737108E1AB; Thu, 15 Oct 2020 14:50:10 +0000 (UTC) Received: from merkur.redhat.com (ovpn-114-163.ams2.redhat.com [10.36.114.163]) by smtp.corp.redhat.com (Postfix) with ESMTP id E15B360C07; Thu, 15 Oct 2020 14:50:09 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PULL 08/10] monitor: Fix order in monitor_cleanup() Date: Thu, 15 Oct 2020 16:49:50 +0200 Message-Id: <20201015144952.388043-9-kwolf@redhat.com> In-Reply-To: <20201015144952.388043-1-kwolf@redhat.com> References: <20201015144952.388043-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/15 02:10:02 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" We can only destroy Monitor objects after we're sure that they are not in use by the dispatcher coroutine any more. This fixes crashes like the following where we tried to destroy a monitor mutex while the dispatcher coroutine still holds it: (gdb) bt #0 0x00007fe541cf4bc5 in raise () at /lib64/libc.so.6 #1 0x00007fe541cdd8a4 in abort () at /lib64/libc.so.6 #2 0x000055c24e965327 in error_exit (err=16, msg=0x55c24eead3a0 <__func__.33> "qemu_mutex_destroy") at ../util/qemu-thread-posix.c:37 #3 0x000055c24e9654c3 in qemu_mutex_destroy (mutex=0x55c25133e0f0) at ../util/qemu-thread-posix.c:70 #4 0x000055c24e7cfaf1 in monitor_data_destroy_qmp (mon=0x55c25133dfd0) at ../monitor/qmp.c:439 #5 0x000055c24e7d23bc in monitor_data_destroy (mon=0x55c25133dfd0) at ../monitor/monitor.c:615 #6 0x000055c24e7d253a in monitor_cleanup () at ../monitor/monitor.c:644 #7 0x000055c24e6cb002 in qemu_cleanup () at ../softmmu/vl.c:4549 #8 0x000055c24e0d259b in main (argc=24, argv=0x7ffff66b0d58, envp=0x7ffff66b0e20) at ../softmmu/main.c:51 Reported-by: Alex Bennée Signed-off-by: Kevin Wolf Message-Id: <20201013125027.41003-1-kwolf@redhat.com> Tested-by: Ben Widawsky Tested-by: Alex Bennée Reviewed-by: Alex Bennée Signed-off-by: Kevin Wolf --- monitor/monitor.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/monitor/monitor.c b/monitor/monitor.c index ceffe1a83b..84222cd130 100644 --- a/monitor/monitor.c +++ b/monitor/monitor.c @@ -632,23 +632,9 @@ void monitor_cleanup(void) iothread_stop(mon_iothread); } - /* Flush output buffers and destroy monitors */ - qemu_mutex_lock(&monitor_lock); - monitor_destroyed = true; - while (!QTAILQ_EMPTY(&mon_list)) { - Monitor *mon = QTAILQ_FIRST(&mon_list); - QTAILQ_REMOVE(&mon_list, mon, entry); - /* Permit QAPI event emission from character frontend release */ - qemu_mutex_unlock(&monitor_lock); - monitor_flush(mon); - monitor_data_destroy(mon); - qemu_mutex_lock(&monitor_lock); - g_free(mon); - } - qemu_mutex_unlock(&monitor_lock); - /* - * The dispatcher needs to stop before destroying the I/O thread. + * The dispatcher needs to stop before destroying the monitor and + * the I/O thread. * * We need to poll both qemu_aio_context and iohandler_ctx to make * sure that the dispatcher coroutine keeps making progress and @@ -665,6 +651,21 @@ void monitor_cleanup(void) (aio_poll(iohandler_get_aio_context(), false), qatomic_mb_read(&qmp_dispatcher_co_busy))); + /* Flush output buffers and destroy monitors */ + qemu_mutex_lock(&monitor_lock); + monitor_destroyed = true; + while (!QTAILQ_EMPTY(&mon_list)) { + Monitor *mon = QTAILQ_FIRST(&mon_list); + QTAILQ_REMOVE(&mon_list, mon, entry); + /* Permit QAPI event emission from character frontend release */ + qemu_mutex_unlock(&monitor_lock); + monitor_flush(mon); + monitor_data_destroy(mon); + qemu_mutex_lock(&monitor_lock); + g_free(mon); + } + qemu_mutex_unlock(&monitor_lock); + if (mon_iothread) { iothread_destroy(mon_iothread); mon_iothread = NULL; From patchwork Thu Oct 15 14:49:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 11839481 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BC02761C for ; Thu, 15 Oct 2020 14:55:19 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 59F7622256 for ; Thu, 15 Oct 2020 14:55:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="J1NIM1ZN" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 59F7622256 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:48372 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kT4f0-0002qC-6q for patchwork-qemu-devel@patchwork.kernel.org; Thu, 15 Oct 2020 10:55:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42368) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kT4aA-0004jF-9N for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:18 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:44144) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kT4a8-0001jd-AB for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1602773415; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Y6DoE10Zmh8TnT++WrnJ2FwLyHCnk+WU0URUmUnUizs=; b=J1NIM1ZNODG4QMigdtymHbIF0xRR3tLgixICWSWwKWbbLkNwL8Y9njNh9CIaBpPxxgV/4M 89C5is1OmRZtsBFnbdiWpS8KplZ/Pq6Dluln2+B1LsMbYAw+iZEXKnqG5LwA+Ce7EEL366 pmaAqIx/UAqrqfeumy4GznCrz0QU2To= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-50-sm13lk3uMy6r_PqKpjycJw-1; Thu, 15 Oct 2020 10:50:13 -0400 X-MC-Unique: sm13lk3uMy6r_PqKpjycJw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 20C1B108E1A2; Thu, 15 Oct 2020 14:50:12 +0000 (UTC) Received: from merkur.redhat.com (ovpn-114-163.ams2.redhat.com [10.36.114.163]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2CDF960C07; Thu, 15 Oct 2020 14:50:11 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PULL 09/10] block: drop moderated sheepdog mailing list from MAINTAINERS file Date: Thu, 15 Oct 2020 16:49:51 +0200 Message-Id: <20201015144952.388043-10-kwolf@redhat.com> In-Reply-To: <20201015144952.388043-1-kwolf@redhat.com> References: <20201015144952.388043-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/15 02:10:02 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Daniel P. Berrangé The sheepdog mailing list is setup to stop and queue messages from non-subscribers, pending moderator approval. Unfortunately it seems that the moderation queue is not actively dealt with. Even when messages are approved, the sender is never added to the whitelist, so every future mail from the same sender continues to get stopped for moderation. MAINTAINERS entries should be responsive and not unneccessarily block mails from QEMU contributors, so drop the sheepdog mailing list. Reviewed-by: Thomas Huth Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Daniel P. Berrangé Message-Id: <20201002113243.2347710-2-berrange@redhat.com> Reviewed-by: Neal Gompa Signed-off-by: Kevin Wolf --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 47dd38a8cc..99ab02bbab 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2881,7 +2881,6 @@ F: block/rbd.c Sheepdog M: Liu Yuan L: qemu-block@nongnu.org -L: sheepdog@lists.wpkg.org S: Odd Fixes F: block/sheepdog.c From patchwork Thu Oct 15 14:49:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 11839491 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8EEB461C for ; Thu, 15 Oct 2020 14:58:54 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 331EE21D7F for ; Thu, 15 Oct 2020 14:58:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="GPYJpyCv" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 331EE21D7F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:60728 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kT4iT-00089f-6P for patchwork-qemu-devel@patchwork.kernel.org; Thu, 15 Oct 2020 10:58:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42454) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kT4aD-0004sE-VV for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:21 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:23993) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kT4aB-0001nC-1c for qemu-devel@nongnu.org; Thu, 15 Oct 2020 10:50:21 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1602773417; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pbRtfCgbHUT3lvRbCn/1nQl2DeMUCxGO1cFgjgWmSA8=; b=GPYJpyCvK3tUz5nH39yyV2p3IQmfWs+TCM83tYzDDICk67tPyTLtDqcY0hxL8+7gOfpaBu aI03uTBDBeqIiqQna+4t41HUablp62507TRSMY/sd5jP/8ne+hW/OVw0Eh+Wf/amBXJ58Q 3ISZqAbEba4V8sTSrqgY111I9XXx0iY= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-180-YHZEVZlzNxqf7hXsryBLuQ-1; Thu, 15 Oct 2020 10:50:14 -0400 X-MC-Unique: YHZEVZlzNxqf7hXsryBLuQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 5CE111021206; Thu, 15 Oct 2020 14:50:13 +0000 (UTC) Received: from merkur.redhat.com (ovpn-114-163.ams2.redhat.com [10.36.114.163]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6876160E1C; Thu, 15 Oct 2020 14:50:12 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PULL 10/10] block: deprecate the sheepdog block driver Date: Thu, 15 Oct 2020 16:49:52 +0200 Message-Id: <20201015144952.388043-11-kwolf@redhat.com> In-Reply-To: <20201015144952.388043-1-kwolf@redhat.com> References: <20201015144952.388043-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/15 02:10:02 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Daniel P. Berrangé This thread from a little over a year ago: http://lists.wpkg.org/pipermail/sheepdog/2019-March/thread.html states that sheepdog is no longer actively developed. The only mentioned users are some companies who are said to have it for legacy reasons with plans to replace it by Ceph. There is talk about cutting out existing features to turn it into a simple demo of how to write a distributed block service. There is no evidence of anyone working on that idea: https://github.com/sheepdog/sheepdog/commits/master No real commits to git since Jan 2018, and before then just some minor technical debt cleanup. There is essentially no activity on the mailing list aside from patches to QEMU that get CC'd due to our MAINTAINERS entry. Fedora packages for sheepdog failed to build from upstream source because of the more strict linker that no longer merges duplicate global symbols. Fedora patches it to add the missing "extern" annotations and presumably other distros do to, but upstream source remains broken. There is only basic compile testing, no functional testing of the driver. Since there are no build pre-requisites the sheepdog driver is currently enabled unconditionally. This would result in configure issuing a deprecation warning by default for all users. Thus the configure default is changed to disable it, requiring users to pass --enable-sheepdog to build the driver. Reviewed-by: Markus Armbruster Reviewed-by: Thomas Huth Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Daniel P. Berrangé Message-Id: <20201002113243.2347710-3-berrange@redhat.com> Reviewed-by: Neal Gompa Signed-off-by: Kevin Wolf --- docs/system/deprecated.rst | 9 +++++++++ configure | 5 +++-- block/sheepdog.c | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst index 09ec8b1ae8..2ac3bfd5e9 100644 --- a/docs/system/deprecated.rst +++ b/docs/system/deprecated.rst @@ -390,6 +390,15 @@ The above, converted to the current supported format:: json:{"file.driver":"rbd", "file.pool":"rbd", "file.image":"name"} +``sheepdog`` driver (since 5.2.0) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``sheepdog`` block device driver is deprecated. The corresponding upstream +server project is no longer actively maintained. Users are recommended to switch +to an alternative distributed block device driver such as RBD. The +``qemu-img convert`` command can be used to liberate existing data by moving +it out of sheepdog volumes into an alternative storage backend. + linux-user mode CPUs -------------------- diff --git a/configure b/configure index f839c2a557..f498a37f9a 100755 --- a/configure +++ b/configure @@ -433,7 +433,7 @@ vdi="yes" vvfat="yes" qed="yes" parallels="yes" -sheepdog="yes" +sheepdog="no" libxml2="" debug_mutex="no" libpmem="" @@ -1830,7 +1830,7 @@ disabled with --disable-FEATURE, default is enabled if available: vvfat vvfat image format support qed qed image format support parallels parallels image format support - sheepdog sheepdog block driver support + sheepdog sheepdog block driver support (deprecated) crypto-afalg Linux AF_ALG crypto backend driver capstone capstone disassembler support debug-mutex mutex debugging support @@ -6729,6 +6729,7 @@ if test "$parallels" = "yes" ; then echo "CONFIG_PARALLELS=y" >> $config_host_mak fi if test "$sheepdog" = "yes" ; then + add_to deprecated_features "sheepdog" echo "CONFIG_SHEEPDOG=y" >> $config_host_mak fi if test "$pty_h" = "yes" ; then diff --git a/block/sheepdog.c b/block/sheepdog.c index 25111d5a70..a45c73826d 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -242,6 +242,16 @@ typedef struct SheepdogInode { */ #define FNV1A_64_INIT ((uint64_t)0xcbf29ce484222325ULL) +static void deprecation_warning(void) +{ + static bool warned; + + if (!warned) { + warn_report("the sheepdog block driver is deprecated"); + warned = true; + } +} + /* * 64 bit Fowler/Noll/Vo FNV-1a hash code */ @@ -1548,6 +1558,8 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags, char *buf = NULL; QemuOpts *opts; + deprecation_warning(); + s->bs = bs; s->aio_context = bdrv_get_aio_context(bs); @@ -2007,6 +2019,8 @@ static int sd_co_create(BlockdevCreateOptions *options, Error **errp) assert(options->driver == BLOCKDEV_DRIVER_SHEEPDOG); + deprecation_warning(); + s = g_new0(BDRVSheepdogState, 1); /* Steal SocketAddress from QAPI, set NULL to prevent double free */