diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6cb3003499..893859caba 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2405,6 +2405,7 @@ virFileCacheSetPriv; # util/virfirewall.h virFirewallAddCmdFull; +virFirewallAddRollbackCmd; virFirewallApply; virFirewallBackendTypeFromString; virFirewallBackendTypeToString; diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c index 77de34533d..9def8999d5 100644 --- a/src/util/virfirewall.c +++ b/src/util/virfirewall.c @@ -198,10 +198,12 @@ void virFirewallFree(virFirewall *firewall) fwCmd->args[fwCmd->argsLen++] = g_strdup(str); \ } while (0) + static virFirewallCmd * virFirewallAddCmdFullV(virFirewall *firewall, virFirewallLayer layer, bool ignoreErrors, + bool isRollback, virFirewallQueryCallback cb, void *opaque, va_list args) @@ -218,18 +220,16 @@ virFirewallAddCmdFullV(virFirewall *firewall, } group = firewall->groups[firewall->currentGroup]; - fwCmd = g_new0(virFirewallCmd, 1); - fwCmd->layer = layer; - fwCmd->queryCB = cb; - fwCmd->queryOpaque = opaque; while ((str = va_arg(args, char *)) != NULL) ADD_ARG(fwCmd, str); - if (group->addingRollback) { + if (isRollback || group->addingRollback) { fwCmd->ignoreErrors = true; /* always ignore errors when rolling back */ + fwCmd->queryCB = NULL; /* rollback commands can't have a callback */ + fwCmd->queryOpaque = NULL; VIR_APPEND_ELEMENT_COPY(group->rollback, group->nrollback, fwCmd); } else { /* when not rolling back, ignore errors if this group (transaction) @@ -237,6 +237,8 @@ virFirewallAddCmdFullV(virFirewall *firewall, * if this specific rule was created with ignoreErrors == true */ fwCmd->ignoreErrors = ignoreErrors || (group->actionFlags & VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS); + fwCmd->queryCB = cb; + fwCmd->queryOpaque = opaque; VIR_APPEND_ELEMENT_COPY(group->action, group->naction, fwCmd); } @@ -277,7 +279,33 @@ virFirewallCmd *virFirewallAddCmdFull(virFirewall *firewall, virFirewallCmd *fwCmd; va_list args; va_start(args, opaque); - fwCmd = virFirewallAddCmdFullV(firewall, layer, ignoreErrors, cb, opaque, args); + fwCmd = virFirewallAddCmdFullV(firewall, layer, ignoreErrors, false, cb, opaque, args); + va_end(args); + return fwCmd; +} + + +/** + * virFirewallAddRollbackCmd: + * @firewall: firewall commands to add to + * @layer: the firewall layer to change + * @...: NULL terminated list of strings for the command + * + * Add a command to the current firewall command group "rollback". + * Rollback commands always ignore errors and don't support any + * callbacks. + * + * Returns the new Command + */ +virFirewallCmd * +virFirewallAddRollbackCmd(virFirewall *firewall, + virFirewallLayer layer, + ...) +{ + virFirewallCmd *fwCmd; + va_list args; + va_start(args, layer); + fwCmd = virFirewallAddCmdFullV(firewall, layer, true, true, NULL, NULL, args); va_end(args); return fwCmd; } @@ -434,6 +462,21 @@ void virFirewallStartTransaction(virFirewall *firewall, firewall->currentGroup = firewall->ngroups - 1; } + +/** + * virFirewallTransactionGetFlags: + * @firewall: the firewall to look at + * + * Returns the virFirewallTransactionFlags for the currently active + * group (transaction) in @firewall. + */ +static virFirewallTransactionFlags G_GNUC_UNUSED +virFirewallTransactionGetFlags(virFirewall *firewall) +{ + return firewall->groups[firewall->currentGroup]->actionFlags; +} + + /** * virFirewallBeginRollback: * @firewall: the firewall ruleset diff --git a/src/util/virfirewall.h b/src/util/virfirewall.h index 1ca1cce10a..e6aac365f1 100644 --- a/src/util/virfirewall.h +++ b/src/util/virfirewall.h @@ -73,6 +73,11 @@ virFirewallCmd *virFirewallAddCmdFull(virFirewall *firewall, ...) G_GNUC_NULL_TERMINATED; +virFirewallCmd *virFirewallAddRollbackCmd(virFirewall *firewall, + virFirewallLayer layer, + ...) + G_GNUC_NULL_TERMINATED; + void virFirewallRemoveCmd(virFirewall *firewall, virFirewallCmd *rule); @@ -105,6 +110,8 @@ typedef enum { /* Ignore all errors when applying rules, so no * rollback block will be required */ VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS = (1 << 0), + /* Set to auto-add a rollback rule for each rule that is applied */ + VIR_FIREWALL_TRANSACTION_AUTO_ROLLBACK = (1 << 1), } virFirewallTransactionFlags; void virFirewallStartTransaction(virFirewall *firewall,