Hello community, here is the log from the commit of package perl-Bootloader checked in at Tue Mar 27 01:45:56 CEST 2007. -------- --- perl-Bootloader/perl-Bootloader.changes 2007-02-28 11:51:17.000000000 +0100 +++ /mounts/work_src_done/STABLE/perl-Bootloader/perl-Bootloader.changes 2007-03-26 19:07:40.000000000 +0200 @@ -1,0 +2,73 @@ +Mon Mar 26 19:06:17 CEST 2007 - aosthof@suse.de + +- Corrected mechanism for removal of sections in Tools.pm - part 2 + +------------------------------------------------------------------- +Mon Mar 26 17:54:54 CEST 2007 - aosthof@suse.de + +- Corrected mechanism for removal of sections in Tools.pm + +------------------------------------------------------------------- +Mon Mar 26 13:57:04 CEST 2007 - sf@suse.de + +- fixed typo + +------------------------------------------------------------------- +Mon Mar 26 11:23:35 CEST 2007 - aosthof@suse.de + +- Corrected mechanism for adapting default value in Tools.pm + +------------------------------------------------------------------- +Fri Mar 23 19:25:14 CET 2007 - aosthof@suse.de + +- Commented out wrong code in update-bootloader and Tools.pm + +------------------------------------------------------------------- +Fri Mar 23 14:26:58 CET 2007 - aosthof@suse.de + +- Removed function AddNewImageSection() because it's obsolete +- Corrected resolution of symlinks in Tools.pm +- Corrected deletion of obsolete entries in Tools.pm +- Removed commented out code sections + +------------------------------------------------------------------- +Thu Mar 22 17:11:47 CET 2007 - aosthof@suse.de + +- Added mechanism to name boot entries in a unique way +- Added mechanism to resolve symlinks in boot entries to be able to + remove them properly if needed +- Corrected naming scheme appropriate to corresponding bootloader + +------------------------------------------------------------------- +Tue Mar 20 12:41:23 CET 2007 - sf@suse.de + +- implemented DM RAID functionality, using devicemapper instead + of udev (to "emulate" yast2-storage) + +------------------------------------------------------------------- +Mon Mar 19 18:59:06 CET 2007 - aosthof@suse.de + +- Added mechanism to create failsafe boot entries appropriately +- Corrected handling for default boot entries + +------------------------------------------------------------------- +Wed Mar 14 09:47:40 CET 2007 - aosthof@suse.de + +- New kernels will now be put on top of menu.lst + +------------------------------------------------------------------- +Tue Mar 13 16:16:56 CET 2007 - aosthof@suse.de + +- Display labels of boot entries correctly, e.g. "openSUSE 10.2 -- + Kernel-2.6.20-9-default" (#252911) +- Fixed handling concerning which kernel will be the default entry + in bootloader menu (#252911) + +------------------------------------------------------------------- +Tue Mar 13 13:09:18 CET 2007 - aosthof@suse.de + +- Following changes merged from branch SLES10-SP1 to trunk: +- Fixed removal of obsolete entries in /boot/grub/menu.lst +- Exluded kernel-debug from getting default (#241370) + +------------------------------------------------------------------- Old: ---- perl-Bootloader-0.4.11.tar.bz2 New: ---- perl-Bootloader-0.4.13.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Bootloader.spec ++++++ --- /var/tmp/diff_new_pack.Wc7275/_old 2007-03-27 01:45:47.000000000 +0200 +++ /var/tmp/diff_new_pack.Wc7275/_new 2007-03-27 01:45:47.000000000 +0200 @@ -1,5 +1,5 @@ # -# spec file for package perl-Bootloader (Version 0.4.11) +# spec file for package perl-Bootloader (Version 0.4.13) # # Copyright (c) 2007 SUSE LINUX Products GmbH, Nuernberg, Germany. # This file and all modifications and additions to the pristine @@ -11,8 +11,8 @@ # norootforbuild Name: perl-Bootloader -Version: 0.4.11 -Release: 3 +Version: 0.4.13 +Release: 1 Requires: perl >= %{perl_version} Requires: perl-gettext Requires: mdadm e2fsprogs @@ -63,6 +63,43 @@ /usr/lib/bootloader %changelog +* Mon Mar 26 2007 - aosthof@suse.de +- Corrected mechanism for removal of sections in Tools.pm - part 2 +* Mon Mar 26 2007 - aosthof@suse.de +- Corrected mechanism for removal of sections in Tools.pm +* Mon Mar 26 2007 - sf@suse.de +- fixed typo +* Mon Mar 26 2007 - aosthof@suse.de +- Corrected mechanism for adapting default value in Tools.pm +* Fri Mar 23 2007 - aosthof@suse.de +- Commented out wrong code in update-bootloader and Tools.pm +* Fri Mar 23 2007 - aosthof@suse.de +- Removed function AddNewImageSection() because it's obsolete +- Corrected resolution of symlinks in Tools.pm +- Corrected deletion of obsolete entries in Tools.pm +- Removed commented out code sections +* Thu Mar 22 2007 - aosthof@suse.de +- Added mechanism to name boot entries in a unique way +- Added mechanism to resolve symlinks in boot entries to be able to + remove them properly if needed +- Corrected naming scheme appropriate to corresponding bootloader +* Tue Mar 20 2007 - sf@suse.de +- implemented DM RAID functionality, using devicemapper instead + of udev (to "emulate" yast2-storage) +* Mon Mar 19 2007 - aosthof@suse.de +- Added mechanism to create failsafe boot entries appropriately +- Corrected handling for default boot entries +* Wed Mar 14 2007 - aosthof@suse.de +- New kernels will now be put on top of menu.lst +* Tue Mar 13 2007 - aosthof@suse.de +- Display labels of boot entries correctly, e.g. "openSUSE 10.2 -- + Kernel-2.6.20-9-default" (#252911) +- Fixed handling concerning which kernel will be the default entry + in bootloader menu (#252911) +* Tue Mar 13 2007 - aosthof@suse.de +- Following changes merged from branch SLES10-SP1 to trunk: +- Fixed removal of obsolete entries in /boot/grub/menu.lst +- Exluded kernel-debug from getting default (#241370) * Wed Feb 28 2007 - aosthof@suse.de - Fixed a perl warning bug in Core/GRUB.pm (#248211) * Wed Feb 21 2007 - aosthof@suse.de ++++++ bootloader_entry ++++++ --- perl-Bootloader/bootloader_entry 2007-02-14 11:49:53.000000000 +0100 +++ /mounts/work_src_done/STABLE/perl-Bootloader/bootloader_entry 2007-03-13 16:58:55.000000000 +0100 @@ -78,16 +78,30 @@ set -- ${1#xen} opt_xen_kernel=--xen-kernel=/boot/xen${1:+-$1}.gz - # Add the new bootloader entry + # Add the new bootloader entry (xen kernel) update_bootloader --image /boot/$image \ --initrd /boot/$initrd \ + --default \ --add \ --force $opt_xen_kernel \ --name "Kernel-$release" # Run the bootloader (e.g., lilo). update_bootloader --refresh + ;; + + (debug) + # Add the new bootloader entry (debug kernel) + update_bootloader --image /boot/$image \ + --initrd /boot/$initrd \ + --add \ + --force \ + --name "Kernel-$release" + + # Run the bootloader (e.g., lilo). + update_bootloader --refresh ;; + (*) # Add the new bootloader entry update_bootloader --image /boot/$image \ ++++++ perl-Bootloader-0.4.11.tar.bz2 -> perl-Bootloader-0.4.13.tar.bz2 ++++++ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/perl-Bootloader-0.4.11/lib/Bootloader/Core/GRUB.pm new/perl-Bootloader-0.4.13/lib/Bootloader/Core/GRUB.pm --- old/perl-Bootloader-0.4.11/lib/Bootloader/Core/GRUB.pm 2007-02-28 11:51:17.000000000 +0100 +++ new/perl-Bootloader-0.4.13/lib/Bootloader/Core/GRUB.pm 2007-03-13 13:12:31.000000000 +0100 @@ -22,6 +22,8 @@ C<< $quoted = Bootloader::Core::GRUB->Quote ($text, $when); >> +C<< $unix_dev = Bootloader::Core::GRUB->UnixFile2UnixDev ($unix_file); >> + C<< $unix_dev = Bootloader::Core::GRUB->GrubDev2UnixDev ($grub_dev); >> C<< $grub_dev = Bootloader::Core::GRUB->UnixDev2GrubDev ($unix_dev); >> @@ -318,6 +320,53 @@ } =item +C<< $unix_dev = Bootloader::Core::GRUB->UnixFile2UnixDev ($unix_file); >> + +Detects the underlying partition (e.g. '/dev/sda1') a given UNIX file +(e.g. '/boot') is located on. Takes a UNIX file as argument and returns +the corresponding UNIX device. + +=cut + +# string UnixFile2UnixDev (string unix_file) +sub UnixFile2UnixDev { + my $self = shift; + my $unix_file = shift; + my $unix_dev = ""; + + # Collect information about device using "stat" + my ($temp_unix_dev, undef, undef, undef, undef, undef, undef, undef, + undef, undef, undef, undef, undef) + = stat ($unix_file); + + # Open "/proc/partitions" to look up the partition corresponding to + # major and minor device numbers + open (PARTITIONS, "GrubDev2UnixDev ($grub_dev); >> Translates the GRUB device (eg. '(hd0,0)') to UNIX device (eg. '/dev/hda1'). @@ -1557,8 +1606,8 @@ } elsif ($key eq "default") { - $line_ref->{"value"} = - $self->IndexOfSection (delete $globinfo{$key}, $sections_ref) || 0; + $line_ref->{"value"} = $self->IndexOfSection ( + delete $globinfo{$key}, $sections_ref) || 0; } elsif ($key eq "password") { diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/perl-Bootloader-0.4.11/lib/Bootloader/Library.pm new/perl-Bootloader-0.4.13/lib/Bootloader/Library.pm --- old/perl-Bootloader-0.4.11/lib/Bootloader/Library.pm 2006-10-31 16:16:33.000000000 +0100 +++ new/perl-Bootloader-0.4.13/lib/Bootloader/Library.pm 2007-03-13 13:12:31.000000000 +0100 @@ -63,6 +63,8 @@ C<< $status = Bootloader::Library->SetDeviceMapping ($device_map_ref); >> +C<< $grub_dev = Bootloader::Library->UnixFile2GrubDev ($unix_file); >> + =head1 DESCRIPTION =over 2 @@ -820,6 +822,28 @@ return $self->SetSettings (\%settings) } +=item +C<< $grub_dev = Bootloader::Library->UnixFile2GrubDev ($unix_file); >> + +Detects the underlying partition (e.g. '/dev/sda1') a given UNIX file +(e.g. '/boot') is located on and translates it to the corresponding GRUB +device (e.g. '(hd0,0)'). Takes a UNIX file as argument and returns the +corresponding GRUB device. + +=cut + +# string UnixFile2GrubDev (string unix_file) +sub UnixFile2GrubDev { + my $self = shift; + my $unix_file = shift; + my $loader = $self->{loader} || return undef; + + my $unix_dev = $loader->UnixFile2UnixDev ($unix_file); + my $grub_dev = $loader->UnixDev2GrubDev ($unix_dev); + + return $grub_dev; +} + 1; # diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/perl-Bootloader-0.4.11/lib/Bootloader/Tools.pm new/perl-Bootloader-0.4.13/lib/Bootloader/Tools.pm --- old/perl-Bootloader-0.4.11/lib/Bootloader/Tools.pm 2006-09-29 14:22:24.000000000 +0200 +++ new/perl-Bootloader-0.4.13/lib/Bootloader/Tools.pm 2007-03-26 19:07:40.000000000 +0200 @@ -20,14 +20,34 @@ C<< $part_ref = Bootloader::Tools::ReadPartitions (); >> +C<< $numDM = Bootloader::Tools::DMRaidAvailable (); >> + +C<< $part_ref = Bootloader::Tools::ReadDMRaidPartitions (); >> + +C<< $part_ref = Bootloader::Tools::ReadDMRaidDisks (); >> + +C<< Bootloader::Tools::IsDMRaidSlave ($kernel_disk); >> + +C<< Bootloader::Tools::IsDMDevice($dev); >> + +C<< $dm_dev = Bootloader::Udev2DMDev($udevdevice); >> + +C<< $udev_dev = Bootloader::Tools::DMDev2Udev($dmdev); >> + +C<< $majmin = Bootloader::Tools::DMDev2MajMin($dmdev); >> + +C<< $majmin = Bootloader::Tools::Udev2MajMin($udev); >> + +C<< $udev_dev = Bootloader::Tools::MajMin2Udev($majmin); >> + +C<< $dm_dev = Bootloader::Tools::MajMin2DMDev($majmin); >> + C<< $md_ref = Bootloader::Tools::ReadRAID1Arrays (); >> C<< $loader = Bootloader::Tools::GetBootloader (); >> C<< Bootloader::Tools::InitLibrary (); >> -C<< Bootloader::Tools::AddNewImageSection ($name, $image, $initrd, $default); >> - C<< Bootloader::Tools::CountImageSections ($image); >> C<< Bootloader::Tools::RemoveImageSections ($image); >> @@ -50,7 +70,7 @@ C<< Bootloader::Tools::AddSection($name, @params); >> -C<< Bootloader::Tools::RemoveSection($name); >> +C<< Bootloader::Tools::RemoveSections($name); >> =head1 DESCRIPTION @@ -65,10 +85,10 @@ use base 'Exporter'; our @EXPORT = qw(InitLibrary CountImageSections CountSections - RemoveImageSections RemoveSections GetDefaultImage + RemoveImageSections GetDefaultImage GetDefaultInitrd GetBootloader UpdateBootloader GetGlobals SetGlobals - GetSectionList GetSection AddSection RemoveSection + GetSectionList GetSection AddSection RemoveSections ); use Bootloader::Library; @@ -187,32 +207,347 @@ closedir BLOCK_DEVICES; my @devices = (); + # Add DM RAID Partitions to @devices + if (DMRaidAvailable()){ + my $dev_ref = ReadDMRaidPartitions(); + push (@devices, @{$dev_ref}); + + } + foreach my $disk (@disks) { my $dev_disk = Udev2Dev ($disk); - opendir(BLOCK_DEVICES, "$sb/$disk") || - die ("Failed to open dir $sb/$disk"); - my @parts = grep { - !m/^\./ and -d "$sb/$disk/$_" and -f "$sb/$disk/$_/dev" - } readdir (BLOCK_DEVICES); - closedir BLOCK_DEVICES; + if (!IsDMDevice($disk) && !IsDMRaidSlave($disk)){ + opendir(BLOCK_DEVICES, "$sb/$disk") || + die ("Failed to open dir $sb/$disk"); + + my @parts = grep { + !m/^\./ and -d "$sb/$disk/$_" and -f "$sb/$disk/$_/dev" + } readdir (BLOCK_DEVICES); + closedir BLOCK_DEVICES; - foreach my $part (@parts) - { - chomp ($part); - $part = Udev2Dev ("$disk/$part"); - my $index = substr ($part, length ($dev_disk)); - while (length ($index) > 0 && substr ($index, 0, 1) !~ /[0-9]/) + foreach my $part (@parts) { - $index = substr ($index, 1); - } - push @devices, [$part, $dev_disk, $index]; + chomp ($part); + $part = Udev2Dev ("$disk/$part"); + my $index = substr ($part, length ($dev_disk)); + while (length ($index) > 0 && substr ($index, 0, 1) !~ /[0-9]/) + { + $index = substr ($index, 1); + } + push @devices, [$part, $dev_disk, $index]; + } } } return \@devices; } =item +C<< Bootloader::Tools::DMRaidAvailable (); >> + +Tests wether DMRAID is available. +Return 0 if no device, 1 if there are any. + +=cut + +sub DMRaidAvailable (){ + my $dm_devices = qx{dmsetup info -c --noheadings -o uuid}; + chomp($dm_devices); + + if ("$dm_devices" eq "No devices found"){ + return 0; + } + return 1; +} + +=item +C<< $part_ref = Bootloader::Tools::ReadDMRaidPartitions (); >> + +reads partitions belonging to a Devicemapper RAID device. +needed to be able to put get the correct translation +into Grub notation +DMRaid Devices look like: +dmraid-<strange name> + +DMRaid Partitions look like: +partX-dmraid-<strange name> + + +=cut + +#FIXME: this has to be done through Storage +sub ReadDMRaidPartitions() { + + my @dmdisks = (); + my @dmparts = (); + my $dmdev; + + + open(DMDEV, "dmsetup info -c --noheadings -o name |") || die ("FOOBAR"); + + while(<DMDEV>){ + $dmdev = $_; + chomp($dmdev); + + #FIXME: I should not need to do this twice + if ($dmdev !~ m/part/){ + # $dmdev is the base device + $dmdev = "/dev/mapper/" . $dmdev; + push @dmdisks, $dmdev; + } + else{ #FIXME: need to check what needs to be removed + $dmdev = "/dev/mapper/" . $dmdev; + push @dmparts, $dmdev; + } + } + close DMDEV; + my @devices = (); + my $dmpart; + my $tmp_part; + + foreach $dmdev (@dmdisks){ + foreach $dmpart (@dmparts){ + my $index = substr ($dmpart, length($dmpart)-1,1); + + while (length ($index) > 0 && substr ($index, 0, 1) !~ /[0-9]/) + { + $index = substr ($index, 1); + } + push @devices, [$dmpart, $dmdev, $index]; + } + } + return \@devices; +} + +=item +C<< $part_ref = Bootloader::Tools::ReadDMRaidDisks (); >> + +returns a refenrence to a list of DMRaid devices + +=cut + +sub ReadDMRaidDisks(){ + + my @dmdisks = (); + my @dmparts = (); + my $dmdev; + + + open(DMDEV, "dmsetup info -c --noheadings -oname |") || die ("FOOBAR"); + + while(<DMDEV>){ + $dmdev = $_; + chomp($dmdev); + + if ($dmdev !~ m/part/){ + # $dmdev is the base device + $dmdev = "/dev/mapper/" . $dmdev; + push @dmdisks, $dmdev; + } + } + return \@dmdisks; +} + +=item +C<< Bootloader::Tools::IsDMRaidSlave ($kernel_disk); >> + +checks wether a kernel_device is part of a DMRAID +returns 1 if yes, 0 if no + +=cut + +sub IsDMRaidSlave(){ + + my $disk = shift; + my $majmin_disk = Udev2MajMin($disk); + my @dmparts = (); + my @dm_devs = qx{dmsetup info -c --noheadings -o name | grep -v part}; + + if ($dm_devs[0] !~ /No devices found/){ + foreach my $dmdisk (@dm_devs){ + my @tables = qx{dmsetup table $dmdisk}; + + foreach my $line (@tables){ + my @content = split(/ /, $line); + + foreach my $majmins (@content){ + if ("$majmins" eq "$majmin_disk"){ + return 1; + } + } + } + } + } + + return 0; +} + +=item + +C<< Bootloader::Tools:IsDMDevice ($device); >> + + returns 1 if $device is a Devicemapper device, + otherwise 0. +=cut + +sub IsDMDevice(){ + my $dev = shift; + + my $cmd = "dmsetup info -c --noheadings -oname $dev"; + if (my $test = qx{$cmd 2>/dev/null}){ + chomp $test; + + if ($dev =~ m/$test/){ + return 1; + } + } + return 0; +} + +=item +C<< $dm_dev = Bootloader::Tools::Udev2DMDev($udevdevice); >> + +takes a udev device (dm-X) +returns the devicemapper device like dmsetup returns + +=cut + +sub Bootloader::Tools::Udev2DMDev(){ + + my $udevd = shift; + my $majmin = Udev2MajMin($udevd); + my $dmdev = MajMin2DMDev($majmin); + + return $dmdev +} + +=item +C<< $udev_dev = Bootloader::Tools::DMDev2Udev($dmdev); >> + +takes a devicemapper device as reported from dmsetup +returns a udev device (dm-X) + +=cut + +sub Bootloader::Tools::DMDev2Udev(){ + + my $dmdev = shift; + my $majmin = DMDev2MajMin($dmdev); + my $udevdev = MajMin2Udev($majmin); + + return $udevdev; +} + +=item +C<< $majmin = Bootloader::Tools::DMDev2MajMin($dmdev); >> + +takes a devicemapper device as reported from dmsetup +returns a string containing major:minor + +=cut + +sub Bootloader::Tools::DMDev2MajMin(){ + + my $dmdev = shift; + my $majmin; + $majmin = qx{dmsetup info -c --noheadings -o major,minor $dmdev}; + + return $majmin; +} + + +=item +C<< $majmin = Bootloader::Tools::Udev2MajMin($udev); >> +takes a udev device as reported from udevinfo +returns a string containing major:minor + +=cut + +sub Bootloader::Tools::Udev2MajMin(){ + + my $udev_dev = shift; + my $majmin; + my $cmd = "udevinfo -qpath -n $udev_dev"; + + if (my $udev_path = qx{$cmd 2>/dev/null}){ + chomp ($udev_path); + $majmin = qx{cat /sys$udev_path/dev}; + } + return $majmin; +} + +=item +C<< $udev_dev = Bootloader::Tools::MajMin2Udev($majmin); >> +takes a string major:minor as reported from udevinfo +returns a string containing the udev device as reported +by udevinfo + +=cut + +sub Bootloader::Tools::MajMin2Udev(){ + +my $majmin = shift; + +my ($major, $minor) = split (/:/, $majmin ); +my $udevdev; +my $sb="/sys/block"; +my $devmajmin; +#print ("Major: $major; Minor: $minor\n"); +opendir (SYSBLOCK, "$sb"); + +foreach my $dirent (readdir(SYSBLOCK)){ + next if $dirent =~ m/^\./; + next if -r "$sb/$dirent/range" and qx{ cat $sb/$dirent/range } == 1; + $devmajmin = qx{cat $sb/$dirent/dev}; + my ($p, undef) = (split(/:/, $devmajmin)); + + if ("$p" eq "$major" ){ + $udevdev = "$sb/$dirent"; + last; + } +} +closedir (SYSBLOCK); +opendir (SYSBLOCK, "$udevdev"); +my $part; + +foreach my $dirent (readdir(SYSBLOCK)){ + next if $dirent =~ m/^\./; + + if (-r "$udevdev/$dirent/dev"){ + my $mm = qx{cat $udevdev/$dirent/dev}; + chomp ($mm); + + if ("$mm" eq "$majmin"){ + $part = $dirent; + last; + } + } +} +closedir (SYSBLOCK); +return $part; + +} + +=item +C<< $dm_dev = Bootloader::Tools::DMDev2MajMin($majmin); >> +takes a string major:minor as reported from udevinfo +returns a string containing the device as reported by +dmsetup + +=cut + +sub Bootloader::Tools::MajMin2DMDev(){ + + my $majmin = shift; + my $dm_name = qx{devmap_name $majmin}; + + return $dm_name; + +} + + + +=item C<< $md_ref = Bootloader::Tools::ReadRAID1Arrays (); >> reads the information about disk MD RAID1 arrays. This data is needed @@ -299,33 +634,6 @@ DumpLog (); } -=item -C<< Bootloader::Tools::AddNewImageSection ($name, $image, $initrd, $default); >> - -Adds a new section to the bootloader menu via one function call (just the -library needs to be initialized before). C<$initrd> and C<$default> are -optional, if C<$default> is defined and nonzero, the new section is marked -as default. - -EXAMPLE: - - Bootloader::Tools::InitLibrary(); - Bootloader::Tools::AddNewImageSection("2.6.11", "/boot/vmlinuz-2.6.11", "/boot/initrd-2.6.11", 1); - Bootloader::Tools::UpdateBootloader(); - -=cut - -sub AddNewImageSection { - my $name = shift; - my $image = shift; - my $initrd = shift; - my $default = shift; - - # old broken stuff - exit 1; -} - - # internal: does section match with set of tags sub match_section { my ($sect_ref, $opt_ref,) = @_; @@ -398,56 +706,6 @@ =item -C<< Bootloader::Tools::RemoveImageSections ($image); >> - -removes all sections in the bootloader menu referring to the -specified kernel. - -EXAMPLE: - - Bootloader::Tools::InitLibrary (); - Bootloader::Tools::RemoveImageSections ("/boot/vmlinuz-2.6.11"); - Bootloader::Tools::UpdateBootloader(); - -=cut - -sub RemoveImageSections { - my $image = shift; - - return unless $image; - RemoveSections(type=>"image", image => $image); -} - - -sub RemoveSections { - my %option = @_; - my @sections = @{$lib_ref->GetSections()}; - my $glob_ref = $lib_ref->GetGlobalSettings(); - my $default_section = $glob_ref->{"default"} || ""; - my $default_removed = 0; - - normalize_options(\%option); - @sections = grep { - my $match = match_section($_, \%option); - $default_removed = 1 - if $match and $default_section eq $_->{"name"}; - !$match; - } @sections; - $lib_ref->SetSections (\@sections); - if ($default_removed) { - $glob_ref->{"default"} = $sections[0]{"name"}; - } - $glob_ref->{"__modified"} = 1; # needed because of GRUB - index of default - # may change even if not deleted - $lib_ref->SetGlobalSettings ($glob_ref); - $lib_ref->WriteSettings (1); - $lib_ref->UpdateBootloader (1); # avoid initialization but write config to - # the right place - DumpLog (); -} - - -=item C<< Bootloader::Tools::UpdateBootloader (); >> Updates the bootloader settings meaning do whatever it takes for the actual @@ -605,6 +863,32 @@ sub GetSectionList { my %option = @_; + my $loader = GetBootloader (); + +# FIXME: Maybe activate this part of code later if - against all expectations +# - still needed, but this shouldn't happen. + # Examines if image and initrd strings already contain a grub device + # prefix. If it is not the case, attach it. + if ($loader eq "grub") { + foreach my $key (sort keys %option) { + unless ($option{$key} =~ /^\(hd\d+,\d+\).*$/) { + # In case /boot is resided on an own partition, the function + # UnixPath2GrubPath (in GRUB.pm) doesn't substitute "/boot" + # with the corresponding grub device, but keeps it. + # + # So the image, kernel and initrd values in the @sections + # array don't contain such a grub device prefix. Thus, to + # match sections to be deleted, a grub device prefix must not + # be attached to the given @option elements. + if ($lib_ref->UnixFile2GrubDev ("/boot") eq $lib_ref->UnixFile2GrubDev ("/")){ + if ($key eq "image" || $key eq "initrd" || $key eq "kernel") { + my $grub_dev = $lib_ref->UnixFile2GrubDev ("/boot"); + $option{$key} = $grub_dev . $option{$key}; + } + } + } + } + } normalize_options(\%option); my @sections = @{$lib_ref->GetSections ()}; @@ -636,7 +920,18 @@ =item C<< Bootloader::Tools::AddSection($name, @params); >> -# FIXME: Add documentation +Add a new section (boot entry) to config file, e.g. to /boot/grub/menu.lst + +EXAMPLE: + + my $opt_name = "LabelOfSection"; + my @params = (type => $type, + image => $opt_image, + initrd => $opt_initrd, + ); + + Bootloader::Tools::AddSection ($opt_name, @params); + =cut sub AddSection { @@ -647,12 +942,13 @@ return unless exists $option{"type"}; my $default = delete $option{"default"} || 0; - + my $mp = $lib_ref->GetMountPoints (); my @sections = @{$lib_ref->GetSections ()}; my %new = ( "root" => $mp->{"/"} || "/dev/null", ); + my %def = (); foreach my $s (@sections) { @@ -686,44 +982,230 @@ } $new{"name"} = $name; + my $failsafe_modified = 0; + + # FIXME: Failsafe parameters should be set dynamically in the future + if ($name =~ m/^Failsafe.*$/) { + my $arch = `uname --machine`; + chomp ($arch); + + if ($arch eq "i386") { + $new{"append"} = "showopts ide=nodma apm=off acpi=off noresume nosmp noapic maxcpus=0 edd=off"; + } + elsif ($arch eq "x86_64") { + $new{"append"} = "showopts ide=nodma apm=off acpi=off noresume edd=off"; + } + elsif ($arch eq "ia64") { + $new{"append"} = "ide=nodma nohalt noresume"; + } + else { + print ("Architecture $arch does not support failsafe entries.\n"); + } + + # Set vgamode to "normal" for failsafe entries + if (exists $new{"vgamode"} && defined $new{"vgamode"}) { + $new{"vgamode"} = "normal"; + } + + $failsafe_modified = 1; + + # Don't make the failsafe entry the default one + $default = 0; + } $new{"__modified"} = 1; - push @sections, \%new; + + my $match = ''; + my $new_name = ''; + + my $loader = Bootloader::Tools::GetBootloader (); + + if ($loader ne "grub") { + # Search for duplicate boot entry label and rename them in a unique way + foreach my $s (@sections) { + while ((my $k, my $v) = each (%$s)) { + if ($k eq "name" && index ($v, $new{"name"}) >= 0) { + $match += 1; + $new_name = $new{"name"} . "V" . $match; + + if ($new_name eq $v) { + $match += 1; + $new_name = $new{"name"} . "V" . $match; + } + $new{"name"} = $new_name; + } + } + } + } + + # Put new entries on top + unshift @sections, \%new; + + # Resolve kernel symlinks (if available) to full names + my $link_target = ''; + foreach my $s (@sections) { + while ((my $k, my $v) = each (%$s)) { + if ($k eq "kernel" || $k eq "image" || $k eq "initrd") { + $v =~ s/^\(.*\)//; + if ($link_target = readlink ($v)) { + chomp ($link_target); + $s->{$k} = "/boot/" . $link_target; + } + } + if ($k eq "__lines") { + my $index = 0; + foreach my $elem (@$v) { + while ((my $k, my $v) = each (%$elem)) { + if ((index ($v, "vmlinuz") >= 0 || index ($v, "initrd") >= 0) + && ($link_target = readlink ($v))) { + $v = (split (/ /, $v))[0]; + chomp ($link_target); + $s->{"__lines"}[$index]->{$k} = "/boot/" . $link_target; + } + } + $index += 1; + } + } + } + } + + # Switch the first 2 entries in @sections array to put the normal entry on + # top of corresponding failsafe entry + if (($failsafe_modified == 1) && scalar (@sections) >= 2) { + my $failsafe_entry = shift (@sections); + my $normal_entry = shift (@sections); + + # Delete obsolete (normal) boot entries from section array + my $section_index = 0; + foreach my $s (@sections) { + if (exists $normal_entry->{"kernel"} && $normal_entry->{"kernel"} eq $s->{"kernel"}) { + delete $sections[$section_index]; + } + elsif (exists $normal_entry->{"image"} && $normal_entry->{"image"} eq $s->{"image"}) { + delete $sections[$section_index]; + } + else { + $section_index++; + } + } + + # Delete obsolete (failsafe) boot entries from section array + $section_index = 0; + foreach my $s (@sections) { + if (exists $failsafe_entry->{"kernel"} && $failsafe_entry->{"kernel"} eq $s->{"kernel"}) { + delete $sections[$section_index]; + } + elsif (exists $failsafe_entry->{"image"} && $failsafe_entry->{"image"} eq $s->{"image"}) { + delete $sections[$section_index]; + } + else { + $section_index += 1; + } + } + + unshift @sections, $failsafe_entry; + unshift @sections, $normal_entry; + } $lib_ref->SetSections (\@sections); + # If the former default boot entry is updated, the new one will become now + # the new default entry. + my $glob_ref = $lib_ref->GetGlobalSettings (); if ($default) { - my $glob_ref = $lib_ref->GetGlobalSettings (); - $glob_ref->{"default"} = $name; + $glob_ref->{"default"} = $new{"name"}; $glob_ref->{"__modified"} = 1; $lib_ref->SetGlobalSettings ($glob_ref); } + # If a non default entry is updated, the index of the current + # default entry has to be increased, because it is shifted down in the + # array of sections. Only do this for grub. + elsif ($loader eq "grub") { + my $array_ref = $glob_ref->{"__lines"}; + + foreach my $line (@$array_ref) { + if ($line->{"key"} eq "default") { + $line->{"value"} += 1; + } + } + $lib_ref->SetGlobalSettings ($glob_ref); + } $lib_ref->WriteSettings (1); $lib_ref->UpdateBootloader (1); # avoid initialization but write config to # the right place + DumpLog (); } =item -C<< Bootloader::Tools::RemoveSection($name); >> +C<< Bootloader::Tools::RemoveImageSections ($image); >> + +removes all sections in the bootloader menu referring to the +specified kernel. + +EXAMPLE: + + Bootloader::Tools::InitLibrary (); + Bootloader::Tools::RemoveImageSections ("/boot/vmlinuz-2.6.11"); + Bootloader::Tools::UpdateBootloader(); =cut -sub RemoveSection { - my $name = shift or return; +sub RemoveImageSections { + my $image = shift; + + return unless $image; + RemoveSections(type=>"image", image => $image); +} + +=item +C<< Bootloader::Tools::RemoveSection($name); >> + +=cut + +sub RemoveSections { + my %option = @_; my @sections = @{$lib_ref->GetSections()}; my $glob_ref = $lib_ref->GetGlobalSettings(); my $default_section = $glob_ref->{"default"} || ""; my $default_removed = 0; +# FIXME: Maybe activate this part of code later if - against all expectations +# - still needed, but this shouldn't happen. + my $loader = GetBootloader (); + # Examines if image and initrd strings already contain a grub device + # prefix. If it is not the case, attach it. + if ($loader eq "grub") { + foreach my $key (sort keys %option) { + unless ($option{$key} =~ /^\(hd\d+,\d+\).*$/) { + # In case /boot is resided on an own partition, the function + # UnixPath2GrubPath (in GRUB.pm) doesn't substitute "/boot" + # with the corresponding grub device, but keeps it. + # + # So the image, kernel and initrd values in the @sections + # array don't contain such a grub device prefix. Thus, to + # match sections to be deleted, a grub device prefix must not + # be attached to the given @option elements. + if ($lib_ref->UnixFile2GrubDev ("/boot") eq $lib_ref->UnixFile2GrubDev ("/")){ + if ($key eq "image" || $key eq "initrd" || $key eq "kernel") { + my $grub_dev = $lib_ref->UnixFile2GrubDev ("/boot"); + $option{$key} = $grub_dev . $option{$key}; + } + } + } + } + } + + normalize_options(\%option); @sections = grep { - my $match = $_->{"name"} eq $name; + my $match = match_section($_, \%option); $default_removed = 1 if $match and $default_section eq $_->{"name"}; !$match; } @sections; + $lib_ref->SetSections (\@sections); if ($default_removed) { $glob_ref->{"default"} = $sections[0]{"name"}; @@ -734,11 +1216,11 @@ $lib_ref->WriteSettings (1); $lib_ref->UpdateBootloader (1); # avoid initialization but write config to # the right place + DumpLog (); } - 1; ++++++ update-bootloader ++++++ --- perl-Bootloader/update-bootloader 2006-11-29 13:39:53.000000000 +0100 +++ /mounts/work_src_done/STABLE/perl-Bootloader/update-bootloader 2007-03-23 19:26:31.000000000 +0100 @@ -10,7 +10,8 @@ my %oper; my ($opt_default, $opt_force, $opt_help, $opt_man, $opt_previous, $opt_xen) = (0,0,0,0,0,0); -my ($opt_image, $opt_initrd, $opt_name, $opt_xen_kernel) = ('','','',undef); +my ($opt_image, $opt_initrd, $opt_name, $opt_xen_name, $opt_failsafe, $opt_xen_kernel) + = ('','','','','',undef); my $add_product = 0; =head1 NAME @@ -75,8 +76,8 @@ =item B<--default> -let the new section to be added be the default section. Only allowed together -with --add operation +let the new section to be added be the default section if appropriate. Only +allowed together with --add operation =item B<--previous> @@ -111,19 +112,32 @@ # First try: Does yast work these days? $namever = `yast2 print-product 2>&1`; chomp $namever; - return "$namever" if $namever != '' and $namever !~ /\n/; + + # Determine the bootloader type, because long product names may only + # be used in case of grub + my $loader = Bootloader::Tools::GetBootloader(); + + # Substitude whitespaces with an underscore + if ($loader ne "grub") { + $namever =~ s/\s/_/; + } + return "$namever" if $namever ne '' and $namever !~ /\n/; # Second try: Is there a usable /etc/SuSE-release? - if (open(RELEASE, " $type, image => $opt_image, ); - if (CountSections(@params) != 0) - { + if (CountSections(@params) != 0) { if (not $opt_force) { pod2usage("There are already sections with image '$opt_image'"); } } else { - push @params, default => $opt_default; + # FIXME: Subject of change (depending on how the weather is) + # only add default if "appropriate" + # meaning now flavor of current default matches new one + #my $flavor = GetDefaultImage(); + #$flavor =~ s/^.*-//; + # + #if ($opt_image =~ m/.*-${flavor}$/) { + # push @params, default => $opt_default; + #} push @params, xen => $opt_xen_kernel if $type eq "xen"; push @params, initrd => $opt_initrd if $opt_initrd; - - AddSection($opt_name, @params); + + if ($opt_xen) { + # Add "xen" section + AddSection($opt_xen_name, @params); + } + else { + # Add "normal" sections + AddSection($opt_name, @params); + } + + my $arch = `uname --machine`; + chomp ($arch); + + # Add a "Failsafe" section + if ((($arch eq "i386") || ($arch eq "x86_64") || ($arch eq "ia64")) + && $opt_xen != 1) { + AddSection($opt_failsafe, @params); + } } } @@ -269,6 +340,7 @@ push @params, name => $opt_name if $opt_name; my $num = CountSections(@params); + if ($num > 0) { if ($num > 1 and not $opt_force) { pod2usage("There is more than one section with image '$opt_image'"); ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org