[prev in list] [next in list] [prev in thread] [next in thread]
List: fink-commits
Subject: fink/perlmod/Fink ChangeLog,1.1180,1.1181 Engine.pm,1.336,1.337 Package.pm,1.163,1.164 PkgVersion.pm
From: Daniel Macks <dmacks () users ! sourceforge ! net>
Date: 2005-10-31 20:32:36
Message-ID: E1EWgKf-0000c0-Nw () mail ! sourceforge ! net
[Download RAW message or body]
Update of /cvsroot/fink/fink/perlmod/Fink
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20326
Modified Files:
ChangeLog Engine.pm Package.pm PkgVersion.pm
Log Message:
Yet Another rewrite of buildlock mechanism, this time using
semi-autonomous lockpkg interlocking.
Index: PkgVersion.pm
===================================================================
RCS file: /cvsroot/fink/fink/perlmod/Fink/PkgVersion.pm,v
retrieving revision 1.488
retrieving revision 1.489
diff -u -d -r1.488 -r1.489
--- PkgVersion.pm 25 Oct 2005 22:08:16 -0000 1.488
+++ PkgVersion.pm 31 Oct 2005 20:32:34 -0000 1.489
@@ -4116,29 +4116,36 @@
return $self->get_parent->set_buildlock();
}
+ # bootstrapping occurs before we have package-management tools
+ # needed for buildlocking. If you're bootstrapping into a location
+ # that already has a running fink, you already know you're gonne
+ # hose whatever may be running under that fink...
+ return if $self->{_bootstrap};
+
+ # The plan: get an exlusive lock for %n-%v-%r_$timestamp that
+ # automatically goes away when this fink process quit. Install a
+ # %n-%v-%r package that prohibits removal of itself if that lock
+ # is present. It's always safe to attempt to remove all installed
+ # buildlock pkgs since they can each determine if these locks are
+ # dead. Attempting to install a lockpkg for the same %n-%v-%r
+ # will cause existing one to attempt to be removed, which will
+ # fail iff its lock is still alive. Fallback to the newer pkg's
+ # prerm is okay because that will also be blocked by its own live
+ # lock.
+
print "Setting runtime build-lock...\n";
- # get an exlusive lock for the the %n-%v-%r
- Fink::Package->control_buildlocks(1);
my $lockdir = "$basepath/var/run/fink/buildlock";
mkdir_p $lockdir or
die "can't create $lockdir directory for buildlocks\n";
- my $lockfile = $lockdir . '/' . $self->get_fullname() . '.lock';
- my $lock_FH = lock_wait($lockfile, exclusive => 1);
- $self->{_lockfile} = [ $lockfile, $lock_FH ];
-
- # bootstrapping occurs before we have package-management tools
- # needed for buildlock package so don't create one
- if ($self->{_bootstrap}) {
- Fink::Package->control_buildlocks(0);
- return;
- }
+ my $timestamp = strftime "%Y.%m.%d-%H.%M.%S", localtime;
+ my $lockfile = $lockdir . '/' . $self->get_fullname() . "_$timestamp.lock";
+ my $lock_FH = lock_wait($lockfile, exclusive => 1);
my $pkgname = $self->get_name();
my $pkgvers = $self->get_fullversion();
my $lockpkg = 'fink-buildlock-' . $self->get_fullname();
- my $timestamp = strftime "%Y.%m.%d-%H.%M.%S", localtime;
my $destdir = $self->get_install_directory($lockpkg);
@@ -4167,7 +4174,6 @@
Maintainer: Fink Core Group <fink-core\@lists.sourceforge.net>
Maintainer: Fink Core Group <fink-core\@lists.sourceforge.net>
Provides: fink-buildlock
-Essential: yes
EOF
# buildtime (anti)dependencies of pkg are runtime (anti)dependencies of lockpkg
@@ -4182,9 +4188,40 @@
}
### write "control" file
- open(CONTROL,">$destdir/DEBIAN/control") or die "can't write control file for \
$lockpkg: $!\n";
- print CONTROL $control;
- close(CONTROL) or die "can't write control file for $lockpkg: $!\n";
+ if (open my $controlfh, '>', "$destdir/DEBIAN/control") {
+ print $controlfh $control;
+ close $controlfh or die "can't write control file for $lockpkg: $!\n";
+ } else {
+ die "can't write control file for $lockpkg: $!\n";
+ }
+
+ ### set up the lockfile interlocking
+
+ # this is implemented in perl but PreRm is in bash so we gonna in-line it
+ my $prerm = <<EOF;
+#!/bin/bash -e
+
+if perl -Mlib=$basepath/lib/perl5 -MFink::Services=lock_wait -e \
'lock_wait("$lockfile", exclusive => 1, no_block => 1) ? exit 0 : exit 1' ; then + \
rm -f $lockfile + exit 0
+else
+ cat <<EOMSG
+There is currently an active buildlock for the package
+ $pkgname ($pkgvers)
+meaning some other fink process is currently building it.
+EOMSG
+ exit 1
+fi
+EOF
+
+ ### write prerm file
+ if (open my $prermfh, '>', "$destdir/DEBIAN/prerm") {
+ print $prermfh $prerm;
+ close $prermfh or die "can't write PreRm file for $lockpkg: $!\n";
+ chmod 0755, "$destdir/DEBIAN/prerm";
+ } else {
+ die "can't write PreRm file for $lockpkg: $!\n";
+ }
### store our PID in a file in the buildlock package
my $deb_piddir = "$destdir$lockdir";
@@ -4210,7 +4247,7 @@
"the directory manually to save disk space. ".
"Continuing with normal procedure.");
- # install lockpkg (== set lockfile for building ourself)
+ # install lockpkg (== set dpkg lock on our deps)
print "Installing build-lock package...\n";
my $debfile = $buildpath.'/'.$lockpkg.'_'.$timestamp.'_'.$debarch.'.deb';
my $lock_failed = &execute(dpkg_lockwait() . " -i $debfile", ignore_INT=>1);
@@ -4237,7 +4274,9 @@
# Failure due to depenendecy problems leaves lockpkg in an
# "unpacked" state, so try to remove it entirely.
- &execute(dpkg_lockwait() . " --force-remove-essential -r $lockpkg 2>/dev/null", \
ignore_INT=>1); + unlink $lockfile;
+ close $lock_FH;
+ &execute(dpkg_lockwait() . " -r $lockpkg", ignore_INT=>1);
}
# Even if installation fails, no reason to keep this around
@@ -4250,10 +4289,12 @@
die "buildlock failure\n" if $lock_failed;
- Fink::Package->control_buildlocks(0);
-
# record buildlock package name so we can remove it during clear_buildkock
- $self->{_lockpkg} = $lockpkg;
+ $self->{_buildlock} = {
+ lockfile => $lockfile,
+ lock_FH => $lock_FH,
+ lockpkg => $lockpkg
+ };
}
# remove the lock created by set_buildlock
@@ -4267,13 +4308,16 @@
return $self->get_parent->clear_buildlock();
}
- Fink::Package->control_buildlocks(0);
+ if (exists $self->{_buildlock}) {
+ # we were locked...
+ print "Removing runtime build-lock...\n";
+ close $self->{_buildlock}->{lock_FH};
- if (exists $self->{_lockpkg}) {
print "Removing build-lock package...\n";
- my $lockpkg = $self->{_lockpkg};
+ my $lockpkg = $self->{_buildlock}->{lockpkg};
- if (&execute(dpkg_lockwait() . " --force-remove-essential -r $lockpkg \
2>/dev/null", ignore_INT=>1)) { + # lockpkg's prerm deletes the lockfile
+ if (&execute(dpkg_lockwait() . " -r $lockpkg", ignore_INT=>1)) {
&print_breaking("WARNING: Can't remove package ".
"$lockpkg. ".
"This is not fatal, but you may want to remove ".
@@ -4282,17 +4326,8 @@
"Continuing with normal procedure.");
}
Fink::PkgVersion->dpkg_changed;
- delete $self->{_lockpkg};
- }
-
- if (exists $self->{_lockfile}) {
- print "Removing runtime build-lock...\n";
- close $self->{_lockfile}->[1];
- unlink $self->{_lockfile}->[0]; # try to clean up
- delete $self->{_lockfile};
+ delete $self->{_buildlock};
}
-
- Fink::Package->control_buildlocks(0);
}
=item ensure_gpp_prefix
Index: Package.pm
===================================================================
RCS file: /cvsroot/fink/fink/perlmod/Fink/Package.pm,v
retrieving revision 1.163
retrieving revision 1.164
diff -u -d -r1.163 -r1.164
--- Package.pm 12 Oct 2005 05:31:47 -0000 1.163
+++ Package.pm 31 Oct 2005 20:32:34 -0000 1.164
@@ -1240,38 +1240,6 @@
}
}
-=item control_buildlocks
-
- Fink::Package->control_buildlocks(1);
- # add or remove buildlocks
- Fink::Package->control_buildlocks(0);
-
-When called with a boolean "true" value, get an exclusive lock on the
-buildlock system. When called with a boolean "false" value, release
-this exclusive lock. You must have this exclusive lock whenever you
-will be setting or clearing buildlocks (or if you want to prevent
-other fink processes from doing so for any reason).
-
-=cut
-
-sub control_buildlocks {
- my $class = shift;
- my $lock = shift || 0;
-
- if ($lock) {
- if (!defined $buildlock_master) {
- # no use relocking if we already own the lock
- my $lockdir = "$basepath/var/run/fink/buildlock";
- mkdir_p $lockdir or
- die "can't create $lockdir directory for master buildlock\n";
- my $lockfile = "$lockdir/MASTER_LOCK";
- $buildlock_master = lock_wait($lockfile, exclusive => 1);
- }
- } else {
- undef $buildlock_master;
- }
-}
-
=back
=cut
Index: Engine.pm
===================================================================
RCS file: /cvsroot/fink/fink/perlmod/Fink/Engine.pm,v
retrieving revision 1.336
retrieving revision 1.337
diff -u -d -r1.336 -r1.337
--- Engine.pm 21 Oct 2005 19:27:54 -0000 1.336
+++ Engine.pm 31 Oct 2005 20:32:34 -0000 1.337
@@ -1336,17 +1336,16 @@
=item cleanup_buildlocks
-Check for all processes corresponding to each buildlock pid-file.
-Optionally remove those buildlocks whose processes do not
-exist. Returns a boolean indicating whether there any active
-buildlocks are still present after cleanup. The following option is
-known:
+Search for all present lockfiles and all installed lockpkgs Optionally
+have lockpkgs remove themselves and nuke unlocked lockfiles. Returns a
+boolean indicating whether there any active buildlocks are still
+present after cleanup. The following option is known:
=over 4
=item dryrun
-If true, don't actually remove the locks.
+If true, don't actually remove things.
=back
@@ -1355,68 +1354,74 @@
sub cleanup_buildlocks {
my %opts = (dryrun => 0, @_);
- Fink::Package->control_buildlocks(1);
-
- print "Reading buildlocks...\n";
my $lockdir = "$basepath/var/run/fink/buildlock";
+ my @locks;
+ my $locks_left = 0; # return value (set to 1 if an error occurs)
- my @lockfiles = ();
+ print "Reading buildlock packages...\n";
+ @locks = ();
if (opendir my $dirhandle, $lockdir) {
- @lockfiles = grep { /^.+\.lock$/ } readdir $dirhandle;
+ @locks = readdir $dirhandle;
close $dirhandle;
} else {
print "Warning: could not read buildlock directory $lockdir: $!\n";
- Fink::Package->control_buildlocks(0);
- return 0;
+ $locks_left = 1;
}
+ # lock packages are named fink-buildlock-%n-%v-%r and install %n-%v-%r.pid
+ @locks = grep { s/(.+)\.pid$/fink-buildlock-$1/ } @locks;
- if (!@lockfiles) {
- print "No buildlocks found\n";
- Fink::Package->control_buildlocks(0);
- return 0;
+ if ($opts{dryrun}) {
+ print map "\t$_\n", @locks;
+ } else {
+ print map "\t$_... will remove\n", @locks;
}
- my $locks_left = 0;
- my %lock_FHs = ();
- my @lock_pkgs = ();
- foreach my $lockfile (sort @lockfiles) {
- my ($fullname) = $lockfile =~ /^(.+)\.lock$/;
+ if (@locks) {
+ if ($opts{dryrun}) {
+ $locks_left = 1;
+ } else {
+ if (&execute(dpkg_lockwait() . " -r @locks", ignore_INT=>1)) {
+ print "Warning: could not remove all buildlock packages!\n";
+ $locks_left = 1;
+ }
+ Fink::PkgVersion->dpkg_changed;
+ }
+ }
+
+ print "Reading buildlock lockfiles...\n";
+ @locks = ();
+ if (opendir my $dirhandle, $lockdir) {
+ @locks = readdir $dirhandle;
+ close $dirhandle;
+ } else {
+ print "Warning: could not read buildlock directory $lockdir: $!\n";
+ $locks_left = 1;
+ }
+ # lock lockfiles are named %n-%v-%r_$timestamp.lock
+ @locks = grep { /\.lock$/ } @locks;
+
+ foreach my $lockfile (@locks) {
+ printf "\t$lockfile";
my $lock_FH = lock_wait("$lockdir/$lockfile", exclusive => 1, no_block => 1);
if ($lock_FH) {
# got flock so buildlock is not in use
- if ($opts{dryrun}) {
- print "Runtime buildlock for $fullname is dead.\n";
+ print "... dead";
+ if (not $opts{dryrun}) {
+ print "... deleting";
+ if (not unlink "$lockdir/$lockfile") {
+ print "... failed";
+ $locks_left = 1;
+ }
} else {
- print "Runtime buildlock for $fullname is dead...will clear.\n";
- $lock_FHs{"$lockdir/$lockfile"} = $lock_FH;
- }
- if (-e "$lockdir/$fullname.pid") {
- print "...and its lock package too.\n";
- push @lock_pkgs, "fink-buildlock-$fullname" if !$opts{dryrun};
+ $locks_left = 1;
}
+ print "\n";
} else {
- print "Buildlock for $fullname is still in use.\n";
- $locks_left = 1;
- }
- }
-
- if (@lock_pkgs) {
- printf "Removing %i dead buildlock package(s)...\n", scalar @lock_pkgs;
- if (&execute(dpkg_lockwait() . " --force-remove-essential -r @lock_pkgs \
2>/dev/null", ignore_INT=>1)) {
- print "Warning: could not remove all buildlock packages!\n";
+ print "... still in use\n";
$locks_left = 1;
}
- Fink::PkgVersion->dpkg_changed;
- }
-
- if (%lock_FHs) {
- printf "Removing %i dead lockfile(s)...\n", scalar keys %lock_FHs;
- rm_f keys %lock_FHs or $locks_left = 1;
- %lock_FHs = ();
}
- Fink::Package->control_buildlocks(0);
-
return $locks_left;
}
Index: ChangeLog
===================================================================
RCS file: /cvsroot/fink/fink/perlmod/Fink/ChangeLog,v
retrieving revision 1.1180
retrieving revision 1.1181
diff -u -d -r1.1180 -r1.1181
--- ChangeLog 27 Oct 2005 12:17:24 -0000 1.1180
+++ ChangeLog 31 Oct 2005 20:32:34 -0000 1.1181
@@ -1,3 +1,11 @@
+2005-10-31 Daniel Macks <dmacks@netspace.org>
+
+ * PkgVersion.pm: overhaul buildlocks again. Now we set/unset lock
+ on a timestamped lockfile before installing/removing lockpkg;
+ lockpkg prerm fails if lockfile is locked.
+ * Engine.pm: Rewrite cleanup_buildlocks for new implementation.
+ * Package.pm: Remove no-longer-needed control_buildlocks.
+
2005-10-27 Benjamin Reed <rangerrick@users.sourceforge.net>
* VirtPackage.pm: added proper URL for JavaAI and Java3D
-------------------------------------------------------
This SF.Net email is sponsored by the JBoss Inc.
Get Certified Today * Register for a JBoss Training Course
Free Certification Exam for All Training Attendees Through End of 2005
Visit http://www.jboss.com/services/certification for more information
_______________________________________________
Fink-commits mailing list
Fink-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/fink-commits
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic