diff --git a/cts/cli/regression.access_render.exp b/cts/cli/regression.access_render.exp index f0ec2675178..ed2f704bcfd 100644 --- a/cts/cli/regression.access_render.exp +++ b/cts/cli/regression.access_render.exp @@ -1,6 +1,6 @@ =#=#=#= Begin test: Configure some ACLs =#=#=#= =#=#=#= Current cib after: Configure some ACLs =#=#=#= - + @@ -23,7 +23,7 @@ * Passed: cibadmin - Configure some ACLs =#=#=#= Begin test: Enable ACLs =#=#=#= =#=#=#= Current cib after: Enable ACLs =#=#=#= - + @@ -50,7 +50,7 @@ * Passed: crm_attribute - Enable ACLs =#=#=#= Begin test: An instance of ACLs render (into color) =#=#=#= - +    @@ -77,7 +77,7 @@ * Passed: cibadmin - An instance of ACLs render (into color) =#=#=#= Begin test: An instance of ACLs render (into namespacing) =#=#=#= - + @@ -105,7 +105,7 @@ =#=#=#= Begin test: An instance of ACLs render (into text) =#=#=#= vvv---[ READABLE ]---vvv - + diff --git a/cts/cli/regression.acls.exp b/cts/cli/regression.acls.exp index a6aeb155e23..353edeb53c3 100644 --- a/cts/cli/regression.acls.exp +++ b/cts/cli/regression.acls.exp @@ -1,6 +1,6 @@ =#=#=#= Begin test: Configure some ACLs =#=#=#= =#=#=#= Current cib after: Configure some ACLs =#=#=#= - + @@ -56,7 +56,7 @@ * Passed: cibadmin - Configure some ACLs =#=#=#= Begin test: Enable ACLs =#=#=#= =#=#=#= Current cib after: Enable ACLs =#=#=#= - + @@ -116,7 +116,7 @@ * Passed: crm_attribute - Enable ACLs =#=#=#= Begin test: Set cluster option =#=#=#= =#=#=#= Current cib after: Set cluster option =#=#=#= - + @@ -177,7 +177,7 @@ * Passed: crm_attribute - Set cluster option =#=#=#= Begin test: New ACL role =#=#=#= =#=#=#= Current cib after: New ACL role =#=#=#= - + @@ -241,7 +241,7 @@ * Passed: cibadmin - New ACL role =#=#=#= Begin test: New ACL target =#=#=#= =#=#=#= Current cib after: New ACL target =#=#=#= - + @@ -308,7 +308,7 @@ * Passed: cibadmin - New ACL target =#=#=#= Begin test: Another ACL role =#=#=#= =#=#=#= Current cib after: Another ACL role =#=#=#= - + @@ -378,7 +378,7 @@ * Passed: cibadmin - Another ACL role =#=#=#= Begin test: Another ACL target =#=#=#= =#=#=#= Current cib after: Another ACL target =#=#=#= - + @@ -451,7 +451,7 @@ * Passed: cibadmin - Another ACL target =#=#=#= Begin test: Updated ACL =#=#=#= =#=#=#= Current cib after: Updated ACL =#=#=#= - + @@ -560,7 +560,7 @@ cibadmin: CIB API call failed: Permission denied =#=#=#= End test: l33t-haxor: Create a resource - Insufficient privileges (4) =#=#=#= * Passed: cibadmin - l33t-haxor: Create a resource =#=#=#= Begin test: niceguy: Query configuration =#=#=#= - + @@ -641,7 +641,7 @@ crm_attribute: Error performing operation: Permission denied =#=#=#= Begin test: niceguy: Set fencing-enabled =#=#=#= pcmk__apply_creation_acl trace: ACLs allow creation of with id="cib-bootstrap-options-fencing-enabled" =#=#=#= Current cib after: niceguy: Set fencing-enabled =#=#=#= - + @@ -721,7 +721,7 @@ cibadmin: CIB API call failed: Permission denied =#=#=#= End test: niceguy: Create a resource - Insufficient privileges (4) =#=#=#= * Passed: cibadmin - niceguy: Create a resource =#=#=#= Begin test: root: Query configuration =#=#=#= - + @@ -796,7 +796,7 @@ cibadmin: CIB API call failed: Permission denied * Passed: cibadmin - root: Query configuration =#=#=#= Begin test: root: Set fencing-enabled =#=#=#= =#=#=#= Current cib after: root: Set fencing-enabled =#=#=#= - + @@ -871,7 +871,7 @@ cibadmin: CIB API call failed: Permission denied * Passed: crm_attribute - root: Set fencing-enabled =#=#=#= Begin test: root: Create a resource =#=#=#= =#=#=#= Current cib after: root: Create a resource =#=#=#= - + @@ -948,7 +948,7 @@ cibadmin: CIB API call failed: Permission denied * Passed: cibadmin - root: Create a resource =#=#=#= Begin test: root: Create another resource (with description) =#=#=#= =#=#=#= Current cib after: root: Create another resource (with description) =#=#=#= - + @@ -1045,7 +1045,7 @@ pcmk__apply_creation_acl trace: Creation of scaffolding with pcmk__apply_creation_acl trace: ACLs allow creation of with id="dummy-meta_attributes-target-role" Set 'dummy' option: id=dummy-meta_attributes-target-role set=dummy-meta_attributes name=target-role value=Stopped =#=#=#= Current cib after: niceguy: Create a resource meta attribute =#=#=#= - + @@ -1129,7 +1129,7 @@ Set 'dummy' option: id=dummy-meta_attributes-target-role set=dummy-meta_attribut unpack_resources error: Resource start-up disabled since no fencing resources have been defined. Either configure some or disable fencing with the fencing-enabled option. NOTE: Clusters with shared data need fencing to ensure data integrity. Stopped =#=#=#= Current cib after: niceguy: Query a resource meta attribute =#=#=#= - + @@ -1213,7 +1213,7 @@ Stopped unpack_resources error: Resource start-up disabled since no fencing resources have been defined. Either configure some or disable fencing with the fencing-enabled option. NOTE: Clusters with shared data need fencing to ensure data integrity. Deleted 'dummy' option: id=dummy-meta_attributes-target-role name=target-role =#=#=#= Current cib after: niceguy: Remove a resource meta attribute =#=#=#= - + @@ -1296,7 +1296,7 @@ unpack_resources error: Resource start-up disabled since no fencing resources h pcmk__apply_creation_acl trace: ACLs allow creation of with id="dummy-meta_attributes-target-role" Set 'dummy' option: id=dummy-meta_attributes-target-role set=dummy-meta_attributes name=target-role value=Started =#=#=#= Current cib after: niceguy: Create a resource meta attribute =#=#=#= - + @@ -1404,7 +1404,7 @@ Set 'dummy' option: id=dummy-meta_attributes-target-role set=dummy-meta_attribut =#=#=#= End test: betteridea: Query configuration - explicit deny - OK (0) =#=#=#= * Passed: cibadmin - betteridea: Query configuration - explicit deny - + @@ -1432,7 +1432,7 @@ pcmk__check_acl trace: Default ACL denies user 'niceguy' read/write access to / cibadmin: CIB API call failed: Permission denied =#=#=#= End test: niceguy: Replace - remove acls - Insufficient privileges (4) =#=#=#= * Passed: cibadmin - niceguy: Replace - remove acls - + @@ -1518,7 +1518,7 @@ pcmk__apply_creation_acl trace: ACLs disallow creation of with id=" cibadmin: CIB API call failed: Permission denied =#=#=#= End test: niceguy: Replace - create resource - Insufficient privileges (4) =#=#=#= * Passed: cibadmin - niceguy: Replace - create resource - + @@ -1602,7 +1602,7 @@ pcmk__check_acl trace: Default ACL denies user 'niceguy' read/write access to / cibadmin: CIB API call failed: Permission denied =#=#=#= End test: niceguy: Replace - modify attribute (deny) - Insufficient privileges (4) =#=#=#= * Passed: cibadmin - niceguy: Replace - modify attribute (deny) - + @@ -1686,7 +1686,7 @@ pcmk__check_acl trace: Default ACL denies user 'niceguy' read/write access to / cibadmin: CIB API call failed: Permission denied =#=#=#= End test: niceguy: Replace - delete attribute (deny) - Insufficient privileges (4) =#=#=#= * Passed: cibadmin - niceguy: Replace - delete attribute (deny) - + @@ -1770,7 +1770,7 @@ pcmk__check_acl trace: Default ACL denies user 'niceguy' read/write access to / cibadmin: CIB API call failed: Permission denied =#=#=#= End test: niceguy: Replace - create attribute (deny) - Insufficient privileges (4) =#=#=#= * Passed: cibadmin - niceguy: Replace - create attribute (deny) - + @@ -1851,7 +1851,7 @@ cibadmin: CIB API call failed: Permission denied =#=#=#= Begin test: bob: Replace - create attribute (direct allow) =#=#=#= =#=#=#= End test: bob: Replace - create attribute (direct allow) - OK (0) =#=#=#= * Passed: cibadmin - bob: Replace - create attribute (direct allow) - + @@ -1932,7 +1932,7 @@ cibadmin: CIB API call failed: Permission denied =#=#=#= Begin test: bob: Replace - modify attribute (direct allow) =#=#=#= =#=#=#= End test: bob: Replace - modify attribute (direct allow) - OK (0) =#=#=#= * Passed: cibadmin - bob: Replace - modify attribute (direct allow) - + @@ -2009,7 +2009,7 @@ cibadmin: CIB API call failed: Permission denied =#=#=#= Begin test: bob: Replace - delete attribute (direct allow) =#=#=#= =#=#=#= End test: bob: Replace - delete attribute (direct allow) - OK (0) =#=#=#= * Passed: cibadmin - bob: Replace - delete attribute (direct allow) - + @@ -2086,7 +2086,7 @@ cibadmin: CIB API call failed: Permission denied =#=#=#= Begin test: joe: Replace - create attribute (inherited allow) =#=#=#= =#=#=#= End test: joe: Replace - create attribute (inherited allow) - OK (0) =#=#=#= * Passed: cibadmin - joe: Replace - create attribute (inherited allow) - + @@ -2163,7 +2163,7 @@ cibadmin: CIB API call failed: Permission denied =#=#=#= Begin test: joe: Replace - modify attribute (inherited allow) =#=#=#= =#=#=#= End test: joe: Replace - modify attribute (inherited allow) - OK (0) =#=#=#= * Passed: cibadmin - joe: Replace - modify attribute (inherited allow) - + @@ -2240,7 +2240,7 @@ cibadmin: CIB API call failed: Permission denied =#=#=#= Begin test: joe: Replace - delete attribute (inherited allow) =#=#=#= =#=#=#= End test: joe: Replace - delete attribute (inherited allow) - OK (0) =#=#=#= * Passed: cibadmin - joe: Replace - delete attribute (inherited allow) - + @@ -2317,7 +2317,7 @@ cibadmin: CIB API call failed: Permission denied =#=#=#= Begin test: mike: Replace - create attribute (allow overrides deny) =#=#=#= =#=#=#= End test: mike: Replace - create attribute (allow overrides deny) - OK (0) =#=#=#= * Passed: cibadmin - mike: Replace - create attribute (allow overrides deny) - + @@ -2394,7 +2394,7 @@ cibadmin: CIB API call failed: Permission denied =#=#=#= Begin test: mike: Replace - modify attribute (allow overrides deny) =#=#=#= =#=#=#= End test: mike: Replace - modify attribute (allow overrides deny) - OK (0) =#=#=#= * Passed: cibadmin - mike: Replace - modify attribute (allow overrides deny) - + @@ -2471,7 +2471,7 @@ cibadmin: CIB API call failed: Permission denied =#=#=#= Begin test: mike: Replace - delete attribute (allow overrides deny) =#=#=#= =#=#=#= End test: mike: Replace - delete attribute (allow overrides deny) - OK (0) =#=#=#= * Passed: cibadmin - mike: Replace - delete attribute (allow overrides deny) - + @@ -2548,7 +2548,7 @@ cibadmin: CIB API call failed: Permission denied =#=#=#= Begin test: mike: Create another resource =#=#=#= pcmk__apply_creation_acl trace: ACLs allow creation of with id="dummy2" =#=#=#= Current cib after: mike: Create another resource =#=#=#= - + @@ -2625,7 +2625,7 @@ pcmk__apply_creation_acl trace: ACLs allow creation of with id="dum =#=#=#= End test: mike: Create another resource - OK (0) =#=#=#= * Passed: cibadmin - mike: Create another resource - + @@ -2705,7 +2705,7 @@ pcmk__check_acl trace: Parent ACL denies user 'chris' read/write access to /cib cibadmin: CIB API call failed: Permission denied =#=#=#= End test: chris: Replace - create attribute (deny overrides allow) - Insufficient privileges (4) =#=#=#= * Passed: cibadmin - chris: Replace - create attribute (deny overrides allow) - + @@ -2785,7 +2785,7 @@ pcmk__check_acl trace: Parent ACL denies user 'chris' read/write access to /cib cibadmin: CIB API call failed: Permission denied =#=#=#= End test: chris: Replace - modify attribute (deny overrides allow) - Insufficient privileges (4) =#=#=#= * Passed: cibadmin - chris: Replace - modify attribute (deny overrides allow) - + diff --git a/cts/cli/regression.cibadmin.exp b/cts/cli/regression.cibadmin.exp index 94d919f082e..0b009a88815 100644 --- a/cts/cli/regression.cibadmin.exp +++ b/cts/cli/regression.cibadmin.exp @@ -1,5 +1,5 @@ =#=#=#= Begin test: Validate CIB =#=#=#= - + @@ -17,7 +17,7 @@ =#=#=#= Current cib after: Validate CIB =#=#=#= - + @@ -38,7 +38,7 @@ * Passed: cibadmin - Validate CIB =#=#=#= Begin test: Validate CIB (XML) =#=#=#= - + @@ -59,7 +59,7 @@ =#=#=#= Current cib after: Validate CIB (XML) =#=#=#= - + @@ -79,12 +79,12 @@ =#=#=#= End test: Validate CIB (XML) - OK (0) =#=#=#= * Passed: cibadmin - Validate CIB (XML) =#=#=#= Begin test: Digest calculation =#=#=#= -9130d6f39c2b83bd032a00e76621508c +1f3492630cde57d6b7ee45de4d390469 =#=#=#= End test: Digest calculation - OK (0) =#=#=#= * Passed: cibadmin - Digest calculation =#=#=#= Begin test: Digest calculation (XML) =#=#=#= - + =#=#=#= End test: Digest calculation (XML) - OK (0) =#=#=#= @@ -92,7 +92,7 @@ =#=#=#= Begin test: Require --force for CIB erasure =#=#=#= cibadmin: The supplied command is considered dangerous. To prevent accidental destruction of the cluster, the --force flag is required in order to proceed. =#=#=#= Current cib after: Require --force for CIB erasure =#=#=#= - + @@ -120,7 +120,7 @@ cibadmin: The supplied command is considered dangerous. To prevent accidental de =#=#=#= Current cib after: Require --force for CIB erasure (XML) =#=#=#= - + @@ -149,7 +149,7 @@ cibadmin: The supplied command is considered dangerous. To prevent accidental de =#=#=#= End test: Allow CIB erasure with --force (XML) - OK (0) =#=#=#= * Passed: cibadmin - Allow CIB erasure with --force (XML) =#=#=#= Begin test: Query CIB =#=#=#= - + @@ -159,7 +159,7 @@ cibadmin: The supplied command is considered dangerous. To prevent accidental de =#=#=#= Current cib after: Query CIB =#=#=#= - + @@ -172,7 +172,7 @@ cibadmin: The supplied command is considered dangerous. To prevent accidental de * Passed: cibadmin - Query CIB =#=#=#= Begin test: Query CIB (XML) =#=#=#= - + @@ -185,7 +185,7 @@ cibadmin: The supplied command is considered dangerous. To prevent accidental de =#=#=#= Current cib after: Query CIB (XML) =#=#=#= - + diff --git a/cts/cli/regression.crm_attribute.exp b/cts/cli/regression.crm_attribute.exp index 882f5da2113..a9e69cec54c 100644 --- a/cts/cli/regression.crm_attribute.exp +++ b/cts/cli/regression.crm_attribute.exp @@ -1067,7 +1067,7 @@ crm_attribute: Error performing operation: No such device or address * Passed: crm_attribute - Query the value of an attribute that does not exist =#=#=#= Begin test: Configure something before erasing =#=#=#= =#=#=#= Current cib after: Configure something before erasing =#=#=#= - + @@ -1084,7 +1084,7 @@ crm_attribute: Error performing operation: No such device or address * Passed: crm_attribute - Configure something before erasing =#=#=#= Begin test: Test '++' XML attribute update syntax =#=#=#= =#=#=#= Current cib after: Test '++' XML attribute update syntax =#=#=#= - + @@ -1101,7 +1101,7 @@ crm_attribute: Error performing operation: No such device or address * Passed: cibadmin - Test '++' XML attribute update syntax =#=#=#= Begin test: Test '+=' XML attribute update syntax =#=#=#= =#=#=#= Current cib after: Test '+=' XML attribute update syntax =#=#=#= - + @@ -1118,7 +1118,7 @@ crm_attribute: Error performing operation: No such device or address * Passed: cibadmin - Test '+=' XML attribute update syntax =#=#=#= Begin test: Test '++' nvpair value update syntax =#=#=#= =#=#=#= Current cib after: Test '++' nvpair value update syntax =#=#=#= - + @@ -1138,7 +1138,7 @@ crm_attribute: Error performing operation: No such device or address =#=#=#= Current cib after: Test '++' nvpair value update syntax (XML) =#=#=#= - + @@ -1155,7 +1155,7 @@ crm_attribute: Error performing operation: No such device or address * Passed: crm_attribute - Test '++' nvpair value update syntax (XML) =#=#=#= Begin test: Test '+=' nvpair value update syntax =#=#=#= =#=#=#= Current cib after: Test '+=' nvpair value update syntax =#=#=#= - + @@ -1175,7 +1175,7 @@ crm_attribute: Error performing operation: No such device or address =#=#=#= Current cib after: Test '+=' nvpair value update syntax (XML) =#=#=#= - + @@ -1192,7 +1192,7 @@ crm_attribute: Error performing operation: No such device or address * Passed: crm_attribute - Test '+=' nvpair value update syntax (XML) =#=#=#= Begin test: Test '++' XML attribute update syntax (--score not set) =#=#=#= =#=#=#= Current cib after: Test '++' XML attribute update syntax (--score not set) =#=#=#= - + @@ -1209,7 +1209,7 @@ crm_attribute: Error performing operation: No such device or address * Passed: cibadmin - Test '++' XML attribute update syntax (--score not set) =#=#=#= Begin test: Test '+=' XML attribute update syntax (--score not set) =#=#=#= =#=#=#= Current cib after: Test '+=' XML attribute update syntax (--score not set) =#=#=#= - + @@ -1226,7 +1226,7 @@ crm_attribute: Error performing operation: No such device or address * Passed: cibadmin - Test '+=' XML attribute update syntax (--score not set) =#=#=#= Begin test: Test '++' nvpair value update syntax (--score not set) =#=#=#= =#=#=#= Current cib after: Test '++' nvpair value update syntax (--score not set) =#=#=#= - + @@ -1246,7 +1246,7 @@ crm_attribute: Error performing operation: No such device or address =#=#=#= Current cib after: Test '++' nvpair value update syntax (--score not set) (XML) =#=#=#= - + @@ -1263,7 +1263,7 @@ crm_attribute: Error performing operation: No such device or address * Passed: crm_attribute - Test '++' nvpair value update syntax (--score not set) (XML) =#=#=#= Begin test: Test '+=' nvpair value update syntax (--score not set) =#=#=#= =#=#=#= Current cib after: Test '+=' nvpair value update syntax (--score not set) =#=#=#= - + @@ -1283,7 +1283,7 @@ crm_attribute: Error performing operation: No such device or address =#=#=#= Current cib after: Test '+=' nvpair value update syntax (--score not set) (XML) =#=#=#= - + @@ -1300,7 +1300,7 @@ crm_attribute: Error performing operation: No such device or address * Passed: crm_attribute - Test '+=' nvpair value update syntax (--score not set) (XML) =#=#=#= Begin test: Set cluster option =#=#=#= =#=#=#= Current cib after: Set cluster option =#=#=#= - + @@ -1321,7 +1321,7 @@ crm_attribute: Error performing operation: No such device or address * Passed: cibadmin - Query new cluster option =#=#=#= Begin test: Set no-quorum policy =#=#=#= =#=#=#= Current cib after: Set no-quorum policy =#=#=#= - + @@ -1339,7 +1339,7 @@ crm_attribute: Error performing operation: No such device or address * Passed: crm_attribute - Set no-quorum policy =#=#=#= Begin test: Delete nvpair =#=#=#= =#=#=#= Current cib after: Delete nvpair =#=#=#= - + @@ -1364,7 +1364,7 @@ cibadmin: CIB API call failed: File exists =#=#=#= Current cib after: Create operation should fail =#=#=#= - + @@ -1381,7 +1381,7 @@ cibadmin: CIB API call failed: File exists * Passed: cibadmin - Create operation should fail =#=#=#= Begin test: Modify cluster options section =#=#=#= =#=#=#= Current cib after: Modify cluster options section =#=#=#= - + @@ -1400,7 +1400,7 @@ cibadmin: CIB API call failed: File exists =#=#=#= Begin test: Query updated cluster option =#=#=#= =#=#=#= Current cib after: Query updated cluster option =#=#=#= - + @@ -1418,7 +1418,7 @@ cibadmin: CIB API call failed: File exists * Passed: cibadmin - Query updated cluster option =#=#=#= Begin test: Set duplicate cluster option =#=#=#= =#=#=#= Current cib after: Set duplicate cluster option =#=#=#= - + @@ -1443,7 +1443,7 @@ Multiple attributes match name=cluster-delay Value: 60s (id=cib-bootstrap-options-cluster-delay) Value: 40s (id=duplicate-cluster-delay) =#=#=#= Current cib after: Setting multiply defined cluster option should fail =#=#=#= - + @@ -1464,7 +1464,7 @@ Multiple attributes match name=cluster-delay * Passed: crm_attribute - Setting multiply defined cluster option should fail =#=#=#= Begin test: Set cluster option with -s =#=#=#= =#=#=#= Current cib after: Set cluster option with -s =#=#=#= - + @@ -1486,7 +1486,7 @@ Multiple attributes match name=cluster-delay =#=#=#= Begin test: Delete cluster option with -i =#=#=#= Deleted crm_config option: id=(null) name=cluster-delay =#=#=#= Current cib after: Delete cluster option with -i =#=#=#= - + @@ -1526,7 +1526,7 @@ Revised Cluster Status: * Full List of Resources: * No resources =#=#=#= Current cib after: Create node1 and bring it online =#=#=#= - + @@ -1550,7 +1550,7 @@ Revised Cluster Status: * Passed: crm_simulate - Create node1 and bring it online =#=#=#= Begin test: Create node attribute =#=#=#= =#=#=#= Current cib after: Create node attribute =#=#=#= - + @@ -1579,7 +1579,7 @@ Revised Cluster Status: =#=#=#= Begin test: Query new node attribute =#=#=#= =#=#=#= Current cib after: Query new node attribute =#=#=#= - + @@ -1607,7 +1607,7 @@ Revised Cluster Status: * Passed: cibadmin - Query new node attribute =#=#=#= Begin test: Create second node attribute =#=#=#= =#=#=#= Current cib after: Create second node attribute =#=#=#= - + @@ -1641,7 +1641,7 @@ scope=nodes name=rattr value=XYZ * Passed: crm_attribute - Query node attributes by pattern =#=#=#= Begin test: Update node attributes by pattern =#=#=#= =#=#=#= Current cib after: Update node attributes by pattern =#=#=#= - + @@ -1671,7 +1671,7 @@ scope=nodes name=rattr value=XYZ =#=#=#= Begin test: Delete node attributes by pattern =#=#=#= Deleted nodes attribute: id=nodes-node1-rattr name=rattr =#=#=#= Current cib after: Delete node attributes by pattern =#=#=#= - + @@ -1699,7 +1699,7 @@ Deleted nodes attribute: id=nodes-node1-rattr name=rattr * Passed: crm_attribute - Delete node attributes by pattern =#=#=#= Begin test: Set a transient (fail-count) node attribute =#=#=#= =#=#=#= Current cib after: Set a transient (fail-count) node attribute =#=#=#= - + @@ -1734,7 +1734,7 @@ Deleted nodes attribute: id=nodes-node1-rattr name=rattr =#=#=#= Begin test: Query a fail count =#=#=#= scope=status name=fail-count-foo value=3 =#=#=#= Current cib after: Query a fail count =#=#=#= - + @@ -1782,7 +1782,7 @@ Current cluster status: * Passed: crm_simulate - Show node attributes with crm_simulate =#=#=#= Begin test: Set a second transient node attribute =#=#=#= =#=#=#= Current cib after: Set a second transient node attribute =#=#=#= - + @@ -1822,7 +1822,7 @@ scope=status name=fail-count-bar value=5 * Passed: crm_attribute - Query transient node attributes by pattern =#=#=#= Begin test: Update transient node attributes by pattern =#=#=#= =#=#=#= Current cib after: Update transient node attributes by pattern =#=#=#= - + @@ -1859,7 +1859,7 @@ scope=status name=fail-count-bar value=5 Deleted status attribute: id=status-node1-fail-count-foo name=fail-count-foo Deleted status attribute: id=status-node1-fail-count-bar name=fail-count-bar =#=#=#= Current cib after: Delete transient node attributes by pattern =#=#=#= - + @@ -1895,7 +1895,7 @@ crm_attribute: Error: must specify attribute name or pattern to delete * Passed: crm_attribute - crm_attribute given invalid delete usage =#=#=#= Begin test: Set a utilization node attribute =#=#=#= =#=#=#= Current cib after: Set a utilization node attribute =#=#=#= - + diff --git a/cts/cli/regression.crm_resource.exp b/cts/cli/regression.crm_resource.exp index 394d5b933a8..1b8f728f653 100644 --- a/cts/cli/regression.crm_resource.exp +++ b/cts/cli/regression.crm_resource.exp @@ -824,7 +824,7 @@ Special parameters that are available for all fencing resources, regardless of t * Passed: crm_resource - List all available fencing parameters (XML) =#=#=#= Begin test: Create a resource =#=#=#= =#=#=#= Current cib after: Create a resource =#=#=#= - + @@ -857,7 +857,7 @@ crm_resource: --class, --agent, and --provider can only be used with --validate unpack_resources error: Resource start-up disabled since no fencing resources have been defined. Either configure some or disable fencing with the fencing-enabled option. NOTE: Clusters with shared data need fencing to ensure data integrity. Set 'dummy' option: id=dummy-meta_attributes-is-managed set=dummy-meta_attributes name=is-managed value=false =#=#=#= Current cib after: Create a resource meta attribute =#=#=#= - + @@ -886,7 +886,7 @@ Set 'dummy' option: id=dummy-meta_attributes-is-managed set=dummy-meta_attribute unpack_resources error: Resource start-up disabled since no fencing resources have been defined. Either configure some or disable fencing with the fencing-enabled option. NOTE: Clusters with shared data need fencing to ensure data integrity. false =#=#=#= Current cib after: Query a resource meta attribute =#=#=#= - + @@ -915,7 +915,7 @@ false unpack_resources error: Resource start-up disabled since no fencing resources have been defined. Either configure some or disable fencing with the fencing-enabled option. NOTE: Clusters with shared data need fencing to ensure data integrity. Deleted 'dummy' option: id=dummy-meta_attributes-is-managed name=is-managed =#=#=#= Current cib after: Remove a resource meta attribute =#=#=#= - + @@ -984,7 +984,7 @@ unpack_resources error: Resource start-up disabled since no fencing resources h unpack_resources error: Resource start-up disabled since no fencing resources have been defined. Either configure some or disable fencing with the fencing-enabled option. NOTE: Clusters with shared data need fencing to ensure data integrity. Attribute 'nonexistent' not found for 'dummy' =#=#=#= Current cib after: Get a non-existent attribute from a resource element =#=#=#= - + @@ -1017,7 +1017,7 @@ unpack_resources error: Resource start-up disabled since no fencing resources h =#=#=#= Current cib after: Get a non-existent attribute from a resource element (XML) =#=#=#= - + @@ -1044,7 +1044,7 @@ unpack_resources error: Resource start-up disabled since no fencing resources h unpack_resources error: Resource start-up disabled since no fencing resources have been defined. Either configure some or disable fencing with the fencing-enabled option. NOTE: Clusters with shared data need fencing to ensure data integrity. ocf =#=#=#= Current cib after: Get an existent attribute from a resource element =#=#=#= - + @@ -1073,7 +1073,7 @@ unpack_resources error: Resource start-up disabled since no fencing resources h =#=#=#= Current cib after: Set a non-existent attribute for a resource element (XML) =#=#=#= - + @@ -1102,7 +1102,7 @@ unpack_resources error: Resource start-up disabled since no fencing resources h =#=#=#= Current cib after: Set an existent attribute for a resource element (XML) =#=#=#= - + @@ -1131,7 +1131,7 @@ unpack_resources error: Resource start-up disabled since no fencing resources h =#=#=#= Current cib after: Delete an existent attribute for a resource element (XML) =#=#=#= - + @@ -1160,7 +1160,7 @@ unpack_resources error: Resource start-up disabled since no fencing resources h =#=#=#= Current cib after: Delete a non-existent attribute for a resource element (XML) =#=#=#= - + @@ -1187,7 +1187,7 @@ unpack_resources error: Resource start-up disabled since no fencing resources h unpack_resources error: Resource start-up disabled since no fencing resources have been defined. Either configure some or disable fencing with the fencing-enabled option. NOTE: Clusters with shared data need fencing to ensure data integrity. Set attribute: name=description value=test_description =#=#=#= Current cib after: Set a non-existent attribute for a resource element =#=#=#= - + @@ -1214,7 +1214,7 @@ Set attribute: name=description value=test_description unpack_resources error: Resource start-up disabled since no fencing resources have been defined. Either configure some or disable fencing with the fencing-enabled option. NOTE: Clusters with shared data need fencing to ensure data integrity. Set attribute: name=description value=test_description =#=#=#= Current cib after: Set an existent attribute for a resource element =#=#=#= - + @@ -1241,7 +1241,7 @@ Set attribute: name=description value=test_description unpack_resources error: Resource start-up disabled since no fencing resources have been defined. Either configure some or disable fencing with the fencing-enabled option. NOTE: Clusters with shared data need fencing to ensure data integrity. Deleted attribute: description =#=#=#= Current cib after: Delete an existent attribute for a resource element =#=#=#= - + @@ -1268,7 +1268,7 @@ Deleted attribute: description unpack_resources error: Resource start-up disabled since no fencing resources have been defined. Either configure some or disable fencing with the fencing-enabled option. NOTE: Clusters with shared data need fencing to ensure data integrity. Deleted attribute: description =#=#=#= Current cib after: Delete a non-existent attribute for a resource element =#=#=#= - + @@ -1295,7 +1295,7 @@ Deleted attribute: description unpack_resources error: Resource start-up disabled since no fencing resources have been defined. Either configure some or disable fencing with the fencing-enabled option. NOTE: Clusters with shared data need fencing to ensure data integrity. Set 'dummy' option: id=dummy-instance_attributes-delay set=dummy-instance_attributes name=delay value=10s =#=#=#= Current cib after: Create a resource attribute =#=#=#= - + @@ -1326,7 +1326,7 @@ unpack_resources error: Resource start-up disabled since no fencing resources h Full List of Resources: * dummy (ocf:pacemaker:Dummy): Stopped =#=#=#= Current cib after: List the configured resources =#=#=#= - + @@ -1361,7 +1361,7 @@ unpack_resources error: Resource start-up disabled since no fencing resources h =#=#=#= Current cib after: List the configured resources (XML) =#=#=#= - + @@ -1432,7 +1432,7 @@ unpack_resources error: Resource start-up disabled since no fencing resources h crm_resource: Resource 'dummy' not moved: active in 0 locations. To prevent 'dummy' from running on a specific location, specify a node. =#=#=#= Current cib after: Require a destination when migrating a resource that is stopped =#=#=#= - + @@ -1463,7 +1463,7 @@ unpack_resources error: Resource start-up disabled since no fencing resources h crm_resource: Node 'i.do.not.exist' not found Error performing operation: No such object =#=#=#= Current cib after: Don't support migration to non-existent locations =#=#=#= - + @@ -1491,7 +1491,7 @@ Error performing operation: No such object * Passed: crm_resource - Don't support migration to non-existent locations =#=#=#= Begin test: Create a fencing resource =#=#=#= =#=#=#= Current cib after: Create a fencing resource =#=#=#= - + @@ -1545,7 +1545,7 @@ Revised Cluster Status: * dummy (ocf:pacemaker:Dummy): Started node1 * Fence (stonith:fence_true): Started node1 =#=#=#= Current cib after: Bring resources online =#=#=#= - + @@ -1586,7 +1586,7 @@ Revised Cluster Status: =#=#=#= Begin test: Try to move a resource to its existing location =#=#=#= crm_resource: Error performing operation: Requested item already exists =#=#=#= Current cib after: Try to move a resource to its existing location =#=#=#= - + @@ -1634,7 +1634,7 @@ WARNING: Creating rsc_location constraint 'cli-ban-dummy-on-node1' with a score This will prevent dummy from running on node1 until the constraint is removed using the clear option or by editing the CIB with an appropriate tool. This will be the case even if node1 is the last node in the cluster =#=#=#= Current cib after: Move a resource from its existing location =#=#=#= - + @@ -1677,7 +1677,7 @@ WARNING: Creating rsc_location constraint 'cli-ban-dummy-on-node1' with a score =#=#=#= Begin test: Clear out constraints generated by --move =#=#=#= Removing constraint: cli-ban-dummy-on-node1 =#=#=#= Current cib after: Clear out constraints generated by --move =#=#=#= - + @@ -1752,7 +1752,7 @@ Revised Cluster Status: * dummy (ocf:pacemaker:Dummy): Started node1 * Fence (stonith:fence_true): Started node2 =#=#=#= Current cib after: Create two more nodes and bring them online =#=#=#= - + @@ -1821,7 +1821,7 @@ WARNING: Creating rsc_location constraint 'cli-ban-dummy-on-node1' with a score This will prevent dummy from running on node1 until the constraint is removed using the clear option or by editing the CIB with an appropriate tool. This will be the case even if node1 is the last node in the cluster =#=#=#= Current cib after: Ban dummy from node1 =#=#=#= - + @@ -1901,7 +1901,7 @@ Locations: =#=#=#= Current cib after: Ban dummy from node2 (XML) =#=#=#= - + @@ -1992,7 +1992,7 @@ Revised Cluster Status: * dummy (ocf:pacemaker:Dummy): Started node3 * Fence (stonith:fence_true): Started node2 =#=#=#= Current cib after: Relocate resources due to ban =#=#=#= - + @@ -2064,7 +2064,7 @@ Revised Cluster Status: =#=#=#= Current cib after: Move dummy to node1 (XML) =#=#=#= - + @@ -2134,7 +2134,7 @@ Revised Cluster Status: =#=#=#= Begin test: Clear implicit constraints for dummy on node2 =#=#=#= Removing constraint: cli-ban-dummy-on-node2 =#=#=#= Current cib after: Clear implicit constraints for dummy on node2 =#=#=#= - + @@ -2210,7 +2210,7 @@ Removing constraint: cli-ban-dummy-on-node2 Performing update of 'is-managed' on 'test-clone', the parent of 'test-primitive' Set 'test-clone' option: id=test-clone-meta_attributes-is-managed set=test-clone-meta_attributes name=is-managed value=false =#=#=#= Current cib after: Create a resource meta attribute =#=#=#= - + @@ -2248,7 +2248,7 @@ Set 'test-clone' option: id=test-clone-meta_attributes-is-managed set=test-clone =#=#=#= Begin test: Create a resource meta attribute in the primitive =#=#=#= Set 'test-primitive' option: id=test-primitive-meta_attributes-is-managed set=test-primitive-meta_attributes name=is-managed value=false =#=#=#= Current cib after: Create a resource meta attribute in the primitive =#=#=#= - + @@ -2295,7 +2295,7 @@ Multiple attributes match name=is-managed A value for 'is-managed' already exists in child 'test-primitive', performing update on that instead of 'test-clone' Set 'test-primitive' option: id=test-primitive-meta_attributes-is-managed name=is-managed value=true =#=#=#= Current cib after: Update resource meta attribute with duplicates =#=#=#= - + @@ -2337,7 +2337,7 @@ Set 'test-primitive' option: id=test-primitive-meta_attributes-is-managed name=i =#=#=#= Begin test: Update resource meta attribute with duplicates (force clone) =#=#=#= Set 'test-clone' option: id=test-clone-meta_attributes-is-managed name=is-managed value=true =#=#=#= Current cib after: Update resource meta attribute with duplicates (force clone) =#=#=#= - + @@ -2383,7 +2383,7 @@ Multiple attributes match name=is-managed Set 'test-primitive' option: id=test-primitive-meta_attributes-is-managed name=is-managed value=false =#=#=#= Current cib after: Update child resource meta attribute with duplicates =#=#=#= - + @@ -2430,7 +2430,7 @@ Multiple attributes match name=is-managed A value for 'is-managed' already exists in child 'test-primitive', performing delete on that instead of 'test-clone' Deleted 'test-primitive' option: id=test-primitive-meta_attributes-is-managed name=is-managed =#=#=#= Current cib after: Delete resource meta attribute with duplicates =#=#=#= - + @@ -2471,7 +2471,7 @@ Deleted 'test-primitive' option: id=test-primitive-meta_attributes-is-managed na Performing delete of 'is-managed' on 'test-clone', the parent of 'test-primitive' Deleted 'test-clone' option: id=test-clone-meta_attributes-is-managed name=is-managed =#=#=#= Current cib after: Delete resource meta attribute in parent =#=#=#= - + @@ -2509,7 +2509,7 @@ Deleted 'test-clone' option: id=test-clone-meta_attributes-is-managed name=is-ma =#=#=#= Begin test: Create a resource meta attribute in the primitive =#=#=#= Set 'test-primitive' option: id=test-primitive-meta_attributes-is-managed set=test-primitive-meta_attributes name=is-managed value=false =#=#=#= Current cib after: Create a resource meta attribute in the primitive =#=#=#= - + @@ -2550,7 +2550,7 @@ Set 'test-primitive' option: id=test-primitive-meta_attributes-is-managed set=te A value for 'is-managed' already exists in child 'test-primitive', performing update on that instead of 'test-clone' Set 'test-primitive' option: id=test-primitive-meta_attributes-is-managed name=is-managed value=true =#=#=#= Current cib after: Update existing resource meta attribute =#=#=#= - + @@ -2590,7 +2590,7 @@ Set 'test-primitive' option: id=test-primitive-meta_attributes-is-managed name=i =#=#=#= Begin test: Create a resource meta attribute in the parent =#=#=#= Set 'test-clone' option: id=test-clone-meta_attributes-is-managed set=test-clone-meta_attributes name=is-managed value=true =#=#=#= Current cib after: Create a resource meta attribute in the parent =#=#=#= - + @@ -2632,7 +2632,7 @@ Set 'test-clone' option: id=test-clone-meta_attributes-is-managed set=test-clone =#=#=#= Begin test: Delete resource parent meta attribute (force) =#=#=#= Deleted 'test-clone' option: id=test-clone-meta_attributes-is-managed name=is-managed =#=#=#= Current cib after: Delete resource parent meta attribute (force) =#=#=#= - + @@ -2676,7 +2676,7 @@ Multiple attributes match name=is-managed Deleted 'test-primitive' option: id=test-primitive-meta_attributes-is-managed name=is-managed =#=#=#= Current cib after: Delete resource child meta attribute =#=#=#= - + @@ -2715,7 +2715,7 @@ Deleted 'test-primitive' option: id=test-primitive-meta_attributes-is-managed na * Passed: crm_resource - Delete resource child meta attribute =#=#=#= Begin test: Create the dummy-group resource group =#=#=#= =#=#=#= Current cib after: Create the dummy-group resource group =#=#=#= - + @@ -2759,7 +2759,7 @@ Deleted 'test-primitive' option: id=test-primitive-meta_attributes-is-managed na =#=#=#= Begin test: Create a resource meta attribute in dummy1 =#=#=#= Set 'dummy1' option: id=dummy1-meta_attributes-is-managed set=dummy1-meta_attributes name=is-managed value=true =#=#=#= Current cib after: Create a resource meta attribute in dummy1 =#=#=#= - + @@ -2808,7 +2808,7 @@ Set 'dummy1' option: id=dummy1-meta_attributes-is-managed set=dummy1-meta_attrib Set 'dummy1' option: id=dummy1-meta_attributes-is-managed name=is-managed value=false Set 'dummy-group' option: id=dummy-group-meta_attributes-is-managed set=dummy-group-meta_attributes name=is-managed value=false =#=#=#= Current cib after: Create a resource meta attribute in dummy-group =#=#=#= - + @@ -2858,7 +2858,7 @@ Set 'dummy-group' option: id=dummy-group-meta_attributes-is-managed set=dummy-gr * Passed: crm_resource - Create a resource meta attribute in dummy-group =#=#=#= Begin test: Delete the dummy-group resource group =#=#=#= =#=#=#= Current cib after: Delete the dummy-group resource group =#=#=#= - + @@ -2898,7 +2898,7 @@ Set 'dummy-group' option: id=dummy-group-meta_attributes-is-managed set=dummy-gr =#=#=#= Begin test: Specify a lifetime when moving a resource =#=#=#= Migration will take effect until: =#=#=#= Current cib after: Specify a lifetime when moving a resource =#=#=#= - + @@ -2942,7 +2942,7 @@ Migration will take effect until: * Passed: crm_resource - Specify a lifetime when moving a resource =#=#=#= Begin test: Try to move a resource previously moved with a lifetime =#=#=#= =#=#=#= Current cib after: Try to move a resource previously moved with a lifetime =#=#=#= - + @@ -2985,7 +2985,7 @@ WARNING: Creating rsc_location constraint 'cli-ban-dummy-on-node1' with a score This will prevent dummy from running on node1 until the constraint is removed using the clear option or by editing the CIB with an appropriate tool. This will be the case even if node1 is the last node in the cluster =#=#=#= Current cib after: Ban dummy from node1 for a short time =#=#=#= - + @@ -3031,7 +3031,7 @@ WARNING: Creating rsc_location constraint 'cli-ban-dummy-on-node1' with a score =#=#=#= Begin test: Remove expired constraints =#=#=#= Removing constraint: cli-ban-dummy-on-node1 =#=#=#= Current cib after: Remove expired constraints =#=#=#= - + @@ -3071,7 +3071,7 @@ Removing constraint: cli-ban-dummy-on-node1 =#=#=#= Begin test: Clear all implicit constraints for dummy =#=#=#= Removing constraint: cli-prefer-dummy =#=#=#= Current cib after: Clear all implicit constraints for dummy =#=#=#= - + @@ -3108,7 +3108,7 @@ Removing constraint: cli-prefer-dummy * Passed: crm_resource - Clear all implicit constraints for dummy =#=#=#= Begin test: Set a node health strategy =#=#=#= =#=#=#= Current cib after: Set a node health strategy =#=#=#= - + @@ -3146,7 +3146,7 @@ Removing constraint: cli-prefer-dummy * Passed: crm_attribute - Set a node health strategy =#=#=#= Begin test: Set a node health attribute =#=#=#= =#=#=#= Current cib after: Set a node health attribute =#=#=#= - + @@ -3197,7 +3197,7 @@ Removing constraint: cli-prefer-dummy * Passed: crm_resource - Show why a resource is not running on an unhealthy node (XML) =#=#=#= Begin test: Delete a resource =#=#=#= =#=#=#= Current cib after: Delete a resource =#=#=#= - + diff --git a/cts/cli/regression.crm_shadow.exp b/cts/cli/regression.crm_shadow.exp index f8a733743db..84fae0fdf17 100644 --- a/cts/cli/regression.crm_shadow.exp +++ b/cts/cli/regression.crm_shadow.exp @@ -743,7 +743,7 @@ cts-cli * Passed: crm_shadow - Get active shadow instance's diff (copied) (XML) =#=#=#= Begin test: Get active shadow instance's diff (after changes) =#=#=#= Diff: --- 1.1.173 2 -Diff: +++ 1.4.1 (null) +Diff: +++ 1.4.1 (no digest) -- /cib/configuration/op_defaults + /cib: @epoch=4, @num_updates=1 + /cib/configuration/resources/primitive[@id='dummy']: @description=desc @@ -800,7 +800,7 @@ To prevent accidental destruction of the cluster, the --force flag is required i * Passed: crm_shadow - Commit shadow instance (force) =#=#=#= Begin test: Get active shadow instance's diff (after commit) =#=#=#= Diff: --- 1.2.0 2 -Diff: +++ 1.4.1 (null) +Diff: +++ 1.4.1 (no digest) + /cib: @epoch=4, @num_updates=1 ++ /cib/status: =#=#=#= End test: Get active shadow instance's diff (after commit) - Error occurred (1) =#=#=#= @@ -810,7 +810,7 @@ Diff: +++ 1.4.1 (null) * Passed: crm_shadow - Commit shadow instance (force) (all) =#=#=#= Begin test: Get active shadow instance's diff (after commit all) =#=#=#= Diff: --- 1.4.2 2 -Diff: +++ 1.4.1 (null) +Diff: +++ 1.4.1 (no digest) + /cib: @num_updates=1 =#=#=#= End test: Get active shadow instance's diff (after commit all) - Error occurred (1) =#=#=#= * Passed: crm_shadow - Get active shadow instance's diff (after commit all) @@ -1322,7 +1322,7 @@ A new shadow instance was created. To begin using it, enter the following into y =#=#=#= End test: Create empty shadow instance (file already exists) (force) (XML) - OK (0) =#=#=#= * Passed: crm_shadow - Create empty shadow instance (file already exists) (force) (XML) =#=#=#= Begin test: Get active shadow instance's contents (empty CIB) =#=#=#= - + @@ -1336,7 +1336,7 @@ A new shadow instance was created. To begin using it, enter the following into y =#=#=#= Begin test: Get active shadow instance's contents (empty CIB) (XML) =#=#=#= - + @@ -1353,7 +1353,7 @@ A new shadow instance was created. To begin using it, enter the following into y * Passed: crm_shadow - Get active shadow instance's contents (empty CIB) (XML) =#=#=#= Begin test: Get active shadow instance's diff (empty CIB) =#=#=#= Diff: --- 1.1.173 2 -Diff: +++ 0.1.0 (null) +Diff: +++ 0.1.0 (no digest) -- /cib/configuration/crm_config/cluster_property_set[@id='cib-bootstrap-options'] -- /cib/configuration/nodes/node[@id='1'] -- /cib/configuration/nodes/node[@id='2'] @@ -1374,7 +1374,7 @@ Diff: +++ 0.1.0 (null) -- /cib/status/node_state[@id='1'] -- /cib/status/node_state[@id='httpd-bundle-0'] -- /cib/status/node_state[@id='httpd-bundle-1'] -+ /cib: @validate-with=pacemaker-X, @num_updates=0, @admin_epoch=0 ++ /cib: @validate-with=pacemaker-X, @admin_epoch=0, @epoch=1, @num_updates=0 -- /cib: @cib-last-written, @update-origin, @update-client, @update-user, @have-quorum, @dc-uuid =#=#=#= End test: Get active shadow instance's diff (empty CIB) - Error occurred (1) =#=#=#= * Passed: crm_shadow - Get active shadow instance's diff (empty CIB) @@ -1410,8 +1410,9 @@ Diff: +++ 0.1.0 (null) - + + @@ -1420,7 +1421,7 @@ Diff: +++ 0.1.0 (null) - + @@ -1445,7 +1446,7 @@ A new shadow instance was created. To begin using it, enter the following into y * Passed: crm_shadow - Active shadow instance no different from active CIB after reset =#=#=#= Begin test: Active shadow instance differs from active CIB after change =#=#=#= Diff: --- 1.1.173 2 -Diff: +++ 1.2.0 (null) +Diff: +++ 1.2.0 (no digest) + /cib: @epoch=2, @num_updates=0 ++ /cib/configuration/crm_config/cluster_property_set[@id='cib-bootstrap-options']: =#=#=#= End test: Active shadow instance differs from active CIB after change - Error occurred (1) =#=#=#= diff --git a/cts/cli/regression.crm_standby.exp b/cts/cli/regression.crm_standby.exp index ef406bb72be..5dce954c75d 100644 --- a/cts/cli/regression.crm_standby.exp +++ b/cts/cli/regression.crm_standby.exp @@ -4,7 +4,7 @@ scope=status name=standby value=off * Passed: crm_standby - Default standby value =#=#=#= Begin test: Set standby status =#=#=#= =#=#=#= Current cib after: Set standby status =#=#=#= - + @@ -28,7 +28,7 @@ scope=nodes name=standby value=true =#=#=#= Begin test: Delete standby value =#=#=#= Deleted nodes attribute: id=nodes-node1-standby name=standby =#=#=#= Current cib after: Delete standby value =#=#=#= - + diff --git a/cts/cli/regression.crm_ticket.exp b/cts/cli/regression.crm_ticket.exp index afb8be30794..1a30cb97190 100644 --- a/cts/cli/regression.crm_ticket.exp +++ b/cts/cli/regression.crm_ticket.exp @@ -4,7 +4,7 @@ false * Passed: crm_ticket - Default ticket granted state =#=#=#= Begin test: Set ticket granted state =#=#=#= =#=#=#= Current cib after: Set ticket granted state =#=#=#= - + @@ -70,7 +70,7 @@ false * Passed: crm_ticket - Query ticket granted state (XML) =#=#=#= Begin test: Delete ticket granted state =#=#=#= =#=#=#= Current cib after: Delete ticket granted state =#=#=#= - + @@ -93,7 +93,7 @@ false * Passed: crm_ticket - Delete ticket granted state =#=#=#= Begin test: Make a ticket standby =#=#=#= =#=#=#= Current cib after: Make a ticket standby =#=#=#= - + @@ -120,7 +120,7 @@ true * Passed: crm_ticket - Query ticket standby state =#=#=#= Begin test: Activate a ticket =#=#=#= =#=#=#= Current cib after: Activate a ticket =#=#=#= - + @@ -157,7 +157,7 @@ ticketA revoked (standby=false) =#=#=#= Begin test: Add a second ticket =#=#=#= false =#=#=#= Current cib after: Add a second ticket =#=#=#= - + @@ -180,7 +180,7 @@ false * Passed: crm_ticket - Add a second ticket =#=#=#= Begin test: Set second ticket granted state =#=#=#= =#=#=#= Current cib after: Set second ticket granted state =#=#=#= - + @@ -219,7 +219,7 @@ ticketB revoked * Passed: crm_ticket - List tickets (XML) =#=#=#= Begin test: Delete second ticket =#=#=#= =#=#=#= Current cib after: Delete second ticket =#=#=#= - + @@ -242,7 +242,7 @@ ticketB revoked * Passed: cibadmin - Delete second ticket =#=#=#= Begin test: Delete ticket standby state =#=#=#= =#=#=#= Current cib after: Delete ticket standby state =#=#=#= - + @@ -265,7 +265,7 @@ ticketB revoked * Passed: crm_ticket - Delete ticket standby state =#=#=#= Begin test: Add a constraint to a ticket =#=#=#= =#=#=#= Current cib after: Add a constraint to a ticket =#=#=#= - + @@ -312,7 +312,7 @@ Constraints XML: * Passed: crm_ticket - Query ticket constraints (XML) =#=#=#= Begin test: Delete ticket constraint =#=#=#= =#=#=#= Current cib after: Delete ticket constraint =#=#=#= - + diff --git a/cts/cli/regression.upgrade.exp b/cts/cli/regression.upgrade.exp index b4e69f6195a..3f3455a8e82 100644 --- a/cts/cli/regression.upgrade.exp +++ b/cts/cli/regression.upgrade.exp @@ -1,6 +1,6 @@ =#=#=#= Begin test: Set fencing-enabled=false =#=#=#= =#=#=#= Current cib after: Set fencing-enabled=false =#=#=#= - + @@ -17,7 +17,7 @@ * Passed: crm_attribute - Set fencing-enabled=false =#=#=#= Begin test: Configure the initial resource =#=#=#= =#=#=#= Current cib after: Configure the initial resource =#=#=#= - + @@ -78,7 +78,7 @@ pcmk__update_schema debug: Schema pacemaker-3.10 validates pcmk__update_schema debug: Schema pacemaker-4.0 validates pcmk__update_schema info: Transformed the configuration schema to pacemaker-4.0 =#=#=#= Current cib after: Upgrade to latest CIB schema (trigger 2.10.xsl + the wrapping) =#=#=#= - + @@ -111,7 +111,7 @@ pcmk__update_schema info: Transformed the configuration schema to pacemaker-4.0 =#=#=#= Begin test: Query a resource instance attribute (shall survive) =#=#=#= outputpower =#=#=#= Current cib after: Query a resource instance attribute (shall survive) =#=#=#= - + diff --git a/cts/cli/regression.validity.exp b/cts/cli/regression.validity.exp index 03b61cee5b3..fd566608b3f 100644 --- a/cts/cli/regression.validity.exp +++ b/cts/cli/regression.validity.exp @@ -9,7 +9,7 @@ cibadmin: CIB API call failed: Update does not conform to the configured schema =#=#=#= Begin test: Try to use rsc_order first-action value disallowed by schema =#=#=#= cibadmin: CIB API call failed: Update does not conform to the configured schema =#=#=#= Current cib after: Try to use rsc_order first-action value disallowed by schema =#=#=#= - + @@ -28,7 +28,7 @@ cibadmin: CIB API call failed: Update does not conform to the configured schema =#=#=#= Begin test: Try to use configuration legal only with schema after configured one =#=#=#= cibadmin: CIB API call failed: Update does not conform to the configured schema =#=#=#= Current cib after: Try to use configuration legal only with schema after configured one =#=#=#= - + @@ -49,7 +49,7 @@ cibadmin: CIB API call failed: Update does not conform to the configured schema * Passed: cibadmin - Disable schema validation =#=#=#= Begin test: Set invalid rsc_order first-action value (schema validation disabled) =#=#=#= =#=#=#= Current cib after: Set invalid rsc_order first-action value (schema validation disabled) =#=#=#= - + diff --git a/cts/cts-cli.in b/cts/cts-cli.in index 6f2422b3587..eadb6a69ba1 100644 --- a/cts/cts-cli.in +++ b/cts/cts-cli.in @@ -193,9 +193,9 @@ def reset_shadow_cib_version(): """Set various version numbers in a shadow CIB file back to 0.""" with fileinput.input(files=[shadow_path()], inplace=True) as f: for line in f: - line = re.sub('epoch="[0-9]*"', 'epoch="1"', line) - line = re.sub('num_updates="[0-9]*"', 'num_updates="0"', line) - line = re.sub('admin_epoch="[0-9]*"', 'admin_epoch="0"', line) + line = re.sub(r'\badmin_epoch="[0-9]*"', 'admin_epoch="0"', line) + line = re.sub(r'\bepoch="[0-9]*"', 'epoch="1"', line) + line = re.sub(r'\bnum_updates="[0-9]*"', 'num_updates="0"', line) print(line, end='') @@ -1417,7 +1417,7 @@ class CrmAttributeRegressionTest(RegressionTest): "crm_attribute --query -n cpu -N node1 -z"), # This update will fail because it has version numbers Test("Replace operation should fail", - """cibadmin -Q | sed -e 's/epoch="[^"]*"/epoch="1"/' | cibadmin -R -p""", + """cibadmin -Q | sed -e 's/ epoch="[^"]*"/ epoch="1"/' | cibadmin -R -p""", expected_rc=ExitStatus.OLD), ] @@ -2346,7 +2346,7 @@ class CrmSimulateRegressionTest(RegressionTest): no_version_cib = good_cib.replace('validate-with="pacemaker-1.2" ', "") - no_version_bad_cib = bad_version_cib.replace('epoch="3"', 'epoch="30"').replace("start", "break") + no_version_bad_cib = re.sub(r'\bepoch="3"', 'epoch="30"', bad_version_cib).replace("start", "break") basic_tests = [ Test("Show allocation scores with crm_simulate", diff --git a/daemons/based/based_callbacks.c b/daemons/based/based_callbacks.c index 48d4a9f31a7..ce49437253c 100644 --- a/daemons/based/based_callbacks.c +++ b/daemons/based/based_callbacks.c @@ -371,9 +371,9 @@ parse_peer_options(const cib__operation_t *operation, xmlNode *request, delegated = reply_to; } goto skip_is_reply; + } - } else if (pcmk__str_eq(op, PCMK__CIB_REQUEST_SYNC_TO_ALL, - pcmk__str_none)) { + if (pcmk__str_eq(op, PCMK__CIB_REQUEST_SYNC, pcmk__str_none)) { // Nothing to do } else if (is_reply && pcmk__str_eq(op, CRM_OP_PING, pcmk__str_casei)) { @@ -416,11 +416,6 @@ parse_peer_options(const cib__operation_t *operation, xmlNode *request, return false; } - } else if (pcmk__xe_attr_is_true(request, PCMK__XA_CIB_UPDATE)) { - pcmk__info("Detected legacy %s global update from %s", op, originator); - send_sync_request(); - return false; - } else if (is_reply && pcmk__is_set(operation->flags, cib__op_attr_modifies)) { @@ -615,23 +610,26 @@ cib_process_command(xmlNode *request, const cib__operation_t *operation, /* @COMPAT: Handle a valid write action (legacy) * - * @TODO: Re-evaluate whether this is all truly legacy. PCMK__XA_CIB_UPDATE - * may be set by a sync operation even in non-legacy mode, and - * manage_counters tells xml_create_patchset() whether to update - * version/epoch info. + * @TODO: Re-evaluate whether this is truly legacy. PCMK__XA_CIB_UPDATE may + * be set by a sync operation even in non-legacy mode, and manage_counters + * tells xml_create_patchset() whether to update version/epoch info. */ if (pcmk__xe_attr_is_true(request, PCMK__XA_CIB_UPDATE)) { manage_counters = false; - CRM_LOG_ASSERT(pcmk__str_any_of(op, PCMK__CIB_REQUEST_APPLY_PATCH, - PCMK__CIB_REQUEST_REPLACE, NULL)); + CRM_LOG_ASSERT(pcmk__str_eq(op, PCMK__CIB_REQUEST_REPLACE, + pcmk__str_none)); } ping_modified_since = true; - // result_cib must not be modified after cib_perform_op() returns - rc = cib_perform_op(NULL, op, call_options, op_function, section, request, - input, manage_counters, &config_changed, &the_cib, - &result_cib, &cib_diff, &output); + /* result_cib must not be modified after cib_perform_op() returns. + * + * It's not important whether the client variant is cib_native or + * cib_remote. + */ + rc = cib_perform_op(cib_undefined, op, call_options, op_function, section, + request, input, manage_counters, &config_changed, + &the_cib, &result_cib, &cib_diff, &output); /* Always write to disk for successful ops with the flag set. This also * negates the need to detect ordering changes. @@ -695,8 +693,6 @@ cib_process_command(xmlNode *request, const cib__operation_t *operation, client_name, originator, cib_diff); } - pcmk__log_xml_patchset(LOG_TRACE, cib_diff); - done: if (!pcmk__is_set(call_options, cib_discard_reply)) { *reply = create_cib_reply(op, call_id, client_id, call_options, @@ -740,22 +736,6 @@ log_op_result(const xmlNode *request, const cib__operation_t *operation, int rc, if (!pcmk__is_set(operation->flags, cib__op_attr_modifies)) { level = LOG_TRACE; - } else if (pcmk__xe_attr_is_true(request, PCMK__XA_CIB_UPDATE)) { - switch (rc) { - case pcmk_rc_ok: - level = LOG_INFO; - break; - - case pcmk_rc_old_data: - case pcmk_rc_diff_resync: - case pcmk_rc_diff_failed: - level = LOG_TRACE; - break; - - default: - level = LOG_ERR; - } - } else if (rc != pcmk_rc_ok) { level = LOG_WARNING; } diff --git a/daemons/based/based_messages.c b/daemons/based/based_messages.c index feb5c8ba539..e21544a43b1 100644 --- a/daemons/based/based_messages.c +++ b/daemons/based/based_messages.c @@ -29,30 +29,21 @@ #include "pacemaker-based.h" -/* Maximum number of diffs to ignore while waiting for a resync */ -#define MAX_DIFF_RETRY 5 - bool based_is_primary = false; xmlNode *the_cib = NULL; -/* Set to 1 when a sync is requested, incremented when a diff is ignored, - * reset to 0 when a sync is received - */ -static int sync_in_progress = 0; - /*! * \internal * \brief Process a \c PCMK__CIB_REQUEST_ABS_DELETE * - * \param[in] op Ignored - * \param[in] options Ignored - * \param[in] section Ignored - * \param[in] req Ignored - * \param[in] input Ignored - * \param[in] existing_cib Ignored - * \param[in] result_cib Ignored - * \param[in] answer Ignored + * \param[in] op Ignored + * \param[in] options Ignored + * \param[in] section Ignored + * \param[in] req Ignored + * \param[in] input Ignored + * \param[in] cib Ignored + * \param[in] answer Ignored * * \return \c EINVAL * @@ -60,8 +51,8 @@ static int sync_in_progress = 0; */ int based_process_abs_delete(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { /* @COMPAT Remove when PCMK__CIB_REQUEST_ABS_DELETE is removed. Note that * external clients with Pacemaker versions < 3.0.0 can send it. @@ -69,68 +60,21 @@ based_process_abs_delete(const char *op, int options, const char *section, return EINVAL; } -int -based_process_apply_patch(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) -{ - int rc = pcmk_rc_ok; - - if (sync_in_progress > MAX_DIFF_RETRY) { - /* Don't ignore diffs forever; the last request may have been lost. - * If the diff fails, we'll ask for another full resync. - */ - sync_in_progress = 0; - } - - // The primary instance should never ignore a diff - if (sync_in_progress && !based_is_primary) { - int source[] = { 0, 0, 0 }; - int target[] = { 0, 0, 0 }; - - pcmk__xml_patchset_versions(input, source, target); - - sync_in_progress++; - pcmk__notice("Not applying diff %d.%d.%d -> %d.%d.%d (sync in " - "progress)", - source[0], source[1], source[2], - target[0], target[1], target[2]); - return pcmk_rc_diff_resync; - } - - rc = cib__process_apply_patch(op, options, section, req, input, - existing_cib, result_cib, answer); - pcmk__trace("result: %s (%d), %s", pcmk_rc_str(rc), rc, - (based_is_primary? "primary": "secondary")); - - if ((rc == pcmk_rc_diff_resync) && !based_is_primary) { - pcmk__xml_free(*result_cib); - *result_cib = NULL; - send_sync_request(); - - } else if (rc == pcmk_rc_diff_resync) { - rc = pcmk_rc_diff_failed; - } - - return rc; -} - int based_process_commit_transact(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, - xmlNode *existing_cib, xmlNode **result_cib, + xmlNode *req, xmlNode *input, xmlNode **cib, xmlNode **answer) { - /* On success, our caller will activate *result_cib locally, trigger a - * replace notification if appropriate, and sync *result_cib to all nodes. - * On failure, our caller will free *result_cib. + /* On success, our caller will activate *cib locally, trigger a replace + * notification if appropriate, and sync *cib to all nodes. On failure, our + * caller will free *cib. */ int rc = pcmk_rc_ok; const char *client_id = pcmk__xe_get(req, PCMK__XA_CIB_CLIENTID); const char *origin = pcmk__xe_get(req, PCMK__XA_SRC); pcmk__client_t *client = pcmk__find_client_by_id(client_id); - rc = based_commit_transaction(input, client, origin, result_cib); + rc = based_commit_transaction(input, client, origin, cib); if (rc != pcmk_rc_ok) { char *source = based_transaction_source_str(client, origin); @@ -144,8 +88,8 @@ based_process_commit_transact(const char *op, int options, const char *section, int based_process_is_primary(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { // @COMPAT Pacemaker Remote clients <3.0.0 may send this return (based_is_primary? pcmk_rc_ok : EPERM); @@ -154,8 +98,8 @@ based_process_is_primary(const char *op, int options, const char *section, // @COMPAT: Remove when PCMK__CIB_REQUEST_NOOP is removed int based_process_noop(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { *answer = NULL; return pcmk_rc_ok; @@ -163,10 +107,10 @@ based_process_noop(const char *op, int options, const char *section, int based_process_ping(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { - /* existing_cib and *result_cib should be identical. In the absence of ACL + /* existing_cib and *cib should be identical. In the absence of ACL * filtering, they should also match the_cib. However, they may be copies * filtered based on the current CIB user's ACLs. In that case, our log * messages can use info from the full CIB, and the answer can include the @@ -187,21 +131,21 @@ based_process_ping(const char *op, int options, const char *section, wrapper = pcmk__xe_create(*answer, PCMK__XE_CIB_CALLDATA); - if (*result_cib != NULL) { - // Use *result_cib so that ACL filtering is applied to the answer + if (*cib != NULL) { + // Use *cib so that ACL filtering is applied to the answer pcmk__if_tracing( { /* Append additional detail so the receiver can log the * differences */ - pcmk__xml_copy(wrapper, *result_cib); + pcmk__xml_copy(wrapper, *cib); }, { // Always include at least the version details - const char *name = (const char *) (*result_cib)->name; + const char *name = (const char *) (*cib)->name; xmlNode *shallow = pcmk__xe_create(wrapper, name); - pcmk__xe_copy_attrs(shallow, *result_cib, pcmk__xaf_none); + pcmk__xe_copy_attrs(shallow, *cib, pcmk__xaf_none); } ); } @@ -219,8 +163,8 @@ based_process_ping(const char *op, int options, const char *section, int based_process_primary(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode ** answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { if (!based_is_primary) { pcmk__info("We are now in R/W mode"); @@ -233,24 +177,10 @@ based_process_primary(const char *op, int options, const char *section, return pcmk_rc_ok; } -int -based_process_replace(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) -{ - int rc = cib__process_replace(op, options, section, req, input, - existing_cib, result_cib, answer); - - if ((rc == pcmk_rc_ok) && pcmk__xe_is(input, PCMK_XE_CIB)) { - sync_in_progress = 0; - } - return rc; -} - int based_process_schemas(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { xmlNode *wrapper = NULL; xmlNode *data = NULL; @@ -295,8 +225,8 @@ based_process_schemas(const char *op, int options, const char *section, int based_process_secondary(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { if (based_is_primary) { pcmk__info("We are now in R/O mode"); @@ -311,8 +241,8 @@ based_process_secondary(const char *op, int options, const char *section, int based_process_shutdown(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { const char *host = pcmk__xe_get(req, PCMK__XA_SRC); @@ -334,25 +264,17 @@ based_process_shutdown(const char *op, int options, const char *section, } int -based_process_sync_to_all(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) +based_process_sync(const char *op, int options, const char *section, + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { return sync_our_cib(req, true); } -int -based_process_sync_to_one(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) -{ - return sync_our_cib(req, false); -} - int based_process_upgrade(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { int rc = pcmk_rc_ok; @@ -364,11 +286,11 @@ based_process_upgrade(const char *op, int options, const char *section, * re-broadcasts the request with PCMK__XA_CIB_SCHEMA_MAX, and each node * performs the upgrade (and notifies its local clients) here. */ - return cib__process_upgrade(op, options, section, req, input, - existing_cib, result_cib, answer); + return cib__process_upgrade(op, options, section, req, input, cib, + answer); } else { - xmlNode *scratch = pcmk__xml_copy(NULL, *result_cib); + xmlNode *scratch = pcmk__xml_copy(NULL, *cib); const char *host = pcmk__xe_get(req, PCMK__XA_SRC); const char *original_schema = NULL; const char *new_schema = NULL; @@ -376,7 +298,7 @@ based_process_upgrade(const char *op, int options, const char *section, const char *call_opts = pcmk__xe_get(req, PCMK__XA_CIB_CALLOPT); const char *call_id = pcmk__xe_get(req, PCMK__XA_CIB_CALLID); - original_schema = pcmk__xe_get(*result_cib, PCMK_XA_VALIDATE_WITH); + original_schema = pcmk__xe_get(*cib, PCMK_XA_VALIDATE_WITH); if (original_schema == NULL) { pcmk__info("Rejecting upgrade request from %s: No " PCMK_XA_VALIDATE_WITH, @@ -443,23 +365,6 @@ based_process_upgrade(const char *op, int options, const char *section, return rc; } -void -send_sync_request(void) -{ - xmlNode *sync_me = pcmk__xe_create(NULL, "sync-me"); - pcmk__node_status_t *peer = NULL; - - pcmk__info("Requesting re-sync from all peers"); - sync_in_progress = 1; - - pcmk__xe_set(sync_me, PCMK__XA_T, PCMK__VALUE_CIB); - pcmk__xe_set(sync_me, PCMK__XA_CIB_OP, PCMK__CIB_REQUEST_SYNC_TO_ONE); - pcmk__xe_set(sync_me, PCMK__XA_CIB_DELEGATED_FROM, OUR_NODENAME); - - pcmk__cluster_send_message(peer, pcmk_ipc_based, sync_me); - pcmk__xml_free(sync_me); -} - static xmlNode * cib_msg_copy(xmlNode *msg) { diff --git a/daemons/based/based_messages.h b/daemons/based/based_messages.h index fee6e089cb8..a3e986536d2 100644 --- a/daemons/based/based_messages.h +++ b/daemons/based/based_messages.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2025 the Pacemaker project contributors + * Copyright 2004-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -18,68 +18,54 @@ extern bool based_is_primary; extern xmlNode *the_cib; int based_process_abs_delete(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, - xmlNode *existing_cib, xmlNode **result_cib, + xmlNode *req, xmlNode *input, xmlNode **cib, xmlNode **answer); int based_process_apply_patch(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, - xmlNode *existing_cib, xmlNode **result_cib, + xmlNode *req, xmlNode *input, xmlNode **cib, xmlNode **answer); int based_process_commit_transact(const char *op, int options, const char *section, xmlNode *req, - xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *input, xmlNode **cib, + xmlNode **answer); int based_process_is_primary(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, - xmlNode *existing_cib, xmlNode **result_cib, + xmlNode *req, xmlNode *input, xmlNode **cib, xmlNode **answer); int based_process_noop(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int based_process_ping(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int based_process_primary(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); - -int based_process_replace(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int based_process_schemas(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int based_process_secondary(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int based_process_shutdown(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); - -int based_process_sync_to_all(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, - xmlNode *existing_cib, xmlNode **result_cib, - xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); -int based_process_sync_to_one(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, - xmlNode *existing_cib, xmlNode **result_cib, - xmlNode **answer); +int based_process_sync(const char *op, int options, const char *section, + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int based_process_upgrade(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); -void send_sync_request(void); int sync_our_cib(xmlNode *request, bool all); #endif // BASED_MESSAGES__H diff --git a/daemons/based/based_operation.c b/daemons/based/based_operation.c index 9189a374354..04d1c5417e8 100644 --- a/daemons/based/based_operation.c +++ b/daemons/based/based_operation.c @@ -18,7 +18,7 @@ static const cib__op_fn_t op_functions[] = { [cib__op_abs_delete] = based_process_abs_delete, - [cib__op_apply_patch] = based_process_apply_patch, + [cib__op_apply_patch] = cib__process_apply_patch, [cib__op_bump] = cib__process_bump, [cib__op_commit_transact] = based_process_commit_transact, [cib__op_create] = cib__process_create, @@ -30,12 +30,11 @@ static const cib__op_fn_t op_functions[] = { [cib__op_ping] = based_process_ping, [cib__op_primary] = based_process_primary, [cib__op_query] = cib__process_query, - [cib__op_replace] = based_process_replace, + [cib__op_replace] = cib__process_replace, [cib__op_schemas] = based_process_schemas, [cib__op_secondary] = based_process_secondary, [cib__op_shutdown] = based_process_shutdown, - [cib__op_sync_to_all] = based_process_sync_to_all, - [cib__op_sync_to_one] = based_process_sync_to_one, + [cib__op_sync] = based_process_sync, [cib__op_upgrade] = based_process_upgrade, }; diff --git a/daemons/controld/controld_cib.c b/daemons/controld/controld_cib.c index 0e4849ad4db..017bdab4516 100644 --- a/daemons/controld/controld_cib.c +++ b/daemons/controld/controld_cib.c @@ -729,22 +729,17 @@ controld_record_pending_op(const char *node_name, const lrmd_rsc_info_t *rsc, static void cib_rsc_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { - switch (rc) { - case pcmk_ok: - case -pcmk_err_diff_failed: - case -pcmk_err_diff_resync: - pcmk__trace("Resource history update completed (call=%d rc=%d)", - call_id, rc); - break; - default: - if (call_id > 0) { - pcmk__warn("Resource history update %d failed: %s " - QB_XS " rc=%d", - call_id, pcmk_strerror(rc), rc); - } else { - pcmk__warn("Resource history update failed: %s " QB_XS " rc=%d", - pcmk_strerror(rc), rc); - } + if (rc == pcmk_ok) { + pcmk__trace("Resource history update completed (call=%d rc=%d)", + call_id, rc); + + } else if (call_id > 0) { + pcmk__warn("Resource history update %d failed: %s " QB_XS " rc=%d", + call_id, pcmk_strerror(rc), rc); + + } else { + pcmk__warn("Resource history update failed: %s " QB_XS " rc=%d", + pcmk_strerror(rc), rc); } if (call_id == pending_rsc_update) { diff --git a/daemons/fenced/fenced_cib.c b/daemons/fenced/fenced_cib.c index f030c1b2b06..9ecf635f371 100644 --- a/daemons/fenced/fenced_cib.c +++ b/daemons/fenced/fenced_cib.c @@ -1,5 +1,5 @@ /* - * Copyright 2009-2025 the Pacemaker project contributors + * Copyright 2009-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -516,7 +516,6 @@ update_cib_cache_cb(const char *event, xmlNode * msg) * old diff. */ break; - case -pcmk_err_diff_resync: case -pcmk_err_diff_failed: pcmk__notice("[%s] Patch aborted: %s (%d)", event, pcmk_strerror(rc), rc); diff --git a/include/crm/cib/internal.h b/include/crm/cib/internal.h index e6b2f53f178..6eaf1516d7d 100644 --- a/include/crm/cib/internal.h +++ b/include/crm/cib/internal.h @@ -23,8 +23,7 @@ extern "C" { // Request types for CIB manager IPC/CPG #define PCMK__CIB_REQUEST_SECONDARY "cib_slave" #define PCMK__CIB_REQUEST_PRIMARY "cib_master" -#define PCMK__CIB_REQUEST_SYNC_TO_ALL "cib_sync" -#define PCMK__CIB_REQUEST_SYNC_TO_ONE "cib_sync_one" +#define PCMK__CIB_REQUEST_SYNC "cib_sync" #define PCMK__CIB_REQUEST_IS_PRIMARY "cib_ismaster" #define PCMK__CIB_REQUEST_BUMP "cib_bump" #define PCMK__CIB_REQUEST_QUERY "cib_query" @@ -90,13 +89,12 @@ enum cib__op_type { cib__op_schemas, cib__op_secondary, cib__op_shutdown, - cib__op_sync_to_all, - cib__op_sync_to_one, + cib__op_sync, cib__op_upgrade, }; typedef int (*cib__op_fn_t)(const char *, int, const char *, xmlNode *, - xmlNode *, xmlNode *, xmlNode **, xmlNode **); + xmlNode *, xmlNode **, xmlNode **); typedef struct { const char *name; @@ -184,11 +182,11 @@ int cib__perform_query(const char *op, uint32_t call_options, cib__op_fn_t fn, const char *section, xmlNode *req, xmlNode *input, xmlNode **current_cib, xmlNode **output); -int cib_perform_op(cib_t *cib, const char *op, uint32_t call_options, - cib__op_fn_t fn, const char *section, xmlNode *req, - xmlNode *input, bool manage_counters, bool *config_changed, - xmlNode **current_cib, xmlNode **result_cib, xmlNode **diff, - xmlNode **output); +int cib_perform_op(enum cib_variant variant, const char *op, + uint32_t call_options, cib__op_fn_t fn, const char *section, + xmlNode *req, xmlNode *input, bool manage_counters, + bool *config_changed, xmlNode **current_cib, + xmlNode **result_cib, xmlNode **diff, xmlNode **output); int cib__create_op(cib_t *cib, const char *op, const char *host, const char *section, xmlNode *data, int call_options, @@ -203,40 +201,40 @@ void cib_native_notify(gpointer data, gpointer user_data); int cib__get_operation(const char *op, const cib__operation_t **operation); int cib__process_apply_patch(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int cib__process_bump(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int cib__process_create(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int cib__process_delete(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int cib__process_erase(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int cib__process_modify(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int cib__process_query(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int cib__process_replace(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int cib__process_upgrade(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer); + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer); int cib_internal_op(cib_t * cib, const char *op, const char *host, const char *section, xmlNode * data, diff --git a/include/crm/common/xml.h b/include/crm/common/xml.h index b5a5b08f0e5..ceb6cddf390 100644 --- a/include/crm/common/xml.h +++ b/include/crm/common/xml.h @@ -33,8 +33,8 @@ extern "C" { * undeprecated until we create replacements */ -xmlNode *xml_create_patchset( - int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version); +xmlNode *xml_create_patchset(int format, const xmlNode *source, xmlNode *target, + bool *config, bool manage_version); int xml_apply_patchset(xmlNode *xml, const xmlNode *patchset, bool check_version); diff --git a/include/crm/common/xml_internal.h b/include/crm/common/xml_internal.h index eed9c6fc837..8fd2148354d 100644 --- a/include/crm/common/xml_internal.h +++ b/include/crm/common/xml_internal.h @@ -326,6 +326,7 @@ pcmk__xml_next(const xmlNode *child) void pcmk__xml_free(xmlNode *xml); void pcmk__xml_free_doc(xmlDoc *doc); xmlNode *pcmk__xml_copy(xmlNode *parent, xmlNode *src); +xmlNode *pcmk__xml_replace_with_copy(xmlNode *old, xmlNode *new); /*! * \internal diff --git a/lib/cib/cib_client.c b/lib/cib/cib_client.c index 38fae89be7c..2009c5d4739 100644 --- a/lib/cib/cib_client.c +++ b/lib/cib/cib_client.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2025 the Pacemaker project contributors + * Copyright 2004-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -290,8 +290,8 @@ cib_client_sync(cib_t * cib, const char *section, int call_options) static int cib_client_sync_from(cib_t * cib, const char *host, const char *section, int call_options) { - return cib_internal_op(cib, PCMK__CIB_REQUEST_SYNC_TO_ALL, host, section, - NULL, NULL, call_options, cib->user); + return cib_internal_op(cib, PCMK__CIB_REQUEST_SYNC, host, section, NULL, + NULL, call_options, cib->user); } static int diff --git a/lib/cib/cib_file.c b/lib/cib/cib_file.c index 69fa7168037..310ffdd0cca 100644 --- a/lib/cib/cib_file.c +++ b/lib/cib/cib_file.c @@ -1,6 +1,6 @@ /* * Original copyright 2004 International Business Machines - * Later changes copyright 2008-2025 the Pacemaker project contributors + * Later changes copyright 2008-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -138,7 +138,7 @@ get_client(const char *client_id) static int process_request(cib_t *cib, xmlNode *request, xmlNode **output) { - int rc = pcmk_ok; + int rc = pcmk_rc_ok; const cib__operation_t *operation = NULL; cib__op_fn_t op_function = NULL; @@ -180,7 +180,7 @@ process_request(cib_t *cib, xmlNode *request, xmlNode **output) rc = cib__perform_query(op, call_options, op_function, section, request, data, &private->cib_xml, output); } else { - rc = cib_perform_op(cib, op, call_options, op_function, section, + rc = cib_perform_op(cib_file, op, call_options, op_function, section, request, data, true, &changed, &private->cib_xml, &result_cib, &cib_diff, output); } @@ -197,8 +197,6 @@ process_request(cib_t *cib, xmlNode *request, xmlNode **output) pcmk__validate_xml(result_cib, NULL, NULL, NULL); } else if ((rc == pcmk_rc_ok) && !read_only) { - pcmk__log_xml_patchset(LOG_DEBUG, cib_diff); - if (result_cib != private->cib_xml) { pcmk__xml_free(private->cib_xml); private->cib_xml = result_cib; @@ -211,7 +209,7 @@ process_request(cib_t *cib, xmlNode *request, xmlNode **output) pcmk__xml_free(result_cib); } pcmk__xml_free(cib_diff); - return pcmk_rc2legacy(rc); + return rc; } /*! @@ -241,7 +239,6 @@ process_transaction_requests(cib_t *cib, xmlNode *transaction) int rc = process_request(cib, request, &output); - rc = pcmk_legacy2rc(rc); if (rc != pcmk_rc_ok) { pcmk__err("Aborting transaction for CIB file client (%s) on file " "'%s' due to failed %s request: %s", @@ -322,8 +319,8 @@ commit_transaction(cib_t *cib, xmlNode *transaction, xmlNode **result_cib) static int process_commit_transact(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib_xml, + xmlNode **answer) { int rc = pcmk_rc_ok; const char *client_id = pcmk__xe_get(req, PCMK__XA_CIB_CLIENTID); @@ -334,7 +331,7 @@ process_commit_transact(const char *op, int options, const char *section, cib = get_client(client_id); CRM_CHECK(cib != NULL, return -EINVAL); - rc = commit_transaction(cib, input, result_cib); + rc = commit_transaction(cib, input, cib_xml); if (rc != pcmk_rc_ok) { file_opaque_t *private = cib->variant_opaque; @@ -453,18 +450,22 @@ file_perform_op_delegate(cib_t *cib, const char *op, const char *host, rc = cib__create_op(cib, op, host, section, data, call_options, user_name, NULL, &request); + rc = pcmk_rc2legacy(rc); if (rc != pcmk_ok) { return rc; } + pcmk__xe_set(request, PCMK__XA_ACL_TARGET, user_name); pcmk__xe_set(request, PCMK__XA_CIB_CLIENTID, private->id); if (pcmk__is_set(call_options, cib_transaction)) { rc = cib__extend_transaction(cib, request); + rc = pcmk_rc2legacy(rc); goto done; } rc = process_request(cib, request, &output); + rc = pcmk_rc2legacy(rc); if ((output_data != NULL) && (output != NULL)) { if (output->doc == private->cib_xml->doc) { diff --git a/lib/cib/cib_native.c b/lib/cib/cib_native.c index db28bd2b120..9cb585d9747 100644 --- a/lib/cib/cib_native.c +++ b/lib/cib/cib_native.c @@ -68,12 +68,14 @@ cib_native_perform_op_delegate(cib_t *cib, const char *op, const char *host, rc = cib__create_op(cib, op, host, section, data, call_options, user_name, NULL, &op_msg); + rc = pcmk_rc2legacy(rc); if (rc != pcmk_ok) { return rc; } if (pcmk__is_set(call_options, cib_transaction)) { rc = cib__extend_transaction(cib, op_msg); + rc = pcmk_rc2legacy(rc); goto done; } @@ -141,11 +143,6 @@ cib_native_perform_op_delegate(cib_t *cib, const char *op, const char *host, case -EPERM: break; - /* This is an internal value that clients do not and should not care about */ - case -pcmk_err_diff_resync: - rc = pcmk_ok; - break; - /* These indicate internal problems */ case -EPROTO: case -ENOMSG: @@ -311,6 +308,7 @@ cib_native_signon(cib_t *cib, const char *name, enum cib_conn_type type) if (rc == pcmk_ok) { rc = cib__create_op(cib, CRM_OP_REGISTER, NULL, NULL, NULL, cib_sync_call, NULL, name, &hello); + rc = pcmk_rc2legacy(rc); } if (rc == pcmk_ok) { diff --git a/lib/cib/cib_ops.c b/lib/cib/cib_ops.c index 143d2b5f428..ab4a341bc6e 100644 --- a/lib/cib/cib_ops.c +++ b/lib/cib/cib_ops.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2025 the Pacemaker project contributors + * Copyright 2004-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -118,12 +118,7 @@ static const cib__operation_t cib_ops[] = { PCMK__CIB_REQUEST_SHUTDOWN, cib__op_shutdown, cib__op_attr_privileged }, { - PCMK__CIB_REQUEST_SYNC_TO_ALL, cib__op_sync_to_all, - cib__op_attr_privileged - }, - { - PCMK__CIB_REQUEST_SYNC_TO_ONE, cib__op_sync_to_one, - cib__op_attr_privileged + PCMK__CIB_REQUEST_SYNC, cib__op_sync, cib__op_attr_privileged }, { PCMK__CIB_REQUEST_UPGRADE, cib__op_upgrade, @@ -169,10 +164,10 @@ cib__get_operation(const char *op, const cib__operation_t **operation) int cib__process_apply_patch(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { - int rc = xml_apply_patchset(*result_cib, input, true); + int rc = xml_apply_patchset(*cib, input, true); return pcmk_legacy2rc(rc); } @@ -196,10 +191,9 @@ update_counter(xmlNode *xml, const char *field, bool reset) int cib__process_bump(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, xmlNode **answer) { - update_counter(*result_cib, PCMK_XA_EPOCH, false); + update_counter(*cib, PCMK_XA_EPOCH, false); return pcmk_rc_ok; } @@ -265,11 +259,11 @@ update_results(xmlNode *failed, xmlNode *target, const char *operation, int rc) static int process_create_xpath(const char *op, const char *xpath, xmlNode *input, - xmlNode *result_cib) + xmlNode *cib) { int num_results = 0; int rc = pcmk_rc_ok; - xmlXPathObject *xpath_obj = pcmk__xpath_search(result_cib->doc, xpath); + xmlXPathObject *xpath_obj = pcmk__xpath_search(cib->doc, xpath); xmlNode *match = NULL; xmlChar *path = NULL; @@ -298,8 +292,8 @@ process_create_xpath(const char *op, const char *xpath, xmlNode *input, int cib__process_create(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { xmlNode *failed = NULL; int rc = pcmk_rc_ok; @@ -323,14 +317,14 @@ cib__process_create(const char *op, int options, const char *section, } if (section == NULL) { - return cib__process_modify(op, options, section, req, input, - existing_cib, result_cib, answer); + return cib__process_modify(op, options, section, req, input, cib, + answer); } // @COMPAT Deprecated since 2.1.8 failed = pcmk__xe_create(NULL, PCMK__XE_FAILED); - update_section = pcmk_find_cib_element(*result_cib, section); + update_section = pcmk_find_cib_element(*cib, section); if (pcmk__xe_is(input, section)) { xmlNode *a_child = NULL; @@ -368,12 +362,12 @@ cib__process_create(const char *op, int options, const char *section, static int process_delete_xpath(const char *op, int options, const char *xpath, - xmlNode *result_cib) + xmlNode *cib) { int num_results = 0; int rc = pcmk_rc_ok; - xmlXPathObject *xpath_obj = pcmk__xpath_search(result_cib->doc, xpath); + xmlXPathObject *xpath_obj = pcmk__xpath_search(cib->doc, xpath); num_results = pcmk__xpath_num_results(xpath_obj); if (num_results == 0) { @@ -415,7 +409,7 @@ process_delete_xpath(const char *op, int options, const char *xpath, pcmk__debug("Processing %s op for %s with %s", op, xpath, path); free(path); - if (match == result_cib) { + if (match == cib) { pcmk__warn("Cannot perform %s for %s: the XPath is addressing the " "whole /cib", op, xpath); rc = EINVAL; @@ -447,7 +441,7 @@ delete_child(xmlNode *child, void *userdata) } static int -process_delete_section(const char *section, xmlNode *input, xmlNode *result_cib) +process_delete_section(const char *section, xmlNode *input, xmlNode *cib) { xmlNode *obj_root = NULL; @@ -456,7 +450,7 @@ process_delete_section(const char *section, xmlNode *input, xmlNode *result_cib) return EINVAL; } - obj_root = pcmk_find_cib_element(result_cib, section); + obj_root = pcmk_find_cib_element(cib, section); if (pcmk__xe_is(input, section)) { pcmk__xe_foreach_child(input, NULL, delete_child, obj_root); @@ -470,20 +464,20 @@ process_delete_section(const char *section, xmlNode *input, xmlNode *result_cib) int cib__process_delete(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { if (pcmk__is_set(options, cib_xpath)) { - return process_delete_xpath(op, options, section, *result_cib); + return process_delete_xpath(op, options, section, *cib); } - return process_delete_section(section, input, *result_cib); + return process_delete_section(section, input, *cib); } int cib__process_erase(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { xmlNode *empty = createEmptyCib(0); xmlNode *empty_config = pcmk__xe_first_child(empty, PCMK_XE_CONFIGURATION, @@ -492,20 +486,19 @@ cib__process_erase(const char *op, int options, const char *section, NULL); // Free all existing children, regardless of node type - while ((*result_cib)->children != NULL) { - pcmk__xml_free((*result_cib)->children); + while ((*cib)->children != NULL) { + pcmk__xml_free((*cib)->children); } /* Copying is wasteful here, but calling pcmk__xml_copy() adds the copy as a - * child of the existing *result_cib within the same document. This reduces - * the number of opportunities to make mistakes related to XML documents, - * change tracking, etc., compared to calling xmlUnlinkChild(), - * xmlAddChild(), etc. + * child of the existing *cib within the same document. This reduces the + * number of opportunities to make mistakes related to XML documents, change + * tracking, etc., compared to calling xmlUnlinkChild(), xmlAddChild(), etc. */ - pcmk__xml_copy(*result_cib, empty_config); - pcmk__xml_copy(*result_cib, empty_status); + pcmk__xml_copy(*cib, empty_config); + pcmk__xml_copy(*cib, empty_status); - update_counter(*result_cib, PCMK_XA_ADMIN_EPOCH, false); + update_counter(*cib, PCMK_XA_ADMIN_EPOCH, false); pcmk__xml_free(empty); return pcmk_rc_ok; @@ -513,11 +506,11 @@ cib__process_erase(const char *op, int options, const char *section, static int process_modify_xpath(const char *op, int options, const char *xpath, - xmlNode *input, xmlNode *result_cib) + xmlNode *input, xmlNode *cib) { int num_results = 0; int rc = pcmk_rc_ok; - xmlXPathObject *xpath_obj = pcmk__xpath_search(result_cib->doc, xpath); + xmlXPathObject *xpath_obj = pcmk__xpath_search(cib->doc, xpath); const bool score = pcmk__is_set(options, cib_score_update); const uint32_t flags = (score? pcmk__xaf_score_update : pcmk__xaf_none); @@ -556,7 +549,7 @@ process_modify_xpath(const char *op, int options, const char *xpath, static int process_modify_section(int options, const char *section, xmlNode *input, - xmlNode *result_cib) + xmlNode *cib) { const bool score = pcmk__is_set(options, cib_score_update); const uint32_t flags = (score? pcmk__xaf_score_update : pcmk__xaf_none); @@ -567,7 +560,7 @@ process_modify_section(int options, const char *section, xmlNode *input, return EINVAL; } - obj_root = pcmk_find_cib_element(result_cib, section); + obj_root = pcmk_find_cib_element(cib, section); if (obj_root == NULL) { xmlNode *tmp_section = NULL; const char *path = pcmk_cib_parent_name_for(section); @@ -579,11 +572,10 @@ process_modify_section(int options, const char *section, xmlNode *input, tmp_section = pcmk__xe_create(NULL, section); // @TODO This feels hacky and is the only call to process_create_xpath() - process_create_xpath(PCMK__CIB_REQUEST_CREATE, path, tmp_section, - result_cib); + process_create_xpath(PCMK__CIB_REQUEST_CREATE, path, tmp_section, cib); pcmk__xml_free(tmp_section); - obj_root = pcmk_find_cib_element(result_cib, section); + obj_root = pcmk_find_cib_element(cib, section); } // Should be impossible, as we just created this section if it didn't exist @@ -603,23 +595,23 @@ process_modify_section(int options, const char *section, xmlNode *input, int cib__process_modify(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { if (pcmk__is_set(options, cib_xpath)) { - return process_modify_xpath(op, options, section, input, *result_cib); + return process_modify_xpath(op, options, section, input, *cib); } - return process_modify_section(options, section, input, *result_cib); + return process_modify_section(options, section, input, *cib); } static int process_query_xpath(const char *op, int options, const char *xpath, - xmlNode *existing_cib, xmlNode **answer) + xmlNode *cib, xmlNode **answer) { int num_results = 0; int rc = pcmk_rc_ok; - xmlXPathObject *xpath_obj = pcmk__xpath_search(existing_cib->doc, xpath); + xmlXPathObject *xpath_obj = pcmk__xpath_search(cib->doc, xpath); num_results = pcmk__xpath_num_results(xpath_obj); if (num_results == 0) { @@ -706,7 +698,7 @@ process_query_xpath(const char *op, int options, const char *xpath, } static int -process_query_section(int options, const char *section, xmlNode *existing_cib, +process_query_section(int options, const char *section, xmlNode *cib, xmlNode **answer) { xmlNode *obj_root = NULL; @@ -715,7 +707,7 @@ process_query_section(int options, const char *section, xmlNode *existing_cib, section = NULL; } - obj_root = pcmk_find_cib_element(existing_cib, section); + obj_root = pcmk_find_cib_element(cib, section); if (obj_root == NULL) { return ENXIO; } @@ -737,23 +729,22 @@ process_query_section(int options, const char *section, xmlNode *existing_cib, int cib__process_query(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, xmlNode **answer) { if (pcmk__is_set(options, cib_xpath)) { - return process_query_xpath(op, options, section, existing_cib, answer); + return process_query_xpath(op, options, section, *cib, answer); } - return process_query_section(options, section, existing_cib, answer); + return process_query_section(options, section, *cib, answer); } static int process_replace_xpath(const char *op, int options, const char *xpath, - xmlNode *input, xmlNode *result_cib) + xmlNode *input, xmlNode *cib) { int num_results = 0; int rc = pcmk_rc_ok; - xmlXPathObject *xpath_obj = pcmk__xpath_search(result_cib->doc, xpath); + xmlXPathObject *xpath_obj = pcmk__xpath_search(cib->doc, xpath); num_results = pcmk__xpath_num_results(xpath_obj); if (num_results == 0) { @@ -820,7 +811,7 @@ replace_cib_digest_matches(xmlNode *request, xmlNode *input) } static int -replace_cib(xmlNode *request, xmlNode *input, xmlNode **result_cib) +replace_cib(xmlNode *request, xmlNode *input, xmlNode **cib) { int updates = 0; int epoch = 0; @@ -833,7 +824,7 @@ replace_cib(xmlNode *request, xmlNode *input, xmlNode **result_cib) const char *reason = NULL; const char *peer = pcmk__xe_get(request, PCMK__XA_SRC); - cib_version_details(*result_cib, &admin_epoch, &epoch, &updates); + cib_version_details(*cib, &admin_epoch, &epoch, &updates); cib_version_details(input, &replace_admin_epoch, &replace_epoch, &replace_updates); @@ -868,19 +859,17 @@ replace_cib(xmlNode *request, xmlNode *input, xmlNode **result_cib) return pcmk_rc_old_data; } + *cib = pcmk__xml_replace_with_copy(*cib, input); + pcmk__info("Replaced %d.%d.%d with %d.%d.%d from %s", admin_epoch, epoch, updates, replace_admin_epoch, replace_epoch, replace_updates, peer); - - pcmk__xml_free(*result_cib); - *result_cib = pcmk__xml_copy(NULL, input); - return pcmk_rc_ok; } static int process_replace_section(const char *section, xmlNode *request, xmlNode *input, - xmlNode **result_cib) + xmlNode **cib) { int rc = pcmk_rc_ok; xmlNode *obj_root = NULL; @@ -891,7 +880,7 @@ process_replace_section(const char *section, xmlNode *request, xmlNode *input, } if (pcmk__xe_is(input, PCMK_XE_CIB)) { - return replace_cib(request, input, result_cib); + return replace_cib(request, input, cib); } if (pcmk__str_eq(PCMK__XE_ALL, section, pcmk__str_casei) @@ -900,7 +889,7 @@ process_replace_section(const char *section, xmlNode *request, xmlNode *input, section = NULL; } - obj_root = pcmk_find_cib_element(*result_cib, section); + obj_root = pcmk_find_cib_element(*cib, section); rc = pcmk__xe_replace_match(obj_root, input); if (rc != pcmk_rc_ok) { @@ -912,35 +901,35 @@ process_replace_section(const char *section, xmlNode *request, xmlNode *input, int cib__process_replace(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { if (pcmk__is_set(options, cib_xpath)) { - return process_replace_xpath(op, options, section, input, *result_cib); + return process_replace_xpath(op, options, section, input, *cib); } - return process_replace_section(section, req, input, result_cib); + return process_replace_section(section, req, input, cib); } int cib__process_upgrade(const char *op, int options, const char *section, - xmlNode *req, xmlNode *input, xmlNode *existing_cib, - xmlNode **result_cib, xmlNode **answer) + xmlNode *req, xmlNode *input, xmlNode **cib, + xmlNode **answer) { int rc = pcmk_rc_ok; const char *max_schema = pcmk__xe_get(req, PCMK__XA_CIB_SCHEMA_MAX); const char *original_schema = NULL; const char *new_schema = NULL; - original_schema = pcmk__xe_get(*result_cib, PCMK_XA_VALIDATE_WITH); - rc = pcmk__update_schema(result_cib, max_schema, true, + original_schema = pcmk__xe_get(*cib, PCMK_XA_VALIDATE_WITH); + rc = pcmk__update_schema(cib, max_schema, true, !pcmk__is_set(options, cib_verbose)); - new_schema = pcmk__xe_get(*result_cib, PCMK_XA_VALIDATE_WITH); + new_schema = pcmk__xe_get(*cib, PCMK_XA_VALIDATE_WITH); if (pcmk__cmp_schemas_by_name(new_schema, original_schema) > 0) { - update_counter(*result_cib, PCMK_XA_ADMIN_EPOCH, false); - update_counter(*result_cib, PCMK_XA_EPOCH, true); - update_counter(*result_cib, PCMK_XA_NUM_UPDATES, true); + update_counter(*cib, PCMK_XA_ADMIN_EPOCH, false); + update_counter(*cib, PCMK_XA_EPOCH, true); + update_counter(*cib, PCMK_XA_NUM_UPDATES, true); return pcmk_rc_ok; } diff --git a/lib/cib/cib_remote.c b/lib/cib/cib_remote.c index 3ab07278d7e..1b3a8c08574 100644 --- a/lib/cib/cib_remote.c +++ b/lib/cib/cib_remote.c @@ -78,6 +78,7 @@ cib_remote_perform_op(cib_t *cib, const char *op, const char *host, rc = cib__create_op(cib, op, host, section, data, call_options, user_name, NULL, &op_msg); + rc = pcmk_rc2legacy(rc); if (rc != pcmk_ok) { return rc; } @@ -85,7 +86,7 @@ cib_remote_perform_op(cib_t *cib, const char *op, const char *host, if (pcmk__is_set(call_options, cib_transaction)) { rc = cib__extend_transaction(cib, op_msg); pcmk__xml_free(op_msg); - return rc; + return pcmk_rc2legacy(rc); } pcmk__trace("Sending %s message to the CIB manager", op); @@ -162,11 +163,6 @@ cib_remote_perform_op(cib_t *cib, const char *op, const char *host, rc = -EPROTO; } - if (rc == -pcmk_err_diff_resync) { - /* This is an internal value that clients do not and should not care about */ - rc = pcmk_ok; - } - if (rc == pcmk_ok || rc == -EPERM) { pcmk__log_xml_debug(op_reply, "passed"); diff --git a/lib/cib/cib_utils.c b/lib/cib/cib_utils.c index 624bab190bd..505080591fc 100644 --- a/lib/cib/cib_utils.c +++ b/lib/cib/cib_utils.c @@ -1,6 +1,6 @@ /* * Original copyright 2004 International Business Machines - * Later changes copyright 2008-2025 the Pacemaker project contributors + * Later changes copyright 2008-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -100,9 +100,9 @@ createEmptyCib(int cib_epoch) pcmk__xe_set(cib_root, PCMK_XA_CRM_FEATURE_SET, CRM_FEATURE_SET); pcmk__xe_set(cib_root, PCMK_XA_VALIDATE_WITH, pcmk__highest_schema_name()); + pcmk__xe_set_int(cib_root, PCMK_XA_ADMIN_EPOCH, 0); pcmk__xe_set_int(cib_root, PCMK_XA_EPOCH, cib_epoch); pcmk__xe_set_int(cib_root, PCMK_XA_NUM_UPDATES, 0); - pcmk__xe_set_int(cib_root, PCMK_XA_ADMIN_EPOCH, 0); config = pcmk__xe_create(cib_root, PCMK_XE_CONFIGURATION); pcmk__xe_create(cib_root, PCMK_XE_STATUS); @@ -177,7 +177,7 @@ cib__perform_query(const char *op, uint32_t call_options, cib__op_fn_t fn, int rc = pcmk_rc_ok; const char *user = NULL; - xmlNode *cib_ro = NULL; + xmlNode *cib = NULL; xmlNode *cib_filtered = NULL; pcmk__assert((op != NULL) && (fn != NULL) && (req != NULL) @@ -185,7 +185,7 @@ cib__perform_query(const char *op, uint32_t call_options, cib__op_fn_t fn, && (output != NULL) && (*output == NULL)); user = pcmk__xe_get(req, PCMK__XA_CIB_USER); - cib_ro = *current_cib; + cib = *current_cib; if (cib_acl_enabled(*current_cib, user) && xml_acl_filtered_copy(user, *current_cib, *current_cib, @@ -195,15 +195,15 @@ cib__perform_query(const char *op, uint32_t call_options, cib__op_fn_t fn, pcmk__debug("Pre-filtered the entire cib"); return EACCES; } - cib_ro = cib_filtered; - pcmk__log_xml_trace(cib_ro, "filtered"); + cib = cib_filtered; + pcmk__log_xml_trace(cib, "filtered"); } pcmk__trace("Processing %s for section '%s', user '%s'", op, pcmk__s(section, "(null)"), pcmk__s(user, "(null)")); pcmk__log_xml_trace(req, "request"); - rc = fn(op, call_options, section, req, input, cib_ro, &cib_ro, output); + rc = fn(op, call_options, section, req, input, &cib, output); if (*output == NULL) { // Do nothing @@ -226,7 +226,6 @@ cib__perform_query(const char *op, uint32_t call_options, cib__op_fn_t fn, } pcmk__xml_free(cib_filtered); - return rc; } @@ -278,284 +277,340 @@ should_copy_cib(const char *op, const char *section, int call_options) return true; } +/*! + * \internal + * \brief Validate that a new CIB's feature set is not newer than ours + * + * Return an error if the new CIB's feature set is newer than ours. + * + * \param[in] new_cib Result CIB after performing operation + * + * \return Standard Pacemaker return code + */ +static int +check_new_feature_set(const xmlNode *new_cib) +{ + const char *new_version = pcmk__xe_get(new_cib, PCMK_XA_CRM_FEATURE_SET); + int rc = pcmk__check_feature_set(new_version); + + if (rc == pcmk_rc_ok) { + return pcmk_rc_ok; + } + + pcmk__err("Discarding update with feature set %s greater than our own (%s)", + new_version, CRM_FEATURE_SET); + return rc; +} + +/*! + * \internal + * \brief Validate that a new CIB has a newer version attribute than an old CIB + * + * Return an error if the value of the given attribute is higher in the old CIB + * than in the new CIB. + * + * \param[in] attr Name of version attribute to check + * \param[in] old_cib \c PCMK_XE_CIB element before performing operation + * \param[in] new_cib \c PCMK_XE_CIB element from result of operation + * \param[in] request CIB request + * \param[in] input Input data for CIB request + * + * \return Standard Pacemaker return code + * + * \note \p old_cib only has to contain the top-level \c PCMK_XE_CIB element. It + * might not be a full CIB. + */ +static int +check_cib_version_attr(const char *attr, const xmlNode *old_cib, + const xmlNode *new_cib, const xmlNode *request, + const xmlNode *input) +{ + const char *op = pcmk__xe_get(request, PCMK__XA_CIB_OP); + int old_version = 0; + int new_version = 0; + + pcmk__xe_get_int(old_cib, attr, &old_version); + pcmk__xe_get_int(new_cib, attr, &new_version); + + if (old_version < new_version) { + return pcmk_rc_ok; + } + + if (old_version == new_version) { + return pcmk_rc_undetermined; + } + + pcmk__err("%s went backwards in %s request: %d -> %d", attr, op, + old_version, new_version); + pcmk__log_xml_warn(request, "bad-request"); + pcmk__log_xml_warn(input, "bad-input"); + + return pcmk_rc_old_data; +} + +/*! + * \internal + * \brief Validate that a new CIB has newer versions than an old CIB + * + * Return an error if: + * - \c PCMK_XA_ADMIN_EPOCH is newer in the old CIB than in the new CIB; or + * - The \c PCMK_XA_ADMIN_EPOCH attributes are equal and \c PCMK_XA_EPOCH is + * newer in the old CIB than in the new CIB. + * + * \param[in] old_cib \c PCMK_XE_CIB element before performing operation + * \param[in] new_cib \c PCMK_XE_CIB element from result of operation + * \param[in] request CIB request + * \param[in] input Input data for CIB request + * + * \return Standard Pacemaker return code + * + * \note \p old_cib only has to contain the top-level \c PCMK_XE_CIB element. It + * might not be a full CIB. + */ +static int +check_cib_versions(const xmlNode *old_cib, const xmlNode *new_cib, + const xmlNode *request, const xmlNode *input) +{ + int rc = check_cib_version_attr(PCMK_XA_ADMIN_EPOCH, old_cib, new_cib, + request, input); + + if (rc != pcmk_rc_undetermined) { + return rc; + } + + // @TODO Why aren't we checking PCMK_XA_NUM_UPDATES if epochs are equal? + rc = check_cib_version_attr(PCMK_XA_EPOCH, old_cib, new_cib, request, + input); + if (rc == pcmk_rc_undetermined) { + rc = pcmk_rc_ok; + } + + return rc; +} + +/*! + * \internal + * \brief Set values for update origin host, client, and user in new CIB + * + * \param[in,out] new_cib Result CIB after performing operation + * \param[in] request CIB request (source of origin info) + * + * \return Standard Pacemaker return code + */ +static int +set_update_origin(xmlNode *new_cib, const xmlNode *request) +{ + const char *origin = pcmk__xe_get(request, PCMK__XA_SRC); + const char *client = pcmk__xe_get(request, PCMK__XA_CIB_CLIENTNAME); + const char *user = pcmk__xe_get(request, PCMK__XA_CIB_USER); + const char *schema = pcmk__xe_get(new_cib, PCMK_XA_VALIDATE_WITH); + + if (schema == NULL) { + return pcmk_rc_cib_corrupt; + } + + pcmk__xe_add_last_written(new_cib); + pcmk__warn_if_schema_deprecated(schema); + + // pacemaker-1.2 is the earliest schema version that allow these attributes + if (pcmk__cmp_schemas_by_name(schema, "pacemaker-1.2") < 0) { + return pcmk_rc_ok; + } + + if (origin != NULL) { + pcmk__xe_set(new_cib, PCMK_XA_UPDATE_ORIGIN, origin); + } else { + pcmk__xe_remove_attr(new_cib, PCMK_XA_UPDATE_ORIGIN); + } + + if (client != NULL) { + pcmk__xe_set(new_cib, PCMK_XA_UPDATE_CLIENT, client); + } else { + pcmk__xe_remove_attr(new_cib, PCMK_XA_UPDATE_CLIENT); + } + + if (user != NULL) { + pcmk__xe_set(new_cib, PCMK_XA_UPDATE_USER, user); + } else { + pcmk__xe_remove_attr(new_cib, PCMK_XA_UPDATE_USER); + } + + return pcmk_rc_ok; +} + int -cib_perform_op(cib_t *cib, const char *op, uint32_t call_options, +cib_perform_op(enum cib_variant variant, const char *op, uint32_t call_options, cib__op_fn_t fn, const char *section, xmlNode *req, xmlNode *input, bool manage_counters, bool *config_changed, xmlNode **current_cib, xmlNode **result_cib, xmlNode **diff, xmlNode **output) { int rc = pcmk_rc_ok; - bool make_copy = true; + + /* PCMK_XE_CIB element containing version numbers from before the operation. + * This may or may not point to a full CIB XML tree. Do not free, as this + * will be used as an alias for another pointer. + */ + xmlNode *old_versions = NULL; + xmlNode *top = NULL; - xmlNode *scratch = NULL; - xmlNode *patchset_cib = NULL; - xmlNode *local_diff = NULL; + xmlNode *working_cib = NULL; const char *user = NULL; bool enable_acl = false; - bool with_digest = false; pcmk__assert((op != NULL) && (fn != NULL) && (req != NULL) && (config_changed != NULL) && (!*config_changed) && (current_cib != NULL) && (*current_cib != NULL) && (result_cib != NULL) && (*result_cib == NULL) + && (diff != NULL) && (*diff == NULL) && (output != NULL) && (*output == NULL)); user = pcmk__xe_get(req, PCMK__XA_CIB_USER); enable_acl = cib_acl_enabled(*current_cib, user); - make_copy = should_copy_cib(op, section, call_options); - - if (!make_copy) { - /* Conditional on v2 patch style */ - - scratch = *current_cib; - + if (!should_copy_cib(op, section, call_options)) { // Make a copy of the top-level element to store version details - top = pcmk__xe_create(NULL, (const char *) scratch->name); - pcmk__xe_copy_attrs(top, scratch, pcmk__xaf_none); - patchset_cib = top; + top = pcmk__xe_create(NULL, (const char *) (*current_cib)->name); + pcmk__xe_copy_attrs(top, *current_cib, pcmk__xaf_none); + old_versions = top; - pcmk__xml_commit_changes(scratch->doc); - pcmk__xml_doc_set_flags(scratch->doc, pcmk__xf_tracking); + pcmk__xml_commit_changes((*current_cib)->doc); + pcmk__xml_doc_set_flags((*current_cib)->doc, pcmk__xf_tracking); if (enable_acl) { - pcmk__enable_acls((*current_cib)->doc, scratch->doc, user); + pcmk__enable_acls((*current_cib)->doc, (*current_cib)->doc, user); } pcmk__trace("Processing %s for section '%s', user '%s'", op, pcmk__s(section, "(null)"), pcmk__s(user, "(null)")); pcmk__log_xml_trace(req, "request"); - rc = (*fn) (op, call_options, section, req, input, scratch, &scratch, output); + rc = fn(op, call_options, section, req, input, current_cib, output); - /* If scratch points to a new object now (for example, after an erase - * operation), then *current_cib should point to the same object. - * - * @TODO Enable tracking and ACLs and calculate changes? Change tracking - * and unpacked ACLs didn't carry over to new object. + /* Set working_cib to *current_cib after fn(), in case *current_cib + * points somewhere else now (for example, after a erase or full-CIB + * replace op). + */ + working_cib = *current_cib; + + /* @TODO Enable tracking and ACLs and calculate changes? If working_cib + * and *current_cib point to a new object, then change tracking and + * unpacked ACLs didn't carry over to it. */ - *current_cib = scratch; } else { - scratch = pcmk__xml_copy(NULL, *current_cib); - patchset_cib = *current_cib; + working_cib = pcmk__xml_copy(NULL, *current_cib); + old_versions = *current_cib; - pcmk__xml_doc_set_flags(scratch->doc, pcmk__xf_tracking); + pcmk__xml_doc_set_flags(working_cib->doc, pcmk__xf_tracking); if (enable_acl) { - pcmk__enable_acls((*current_cib)->doc, scratch->doc, user); + pcmk__enable_acls((*current_cib)->doc, working_cib->doc, user); } pcmk__trace("Processing %s for section '%s', user '%s'", op, pcmk__s(section, "(null)"), pcmk__s(user, "(null)")); pcmk__log_xml_trace(req, "request"); - rc = (*fn) (op, call_options, section, req, input, *current_cib, - &scratch, output); + rc = fn(op, call_options, section, req, input, &working_cib, output); - /* @TODO This appears to be a hack to determine whether scratch points - * to a new object now, without saving the old pointer (which may be - * invalid now) for comparison. Confirm this, and check more clearly. + /* @TODO This appears to be a hack to determine whether working_cib + * points to a new object now, without saving the old pointer (which may + * be invalid now) for comparison. Confirm this, and check more clearly. */ - if (!pcmk__xml_doc_all_flags_set(scratch->doc, pcmk__xf_tracking)) { + if (!pcmk__xml_doc_all_flags_set(working_cib->doc, pcmk__xf_tracking)) { pcmk__trace("Inferring changes after %s op", op); - pcmk__xml_commit_changes(scratch->doc); + pcmk__xml_commit_changes(working_cib->doc); if (enable_acl) { - pcmk__enable_acls((*current_cib)->doc, scratch->doc, user); + pcmk__enable_acls((*current_cib)->doc, working_cib->doc, user); } - pcmk__xml_mark_changes(*current_cib, scratch); + pcmk__xml_mark_changes(*current_cib, working_cib); } - CRM_CHECK(*current_cib != scratch, return EINVAL); + + pcmk__assert(*current_cib != working_cib); } - xml_acl_disable(scratch); /* Allow the system to make any additional changes */ + // Allow ourselves to make any additional necessary changes + xml_acl_disable(working_cib); + + if (rc != pcmk_rc_ok) { + goto done; + } - if ((rc == pcmk_rc_ok) && (scratch == NULL)) { + if (working_cib == NULL) { rc = EINVAL; goto done; + } - } else if ((rc == pcmk_rc_ok) && xml_acl_denied(scratch)) { + if (xml_acl_denied(working_cib)) { pcmk__trace("ACL rejected part or all of the proposed changes"); rc = EACCES; goto done; - - } else if (rc != pcmk_rc_ok) { - goto done; } /* If the CIB is from a file, we don't need to check that the feature set is * supported. All we care about in that case is the schema version, which * is checked elsewhere. */ - if (scratch && (cib == NULL || cib->variant != cib_file)) { - const char *new_version = pcmk__xe_get(scratch, - PCMK_XA_CRM_FEATURE_SET); - - rc = pcmk__check_feature_set(new_version); + if (variant != cib_file) { + rc = check_new_feature_set(working_cib); if (rc != pcmk_rc_ok) { - pcmk__err("Discarding update with feature set '%s' greater than " - "our own '%s'", - new_version, CRM_FEATURE_SET); goto done; } } - if (patchset_cib != NULL) { - int old = 0; - int new = 0; - - pcmk__xe_get_int(scratch, PCMK_XA_ADMIN_EPOCH, &new); - pcmk__xe_get_int(patchset_cib, PCMK_XA_ADMIN_EPOCH, &old); - - if (old > new) { - pcmk__err("%s went backwards: %d -> %d (Opts: %#x)", - PCMK_XA_ADMIN_EPOCH, old, new, call_options); - pcmk__log_xml_warn(req, "Bad Op"); - pcmk__log_xml_warn(input, "Bad Data"); - rc = pcmk_rc_old_data; - - } else if (old == new) { - pcmk__xe_get_int(scratch, PCMK_XA_EPOCH, &new); - pcmk__xe_get_int(patchset_cib, PCMK_XA_EPOCH, &old); - if (old > new) { - pcmk__err("%s went backwards: %d -> %d (Opts: %#x)", - PCMK_XA_EPOCH, old, new, call_options); - pcmk__log_xml_warn(req, "Bad Op"); - pcmk__log_xml_warn(input, "Bad Data"); - rc = pcmk_rc_old_data; - } - } - } + rc = check_cib_versions(old_versions, working_cib, req, input); - pcmk__trace("Massaging CIB contents"); - pcmk__strip_xml_text(scratch); + pcmk__strip_xml_text(working_cib); - if (make_copy) { - static time_t expires = 0; - time_t tm_now = time(NULL); + /* If we didn't make a copy, the diff will only be accurate for the + * top-level PCMK_XE_CIB element + */ + *diff = xml_create_patchset(0, old_versions, working_cib, config_changed, + manage_counters); - if (expires < tm_now) { - expires = tm_now + 60; /* Validate clients are correctly applying v2-style diffs at most once a minute */ - with_digest = true; - } - } + /* pcmk__xml_commit_changes() resets document private data, so call it even + * if there were no changes. + */ + pcmk__xml_commit_changes(working_cib->doc); - local_diff = xml_create_patchset(0, patchset_cib, scratch, - config_changed, manage_counters); + if (*diff == NULL) { + goto done; + } - pcmk__log_xml_changes(LOG_TRACE, scratch); - pcmk__xml_commit_changes(scratch->doc); + pcmk__log_xml_patchset(LOG_INFO, *diff); - if(local_diff) { - if (with_digest) { - pcmk__xml_patchset_add_digest(local_diff, scratch); - } - pcmk__log_xml_patchset(LOG_INFO, local_diff); - pcmk__log_xml_trace(local_diff, "raw patch"); - } - - if (make_copy && (local_diff != NULL)) { - // Original to compare against doesn't exist - pcmk__if_tracing( - { - // Validate the calculated patch set - int test_rc = pcmk_ok; - int format = 1; - xmlNode *cib_copy = pcmk__xml_copy(NULL, patchset_cib); - - pcmk__xe_get_int(local_diff, PCMK_XA_FORMAT, &format); - test_rc = xml_apply_patchset(cib_copy, local_diff, - manage_counters); - - if (test_rc != pcmk_ok) { - pcmk__xml_write_temp_file(cib_copy, "PatchApply:calculated", - NULL); - pcmk__xml_write_temp_file(patchset_cib, "PatchApply:input", - NULL); - pcmk__xml_write_temp_file(scratch, "PatchApply:actual", - NULL); - pcmk__xml_write_temp_file(local_diff, "PatchApply:diff", - NULL); - pcmk__err("v%d patchset error, patch failed to apply: %s " - "(%d)", - format, pcmk_rc_str(pcmk_legacy2rc(test_rc)), - test_rc); - } - pcmk__xml_free(cib_copy); - }, - {} - ); - } - - /* scratch must not be modified after this point, except for the attributes - * for which pcmk__xa_filterable() returns true + /* working_cib must not be modified after this point, except for the + * attributes for which pcmk__xa_filterable() returns true */ if (*config_changed && !pcmk__is_set(call_options, cib_no_mtime)) { - const char *schema = pcmk__xe_get(scratch, PCMK_XA_VALIDATE_WITH); - - if (schema == NULL) { - rc = pcmk_rc_cib_corrupt; - } - - pcmk__xe_add_last_written(scratch); - pcmk__warn_if_schema_deprecated(schema); - - /* Make values of origin, client, and user in scratch match - * the ones in req (if the schema allows the attributes) - */ - if (pcmk__cmp_schemas_by_name(schema, "pacemaker-1.2") >= 0) { - const char *origin = pcmk__xe_get(req, PCMK__XA_SRC); - const char *client = pcmk__xe_get(req, PCMK__XA_CIB_CLIENTNAME); - - if (origin != NULL) { - pcmk__xe_set(scratch, PCMK_XA_UPDATE_ORIGIN, origin); - } else { - pcmk__xe_remove_attr(scratch, PCMK_XA_UPDATE_ORIGIN); - } - - if (client != NULL) { - pcmk__xe_set(scratch, PCMK_XA_UPDATE_CLIENT, client); - } else { - pcmk__xe_remove_attr(scratch, PCMK_XA_UPDATE_CLIENT); - } - - if (user != NULL) { - pcmk__xe_set(scratch, PCMK_XA_UPDATE_USER, user); - } else { - pcmk__xe_remove_attr(scratch, PCMK_XA_UPDATE_USER); - } + rc = set_update_origin(working_cib, req); + if (rc != pcmk_rc_ok) { + goto done; } } // Skip validation for status-only updates, since we allow anything there if ((rc == pcmk_rc_ok) && !pcmk__str_eq(section, PCMK_XE_STATUS, pcmk__str_casei) - && !pcmk__configured_schema_validates(scratch)) { + && !pcmk__configured_schema_validates(working_cib)) { rc = pcmk_rc_schema_validation; } - done: - - *result_cib = scratch; +done: + *result_cib = working_cib; - /* @TODO: This may not work correctly with !make_copy, since we don't + /* @TODO This may not work correctly when !should_copy_cib(), since we don't * keep the original CIB. */ - if ((rc != pcmk_rc_ok) && cib_acl_enabled(patchset_cib, user) - && xml_acl_filtered_copy(user, patchset_cib, scratch, result_cib)) { + if ((rc != pcmk_rc_ok) && cib_acl_enabled(old_versions, user) + && xml_acl_filtered_copy(user, old_versions, working_cib, result_cib)) { if (*result_cib == NULL) { pcmk__debug("Pre-filtered the entire cib result"); } - pcmk__xml_free(scratch); - } - - if(diff) { - *diff = local_diff; - } else { - pcmk__xml_free(local_diff); + pcmk__xml_free(working_cib); } pcmk__xml_free(top); @@ -569,7 +624,7 @@ cib__create_op(cib_t *cib, const char *op, const char *host, const char *user_name, const char *client_name, xmlNode **op_msg) { - CRM_CHECK((cib != NULL) && (op_msg != NULL), return -EPROTO); + CRM_CHECK((cib != NULL) && (op_msg != NULL), return EPROTO); *op_msg = pcmk__xe_create(NULL, PCMK__XE_CIB_COMMAND); @@ -596,7 +651,7 @@ cib__create_op(cib_t *cib, const char *op, const char *host, pcmk__xml_copy(wrapper, data); } - return pcmk_ok; + return pcmk_rc_ok; } /*! @@ -641,11 +696,13 @@ validate_transaction_request(const xmlNode *request) * \param[in,out] cib CIB client whose transaction to extend * \param[in,out] request Request to add to transaction * - * \return Legacy Pacemaker return code + * \return Standard Pacemaker return code */ int cib__extend_transaction(cib_t *cib, xmlNode *request) { + const char *op = pcmk__xe_get(request, PCMK__XA_CIB_OP); + const char *client_id = NULL; int rc = pcmk_rc_ok; pcmk__assert((cib != NULL) && (request != NULL)); @@ -658,18 +715,16 @@ cib__extend_transaction(cib_t *cib, xmlNode *request) if (rc == pcmk_rc_ok) { pcmk__xml_copy(cib->transaction, request); + return pcmk_rc_ok; + } - } else { - const char *op = pcmk__xe_get(request, PCMK__XA_CIB_OP); - const char *client_id = NULL; + cib->cmds->client_id(cib, NULL, &client_id); - cib->cmds->client_id(cib, NULL, &client_id); - pcmk__err("Failed to add '%s' operation to transaction for client %s: " - "%s", - op, pcmk__s(client_id, "(unidentified)"), pcmk_rc_str(rc)); - pcmk__log_xml_info(request, "failed"); - } - return pcmk_rc2legacy(rc); + pcmk__err("Failed to add '%s' operation to transaction for client %s: %s", + op, pcmk__s(client_id, "(unidentified)"), pcmk_rc_str(rc)); + pcmk__log_xml_info(request, "failed"); + + return rc; } void @@ -697,11 +752,6 @@ cib_native_callback(cib_t * cib, xmlNode * msg, int call_id, int rc) pcmk__debug("No cib object supplied"); } - if (rc == -pcmk_err_diff_resync) { - /* This is an internal value that clients do not and should not care about */ - rc = pcmk_ok; - } - if (blob && blob->callback && (rc == pcmk_ok || blob->only_success == FALSE)) { pcmk__trace("Invoking callback %s for call %d", pcmk__s(blob->id, "without ID"), call_id); @@ -823,8 +873,8 @@ cib_apply_patch_event(xmlNode *event, xmlNode *input, xmlNode **output, *output = pcmk__xml_copy(NULL, input); } - rc = cib__process_apply_patch(NULL, cib_none, NULL, event, diff, input, - output, NULL); + rc = cib__process_apply_patch(NULL, cib_none, NULL, event, diff, output, + NULL); rc = pcmk_rc2legacy(rc); if (rc == pcmk_ok) { return pcmk_ok; diff --git a/lib/common/messages.c b/lib/common/messages.c index fe8a0921e9d..da226ee699f 100644 --- a/lib/common/messages.c +++ b/lib/common/messages.c @@ -229,7 +229,7 @@ pcmk__process_request(pcmk__request_t *request, GHashTable *handlers) } } - return (*handler)(request); + return handler(request); } /*! diff --git a/lib/common/patchset.c b/lib/common/patchset.c index f4a25d38f30..311478717b1 100644 --- a/lib/common/patchset.c +++ b/lib/common/patchset.c @@ -180,8 +180,9 @@ is_config_change(xmlNode *xml) return FALSE; } +// Guaranteed to return non-NULL static xmlNode * -xml_create_patchset_v2(xmlNode *source, xmlNode *target) +xml_create_patchset_v2(const xmlNode *source, xmlNode *target) { int lpc = 0; GList *gIter = NULL; @@ -192,11 +193,6 @@ xml_create_patchset_v2(xmlNode *source, xmlNode *target) xmlNode *patchset = NULL; pcmk__assert(target != NULL); - - if (!pcmk__xml_doc_all_flags_set(target->doc, pcmk__xf_dirty)) { - return NULL; - } - pcmk__assert(target->doc != NULL); docpriv = target->doc->_private; @@ -240,8 +236,9 @@ xml_create_patchset_v2(xmlNode *source, xmlNode *target) return patchset; } +// *config_changed is unchanged if the return value is NULL xmlNode * -xml_create_patchset(int format, xmlNode *source, xmlNode *target, +xml_create_patchset(int format, const xmlNode *source, xmlNode *target, bool *config_changed, bool manage_version) { bool local_config_changed = false; @@ -467,7 +464,7 @@ check_patchset_versions(const xmlNode *cib_root, const xmlNode *patchset) vfields[i], current[0], current[1], current[2], source[0], source[1], source[2], target[0], target[1], target[2]); - return pcmk_rc_diff_resync; + return pcmk_rc_diff_failed; } if (current[i] > source[i]) { pcmk__info("Current %s is too high " diff --git a/lib/common/patchset_display.c b/lib/common/patchset_display.c index 9cc1663eaf0..110e56e3a98 100644 --- a/lib/common/patchset_display.c +++ b/lib/common/patchset_display.c @@ -50,9 +50,10 @@ xml_show_patchset_header(pcmk__output_t *out, const xmlNode *patchset) const char *fmt = pcmk__xe_get(patchset, PCMK_XA_FORMAT); const char *digest = pcmk__xe_get(patchset, PCMK_XA_DIGEST); - out->info(out, "Diff: --- %d.%d.%d %s", del[0], del[1], del[2], fmt); + out->info(out, "Diff: --- %d.%d.%d %s", del[0], del[1], del[2], + pcmk__s(fmt, "(no format)")); rc = out->info(out, "Diff: +++ %d.%d.%d %s", - add[0], add[1], add[2], digest); + add[0], add[1], add[2], pcmk__s(digest, "(no digest)")); } else if ((add[0] != 0) || (add[1] != 0) || (add[2] != 0)) { rc = out->info(out, "Local-only Change: %d.%d.%d", diff --git a/lib/common/xml.c b/lib/common/xml.c index 5b34ba2fe5a..4f3c7897f26 100644 --- a/lib/common/xml.c +++ b/lib/common/xml.c @@ -856,6 +856,51 @@ pcmk__xml_copy(xmlNode *parent, xmlNode *src) return copy; } +/*! + * \internal + * \brief Replace one XML node with a copy of another XML node + * + * This function handles change tracking and applies ACLs. + * + * \param[in,out] old XML node to replace + * \param[in] new XML node to copy as replacement for \p old + * + * \return Copy of \p new that replaced \p old + * + * \note This frees \p old. + * \note The caller is responsible for freeing the return value using + * \c pcmk__xml_free() (but note that it may be part of a larger XML + * tree). + */ +xmlNode * +pcmk__xml_replace_with_copy(xmlNode *old, xmlNode *new) +{ + xmlNode *new_copy = NULL; + + pcmk__assert((old != NULL) && (new != NULL)); + + /* Pass old to pcmk__xml_copy() so that new_copy gets created within the + * same doc. But old won't remain its parent. + */ + new_copy = pcmk__xml_copy(old, new); + old = xmlReplaceNode(old, new_copy); + + // old == NULL means memory allocation error + pcmk__assert(old != NULL); + + // May be unnecessary but avoids slight changes to some test outputs + pcmk__xml_tree_foreach(new_copy, pcmk__xml_reset_node_flags, NULL); + + if (pcmk__xml_doc_all_flags_set(new_copy->doc, pcmk__xf_tracking)) { + // Replaced sections may have included relevant ACLs + pcmk__apply_acls(new_copy->doc); + } + pcmk__xml_mark_changes(old, new_copy); + pcmk__xml_free_node(old); + + return new_copy; +} + /*! * \internal * \brief Remove XML text nodes from specified XML and all its children diff --git a/lib/common/xml_element.c b/lib/common/xml_element.c index 106ac6f1de1..5e7b5aa97c1 100644 --- a/lib/common/xml_element.c +++ b/lib/common/xml_element.c @@ -732,38 +732,6 @@ pcmk__xe_delete_match(xmlNode *xml, xmlNode *search) return ENXIO; } -/*! - * \internal - * \brief Replace one XML node with a copy of another XML node - * - * This function handles change tracking and applies ACLs. - * - * \param[in,out] old XML node to replace - * \param[in] new XML node to copy as replacement for \p old - * - * \note This frees \p old. - */ -static void -replace_node(xmlNode *old, xmlNode *new) -{ - // Pass old for its doc; it won't remain the parent of new - new = pcmk__xml_copy(old, new); - old = xmlReplaceNode(old, new); - - // old == NULL means memory allocation error - pcmk__assert(old != NULL); - - // May be unnecessary but avoids slight changes to some test outputs - pcmk__xml_tree_foreach(new, pcmk__xml_reset_node_flags, NULL); - - if (pcmk__xml_doc_all_flags_set(new->doc, pcmk__xf_tracking)) { - // Replaced sections may have included relevant ACLs - pcmk__apply_acls(new->doc); - } - pcmk__xml_mark_changes(old, new); - pcmk__xml_free_node(old); -} - /*! * \internal * \brief Replace one XML subtree with a copy of another if the two match @@ -805,7 +773,7 @@ replace_xe_if_matching(xmlNode *xml, void *user_data) pcmk__log_xml_trace(xml, "replace-match"); pcmk__log_xml_trace(replace, "replace-with"); - replace_node(xml, replace); + pcmk__xml_replace_with_copy(xml, replace); // Found a match and replaced it; stop traversing tree return false; diff --git a/lib/common/xpath.c b/lib/common/xpath.c index 8bff702dcb0..96de7b01c42 100644 --- a/lib/common/xpath.c +++ b/lib/common/xpath.c @@ -182,7 +182,7 @@ pcmk__xpath_foreach_result(xmlDoc *doc, const char *path, xmlNode *result = pcmk__xpath_result(xpath_obj, i); if (result != NULL) { - (*fn)(result, user_data); + fn(result, user_data); } } xmlXPathFreeObject(xpath_obj); @@ -519,7 +519,7 @@ crm_foreach_xpath_result(xmlNode *xml, const char *xpath, CRM_LOG_ASSERT(result != NULL); if (result != NULL) { - (*helper)(result, user_data); + helper(result, user_data); } } } diff --git a/lib/pengine/remote.c b/lib/pengine/remote.c index 84b5ca4972c..45a15f7ee07 100644 --- a/lib/pengine/remote.c +++ b/lib/pengine/remote.c @@ -103,7 +103,7 @@ pe_foreach_guest_node(const pcmk_scheduler_t *scheduler, pcmk_node_t *guest_node = pcmk_find_node(scheduler, rsc->id); if (guest_node) { - (*helper)(guest_node, user_data); + helper(guest_node, user_data); } } } diff --git a/tools/crm_mon.c b/tools/crm_mon.c index ab42c3bac96..8853e6ba52e 100644 --- a/tools/crm_mon.c +++ b/tools/crm_mon.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2025 the Pacemaker project contributors + * Copyright 2004-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -1948,7 +1948,6 @@ crm_diff_update(const char *event, xmlNode * msg) rc = xml_apply_patchset(current_cib, diff, TRUE); switch (rc) { - case -pcmk_err_diff_resync: case -pcmk_err_diff_failed: pcmk__notice("[%s] Patch aborted: %s (%d)", event, pcmk_strerror(rc), rc); @@ -1961,6 +1960,7 @@ crm_diff_update(const char *event, xmlNode * msg) pcmk__notice("[%s] ABORTED: %s (%d)", event, pcmk_strerror(rc), rc); pcmk__xml_free(current_cib); current_cib = NULL; + break; } }