# 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);
}