mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-21 19:22:05 +00:00
182 lines
6.7 KiB
Perl
182 lines
6.7 KiB
Perl
package xCAT_plugin::iscsi;
|
|
use strict;
|
|
use xCAT::Table;
|
|
use xCAT::TableUtils;
|
|
use Socket;
|
|
use File::Path;
|
|
use File::Basename;
|
|
use Getopt::Long;
|
|
Getopt::Long::Configure("bundling");
|
|
Getopt::Long::Configure("pass_through");
|
|
|
|
|
|
sub handled_commands {
|
|
return {
|
|
"setupiscsidev" => "iscsi",
|
|
};
|
|
}
|
|
|
|
sub get_tid {
|
|
|
|
#generate a unique tid given a node for tgtadm to use
|
|
my $node = shift;
|
|
my $tid = unpack("N", inet_aton($node));
|
|
$tid = $tid & ((2**31) - 1);
|
|
return $tid;
|
|
}
|
|
|
|
sub preprocess_request {
|
|
my $request = shift;
|
|
my $callback = shift;
|
|
my @requests = ();
|
|
my %iscsiserverhash;
|
|
if ($request->{_xcatpreprocessed}->[0] == 1) { return [$request]; }
|
|
my $iscsitab = xCAT::Table->new('iscsi');
|
|
foreach my $node (@{ $request->{node} }) {
|
|
my $tent = $iscsitab->getNodeAttribs($node, ['server']);
|
|
if ($tent and $tent->{server}) {
|
|
$iscsiserverhash{ $tent->{server} }->{$node} = 1;
|
|
} else {
|
|
$callback->({ error => ["No iscsi.server for $node, aborting request"] });
|
|
return [];
|
|
}
|
|
}
|
|
foreach my $iscsis (keys %iscsiserverhash) {
|
|
my $reqcopy = {%$request};
|
|
$reqcopy->{'_xcatdest'} = $iscsis;
|
|
$reqcopy->{_xcatpreprocessed}->[0] = 1;
|
|
$reqcopy->{node} = [ keys %{ $iscsiserverhash{$iscsis} } ];
|
|
push @requests, $reqcopy;
|
|
}
|
|
return \@requests;
|
|
}
|
|
|
|
sub process_request {
|
|
my $request = shift;
|
|
my $callback = shift;
|
|
unless (-x "/usr/sbin/tgtadm") {
|
|
$callback->({ error => "/usr/sbin/tgtadm does not exist, iSCSI plugin currently requires it, please install scsi-target-utils package under CentOS, RHEL, or Fedora. SLES support is not yet implemented", errorcode => [1] });
|
|
return;
|
|
}
|
|
my $lunsize = 4096;
|
|
if ($request->{arg}) {
|
|
@ARGV = @{ $request->{arg} };
|
|
GetOptions(
|
|
"size|s=i" => \$lunsize,
|
|
);
|
|
}
|
|
my $iscsitab = xCAT::Table->new('iscsi');
|
|
my @nodes = @{ $request->{node} };
|
|
|
|
my $nd = xCAT::NetworkUtils->getNodeDomains(\@nodes);
|
|
my %nodedomains = %{$nd};
|
|
|
|
my $iscsiprefix;
|
|
my @entries = xCAT::TableUtils->get_site_attribute("iscsidir");
|
|
my $t_entry = $entries[0];
|
|
if (defined($t_entry)) {
|
|
$iscsiprefix = $t_entry;
|
|
}
|
|
foreach my $node (@nodes) {
|
|
my $fileloc;
|
|
my %rsp;
|
|
%rsp = (name => [$node]);
|
|
my $iscsient = $iscsitab->getNodeAttribs($node, ['file']);
|
|
if ($iscsient and $iscsient->{file}) {
|
|
$fileloc = $iscsient->{file};
|
|
unless ($fileloc =~ /^\//) {
|
|
unless ($iscsiprefix) {
|
|
$rsp{error} = ["$node: Unable to identify file to back iSCSI LUN, no iscsidir in site table and iscsi.file entry for node is a relative path"];
|
|
$rsp{errorcode} = [1];
|
|
$callback->({ node => [ \%rsp ] });
|
|
%rsp = (name => [$node]);
|
|
next;
|
|
}
|
|
$fileloc = $iscsiprefix . "/" . $iscsient->{file};
|
|
}
|
|
} else {
|
|
unless ($iscsiprefix) {
|
|
$rsp{error} = ["$node: Unable to identify file to back iSCSI LUN, no iscsidir in site table nor iscsi.file entry for node (define at least either)"];
|
|
$rsp{errorcode} = [1];
|
|
$callback->({ node => [ \%rsp ] });
|
|
%rsp = (name => [$node]);
|
|
next;
|
|
}
|
|
$fileloc = "$iscsiprefix/$node";
|
|
$iscsitab->setNodeAttribs($node, { file => $fileloc });
|
|
}
|
|
unless (-d dirname($fileloc)) {
|
|
mkpath dirname($fileloc);
|
|
}
|
|
unless (-f $fileloc) {
|
|
$rsp{name} = [$node];
|
|
$rsp{data} = ["Creating $fileloc ($lunsize MB)"];
|
|
$callback->({ node => [ \%rsp ] });
|
|
%rsp = (name => [$node]);
|
|
$lunsize -= 1;
|
|
my $rc = system("dd if=/dev/zero of=$fileloc bs=1M count=1 seek=$lunsize");
|
|
$lunsize += 1;
|
|
if ($rc) {
|
|
$rsp{error} = ["dd process exited with return code $rc"];
|
|
$rsp{errorcode} = [1];
|
|
$callback->({ node => [ \%rsp ] });
|
|
%rsp = (name => [$node]);
|
|
next;
|
|
}
|
|
}
|
|
my $targname;
|
|
my $lun;
|
|
$iscsient = $iscsitab->getNodeAttribs($node, [ 'target', 'lun' ]);
|
|
if ($iscsient and $iscsient->{target}) {
|
|
$targname = $iscsient->{target};
|
|
}
|
|
if ($iscsient and defined($iscsient->{lun})) {
|
|
$lun = $iscsient->{lun};
|
|
} else {
|
|
$lun = '1';
|
|
$iscsitab->setNodeAttribs($node, { lun => $lun });
|
|
}
|
|
unless ($targname) {
|
|
my @date = localtime;
|
|
my $year = 1900 + $date[5];
|
|
my $month = $date[4];
|
|
my $domain = $nodedomains{$node};
|
|
$targname = "iqn.$year-$month.$domain:$node";
|
|
$iscsitab->setNodeAttribs($node, { target => $targname });
|
|
}
|
|
system("tgtadm --lld iscsi --mode target --op delete --tid " . get_tid($node) . " -T $targname");
|
|
my $rc = system("tgtadm --lld iscsi --mode target --op new --tid " . get_tid($node) . " -T $targname");
|
|
if ($rc) {
|
|
$rsp{error} = [ "tgtadm --lld iscsi --mode target --op new --tid " . get_tid($node) . " -T $targname returned $rc" ];
|
|
if ($rc == 27392) {
|
|
push @{ $rsp{error} }, "This likely indicates the need to do /etc/init.d/tgtd start";
|
|
}
|
|
$rsp{errorcode} = [1];
|
|
$callback->({ node => [ \%rsp ] });
|
|
%rsp = (name => [$node]);
|
|
next;
|
|
}
|
|
$rc = system("tgtadm --lld iscsi --mode logicalunit --op new --tid " . get_tid($node) . " --lun 1 --backing-store $fileloc --device-type disk");
|
|
if ($rc) {
|
|
$rsp{error} = [ "tgtadm --lld iscsi mode logicalunit --op new --tid " . get_tid($node) . " --lun 1 --backing-store $fileloc returned $rc" ];
|
|
$rsp{errorcode} = [1];
|
|
$callback->({ node => [ \%rsp ] });
|
|
%rsp = (name => [$node]);
|
|
next;
|
|
}
|
|
$rc = system("tgtadm --lld iscsi --mode target --op bind --tid " . get_tid($node) . " -I " . inet_ntoa(inet_aton($node)));
|
|
if ($rc) {
|
|
$rsp{error} = [ "tgtadm --lld iscsi --mode target --op bind --tid " . get_tid($node) . " -I " . inet_ntoa(inet_aton($node)) . " returned $rc" ];
|
|
$rsp{errorcode} = [1];
|
|
$callback->({ node => [ \%rsp ] });
|
|
%rsp = (name => [$node]);
|
|
} else {
|
|
$rsp{data} = ["iSCSI LUN configured"];
|
|
$callback->({ node => [ \%rsp ] });
|
|
%rsp = (name => [$node]);
|
|
}
|
|
}
|
|
}
|
|
|
|
1;
|