<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Oct 25, 2021 at 1:25 AM Markus Armbruster <<a href="mailto:armbru@redhat.com">armbru@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The code to check command policy can see special feature flag<br>
'deprecated' as command flag QCO_DEPRECATED. I want to make feature<br>
flag 'unstable' visible there as well, so I can add policy for it.<br>
<br>
To let me make it visible, add member @special_features (a bitset of<br>
QapiSpecialFeature) to QmpCommand, and adjust the generator to pass it<br>
through qmp_register_command(). Then replace "QCO_DEPRECATED in<br>
@flags" by QAPI_DEPRECATED in @special_features", and drop<br>
QCO_DEPRECATED.<br>
<br>
Signed-off-by: Markus Armbruster <<a href="mailto:armbru@redhat.com" target="_blank">armbru@redhat.com</a>><br>
---<br>
include/qapi/qmp/dispatch.h | 5 +++--<br>
monitor/misc.c | 6 ++++--<br>
qapi/qmp-dispatch.c | 2 +-<br>
qapi/qmp-registry.c | 4 +++-<br>
storage-daemon/qemu-storage-daemon.c | 3 ++-<br>
scripts/qapi/commands.py | 9 ++++-----<br>
6 files changed, 17 insertions(+), 12 deletions(-)<br>
<br>
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h<br>
index 0ce88200b9..1e4240fd0d 100644<br>
--- a/include/qapi/qmp/dispatch.h<br>
+++ b/include/qapi/qmp/dispatch.h<br>
@@ -25,7 +25,6 @@ typedef enum QmpCommandOptions<br>
QCO_ALLOW_OOB = (1U << 1),<br>
QCO_ALLOW_PRECONFIG = (1U << 2),<br>
QCO_COROUTINE = (1U << 3),<br>
- QCO_DEPRECATED = (1U << 4),<br>
} QmpCommandOptions;<br>
<br>
typedef struct QmpCommand<br>
@@ -34,6 +33,7 @@ typedef struct QmpCommand<br>
/* Runs in coroutine context if QCO_COROUTINE is set */<br>
QmpCommandFunc *fn;<br>
QmpCommandOptions options;<br>
+ unsigned special_features;<br>
QTAILQ_ENTRY(QmpCommand) node;<br>
bool enabled;<br>
const char *disable_reason;<br>
@@ -42,7 +42,8 @@ typedef struct QmpCommand<br>
typedef QTAILQ_HEAD(QmpCommandList, QmpCommand) QmpCommandList;<br>
<br>
void qmp_register_command(QmpCommandList *cmds, const char *name,<br>
- QmpCommandFunc *fn, QmpCommandOptions options);<br>
+ QmpCommandFunc *fn, QmpCommandOptions options,<br>
+ unsigned special_features);<br>
const QmpCommand *qmp_find_command(const QmpCommandList *cmds,<br>
const char *name);<br>
void qmp_disable_command(QmpCommandList *cmds, const char *name,<br>
diff --git a/monitor/misc.c b/monitor/misc.c<br>
index 3556b177f6..c2d227a07c 100644<br>
--- a/monitor/misc.c<br>
+++ b/monitor/misc.c<br>
@@ -230,11 +230,13 @@ static void monitor_init_qmp_commands(void)<br>
<br>
qmp_init_marshal(&qmp_commands);<br>
<br>
- qmp_register_command(&qmp_commands, "device_add", qmp_device_add, 0);<br>
+ qmp_register_command(&qmp_commands, "device_add",<br>
+ qmp_device_add, 0, 0);<br>
<br>
QTAILQ_INIT(&qmp_cap_negotiation_commands);<br>
qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",<br>
- qmp_marshal_qmp_capabilities, QCO_ALLOW_PRECONFIG);<br>
+ qmp_marshal_qmp_capabilities,<br>
+ QCO_ALLOW_PRECONFIG, 0);<br>
}<br>
<br>
/* Set the current CPU defined by the user. Callers must hold BQL. */<br>
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c<br>
index 7e943a0af5..8cca18c891 100644<br>
--- a/qapi/qmp-dispatch.c<br>
+++ b/qapi/qmp-dispatch.c<br>
@@ -176,7 +176,7 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request,<br>
"The command %s has not been found", command);<br>
goto out;<br>
}<br>
- if (cmd->options & QCO_DEPRECATED) {<br>
+ if (cmd->special_features & 1u << QAPI_DEPRECATED) {<br>
switch (compat_policy.deprecated_input) {<br>
case COMPAT_POLICY_INPUT_ACCEPT:<br>
break;<br>
diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c<br>
index f78c064aae..485bc5e6fc 100644<br>
--- a/qapi/qmp-registry.c<br>
+++ b/qapi/qmp-registry.c<br>
@@ -16,7 +16,8 @@<br>
#include "qapi/qmp/dispatch.h"<br>
<br>
void qmp_register_command(QmpCommandList *cmds, const char *name,<br>
- QmpCommandFunc *fn, QmpCommandOptions options)<br>
+ QmpCommandFunc *fn, QmpCommandOptions options,<br>
+ unsigned special_features)<br>
{<br>
QmpCommand *cmd = g_malloc0(sizeof(*cmd));<br>
<br>
@@ -27,6 +28,7 @@ void qmp_register_command(QmpCommandList *cmds, const char *name,<br>
cmd->fn = fn;<br>
cmd->enabled = true;<br>
cmd->options = options;<br>
+ cmd->special_features = special_features;<br>
QTAILQ_INSERT_TAIL(cmds, cmd, node);<br>
}<br>
<br>
diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c<br>
index 10a1a33761..52cf17e8ac 100644<br>
--- a/storage-daemon/qemu-storage-daemon.c<br>
+++ b/storage-daemon/qemu-storage-daemon.c<br>
@@ -146,7 +146,8 @@ static void init_qmp_commands(void)<br>
<br>
QTAILQ_INIT(&qmp_cap_negotiation_commands);<br>
qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",<br>
- qmp_marshal_qmp_capabilities, QCO_ALLOW_PRECONFIG);<br>
+ qmp_marshal_qmp_capabilities,<br>
+ QCO_ALLOW_PRECONFIG, 0);<br>
}<br>
<br>
static int getopt_set_loc(int argc, char **argv, const char *optstring,<br>
diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py<br>
index c8a975528f..21001bbd6b 100644<br>
--- a/scripts/qapi/commands.py<br>
+++ b/scripts/qapi/commands.py<br>
@@ -26,6 +26,7 @@<br>
QAPISchemaModularCVisitor,<br>
build_params,<br>
ifcontext,<br>
+ gen_special_features,<br>
)<br>
from .schema import (<br>
QAPISchema,<br>
@@ -217,9 +218,6 @@ def gen_register_command(name: str,<br>
coroutine: bool) -> str:<br>
options = []<br>
<br>
- if 'deprecated' in [<a href="http://f.name" rel="noreferrer" target="_blank">f.name</a> for f in features]:<br>
- options += ['QCO_DEPRECATED']<br>
-<br>
if not success_response:<br>
options += ['QCO_NO_SUCCESS_RESP']<br>
if allow_oob:<br>
@@ -231,10 +229,11 @@ def gen_register_command(name: str,<br>
<br>
ret = mcgen('''<br>
qmp_register_command(cmds, "%(name)s",<br>
- qmp_marshal_%(c_name)s, %(opts)s);<br>
+ qmp_marshal_%(c_name)s, %(opts)s, %(feats)s);<br>
''',<br>
name=name, c_name=c_name(name),<br>
- opts=' | '.join(options) or 0)<br>
+ opts=' | '.join(options) or 0,<br>
+ feats=gen_special_features(features))<br></blockquote><div><br></div><div>Ah, you use the '0' return here. Alright then.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
return ret<br>
<br>
<br>
-- <br>
2.31.1<br>
<br></blockquote><div><br></div><div>Python bits: Acked-by: John Snow <<a href="mailto:jsnow@redhat.com">jsnow@redhat.com</a>></div><div>C bits: "I believe in my heart that they probably work."<br></div><div><br></div><div>(for this and previous patch.)<br></div></div></div>