From f4c5b3fcf6bbca2fa0fcfcf7ab58819c79caeb50 Mon Sep 17 00:00:00 2001 From: Pascal Rigaux Date: Tue, 21 Nov 2006 15:19:52 +0000 Subject: move lock functions to urpm::sys --- gurpmi2 | 8 +++--- urpm.pm | 67 ++++++--------------------------------------- urpm/sys.pm | 91 +++++++++++++++++++++++++++++++++++++++++++++++-------------- urpmf | 4 +-- urpmi | 8 +++--- urpmq | 8 +++--- 6 files changed, 93 insertions(+), 93 deletions(-) diff --git a/gurpmi2 b/gurpmi2 index b7840ea8..90be7706 100755 --- a/gurpmi2 +++ b/gurpmi2 @@ -114,8 +114,8 @@ sub configure_urpm() { $w->run; $w->destroy; }; - $urpm->lock_rpm_db('exclusive'); - $urpm->lock_urpmi_db; + urpm::sys::lock_rpm_db($urpm, 'exclusive'); + urpm::sys::lock_urpmi_db($urpm); $urpm->configure( root => $gurpmi::options{root}, media => $gurpmi::options{media}, @@ -332,7 +332,7 @@ sub do_install_3 () { } else { $progress_label->set_label(N("Installation finished")); } - $urpm->unlock_urpmi_db; - $urpm->unlock_rpm_db; + urpm::sys::unlock_urpmi_db($urpm); + urpm::sys::unlock_rpm_db($urpm); $urpm->try_umounting_removables; } diff --git a/urpm.pm b/urpm.pm index 842a7334..51a01e1e 100644 --- a/urpm.pm +++ b/urpm.pm @@ -18,9 +18,6 @@ our @ISA = qw(URPM); use URPM; use URPM::Resolve; -my $RPMLOCK_FILE; -my $LOCK_FILE; - #- this violently overrides is_arch_compat() to always return true. sub shunt_ignorearch { eval q( sub URPM::Package::is_arch_compat { 1 } ); @@ -740,7 +737,7 @@ sub add_medium { #- make sure configuration has been read. $urpm->{media} or die "caller should have used ->read_config or ->configure first"; - $urpm->lock_urpmi_db('exclusive') if !$options{nolock}; + urpm::sys::lock_urpmi_db($urpm, 'exclusive') if !$options{nolock}; #- if a medium with that name has already been found, we have to exit now my $medium; @@ -783,7 +780,7 @@ sub add_medium { $urpm->{log}(N("added medium %s", $name)); $urpm->{modified} = 1; - $options{nolock} or $urpm->unlock_urpmi_db; + $options{nolock} or urpm::sys::unlock_urpmi_db($urpm); $name; } @@ -1888,11 +1885,11 @@ sub update_media { $options{nopubkey} ||= $urpm->{options}{nopubkey}; #- get gpg-pubkey signature. if (!$options{nopubkey}) { - $urpm->lock_rpm_db('exclusive'); + urpm::sys::lock_rpm_db($urpm, 'exclusive'); $urpm->{keys} or $urpm->parse_pubkeys(root => $urpm->{root}); } #- lock database if allowed. - $urpm->lock_urpmi_db('exclusive') if !$options{nolock}; + urpm::sys::lock_urpmi_db($urpm, 'exclusive') if !$options{nolock}; #- examine each medium to see if one of them needs to be updated. #- if this is the case and if not forced, try to use a pre-calculated @@ -1943,8 +1940,8 @@ sub update_media { write_MD5SUM($urpm); } - $options{nolock} or $urpm->unlock_urpmi_db; - $options{nopubkey} or $urpm->unlock_rpm_db; + $options{nolock} or urpm::sys::unlock_urpmi_db($urpm); + $options{nopubkey} or urpm::sys::unlock_rpm_db($urpm); } #- clean params and depslist computation zone. @@ -2494,64 +2491,18 @@ sub download_source_packages { my %sources = %$local_sources; my %error_sources; - $urpm->lock_urpmi_db('exclusive') if !$options{nolock}; + urpm::sys::lock_urpmi_db($urpm, 'exclusive') if !$options{nolock}; $urpm->copy_packages_of_removable_media($list, \%sources, $options{ask_for_medium}) or return; $urpm->download_packages_of_distant_media($list, \%sources, \%error_sources, %options); - $urpm->unlock_urpmi_db unless $options{nolock}; + urpm::sys::unlock_urpmi_db($urpm) unless $options{nolock}; %sources, %error_sources; } -#- lock policy concerning chroot : -# - lock rpm db in chroot -# - lock urpmi db in / -sub _lock { - my ($urpm, $fh_ref, $file, $b_exclusive) = @_; - #- avoid putting a require on Fcntl ':flock' (which is perl and not perl-base). - my ($LOCK_SH, $LOCK_EX, $LOCK_NB) = (1, 2, 4); - if ($b_exclusive) { - #- lock urpmi database, but keep lock to wait for an urpmi.update to finish. - } else { - #- create the .LOCK file if needed (and if possible) - -e $file or open(my $_f, ">", $file); - - #- lock urpmi database, if the LOCK file doesn't exists no share lock. - } - my ($sense, $mode) = $b_exclusive ? ('>', $LOCK_EX) : ('<', $LOCK_SH); - open $$fh_ref, $sense, $file or return; - flock $$fh_ref, $mode|$LOCK_NB or $urpm->{fatal}(7, N("urpmi database locked")); -} - -sub lock_rpm_db { - my ($urpm, $b_exclusive) = @_; - _lock($urpm, \$RPMLOCK_FILE, "$urpm->{root}/$urpm->{statedir}/.RPMLOCK", $b_exclusive); -} -sub lock_urpmi_db { - my ($urpm, $b_exclusive) = @_; - _lock($urpm, \$LOCK_FILE, "$urpm->{statedir}/.LOCK", $b_exclusive); -} #- deprecated sub exlock_urpmi_db { my ($urpm) = @_; - lock_urpmi_db($urpm, 'exclusive'); -} - -sub _unlock { - my ($fh_ref) = @_; - #- avoid putting a require on Fcntl ':flock' (which is perl and not perl-base). - my $LOCK_UN = 8; - #- now everything is finished. - #- release lock on database. - flock $$fh_ref, $LOCK_UN; - close $$fh_ref; -} -sub unlock_rpm_db { - my ($_urpm) = @_; - _unlock(\$RPMLOCK_FILE); -} -sub unlock_urpmi_db { - my ($_urpm) = @_; - _unlock(\$LOCK_FILE); + urpm::sys::lock_urpmi_db($urpm, 'exclusive'); } #- $list is a [ { pkg_id1 => url1, ... }, { ... }, ... ] diff --git a/urpm/sys.pm b/urpm/sys.pm index 9defc2f5..313cf730 100644 --- a/urpm/sys.pm +++ b/urpm/sys.pm @@ -4,6 +4,8 @@ package urpm::sys; use strict; use warnings; +use urpm::util; +use urpm::msg; use POSIX (); (our $VERSION) = q($Revision$) =~ /(\d+)/; @@ -13,10 +15,9 @@ use POSIX (); sub find_mntpoints { my ($dir, $infos) = @_; my (%fstab, @mntpoints); - local ($_); + #- read /etc/fstab and check for existing mount point. - open my $f, "/etc/fstab" or return (); - while (<$f>) { + foreach (cat_("/etc/fstab")) { next if /^\s*#/; my ($device, $mntpoint, $fstype, $options) = m!^\s*(\S+)\s+(/\S+)\s+(\S+)\s+(\S+)! or next; @@ -35,9 +36,7 @@ sub find_mntpoints { } } } - close $f; - open $f, "/etc/mtab" or return (); - while (<$f>) { + foreach (cat_("/etc/mtab")) { my ($device, $mntpoint, $fstype, $options) = m!^\s*(\S+)\s+(/\S+)\s+(\S+)\s+(\S+)! or next; $mntpoint =~ s,/+,/,g; $mntpoint =~ s,/$,,; @@ -55,11 +54,12 @@ sub find_mntpoints { } } } - close $f; + #- try to follow symlink, too complex symlink graph may not be seen. #- check the possible mount point. my @paths = split '/', $dir; my $pdir = ''; + local $_; while (defined ($_ = shift @paths)) { length($_) or next; $pdir .= "/$_"; @@ -93,25 +93,25 @@ sub find_mntpoints { @mntpoints; } +sub proc_mounts() { + my @l = cat_('/proc/mounts') or warn "Can't read /proc/mounts: $!\n"; + @l; +} + #- returns the first unused loop device, or an empty string if none is found. sub first_free_loopdev () { - open my $mounts, '/proc/mounts' or do { warn "Can't read /proc/mounts: $!\n"; return 1 }; my %loopdevs = map { $_ => 1 } grep { ! -d $_ } glob('/dev/loop*'); - local *_; - while (<$mounts>) { + foreach (proc_mounts()) { (our $dev) = split ' '; delete $loopdevs{$dev} if $dev =~ m!^/dev/loop!; } - close $mounts; my @l = keys %loopdevs; @l ? $l[0] : ''; } sub trim_until_d { my ($dir) = @_; - open my $mounts, '/proc/mounts' or do { warn "Can't read /proc/mounts: $!\n"; return $dir }; - local $_; - while (<$mounts>) { + foreach (proc_mounts()) { #- fail if an iso is already mounted m!^/dev/loop! and return $dir; } @@ -121,9 +121,7 @@ sub trim_until_d { #- checks if the main filesystems are writeable for urpmi to install files in sub check_fs_writable () { - open my $mounts, '/proc/mounts' or do { warn "Can't read /proc/mounts: $!\n"; return 1 }; - local *_; - while (<$mounts>) { + foreach (proc_mounts()) { (undef, our $mountpoint, undef, my $opts) = split ' '; if ($opts =~ /(?:^|,)ro(?:,|$)/ && $mountpoint =~ m!^(/|/usr|/s?bin)\z!) { return 0; @@ -147,7 +145,7 @@ sub apply_delta_rpm { if ($o_pkg) { $rpm = $o_pkg->name . '-' . $o_pkg->version . '-' . $o_pkg->release . '.' . $o_pkg->arch . '.rpm'; } else { - $rpm = qx(rpm -qp --qf '%{name}-%{version}-%{release}.%{arch}.rpm' '$deltarpm'); + $rpm = `rpm -qp --qf '%{name}-%{version}-%{release}.%{arch}.rpm' '$deltarpm'`; } $rpm or return 0; $rpm = $o_dir . '/' . $rpm; @@ -157,12 +155,12 @@ sub apply_delta_rpm { } our $tempdir_template = '/tmp/urpm.XXXXXX'; -sub mktempdir { +sub mktempdir() { my $tmpdir; eval { require File::Temp }; if ($@) { #- fall back to external command (File::Temp not in perl-base) - $tmpdir = qx(mktemp -d $tempdir_template); + $tmpdir = `mktemp -d $tempdir_template`; chomp $tmpdir; } else { $tmpdir = File::Temp::tempdir($tempdir_template); @@ -175,7 +173,7 @@ sub fix_fd_leak() { opendir my $dirh, "/proc/$$/fd" or return undef; my @fds = grep { /^(\d+)$/ && $1 > 2 } readdir $dirh; closedir $dirh; - for (@fds) { + foreach (@fds) { my $link = readlink("/proc/$$/fd/$_"); $link or next; next if $link =~ m!^/(usr|dev)/! || $link !~ m!^/!; @@ -183,6 +181,57 @@ sub fix_fd_leak() { } } +#- lock policy concerning chroot : +# - lock rpm db in chroot +# - lock urpmi db in / +sub _lock { + my ($urpm, $fh_ref, $file, $b_exclusive) = @_; + #- avoid putting a require on Fcntl ':flock' (which is perl and not perl-base). + my ($LOCK_SH, $LOCK_EX, $LOCK_NB) = (1, 2, 4); + if ($b_exclusive) { + #- lock urpmi database, but keep lock to wait for an urpmi.update to finish. + } else { + #- create the .LOCK file if needed (and if possible) + -e $file or open(my $_f, ">", $file); + + #- lock urpmi database, if the LOCK file doesn't exists no share lock. + } + my ($sense, $mode) = $b_exclusive ? ('>', $LOCK_EX) : ('<', $LOCK_SH); + open $$fh_ref, $sense, $file or return; + flock $$fh_ref, $mode|$LOCK_NB or $urpm->{fatal}(7, N("urpmi database locked")); +} + + +my $RPMLOCK_FILE; +my $LOCK_FILE; + +sub lock_rpm_db { + my ($urpm, $b_exclusive) = @_; + _lock($urpm, \$RPMLOCK_FILE, "$urpm->{root}/$urpm->{statedir}/.RPMLOCK", $b_exclusive); +} +sub lock_urpmi_db { + my ($urpm, $b_exclusive) = @_; + _lock($urpm, \$LOCK_FILE, "$urpm->{statedir}/.LOCK", $b_exclusive); +} + +sub _unlock { + my ($fh_ref) = @_; + #- avoid putting a require on Fcntl ':flock' (which is perl and not perl-base). + my $LOCK_UN = 8; + #- now everything is finished. + #- release lock on database. + flock $$fh_ref, $LOCK_UN; + close $$fh_ref; +} +sub unlock_rpm_db { + my ($_urpm) = @_; + _unlock(\$RPMLOCK_FILE); +} +sub unlock_urpmi_db { + my ($_urpm) = @_; + _unlock(\$LOCK_FILE); +} + 1; __END__ diff --git a/urpmf b/urpmf index 698a7d8c..8b42bc4c 100755 --- a/urpmf +++ b/urpmf @@ -193,7 +193,7 @@ if ($env) { #- lock to avoid concurrent media updates, #- but don't die if it doesn't work local $urpm->{fatal} = sub { printf STDERR "%s\n", $_[1] }; - $urpm->lock_urpmi_db; + urpm::sys::lock_urpmi_db($urpm); } my $need_hdlist = grep { $usedtags{$_} } qw( buildhost @@ -218,7 +218,7 @@ $urpm->configure( callback => $callback, need_hdlist => $need_hdlist, ); -$urpm->unlock_urpmi_db; +urpm::sys::unlock_urpmi_db($urpm); if ($need_hdlist) { # @hdmedia is the list of all media searched that use hdlists diff --git a/urpmi b/urpmi index 4baeaee3..5a59197f 100755 --- a/urpmi +++ b/urpmi @@ -330,8 +330,8 @@ if (exists $urpm->{options}{'priority-upgrade'} && $urpm->{options}{'priority-up } unless ($env || $nolock) { - $urpm->lock_rpm_db('exclusive'); - $urpm->lock_urpmi_db; + urpm::sys::lock_rpm_db($urpm, 'exclusive'); + urpm::sys::lock_urpmi_db($urpm); } #- should we ignore arch compatibility @@ -820,8 +820,8 @@ if ($nok) { } unless ($env || $nolock) { - $urpm->unlock_urpmi_db; - $urpm->unlock_rpm_db; + urpm::sys::unlock_urpmi_db($urpm); + urpm::sys::unlock_rpm_db($urpm); #- try to umount removable device which may have been mounted. $urpm->try_umounting_removables; diff --git a/urpmq b/urpmq index e0d98191..1fc76dc9 100755 --- a/urpmq +++ b/urpmq @@ -136,8 +136,8 @@ if ($urpm::args::options{env}) { if ($urpm::args::options{ignorearch}) { urpm::shunt_ignorearch() } $urpm::args::options{upgrade} && !$urpm::args::options{env} && !$urpm::args::options{nolock} - and $urpm->lock_rpm_db; -$urpm->lock_urpmi_db if !$urpm::args::options{nolock}; + and urpm::sys::lock_rpm_db($urpm); +urpm::sys::lock_urpmi_db($urpm) if !$urpm::args::options{nolock}; $urpm->configure( nocheck_access => 1, nodepslist => $urpm::args::options{nodepslist}, @@ -424,9 +424,9 @@ if ($urpm::args::options{list_aliases}) { exit 0; } } -$urpm::args::options{nolock} or $urpm->unlock_urpmi_db; +$urpm::args::options{nolock} or urpm::sys::unlock_urpmi_db($urpm); $urpm::args::options{upgrade} && !$urpm::args::options{env} && !$urpm::args::options{nolock} - and $urpm->unlock_rpm_db; + and urpm::sys::unlock_rpm_db($urpm); #- print sub for query. my $query_sub = sub { -- cgit v1.2.1