]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Do lazy init of host PM features
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 29 Nov 2011 15:20:03 +0000 (15:20 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Wed, 30 Nov 2011 10:12:30 +0000 (10:12 +0000)
To avoid probing the host power management features on any
call to virInitialize, only initialize the mutex in
virNodeSuspendInit. Do lazy load of the supported PM target
mask when it is actually needed

* src/util/virnodesuspend.c: Lazy init of supported features

src/util/virnodesuspend.c

index 29b7f871c0810a9feab169a76462d5de22915aff..39ce56dd42cb14d1e2184641a46f6ebcef7fde95 100644 (file)
  * Bitmask to hold the Power Management features supported by the host,
  * such as Suspend-to-RAM, Suspend-to-Disk, Hybrid-Suspend etc.
  */
-static unsigned int hostPMFeatures;
+static unsigned int nodeSuspendTargetMask;
+static bool nodeSuspendTargetMaskInit;
 
-virMutex virNodeSuspendMutex;
+static virMutex virNodeSuspendMutex;
 
 static bool aboutToSuspend;
 
@@ -75,17 +76,9 @@ static void virNodeSuspendUnlock(void)
  */
 int virNodeSuspendInit(void)
 {
-
     if (virMutexInit(&virNodeSuspendMutex) < 0)
         return -1;
 
-    /* Get the power management capabilities supported by the host */
-    hostPMFeatures = 0;
-    if (virNodeSuspendGetTargetMask(&hostPMFeatures) < 0) {
-        if (geteuid() == 0)
-            VIR_ERROR(_("Failed to get host power management features"));
-    }
-
     return 0;
 }
 
@@ -191,9 +184,14 @@ int nodeSuspendForDuration(virConnectPtr conn ATTRIBUTE_UNUSED,
 {
     static virThread thread;
     char *cmdString = NULL;
+    int ret = -1;
+    unsigned int supported;
 
     virCheckFlags(0, -1);
 
+    if (virNodeSuspendGetTargetMask(&supported) < 0)
+        return -1;
+
     /*
      * Ensure that we are the only ones trying to suspend.
      * Fail if somebody has already initiated a suspend.
@@ -202,18 +200,16 @@ int nodeSuspendForDuration(virConnectPtr conn ATTRIBUTE_UNUSED,
 
     if (aboutToSuspend) {
         /* A suspend operation is already in progress */
-        virNodeSuspendUnlock();
-        return -1;
-    } else {
-        aboutToSuspend = true;
+        virNodeSuspendError(VIR_ERR_OPERATION_INVALID, "%s",
+                            _("Suspend operation already in progress"));
+        goto cleanup;
     }
-
-    virNodeSuspendUnlock();
+    aboutToSuspend = true;
 
     /* Check if the host supports the requested suspend target */
     switch (target) {
     case VIR_NODE_SUSPEND_TARGET_MEM:
-        if (hostPMFeatures & (1 << VIR_NODE_SUSPEND_TARGET_MEM)) {
+        if (supported & (1 << VIR_NODE_SUSPEND_TARGET_MEM)) {
             cmdString = strdup("pm-suspend");
             if (cmdString == NULL) {
                 virReportOOMError();
@@ -225,7 +221,7 @@ int nodeSuspendForDuration(virConnectPtr conn ATTRIBUTE_UNUSED,
         goto cleanup;
 
     case VIR_NODE_SUSPEND_TARGET_DISK:
-        if (hostPMFeatures & (1 << VIR_NODE_SUSPEND_TARGET_DISK)) {
+        if (supported & (1 << VIR_NODE_SUSPEND_TARGET_DISK)) {
             cmdString = strdup("pm-hibernate");
             if (cmdString == NULL) {
                 virReportOOMError();
@@ -237,7 +233,7 @@ int nodeSuspendForDuration(virConnectPtr conn ATTRIBUTE_UNUSED,
         goto cleanup;
 
     case VIR_NODE_SUSPEND_TARGET_HYBRID:
-        if (hostPMFeatures & (1 << VIR_NODE_SUSPEND_TARGET_HYBRID)) {
+        if (supported & (1 << VIR_NODE_SUSPEND_TARGET_HYBRID)) {
             cmdString = strdup("pm-suspend-hybrid");
             if (cmdString == NULL) {
                 virReportOOMError();
@@ -263,11 +259,11 @@ int nodeSuspendForDuration(virConnectPtr conn ATTRIBUTE_UNUSED,
         goto cleanup;
     }
 
-    return 0;
-
+    ret = 0;
 cleanup:
+    virNodeSuspendUnlock();
     VIR_FREE(cmdString);
-    return -1;
+    return ret;
 }
 
 
@@ -338,35 +334,40 @@ cleanup:
 int
 virNodeSuspendGetTargetMask(unsigned int *bitmask)
 {
-    int ret;
-    bool supported;
+    int ret = -1;
 
     *bitmask = 0;
 
-    /* Check support for Suspend-to-RAM (S3) */
-    ret = virNodeSuspendSupportsTarget(VIR_NODE_SUSPEND_TARGET_MEM, &supported);
-    if (ret < 0)
-        goto error;
-    if (supported)
-        *bitmask |= (1 << VIR_NODE_SUSPEND_TARGET_MEM);
-
-    /* Check support for Suspend-to-Disk (S4) */
-    ret = virNodeSuspendSupportsTarget(VIR_NODE_SUSPEND_TARGET_DISK, &supported);
-    if (ret < 0)
-        goto error;
-    if (supported)
-        *bitmask |= (1 << VIR_NODE_SUSPEND_TARGET_DISK);
-
-    /* Check support for Hybrid-Suspend */
-    ret = virNodeSuspendSupportsTarget(VIR_NODE_SUSPEND_TARGET_HYBRID, &supported);
-    if (ret < 0)
-        goto error;
-    if (supported)
-        *bitmask |= (1 << VIR_NODE_SUSPEND_TARGET_HYBRID);
-
-    return 0;
+    virNodeSuspendLock();
+    /* Get the power management capabilities supported by the host */
+    if (!nodeSuspendTargetMaskInit) {
+        bool supported;
+        nodeSuspendTargetMask = 0;
+
+        /* Check support for Suspend-to-RAM (S3) */
+        if (virNodeSuspendSupportsTarget(VIR_NODE_SUSPEND_TARGET_MEM, &supported) < 0)
+            goto cleanup;
+        if (supported)
+            nodeSuspendTargetMask |= (1 << VIR_NODE_SUSPEND_TARGET_MEM);
+
+        /* Check support for Suspend-to-Disk (S4) */
+        if (virNodeSuspendSupportsTarget(VIR_NODE_SUSPEND_TARGET_DISK, &supported) < 0)
+            goto cleanup;
+        if (supported)
+            nodeSuspendTargetMask |= (1 << VIR_NODE_SUSPEND_TARGET_DISK);
+
+        /* Check support for Hybrid-Suspend */
+        if (virNodeSuspendSupportsTarget(VIR_NODE_SUSPEND_TARGET_HYBRID, &supported) < 0)
+            goto cleanup;
+        if (supported)
+            nodeSuspendTargetMask |= (1 << VIR_NODE_SUSPEND_TARGET_HYBRID);
+
+        nodeSuspendTargetMaskInit = true;
+    }
 
-error:
-    *bitmask = 0;
-    return -1;
+    *bitmask = nodeSuspendTargetMask;
+    ret = 0;
+cleanup:
+    virNodeSuspendUnlock();
+    return ret;
 }