summaryrefslogtreecommitdiff
path: root/storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeMgmt.pm
diff options
context:
space:
mode:
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.pm318
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: