#!/opt/star/bin/perl -w # # This script scans a disk given as the first argument # checks all files and update the database with a file # location new netry if it finds the same entry as # storage = HPPS. # # It uses the clone_location() method to update the # database with that entry and is a very good example # of how to do this ... # # *** # This is REALLY a spider ... It is used to post-scan # disk and catch entries which may be missing. # # Only clones (if there is no similar entries in the db, # it won't add it). # *** # # BEWARE : # (1) $SITE and $HPSSD are global variables # (2) There is an hidden logic based on $path !~ /\/star\/data/ # to recognized if the storage is local or NFS. # # Arguments are # ARGV0 the base path of a disk to scan (default /star/data06) # ARGV1 the filetype (default .MuDst.root ). If null, it will # search for all files # ARGV2 this scripts limits it to a sub-directory "reco" starting # from $ARGV0. Use this argument to overwrite. # ARGV3 A base path substitution for find the entry in HPSS # Default is /home/starreco . # # ARGV4 a user name (default FC_admin) # ARGV5 a password (default will be to use the # get_connection() method as a guess try) # # # # Examples # % DBUpdate.pl /star/data27 # % DBUpdate.pl /star/data27 "" # % DBUpdate.pl /star/data03 .daq daq /home/starsink/raw # # # use lib "/afs/rhic/star/packages/scripts"; #use lib "/star/u/jeromel/work/ddb"; use FileCatalog; use Date::Manip; $SITE = "BNL"; $HPSSD = "/home/starreco"; $SCAND = "/star/data06"; $USER = ""; $PASSWD= ""; $SUB = "reco"; # Argument pick-up $SCAND = shift(@ARGV) if (@ARGV); $FTYPE = shift(@ARGV) if (@ARGV); $SUB = shift(@ARGV) if (@ARGV); $HPSSD = shift(@ARGV) if (@ARGV); $USER = shift(@ARGV) if (@ARGV); $PASSWD= shift(@ARGV) if (@ARGV); #@ALL =( "$SCAND/$SUB/FPDXmas/FullField/P02ge/2002/013/st_physics_3013016_raw_0018.MuDst.root", # "$SCAND/$SUB/FPDXmas/FullField/P02ge/2002/013/st_physics_3013012_raw_0008.MuDst.root"); $DOIT = ($#ALL == -1); if ( ! defined($FTYPE) ){ $FTYPE = ".MuDst.root";} if( $DOIT ){ if ($FTYPE ne ""){ print "Searching for all files like '*$FTYPE' ...\n"; @ALL = `find $SCAND/$SUB -type f -name '*$FTYPE'`; print "Found ".($#ALL+1)." files to add (x2)\n"; } else { print "Searching for all files ...\n"; @ALL = `find $SCAND/$SUB -type f`; print "Found ".($#ALL+1)." files to add (x2)\n"; } } if ($#ALL == -1){ exit;} $fC = FileCatalog->new(); # Get connection fills the blanks while reading from XML # However, USER/PASSWORD presence are re-checked #$fC->debug_on(); ($USER,$PASSWD,$PORT,$HOST,$DB) = $fC->get_connection("Admin"); $port = $PORT if ( defined($PORT) ); $host = $HOST if ( defined($HOST) ); $db = $DB if ( defined($DB) ); if ( defined($USER) ){ $user = $USER;} else { $user = "FC_admin";} if ( defined($PASSWD) ){ $passwd = $PASSWD;} else { print "Password for $user : "; chomp($passwd = <STDIN>);} # # Now connect # $fC->connect($user,$passwd,$port,$host,$db); #$fC->debug_off(); $failed = $unkn = $old = $new = 0; #$fC->set_delimeter(","); # Make it easier to parse $fC->set_silent(1); # Turn OFF messaging # Make a main context # Temporary so we get it once only chomp($NODE = `hostname`); foreach $file (@ALL){ chomp($file); # We need to parse the information we can # save in the ddb $file =~ m/(.*\/)(.*)/; $path = $1; $file = $2; chop($path); $hpath= $path; $hpath=~ s/$SCAND/$HPSSD/; # Is a disk copy ?? $fC->clear_context(); if ( $path =~ m/\/star\/data/){ $node = ""; $storage = "NFS"; $fC->set_context("path = $path","filename = $file","storage = NFS","site = $SITE"); } else { $storage = "local"; $node = $NODE; $fC->set_context("path = $path","filename = $file","storage = local","site = $SITE", "node = $NODE"); } @all1 = $fC->run_query("size"); # HPSS copy (must be the last context to use clone_location() afterward ) $fC->clear_context(); $fC->set_context("path = $hpath","filename = $file","storage = HPSS","site = $SITE"); @all = $fC->run_query("size"); if ($#all == -1){ $unkn++; print STDERR "Did not find $path $file in HPSS\n"; } else { $mess = "Found ".($#all+1)." records for $file "; @stat = stat("$path/$file"); if ($#stat == -1){ print "/!\ stat($path/$file) failed\n"; next; } #if( $stat[7] != 0){ # $sanity = 1; #} else { # $sanity = 0; #} if ($path !~ /\/star\/data/){ } else { } if ($#all1 != -1){ $old++; #print "$mess Already in ddb\n"; } else { #print "Cloning $hpath $file\n"; if ( ! $fC->clone_location() ){ print "Cloning of $file did not occur\n"; } else { print "$mess File cloned ".sprintf("%.2f %%",($new/$#ALL)*100)."\n" if ($new % 10 == 0); $fC->set_context("persistent= 0"); #chomp($node = `hostname`); $fsize = $stat[7]; @own = getpwuid($stat[4]); $prot = &ShowPerms($stat[2]); #$dt = &UnixDate(scalar(localtime($stat[10])),"%Y%m%d%H%M%S"); $fC->set_context("path = $path", "storage = $storage", "persistent = 0", "size = $fsize", "owner = $own[0]", "protection = $prot", "available = 1", "site = $SITE"); if ( $node ne ""){ $fC->set_context("node = $node"); } if ( ! $fC->insert_file_location() ){ print "\tAttempt to insert new location $path failed\n"; $failed++; } else { $new++; } } } } } $fC->destroy(); print "Unkown = $unkn\n", "Old = $old\n", "New = $new\n", "Failed = $failed\n"; # This sub has been taken from fcheck software # as-is (was too lazzy to get it done by myself) sub ShowPerms { local ($mode) = @_; local (@perms) = ("---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"); local (@ftype) = ("?", "p", "c", "?", "d", "?", "b", "?", "-", "?", "l", "?", "s", "?", "?", "?"); local ($setids) = ($mode & 07000)>>9; local (@permstrs) = @perms[($mode & 0700) >> 6, ($mode & 0070) >> 3, ($mode & 0007) >> 0]; local ($ftype) = $ftype[($mode & 0170000)>>12]; if ($setids){ # Sticky Bit? if ($setids & 01) { $permstrs[2] =~ s/([-x])$/$1 eq 'x' ? 't' : 'T'/e; } # Setuid Bit? if ($setids & 04) { $permstrs[0] =~ s/([-x])$/$1 eq 'x' ? 's' : 'S'/e; } # Setgid Bit? if ($setids & 02) { $permstrs[1] =~ s/([-x])$/$1 eq 'x' ? 's' : 'S'/e; } } return (join('', $ftype, @permstrs)); }