On Wed, Jul 03, 2024 at 01:01:11PM +0300, Manos Pitsidianakis wrote: > Hello Daniel, > > This cleanup seems like a good idea, > > On Thu, 13 Jun 2024 18:44, "Daniel P. Berrangé" <berra...@redhat.com> wrote: > > It is confusing having many different pieces of code enabling and > > disabling commands, and it is not clear that they all have the same > > semantics, especially wrt prioritization of the block/allow lists. > > The code attempted to prevent the user from setting both the block > > and allow lists concurrently, however, the logic was flawed as it > > checked settings in the configuration file separately from the > > command line arguments. Thus it was possible to set a block list > > in the config file and an allow list via a command line argument. > > The --dump-conf option also creates a configuration file with both > > keys present, even if unset, which means it is creating a config > > that cannot actually be loaded again. > > > > Centralizing the code in a single method "ga_apply_command_filters" > > will provide a strong guarantee of consistency and clarify the > > intended behaviour. With this there is no compelling technical > > reason to prevent concurrent setting of both the allow and block > > lists, so this flawed restriction is removed. > > > > Signed-off-by: Daniel P. Berrangé <berra...@redhat.com> > > --- > > docs/interop/qemu-ga.rst | 14 +++++ > > qga/commands-posix.c | 6 -- > > qga/commands-win32.c | 6 -- > > qga/main.c | 128 +++++++++++++++++---------------------- > > 4 files changed, 70 insertions(+), 84 deletions(-)
> > diff --git a/qga/main.c b/qga/main.c > > index f68a32bf7b..72c16fead8 100644 > > --- a/qga/main.c > > +++ b/qga/main.c > > @@ -419,60 +419,79 @@ static gint ga_strcmp(gconstpointer str1, > > gconstpointer str2) > > return strcmp(str1, str2); > > } > > > > -/* disable commands that aren't safe for fsfreeze */ > > -static void ga_disable_not_allowed_freeze(const QmpCommand *cmd, void > > *opaque) > > +static bool ga_command_is_allowed(const QmpCommand *cmd, GAState *state) > > { > > - bool allowed = false; > > int i = 0; > > + GAConfig *config = state->config; > > const char *name = qmp_command_name(cmd); > > + /* Fallback policy is allow everything */ > > + bool allowed = true; > > > > - while (ga_freeze_allowlist[i] != NULL) { > > - if (strcmp(name, ga_freeze_allowlist[i]) == 0) { > > + if (config->allowedrpcs) { > > + /* > > + * If an allow-list is given, this changes the fallback > > + * policy to deny everything > > + */ > > + allowed = false; > > + > > + if (g_list_find_custom(config->allowedrpcs, name, ga_strcmp) != > > NULL) { > > allowed = true; > > } > > - i++; > > } > > - if (!allowed) { > > - g_debug("disabling command: %s", name); > > - qmp_disable_command(&ga_commands, name, "the agent is in frozen > > state"); > > - } > > -} > > > > -/* [re-]enable all commands, except those explicitly blocked by user */ > > -static void ga_enable_non_blocked(const QmpCommand *cmd, void *opaque) > > -{ > > - GAState *s = opaque; > > - GList *blockedrpcs = s->blockedrpcs; > > - GList *allowedrpcs = s->allowedrpcs; > > - const char *name = qmp_command_name(cmd); > > - > > - if (g_list_find_custom(blockedrpcs, name, ga_strcmp) == NULL) { > > - if (qmp_command_is_enabled(cmd)) { > > - return; > > + /* > > + * If both allowedrpcs and blockedrpcs are set, the blocked > > + * list will take priority > > + */ > > + if (config->blockedrpcs) { > > + if (g_list_find_custom(config->blockedrpcs, name, ga_strcmp) != > > NULL) { > > + allowed = false; > > } > > + } > > > > - if (allowedrpcs && > > - g_list_find_custom(allowedrpcs, name, ga_strcmp) == NULL) { > > - return; > > - } > > + /* > > + * If frozen, this filtering must take priority over > > + * absolutely everything > > + */ > > + if (state->frozen) { > > + allowed = false; > > > > - g_debug("enabling command: %s", name); > > - qmp_enable_command(&ga_commands, name); > > + while (ga_freeze_allowlist[i] != NULL) { > > + if (strcmp(name, ga_freeze_allowlist[i]) == 0) { > > + allowed = true; > > + } > > + i++; > > + } > > } > > + > > + return allowed; > > } > > IUUC, we can check by priority here: first check if (state->frozen), then > blockedrpcs, then allowedrpcs and then return a default fallback value > allowed = config->blockedrpcs != NULL && config->allowedrpcs != NULL That would imply each check does an early return. When I add in the following series, I have further checks going in this method which rely on the fallthrough for overrides, which works better as it is written here. With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|