diff options
-rw-r--r-- | man/C/urpmi.addmedia.8 | 15 | ||||
-rw-r--r-- | urpm.pm | 50 | ||||
-rw-r--r-- | urpm/sys.pm | 20 |
3 files changed, 66 insertions, 19 deletions
diff --git a/man/C/urpmi.addmedia.8 b/man/C/urpmi.addmedia.8 index c6c6ff2f..75506d51 100644 --- a/man/C/urpmi.addmedia.8 +++ b/man/C/urpmi.addmedia.8 @@ -3,7 +3,7 @@ .SH NAME urpmi.addmedia \- adds a new rpm medium to be used by urpmi .SH SYNOPSIS -.B urpmi.addmedia [\fIoptions\fP] <\fIname\fP> <\fIurl\fP> +.B urpmi.addmedia [\fIoptions\fP] <\fIname\fP> <\fIurl\fP> [with <\fIhdlist\fP>] .SH DESCRIPTION urpmi.addmedia tells urpmi that it can find new rpms at the specified location. Currently supported media types are: local drives, removable drives (such as @@ -16,7 +16,8 @@ http: Where <\fIname\fP> is your reference for the medium (e.g. "updates"). <\fIname\fP> is optional if \fB--distrib\fP is given in \fIoptions\fP. .br -<\fIhost\fP>/<\fIpath\fP> is the location of the rpm directory on the net. +<\fIhost\fP>/<\fIpath\fP> is the location of the media directory on the net +(e.g. media/main). .br <\fIrelative path of hdlist\fP> is the pathname where to find the hdlist of the rpms. The location is given relative to <\fIpath\fP>. @@ -56,13 +57,17 @@ Local drive or NFS: .IP "\fB urpmi.addmedia [\fIoptions\fP] <\fIname\fP> file://<\fIpath\fP>\fP [with <\fIrelative path of synthesis|hdlist\fP>]\fP" Where <\fIname\fP> is your reference for the medium (e.g. Myrpms). .br -<\fIpath\fP> is the location of the rpm directory on your machine. +<\fIpath\fP> is the location of the media directory on your machine +(e.g. media/main). .PP Removable device: .br .IP "\fB urpmi.addmedia [\fIoptions\fP] <\fIname\fP> removable://<\fIpath\fP>\fP [with <\fIrelative path of synthesis|hdlist\fP>]\fP" -<\fIpath\fP> is the location of the rpm directory on your machine when the -removable device is mounted. +<\fIpath\fP> is the location of the media directory on your machine when the +removable device is mounted. This works for removable drives, but also for ISO +images mounted on a loop device. urpmi will then be able to re-mount the ISO +image to the specified path (but the ISO image must be mounted when you run +\fBurpmi.addmedia\fP). .PP .SH OPTIONS .IP "\fB\--wget\fP" @@ -318,10 +318,17 @@ sub probe_medium { $medium; } +#- returns the removable device name if it corresponds to an iso image, '' otherwise +sub is_iso { + my ($removable_dev) = @_; + $removable_dev && $removable_dev =~ /\.iso$/i ? $removable_dev : ''; +} + #- probe device associated with a removable device. sub probe_removable_device { my ($urpm, $medium) = @_; + #- try to find device name in url scheme if ($medium->{url} && $medium->{url} =~ /^removable_?([^_:]*)(?:_[^:]*)?:/) { $medium->{removable} ||= $1 && "/dev/$1"; } else { @@ -343,6 +350,8 @@ sub probe_removable_device { $infos{$mntpoints[-1]}{device}, $medium->{name})); } $medium->{removable} = $infos{$mntpoints[-1]}{device}; + } elsif (is_iso($medium->{removable})) { + $urpm->{log}(N("Medium \"%s\" is an ISO image, will be mounted on-the-fly", $medium->{name})); } else { $urpm->{error}(N("unable to retrieve pathname for removable medium \"%s\"", $medium->{name})); } @@ -1036,11 +1045,14 @@ sub update_media { my $with_hdlist_dir = reduce_pathname($dir . ($medium->{with_hdlist} ? "/$medium->{with_hdlist}" : "/..")); #- the directory given does not exist and may be accessible - #- by mounting some other. try to figure out these directory and - #- mount everything necessary. - $urpm->try_mounting($options{force} < 2 && ($options{probe_with} || $medium->{with_hdlist}) ? - $with_hdlist_dir : $dir) or - $urpm->{error}(N("unable to access medium \"%s\", + #- by mounting some other directory. Try to figure it out and mount + #- mount everything that might be necessary. + $urpm->try_mounting( + $options{force} < 2 && ($options{probe_with} || $medium->{with_hdlist}) + ? $with_hdlist_dir : $dir, + #- in case of an iso image, pass its name + is_iso($medium->{removable}), + ) or $urpm->{error}(N("unable to access medium \"%s\", this could happen if you mounted manually the directory when creating the medium.", $medium->{name})), next; #- try to probe for possible with_hdlist parameter, unless @@ -1937,18 +1949,28 @@ sub clean { } } -#- check for necessity of mounting some directory to get access sub try_mounting { my ($urpm, $dir, $removable) = @_; my %infos; - $dir = reduce_pathname($dir); + my $is_iso = is_iso($removable); + my @mntpoints = $is_iso + #- note: for isos, we don't parse the fstab because it might not be declared in it. + #- so we try to remove suffixes from the dir name until the dir exists + ? ($dir = urpm::sys::trim_until_d($dir)) + : urpm::sys::find_mntpoints(($dir = reduce_pathname($dir)), \%infos); foreach (grep { ! $infos{$_}{mounted} && $infos{$_}{fs} ne 'supermount'; - } urpm::sys::find_mntpoints($dir, \%infos)) + } @mntpoints) { $urpm->{log}(N("mounting %s", $_)); - `mount '$_' 2>/dev/null`; + if ($is_iso) { + #- to mount an iso image, grab the first loop device + my $loopdev = urpm::sys::first_free_loopdev(); + $loopdev and `mount '$removable' $_ -t iso9660 -o loop=$loopdev`; + } else { + `mount '$_' 2>/dev/null`; + } $removable && $infos{$_}{fs} ne 'supermount' and $urpm->{removable_mounted}{$_} = undef; } -e $dir; @@ -2550,14 +2572,14 @@ sub copy_packages_of_removable_media { my ($id, $device, $copy) = @_; my $medium = $urpm->{media}[$id]; if (my ($dir) = $medium->{url} =~ m!^(?:(?:removable[^:]*|file):/)?(/.*)!) { - #- the directory given does not exist or may be accessible - #- by mounting some other. Try to figure out these directories and + #- the directory given does not exist and may be accessible + #- by mounting some other directory. Try to figure it out and mount #- mount everything that might be necessary. - while ($check_notfound->($id, $dir, 'removable')) { + while ($check_notfound->($id, $dir, is_iso($medium->{removable}) || 'removable')) { $options{ask_for_medium} or $urpm->{fatal}(4, N("medium \"%s\" is not selected", $medium->{name})); $urpm->try_umounting($dir); system("eject", $device); - $options{ask_for_medium}(remove_internal_name($medium->{name}), $medium->{removable}) or - $urpm->{fatal}(4, N("medium \"%s\" is not selected", $medium->{name})); + $options{ask_for_medium}(remove_internal_name($medium->{name}), $medium->{removable}) + or $urpm->{fatal}(4, N("medium \"%s\" is not selected", $medium->{name})); } if (-e $dir) { while (my ($i, $url) = each %{$list->[$id]}) { diff --git a/urpm/sys.pm b/urpm/sys.pm index 1ccc3b6e..8a5e0739 100644 --- a/urpm/sys.pm +++ b/urpm/sys.pm @@ -107,6 +107,26 @@ sub find_mntpoints { @mntpoints; } +#- 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>) { + (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) = @_; + while ($dir && !-d $dir) { $dir =~ s,/[^/]*$,, } + $dir; +} + #- 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 }; |