MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
atrt.hpp
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 #ifndef atrt_config_hpp
19 #define atrt_config_hpp
20 
21 #include <ndb_global.h>
22 #include <Vector.hpp>
23 #include <BaseString.hpp>
24 #include <NdbAutoPtr.hpp>
25 #include <Logger.hpp>
26 #include <mgmapi.h>
27 #include <CpcClient.hpp>
28 #include <Properties.hpp>
29 #include <mysql.h>
30 #include <my_dir.h>
31 
32 enum ErrorCodes
33 {
34  ERR_OK = 0,
35  ERR_NDB_FAILED = 101,
36  ERR_SERVERS_FAILED = 102,
37  ERR_MAX_TIME_ELAPSED = 103,
38  ERR_COMMAND_FAILED = 104,
39  ERR_FAILED_TO_START = 105
40 };
41 
42 struct atrt_host
43 {
44  unsigned m_index;
45  BaseString m_user;
46  BaseString m_basedir;
47  BaseString m_hostname;
48  SimpleCpcClient * m_cpcd;
49  Vector<struct atrt_process*> m_processes;
50 };
51 
53 {
54  enum Feature {
55  AO_REPLICATION = 1,
56  AO_NDBCLUSTER = 2
57  };
58 
59  int m_features;
60  Properties m_loaded;
61  Properties m_generated;
62 };
63 
64 struct atrt_process
65 {
66  unsigned m_index;
67  struct atrt_host * m_host;
68  struct atrt_cluster * m_cluster;
69 
70  enum Type {
71  AP_ALL = 255
72  ,AP_NDBD = 1
73  ,AP_NDB_API = 2
74  ,AP_NDB_MGMD = 4
75  ,AP_MYSQLD = 16
76  ,AP_CLIENT = 32
77  ,AP_CLUSTER = 256 // Used for options parsing for "cluster" options
78  } m_type;
79 
81 
82  NdbMgmHandle m_ndb_mgm_handle; // if type == ndb_mgm
83  atrt_process * m_mysqld; // if type == client
84  atrt_process * m_rep_src; // if type == mysqld
85  Vector<atrt_process*> m_rep_dst; // if type == mysqld
86  MYSQL m_mysql; // if type == mysqld
87  atrt_options m_options;
88  uint m_nodeid; // if m_fix_nodeid
89 
90  struct {
91  bool m_saved;
93  } m_save;
94 
95 };
96 
98 {
99  BaseString m_name;
100  BaseString m_dir;
101  Vector<atrt_process*> m_processes;
102  atrt_options m_options;
103  uint m_next_nodeid; // if m_fix_nodeid
104 };
105 
106 struct atrt_config
107 {
108  bool m_generated;
109  BaseString m_key;
110  BaseString m_replication;
111  Vector<atrt_host*> m_hosts;
112  Vector<atrt_cluster*> m_clusters;
113  Vector<atrt_process*> m_processes;
114 };
115 
117 {
118  bool m_report;
119  bool m_run_all;
120  time_t m_max_time;
121  BaseString m_command;
122  BaseString m_args;
123  BaseString m_name;
124 };
125 
126 extern Logger g_logger;
127 
128 bool parse_args(int argc, char** argv);
129 bool setup_config(atrt_config&, const char * mysqld);
130 bool configure(atrt_config&, int setup);
131 bool setup_directories(atrt_config&, int setup);
132 bool setup_files(atrt_config&, int setup, int sshx);
133 
134 bool deploy(int, atrt_config&);
135 bool sshx(atrt_config&, unsigned procmask);
136 bool start(atrt_config&, unsigned procmask);
137 
138 bool remove_dir(const char *, bool incl = true);
139 bool connect_hosts(atrt_config&);
140 bool connect_ndb_mgm(atrt_config&);
141 bool wait_ndb(atrt_config&, int ndb_mgm_node_status);
142 bool start_processes(atrt_config&, int);
143 bool stop_processes(atrt_config&, int);
144 bool update_status(atrt_config&, int);
145 int is_running(atrt_config&, int);
146 bool gather_result(atrt_config&, int * result);
147 
148 bool read_test_case(FILE *, atrt_testcase&, int& line);
149 bool setup_test_case(atrt_config&, const atrt_testcase&);
150 
151 bool setup_hosts(atrt_config&);
152 
154 
155 bool start_process(atrt_process & proc);
156 bool stop_process(atrt_process & proc);
157 
165 bool reset_config(atrt_config&);
166 
167 NdbOut&
168 operator<<(NdbOut& out, const atrt_process& proc);
169 
173 bool setup_db(atrt_config&);
174 
178 extern Logger g_logger;
179 
180 extern const char * g_cwd;
181 extern const char * g_my_cnf;
182 extern const char * g_user;
183 extern const char * g_basedir;
184 extern const char * g_prefix;
185 extern const char * g_prefix1;
186 extern int g_baseport;
187 extern int g_fqpn;
188 extern int g_fix_nodeid;
189 extern int g_default_ports;
190 
191 extern const char * g_clusters;
192 
193 #ifdef _WIN32
194 #include <direct.h>
195 
196 inline int lstat(const char *name, struct stat *buf) {
197  return stat(name, buf);
198 }
199 
200 inline int S_ISREG(int x) {
201  return x & _S_IFREG;
202 }
203 
204 inline int S_ISDIR(int x) {
205  return x & _S_IFDIR;
206 }
207 
208 #endif
209 
210 
211 /* in-place replace */
212 static inline char* replace_chars(char *str, char from, char to)
213 {
214  int i;
215 
216  for(i = 0; str[i]; i++) {
217  if(i && str[i]==from && str[i-1]!=' ') {
218  str[i]=to;
219  }
220  }
221  return str;
222 }
223 
224 static inline BaseString &replace_chars(BaseString &bs, char from, char to)
225 {
226  replace_chars((char*)bs.c_str(), from, to);
227  return bs;
228 }
229 static inline BaseString &to_native(BaseString &bs) {
230  return replace_chars(bs, DIR_SEPARATOR[0]=='/'?'\\':'/', DIR_SEPARATOR[0]);
231 }
232 static inline BaseString &to_fwd_slashes(BaseString &bs) {
233  return replace_chars(bs, '\\', '/');
234 }
235 static inline char* to_fwd_slashes(char* bs) {
236  return replace_chars(bs, '\\', '/');
237 }
238 
239 //you must free() the result
240 static inline char* replace_drive_letters(const char* path) {
241 
242  int i, j;
243  int count; // number of ':'s in path
244  char *retval; // return value
245  const char cygdrive[] = "/cygdrive";
246  size_t cyglen = strlen(cygdrive), retval_len;
247 
248  for(i = 0, count = 0; path[i]; i++) {
249  count += path[i] == ':';
250  }
251  retval_len = strlen(path) + count * cyglen + 1;
252  retval = (char*)malloc(retval_len);
253 
254  for(i = j = 0; path[i]; i++) {
255  if(path[i] && path[i+1]) {
256  if( (!i || isspace(path[i-1]) || ispunct(path[i-1])) && path[i+1] == ':')
257 {
258  assert(path[i+2] == '/');
259  j += BaseString::snprintf(retval + j, retval_len - 1, "%s/%c", cygdrive, path[i]);
260  i++;
261  continue;
262  }
263  }
264  retval[j++] = path[i];
265  }
266  retval[j] = 0;
267 
268  return retval;
269 }
270 
271 static inline int sh(const char *script){
272 
273 #ifdef _WIN32
274  g_logger.debug("sh('%s')", script);
275 
276  /*
277  Running sh script on Windows
278  1) Write the command to run into temporary file
279  2) Run the temporary file with 'sh <temp_file_name>'
280  */
281 
282  char tmp_path[MAX_PATH];
283  if (GetTempPath(sizeof(tmp_path), tmp_path) == 0)
284  {
285  g_logger.error( "GetTempPath failed, error: %d", GetLastError());
286  return -1;
287  }
288 
289  char tmp_file[MAX_PATH];
290  if (GetTempFileName(tmp_path, "sh_", 0, tmp_file) == 0)
291  {
292  g_logger.error( "GetTempFileName failed, error: %d", GetLastError());
293  return -1;
294  }
295 
296  FILE* fp = fopen(tmp_file, "w");
297  if (fp == NULL)
298  {
299  g_logger.error( "Cannot open file '%s', error: %d", tmp_file, errno);
300  return -1;
301  }
302 
303  // cygwin'ify the script and write it to temp file
304  {
305  char* cygwin_script = replace_drive_letters(script);
306  g_logger.debug(" - cygwin_script: '%s' ", cygwin_script);
307  fprintf(fp, "%s", cygwin_script);
308  free(cygwin_script);
309  }
310 
311  fclose(fp);
312 
313  // Run the temp file with "sh"
314  BaseString command;
315  command.assfmt("sh %s", tmp_file);
316  g_logger.debug(" - running '%s' ", command.c_str());
317 
318  int ret = system(command.c_str());
319  if (ret == 0)
320  g_logger.debug(" - OK!");
321  else
322  g_logger.warning("Running the command '%s' as '%s' failed, ret: %d",
323  script, command.c_str(), ret);
324 
325  // Remove the temp file
326  unlink(tmp_file);
327 
328  return ret;
329 
330 #else
331 
332  return system(script);
333 
334 #endif
335 
336 }
337 #endif