#!/usr/bin/perl # This is only for use on SLES 10 s390x systems # With minor modification to the device paths, it should work for any # s390 or s390x Linux system # Adam Thornton # Sine Nomine Associates # Version history # 14 August 2008 - Initial release # 23 December 2008 - Corrected match regexp at step 3 (S. Courtney) # 15 January 2009 - Fixed some path stuff # This program is licensed under the terms of the Artistic License 2.0, # as found at http://www.perlfoundation.org/artistic_license_2_0 $PARENTDIR="/sys/bus/ccw/drivers"; $FSTAB="/etc/fstab"; $ZIPL="/etc/zipl.conf"; $findcmd="find -L $PARENTDIR -maxdepth 3 -name uid 2>/dev/null"; use File::Temp qw(tempdir); use Getopt::Std; # Step 1: # Walk through everything under $PARENTDIR/dasd-[eckd|fba] # For each entry there that has something in the "uid" parameter (which # is used to construct the by-id path), record what the device number # actually is. # Step 2: # Walk through /etc/fstab # For each by-id entry, substitute it with the corresponding by-path entry # Step 3: # Walk through /etc/zipl.conf # For each by-id entry, substitute it with the corresponding by-path entry # Step 4: # Copy files into place # Replace files (if requested) # Run zipl (if required) # Cleanup (if requested) getopts("hcdrv"); # Get options: "-c" is cleanup, "-d" is dry-run, "-v" is verbose # "-r" is replace, "-h" is help $cleanup=($opt_c?1:0); $dryrun=($opt_d?1:0); $verbose=($opt_v?1:0); $replace=($opt_r?1:0); if ($opt_h) { print << "EOF"; $0 [-h] [-d] [-v] [-r] [-c] -h: shows help message -d: dry run: does not actually create any files -v: verbose: chats about its progress -r: replace fstab and zipl.conf with new files (dangerous!) -c: clean up -- after replacing files, delete old files (insane!) (-c must be combined with -r; please do not use it!) EOF exit 0; } # Step 1 $l=`$findcmd`; @l=split(' ',$l); for (@l) { $uid=`cat $_`; chomp $uid; ($junk1,$junk2,$junk3,$junk4,$junk5,$junk6,$device,$junk7) = split('/',$_); if ($uid) { $dasd{$uid}=$device; chatter("/sys scan: Found $uid -> $device"); } } # Step 2 my $tdir=tempdir( CLEANUP => 1 ); $FSTOUT="$tdir/fstab"; $ZIPLOUT="$tdir/zipl.conf"; my $fstchangereq=0; open (FSTAB,"<$FSTAB") or die ("Could not open $FSTAB: $!\n"); open (FSTOUT,">$FSTOUT") or die ("Could not open $FSTOUT: $!\n"); while () { if (/by-id/) { chomp; chatter("Found by-id path: $_"); m/(^.*)by-id\/(\S+)(\s+)(.*)/; if ($2) { $tdev=$2; $first=$1; $spaces=$3; $rest=$4; chatter("Found $tdev in /etc/fstab"); my ($ccw,$ttdev,$part) = split('-',$tdev); chatter("Device -> $ttdev ; Partition -> $part"); if (defined($dasd{$ttdev}) && $dasd{$ttdev}) { my $k=$dasd{$ttdev}; if ($part) { $k .= "-$part" } $fstchangereq=1; $_=$first . "by-path/ccw-" . $k . $spaces . $rest; chatter("Changed fstab line to $_"); $_ .= "\n"; } else { errorout("Could not find matching device for $tdev!"); } } } print FSTOUT; } close FSTOUT; if ($fstchangereq == 0) { chatter("No changes required to fstab"); } # Step 3 my $ziplchangereq=0; open (ZIPL,"<$ZIPL") or die ("Could not open $ZIPL: $!\n"); open (ZIPLOUT,">$ZIPLOUT") or die ("Could not open $ZIPLOUT: $!\n"); while () { if (/by-id/) { chomp; chatter("Found by-id path: $_"); m/(^.*\/dev\/disk\/)by-id\/(\S+)(\s+)(.*)/; if ($2) { $first=$1; $tdev=$2; $spaces=$3; $rest=$4; chatter("Found $tdev in /etc/fstab"); my ($ccw,$ttdev,$part) = split('-',$tdev); chatter("Device -> $ttdev ; Partition -> $part"); if (defined($dasd{$ttdev}) && $dasd{$ttdev}) { my $k=$dasd{$ttdev}; if ($part) { $k .= "-$part" } $ziplchangereq=1; $_=$first . "by-path/ccw-" . $k . $spaces . $rest; chatter("Changed zipl.conf line to $_"); $_ .= "\n"; } else { errorout("Could not find matching device for $tdev!"); } } } print ZIPLOUT; } close ZIPLOUT; if ($ziplchangereq == 0) { chatter("No changes required to zipl.conf"); } if ($fstchangereq) { if ($dryrun) { print "/etc/fstab needs changing:\n"; print "======/etc/fstab==========\n"; system("cat $FSTOUT"); print "======/etc/fstab==========\n"; } else { system("cp /etc/fstab /etc/fstab-by-id") and errorout($!); system("cp $FSTOUT /etc/fstab-by-path") and errorout($!); if ($replace) { system("cp /etc/fstab-by-path /etc/fstab") and errorout($!); if ($cleanup) { unlink("/etc/fstab-by-id"); unlink("/etc/fstab-by-path"); } } else { print "New fstab is in /etc/fstab-by-path.\n"; } } } else { print "/etc/fstab did not contain by-id statements\n"; } if ($ziplchangereq) { if ($dryrun) { print "/etc/zipl.conf needs changing:\n"; print "======/etc/zipl.conf==========\n"; system("cat $ZIPLOUT"); print "======/etc/zipl.conf==========\n"; } else { system("cp /etc/zipl.conf /etc/zipl.conf-by-id") and errorout($!); system("cp $ZIPLOUT /etc/zipl.conf-by-path") and errorout($!); if ($replace) { system("cp /etc/zipl.conf-by-path /etc/zipl.conf") and errorout($!); system("zipl") and errorout($!); if ($cleanup) { unlink("/etc/zipl.conf-by-id"); unlink("/etc/zipl.conf-by-path"); } } else { print "New fstab is in /etc/zipl.conf-by-path.\n"; } } } else { print "/etc/zipl.conf did not contain by-id statements\n"; } exit 0; # End of mainline code sub chatter { return unless ($verbose); my $a=shift; print "$0: $a\n"; } sub errorout { my $a=shift; print STDERR "$0: $a\n"; exit 1; # No return } __END__ =head1 sane-dasd-update sane-dasd-update - Fix by-id disk paths in /etc/fstab and /etc/zipl.conf sane-dasd-update [-h] [-d] [-v] [-r] [-c] -h: shows help message -d: dry run: does not actually create any files -v: verbose: chats about its progress -r: replace fstab and zipl.conf with new files (dangerous!) -c: clean up -- after replacing files, delete old files (insane!) (-c must be combined with -r; please do not use it!) This is a simple script to match up by-id disk names with by-path disk names, and to replace by-id names with their corresponding by-path names in /etc/fstab and /etc/zipl.conf. If this is run with the -r option (which really replaces files) and zipl.conf has changed, it will also run zipl. This script ONLY WORKS on SLES10 for s390x. With minor modifications it should be easily convertible to other s390 and s390x distributions. It makes no sense for other architectures, whose disk nomenclatures are completely different. This program comes with NO WARRANTY, EXPRESS OR IMPLIED. But as long as you run it WITHOUT the -r, or, Chucky forbid, the -r and the -c options, it's unlikely to do any damage. Seriously, look at the output before committing to it, and then run zipl by hand. You've been warned. sane-dasd-update is copyright 2008, Sine Nomine Associates. It is released under the Artistic License 2.0. =cut