Hi all,
Here's a patch for Dak which implements proper locking by checking pids
etc.
Originally sent to Ganneff, but I know he's very busy at the mo.
I've checked and they're all working as expected on my local testbed,
but you may want to check your own too :)
Neil
--
__
.` `. neilm@debian.org | Application Manager
: :' ! ---------------- | Secure-Testing Team member
'. `- gpg: B345BDD3 | Webapps Team member
`- Please don't cc, I'm subscribed to the list
Index: jennifer
===================================================================
RCS file: /cvs/dak/dak/jennifer,v
retrieving revision 1.65
diff -u -r1.65 jennifer
--- jennifer 5 Dec 2005 05:35:47 -0000 1.65
+++ jennifer 17 Dec 2005 22:20:07 -0000
@@ -1305,20 +1305,14 @@
# Check that we aren't going to clash with the daily cron job
- if not Options["No-Action"] and os.path.exists("%s/daily.lock" % (Cnf["Dir::Lock"])) and not Options["No-Lock"]:
+ if not Options["No-Action"] and os.path.isfile("%s/daily.lock" % (Cnf["Dir::Lock"])) and not Options["No-Lock"]:
utils.fubar("Archive maintenance in progress. Try again later.");
# Obtain lock if not in no-action mode and initialize the log
if not Options["No-Action"]:
- lock_fd = os.open(Cnf["Dinstall::LockFile"], os.O_RDWR | os.O_CREAT);
- try:
- fcntl.lockf(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB);
- except IOError, e:
- if errno.errorcode[e.errno] == 'EACCES' or errno.errorcode[e.errno] == 'EAGAIN':
- utils.fubar("Couldn't obtain lock; assuming another jennifer is already running.");
- else:
- raise;
+ if not utils.lock_aquire(Cnf["Dinstall::LockFile"]):
+ utils.fubar("Couldn't obtain lock; assuming another jennifer is already running.");
Logger = Katie.Logger = logging.Logger(Cnf, "jennifer");
# debian-{devel-,}-changes@lists.debian.org toggles writes access based on this header
Index: kelly
===================================================================
RCS file: /cvs/dak/dak/kelly,v
retrieving revision 1.18
diff -u -r1.18 kelly
--- kelly 17 Dec 2005 10:57:03 -0000 1.18
+++ kelly 17 Dec 2005 22:20:07 -0000
@@ -607,14 +607,8 @@
# Obtain lock if not in no-action mode and initialize the log
if not Options["No-Action"]:
- lock_fd = os.open(Cnf["Dinstall::LockFile"], os.O_RDWR | os.O_CREAT);
- try:
- fcntl.lockf(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB);
- except IOError, e:
- if errno.errorcode[e.errno] == 'EACCES' or errno.errorcode[e.errno] == 'EAGAIN':
- utils.fubar("Couldn't obtain lock; assuming another kelly is already running.");
- else:
- raise;
+ if not utils.lock_aquire(Cnf["Dinstall::LockFile"]):
+ utils.fubar("Couldn't obtain lock; assuming another jennifer is already running.");
Logger = Katie.Logger = logging.Logger(Cnf, "kelly");
if not installing_to_stable and Cnf.get("Dir::UrgencyLog"):
Urgency_Logger = Urgency_Log(Cnf);
Index: lisa
===================================================================
RCS file: /cvs/dak/dak/lisa,v
retrieving revision 1.31
diff -u -r1.31 lisa
--- lisa 15 Nov 2005 09:50:32 -0000 1.31
+++ lisa 17 Dec 2005 22:20:07 -0000
@@ -871,24 +871,18 @@
print "ACCEPT";
if not Options["No-Action"]:
retry = 0;
- while retry < 10:
- try:
- lock_fd = os.open(Cnf["Lisa::AcceptedLockFile"], os.O_RDONLY | os.O_CREAT | os.O_EXCL);
- retry = 10;
- except OSError, e:
- if errno.errorcode[e.errno] == 'EACCES' or errno.errorcode[e.errno] == 'EEXIST':
+ while retry < 10:
+ if not utils.lock_aquire(Cnf["Lisa::AcceptedLockFile"]):
retry += 1;
if (retry >= 10):
utils.fubar("Couldn't obtain lock; assuming jennifer is already running.");
else:
print("Unable to get accepted lock (try %d of 10)" % retry);
time.sleep(60);
- else:
- raise;
(summary, short_summary) = Katie.build_summaries();
Katie.accept(summary, short_summary);
os.unlink(Katie.pkg.changes_file[:-8]+".katie");
- os.unlink(Cnf["Lisa::AcceptedLockFile"]);
+ utils.lock_release(Cnf["Lisa::AcceptedLockFile"]);
def check_status(files):
new = byhand = 0;
Index: utils.py
===================================================================
RCS file: /cvs/dak/dak/utils.py,v
retrieving revision 1.73
diff -u -r1.73 utils.py
--- utils.py 18 Mar 2005 05:24:38 -0000 1.73
+++ utils.py 17 Dec 2005 22:20:07 -0000
@@ -1070,6 +1070,91 @@
return filename;
################################################################################
+# Functions for dealing with lockfiles
+
+def lock_aquire(lockfile,pid=os.getpid()):
+ """Aquire a lockfile"""
+
+ __lock_makefile(lockfile);
+ # Permission check
+ if (lock_check(lockfile,pid) != 1):
+ warn("Coudn't obtain lock, in use by pid %s" % __lock_getpid(lockfile));
+ return 0;
+ else:
+ __lock_setpid(lockfile,pid);
+ return 1;
+
+def lock_release(lockfile,pid=os.getpid()):
+ """Release a lockfile. Checks permissions and won't release unless pid = the locked pid"""
+
+ # First, check if we have 'permission'
+ if (lock_check(lockfile,pid) != 1):
+ warn("Cannot release lockfile, no permission");
+ return 0;
+ else:
+ __lock_rmfile(lockfile);
+ return 1;
+
+def lock_check(lockfile,pid=os.getpid()):
+ """Checks a lock against the given pid (or the current one)"""
+ pidset = __lock_getpid(lockfile);
+ if (pidset != 0 and pidset != "%s" % (pid) and pidset != ''):
+ try:
+ print(os.kill(int(pidset),0));
+ except OSError, err:
+ if (err.errno == 3):
+ # remove the stale lockfile
+ __lock_rmfile(lockfile);
+ return 1;
+ return 0;
+ return 1;
+
+# Some private functions/methods/defs/whatever-python-calls-them
+def __lock_getpid(lockfile):
+ if os.path.isfile(lockfile) != True:
+ return 0;
+ else:
+ try:
+ fd = open(lockfile, "r");
+ pid = fd.readline();
+ pid = string.rstrip(pid);
+ fd.close();
+ return pid;
+ except IOError, err:
+ fubar("Couldn't retrieve pid from lockfile '%s'! : %s" % (filename,err.strerror));
+
+def __lock_setpid(lockfile,pid):
+ if os.path.isfile(lockfile) != True:
+ __lock_makefile(lockfile);
+ try:
+ fd = open(lockfile, "w");
+ fd.write("%s" % pid);
+ fd.close();
+ return 1;
+ except IOError, err:
+ fubar("Coudn't write pid to the lockfile '%s'! : %s" % (filename,err.strerror));
+
+def __lock_makefile(lockfile):
+ if os.path.isfile(lockfile):
+ return 0;
+ else:
+ try:
+ os.open(lockfile, os.O_CREAT, 0666);
+ return 1;
+ except IOError, err:
+ fubar("Coudn't create lockfile '%s': %s" % (filename,err.strerror));
+
+def __lock_rmfile(lockfile):
+ if os.path.isfile(lockfile):
+ try:
+ os.unlink(lockfile)
+ return 1;
+ except IOError, err:
+ fubar("Coudn't remove lockfile '%s': %s" % (filename,err.strerror));
+ else:
+ return 0;
+
+################################################################################
apt_pkg.init();
Attachment:
signature.asc
Description: Digital signature