Annotation of embedaddon/strongswan/src/libcharon/plugins/load_tester/load_tester_plugin.c, revision 1.1.1.1

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: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>