~ubuntu-branches/ubuntu/trusty/mysql-5.6/trusty

« back to all changes in this revision

Viewing changes to storage/ndb/test/tools/cpcc.cpp

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-12 11:54:27 UTC
  • Revision ID: package-import@ubuntu.com-20140212115427-oq6tfsqxl1wuwehi
Tags: upstream-5.6.15
ImportĀ upstreamĀ versionĀ 5.6.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
 
3
 
 
4
   This program is free software; you can redistribute it and/or modify
 
5
   it under the terms of the GNU General Public License as published by
 
6
   the Free Software Foundation; version 2 of the License.
 
7
 
 
8
   This program is distributed in the hope that it will be useful,
 
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
   GNU General Public License for more details.
 
12
 
 
13
   You should have received a copy of the GNU General Public License
 
14
   along with this program; if not, write to the Free Software
 
15
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
 
16
*/
 
17
 
 
18
 
 
19
#include <ndb_global.h>
 
20
#include <getarg.h>
 
21
#include "CpcClient.hpp"
 
22
 
 
23
#include <portlib/NdbEnv.h>
 
24
#include <util/NdbOut.hpp>
 
25
 
 
26
#define DEFAULT_PORT 1234
 
27
#define ENV_HOSTS "NDB_CPCC_HOSTS"
 
28
 
 
29
struct settings {
 
30
  int m_longl;
 
31
  short m_port;
 
32
} g_settings = { 0 , DEFAULT_PORT };
 
33
 
 
34
Vector<SimpleCpcClient*> g_hosts;
 
35
int connect(Vector<SimpleCpcClient*>&);
 
36
 
 
37
class Expression {
 
38
public:
 
39
  virtual ~Expression() {}
 
40
  virtual bool evaluate(SimpleCpcClient*, const SimpleCpcClient::Process &)= 0;
 
41
};
 
42
 
 
43
int for_each(Vector<SimpleCpcClient*>& list, Expression &);
 
44
int start_stop(const char * cmd, Vector<SimpleCpcClient*>& list, 
 
45
               Vector<Vector<Uint32> >& procs);
 
46
 
 
47
class True : public Expression {
 
48
public:
 
49
  virtual ~True() {}
 
50
  virtual bool evaluate(SimpleCpcClient*, const SimpleCpcClient::Process & p){
 
51
    return true;
 
52
  }
 
53
};
 
54
 
 
55
class FieldEQ : public Expression {
 
56
  BaseString m_field;
 
57
  BaseString m_value;
 
58
public:
 
59
  FieldEQ(const BaseString & field, const BaseString & value){
 
60
    m_field = field;
 
61
    m_value = value;
 
62
  }
 
63
  virtual ~FieldEQ(){}
 
64
 
 
65
  virtual bool evaluate(SimpleCpcClient*, const SimpleCpcClient::Process & p){
 
66
    BaseString v;
 
67
    if(m_field == "name") v = p.m_name;
 
68
  
 
69
    if(m_field == "type") v = p.m_type;
 
70
    if(m_field == "status") v = p.m_status;
 
71
    if(m_field == "owner") v = p.m_owner;
 
72
    if(m_field == "group") v = p.m_group;
 
73
    if(m_field == "path") v = p.m_path;
 
74
    if(m_field == "args") v = p.m_args;
 
75
    if(m_field == "env") v = p.m_env;
 
76
    if(m_field == "cwd") v = p.m_cwd;
 
77
    
 
78
    if(m_field == "stdin") v = p.m_stdin;
 
79
    if(m_field == "stdout") v = p.m_stdout;
 
80
    if(m_field == "stderr") v = p.m_stderr;
 
81
    
 
82
    return v == m_value;
 
83
  }
 
84
};
 
85
 
 
86
class Match : public Expression {
 
87
  Expression & m_cond;
 
88
  Expression & m_apply;
 
89
public:
 
90
  Match(Expression& condition, Expression & rule)
 
91
    : m_cond(condition), m_apply(rule) {
 
92
  }
 
93
  virtual ~Match(){}
 
94
 
 
95
  virtual bool evaluate(SimpleCpcClient* c,const SimpleCpcClient::Process & p){
 
96
    if(m_cond.evaluate(c, p))
 
97
      return m_apply.evaluate(c, p);
 
98
    return false;
 
99
  }
 
100
};
 
101
 
 
102
class Operate : public Expression {
 
103
  const char * cmd;
 
104
  SimpleCpcClient * host;
 
105
  settings & sets;
 
106
public:
 
107
  Operate(const char * c, settings & s) : sets(s) {
 
108
    cmd = c;
 
109
    host = 0;
 
110
  }
 
111
  virtual ~Operate() {}
 
112
  
 
113
  virtual bool evaluate(SimpleCpcClient*, const SimpleCpcClient::Process & p);
 
114
};
 
115
 
 
116
class ProcEQ : public Expression {
 
117
  SimpleCpcClient * host;
 
118
  Uint32 id;
 
119
public:
 
120
  ProcEQ(SimpleCpcClient* h, Uint32 i){
 
121
    host = h; id = i;
 
122
  }
 
123
  virtual ~ProcEQ() {}
 
124
  virtual bool evaluate(SimpleCpcClient* c,const SimpleCpcClient::Process & p){
 
125
    return p.m_id == (int)id && c == host;
 
126
  }
 
127
};
 
128
 
 
129
class OrExpr : public Expression {
 
130
  Expression * m_rule;
 
131
  Vector<Expression *> m_cond;
 
132
  bool on_empty;
 
133
public:
 
134
  OrExpr(Expression * rule, bool onEmp = true){
 
135
    m_rule = rule;
 
136
    on_empty = onEmp;
 
137
  }
 
138
 
 
139
  virtual ~OrExpr(){}
 
140
 
 
141
  virtual bool evaluate(SimpleCpcClient* c, const SimpleCpcClient::Process & p){
 
142
    bool run = on_empty;
 
143
    for(size_t i = 0; i<m_cond.size(); i++){
 
144
      if(m_cond[i]->evaluate(c, p)){
 
145
        run = true;
 
146
        break;
 
147
      }
 
148
    }
 
149
    if(run)
 
150
      return m_rule->evaluate(c, p);
 
151
    return false;
 
152
  }
 
153
 
 
154
  void push_back(Expression * expr){
 
155
    m_cond.push_back(expr);
 
156
  }
 
157
};
 
158
 
 
159
void
 
160
add_host(Vector<SimpleCpcClient*> & hosts, BaseString tmp){
 
161
  Vector<BaseString> split;
 
162
  tmp.split(split, ":");
 
163
  
 
164
  short port = g_settings.m_port;
 
165
  if(split.size() > 1)
 
166
    port = atoi(split[1].c_str());
 
167
  
 
168
  hosts.push_back(new SimpleCpcClient(split[0].c_str(), port));
 
169
}
 
170
 
 
171
void
 
172
add_hosts(Vector<SimpleCpcClient*> & hosts, BaseString list){
 
173
  Vector<BaseString> split;
 
174
  list.split(split);
 
175
  for(size_t i = 0; i<split.size(); i++){
 
176
    add_host(hosts, split[i]);
 
177
  }
 
178
}
 
179
 
 
180
int 
 
181
main(int argc, const char** argv){
 
182
  ndb_init();
 
183
  int help = 0;
 
184
  const char *cmd=0, *name=0, *group=0, *owner=0;
 
185
  int list = 0, start = 0, stop = 0, rm = 0;
 
186
  struct getargs args[] = {
 
187
    { "cmd", 'c', arg_string, &cmd, "command", "command to run (default ls)" }
 
188
    ,{ "name", 'n', arg_string, &name, 
 
189
       "apply command for all processes with name", "" }
 
190
    ,{ "group", 'g', arg_string, &group, 
 
191
       "apply command for all processes in group", "" }
 
192
    ,{ "owner", 'g', arg_string, &owner,
 
193
       "apply command for all processes with owner", "" }
 
194
    ,{ "long", 'l', arg_flag, &g_settings.m_longl, "long", "long listing"}
 
195
    ,{ "usage", '?', arg_flag, &help, "Print help", "" }
 
196
    ,{ "ls",  0, arg_flag, &list, "-c list", "list process(es)" }
 
197
    ,{ "start", 0, arg_flag, &start, "-c start", "start process(es)" }
 
198
    ,{ "stop",  0, arg_flag, &stop, "-c stop", "stop process(es)" }
 
199
    ,{ "rm",    0, arg_flag, &rm, "-c rm", "undefine process(es)" }
 
200
  };
 
201
  const int num_args = 10;
 
202
  int i; 
 
203
  int optind = 0;
 
204
  char desc[] = "[host:[port]]\n";
 
205
  
 
206
  if(getarg(args, num_args, argc, argv, &optind) || help) {
 
207
    arg_printusage(args, num_args, argv[0], desc);
 
208
    return 1;
 
209
  }
 
210
 
 
211
  if(list + start + stop + rm > 1){
 
212
    ndbout_c("Can only specify one command");
 
213
    arg_printusage(args, num_args, argv[0], desc);
 
214
    return 1;
 
215
  }
 
216
  
 
217
  if(list) cmd = "list";
 
218
  if(start) cmd = "start";
 
219
  if(stop) cmd = "stop";
 
220
  if(rm) cmd = "rm";
 
221
  if(!cmd) cmd = "list";
 
222
  
 
223
  Expression * m_expr = 0;
 
224
 
 
225
  for(i = optind; i<argc; i++){
 
226
    add_host(g_hosts, argv[i]);
 
227
  }
 
228
 
 
229
  OrExpr * orE = new OrExpr(new Operate(cmd, g_settings), true);
 
230
  m_expr = orE;
 
231
  for(i = optind; i<argc; i++){
 
232
    BaseString tmp(argv[i]);
 
233
    Vector<BaseString> split;
 
234
    tmp.split(split, ":");
 
235
    
 
236
    if(split.size() > 2){
 
237
      Uint32 id = atoi(split[2].c_str());
 
238
      orE->push_back(new ProcEQ(g_hosts[i-optind], id));        
 
239
    }
 
240
  }
 
241
 
 
242
  if(g_hosts.size() == 0){
 
243
    char buf[1024];
 
244
    if(NdbEnv_GetEnv(ENV_HOSTS, buf, sizeof(buf))){
 
245
      add_hosts(g_hosts, BaseString(buf));
 
246
    }
 
247
  }
 
248
  
 
249
  if(g_hosts.size() == 0){
 
250
    g_hosts.push_back(new SimpleCpcClient("localhost", g_settings.m_port));
 
251
  }
 
252
  
 
253
  if(group != 0){
 
254
    Expression * tmp = new FieldEQ("group", group);
 
255
    m_expr = new Match(* tmp, * m_expr);
 
256
  }
 
257
  
 
258
  if(name != 0){
 
259
    Expression * tmp = new FieldEQ("name", name);
 
260
    m_expr = new Match(* tmp, * m_expr);
 
261
  }
 
262
 
 
263
  if(owner != 0){
 
264
    Expression * tmp = new FieldEQ("owner", owner);
 
265
    m_expr = new Match(* tmp, * m_expr);
 
266
  }
 
267
 
 
268
  connect(g_hosts);
 
269
  for_each(g_hosts, * m_expr);
 
270
  
 
271
  return 0;
 
272
}
 
273
 
 
274
int
 
275
connect(Vector<SimpleCpcClient*>& list){
 
276
  for(size_t i = 0; i<list.size(); i++){
 
277
    if(list[i]->connect() != 0){
 
278
      ndbout_c("Failed to connect to %s:%d", 
 
279
               list[i]->getHost(), list[i]->getPort());
 
280
      delete list[i]; list[i] = 0;
 
281
    }
 
282
  }
 
283
  return 0;
 
284
}
 
285
 
 
286
int
 
287
for_each(Vector<SimpleCpcClient*>& list, Expression & expr){
 
288
  for(size_t i = 0; i<list.size(); i++){
 
289
    if(list[i] == 0)
 
290
      continue;
 
291
    Properties p;
 
292
    Vector<SimpleCpcClient::Process> procs;
 
293
    if(list[i]->list_processes(procs, p) != 0){
 
294
      ndbout << "Failed to list processes on " 
 
295
             << list[i]->getHost() << ":" << list[i]->getPort() << endl;
 
296
    }
 
297
    for(size_t j = 0; j<procs.size(); j++)
 
298
      expr.evaluate(list[i], procs[j]);
 
299
  }
 
300
  return 0;
 
301
}
 
302
 
 
303
bool
 
304
Operate::evaluate(SimpleCpcClient* c, const SimpleCpcClient::Process & pp){
 
305
  Uint32 id = pp.m_id;
 
306
  Properties p;
 
307
  int res;
 
308
 
 
309
  if(strcasecmp(cmd, "start") == 0)
 
310
    res = c->start_process(id, p);
 
311
  else if(strcasecmp(cmd, "stop") == 0)
 
312
    res = c->stop_process(id, p);
 
313
  else if(strcasecmp(cmd, "rm") == 0)
 
314
    res = c->undefine_process(id, p);
 
315
  else if(strcasecmp(cmd, "list") == 0){
 
316
    if(!sets.m_longl){
 
317
      if(host != c){
 
318
        ndbout_c("--- %s:%d", c->getHost(), c->getPort());
 
319
        host = c;
 
320
      }
 
321
    }
 
322
    
 
323
    char s = 0;
 
324
    const char * status = pp.m_status.c_str();
 
325
    if(strcmp(status, "stopped") == 0)  s = '-';
 
326
    if(strcmp(status, "starting") == 0) s = 's';
 
327
    if(strcmp(status, "running") == 0)  s = 'r';
 
328
    if(strcmp(status, "stopping") == 0)  s = 'k';    
 
329
    if(s == 0) s = '?';
 
330
 
 
331
    if(!sets.m_longl){
 
332
      ndbout_c("%c%c\t%d\t%s\t%s\t%s(%s)", 
 
333
               s, 
 
334
               pp.m_type.c_str()[0], id, pp.m_owner.c_str(), 
 
335
               pp.m_group.c_str(), pp.m_name.c_str(), pp.m_path.c_str());
 
336
    } else {
 
337
      ndbout_c("%c%c %s:%d:%d %s %s %s(%s)", 
 
338
               s, pp.m_type.c_str()[0], c->getHost(), c->getPort(),
 
339
               id, pp.m_owner.c_str(), pp.m_group.c_str(), 
 
340
               pp.m_name.c_str(), pp.m_path.c_str());
 
341
    }
 
342
    return true;
 
343
  }
 
344
  
 
345
  if(res != 0){
 
346
    BaseString msg;
 
347
    p.get("errormessage", msg);
 
348
    ndbout_c("Failed to %s %d on %s:%d - %s",
 
349
             cmd, id, 
 
350
             c->getHost(), c->getPort(), msg.c_str());
 
351
    return false;
 
352
  }
 
353
  
 
354
  return true;
 
355
}
 
356
 
 
357
template class Vector<Expression*>;
 
358
template class Vector<SimpleCpcClient*>;