On Wed, Apr 07, 2021 at 20:06:30 +0200, Pavel Hrdina wrote:
On Wed, Apr 07, 2021 at 05:09:30PM +0200, Peter Krempa wrote:
> While virCommandSetDryRun is used in tests only, there were some cases
> when error paths would not call the function with NULL arguments to
> reset the dry run infrastructure.
>
> Introduce VIR_COMMAND_DRY_RUN_TOKEN macro which declares a variable
> called 'dryRunToken' which must be passed to virCommandSetDryRun.
>
> This way we can use automatic variable cleaning to trigger the cleanup
> of virCommandSetDryRun parameters and also the use of the token variable
> ensures that all callers of virCommandSetDryRun clean up after
> themselves and also that VIR_COMMAND_DRY_RUN_TOKEN isn't left unused in
> the code.
>
> Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
> ---
> src/libvirt_private.syms | 1 +
> src/util/vircommand.c | 13 ++++++++++-
> src/util/vircommandpriv.h | 10 +++++++-
> tests/networkxml2firewalltest.c | 4 ++--
> tests/nodedevmdevctltest.c | 8 +++----
> tests/nwfilterebiptablestest.c | 28 +++++++++++-----------
> tests/nwfilterxml2firewalltest.c | 4 ++--
> tests/sysinfotest.c | 4 ++--
> tests/virfirewalltest.c | 40 ++++++++++++++++----------------
> tests/viriscsitest.c | 12 +++++-----
> tests/virkmodtest.c | 8 +++----
> tests/virnetdevbandwidthtest.c | 4 ++--
> 12 files changed, 78 insertions(+), 58 deletions(-)
>
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index caa0fd18f8..e32088badb 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1983,6 +1983,7 @@ virCommandAllowCap;
> virCommandClearCaps;
> virCommandDaemonize;
> virCommandDoAsyncIO;
> +virCommandDryRunResetHelper;
> virCommandExec;
> virCommandFree;
> virCommandGetArgList;
> diff --git a/src/util/vircommand.c b/src/util/vircommand.c
> index 8ae5badf0f..7b2588f5c8 100644
> --- a/src/util/vircommand.c
> +++ b/src/util/vircommand.c
> @@ -3132,7 +3132,8 @@ virCommandDoAsyncIO(virCommandPtr cmd)
> * To cancel this effect pass NULL for @buf and @callback.
> */
> void
> -virCommandSetDryRun(virBufferPtr buf,
> +virCommandSetDryRun(virCommandDryRunToken tok G_GNUC_UNUSED,
> + virBufferPtr buf,
> virCommandDryRunCallback cb,
> void *opaque)
> {
> @@ -3141,6 +3142,16 @@ virCommandSetDryRun(virBufferPtr buf,
> dryRunOpaque = opaque;
> }
>
> +
> +void
> +virCommandDryRunResetHelper(virCommandDryRunToken *tok G_GNUC_UNUSED)
> +{
> + dryRunBuffer = NULL;
> + dryRunCallback = NULL;
> + dryRunOpaque = NULL;
> +}
> +
> +
> #ifndef WIN32
> /**
> * virCommandRunRegex:
> diff --git a/src/util/vircommandpriv.h b/src/util/vircommandpriv.h
> index 80f1d1376c..8a47a6d5e3 100644
> --- a/src/util/vircommandpriv.h
> +++ b/src/util/vircommandpriv.h
> @@ -35,6 +35,14 @@ typedef void (*virCommandDryRunCallback)(const char *const*args,
> int *status,
> void *opaque);
>
> -void virCommandSetDryRun(virBufferPtr buf,
> +typedef int virCommandDryRunToken;
> +
> +void virCommandSetDryRun(virCommandDryRunToken tok,
> + virBufferPtr buf,
> virCommandDryRunCallback cb,
> void *opaque);
> +
> +void
> +virCommandDryRunResetHelper(virCommandDryRunToken *tok);
> +
> +#define VIR_COMMAND_DRY_RUN_TOKEN
__attribute__((cleanup(virCommandDryRunResetHelper))) virCommandDryRunToken dryRunToken =
0
How about using this instead:
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(virCommandDryRunToken, virCommandDryRunResetHelper);
> diff --git a/tests/networkxml2firewalltest.c b/tests/networkxml2firewalltest.c
> index d358f12897..574b553fa6 100644
> --- a/tests/networkxml2firewalltest.c
> +++ b/tests/networkxml2firewalltest.c
> @@ -96,8 +96,9 @@ static int testCompareXMLToArgvFiles(const char *xml,
> virNetworkDefPtr def = NULL;
> int ret = -1;
> char *actual;
> + VIR_COMMAND_DRY_RUN_TOKEN;
I don't like this at all, specifically the fact that it hides
declaration of dryRunToken variable.
Here we could use this:
g_auto(virCommandDryRunToken) dryRunToken = 0;
This would be probably acceptable but I would still prefer if we could
create a new struct, for example:
struct _virCommandDryData {
virBufferPtr buf;
virCommandDryRunCallback callback;
void *opaque;
};
That way the struct would be used so clang will not complain about
unused variable and there is no need for the dummy dryRunToken.
I didn't like the VIR_COMMAND_DRY_RUN_TOKEN either but I think the
semantics of usage with the token are good.
IMO a better solution which we could also possibly use instead of the
VIR_XPATH_CTXT_AUTORESTORE macro would be to create a function which
allocates the token (thus shifting responsibility of deallocating it to
the caller/programmer) and provide a autoptr cleanup function for it to
preserve the semantics we have.
While this adds an allocation, the declaration of the variable will be
cleaner.
P.S.: looks like this series had a few conflicts recently with test
changes so if you don't plan on continuing the review right away I'll be
posting another fixed version soon.