1 /* 2 Dummy CTDB client for testing 3 4 Copyright (C) Amitay Isaacs 2017 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "replace.h" 21 #include "system/network.h" 22 23 #include <popt.h> 24 #include <talloc.h> 25 #include <tevent.h> 26 27 #include "common/logging.h" 28 #include "common/path.h" 29 30 #include "client/client.h" 31 32 static struct { 33 const char *sockpath; 34 const char *debuglevel; 35 int num_connections; 36 int timelimit; 37 const char *srvidstr; 38 } options; 39 40 static struct poptOption cmdline_options[] = { 41 POPT_AUTOHELP 42 { "socket", 's', POPT_ARG_STRING, &options.sockpath, 0, 43 "Unix domain socket path", "filename" }, 44 { "debug", 'd', POPT_ARG_STRING, &options.debuglevel, 0, 45 "debug level", "ERR|WARNING|NOTICE|INFO|DEBUG" } , 46 { "nconn", 'n', POPT_ARG_INT, &options.num_connections, 0, 47 "number of connections", "" }, 48 { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, 49 "time limit", "seconds" }, 50 { "srvid", 'S', POPT_ARG_STRING, &options.srvidstr, 0, 51 "srvid to register", "srvid" }, 52 POPT_TABLEEND 53 }; 54 55 static void dummy_handler(uint64_t srvid, TDB_DATA data, void *private_data) 56 { 57 bool *done = (bool *)private_data; 58 59 *done = true; 60 } 61 62 int main(int argc, const char *argv[]) 63 { 64 TALLOC_CTX *mem_ctx; 65 struct tevent_context *ev; 66 struct ctdb_client_context **client; 67 struct ctdb_client_context *last_client; 68 poptContext pc; 69 int opt, ret, i; 70 int log_level; 71 bool status, done; 72 73 /* Set default options */ 74 options.sockpath = NULL; 75 options.debuglevel = "ERR"; 76 options.num_connections = 1; db_test_get_lmaster(TALLOC_CTX * mem_ctx,int argc,const char ** argv,void * private_data)77 options.timelimit = 60; 78 options.srvidstr = NULL; 79 80 pc = poptGetContext(argv[0], argc, argv, cmdline_options, 81 POPT_CONTEXT_KEEP_FIRST); 82 while ((opt = poptGetNextOpt(pc)) != -1) { 83 fprintf(stderr, "Invalid option %s\n", poptBadOption(pc, 0)); 84 exit(1); 85 } 86 87 mem_ctx = talloc_new(NULL); 88 if (mem_ctx == NULL) { 89 fprintf(stderr, "Memory allocation error\n"); 90 exit(1); 91 } 92 93 ev = tevent_context_init(mem_ctx); 94 if (ev == NULL) { 95 fprintf(stderr, "Memory allocation error\n"); 96 exit(1); 97 } 98 99 status = debug_level_parse(options.debuglevel, &log_level); 100 if (! status) { 101 fprintf(stderr, "Invalid debug level\n"); 102 poptPrintHelp(pc, stdout, 0); 103 exit(1); 104 } 105 106 setup_logging("dummy_client", DEBUG_STDERR); 107 debuglevel_set(log_level); 108 109 if (options.sockpath == NULL) { 110 options.sockpath = path_socket(mem_ctx, "ctdbd"); 111 if (options.sockpath == NULL) { 112 D_ERR("Memory allocation error\n"); 113 exit(1); 114 } 115 } 116 117 client = talloc_array(mem_ctx, struct ctdb_client_context *, db_find(TALLOC_CTX * mem_ctx,struct db_test_tool_context * ctx,struct ctdb_dbid_map * dbmap,const char * db_name)118 options.num_connections); 119 if (client == NULL) { 120 fprintf(stderr, "Memory allocation error\n"); 121 exit(1); 122 } 123 124 for (i=0; i<options.num_connections; i++) { 125 ret = ctdb_client_init(client, ev, options.sockpath, 126 &client[i]); 127 if (ret != 0) { 128 D_ERR("Failed to initialize client %d, ret=%d\n", 129 i, ret); 130 exit(1); 131 } 132 } 133 134 last_client = client[options.num_connections-1]; 135 136 done = false; 137 if (options.srvidstr != NULL) { 138 uint64_t srvid; 139 140 srvid = strtoull(options.srvidstr, NULL, 0); 141 142 ret = ctdb_client_set_message_handler(ev, last_client, srvid, 143 dummy_handler, &done); 144 if (ret != 0) { 145 D_ERR("Failed to register srvid, ret=%d\n", ret); 146 talloc_free(client); 147 exit(1); 148 } 149 db_exists(TALLOC_CTX * mem_ctx,struct db_test_tool_context * ctx,const char * db_arg,uint32_t * db_id,const char ** db_name,uint8_t * db_flags)150 D_INFO("Registered SRVID 0x%"PRIx64"\n", srvid); 151 } 152 153 ret = ctdb_client_wait_timeout(ev, &done, 154 tevent_timeval_current_ofs(options.timelimit, 0)); 155 if (ret != 0 && ret == ETIMEDOUT) { 156 D_ERR("client_wait_timeout() failed, ret=%d\n", ret); 157 talloc_free(client); 158 exit(1); 159 } 160 161 talloc_free(mem_ctx); 162 exit(0); 163 } 164