# enableHardLink.pl # # by Vijayababu Dandi # Version 1.0 # Feb 05, 2008 ############################################################################################## # Perl must be installed and running on the Linux server where this utility will be used. # NSS must be installed to get the VFS support. # (The SDK for this API set can be downloaded from http://developer.novell.com/wiki/index.php/# Virtual_File_Services_for_NetWare.) # nsscon must be installed. ############################################################################################## # This tool can be used to enable and disable Hard Link attribute for specified nss volume ############################################################################################## sub SetDataStream(*$) { my $fh = $_[0]; my $dataStream = $_[1]; my $result; my $command; $command = ""; seek $fh, 0, 0; if (!syswrite($fh, $command, length($command))) { $result .= "Unable to send datastream command to NDS management. "; seek $fh, 0, 0; if (sysread($fh, $error, 1000)) { $result .= $error; } $result .= "\n"; } return $result; } # # Write a command to a file and get the result # sub WriteCommand(*$) { my $fh = $_[0]; my $command = $_[1]; my $result; seek $fh, 0, 0; if (!syswrite($fh, $command, length($command))) { $result .= "Unable to send command to virtual file. "; seek $fh, 0, 0; if (sysread($fh, $error, 2500)) { $result .= $error; } $result .= "\n"; } else { seek $fh, 0, 0; sysread($fh, $reply, 2500); $result .= $reply; } return $result; } sub ListVolumes { my $command = "
"; my $myresult; my @xml; if (!($ret = SetDataStream(NSSFILE, "command"))) { $myresult .= $ret; my $nssResult = WriteCommand(NSSFILE,$command); $myresult = ParseVolume($nssResult); } print "----------------------------------------------------------------\n". "$myresult\n"; } sub ParseVolume($) { my $xml = $_[0]; my $result; my @xml; my $ret; my $volName = ""; @xml = $xml =~ /(.*?)<\/listVolumes>/gs; @xml = split (/<\/volumeName>/,$xml); foreach $result (@xml) { if ($result =~ //s) { if ($1 != 0) { return "Error $1 getting Snapshot Info\n"; } } if ($result =~ /(.*)/gs) { $volName = $1; $ret .=ParseVolumeData($volName); } } return $ret; } sub ParseVolumeData($) { my $volName = $_[0]; my $nssResult; my @xml; my $name; my $pName; my $mount; my $size; my $ret; my $volId; my $att; my $command = "$volName"; if (!($ret = SetDataStream(NSSFILE, "command"))) { $nssResult = WriteCommand(NSSFILE,$command); } @xml = $nssResult =~ /(.*?)<\/getVolumeInfo>/gs; foreach $result (@xml) { if ($result =~ //s) { if ($1 != 0) { return "Error $1 getting Volume Info\n"; } } if ($result =~ /(.*?)<\/volumeName>/s) { $name = $1; } if ($result =~ /(.*?)<\/mountPoint>/s) { $mount = $1; } if ($result =~ /(.*?)<\/poolName>/s) { $pName = $1; } if ($result =~ /(.*?)<\/blockSize>/s) { $size = $1; } if ($result =~ /(.*?)<\/enabledAttributes>/s) { $att = $2; } $ret .= "Volume Name : $name\n". "Host Pool : $pName\n". "Mount Point : $mount\n". "Block Size : $size\n". "Enabled Attributes : $att\n". "----------------------------------------------------------------\n"; } return $ret; } # # Parse the result of adding or removing a volume # sub ParseResult($$) { my $xml = $_[0]; my $name = $_[1]; my $result = ""; my @xml; if (@xml = $xml =~ /(.*)<\/modifyVolumeInfo>/s) { foreach $result (@xml) { if ($result =~ /(.*?)<\/description>/gs) { $description = $1; } if ($result =~ /(.*?)<\/reporter>/gs) { $reporter = $1; } if ($result =~ //s) { if ($1 != 0) { return " Error No :$1 \n". " Description :$description \n". " Reporter :$reporter \n"; } else { return "$name successfully updated\n"; } } } } else { return "Error parsing results of NSS operation\n"; } } sub ModifyVolume($%) { (my $volumeName, my $volumeQuota, my %attributes) = @_; $result = "Modifying Volume \"$volumeName\"\n"; # # Modify the volume # if (!($ret = SetDataStream(NSSFILE, "command"))) { my $value; my $atrElements; my $attrib; my @keys = keys %attributes; $atrElements .= ""; $atrElements .= ""; for $attrib (@keys) { if ($attrib eq 'shredding') { $atrElements .= "<$attrib count=\"".$attributes{$attrib}."\"/>"; } else { $atrElements .= "<$attrib enabled=\"".$attributes{$attrib}."\"/>"; } } $atrElements .= ""; $result .= $ret; my $nssResult = WriteCommand(NSSFILE, "". "$volumeName". $atrElements. ""); $result .= ParseResult($nssResult, $volumeName); } return $result; } # # Main # { my $volumeName; my $poolName; my $ndsContext = ""; open(NSSFILE,'+>', "/_admin/Manage_NSS/manage.cmd") or die "Error opening NSS management file ($!) on server"; MAIN: while(TRUE) { do { print "1. Update Hard Link attribute\n". "2. Exit\n". "Select action: "; chomp($action = ); }while ($action != 0 && ($action < 1 || $action > 2)); if ($action == 1) { my %attributes; my $volumeQuota; ListVolumes; print "volume name: "; chomp(my $volumeName = ); $volumeName =~ tr/[a-z]/[A-z]/; print("Enable or disable Hard Link attribute (enable/disable):"); chomp($action = lc()); if (($action eq 'e') || ($action eq 'enable')) { $attributes{volumeHardlinks} = "yes"; } else { my $ret = ParseVolumeData($volumeName); if ($ret !~ m//) { print "----------------------------------------------\n". "Hard Link attribute not enabled for $volumeName\n". "----------------------------------------------\n"; goto MAIN; } else { $attributes{volumeHardlinks} = "no"; } } print `nsscon nss /ZLSSUpgradeCurrentVolumeMediaFormat=$volumeName | exit`; my @results = ModifyVolume($volumeName, $volumeQuota, %attributes); print "---------------------------------------\n"; print @results; print "----------------------------------------\n"; } else { last MAIN; } } close(NSSFILE); }