mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-29 02:15:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			224 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			224 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env perl
 | |
| 
 | |
| # This script is used to flash the mics on the host.
 | |
| # This script is run by xdsh from MN/SN to the host
 | |
| # parameters
 | |
| #  -m xcatmaster
 | |
| #  -p the path of the mic configuration file. Generally, it's /tftpboot/xcat/miccfg/micflash.hostname
 | |
| 
 | |
| use strict;
 | |
| use IO::Socket;
 | |
| 
 | |
| use File::Path;
 | |
| use File::Copy;
 | |
| use Getopt::Long;
 | |
| 
 | |
| # enable the autoflush of stdout
 | |
| select STDOUT;
 | |
| $| = 1;
 | |
| 
 | |
| my $tmppath   = "/tmp/mictmp";
 | |
| my $logpath   = "/var/log/xcat/";
 | |
| my $logfile   = "$logpath/flash.log";
 | |
| my $micmnt    = "/var/mpss/mnt";
 | |
| my $flashpath = "$micmnt/usr/share/mpss/flash";
 | |
| 
 | |
| if (!-d "$flashpath") {
 | |
|     $flashpath = "/usr/share/mpss/flash";
 | |
| }
 | |
| 
 | |
| mkpath $tmppath;
 | |
| mkpath $micmnt;
 | |
| 
 | |
| #open the log file
 | |
| open(LOG, ">>$logfile") or die "Error: cannot open $logfile\n";
 | |
| print LOG "\n\n====================================================\nStart mic flashing: " . `date` . "\n";
 | |
| 
 | |
| my ($master, $cfgpath);
 | |
| GetOptions('m=s' => \$master, 'p=s' => \$cfgpath);
 | |
| unless ($master && $cfgpath) {
 | |
|     outputmsg("Error: the -m master and -p path arguments must be specified for configmic.\n", 1);
 | |
| }
 | |
| 
 | |
| # get the correct host name for the host
 | |
| my ($nodename, $nodename_short);
 | |
| my $masterip = `getent hosts $master | awk {'print \$1'}`;
 | |
| if ($masterip) {
 | |
|     chomp($masterip);
 | |
|     my $myip = `ip route get $masterip| head -n 1 | sed 's/^.*src//g' | awk {'print \$1'}`;
 | |
|     if ($myip) {
 | |
|         my $myipinfo = `getent hosts $myip`;
 | |
| 
 | |
|         if ($myipinfo && $myipinfo =~ /([^\s]+)\s+([^\s]+)\s+([^\s]+)/) {
 | |
|             my $n1 = $2;
 | |
|             my $n2 = $3;
 | |
|             if (length($n1) > length($n2)) {
 | |
|                 $nodename_short = $n2;
 | |
|             } else {
 | |
|                 $nodename = $n1;
 | |
|             }
 | |
|         } elsif ($myipinfo && $myipinfo =~ /([^\s]+)\s+([^\s]+)/) {
 | |
|             $nodename_short = $2;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| unless ($nodename) {
 | |
|     $nodename = `hostname`;
 | |
|     chomp($nodename);
 | |
| }
 | |
| unless ($nodename_short) {
 | |
|     $nodename_short = `hostname -s`;
 | |
|     chomp($nodename_short);
 | |
| }
 | |
| 
 | |
| # download the mic configuration file from master
 | |
| my $cmd = "wget -N --waitretry=10 --random-wait -T 60 http://$master/$cfgpath/micflash.$nodename_short -P $tmppath";
 | |
| my ($rc, $output) = runsyscmd($cmd);
 | |
| if ($rc) {
 | |
|     $cmd = "wget -N --waitretry=10 --random-wait -T 60 http://$master/$cfgpath/micflash.$nodename -P $tmppath";
 | |
|     runsyscmd($cmd, "Error: failed to download mic configuration file from $master\n", 3);
 | |
| }
 | |
| 
 | |
| unless (-r "$tmppath/micflash.$nodename") {
 | |
|     runsyscmd("Error: cannot get the mic configuration file from http://$master/$cfgpath/micflash.$nodename\n", 4);
 | |
| }
 | |
| 
 | |
| # parse the configuration file
 | |
| unless (open(CFGFILE, "<$tmppath/micflash.$nodename")) {
 | |
|     runsyscmd("Error: cannot open $tmppath/micflash.$nodename\n", 5);
 | |
| }
 | |
| 
 | |
| # the configureation file should have the following format
 | |
| #miclist=mic0
 | |
| #0:name=host1-mic0
 | |
| #imgpath=/install/mpss3.new
 | |
| 
 | |
| my %miccfg;
 | |
| my $miclist;
 | |
| my $ospath;
 | |
| while (<CFGFILE>) {
 | |
|     if (/(\d+):(.*)/) {
 | |
|         my $deviceid = $1;
 | |
|         my @params = split(/\|/, $2);
 | |
|         foreach (@params) {
 | |
|             my ($n, $v) = split(/=/, $_);
 | |
|             $miccfg{$deviceid}{$n} = $v;
 | |
|         }
 | |
|     } elsif (/^miclist=(.*)/) {
 | |
|         $miclist = $1;
 | |
|     } elsif (/^imgpath=(.*)/) {
 | |
|         $ospath = $1;
 | |
|     }
 | |
| }
 | |
| close(CFGFILE);
 | |
| 
 | |
| $miclist =~ s/,/ /g;
 | |
| 
 | |
| # add the mount entry for mounting of root fs from master to /etc/fstab
 | |
| # e.g. mount $master:/install/mpss3 /var/mpss/mnt
 | |
| $cmd = "grep \'$master:$ospath \' $micmnt /etc/fstab ";
 | |
| ($rc, $output) = runsyscmd($cmd);
 | |
| if ($rc) {
 | |
| 
 | |
|     # not found the exact mount entry
 | |
|     $cmd = "grep $micmnt /etc/fstab";
 | |
|     ($rc, $output) = runsyscmd($cmd);
 | |
|     if (!$rc) {
 | |
| 
 | |
|         # found the mount to $micmnt with another master or directory, remove the entry and umount it
 | |
|         my $trans = $micmnt;
 | |
|         $trans =~ s/\//\\\//g;
 | |
|         $cmd = "sed \"/$trans/d\" /etc/fstab > $tmppath/fstab.tmp";
 | |
|         runsyscmd($cmd, "Error: failed to configure fstab.\n", 6);
 | |
|         copy("$tmppath/fstab.tmp", "/etc/fstab");
 | |
|         $cmd = "umount -l -f $micmnt";
 | |
|         runsyscmd($cmd, "Error: failed to run umount -l -f $micmnt\n", 7);
 | |
|     }
 | |
|     $cmd = "echo \"$master:$ospath $micmnt nfs timeo=14,intr 1 2\" >>/etc/fstab";
 | |
|     runsyscmd($cmd);
 | |
|     $cmd = "mount -a";
 | |
|     runsyscmd($cmd);
 | |
| }
 | |
| 
 | |
| # make sure the remote flash directory is accessable
 | |
| unless (-d "$flashpath") {
 | |
|     outputmsg("Error: cannot access the $flashpath.\n", 8);
 | |
| }
 | |
| 
 | |
| # start to flash the mic
 | |
| # #
 | |
| # # reset the mic to ready stat
 | |
| $cmd = "micctrl -r -w $miclist";
 | |
| ($rc, $output) = runsyscmd($cmd, "Error: failed to reset mic.\n", 100);
 | |
| 
 | |
| my $micidlist;
 | |
| foreach my $micid (keys %miccfg) {
 | |
|     unless (grep /mic$micid: ready/, @$output) {
 | |
|         outputmsg("MICMSG:$miccfg{$micid}{'name'}: Error: failed to reset mic to ready stat.\n", 100);
 | |
|     }
 | |
|     $micidlist .= ",$micid";
 | |
| }
 | |
| 
 | |
| $micidlist =~ s/^,//;
 | |
| 
 | |
| # do the flash
 | |
| $cmd = "micflash -update $flashpath -device $micidlist";
 | |
| ($rc, $output) = runsyscmd($cmd);
 | |
| 
 | |
| # generate the output messages
 | |
| foreach (@$output) {
 | |
|     foreach my $line (split /\n/, $_) {
 | |
|         if ($line =~ /^mic(\d+):/) {
 | |
|             $line =~ s/^mic(\d+):/MICMSG:$miccfg{$1}{'name'}:/;
 | |
|         }
 | |
|         print $line . "\n";
 | |
|     }
 | |
| }
 | |
| 
 | |
| print LOG "\nFinish the mic flashing: " . `date` . "====================================================\n";
 | |
| 
 | |
| close(LOG);
 | |
| 
 | |
| exit 0;
 | |
| 
 | |
| # run command
 | |
| sub runsyscmd {
 | |
|     my $cmd    = shift;
 | |
|     my $errmsg = shift;
 | |
|     my $rc     = shift;
 | |
| 
 | |
|     print LOG "---------------------------------------------\n";
 | |
|     print LOG "Run command: $cmd\n";
 | |
| 
 | |
|     if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
 | |
|     my @output = `$cmd`;
 | |
| 
 | |
|     my $errcode = 0;
 | |
|     if ($?) {
 | |
|         $errcode = $? >> 8;
 | |
|     }
 | |
| 
 | |
|     foreach (@output) {
 | |
|         print LOG $_;
 | |
|     }
 | |
|     print LOG "---------------------------------------------\n";
 | |
| 
 | |
|     if ($rc && $errcode) {
 | |
|         outputmsg($errmsg, $rc);
 | |
|         exit $rc;
 | |
|     }
 | |
|     return ($errcode, \@output);
 | |
| }
 | |
| 
 | |
| # display the output message
 | |
| sub outputmsg {
 | |
|     my $msg = shift;
 | |
|     my $rc  = shift;
 | |
|     print LOG $msg;
 | |
|     print $msg;
 | |
|     if ($rc) {
 | |
|         exit $rc;
 | |
|     }
 | |
| }
 | |
| 
 |