int main(int argc, const char** argv){ ndb_init(); int _help = 0; const char* db = 0; const char* connectstring1 = 0; const char* connectstring2 = 0; struct getargs args[] = { { "connectstring1", 'c', arg_string, &connectstring1, "connectstring1", "" }, { "connectstring2", 'C', arg_string, &connectstring2, "connectstring2", "" }, { "database", 'd', arg_string, &db, "Database", "" }, { "usage", '?', arg_flag, &_help, "Print help", "" } }; int num_args = sizeof(args) / sizeof(args[0]); int optind = 0, i; char desc[] = "<tabname>+ \nThis program listen to events on specified tables\n"; if(getarg(args, num_args, argc, argv, &optind) || argv[optind] == NULL || _help) { arg_printusage(args, num_args, argv[0], desc); return NDBT_ProgramExit(NDBT_WRONGARGS); } // Connect to Ndb Ndb_cluster_connection con(connectstring1); if(con.connect(12, 5, 1) != 0) { return NDBT_ProgramExit(NDBT_FAILED); } Ndb MyNdb( &con, db ? db : "TEST_DB" ); if(MyNdb.init() != 0){ ERR(MyNdb.getNdbError()); return NDBT_ProgramExit(NDBT_FAILED); } // Connect to Ndb and wait for it to become ready while(MyNdb.waitUntilReady() != 0) ndbout << "Waiting for ndb to become ready..." << endl; Ndb_cluster_connection *con2 = NULL; Ndb *ndb2 = NULL; if (connectstring2) { con2 = new Ndb_cluster_connection(connectstring2); if(con2->connect(12, 5, 1) != 0) { return NDBT_ProgramExit(NDBT_FAILED); } ndb2 = new Ndb( con2, db ? db : "TEST_DB" ); if(ndb2->init() != 0){ ERR(ndb2->getNdbError()); return NDBT_ProgramExit(NDBT_FAILED); } // Connect to Ndb and wait for it to become ready while(ndb2->waitUntilReady() != 0) ndbout << "Waiting for ndb to become ready..." << endl; } int result = 0; NdbDictionary::Dictionary *myDict = MyNdb.getDictionary(); Vector<NdbDictionary::Event*> events; Vector<NdbEventOperation*> event_ops; int sz = 0; for(i= optind; i<argc; i++) { const NdbDictionary::Table* table= myDict->getTable(argv[i]); if(!table) { ndbout_c("Could not find table: %s, skipping", argv[i]); continue; } BaseString name; name.appfmt("EV-%s", argv[i]); NdbDictionary::Event *myEvent= new NdbDictionary::Event(name.c_str()); myEvent->setTable(table->getName()); myEvent->addTableEvent(NdbDictionary::Event::TE_ALL); for(int a = 0; a < table->getNoOfColumns(); a++){ myEvent->addEventColumn(a); } if (myDict->createEvent(* myEvent)) { if(myDict->getNdbError().classification == NdbError::SchemaObjectExists) { g_info << "Event creation failed event exists. Removing...\n"; if (myDict->dropEvent(name.c_str())) { g_err << "Failed to drop event: " << myDict->getNdbError() << endl; result = 1; goto end; } // try again if (myDict->createEvent(* myEvent)) { g_err << "Failed to create event: " << myDict->getNdbError() << endl; result = 1; goto end; } } else { g_err << "Failed to create event: " << myDict->getNdbError() << endl; result = 1; goto end; } } events.push_back(myEvent); NdbEventOperation* pOp = MyNdb.createEventOperation(name.c_str()); if ( pOp == NULL ) { g_err << "Event operation creation failed" << endl; result = 1; goto end; } event_values.push_back(Vector<NdbRecAttr *>()); event_pre_values.push_back(Vector<NdbRecAttr *>()); for (int a = 0; a < table->getNoOfColumns(); a++) { event_values[sz]. push_back(pOp->getValue(table->getColumn(a)->getName())); event_pre_values[sz]. push_back(pOp->getPreValue(table->getColumn(a)->getName())); } event_ops.push_back(pOp); { struct Table_info ti; ti.id = sz; table_infos.push_back(ti); } pOp->setCustomData((void *)&table_infos[sz]); sz++; } for(i= 0; i<(int)event_ops.size(); i++) { if (event_ops[i]->execute()) { g_err << "operation execution failed: " << event_ops[i]->getNdbError() << endl; result = 1; goto end; } } struct Trans_arg trans_arg; while(true) { while(MyNdb.pollEvents(100) == 0); NdbEventOperation* pOp= MyNdb.nextEvent(); while(pOp) { Uint64 gci= pOp->getGCI(); Uint64 cnt_i= 0, cnt_u= 0, cnt_d= 0; if (ndb2) do_begin(ndb2, trans_arg); do { switch(pOp->getEventType()) { case NdbDictionary::Event::TE_INSERT: cnt_i++; if (ndb2) do_insert(trans_arg, pOp); break; case NdbDictionary::Event::TE_DELETE: cnt_d++; if (ndb2) do_delete(trans_arg, pOp); break; case NdbDictionary::Event::TE_UPDATE: cnt_u++; if (ndb2) do_update(trans_arg, pOp); break; case NdbDictionary::Event::TE_CLUSTER_FAILURE: break; case NdbDictionary::Event::TE_ALTER: break; case NdbDictionary::Event::TE_DROP: break; case NdbDictionary::Event::TE_NODE_FAILURE: break; case NdbDictionary::Event::TE_SUBSCRIBE: case NdbDictionary::Event::TE_UNSUBSCRIBE: break; default: /* We should REALLY never get here. */ ndbout_c("Error: unknown event type: %u", (Uint32)pOp->getEventType()); abort(); } } while ((pOp= MyNdb.nextEvent()) && gci == pOp->getGCI()); if (ndb2) do_commit(trans_arg); ndbout_c("GCI: %lld events: %lld(I) %lld(U) %lld(D)", gci, cnt_i, cnt_u, cnt_d); } } end: for(i= 0; i<(int)event_ops.size(); i++) MyNdb.dropEventOperation(event_ops[i]); if (ndb2) delete ndb2; if (con2) delete con2; return NDBT_ProgramExit(NDBT_OK); }
NodeType(Uint32 node_type) { const char* str= NULL; const char* alias= ndb_mgm_get_node_type_alias_string((ndb_mgm_node_type)node_type, &str); m_str.assfmt("%s(%s)", alias, str); }
const char* c_str() { return m_str.c_str(); }
static inline int sh(const char *script){ #ifdef _WIN32 g_logger.debug("sh('%s')", script); /* Running sh script on Windows 1) Write the command to run into temporary file 2) Run the temporary file with 'sh <temp_file_name>' */ char tmp_path[MAX_PATH]; if (GetTempPath(sizeof(tmp_path), tmp_path) == 0) { g_logger.error( "GetTempPath failed, error: %d", GetLastError()); return -1; } char tmp_file[MAX_PATH]; if (GetTempFileName(tmp_path, "sh_", 0, tmp_file) == 0) { g_logger.error( "GetTempFileName failed, error: %d", GetLastError()); return -1; } FILE* fp = fopen(tmp_file, "w"); if (fp == NULL) { g_logger.error( "Cannot open file '%s', error: %d", tmp_file, errno); return -1; } // cygwin'ify the script and write it to temp file { char* cygwin_script = replace_drive_letters(script); g_logger.debug(" - cygwin_script: '%s' ", cygwin_script); fprintf(fp, "%s", cygwin_script); free(cygwin_script); } fclose(fp); // Run the temp file with "sh" BaseString command; command.assfmt("sh %s", tmp_file); g_logger.debug(" - running '%s' ", command.c_str()); int ret = system(command.c_str()); if (ret == 0) g_logger.debug(" - OK!"); else g_logger.warning("Running the command '%s' as '%s' failed, ret: %d", script, command.c_str(), ret); // Remove the temp file unlink(tmp_file); return ret; #else return system(script); #endif }
bool call(const char* cmd, const Properties& args, const char* cmd_reply, Properties& reply, const char* bulk = NULL, bool name_value_pairs = true){ if (!is_connected()){ error("call: not connected"); return false; } SocketOutputStream out(socket()); if (out.println("%s", cmd)){ error("call: println failed at line %d", __LINE__); return false; } Properties::Iterator iter(&args); const char *name; while((name = iter.next()) != NULL) { PropertiesType t; Uint32 val_i; Uint64 val_64; BaseString val_s; args.getTypeOf(name, &t); switch(t) { case PropertiesType_Uint32: args.get(name, &val_i); if (out.println("%s: %d", name, val_i)){ error("call: println failed at line %d", __LINE__); return false; } break; case PropertiesType_Uint64: args.get(name, &val_64); if (out.println("%s: %Ld", name, val_64)){ error("call: println failed at line %d", __LINE__); return false; } break; case PropertiesType_char: args.get(name, val_s); if (out.println("%s: %s", name, val_s.c_str())){ error("call: println failed at line %d", __LINE__); return false; } break; default: case PropertiesType_Properties: /* Illegal */ abort(); break; } } // Emtpy line terminates argument list if (out.print("\n")){ error("call: print('\n') failed at line %d", __LINE__); return false; } // Send any bulk data if (bulk) { if (out.write(bulk, strlen(bulk)) >= 0) { if (out.write("\n", 1) < 0) { error("call: print('<bulk>') failed at line %d", __LINE__); return false; } } } BaseString buf; SocketInputStream2 in(socket()); if (cmd_reply) { // Read the reply header and compare against "cmd_reply" if (!in.gets(buf)){ error("call: could not read reply command"); return false; } // 1. Check correct reply header if (buf != cmd_reply){ error("call: unexpected reply command, expected: '%s', got '%s'", cmd_reply, buf.c_str()); return false; } } // 2. Read lines until empty line int line = 1; while(in.gets(buf)){ // empty line -> end of reply if (buf == "") return true; if (name_value_pairs) { // 3a. Read colon separated name value pair, split // the name value pair on first ':' Vector<BaseString> name_value_pair; if (buf.split(name_value_pair, ":", 2) != 2){ error("call: illegal name value pair '%s' received", buf.c_str()); return false; } reply.put(name_value_pair[0].trim(" ").c_str(), name_value_pair[1].trim(" ").c_str()); } else { // 3b. Not name value pair, save the line into "reply" // using unique key reply.put("line", line++, buf.c_str()); } } error("call: should never come here"); reply.print(); abort(); return false; }
virtual void info(BaseString &pMsg) const { info(pMsg.c_str()); };
virtual void debug(BaseString &pMsg) const { debug(pMsg.c_str()); };
virtual void error(BaseString &pMsg) const { error(pMsg.c_str()); };
virtual void warning(BaseString &pMsg) const { warning(pMsg.c_str()); };
virtual void alert(BaseString &pMsg) const { alert(pMsg.c_str()); };
virtual void critical(BaseString &pMsg) const { critical(pMsg.c_str()); };
bool ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 nodeid) { char buf[255]; ndb_mgm_configuration_iterator it(* conf, CFG_SECTION_NODE); if(it.find(CFG_NODE_ID, nodeid)){ BaseString::snprintf(buf, 255, "Unable to find node with id: %d", nodeid); setError(CR_ERROR, buf); return false; } const char * hostname; if(it.get(CFG_NODE_HOST, &hostname)){ BaseString::snprintf(buf, 255, "Unable to get hostname(%d) from config", CFG_NODE_HOST); setError(CR_ERROR, buf); return false; } if (hostname && hostname[0] != 0 && !SocketServer::tryBind(0,hostname)) { BaseString::snprintf(buf, 255, "The hostname this node should have according " "to the configuration does not match a local " "interface. Attempt to bind '%s' " "failed with error: %d '%s'", hostname, errno, strerror(errno)); setError(CR_ERROR, buf); return false; } unsigned int _type; if(it.get(CFG_TYPE_OF_SECTION, &_type)){ BaseString::snprintf(buf, 255, "Unable to get type of node(%d) from config", CFG_TYPE_OF_SECTION); setError(CR_ERROR, buf); return false; } if(_type != (unsigned int)m_node_type){ const char *type_s, *alias_s, *type_s2, *alias_s2; alias_s= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)m_node_type, &type_s); alias_s2= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)_type, &type_s2); BaseString::snprintf(buf, 255, "This node type %s(%s) and config " "node type %s(%s) don't match for nodeid %d", alias_s, type_s, alias_s2, type_s2, nodeid); setError(CR_ERROR, buf); return false; } /** * Check hostnames */ ndb_mgm_configuration_iterator iter(* conf, CFG_SECTION_CONNECTION); for(iter.first(); iter.valid(); iter.next()){ Uint32 type = CONNECTION_TYPE_TCP + 1; if(iter.get(CFG_TYPE_OF_SECTION, &type)) continue; if(type != CONNECTION_TYPE_TCP) continue; Uint32 nodeId1, nodeId2, remoteNodeId; if(iter.get(CFG_CONNECTION_NODE_1, &nodeId1)) continue; if(iter.get(CFG_CONNECTION_NODE_2, &nodeId2)) continue; if(nodeId1 != nodeid && nodeId2 != nodeid) continue; remoteNodeId = (nodeid == nodeId1 ? nodeId2 : nodeId1); const char * name; struct in_addr addr; BaseString tmp; if(!iter.get(CFG_CONNECTION_HOSTNAME_1, &name) && strlen(name)){ if(Ndb_getInAddr(&addr, name) != 0){ tmp.assfmt("Unable to lookup/illegal hostname %s, " "connection from node %d to node %d", name, nodeid, remoteNodeId); setError(CR_ERROR, tmp.c_str()); return false; } } if(!iter.get(CFG_CONNECTION_HOSTNAME_2, &name) && strlen(name)){ if(Ndb_getInAddr(&addr, name) != 0){ tmp.assfmt("Unable to lookup/illegal hostname %s, " "connection from node %d to node %d", name, nodeid, remoteNodeId); setError(CR_ERROR, tmp.c_str()); return false; } } } return true; }
void ConfigRetriever::setError(ErrorType et, BaseString err){ setError(et, err.c_str()); }
bool CPCD::loadProcessList(){ BaseString secondfile; FILE *f; loadingProcessList = true; secondfile.assfmt("%s.new", m_procfile.c_str()); /* Try to open the config file */ f = fopen(m_procfile.c_str(), "r"); /* If it did not exist, try to open the backup. See the saveProcessList() * method for an explanation why it is done this way. */ if(f == NULL) { f = fopen(secondfile.c_str(), "r"); if(f == NULL) { /* XXX What to do here? */ logger.info("Configuration file `%s' not found", m_procfile.c_str()); logger.info("Starting with empty configuration"); loadingProcessList = false; return false; } else { logger.info("Configuration file `%s' missing", m_procfile.c_str()); logger.info("Backup configuration file `%s' is used", secondfile.c_str()); /* XXX Maybe we should just rename the backup file to the official * name, and be done with it? */ } } /* File is ignored anyways, so don't load it, kept for future use of config file. CPCDAPISession sess(f, *this); sess.loadFile(); */ fclose(f); loadingProcessList = false; unsigned i; Vector<int> temporary; for(i = 0; i<m_processes.size(); i++){ Process * proc = m_processes[i]; proc->readPid(); if(proc->m_processType == TEMPORARY){ temporary.push_back(proc->m_id); } } for(i = 0; i<temporary.size(); i++){ RequestStatus rs; undefineProcess(&rs, temporary[i]); } /* Don't call notifyChanges here, as that would save the file we just loaded */ m_monitor->signal(); return true; }
int main(int argc, const char** argv){ ndb_init(); int verbose = 1; int optind = 0; struct getargs args[1+P_MAX] = { { "verbose", 'v', arg_flag, &verbose, "Print verbose status", "verbose" } }; const int num_args = 1 + P_MAX; int i; for(i = 0; i<P_MAX; i++){ args[i+1].long_name = g_paramters[i].name; args[i+1].short_name = * g_paramters[i].name; args[i+1].type = arg_integer; args[i+1].value = &g_paramters[i].value; BaseString tmp; tmp.assfmt("min: %d max: %d", g_paramters[i].min, g_paramters[i].max); args[i+1].help = strdup(tmp.c_str()); args[i+1].arg_help = 0; } if(getarg(args, num_args, argc, argv, &optind)) { arg_printusage(args, num_args, argv[0], "tabname1 tabname2 ..."); return NDBT_WRONGARGS; } myRandom48Init(NdbTick_CurrentMillisecond()); memset(g_times, 0, sizeof(g_times)); Ndb_cluster_connection con; if(con.connect(12, 5, 1)) { return NDBT_ProgramExit(NDBT_FAILED); } g_ndb = new Ndb(&con, "TEST_DB"); if(g_ndb->init() != 0){ g_err << "init() failed" << endl; goto error; } if(g_ndb->waitUntilReady() != 0){ g_err << "Wait until ready failed" << endl; goto error; } for(i = optind; i<argc; i++){ const char * T = argv[i]; g_info << "Testing " << T << endl; BaseString::snprintf(g_table, sizeof(g_table), T); BaseString::snprintf(g_ordered, sizeof(g_ordered), "IDX_O_%s", T); BaseString::snprintf(g_unique, sizeof(g_unique), "IDX_U_%s", T); if(create_table()) goto error; if(load_table()) goto error; for(int l = 0; l<g_paramters[P_LOOPS].value; l++){ for(int j = 0; j<P_OP_TYPES; j++){ g_paramters[P_OPER].value = j; if(run_read()) goto error; } } print_result(); } if(g_ndb) delete g_ndb; return NDBT_OK; error: if(g_ndb) delete g_ndb; return NDBT_FAILED; }
SavedRecord(int _gci, BaseString _str){ m_gci = _gci; m_str.assign(_str); }