Return to load_tester_plugin.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / load_tester |
1.1 misho 1: /* 2: * Copyright (C) 2008 Martin Willi 3: * HSR Hochschule fuer Technik Rapperswil 4: * 5: * This program is free software; you can redistribute it and/or modify it 6: * under the terms of the GNU General Public License as published by the 7: * Free Software Foundation; either version 2 of the License, or (at your 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 9: * 10: * This program is distributed in the hope that it will be useful, but 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13: * for more details. 14: */ 15: 16: #include "load_tester_plugin.h" 17: #include "load_tester_config.h" 18: #include "load_tester_creds.h" 19: #include "load_tester_ipsec.h" 20: #include "load_tester_listener.h" 21: #include "load_tester_control.h" 22: #include "load_tester_diffie_hellman.h" 23: 24: #include <unistd.h> 25: 26: #include <daemon.h> 27: #include <processing/jobs/callback_job.h> 28: #include <threading/condvar.h> 29: #include <threading/mutex.h> 30: 31: typedef struct private_load_tester_plugin_t private_load_tester_plugin_t; 32: 33: /** 34: * private data of load_tester plugin 35: */ 36: struct private_load_tester_plugin_t { 37: 38: /** 39: * implements plugin interface 40: */ 41: load_tester_plugin_t public; 42: 43: /** 44: * load_tester configuration backend 45: */ 46: load_tester_config_t *config; 47: 48: /** 49: * load_tester credential set implementation 50: */ 51: load_tester_creds_t *creds; 52: 53: /** 54: * Unix control socket to initiate load-tests 55: */ 56: load_tester_control_t *control; 57: 58: /** 59: * event handler, listens on bus 60: */ 61: load_tester_listener_t *listener; 62: 63: /** 64: * number of iterations per thread 65: */ 66: int iterations; 67: 68: /** 69: * number desired initiator threads 70: */ 71: int initiators; 72: 73: /** 74: * currently running initiators 75: */ 76: int running; 77: 78: /** 79: * delay between initiations, in ms 80: */ 81: int delay; 82: 83: /** 84: * Throttle initiation if half-open IKE_SA count reached 85: */ 86: int init_limit; 87: 88: /** 89: * mutex to lock running field 90: */ 91: mutex_t *mutex; 92: 93: /** 94: * condvar to wait for initiators 95: */ 96: condvar_t *condvar; 97: }; 98: 99: /** 100: * Begin the load test 101: */ 102: static job_requeue_t do_load_test(private_load_tester_plugin_t *this) 103: { 104: int i, s = 0, ms = 0; 105: 106: this->mutex->lock(this->mutex); 107: this->running++; 108: this->mutex->unlock(this->mutex); 109: if (this->delay) 110: { 111: s = this->delay / 1000; 112: ms = this->delay % 1000; 113: } 114: 115: for (i = 0; this->iterations == 0 || i < this->iterations; i++) 116: { 117: peer_cfg_t *peer_cfg; 118: child_cfg_t *child_cfg = NULL; 119: enumerator_t *enumerator; 120: 121: if (this->init_limit) 122: { 123: while ((charon->ike_sa_manager->get_count(charon->ike_sa_manager) - 124: this->listener->get_established(this->listener)) > 125: this->init_limit) 126: { 127: if (s) 128: { 129: sleep(s); 130: } 131: if (ms) 132: { 133: usleep(ms * 1000); 134: } 135: } 136: } 137: 138: peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends, 139: "load-test"); 140: if (!peer_cfg) 141: { 142: break; 143: } 144: enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg); 145: if (!enumerator->enumerate(enumerator, &child_cfg)) 146: { 147: enumerator->destroy(enumerator); 148: break; 149: } 150: enumerator->destroy(enumerator); 151: 152: charon->controller->initiate(charon->controller, 153: peer_cfg, child_cfg->get_ref(child_cfg), 154: NULL, NULL, 0, FALSE); 155: if (s) 156: { 157: sleep(s); 158: } 159: if (ms) 160: { 161: usleep(ms * 1000); 162: } 163: } 164: this->mutex->lock(this->mutex); 165: this->running--; 166: this->condvar->signal(this->condvar); 167: this->mutex->unlock(this->mutex); 168: return JOB_REQUEUE_NONE; 169: } 170: 171: METHOD(plugin_t, get_name, char*, 172: private_load_tester_plugin_t *this) 173: { 174: return "load-tester"; 175: } 176: 177: /** 178: * Register load_tester plugin features 179: */ 180: static bool register_load_tester(private_load_tester_plugin_t *this, 181: plugin_feature_t *feature, bool reg, void *data) 182: { 183: if (reg) 184: { 185: u_int i, shutdown_on = 0; 186: 187: this->config = load_tester_config_create(); 188: this->creds = load_tester_creds_create(); 189: this->control = load_tester_control_create(); 190: 191: charon->backends->add_backend(charon->backends, &this->config->backend); 192: lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set); 193: 194: if (lib->settings->get_bool(lib->settings, 195: "%s.plugins.load-tester.shutdown_when_complete", 0, lib->ns)) 196: { 197: shutdown_on = this->iterations * this->initiators; 198: } 199: this->listener = load_tester_listener_create(shutdown_on, this->config); 200: charon->bus->add_listener(charon->bus, &this->listener->listener); 201: 202: for (i = 0; i < this->initiators; i++) 203: { 204: lib->processor->queue_job(lib->processor, (job_t*) 205: callback_job_create_with_prio((callback_job_cb_t)do_load_test, 206: this, NULL, NULL, JOB_PRIO_CRITICAL)); 207: } 208: } 209: else 210: { 211: this->iterations = -1; 212: this->mutex->lock(this->mutex); 213: while (this->running) 214: { 215: this->condvar->wait(this->condvar, this->mutex); 216: } 217: this->mutex->unlock(this->mutex); 218: charon->backends->remove_backend(charon->backends, &this->config->backend); 219: lib->credmgr->remove_set(lib->credmgr, &this->creds->credential_set); 220: charon->bus->remove_listener(charon->bus, &this->listener->listener); 221: this->config->destroy(this->config); 222: this->creds->destroy(this->creds); 223: this->listener->destroy(this->listener); 224: this->control->destroy(this->control); 225: } 226: return TRUE; 227: } 228: 229: METHOD(plugin_t, get_features, int, 230: private_load_tester_plugin_t *this, plugin_feature_t *features[]) 231: { 232: static plugin_feature_t f[] = { 233: PLUGIN_REGISTER(DH, load_tester_diffie_hellman_create), 234: PLUGIN_PROVIDE(DH, MODP_NULL), 235: PLUGIN_DEPENDS(CUSTOM, "load-tester"), 236: PLUGIN_CALLBACK((plugin_feature_callback_t)register_load_tester, NULL), 237: PLUGIN_PROVIDE(CUSTOM, "load-tester"), 238: PLUGIN_DEPENDS(CUSTOM, "kernel-net"), 239: PLUGIN_SDEPEND(PRIVKEY, KEY_RSA), 240: PLUGIN_SDEPEND(CERT_DECODE, CERT_ANY), 241: PLUGIN_SDEPEND(CERT_DECODE, CERT_X509), 242: PLUGIN_CALLBACK(kernel_ipsec_register, load_tester_ipsec_create), 243: PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"), 244: }; 245: int count = countof(f); 246: 247: *features = f; 248: 249: if (!lib->settings->get_bool(lib->settings, 250: "%s.plugins.load-tester.fake_kernel", FALSE, lib->ns)) 251: { 252: count -= 2; 253: } 254: return count; 255: } 256: 257: METHOD(plugin_t, destroy, void, 258: private_load_tester_plugin_t *this) 259: { 260: this->mutex->destroy(this->mutex); 261: this->condvar->destroy(this->condvar); 262: free(this); 263: } 264: 265: /* 266: * see header file 267: */ 268: plugin_t *load_tester_plugin_create() 269: { 270: private_load_tester_plugin_t *this; 271: 272: if (!lib->settings->get_bool(lib->settings, "%s.plugins.load-tester.enable", 273: FALSE, lib->ns)) 274: { 275: DBG1(DBG_CFG, "disabling load-tester plugin, not configured"); 276: return NULL; 277: } 278: 279: INIT(this, 280: .public = { 281: .plugin = { 282: .get_name = _get_name, 283: .get_features = _get_features, 284: .reload = (void*)return_false, 285: .destroy = _destroy, 286: }, 287: }, 288: .delay = lib->settings->get_int(lib->settings, 289: "%s.plugins.load-tester.delay", 0, lib->ns), 290: .iterations = lib->settings->get_int(lib->settings, 291: "%s.plugins.load-tester.iterations", 1, lib->ns), 292: .initiators = lib->settings->get_int(lib->settings, 293: "%s.plugins.load-tester.initiators", 0, lib->ns), 294: .init_limit = lib->settings->get_int(lib->settings, 295: "%s.plugins.load-tester.init_limit", 0, lib->ns), 296: .mutex = mutex_create(MUTEX_TYPE_DEFAULT), 297: .condvar = condvar_create(CONDVAR_TYPE_DEFAULT), 298: ); 299: return &this->public.plugin; 300: }