diff options
Diffstat (limited to 'storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeMgmt.pm')
-rw-r--r-- | storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeMgmt.pm | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeMgmt.pm b/storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeMgmt.pm new file mode 100644 index 00000000000..1056e3df623 --- /dev/null +++ b/storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeMgmt.pm @@ -0,0 +1,318 @@ +package NDB::Net::NodeMgmt; + +use strict; +use Carp; +use Symbol; + +require NDB::Net::Node; + +use vars qw(@ISA); +@ISA = qw(NDB::Net::Node); + +# constructors + +my $log; + +sub initmodule { + $log = NDB::Util::Log->instance; +} + +NDB::Net::NodeMgmt->attributes( + port => sub { s/^\s+|\s+$//g; /^\d+$/ }, +); + +sub new { + my $class = shift; + @_ % 2 == 0 or confess 0+@_; + my(%attr) = @_; + my $node = $class->SUPER::new(%attr, type => 'mgmt') + or $log->push, return undef; + $node->setport($attr{port}) + or $log->push, return undef; + return 1; +} + +# socket parser methods + +sub socketcommand { + my $node = shift; + my $socket; + $socket = NDB::Util::SocketINET->new or + $log->push($node), return undef; + $socket->settimeout(10); + $socket->connect($node->getserver->getcanon, $node->getport) or + $log->push($node), return undef; + $socket->write("GET STATUS\r\nBYE\r\n") or + $log->push($node), return undef; + my $out = ""; + my $data; + while ($data = $socket->read) { + $out .= $data; + } + $socket->close; + $out =~ s/\015//g; + return $out; +} + +sub get_status { + my $node = shift; + my $out = $node->socketcommand or + $log->push, return undef; + my @out = split(/\n/, $out); + $out[0] =~ /^get\s+status\s+(\d+)/i or + $log->put("bad line 0: $out[0]"), return undef; + my $cnt = $1; + my $ret = {}; + for (my $i = 1; $i <= $cnt; $i++) { + $out[$i] =~ /^$i\s+(.*)/ or + $log->put("bad line $i: $out[$i]"), return undef; + my $text = $1; + $text =~ s/^\s+|\s+$//g; + if ($text =~ /^ndb\s+(no_contact)\s+(\d+)$/i) { + $text = lc "$1"; + } elsif ($text =~ /^ndb\s+(starting)\s+(\d+)$/i) { + $text = lc "$1/$2"; + } elsif ($text =~ /^ndb\s+(started)\s+(\d+)$/i) { + $text = lc "$1"; + } elsif ($text =~ /^ndb\s+(shutting_down)\s+(\d+)$/i) { + $text = lc "$1"; + } elsif ($text =~ /^ndb\s+(restarting)\s+(\d+)$/i) { + $text = lc "$1"; + } elsif ($text =~ /^ndb\s+(unknown)\s+(\d+)$/i) { + $text = lc "$1"; + } + $ret->{node}{$i} = $text; + } + return $ret; +} + +# run methods + +sub getautoinifile { + my $node = shift; + @_ == 0 or confess 0+@_; + my $name = "config.txt"; + my $file = $node->getnodedir->getfile($name); + return $file; +} + +sub writeautoinifile { + my $node = shift; + @_ == 1 or confess 0+@_; + my($opts) = @_; + my $db = $node->getdb; + my $nodelist = $db->getnodelist('all'); + my $computers = {}; + for my $n (@$nodelist) { + $computers->{$n->getserver->getid} ||= { + id => $n->getserver->getid, + hostname => $n->getserver->getcanon, + }; + } + my $section = ""; # e.g. PROCESSES + my $auto; + my $edit = sub { + chomp; + s/^\s+|\s+$//g; + if (/^(\w+)$/) { + $section = uc($1); + } + elsif (/^\@loop$/i) { + $_ = "#$_"; + if ($auto) { + $log->put("nested \@loop"); + return undef; + } + $auto = {}; + } + elsif (/^\@base\s+(\S+)\s*$/) { + my $arg = $1; + $_ = "#$_"; + if (! $auto) { + $log->put("unexpected \@base"); + return undef; + } + if ($arg !~ /^\d+$/) { + $log->put("non-numerical \@base"); + return undef; + } + $auto->{base} = $arg; + } + elsif (/^\@end$/i) { + $_ = "#$_"; + if (! $auto) { + $log->put("unmatched \@end"); + return undef; + } + if ($section eq 'COMPUTERS') { + for my $id (sort { $a <=> $b } keys %$computers) { + my $computer = $computers->{$id}; + $_ .= "\n"; + $_ .= "\nId: " . $computer->{id}; + $_ .= "\nHostName: " . $computer->{hostname}; + if ($auto->{list}) { + $_ .= "\n#defaults"; + for my $s (@{$auto->{list}}) { + $_ .= "\n$s"; + } + } + } + } + elsif ($section eq 'PROCESSES') { + for my $n (@$nodelist) { + if ($auto->{type} && $n->gettype ne lc($auto->{type})) { + next; + } + $_ .= "\n"; + $_ .= "\nType: " . uc($n->gettype); + $_ .= "\nId: " . $n->getid; + $_ .= "\nExecuteOnComputer: " . $n->getserver->getid; + if ($auto->{list}) { + $_ .= "\n#defaults"; + for my $s (@{$auto->{list}}) { + $_ .= "\n$s"; + } + } + } + } + elsif ($section eq 'CONNECTIONS') { + if (! $auto->{type}) { + $log->put("cannot generate CONNECTIONS without type"); + return undef; + } + if (! defined($auto->{base})) { + $log->put("need \@base for CONNECTIONS"); + return undef; + } + my $key = $auto->{base}; + for (my $i1 = 0; $i1 <= $#$nodelist; $i1++) { + for (my $i2 = $i1+1; $i2 <= $#$nodelist; $i2++) { + my $n1 = $nodelist->[$i1]; + my $n2 = $nodelist->[$i2]; + if ($n1->gettype ne 'db' && $n2->gettype ne 'db') { + next; + } + $_ .= "\n"; + $_ .= "\nType: $auto->{type}"; + $_ .= "\nProcessId1: " . $n1->getid; + $_ .= "\nProcessId2: " . $n2->getid; + $key++; + if ($auto->{type} eq 'TCP') { + $_ .= "\nPortNumber: $key"; + if (my $list = $opts->{proxy}) { + my $id1 = $n1->getid; + my $id2 = $n2->getid; + if ($list =~ /\b$id1\b.*-.*\b$id2\b/) { + $key++; + $_ .= "\nProxy: $key"; + } elsif ($list =~ /\b$id2\b.*-.*\b$id1\b/) { + $key++; + $_ .= "\nProxy: $key"; + } + } + } + elsif ($auto->{type} eq 'SHM') { + $_ .= "\nShmKey: $key"; + } + else { + $log->put("cannot handle CONNECTIONS type $auto->{type}"); + return undef; + } + if ($auto->{list}) { + $_ .= "\n#defaults"; + for my $s (@{$auto->{list}}) { + $_ .= "\n$s"; + } + } + } + } + } + else { + $log->put("found \@end in unknown section '$section'"); + return undef; + } + undef $auto; + } + elsif (/^$/) { + } + elsif ($auto) { + if (/^Type:\s*(\w+)$/i) { + $auto->{type} = uc($1); + } + else { + $auto->{list} ||= []; + push(@{$auto->{list}}, $_); + } + $_ = ""; + return 1; # no output + } + $_ .= "\n"; + return 1; + }; + $node->getautoinifile->mkdir + or $log->push, return undef; + $node->getinifile->copyedit($node->getautoinifile, $edit) + or $log->push, return undef; + return 1; +} + +sub handleprepare { + my $node = shift; + @_ == 1 or confess 0+@_; + my($opts) = @_; + my $envdefs = $node->getenvdefs($opts); + defined($envdefs) or return undef; + my $nodedir = $node->getnodedir; + my $shellfile = $node->getshellfile; + my $port = $node->getport; + my $lpath = $node->getlocalcfg->getbasename; + $node->writeautoinifile($opts) + or $log->push, return undef; + my $ipath = $node->getautoinifile->getbasename; + $node->getbincfg->mkdir or $log->push, return undef; + my $cpath = $node->getbincfg->getbasename; + my $run; + if ($^O ne 'MSWin32') { + $run = "\$NDB_TOP/bin/mgmtsrvr"; + } else { + $run = "mgmtsrvr"; + } + my $statport = $port + 1; + $run .= " -l $lpath -c $ipath"; + if ($node->hasrun) { + $run = $node->getrun; + } + if (defined($opts->{run})) { + $run = $opts->{run}; + } + $log->put("run: $run")->push($node)->user; + if ($^O ne 'MSWin32') { + $shellfile->puttext(<<END) or $log->push, return undef; +$envdefs +cd @{[ $nodedir->getpath ]} || exit 1 +set -x +exec \$DEBUGGER $run +END + } else { + $shellfile->puttext(<<END) or $log->push, return undef; +$envdefs +cd @{[ $nodedir->getpath ]} +call $run +END + } + return 1; +} + +sub cmd_stopnode_fg { + my $node = shift; + @_ == 1 or confess 0+@_; + my($cmd) = @_; + $log->put("write: quit")->push($node)->user; + $node->getiow->write("quit\n"); + $node->setstate('stop') + or log->push($node), return undef; + return 1; +} + +1; +# vim:set sw=4: |