All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jim Fehlig <jfehlig@novell.com>
To: xen-devel@lists.xensource.com
Subject: [PATCH] [RFC] Add lock on domain start
Date: Wed, 06 Aug 2008 00:06:00 -0600	[thread overview]
Message-ID: <48993F48.9030705@novell.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1160 bytes --]

This patch adds a simple lock mechanism when starting domains by placing 
a lock file in xend-domains-path/<dom_uuid>.  The lock file is removed 
when domain is stopped.  The motivation for such a mechanism is to 
prevent starting the same domain from multiple hosts.

If xend-domains-path is set to shared mount point, a domain will fail to 
start on host B if it is already running on host A.  I've added an 
option to XendOptions to control the behavior with default of no lock.

The patch certainly needs some testing (and probably adjustment) to 
ensure the lock is handled properly on save, restore, migrate, domain 
crash, etc. but wanted to get folks' thought on this approach before 
continuing this endeavor.  Some simple improvements could include adding 
info (domain name/id, start time, vmm hostname) to the lock file, 
allowing such messages as "domain foo seems to be already running on 
host bar" and  a --force option to create/start to override the lock.  A 
per-domain config option could also be added to allow more fine-grained 
control.

Comments, suggestions, alternative approaches, ... are welcome and 
appreciated :-).

Regards,
Jim

[-- Attachment #2: xend-domain-lock.patch --]
[-- Type: text/x-patch, Size: 5055 bytes --]

diff -r f20fb83dac2c tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp	Tue Aug 05 13:55:14 2008 +0100
+++ b/tools/examples/xend-config.sxp	Tue Aug 05 23:28:55 2008 -0600
@@ -245,3 +245,9 @@
 
 # Rotation count of qemu-dm log file.
 #(qemu-dm-logrotate-count 10)
+
+# Create a lock file when domains are started.  Lock file is
+# placed in xend-domains-path on domain startup and removed
+# when domain is stopped.  By default, a lock file is not
+# created.  Set to yes to enable lock file creation.
+#(xend-domain-lock no)
diff -r f20fb83dac2c tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py	Tue Aug 05 13:55:14 2008 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py	Tue Aug 05 23:28:55 2008 -0600
@@ -34,7 +34,7 @@ from types import StringTypes
 from types import StringTypes
 
 import xen.lowlevel.xc
-from xen.util import asserts
+from xen.util import asserts, mkdir
 from xen.util.blkif import blkdev_uname_to_file, blkdev_uname_to_taptype
 import xen.util.xsm.xsm as security
 from xen.util import xsconstants
@@ -420,7 +420,10 @@ class XendDomainInfo:
         from xen.xend import XendDomain
 
         if self._stateGet() in (XEN_API_VM_POWER_STATE_HALTED, XEN_API_VM_POWER_STATE_SUSPENDED, XEN_API_VM_POWER_STATE_CRASHED):
-            try:
+            if self._is_locked():
+                raise XendError('VM is locked.  Is it running on another node?')
+
+             try:
                 XendTask.log_progress(0, 30, self._constructDomain)
                 XendTask.log_progress(31, 60, self._initDomain)
                 
@@ -441,6 +444,9 @@ class XendDomainInfo:
                     xendomains.domain_sched_credit_set(self.getDomid(),
                                                        self.getWeight(),
                                                        self.getCap())
+
+                self._create_lock()
+
             except:
                 log.exception('VM start failed')
                 self.destroy()
@@ -1104,6 +1110,53 @@ class XendDomainInfo:
     # internal functions ... TODO: re-categorised
     # 
 
+    def _is_locked(self):
+        if not xoptions.get_xend_domain_lock():
+            return False
+
+        from xen.xend import XendDomain
+        path = XendDomain.instance()._managed_path(self.get_uuid())
+        try:
+            if not os.path.exists(path):
+                return False
+            path += "/lock"
+            return os.access(path, os.F_OK)
+
+        except:
+            log.exception("%s could not be accessed")
+            return False
+
+    def _create_lock(self):
+        if not xoptions.get_xend_domain_lock():
+            return
+
+        from xen.xend import XendDomain
+        path = XendDomain.instance()._managed_path(self.get_uuid())
+        try:
+            if not os.path.exists(path):
+                mkdir.parents(path, stat.S_IRWXU)
+            path += "/lock"
+            oflags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
+            fd = os.open(path, oflags)
+            os.close(fd)
+
+        except:
+            log.exception("%s could not be created." % path)
+
+    def _remove_lock(self):
+        if not xoptions.get_xend_domain_lock():
+            return
+
+        from xen.xend import XendDomain
+        path = XendDomain.instance()._managed_path(self.get_uuid())
+        lock = path + "/lock"
+        try:
+            os.unlink(lock)
+            if not XendDomain.instance().is_domain_managed(self):
+                shutil.rmtree(path)
+        except:
+            log.exception("%s could not be created." % path)
+
     def _augmentInfo(self, priv):
         """Augment self.info, as given to us through L{recreate}, with
         values taken from the store.  This recovers those values known
@@ -2388,6 +2441,8 @@ class XendDomainInfo:
 
         log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
 
+        self._remove_lock()
+
         paths = self._prepare_phantom_paths()
 
         self._cleanupVm()
diff -r f20fb83dac2c tools/python/xen/xend/XendOptions.py
--- a/tools/python/xen/xend/XendOptions.py	Tue Aug 05 13:55:14 2008 +0100
+++ b/tools/python/xen/xend/XendOptions.py	Tue Aug 05 23:28:55 2008 -0600
@@ -135,6 +135,11 @@ class XendOptions:
     """Default rotation count of qemu-dm log file."""
     qemu_dm_logrotate_count = 10
 
+    """Default for the flag indicating whether xend should create
+    a lock file for domains when they are started."""
+    xend_domain_lock = 'no'
+
+
     def __init__(self):
         self.configure()
 
@@ -357,6 +362,11 @@ class XendOptions:
     def get_qemu_dm_logrotate_count(self):
         return self.get_config_int("qemu-dm-logrotate-count",
                                    self.qemu_dm_logrotate_count)
+
+    def get_xend_domain_lock(self):
+        """Get the flag indicating whether xend should create a lock file
+        for domains when they are started."""
+        return self.get_config_bool("xend-domain-lock", self.xend_domain_lock)
 
 
 class XendOptionsFile(XendOptions):

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

             reply	other threads:[~2008-08-06  6:06 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-06  6:06 Jim Fehlig [this message]
2008-08-07  2:23 ` [PATCH] [RFC] Add lock on domain start Zhigang Wang
2008-08-07  4:26   ` Zhigang Wang
2008-08-08 17:07     ` Jim Fehlig
2008-08-11  2:22       ` Zhigang Wang
2008-08-11 11:14 ` Ian Jackson
2008-08-11 16:45   ` Jim Fehlig
2009-08-05  7:41     ` Pasi Kärkkäinen
2009-08-05  8:39       ` Zhigang Wang
2009-08-05  9:33         ` Pasi Kärkkäinen
2009-08-05 16:30           ` Jia Ju Zhang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48993F48.9030705@novell.com \
    --to=jfehlig@novell.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.