root / lib / utils / livelock.py @ a0a92e23
History | View | Annotate | Download (2.2 kB)
1 |
#
|
---|---|
2 |
#
|
3 |
|
4 |
# Copyright (C) 2014 Google Inc.
|
5 |
#
|
6 |
# This program is free software; you can redistribute it and/or modify
|
7 |
# it under the terms of the GNU General Public License as published by
|
8 |
# the Free Software Foundation; either version 2 of the License, or
|
9 |
# (at your option) any later version.
|
10 |
#
|
11 |
# This program is distributed in the hope that it will be useful, but
|
12 |
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 |
# General Public License for more details.
|
15 |
#
|
16 |
# You should have received a copy of the GNU General Public License
|
17 |
# along with this program; if not, write to the Free Software
|
18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 |
# 02110-1301, USA.
|
20 |
|
21 |
"""Lockfiles to prove liveliness
|
22 |
|
23 |
When requesting resources, like locks, from wconfd, requesters have
|
24 |
to provide the name of a file they own an exclusive lock on, to prove
|
25 |
that they are still alive. Provide methods to obtain such a file.
|
26 |
"""
|
27 |
|
28 |
import fcntl |
29 |
import os |
30 |
import struct |
31 |
import time |
32 |
|
33 |
from ganeti.utils.algo import NiceSort |
34 |
from ganeti import pathutils |
35 |
|
36 |
|
37 |
class LiveLock(object): |
38 |
"""Utility for a lockfile needed to request resources from WconfD.
|
39 |
|
40 |
"""
|
41 |
def __init__(self, name=None): |
42 |
if name is None: |
43 |
name = "pid%d_" % os.getpid()
|
44 |
# to avoid reusing existing lock files, extend name
|
45 |
# by the current time
|
46 |
name = "%s_%d" % (name, int(time.time())) |
47 |
fname = os.path.join(pathutils.LIVELOCK_DIR, name) |
48 |
self.lockfile = open(fname, 'w') |
49 |
fcntl.fcntl(self.lockfile, fcntl.F_SETLKW,
|
50 |
struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)) |
51 |
|
52 |
def close(self): |
53 |
"""Close the lockfile and clean it up.
|
54 |
|
55 |
"""
|
56 |
self.lockfile.close()
|
57 |
os.remove(self.lockfile.name)
|
58 |
|
59 |
|
60 |
def GuessLockfileFor(name): |
61 |
"""For a given name, take the latest file matching.
|
62 |
|
63 |
@return: the file with the latest name matching the given
|
64 |
prefix in LIVELOCK_DIR, or the plain name, if none
|
65 |
exists.
|
66 |
"""
|
67 |
lockfiles = filter(lambda n: n.startswith(name), |
68 |
os.listdir(pathutils.LIVELOCK_DIR)) |
69 |
if len(lockfiles) > 0: |
70 |
lockfile = NiceSort(lockfiles)[-1]
|
71 |
else:
|
72 |
lockfile = name |
73 |
|
74 |
return os.path.join(pathutils.LIVELOCK_DIR, lockfile)
|