summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--pod/urpme.8.pod4
-rw-r--r--pod/urpmf.8.pod4
-rw-r--r--pod/urpmi.8.pod4
-rw-r--r--pod/urpmi.addmedia.8.pod4
-rw-r--r--pod/urpmi.removemedia.8.pod4
-rw-r--r--pod/urpmi.update.8.pod4
-rw-r--r--pod/urpmq.8.pod4
-rw-r--r--urpm/args.pm4
-rw-r--r--urpm/lock.pm43
-rw-r--r--urpm/media.pm9
-rw-r--r--urpme2
-rwxr-xr-xurpmf2
-rwxr-xr-xurpmi4
-rwxr-xr-xurpmi.addmedia2
-rw-r--r--urpmi.bash-completion2
-rwxr-xr-xurpmi.removemedia2
-rwxr-xr-xurpmi.update2
-rwxr-xr-xurpmq4
19 files changed, 70 insertions, 37 deletions
diff --git a/NEWS b/NEWS
index 8f9bc008..6aa466f2 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,6 @@
+- all tools
+ o new option --wait-lock (#13025)
+
Version 4.9.30 - 10 August 2007, by Pascal "Pixel" Rigaux
- urpmi (thanks to Thierry Vignaud)
diff --git a/pod/urpme.8.pod b/pod/urpme.8.pod
index e793ec1c..0fa32dcc 100644
--- a/pod/urpme.8.pod
+++ b/pod/urpme.8.pod
@@ -94,6 +94,10 @@ Use synthesis file (to use with --use-distrib).
Use hdlist file (to use with --use-distrib).
+=item B<--wait-lock>
+
+If the urpmi or rpm db is busy, wait until it is available
+
=back
=head1 FILES
diff --git a/pod/urpmf.8.pod b/pod/urpmf.8.pod
index 897aeabc..f69d375d 100644
--- a/pod/urpmf.8.pod
+++ b/pod/urpmf.8.pod
@@ -87,6 +87,10 @@ to B<--root>, the urpmi configuration comes from the rooted tree.
Verbose mode. urpmf will emit various messages related to the parsing of
hdlist files for your media.
+=item B<--wait-lock>
+
+If the urpmi or rpm db is busy, wait until it is available
+
=item B<-i>
Ignore case distinctions in the patterns that follow.
diff --git a/pod/urpmi.8.pod b/pod/urpmi.8.pod
index 33476963..1d48c47f 100644
--- a/pod/urpmi.8.pod
+++ b/pod/urpmi.8.pod
@@ -364,6 +364,10 @@ When several packages are found, propose more choices than the default.
Don't lock urpmi and rpm db. This can be useful in conjunction with
B<--root>.
+=item B<--wait-lock>
+
+If the urpmi or rpm db is busy, wait until it is available
+
=item B<--strict-arch>
Upgrade only packages if the newer version has the same architecture as
diff --git a/pod/urpmi.addmedia.8.pod b/pod/urpmi.addmedia.8.pod
index 63d95ff6..8b551efb 100644
--- a/pod/urpmi.addmedia.8.pod
+++ b/pod/urpmi.addmedia.8.pod
@@ -156,6 +156,10 @@ on distributions.
Use the file system tree rooted for urpmi database and rpm install. Contrary
to B<--root>, the urpmi configuration comes from the rooted tree.
+=item B<--wait-lock>
+
+If the urpmi or rpm db is busy, wait until it is available
+
=item B<--from> I<url>
Use specified URL for list of mirrors. The default is taken from the file
diff --git a/pod/urpmi.removemedia.8.pod b/pod/urpmi.removemedia.8.pod
index 66ddbb45..d77cba78 100644
--- a/pod/urpmi.removemedia.8.pod
+++ b/pod/urpmi.removemedia.8.pod
@@ -41,6 +41,10 @@ Be quiet.
Use the file system tree rooted for urpmi database and rpm install. Contrary
to B<--root>, the urpmi configuration comes from the rooted tree.
+=item B<--wait-lock>
+
+If the urpmi or rpm db is busy, wait until it is available
+
=back
=head1 SEE ALSO
diff --git a/pod/urpmi.update.8.pod b/pod/urpmi.update.8.pod
index 6df86130..a6434fc0 100644
--- a/pod/urpmi.update.8.pod
+++ b/pod/urpmi.update.8.pod
@@ -48,6 +48,10 @@ username and a password.
Use the file system tree rooted for urpmi database and rpm install. Contrary
to B<--root>, the urpmi configuration comes from the rooted tree.
+=item B<--wait-lock>
+
+If the urpmi or rpm db is busy, wait until it is available
+
=item B<--update>
Use only update media.
diff --git a/pod/urpmq.8.pod b/pod/urpmq.8.pod
index c1904f07..6557cd17 100644
--- a/pod/urpmq.8.pod
+++ b/pod/urpmq.8.pod
@@ -186,6 +186,10 @@ Use hdlist file (to use with --use-distrib).
Use a different environment directly from a bug report to replay a bug.
The argument is the same argument given to B<--bug> option.
+=item B<--wait-lock>
+
+If the urpmi or rpm db is busy, wait until it is available
+
=item B<--changelog>
Prints the package changelog.
diff --git a/urpm/args.pm b/urpm/args.pm
index 68feea57..b5694863 100644
--- a/urpm/args.pm
+++ b/urpm/args.pm
@@ -52,6 +52,7 @@ my %options_spec_all = (
'q|quiet' => sub { --$options{verbose} },
'v|verbose' => sub { ++$options{verbose} },
'urpmi-root=s' => sub { urpm::set_files($urpm, $_[1]) },
+ 'wait-lock' => \$options{wait_lock},
'use-copied-hdlist' => sub { $urpm->{options}{use_copied_hdlist} = 1 },
);
@@ -422,6 +423,9 @@ sub parse_cmdline {
if ($options{probe_with} && $options{probe_with} eq 'rpms' && $options{virtual}) {
die N("Can't use %s with %s", "--probe-rpms", "--virtual");
}
+ if ($options{nolock} && $options{wait_lock}) {
+ warn N("Can't use %s with %s", "--wait-lock", "--nolock") . "\n";
+ }
if ($tool eq 'urpmf' && @ARGV && $ARGV[0] eq '--') {
if (@ARGV == 2) {
my $p = $ARGV[1];
diff --git a/urpm/lock.pm b/urpm/lock.pm
index 0b9cf7f7..dbd237ba 100644
--- a/urpm/lock.pm
+++ b/urpm/lock.pm
@@ -15,22 +15,25 @@ my ($LOCK_SH, $LOCK_EX, $LOCK_NB, $LOCK_UN) = (1, 2, 4, 8);
#- lock policy concerning chroot :
# - lock rpm db in chroot
# - lock urpmi db in /
+# (options: nofatal, wait)
sub rpm_db {
- my ($urpm, $b_exclusive) = @_;
+ my ($urpm, $b_exclusive, %options) = @_;
my $f = ($urpm->{root} && !$urpm->{urpmi_root} ? "$urpm->{root}/" : '') . "$urpm->{statedir}/.RPMLOCK";
- urpm::lock->new($urpm, $f, 'rpm', $b_exclusive);
+ urpm::lock->new($urpm, $f, 'rpm', $b_exclusive, %options);
}
+# (options: nofatal, wait)
sub urpmi_db {
- my ($urpm, $b_exclusive, $b_nofatal) = @_;
- urpm::lock->new($urpm, "$urpm->{statedir}/.LOCK", 'urpmi', $b_exclusive, $b_nofatal);
+ my ($urpm, $b_exclusive, %options) = @_;
+ urpm::lock->new($urpm, "$urpm->{statedir}/.LOCK", 'urpmi', $b_exclusive, %options);
}
################################################################################
#- methods
+# (options: nofatal, wait)
sub new {
- my ($_class, $urpm, $file, $db_name, $b_exclusive, $b_nofatal) = @_;
+ my ($_class, $urpm, $file, $db_name, $b_exclusive, %options) = @_;
my $fh;
#- we don't care what the mode is. ">" allow creating the file, but can't be done as user
@@ -38,40 +41,34 @@ sub new {
my $lock = bless {
fh => $fh, db_name => $db_name,
- fatal => $b_nofatal ? $urpm->{error} : sub { $urpm->{fatal}(7, $_[0]) },
+ fatal => $options{nofatal} ? $urpm->{error} : sub { $urpm->{fatal}(7, $_[0]) },
+ info => $urpm->{info},
log => $urpm->{log},
};
- _lock($lock, $b_exclusive);
+ _lock($lock, $b_exclusive, $options{wait});
$lock;
}
-sub _flock_failed {
- my ($lock) = @_;
- $lock->{fatal}(N("%s database locked", $lock->{db_name}));
-}
-
sub _lock {
- my ($lock, $b_exclusive) = @_;
+ my ($lock, $b_exclusive, $b_wait) = @_;
$b_exclusive ||= '';
if ($lock->{log}) {
my $action = $lock->{exclusive} && !$b_exclusive ? 'releasing exclusive' : $b_exclusive ? 'getting exclusive' : 'getting';
$lock->{log}("$action lock on $lock->{db_name}");
}
my $mode = $b_exclusive ? $LOCK_EX : $LOCK_SH;
- flock $lock->{fh}, $mode|$LOCK_NB or _flock_failed($lock);
+ if (!flock($lock->{fh}, $mode | $LOCK_NB)) {
+ if ($b_wait) {
+ $lock->{info}(N("%s database locked. waiting...", $lock->{db_name}));
+ flock($lock->{fh}, $mode) or $lock->{fatal}(N("aborting"));
+ } else {
+ $lock->{fatal}(N("%s database locked", $lock->{db_name}));
+ }
+ }
$lock->{locked} = 1;
$lock->{exclusive} = $b_exclusive;
}
-sub get_exclusive {
- my ($lock) = @_;
- _lock($lock, 'exclusive');
-}
-sub release_exclusive {
- my ($lock) = @_;
- _lock($lock);
-}
-
sub unlock {
my ($lock) = @_;
$lock->{fh} or warn "lock $lock->{db_name} already released\n", return;
diff --git a/urpm/media.pm b/urpm/media.pm
index 16384249..883e5dce 100644
--- a/urpm/media.pm
+++ b/urpm/media.pm
@@ -1539,12 +1539,12 @@ sub _get_pubkey_and_descriptions {
}
sub _read_cachedir_pubkey {
- my ($urpm, $medium) = @_;
+ my ($urpm, $medium, $b_wait_lock) = @_;
-s "$urpm->{cachedir}/partial/pubkey" or return;
$urpm->{log}(N("examining pubkey file of \"%s\"...", $medium->{name}));
- my $_rpm_lock = urpm::lock::rpm_db($urpm, 'exclusive');
+ my $_rpm_lock = urpm::lock::rpm_db($urpm, 'exclusive', wait => $b_wait_lock);
my %key_ids;
$urpm->import_needed_pubkeys(
@@ -1779,6 +1779,7 @@ sub _update_media__handle_some_flags {
#- nopubkey : don't use rpm pubkeys
#- probe_with : probe synthesis or hdlist (or none)
#- quiet : download hdlists quietly
+#- wait_lock : block until lock can be acquired
sub update_media {
my ($urpm, %options) = @_;
@@ -1787,7 +1788,7 @@ sub update_media {
$options{nopubkey} ||= $urpm->{options}{nopubkey};
if (!$options{nopubkey} && !$urpm->{keys}) {
#- get gpg-pubkey signature.
- my $_rpm_lock = urpm::lock::rpm_db($urpm);
+ my $_rpm_lock = urpm::lock::rpm_db($urpm, '', wait => $options{wait_lock});
$urpm->{log}(qq(getting "gpg-pubkey"s from rpmdb));
$urpm->parse_pubkeys(root => $urpm->{root});
}
@@ -1827,7 +1828,7 @@ sub update_media {
if ($medium->{really_modified}) {
_get_pubkey_and_descriptions($urpm, $medium, $options{nopubkey});
- _read_cachedir_pubkey($urpm, $medium);
+ _read_cachedir_pubkey($urpm, $medium, $options{wait_lock});
generate_medium_names($urpm, $medium);
}
}
diff --git a/urpme b/urpme
index f07eb369..7ab603e1 100644
--- a/urpme
+++ b/urpme
@@ -83,7 +83,7 @@ unless ($test) {
}
#- just configure parallel mode if available.
-my $_urpmi_lock = urpm::lock::urpmi_db($urpm);
+my $_urpmi_lock = urpm::lock::urpmi_db($urpm, '', wait => $options{wait_lock});
urpm::media::configure($urpm,
synthesis => ($parallel ? 'none' : ''),
parallel => $parallel,
diff --git a/urpmf b/urpmf
index 8c93f538..cc0e1aca 100755
--- a/urpmf
+++ b/urpmf
@@ -194,7 +194,7 @@ if ($env) {
$urpm->{statedir} = $env;
}
-my $_lock = urpm::lock::urpmi_db($urpm, '', 'nofatal');
+my $_lock = urpm::lock::urpmi_db($urpm, '', nofatal => 1, wait => $options{wait_lock});
my $need_hdlist = grep { $usedtags{$_} } qw(
buildhost
buildtime
diff --git a/urpmi b/urpmi
index 6566781c..e77bb5af 100755
--- a/urpmi
+++ b/urpmi
@@ -328,7 +328,7 @@ if (exists $urpm->{options}{'priority-upgrade'} && $urpm->{options}{'priority-up
unlink glob('/var/lib/rpm/__db.*') unless $urpm->{root};
}
-my $urpmi_lock = !$env && !$options{nolock} && urpm::lock::urpmi_db($urpm);
+my $urpmi_lock = !$env && !$options{nolock} && urpm::lock::urpmi_db($urpm, '', wait => $options{wait_lock});
#- should we ignore arch compatibility
if ($urpm->{options}{ignorearch}) { urpm::shunt_ignorearch() }
@@ -394,7 +394,7 @@ if ($bug) {
urpm::bug_report::copy_requested($urpm, $bug, \%requested);
}
-my $rpm_lock = !$env && !$options{nolock} && urpm::lock::rpm_db($urpm, 'exclusive');
+my $rpm_lock = !$env && !$options{nolock} && urpm::lock::rpm_db($urpm, 'exclusive', wait => $options{wait_lock});
#- search the packages according to the selection given by the user.
my $search_result = '';
diff --git a/urpmi.addmedia b/urpmi.addmedia
index c8bb7076..3a1f6ed1 100755
--- a/urpmi.addmedia
+++ b/urpmi.addmedia
@@ -115,7 +115,7 @@ if (!-e $urpm->{config}) {
$urpm->{log}(N("creating config file [%s]", $urpm->{config}));
open my $_f, '>', $urpm->{config} or $urpm->{fatal}(6, N("Can't create config file [%s]", $urpm->{config}));
}
-my $_urpmi_lock = urpm::lock::urpmi_db($urpm, 'exclusive');
+my $_urpmi_lock = urpm::lock::urpmi_db($urpm, 'exclusive', wait => $options{wait_lock});
urpm::media::read_config($urpm);
if ($options{distrib}) {
diff --git a/urpmi.bash-completion b/urpmi.bash-completion
index 3f67b4c9..c15d84c8 100644
--- a/urpmi.bash-completion
+++ b/urpmi.bash-completion
@@ -2,7 +2,7 @@
# Copyright (c) 2002-2006 Guillaume Rousse <guillomovitch@mandriva.com>
# $Id$
-common_options="-q --quiet -v --verbose --debug -h --help --urpmi-root"
+common_options="-q --quiet -v --verbose --debug -h --help --urpmi-root --wait-lock"
# utility functions
_urpmi_get_medias()
diff --git a/urpmi.removemedia b/urpmi.removemedia
index a3485282..b60c1f55 100755
--- a/urpmi.removemedia
+++ b/urpmi.removemedia
@@ -63,7 +63,7 @@ if ($< != 0) {
$urpm->{fatal}(1, N("Only superuser is allowed to remove media"));
}
-my $_urpmi_lock = urpm::lock::urpmi_db($urpm, 'exclusive');
+my $_urpmi_lock = urpm::lock::urpmi_db($urpm, 'exclusive', wait => $options{wait_lock});
urpm::media::read_config($urpm);
urpm::download::set_cmdline_proxy();
my @entries = map { $_->{name} } @{$urpm->{media}};
diff --git a/urpmi.update b/urpmi.update
index b0993770..257b0198 100755
--- a/urpmi.update
+++ b/urpmi.update
@@ -68,7 +68,7 @@ urpm::args::parse_cmdline(urpm => $urpm) or exit(1);
if ($< != 0) {
$urpm->{fatal}(1, N("Only superuser is allowed to update media"));
}
-my $_urpmi_lock = urpm::lock::urpmi_db($urpm, 'exclusive');
+my $_urpmi_lock = urpm::lock::urpmi_db($urpm, 'exclusive', wait => $options{wait_lock});
urpm::media::read_config($urpm);
my @entries = map { $_->{name} } @{$urpm->{media}};
diff --git a/urpmq b/urpmq
index ce367196..271ee92c 100755
--- a/urpmq
+++ b/urpmq
@@ -145,8 +145,8 @@ if ($options{ignorearch}) { urpm::shunt_ignorearch() }
my $rpm_lock =
$options{upgrade} && !$options{env} && !$options{nolock}
- && urpm::lock::rpm_db($urpm);
-my $urpmi_lock = !$options{nolock} && urpm::lock::urpmi_db($urpm);
+ && urpm::lock::rpm_db($urpm, '', wait => $options{wait_lock});
+my $urpmi_lock = !$options{nolock} && urpm::lock::urpmi_db($urpm, '', wait => $options{wait_lock});
urpm::media::configure($urpm,
nocheck_access => 1,
nodepslist => $options{nodepslist},