[PATCH 2/2] Use more of VIR_XPATH_NODE_AUTORESTORE

Michal Privoznik posted 2 patches 4 years, 5 months ago
[PATCH 2/2] Use more of VIR_XPATH_NODE_AUTORESTORE
Posted by Michal Privoznik 4 years, 5 months ago
This is convenience macro, use it more. This commit was generated
using the following spatch:

  @@
  symbol node;
  identifier old;
  identifier ctxt;
  type xmlNodePtr;
  @@
  - xmlNodePtr old;
  + VIR_XPATH_NODE_AUTORESTORE(ctxt);
    ...
  - old = ctxt->node;
    ... when != old
  - ctxt->node = old;

  @@
  symbol node;
  identifier old;
  identifier ctxt;
  type xmlNodePtr;
  @@
  - xmlNodePtr old = ctxt->node;
  + VIR_XPATH_NODE_AUTORESTORE(ctxt);
    ... when != old
  - ctxt->node = old;

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
 src/conf/cpu_conf.c             |  3 +-
 src/conf/domain_conf.c          |  7 +--
 src/conf/interface_conf.c       | 16 ++-----
 src/conf/netdev_vlan_conf.c     |  3 +-
 src/conf/network_conf.c         | 25 +++-------
 src/conf/networkcommon_conf.c   |  4 +-
 src/conf/node_device_conf.c     | 84 +++++++++------------------------
 src/conf/numa_conf.c            |  3 +-
 src/conf/snapshot_conf.c        |  3 +-
 src/conf/storage_adapter_conf.c |  3 +-
 src/conf/storage_conf.c         |  4 +-
 src/conf/virsavecookie.c        |  3 +-
 src/cpu/cpu_map.c               | 12 +----
 src/cpu/cpu_x86.c               |  3 +-
 src/lxc/lxc_domain.c            |  4 +-
 src/util/virstorageencryption.c |  8 +---
 src/util/virstoragefile.c       |  3 +-
 tools/virsh-domain.c            |  6 +--
 18 files changed, 52 insertions(+), 142 deletions(-)

diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index c6d36e0cb5..1d02e23175 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -326,7 +326,7 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
 {
     virCPUDefPtr def = NULL;
     xmlNodePtr *nodes = NULL;
-    xmlNodePtr oldnode = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     int n;
     size_t i;
     char *cpuMode;
@@ -662,7 +662,6 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
     ret = 0;
 
  cleanup:
-    ctxt->node = oldnode;
     VIR_FREE(fallback);
     VIR_FREE(vendor_id);
     VIR_FREE(nodes);
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 1406cf079e..1cdc7971fc 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -13265,16 +13265,14 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
 
             /* Check for an optional seclabel override in <source/>. */
             if (chr_def) {
-                xmlNodePtr saved_node = ctxt->node;
+                VIR_XPATH_NODE_AUTORESTORE(ctxt);
                 ctxt->node = cur;
                 if (virSecurityDeviceLabelDefParseXML(&def->seclabels,
                                                       &def->nseclabels,
                                                       ctxt,
                                                       flags) < 0) {
-                    ctxt->node = saved_node;
                     goto error;
                 }
-                ctxt->node = saved_node;
             }
         } else if (virXMLNodeNameEqual(cur, "log")) {
             if (logParsed) {
@@ -22181,11 +22179,10 @@ virDomainDefParseXML(xmlDocPtr xml,
     }
 
     if ((node = virXPathNode("./sysinfo[1]", ctxt)) != NULL) {
-        xmlNodePtr oldnode = ctxt->node;
+        VIR_XPATH_NODE_AUTORESTORE(ctxt);
         ctxt->node = node;
         def->sysinfo = virSysinfoParseXML(node, ctxt,
                                           def->uuid, uuid_generated);
-        ctxt->node = oldnode;
 
         if (def->sysinfo == NULL)
             goto error;
diff --git a/src/conf/interface_conf.c b/src/conf/interface_conf.c
index d1732621b5..be5e1133a2 100644
--- a/src/conf/interface_conf.c
+++ b/src/conf/interface_conf.c
@@ -262,12 +262,11 @@ static int
 virInterfaceDefParseDhcp(virInterfaceProtocolDefPtr def,
                          xmlNodePtr dhcp, xmlXPathContextPtr ctxt)
 {
-    xmlNodePtr save;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     char *tmp;
     int ret = 0;
 
     def->dhcp = 1;
-    save = ctxt->node;
     ctxt->node = dhcp;
     def->peerdns = -1;
     /* Not much to do in the current version */
@@ -284,7 +283,6 @@ virInterfaceDefParseDhcp(virInterfaceProtocolDefPtr def,
         VIR_FREE(tmp);
     }
 
-    ctxt->node = save;
     return ret;
 }
 
@@ -426,13 +424,11 @@ static int
 virInterfaceDefParseIfAdressing(virInterfaceDefPtr def,
                                 xmlXPathContextPtr ctxt)
 {
-    xmlNodePtr save;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     xmlNodePtr *protoNodes = NULL;
     int nProtoNodes, pp, ret = -1;
     char *tmp;
 
-    save = ctxt->node;
-
     nProtoNodes = virXPathNodeSet("./protocol", ctxt, &protoNodes);
     if (nProtoNodes < 0)
         goto error;
@@ -487,7 +483,6 @@ virInterfaceDefParseIfAdressing(virInterfaceDefPtr def,
 
  error:
     VIR_FREE(protoNodes);
-    ctxt->node = save;
     return ret;
 
 }
@@ -558,7 +553,7 @@ virInterfaceDefParseBondItfs(virInterfaceDefPtr def,
                              xmlXPathContextPtr ctxt)
 {
     xmlNodePtr *interfaces = NULL;
-    xmlNodePtr bond = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     virInterfaceDefPtr itf;
     int nbItf;
     size_t i;
@@ -591,7 +586,6 @@ virInterfaceDefParseBondItfs(virInterfaceDefPtr def,
     ret = 0;
  cleanup:
     VIR_FREE(interfaces);
-    ctxt->node = bond;
     return ret;
 }
 
@@ -698,7 +692,7 @@ virInterfaceDefParseXML(xmlXPathContextPtr ctxt,
     virInterfaceDefPtr def;
     int type;
     char *tmp;
-    xmlNodePtr cur = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     xmlNodePtr lnk;
 
 
@@ -804,11 +798,9 @@ virInterfaceDefParseXML(xmlXPathContextPtr ctxt,
 
     }
 
-    ctxt->node = cur;
     return def;
 
  error:
-    ctxt->node = cur;
     virInterfaceDefFree(def);
     return NULL;
 }
diff --git a/src/conf/netdev_vlan_conf.c b/src/conf/netdev_vlan_conf.c
index 516129280d..7830a341b2 100644
--- a/src/conf/netdev_vlan_conf.c
+++ b/src/conf/netdev_vlan_conf.c
@@ -33,7 +33,7 @@ int
 virNetDevVlanParse(xmlNodePtr node, xmlXPathContextPtr ctxt, virNetDevVlanPtr def)
 {
     int ret = -1;
-    xmlNodePtr save = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     char *trunk = NULL;
     char *nativeMode = NULL;
     xmlNodePtr *tagNodes = NULL;
@@ -128,7 +128,6 @@ virNetDevVlanParse(xmlNodePtr node, xmlXPathContextPtr ctxt, virNetDevVlanPtr de
 
     ret = 0;
  cleanup:
-    ctxt->node = save;
     VIR_FREE(tagNodes);
     VIR_FREE(trunk);
     VIR_FREE(nativeMode);
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index dc64ce6959..f1d22b25b1 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -800,7 +800,7 @@ virNetworkDNSSrvDefParseXML(const char *networkName,
                             bool partialOkay)
 {
     int ret;
-    xmlNodePtr save_ctxt = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
 
     ctxt->node = node;
 
@@ -895,12 +895,10 @@ virNetworkDNSSrvDefParseXML(const char *networkName,
         goto error;
     }
 
-    ctxt->node = save_ctxt;
     return 0;
 
  error:
     virNetworkDNSSrvDefClear(def);
-    ctxt->node = save_ctxt;
     return -1;
 }
 
@@ -961,7 +959,7 @@ virNetworkDNSDefParseXML(const char *networkName,
     int nhosts, nsrvs, ntxts, nfwds;
     size_t i;
     int ret = -1;
-    xmlNodePtr save = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
 
     ctxt->node = node;
 
@@ -1100,7 +1098,6 @@ virNetworkDNSDefParseXML(const char *networkName,
     VIR_FREE(hostNodes);
     VIR_FREE(srvNodes);
     VIR_FREE(txtNodes);
-    ctxt->node = save;
     return ret;
 }
 
@@ -1116,7 +1113,7 @@ virNetworkIPDefParseXML(const char *networkName,
      * On failure clear it out, but don't free it.
      */
 
-    xmlNodePtr save;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     xmlNodePtr dhcp;
     char *address = NULL, *netmask = NULL;
     unsigned long prefix = 0;
@@ -1124,7 +1121,6 @@ virNetworkIPDefParseXML(const char *networkName,
     int result = -1;
     char *localPtr = NULL;
 
-    save = ctxt->node;
     ctxt->node = node;
 
     /* grab raw data from XML */
@@ -1256,7 +1252,6 @@ virNetworkIPDefParseXML(const char *networkName,
     VIR_FREE(netmask);
     VIR_FREE(localPtr);
 
-    ctxt->node = save;
     return result;
 }
 
@@ -1291,7 +1286,7 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
      * On failure clear it out, but don't free it.
      */
 
-    xmlNodePtr save;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     xmlNodePtr virtPortNode;
     xmlNodePtr vlanNode;
     xmlNodePtr bandwidth_node;
@@ -1300,7 +1295,6 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
 
     int result = -1;
 
-    save = ctxt->node;
     ctxt->node = node;
 
     /* grab raw data from XML */
@@ -1348,7 +1342,6 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
     VIR_FREE(isDefault);
     VIR_FREE(trustGuestRxFilters);
 
-    ctxt->node = save;
     return result;
 }
 
@@ -1365,7 +1358,7 @@ virNetworkForwardNatDefParseXML(const char *networkName,
     int nNatAddrs, nNatPorts;
     char *addrStart = NULL;
     char *addrEnd = NULL;
-    xmlNodePtr save = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
 
     ctxt->node = node;
 
@@ -1477,7 +1470,6 @@ virNetworkForwardNatDefParseXML(const char *networkName,
     VIR_FREE(addrEnd);
     VIR_FREE(natAddrNodes);
     VIR_FREE(natPortNodes);
-    ctxt->node = save;
     return ret;
 }
 
@@ -1499,7 +1491,7 @@ virNetworkForwardDefParseXML(const char *networkName,
     char *forwardManaged = NULL;
     char *forwardDriverName = NULL;
     char *type = NULL;
-    xmlNodePtr save = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
 
     ctxt->node = node;
 
@@ -1726,7 +1718,6 @@ virNetworkForwardDefParseXML(const char *networkName,
     VIR_FREE(forwardIfNodes);
     VIR_FREE(forwardAddrNodes);
     VIR_FREE(forwardNatNodes);
-    ctxt->node = save;
     return ret;
 }
 
@@ -1747,7 +1738,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt,
     xmlNodePtr forwardNode = NULL;
     char *ipv6nogwStr = NULL;
     char *trustGuestRxFilters = NULL;
-    xmlNodePtr save = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     xmlNodePtr bandwidthNode = NULL;
     xmlNodePtr vlanNode;
     xmlNodePtr metadataNode = NULL;
@@ -2164,7 +2155,6 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt,
             goto error;
     }
 
-    ctxt->node = save;
     return def;
 
  error:
@@ -2176,7 +2166,6 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt,
     VIR_FREE(portGroupNodes);
     VIR_FREE(ipv6nogwStr);
     VIR_FREE(trustGuestRxFilters);
-    ctxt->node = save;
     return NULL;
 }
 
diff --git a/src/conf/networkcommon_conf.c b/src/conf/networkcommon_conf.c
index e90cfcbef5..a4f9ce5c62 100644
--- a/src/conf/networkcommon_conf.c
+++ b/src/conf/networkcommon_conf.c
@@ -228,7 +228,7 @@ virNetDevIPRouteParseXML(const char *errorDetail,
      */
 
     virNetDevIPRoutePtr def = NULL;
-    xmlNodePtr save;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     char *family = NULL;
     char *address = NULL, *netmask = NULL;
     char *gateway = NULL;
@@ -237,7 +237,6 @@ virNetDevIPRouteParseXML(const char *errorDetail,
     bool hasPrefix = false;
     bool hasMetric = false;
 
-    save = ctxt->node;
     ctxt->node = node;
 
     /* grab raw data from XML */
@@ -278,7 +277,6 @@ virNetDevIPRouteParseXML(const char *errorDetail,
                                  hasMetric);
 
  cleanup:
-    ctxt->node = save;
     VIR_FREE(family);
     VIR_FREE(address);
     VIR_FREE(netmask);
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index 4cf5b6e3d7..33c9c7dec0 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -703,11 +703,10 @@ virNodeDevCapDRMParseXML(xmlXPathContextPtr ctxt,
                          xmlNodePtr node,
                          virNodeDevCapDRMPtr drm)
 {
-    xmlNodePtr orignode;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     int ret = -1, val;
     char *type = NULL;
 
-    orignode = ctxt->node;
     ctxt->node = node;
 
     type = virXPathString("string(./type[1])", ctxt);
@@ -723,7 +722,6 @@ virNodeDevCapDRMParseXML(xmlXPathContextPtr ctxt,
 
  out:
     VIR_FREE(type);
-    ctxt->node = orignode;
     return ret;
 }
 
@@ -734,11 +732,10 @@ virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt,
                          xmlNodePtr node,
                          virNodeDevCapCCWPtr ccw_dev)
 {
-    xmlNodePtr orignode;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     int ret = -1;
     char *cssid = NULL, *ssid = NULL, *devno = NULL;
 
-    orignode = ctxt->node;
     ctxt->node = node;
 
    if (!(cssid = virXPathString("string(./cssid[1])", ctxt))) {
@@ -783,7 +780,6 @@ virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt,
     ret = 0;
 
  out:
-    ctxt->node = orignode;
     VIR_FREE(cssid);
     VIR_FREE(ssid);
     VIR_FREE(devno);
@@ -797,12 +793,12 @@ virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt,
                              xmlNodePtr node,
                              virNodeDevCapStoragePtr storage)
 {
-    xmlNodePtr orignode, *nodes = NULL;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
+    xmlNodePtr *nodes = NULL;
     size_t i;
     int n, ret = -1;
     unsigned long long val;
 
-    orignode = ctxt->node;
     ctxt->node = node;
 
     storage->block = virXPathString("string(./block[1])", ctxt);
@@ -835,11 +831,8 @@ virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt,
         if (STREQ(type, "hotpluggable")) {
             storage->flags |= VIR_NODE_DEV_CAP_STORAGE_HOTPLUGGABLE;
         } else if (STREQ(type, "removable")) {
-            xmlNodePtr orignode2;
-
             storage->flags |= VIR_NODE_DEV_CAP_STORAGE_REMOVABLE;
 
-            orignode2 = ctxt->node;
             ctxt->node = nodes[i];
 
             if (virXPathBoolean("count(./media_available[. = '1']) > 0", ctxt))
@@ -851,13 +844,10 @@ virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt,
             if (virNodeDevCapsDefParseULongLong("number(./media_size[1])", ctxt, &val, def,
                                                 _("no removable media size supplied for '%s'"),
                                                 _("invalid removable media size supplied for '%s'")) < 0) {
-                ctxt->node = orignode2;
                 VIR_FREE(type);
                 goto out;
             }
             storage->removable_media_size = val;
-
-            ctxt->node = orignode2;
         } else {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("unknown storage capability type '%s' for '%s'"),
@@ -881,7 +871,6 @@ virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt,
     ret = 0;
  out:
     VIR_FREE(nodes);
-    ctxt->node = orignode;
     return ret;
 }
 
@@ -892,10 +881,9 @@ virNodeDevCapSCSIParseXML(xmlXPathContextPtr ctxt,
                           xmlNodePtr node,
                           virNodeDevCapSCSIPtr scsi)
 {
-    xmlNodePtr orignode;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     int ret = -1;
 
-    orignode = ctxt->node;
     ctxt->node = node;
 
     if (virNodeDevCapsDefParseULong("number(./host[1])", ctxt,
@@ -926,7 +914,6 @@ virNodeDevCapSCSIParseXML(xmlXPathContextPtr ctxt,
 
     ret = 0;
  out:
-    ctxt->node = orignode;
     return ret;
 }
 
@@ -937,12 +924,12 @@ virNodeDevCapSCSITargetParseXML(xmlXPathContextPtr ctxt,
                                 xmlNodePtr node,
                                 virNodeDevCapSCSITargetPtr scsi_target)
 {
-    xmlNodePtr orignode, *nodes = NULL;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
+    xmlNodePtr *nodes = NULL;
     int ret = -1, n = 0;
     size_t i;
     char *type = NULL;
 
-    orignode = ctxt->node;
     ctxt->node = node;
 
     scsi_target->name = virXPathString("string(./target[1])", ctxt);
@@ -967,11 +954,8 @@ virNodeDevCapSCSITargetParseXML(xmlXPathContextPtr ctxt,
         }
 
         if (STREQ(type, "fc_remote_port")) {
-            xmlNodePtr orignode2;
-
             scsi_target->flags |= VIR_NODE_DEV_CAP_FLAG_FC_RPORT;
 
-            orignode2 = ctxt->node;
             ctxt->node = nodes[i];
 
             if (virNodeDevCapsDefParseString("string(./rport[1])",
@@ -989,8 +973,6 @@ virNodeDevCapSCSITargetParseXML(xmlXPathContextPtr ctxt,
                                def->name);
                 goto out;
             }
-
-            ctxt->node = orignode2;
         } else {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("unknown SCSI target capability type '%s' for '%s'"),
@@ -1004,7 +986,6 @@ virNodeDevCapSCSITargetParseXML(xmlXPathContextPtr ctxt,
     ret = 0;
 
  out:
-    ctxt->node = orignode;
     VIR_FREE(type);
     VIR_FREE(nodes);
     return ret;
@@ -1019,12 +1000,12 @@ virNodeDevCapSCSIHostParseXML(xmlXPathContextPtr ctxt,
                               int create,
                               const char *virt_type)
 {
-    xmlNodePtr orignode, *nodes = NULL;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
+    xmlNodePtr *nodes = NULL;
     int ret = -1, n = 0;
     size_t i;
     char *type = NULL;
 
-    orignode = ctxt->node;
     ctxt->node = node;
 
     if (create == EXISTING_DEVICE) {
@@ -1061,12 +1042,8 @@ virNodeDevCapSCSIHostParseXML(xmlXPathContextPtr ctxt,
             scsi_host->flags |= VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS;
 
         } else if (STREQ(type, "fc_host")) {
-
-            xmlNodePtr orignode2;
-
             scsi_host->flags |= VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST;
 
-            orignode2 = ctxt->node;
             ctxt->node = nodes[i];
 
             if (virNodeDevCapsDefParseString("string(./wwnn[1])",
@@ -1098,8 +1075,6 @@ virNodeDevCapSCSIHostParseXML(xmlXPathContextPtr ctxt,
                                              &scsi_host->fabric_wwn) < 0)
                 VIR_DEBUG("No fabric_wwn defined for '%s'", def->name);
 
-            ctxt->node = orignode2;
-
         } else {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("unknown SCSI host capability type '%s' for '%s'"),
@@ -1114,7 +1089,6 @@ virNodeDevCapSCSIHostParseXML(xmlXPathContextPtr ctxt,
 
  out:
     VIR_FREE(type);
-    ctxt->node = orignode;
     VIR_FREE(nodes);
     return ret;
 }
@@ -1126,13 +1100,13 @@ virNodeDevCapNetParseXML(xmlXPathContextPtr ctxt,
                          xmlNodePtr node,
                          virNodeDevCapNetPtr net)
 {
-    xmlNodePtr orignode, lnk;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
+    xmlNodePtr lnk;
     size_t i = -1;
     int ret = -1, n = -1;
     char *tmp = NULL;
     xmlNodePtr *nodes = NULL;
 
-    orignode = ctxt->node;
     ctxt->node = node;
 
     net->ifname = virXPathString("string(./interface[1])", ctxt);
@@ -1192,7 +1166,6 @@ virNodeDevCapNetParseXML(xmlXPathContextPtr ctxt,
 
     ret = 0;
  out:
-    ctxt->node = orignode;
     VIR_FREE(nodes);
     VIR_FREE(tmp);
     return ret;
@@ -1205,10 +1178,9 @@ virNodeDevCapUSBInterfaceParseXML(xmlXPathContextPtr ctxt,
                                   xmlNodePtr node,
                                   virNodeDevCapUSBIfPtr usb_if)
 {
-    xmlNodePtr orignode;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     int ret = -1;
 
-    orignode = ctxt->node;
     ctxt->node = node;
 
     if (virNodeDevCapsDefParseULong("number(./number[1])", ctxt,
@@ -1239,7 +1211,6 @@ virNodeDevCapUSBInterfaceParseXML(xmlXPathContextPtr ctxt,
 
     ret = 0;
  out:
-    ctxt->node = orignode;
     return ret;
 }
 
@@ -1274,10 +1245,9 @@ virNodeDevCapUSBDevParseXML(xmlXPathContextPtr ctxt,
                             xmlNodePtr node,
                             virNodeDevCapUSBDevPtr usb_dev)
 {
-    xmlNodePtr orignode;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     int ret = -1;
 
-    orignode = ctxt->node;
     ctxt->node = node;
 
     if (virNodeDevCapsDefParseULong("number(./bus[1])", ctxt,
@@ -1309,7 +1279,6 @@ virNodeDevCapUSBDevParseXML(xmlXPathContextPtr ctxt,
 
     ret = 0;
  out:
-    ctxt->node = orignode;
     return ret;
 }
 
@@ -1319,7 +1288,7 @@ virNodeDevCapPCIDevIommuGroupParseXML(xmlXPathContextPtr ctxt,
                                       xmlNodePtr iommuGroupNode,
                                       virNodeDevCapPCIDevPtr pci_dev)
 {
-    xmlNodePtr origNode = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     xmlNodePtr *addrNodes = NULL;
     char *numberStr = NULL;
     int nAddrNodes, ret = -1;
@@ -1363,7 +1332,6 @@ virNodeDevCapPCIDevIommuGroupParseXML(xmlXPathContextPtr ctxt,
 
     ret = 0;
  cleanup:
-    ctxt->node = origNode;
     VIR_FREE(numberStr);
     VIR_FREE(addrNodes);
     VIR_FREE(pciAddr);
@@ -1376,7 +1344,7 @@ virPCIEDeviceInfoLinkParseXML(xmlXPathContextPtr ctxt,
                               xmlNodePtr linkNode,
                               virPCIELinkPtr lnk)
 {
-    xmlNodePtr origNode = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     int ret = -1, speed;
     char *speedStr = NULL, *portStr = NULL;
 
@@ -1413,7 +1381,6 @@ virPCIEDeviceInfoLinkParseXML(xmlXPathContextPtr ctxt,
  cleanup:
     VIR_FREE(portStr);
     VIR_FREE(speedStr);
-    ctxt->node = origNode;
     return ret;
 }
 
@@ -1423,7 +1390,8 @@ virPCIEDeviceInfoParseXML(xmlXPathContextPtr ctxt,
                           xmlNodePtr pciExpressNode,
                           virPCIEDeviceInfoPtr pci_express)
 {
-    xmlNodePtr lnk, origNode = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
+    xmlNodePtr lnk;
     int ret = -1;
 
     ctxt->node = pciExpressNode;
@@ -1448,7 +1416,6 @@ virPCIEDeviceInfoParseXML(xmlXPathContextPtr ctxt,
 
     ret = 0;
  cleanup:
-    ctxt->node = origNode;
     return ret;
 }
 
@@ -1595,7 +1562,7 @@ virNodeDevPCICapabilityParseXML(xmlXPathContextPtr ctxt,
                                 virNodeDevCapPCIDevPtr pci_dev)
 {
     char *type = virXMLPropString(node, "type");
-    xmlNodePtr orignode = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     int ret = -1;
 
     ctxt->node = node;
@@ -1624,7 +1591,6 @@ virNodeDevPCICapabilityParseXML(xmlXPathContextPtr ctxt,
     ret = 0;
  cleanup:
     VIR_FREE(type);
-    ctxt->node = orignode;
     return ret;
 }
 
@@ -1635,7 +1601,9 @@ virNodeDevCapPCIDevParseXML(xmlXPathContextPtr ctxt,
                             xmlNodePtr node,
                             virNodeDevCapPCIDevPtr pci_dev)
 {
-    xmlNodePtr orignode, iommuGroupNode, pciExpress;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
+    xmlNodePtr iommuGroupNode;
+    xmlNodePtr pciExpress;
     xmlNodePtr *nodes = NULL;
     int n = 0;
     int ret = -1;
@@ -1643,7 +1611,6 @@ virNodeDevCapPCIDevParseXML(xmlXPathContextPtr ctxt,
     char *tmp = NULL;
     size_t i = 0;
 
-    orignode = ctxt->node;
     ctxt->node = node;
 
     if ((tmp = virXPathString("string(./class[1])", ctxt))) {
@@ -1737,7 +1704,6 @@ virNodeDevCapPCIDevParseXML(xmlXPathContextPtr ctxt,
     VIR_FREE(nodes);
     VIR_FREE(tmp);
     virPCIEDeviceInfoFree(pci_express);
-    ctxt->node = orignode;
     return ret;
 }
 
@@ -1750,11 +1716,10 @@ virNodeDevCapSystemParseXML(xmlXPathContextPtr ctxt,
 {
     virNodeDevCapSystemHardwarePtr hardware = &syscap->hardware;
     virNodeDevCapSystemFirmwarePtr firmware = &syscap->firmware;
-    xmlNodePtr orignode;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     int ret = -1;
     char *tmp;
 
-    orignode = ctxt->node;
     ctxt->node = node;
 
     syscap->product_name = virXPathString("string(./product[1])", ctxt);
@@ -1784,7 +1749,6 @@ virNodeDevCapSystemParseXML(xmlXPathContextPtr ctxt,
 
     ret = 0;
  out:
-    ctxt->node = orignode;
     return ret;
 }
 
@@ -1795,10 +1759,9 @@ virNodeDevCapMdevParseXML(xmlXPathContextPtr ctxt,
                           xmlNodePtr node,
                           virNodeDevCapMdevPtr mdev)
 {
-    xmlNodePtr orignode;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     int ret = -1;
 
-    orignode = ctxt->node;
     ctxt->node = node;
 
     if (!(mdev->type = virXPathString("string(./type[1]/@id)", ctxt))) {
@@ -1817,7 +1780,6 @@ virNodeDevCapMdevParseXML(xmlXPathContextPtr ctxt,
 
     ret = 0;
  out:
-    ctxt->node = orignode;
     return ret;
 }
 
diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c
index 6f1257fd8e..09811cb51b 100644
--- a/src/conf/numa_conf.c
+++ b/src/conf/numa_conf.c
@@ -846,7 +846,7 @@ virDomainNumaDefCPUParseXML(virDomainNumaPtr def,
                             xmlXPathContextPtr ctxt)
 {
     xmlNodePtr *nodes = NULL;
-    xmlNodePtr oldNode = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     char *tmp = NULL;
     int n;
     size_t i, j;
@@ -963,7 +963,6 @@ virDomainNumaDefCPUParseXML(virDomainNumaPtr def,
     ret = 0;
 
  cleanup:
-    ctxt->node = oldNode;
     VIR_FREE(nodes);
     VIR_FREE(tmp);
     return ret;
diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
index 98c296b276..857d04c476 100644
--- a/src/conf/snapshot_conf.c
+++ b/src/conf/snapshot_conf.c
@@ -144,7 +144,7 @@ virDomainSnapshotDiskDefParseXML(xmlNodePtr node,
     char *type = NULL;
     char *driver = NULL;
     xmlNodePtr cur;
-    xmlNodePtr saved = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
 
     ctxt->node = node;
 
@@ -205,7 +205,6 @@ virDomainSnapshotDiskDefParseXML(xmlNodePtr node,
 
     ret = 0;
  cleanup:
-    ctxt->node = saved;
 
     VIR_FREE(driver);
     VIR_FREE(snapshot);
diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c
index 18bcb5eb9e..015e572630 100644
--- a/src/conf/storage_adapter_conf.c
+++ b/src/conf/storage_adapter_conf.c
@@ -178,7 +178,7 @@ virStorageAdapterParseXML(virStorageAdapterPtr adapter,
                           xmlXPathContextPtr ctxt)
 {
     int ret = -1;
-    xmlNodePtr relnode = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     char *adapter_type = NULL;
 
     ctxt->node = node;
@@ -208,7 +208,6 @@ virStorageAdapterParseXML(virStorageAdapterPtr adapter,
     ret = 0;
 
  cleanup:
-    ctxt->node = relnode;
     VIR_FREE(adapter_type);
     return ret;
 }
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 626ddd9528..5669b92f8d 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -727,7 +727,7 @@ virStorageDefParsePerms(xmlXPathContextPtr ctxt,
 {
     long long val;
     int ret = -1;
-    xmlNodePtr relnode;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     xmlNodePtr node;
     g_autofree char *mode = NULL;
 
@@ -741,7 +741,6 @@ virStorageDefParsePerms(xmlXPathContextPtr ctxt,
         return 0;
     }
 
-    relnode = ctxt->node;
     ctxt->node = node;
 
     if ((mode = virXPathString("string(./mode)", ctxt))) {
@@ -791,7 +790,6 @@ virStorageDefParsePerms(xmlXPathContextPtr ctxt,
 
     ret = 0;
  error:
-    ctxt->node = relnode;
     return ret;
 }
 
diff --git a/src/conf/virsavecookie.c b/src/conf/virsavecookie.c
index bdc22bb324..7fc951afe2 100644
--- a/src/conf/virsavecookie.c
+++ b/src/conf/virsavecookie.c
@@ -57,7 +57,7 @@ virSaveCookieParse(xmlXPathContextPtr ctxt,
                    virObjectPtr *obj,
                    virSaveCookieCallbacksPtr saveCookie)
 {
-    xmlNodePtr node = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     int ret = -1;
 
     *obj = NULL;
@@ -70,7 +70,6 @@ virSaveCookieParse(xmlXPathContextPtr ctxt,
     ret = virSaveCookieParseNode(ctxt, obj, saveCookie);
 
  cleanup:
-    ctxt->node = node;
     return ret;
 }
 
diff --git a/src/cpu/cpu_map.c b/src/cpu/cpu_map.c
index dffb6ea7e8..4465ebfa7b 100644
--- a/src/cpu/cpu_map.c
+++ b/src/cpu/cpu_map.c
@@ -40,14 +40,12 @@ loadData(const char *mapfile,
          void *data)
 {
     int ret = -1;
-    xmlNodePtr ctxt_node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     xmlNodePtr *nodes = NULL;
     int n;
     size_t i;
     int rv;
 
-    ctxt_node = ctxt->node;
-
     if ((n = virXPathNodeSet(element, ctxt, &nodes)) < 0)
         goto cleanup;
 
@@ -58,7 +56,6 @@ loadData(const char *mapfile,
     }
 
     for (i = 0; i < n; i++) {
-        xmlNodePtr old = ctxt->node;
         char *name = virXMLPropString(nodes[i], "name");
         if (!name) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -68,7 +65,6 @@ loadData(const char *mapfile,
         VIR_DEBUG("Load %s name %s", element, name);
         ctxt->node = nodes[i];
         rv = callback(ctxt, name, data);
-        ctxt->node = old;
         VIR_FREE(name);
         if (rv < 0)
             goto cleanup;
@@ -77,7 +73,6 @@ loadData(const char *mapfile,
     ret = 0;
 
  cleanup:
-    ctxt->node = ctxt_node;
     VIR_FREE(nodes);
 
     return ret;
@@ -135,13 +130,11 @@ loadIncludes(xmlXPathContextPtr ctxt,
              void *data)
 {
     int ret = -1;
-    xmlNodePtr ctxt_node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     xmlNodePtr *nodes = NULL;
     int n;
     size_t i;
 
-    ctxt_node = ctxt->node;
-
     n = virXPathNodeSet("include", ctxt, &nodes);
     if (n < 0)
         goto cleanup;
@@ -164,7 +157,6 @@ loadIncludes(xmlXPathContextPtr ctxt,
     ret = 0;
 
  cleanup:
-    ctxt->node = ctxt_node;
     VIR_FREE(nodes);
 
     return ret;
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index e3c553e943..bf26cf4e76 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -1486,7 +1486,7 @@ x86ModelParseSignatures(virCPUx86ModelPtr model,
                         xmlXPathContextPtr ctxt)
 {
     g_autofree xmlNodePtr *nodes = NULL;
-    xmlNodePtr root = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     size_t i;
     int n;
 
@@ -1527,7 +1527,6 @@ x86ModelParseSignatures(virCPUx86ModelPtr model,
             return -1;
     }
 
-    ctxt->node = root;
     return 0;
 }
 
diff --git a/src/lxc/lxc_domain.c b/src/lxc/lxc_domain.c
index 59f803837a..145997d8dc 100644
--- a/src/lxc/lxc_domain.c
+++ b/src/lxc/lxc_domain.c
@@ -211,7 +211,7 @@ lxcDomainDefNamespaceParse(xmlXPathContextPtr ctxt,
     lxcDomainDefPtr lxcDef = NULL;
     xmlNodePtr *nodes = NULL;
     bool uses_lxc_ns = false;
-    xmlNodePtr node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     int feature;
     int n;
     char *tmp = NULL;
@@ -220,7 +220,6 @@ lxcDomainDefNamespaceParse(xmlXPathContextPtr ctxt,
     if (VIR_ALLOC(lxcDef) < 0)
         return -1;
 
-    node = ctxt->node;
     if ((n = virXPathNodeSet("./lxc:namespace/*", ctxt, &nodes)) < 0)
         goto error;
     uses_lxc_ns |= n > 0;
@@ -259,7 +258,6 @@ lxcDomainDefNamespaceParse(xmlXPathContextPtr ctxt,
         }
     }
     VIR_FREE(nodes);
-    ctxt->node = node;
     if (uses_lxc_ns)
         *data = lxcDef;
     else
diff --git a/src/util/virstorageencryption.c b/src/util/virstorageencryption.c
index 6765fdc23a..34c356b5a3 100644
--- a/src/util/virstorageencryption.c
+++ b/src/util/virstorageencryption.c
@@ -143,7 +143,7 @@ static virStorageEncryptionSecretPtr
 virStorageEncryptionSecretParse(xmlXPathContextPtr ctxt,
                                 xmlNodePtr node)
 {
-    xmlNodePtr old_node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     virStorageEncryptionSecretPtr ret;
     char *type_str = NULL;
     char *uuidstr = NULL;
@@ -152,7 +152,6 @@ virStorageEncryptionSecretParse(xmlXPathContextPtr ctxt,
     if (VIR_ALLOC(ret) < 0)
         return NULL;
 
-    old_node = ctxt->node;
     ctxt->node = node;
 
     if (!(type_str = virXPathString("string(./@type)", ctxt))) {
@@ -173,7 +172,6 @@ virStorageEncryptionSecretParse(xmlXPathContextPtr ctxt,
 
     VIR_FREE(type_str);
 
-    ctxt->node = old_node;
     return ret;
 
  cleanup:
@@ -181,7 +179,6 @@ virStorageEncryptionSecretParse(xmlXPathContextPtr ctxt,
     virStorageEncryptionSecretFree(ret);
     VIR_FREE(uuidstr);
     VIR_FREE(usagestr);
-    ctxt->node = old_node;
     return NULL;
 }
 
@@ -244,7 +241,7 @@ virStorageEncryptionPtr
 virStorageEncryptionParseNode(xmlNodePtr node,
                               xmlXPathContextPtr ctxt)
 {
-    xmlNodePtr saveNode = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     xmlNodePtr *nodes = NULL;
     virStorageEncryptionPtr encdef = NULL;
     virStorageEncryptionPtr ret = NULL;
@@ -313,7 +310,6 @@ virStorageEncryptionParseNode(xmlNodePtr node,
     VIR_FREE(format_str);
     VIR_FREE(nodes);
     virStorageEncryptionFree(encdef);
-    ctxt->node = saveNode;
 
     return ret;
 }
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 535a94e239..a6357abb08 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -1781,7 +1781,7 @@ virStorageAuthDefPtr
 virStorageAuthDefParse(xmlNodePtr node,
                        xmlXPathContextPtr ctxt)
 {
-    xmlNodePtr saveNode = ctxt->node;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     virStorageAuthDefPtr ret = NULL;
     xmlNodePtr secretnode = NULL;
     g_autoptr(virStorageAuthDef) authdef = NULL;
@@ -1832,7 +1832,6 @@ virStorageAuthDefParse(xmlNodePtr node,
     ret = g_steal_pointer(&authdef);
 
  cleanup:
-    ctxt->node = saveNode;
 
     return ret;
 }
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 61cd72f714..069e3de064 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -6818,7 +6818,7 @@ virshDomainGetVcpuBitmap(vshControl *ctl,
     xmlDocPtr xml = NULL;
     xmlXPathContextPtr ctxt = NULL;
     xmlNodePtr *nodes = NULL;
-    xmlNodePtr old;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
     int nnodes;
     size_t i;
     unsigned int curvcpus = 0;
@@ -6853,8 +6853,6 @@ virshDomainGetVcpuBitmap(vshControl *ctl,
         goto cleanup;
     }
 
-    old = ctxt->node;
-
     for (i = 0; i < nnodes; i++) {
         ctxt->node = nodes[i];
 
@@ -6868,8 +6866,6 @@ virshDomainGetVcpuBitmap(vshControl *ctl,
         VIR_FREE(online);
     }
 
-    ctxt->node = old;
-
     if (virBitmapCountBits(ret) != curvcpus) {
         vshError(ctl, "%s", _("Failed to retrieve vcpu state bitmap"));
         virBitmapFree(ret);
-- 
2.26.2

Re: [PATCH 2/2] Use more of VIR_XPATH_NODE_AUTORESTORE
Posted by Ján Tomko 4 years, 5 months ago
On a Wednesday in 2020, Michal Privoznik wrote:
>This is convenience macro, use it more. This commit was generated
>using the following spatch:
>
>  @@
>  symbol node;
>  identifier old;
>  identifier ctxt;
>  type xmlNodePtr;
>  @@
>  - xmlNodePtr old;
>  + VIR_XPATH_NODE_AUTORESTORE(ctxt);
>    ...
>  - old = ctxt->node;
>    ... when != old
>  - ctxt->node = old;
>
>  @@
>  symbol node;
>  identifier old;
>  identifier ctxt;
>  type xmlNodePtr;
>  @@
>  - xmlNodePtr old = ctxt->node;
>  + VIR_XPATH_NODE_AUTORESTORE(ctxt);
>    ... when != old
>  - ctxt->node = old;
>
>Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
>---
> src/conf/cpu_conf.c             |  3 +-
> src/conf/domain_conf.c          |  7 +--
> src/conf/interface_conf.c       | 16 ++-----
> src/conf/netdev_vlan_conf.c     |  3 +-
> src/conf/network_conf.c         | 25 +++-------
> src/conf/networkcommon_conf.c   |  4 +-
> src/conf/node_device_conf.c     | 84 +++++++++------------------------
> src/conf/numa_conf.c            |  3 +-
> src/conf/snapshot_conf.c        |  3 +-
> src/conf/storage_adapter_conf.c |  3 +-
> src/conf/storage_conf.c         |  4 +-
> src/conf/virsavecookie.c        |  3 +-
> src/cpu/cpu_map.c               | 12 +----
> src/cpu/cpu_x86.c               |  3 +-
> src/lxc/lxc_domain.c            |  4 +-
> src/util/virstorageencryption.c |  8 +---
> src/util/virstoragefile.c       |  3 +-
> tools/virsh-domain.c            |  6 +--
> 18 files changed, 52 insertions(+), 142 deletions(-)
>

>@@ -797,12 +793,12 @@ virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt,
>                              xmlNodePtr node,
>                              virNodeDevCapStoragePtr storage)
> {
>-    xmlNodePtr orignode, *nodes = NULL;
>+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
>+    xmlNodePtr *nodes = NULL;
>     size_t i;
>     int n, ret = -1;
>     unsigned long long val;
>
>-    orignode = ctxt->node;
>     ctxt->node = node;
>
>     storage->block = virXPathString("string(./block[1])", ctxt);
>@@ -835,11 +831,8 @@ virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt,
>         if (STREQ(type, "hotpluggable")) {
>             storage->flags |= VIR_NODE_DEV_CAP_STORAGE_HOTPLUGGABLE;
>         } else if (STREQ(type, "removable")) {
>-            xmlNodePtr orignode2;
>-
>             storage->flags |= VIR_NODE_DEV_CAP_STORAGE_REMOVABLE;
>
>-            orignode2 = ctxt->node;

This set orignode2 to 'node'

>             ctxt->node = nodes[i];
>
>             if (virXPathBoolean("count(./media_available[. = '1']) > 0", ctxt))
>@@ -851,13 +844,10 @@ virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt,
>             if (virNodeDevCapsDefParseULongLong("number(./media_size[1])", ctxt, &val, def,
>                                                 _("no removable media size supplied for '%s'"),
>                                                 _("invalid removable media size supplied for '%s'")) < 0) {
>-                ctxt->node = orignode2;
>                 VIR_FREE(type);
>                 goto out;
>             }
>             storage->removable_media_size = val;
>-
>-            ctxt->node = orignode2;

This restored it back to 'node'.
The new code can possibly leave it at node[i],
but the code below using the context is specifically run only for
non-removable devices.

My sympathy to anyone touching this code in the future :)

>         } else {
>             virReportError(VIR_ERR_INTERNAL_ERROR,
>                            _("unknown storage capability type '%s' for '%s'"),
>@@ -881,7 +871,6 @@ virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt,
>     ret = 0;
>  out:
>     VIR_FREE(nodes);
>-    ctxt->node = orignode;
>     return ret;
> }
>

[...]

>diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
>index 61cd72f714..069e3de064 100644
>--- a/tools/virsh-domain.c
>+++ b/tools/virsh-domain.c
>@@ -6818,7 +6818,7 @@ virshDomainGetVcpuBitmap(vshControl *ctl,
>     xmlDocPtr xml = NULL;
>     xmlXPathContextPtr ctxt = NULL;
>     xmlNodePtr *nodes = NULL;
>-    xmlNodePtr old;
>+    VIR_XPATH_NODE_AUTORESTORE(ctxt);

==1644488== Invalid read of size 8
==1644488==    at 0x169BE9: virshDomainGetVcpuBitmap (virsh-domain.c:6821)
==1644488==    by 0x16965A: virshVcpuinfoInactive (virsh-domain.c:6898)
==1644488==    by 0x160132: cmdVcpuinfo (virsh-domain.c:6970)
==1644488==    by 0x19890E: vshCommandRun (vsh.c:1291)
==1644488==    by 0x1362F9: main (virsh.c:905)
==1644488==  Address 0x8 is not stack'd, malloc'd or (recently) free'd

Since 'ctxt' is freed at the end of the function, there is not much
point in restoring it.

>     int nnodes;
>     size_t i;
>     unsigned int curvcpus = 0;
>@@ -6853,8 +6853,6 @@ virshDomainGetVcpuBitmap(vshControl *ctl,
>         goto cleanup;
>     }
>
>-    old = ctxt->node;
>-
>     for (i = 0; i < nnodes; i++) {
>         ctxt->node = nodes[i];
>
>@@ -6868,8 +6866,6 @@ virshDomainGetVcpuBitmap(vshControl *ctl,
>         VIR_FREE(online);
>     }
>
>-    ctxt->node = old;
>-
>     if (virBitmapCountBits(ret) != curvcpus) {
>         vshError(ctl, "%s", _("Failed to retrieve vcpu state bitmap"));
>         virBitmapFree(ret);

With the crash fixed:

Reviewed-by: Ján Tomko <jtomko@redhat.com>

Jano