Subversion Repositories xen

Rev

Rev 2 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 madcat 1
--- /root/xen_lock_patch/XendDomainInfo.py      2011-03-14 11:03:21.000000000 +0100
2
+++ /usr/lib/xen-4.0/lib/python/xen/xend/XendDomainInfo.py      2011-03-14 15:50:52.000000000 +0100
3
@@ -361,6 +361,8 @@
4
     @type state_updated: threading.Condition
5
     @ivar refresh_shutdown_lock: lock for polling shutdown state
6
     @type refresh_shutdown_lock: threading.Condition
7
+    @ivar running_lock: lock for running VM
8
+    @type running_lock: bool or None
9
     @ivar _deviceControllers: device controller cache for this domain
10
     @type _deviceControllers: dict 'string' to DevControllers
11
     """
12
@@ -439,6 +441,8 @@
13
         self.refresh_shutdown_lock = threading.Condition()
14
         self._stateSet(DOM_STATE_HALTED)
15
 
16
+        self.running_lock = None
17
+
18
         self._deviceControllers = {}
19
 
20
         for state in DOM_STATES_OLD:
21
@@ -465,6 +469,7 @@
22
 
23
         if self._stateGet() in (XEN_API_VM_POWER_STATE_HALTED, XEN_API_VM_POWER_STATE_SUSPENDED, XEN_API_VM_POWER_STATE_CRASHED):
24
             try:
25
+                self.acquire_running_lock();
26
                 XendTask.log_progress(0, 30, self._constructDomain)
27
                 XendTask.log_progress(31, 60, self._initDomain)
28
 
29
@@ -491,6 +496,7 @@
30
         state = self._stateGet()
31
         if state in (DOM_STATE_SUSPENDED, DOM_STATE_HALTED):
32
             try:
33
+                self.acquire_running_lock();
34
                 self._constructDomain()
35
 
36
                 try:
37
@@ -2932,6 +2938,11 @@
38
 
39
             self._stateSet(DOM_STATE_HALTED)
40
             self.domid = None  # Do not push into _stateSet()!
41
+
42
+            try:
43
+                self.release_running_lock()
44
+            except:
45
+                log.exception("Release running lock failed: %s" % status)
46
         finally:
47
             self.refresh_shutdown_lock.release()
48
 
49
@@ -4413,6 +4424,32 @@
50
     def has_device(self, dev_class, dev_uuid):
51
         return (dev_uuid in self.info['%s_refs' % dev_class.lower()])
52
 
53
+    def acquire_running_lock(self):    
54
+        if not self.running_lock:
55
+            lock_path = xoptions.get_xend_domains_lock_path()
56
+           if lock_path:
57
+               doms_lock_path = xoptions.get_xend_domains_path()
58
+               if doms_lock_path:
59
+                       status = os.system('%s --lock --name %s --uuid %s --path %s' % \
60
+                                          (lock_path, self.info['name_label'], self.info['uuid'], doms_lock_path))
61
+                       if status == 0:
62
+                           self.running_lock = True
63
+                       else:
64
+                           raise XendError('Acquire running lock failed: %s' % status)
65
+
66
+    def release_running_lock(self):
67
+        if self.running_lock:
68
+            lock_path = xoptions.get_xend_domains_lock_path()
69
+            if lock_path:
70
+               doms_lock_path = xoptions.get_xend_domains_path()
71
+               if doms_lock_path:
72
+                       status = os.system('%s --unlock --name %s --uuid %s --path %s' % \
73
+                                          (lock_path, self.info['name_label'], self.info['uuid'], doms_lock_path))
74
+                       if status == 0:
75
+                           self.running_lock = False
76
+                       else:
77
+                           raise XendError('Release running lock failed: %s' % status)
78
+
79
     def __str__(self):
80
         return '<domain id=%s name=%s memory=%s state=%s>' % \
81
                (str(self.domid), self.info['name_label'],
82
--- /root/xen_lock_patch/XendDomain.py  2011-03-14 11:04:13.000000000 +0100
83
+++ /usr/lib/xen-4.0/lib/python/xen/xend/XendDomain.py  2011-03-14 11:26:44.000000000 +0100
84
@@ -1349,6 +1349,7 @@
85
             raise XendError("Domain is not a managed domain")
86
 
87
         """ The following call may raise a XendError exception """
88
+        dominfo.release_running_lock();
89
         dominfo.testMigrateDevices(True, dst)
90
 
91
         if live:
92
--- /root/xen_lock_patch/XendOptions.py 2011-03-14 11:02:52.000000000 +0100
93
+++ /usr/lib/xen-4.0/lib/python/xen/xend/XendOptions.py 2011-03-14 11:27:33.000000000 +0100
94
@@ -318,6 +318,11 @@
95
         """
96
         return self.get_config_string("xend-domains-path", self.xend_domains_path_default)
97
 
98
+    def get_xend_domains_lock_path(self):
99
+        """ Get the path of the lock utility for running domains.
100
+        """
101
+        return self.get_config_string("xend-domains-lock-path")
102
+
103
     def get_xend_state_path(self):
104
         """ Get the path for persistent domain configuration storage
105
         """
106
--- /root/xen_lock_patch/file-lock.c    2011-03-14 15:48:03.000000000 +0100
107
+++ /etc/xen/scripts/file-lock.c        1970-01-01 01:00:00.000000000 +0100
108
@@ -0,0 +1,190 @@
109
+/*
110
+ * file-lock.c
111
+ *
112
+ * Copyright (C) 2008 Oracle Inc.
113
+ * Copyright (C) 2008 Zhigang Wang <zhigang.x.wang@xxxxxxxxxx>
114
+ *
115
+ * This program is free software: you can redistribute it and/or modify it
116
+ * under the terms of the GNU General Public License as published by the Free
117
+ * Software Foundation, either version 3 of the License, or (at your option)
118
+ * any later version.
119
+ *
120
+ * This program is distributed in the hope that it will be useful, but WITHOUT
121
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
122
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
123
+ * more details.
124
+ *
125
+ * You should have received a copy of the GNU General Public License along with
126
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
127
+ */
128
+
129
+#include <stdio.h>
130
+#include <stdlib.h>
131
+#include <string.h>
132
+#include <unistd.h>
133
+#include <sys/types.h>
134
+#include <sys/stat.h>
135
+#include <fcntl.h>
136
+#include <errno.h>
137
+#include <getopt.h>
138
+
139
+const char version[] = "0.0.1";
140
+static char short_opts[] = "lup:d:n:hvV";
141
+static struct option long_opts[] = {
142
+        { "lock",       no_argument,            NULL,   'l' },
143
+        { "unlock",     no_argument,            NULL,   'u' },
144
+        { "path",       required_argument,      NULL,   'p' },
145
+        { "name",       required_argument,      NULL,   'n' },
146
+        { "uuid",       required_argument,      NULL,   'd' },
147
+        { "help",       no_argument,            NULL,   'h' },
148
+        { "verbose",    no_argument,            NULL,   'v' },
149
+        { "version",    no_argument,            NULL,   'V' },
150
+        {  NULL,        0,                      NULL,    0  }
151
+};
152
+
153
+static void usage(char *prog, FILE *fp, int n) {
154
+        fprintf(fp, "usage: %s [options]\n", prog);
155
+        fprintf(fp, "\n");
156
+        fprintf(fp, "options:\n");
157
+        fprintf(fp, " -l, --lock       Acquire the lock.\n");
158
+        fprintf(fp, " -u, --unlock     Release the lock.\n");
159
+        fprintf(fp, " -p, --path       Set the path for the locks.\n");
160
+        fprintf(fp, " -n, --name       Set the name of the VM.\n");
161
+        fprintf(fp, " -d, --uuid       Set the uuid of the VM.\n");
162
+        fprintf(fp, " -v, --verbose    Show more infomation.\n");
163
+        fprintf(fp, " -V, --version    Show version number and exit.\n");
164
+        fprintf(fp, " -h, --help       Show this help information.\n");
165
+        fprintf(fp, "\n");
166
+        exit(n);
167
+}
168
+
169
+static int do_lock(char *path, char *name, char *uuid)
170
+{
171
+        char *fn;
172
+        int fd;
173
+
174
+        if (asprintf(&fn, "%s/%s-%s.lock", path, name, uuid) == -1)
175
+                return -1;
176
+
177
+        fd = open(fn, O_CREAT|O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
178
+        if (fd == -1) {
179
+                free(fn);
180
+                return errno;
181
+        }
182
+
183
+        free(fn);
184
+        close(fd);
185
+        return 0;
186
+}
187
+
188
+static int do_unlock(char *path, char *name, char *uuid)
189
+{
190
+        char *fn;
191
+
192
+        if (asprintf(&fn, "%s/%s-%s.lock", path, name, uuid) == -1)
193
+                return -1;
194
+
195
+        if (unlink(fn) == -1) {
196
+                free(fn);
197
+                return errno;
198
+        }
199
+
200
+        free(fn);
201
+        return 0;
202
+}
203
+
204
+int main(int argc, char *argv[])
205
+{
206
+        char *prog, *p;
207
+        char *name = NULL;
208
+        char *uuid = NULL;
209
+        char *path = ".";       /* create lock file on current working 
210
+directory by default*/
211
+        int verbose = 0;        /* turn off verbose output by default */
212
+        int status = 0;         /* returned value */
213
+        int lock = 0, unlock = 0;
214
+        int c;
215
+
216
+        prog = argv[0];
217
+        p = strrchr(prog, '/');
218
+        if (p)
219
+                prog = p+1;
220
+
221
+        while ((c = getopt_long(argc, argv, short_opts,
222
+                                 long_opts, NULL)) != -1) {
223
+                switch (c) {
224
+                case 'l':               /* acquire the lock */
225
+                        lock = 1;
226
+                        break;
227
+                case 'u':               /* release the lock */
228
+                        unlock = 1;
229
+                        break;
230
+                case 'p':               /* path for lock file */
231
+                        path = optarg;
232
+                        break;
233
+                case 'n':               /* name of vm  */
234
+                        name = optarg;
235
+                        break;
236
+                case 'd':               /* uuid of vm  */
237
+                        uuid = optarg;
238
+                        break;
239
+                case 'h':               /* help */
240
+                        usage(prog, stdout, 0);
241
+                        break;
242
+                case 'v':               /* be chatty */
243
+                        ++verbose;
244
+                        break;
245
+                case 'V':               /* version */
246
+                        fprintf(stdout, "%s: %s\n", prog, version);
247
+                        exit(0);
248
+                case 0:
249
+                        break;
250
+                case '?':
251
+                default:
252
+                        usage(prog, stderr, 1);
253
+                }
254
+        }
255
+
256
+        if (optind < argc)
257
+                usage(prog, stderr, 1);
258
+
259
+        if (name==NULL || uuid==NULL) {
260
+                fprintf(stderr, "you should specify the name and uuid of vm.\n\n");
261
+                usage(prog, stderr, 1);
262
+        }
263
+
264
+        if (lock && unlock) {
265
+                fprintf(stderr, "cannot execute lock and unlock at the same time.\n\n");
266
+                usage(prog, stderr, 1);
267
+        }
268
+
269
+        if (lock) {
270
+                if (verbose)
271
+                        fprintf(stdout, "creating lock file %s/%s-%s.lock\n", path, name, uuid);
272
+
273
+                status = do_lock(path, name, uuid);
274
+
275
+                if (verbose)
276
+                        if (status == 0)
277
+                                fprintf(stdout, "lock sucess.\n");
278
+                        else
279
+                                fprintf(stdout, "lock failed.\n");
280
+        } else if (unlock) {
281
+                if (verbose)
282
+                        fprintf(stdout, "removing lock file %s/%s-%s.lock\n", path, name, uuid);
283
+
284
+                status = do_unlock(path, name, uuid);
285
+
286
+                if (verbose)
287
+                        if (status == 0)
288
+                                fprintf(stdout, "unlock sucess.\n");
289
+                        else
290
+                                fprintf(stdout, "unlock failed.\n");
291
+        } else {
292
+                fprintf(stderr, "you should specify lock or unlock.\n\n");
293
+                usage(prog, stderr, 1);
294
+        }
295
+
296
+        return status;
297
+}
298
+
299
--- /root/xen_lock/xend-config.sxp      2011-03-14 15:28:51.000000000 +0100
300
+++ /etc/xen/xend-config.sxp    2011-03-14 15:51:54.000000000 +0100
301
@@ -279,3 +279,9 @@
302
 # we have to realize this may incur security issue and we can't make sure the
303
 # device assignment could really work properly even after we do this.
304
 #(pci-passthrough-strict-check yes)
305
+
306
+# Locking patch taken from:
307
+# http://lists.xensource.com/archives/html/xen-devel/2008-08/msg00274.html
308
+#(xend-domains-path /mnt/xenfs/vm-locks/)
309
+#(xend-domains-lock-path /etc/xen/scripts/file-lock)
310
+