File suspend_evtchn_lock.patch of Package xen.481

Fix problems that suspend eventchannel lock file might be obselete for some reason
like segment fault or other abnormal exit, and once obselete lock file exists,
it might affact latter save process.
Have discussed with upstream, for some reason not accepted. 
http://xen.1045712.n5.nabble.com/Re-PATCH-improve-suspend-evtchn-lock-processing-td3395229.html

Signed-off-by: Chunyan Liu <cyliu@suse.com>

Index: xen-4.2.0-testing/tools/libxc/xc_suspend.c
===================================================================
--- xen-4.2.0-testing.orig/tools/libxc/xc_suspend.c
+++ xen-4.2.0-testing/tools/libxc/xc_suspend.c
@@ -16,8 +16,43 @@
 
 #include "xc_private.h"
 #include "xenguest.h"
+#include <signal.h>
+#ifdef __MINIOS__
+extern int kill (__pid_t __pid, int __sig);
+#endif
 
 #define SUSPEND_LOCK_FILE "/var/lib/xen/suspend_evtchn"
+/* cleanup obsolete suspend lock file which is unlinked for any reason,
+so that current process can get lock */
+static void clean_obsolete_lock(int domid)
+{
+    int fd, pid, n;
+    char buf[128];
+    char suspend_file[256];
+
+    snprintf(suspend_file, sizeof(suspend_file), "%s_%d_lock.d",
+        SUSPEND_LOCK_FILE, domid);
+    fd = open(suspend_file, O_RDWR);
+
+    if (fd < 0)
+        return;
+
+    n = read(fd, buf, 127);
+
+    close(fd);
+
+    if (n > 0)
+    {
+        sscanf(buf, "%d", &pid);
+        /* pid does not exist, this lock file is obsolete, just delete it */
+        if ( kill(pid,0) )
+        {
+            unlink(suspend_file);
+            return;
+        }
+    }
+}
+
 static int lock_suspend_event(xc_interface *xch, int domid)
 {
     int fd, rc;
@@ -27,6 +62,7 @@ static int lock_suspend_event(xc_interfa
 
     snprintf(suspend_file, sizeof(suspend_file), "%s_%d_lock.d",
 	    SUSPEND_LOCK_FILE, domid);
+    clean_obsolete_lock(domid);
     mask = umask(022);
     fd = open(suspend_file, O_CREAT | O_EXCL | O_RDWR, 0666);
     if (fd < 0)
@@ -41,6 +77,9 @@ static int lock_suspend_event(xc_interfa
     rc = write_exact(fd, buf, strlen(buf));
     close(fd);
 
+    if(rc)
+    unlink(suspend_file);
+
     return rc;
 }
 
@@ -127,8 +166,7 @@ int xc_suspend_evtchn_init(xc_interface
     return suspend_evtchn;
 
 cleanup:
-    if (suspend_evtchn != -1)
-        xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn);
+    xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn);
 
     return -1;
 }
openSUSE Build Service is sponsored by