Annotation of embedaddon/bmon/src/out_db.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * out_db.c            Database Output
        !             3:  *
        !             4:  * Copyright (c) 2001-2005 Thomas Graf <tgraf@suug.ch>
        !             5:  *
        !             6:  * Permission is hereby granted, free of charge, to any person obtaining a
        !             7:  * copy of this software and associated documentation files (the "Software"),
        !             8:  * to deal in the Software without restriction, including without limitation
        !             9:  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
        !            10:  * and/or sell copies of the Software, and to permit persons to whom the
        !            11:  * Software is furnished to do so, subject to the following conditions:
        !            12:  *
        !            13:  * The above copyright notice and this permission notice shall be included
        !            14:  * in all copies or substantial portions of the Software.
        !            15:  *
        !            16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
        !            17:  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        !            19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        !            20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
        !            21:  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
        !            22:  * DEALINGS IN THE SOFTWARE.
        !            23:  */
        !            24: 
        !            25: /*
        !            26:  *                                     NOTE
        !            27:  *
        !            28:  * This whole code is a realy mess and written in a hurry, most interactions
        !            29:  * should be cached to save traffic. It really is meant as experimental
        !            30:  * features.
        !            31:  */
        !            32: 
        !            33: #include <bmon/bmon.h>
        !            34: #include <bmon/node.h>
        !            35: #include <bmon/output.h>
        !            36: #include <bmon/graph.h>
        !            37: #include <bmon/input.h>
        !            38: #include <bmon/utils.h>
        !            39: 
        !            40: #include <dbi/dbi.h>
        !            41: 
        !            42: static char *c_driverdir = NULL;
        !            43: static char *c_driver = "mysql";
        !            44: static char *c_host = "localhost";
        !            45: static char *c_username = "bmon";
        !            46: static char *c_dbname = "bmon";
        !            47: static char *c_mask = "mhd";
        !            48: static char *c_password;
        !            49: static int   c_interval = 3;
        !            50: 
        !            51: static int do_read;
        !            52: static int do_sec;
        !            53: static int do_min;
        !            54: static int do_hour;
        !            55: static int do_day;
        !            56: 
        !            57: static dbi_conn db_conn;
        !            58: 
        !            59: static int create_tables(void)
        !            60: {
        !            61:        dbi_result r;
        !            62: 
        !            63:        r = dbi_conn_query(db_conn,
        !            64:        "CREATE TABLE IF NOT EXISTS nodes (" \
        !            65:        "       id INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE," \
        !            66:        "       name TEXT NOT NULL," \
        !            67:        "       source TEXT," \
        !            68:        "       PRIMARY KEY (id)" \
        !            69:        ")");
        !            70: 
        !            71:        if (!r)
        !            72:                return 0;
        !            73:        else
        !            74:                dbi_result_free(r);
        !            75:        
        !            76:        r = dbi_conn_query(db_conn,
        !            77:        "CREATE TABLE IF NOT EXISTS items (" \
        !            78:        "       id INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE," \
        !            79:        "       name TEXT NOT NULL," \
        !            80:        "       description TEXT," \
        !            81:        "       node INT UNSIGNED NOT NULL," \
        !            82:        "       handle INT UNSIGNED," \
        !            83:        "       parent INT UNSIGNED," \
        !            84:        "       indent INT UNSIGNED," \
        !            85:        "       rx_usage SMALLINT NOT NULL," \
        !            86:        "       tx_usage SMALLINT NOT NULL," \
        !            87:        "       PRIMARY KEY (id)," \
        !            88:        "       FOREIGN KEY (node) REFERENCES nodes(id)," \
        !            89:        "       FOREIGN KEY (parent) REFERENCES items(id)" \
        !            90:        ")");
        !            91: 
        !            92:        if (!r)
        !            93:                return 0;
        !            94:        else
        !            95:                dbi_result_free(r);
        !            96: 
        !            97:        r = dbi_conn_query(db_conn,
        !            98:        "CREATE TABLE IF NOT EXISTS attrs (" \
        !            99:        "       id INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE," \
        !           100:        "       name CHAR(15) NOT NULL," \
        !           101:        "       item INT UNSIGNED NOT NULL," \
        !           102:        "       rx_rate INT UNSIGNED," \
        !           103:        "       tx_rate INT UNSIGNED," \
        !           104:        "       rx_counter BIGINT UNSIGNED NOT NULL," \
        !           105:        "       tx_counter BIGINT UNSIGNED NOT NULL," \
        !           106:        "       PRIMARY KEY (id)," \
        !           107:        "       FOREIGN KEY (item) REFERENCES items(id)" \
        !           108:        ")");
        !           109: 
        !           110:        if (!r)
        !           111:                return 0;
        !           112:        else
        !           113:                dbi_result_free(r);
        !           114: 
        !           115:        r = dbi_conn_query(db_conn,
        !           116:        "CREATE TABLE IF NOT EXISTS attr_desc (" \
        !           117:        "       id CHAR(15) NOT NULL UNIQUE," \
        !           118:        "       is_num SMALLINT UNSIGNED NOT NULL," \
        !           119:        "       txt TEXT NOT NULL," \
        !           120:        "       PRIMARY KEY(id)" \
        !           121:        ")");
        !           122: 
        !           123:        if (!r)
        !           124:                return 0;
        !           125:        else
        !           126:                dbi_result_free(r);
        !           127: 
        !           128:        r = dbi_conn_query(db_conn,
        !           129:        "CREATE TABLE IF NOT EXISTS hist_r (" \
        !           130:        "       attr INT UNSIGNED NOT NULL," \
        !           131:        "       ts INT UNSIGNED NOT NULL," \
        !           132:        "       offset INT UNSIGNED NOT NULL," \
        !           133:        "       rx_rate INT UNSIGNED NOT NULL," \
        !           134:        "       tx_rate INT UNSIGNED NOT NULL," \
        !           135:        "       PRIMARY KEY (attr, ts, offset)," \
        !           136:        "       FOREIGN KEY (attr) REFERENCES attrs(id)" \
        !           137:        ")");
        !           138: 
        !           139:        if (!r)
        !           140:                return 0;
        !           141:        else
        !           142:                dbi_result_free(r);
        !           143: 
        !           144:        r = dbi_conn_query(db_conn,
        !           145:        "CREATE TABLE IF NOT EXISTS hist_s (" \
        !           146:        "       attr INT UNSIGNED NOT NULL," \
        !           147:        "       ts INT UNSIGNED NOT NULL," \
        !           148:        "       offset INT UNSIGNED NOT NULL," \
        !           149:        "       rx_rate INT UNSIGNED NOT NULL," \
        !           150:        "       tx_rate INT UNSIGNED NOT NULL," \
        !           151:        "       PRIMARY KEY (attr, ts, offset)," \
        !           152:        "       FOREIGN KEY (attr) REFERENCES attrs(id)" \
        !           153:        ")");
        !           154: 
        !           155:        if (!r)
        !           156:                return 0;
        !           157:        else
        !           158:                dbi_result_free(r);
        !           159: 
        !           160:        r = dbi_conn_query(db_conn,
        !           161:        "CREATE TABLE IF NOT EXISTS hist_m (" \
        !           162:        "       attr INT UNSIGNED NOT NULL," \
        !           163:        "       ts INT UNSIGNED NOT NULL," \
        !           164:        "       offset INT UNSIGNED NOT NULL," \
        !           165:        "       rx_rate INT UNSIGNED NOT NULL," \
        !           166:        "       tx_rate INT UNSIGNED NOT NULL," \
        !           167:        "       PRIMARY KEY (attr, ts, offset)," \
        !           168:        "       FOREIGN KEY (attr) REFERENCES attrs(id)" \
        !           169:        ")");
        !           170: 
        !           171:        if (!r)
        !           172:                return 0;
        !           173:        else
        !           174:                dbi_result_free(r);
        !           175: 
        !           176:        r = dbi_conn_query(db_conn,
        !           177:        "CREATE TABLE IF NOT EXISTS hist_h (" \
        !           178:        "       attr INT UNSIGNED NOT NULL," \
        !           179:        "       ts INT UNSIGNED NOT NULL," \
        !           180:        "       offset INT UNSIGNED NOT NULL," \
        !           181:        "       rx_rate INT UNSIGNED NOT NULL," \
        !           182:        "       tx_rate INT UNSIGNED NOT NULL," \
        !           183:        "       PRIMARY KEY (attr, ts, offset)," \
        !           184:        "       FOREIGN KEY (attr) REFERENCES attrs(id)" \
        !           185:        ")");
        !           186: 
        !           187:        if (!r)
        !           188:                return 0;
        !           189:        else
        !           190:                dbi_result_free(r);
        !           191: 
        !           192:        r = dbi_conn_query(db_conn,
        !           193:        "CREATE TABLE IF NOT EXISTS hist_d (" \
        !           194:        "       attr INT UNSIGNED NOT NULL," \
        !           195:        "       ts INT UNSIGNED NOT NULL," \
        !           196:        "       offset INT UNSIGNED NOT NULL," \
        !           197:        "       rx_rate INT UNSIGNED NOT NULL," \
        !           198:        "       tx_rate INT UNSIGNED NOT NULL," \
        !           199:        "       PRIMARY KEY (attr, ts, offset)," \
        !           200:        "       FOREIGN KEY (attr) REFERENCES attrs(id)" \
        !           201:        ")");
        !           202: 
        !           203:        if (!r)
        !           204:                return 0;
        !           205:        else
        !           206:                dbi_result_free(r);
        !           207: 
        !           208:        return 1;
        !           209: }
        !           210: 
        !           211: static int insert_attr_desc(struct attr_type *a, void *arg)
        !           212: {
        !           213:        dbi_result r = dbi_conn_queryf(db_conn,
        !           214:            "SELECT id FROM attr_desc WHERE id = '%s'", a->name);
        !           215: 
        !           216:        if (!r)
        !           217:                return -1;
        !           218: 
        !           219:        if (dbi_result_first_row(r) == 1) {
        !           220:                dbi_result_free(r);
        !           221:                return 0;
        !           222:        }
        !           223: 
        !           224:        dbi_result_free(r);
        !           225: 
        !           226:        r = dbi_conn_queryf(db_conn,
        !           227:            "INSERT INTO attr_desc (id, is_num, txt) VALUES " \
        !           228:            "('%s', %d, '%s')", a->name, a->unit == U_NUMBER,
        !           229:            a->desc);
        !           230: 
        !           231:        if (!r)
        !           232:                return -1;
        !           233: 
        !           234:        dbi_result_free(r);
        !           235:        return 0;
        !           236: }
        !           237: 
        !           238: static int insert_attr_descs(void)
        !           239: {
        !           240:        return !foreach_attr_type(&insert_attr_desc, NULL);
        !           241: }
        !           242: 
        !           243: static void add_history(const char *table, int attr_id, timestamp_t *ts,
        !           244:                        rate_cnt_t rx, rate_cnt_t tx)
        !           245: {
        !           246:        dbi_result r = dbi_conn_queryf(db_conn,
        !           247:                "INSERT INTO %s (attr, ts, offset, rx_rate, tx_rate) " \
        !           248:                "values (%d, %u, %u, %u, %u)",
        !           249:                table, attr_id, (unsigned int) ts->tv_sec,
        !           250:                (unsigned int) ts->tv_usec, rx, tx);
        !           251: 
        !           252:        if (r)
        !           253:                dbi_result_free(r);
        !           254: }
        !           255: 
        !           256: 
        !           257: static inline int attr_exists(const char *name, int item_id)
        !           258: {
        !           259:        int ret = -1;
        !           260: 
        !           261:        dbi_result r = dbi_conn_queryf(db_conn,
        !           262:            "SELECT id FROM attrs WHERE name = '%s' AND " \
        !           263:            "item = %d", name, item_id);
        !           264: 
        !           265:        if (r) {
        !           266:                if (dbi_result_first_row(r) == 1)
        !           267:                        ret = (int) dbi_result_get_long(r, "id");
        !           268:                dbi_result_free(r);
        !           269:        }
        !           270: 
        !           271:        return ret;
        !           272: }
        !           273: 
        !           274: static inline int insert_attr(stat_attr_t *a, int item_id)
        !           275: {
        !           276:        dbi_result r;
        !           277: 
        !           278:        r = dbi_conn_queryf(db_conn,
        !           279:                "INSERT INTO attrs (name, item, rx_rate, tx_rate, " \
        !           280:                "rx_counter, tx_counter) VALUES ('%s', %d, %d, %d, " \
        !           281:                "%lld, %lld)", type2name(a->a_type), item_id,
        !           282:                attr_get_rx_rate(a), attr_get_tx_rate(a),
        !           283:                attr_get_rx(a), attr_get_tx(a));
        !           284: 
        !           285:        if (!r)
        !           286:                return -1;
        !           287: 
        !           288:        dbi_result_free(r);
        !           289:        return attr_exists(type2name(a->a_type), item_id);
        !           290: 
        !           291: }
        !           292: 
        !           293: static inline int up_attr(stat_attr_t *a, int attr_id)
        !           294: {
        !           295:        dbi_result r;
        !           296: 
        !           297:        r = dbi_conn_queryf(db_conn,
        !           298:                "UPDATE attrs SET rx_rate = %d, tx_rate = %d, " \
        !           299:                "rx_counter = %lld, tx_counter = %lld WHERE id = %d",
        !           300:                attr_get_rx_rate(a), attr_get_tx_rate(a),
        !           301:                attr_get_rx(a), attr_get_tx(a), attr_id);
        !           302: 
        !           303:        if (!r)
        !           304:                return -1;
        !           305: 
        !           306:        dbi_result_free(r);
        !           307: 
        !           308:        return 0;
        !           309: }
        !           310: 
        !           311: static inline int item_exists(item_t *it, node_t *node, int node_id)
        !           312: {
        !           313:        int ret = -1;
        !           314:        dbi_result r;
        !           315: 
        !           316:        if (it->i_flags & ITEM_FLAG_IS_CHILD) {
        !           317:                int parent;
        !           318:                item_t *p = get_item(node, it->i_parent);
        !           319:                if (!p)
        !           320:                        goto no_parent;
        !           321: 
        !           322:                parent = item_exists(p, node, node_id);
        !           323:                if (parent < 0)
        !           324:                        goto no_parent;
        !           325: 
        !           326:                r = dbi_conn_queryf(db_conn,
        !           327:                    "SELECT id FROM items WHERE node = %d AND " \
        !           328:                    "name = '%s' AND handle = %d AND parent = %d",
        !           329:                    node_id, it->i_name, it->i_handle, parent);
        !           330:                goto skip;
        !           331:        }
        !           332: 
        !           333: no_parent:
        !           334:        r = dbi_conn_queryf(db_conn,
        !           335:            "SELECT id FROM items WHERE node = %d AND " \
        !           336:            "name = '%s' AND handle = %d", node_id, it->i_name, it->i_handle);
        !           337: 
        !           338: skip:
        !           339:        if (r) {
        !           340:                if (dbi_result_first_row(r) == 1)
        !           341:                        ret = (int) dbi_result_get_long(r, "id");
        !           342:                dbi_result_free(r);
        !           343:        }
        !           344: 
        !           345:        return ret;
        !           346: }
        !           347: 
        !           348: static inline int insert_item(item_t *it, node_t *node, int node_id)
        !           349: {
        !           350:        dbi_result r;
        !           351: 
        !           352:        if (it->i_flags & ITEM_FLAG_IS_CHILD) {
        !           353:                int parent;
        !           354:                item_t *p = get_item(node, it->i_parent);
        !           355:                if (!p)
        !           356:                        goto no_parent;
        !           357: 
        !           358:                parent = item_exists(p, node, node_id);
        !           359:                if (parent < 0)
        !           360:                        goto no_parent;
        !           361: 
        !           362:                r = dbi_conn_queryf(db_conn,
        !           363:                        "INSERT INTO items (name, node, handle, parent, " \
        !           364:                        "indent, description) VALUES ('%s', %d, %d, %d, " \
        !           365:                        "%d, %s%s%s)",
        !           366:                        it->i_name, node_id, it->i_handle,
        !           367:                        parent, it->i_level,
        !           368:                        it->i_desc ? "'" : "",
        !           369:                        it->i_desc ? it->i_desc : "NULL",
        !           370:                        it->i_desc ? "'" : "");
        !           371:                goto skip;
        !           372:        }
        !           373: 
        !           374: no_parent:
        !           375:        r = dbi_conn_queryf(db_conn,
        !           376:                        "INSERT INTO items (name, node, handle) VALUES " \
        !           377:                        "('%s', %d, %d)", it->i_name, node_id, it->i_handle);
        !           378: 
        !           379: skip:
        !           380:        if (!r)
        !           381:                return -1;
        !           382: 
        !           383:        dbi_result_free(r);
        !           384:        return item_exists(it, node, node_id);
        !           385: }
        !           386: 
        !           387: static inline int up_item(item_t *it, int item_id)
        !           388: {
        !           389:        dbi_result r;
        !           390: 
        !           391:        r = dbi_conn_queryf(db_conn,
        !           392:                "UPDATE attrs SET rx_usage = %d, tx_usage = %d " \
        !           393:                "WHERE id = %d",
        !           394:                it->i_rx_usage, it->i_tx_usage, item_id);
        !           395: 
        !           396:        if (!r)
        !           397:                return -1;
        !           398: 
        !           399:        dbi_result_free(r);
        !           400: 
        !           401:        return 0;
        !           402: }
        !           403: 
        !           404: static inline int node_exists(const char *name)
        !           405: {
        !           406:        int ret = -1;
        !           407:        dbi_result r = dbi_conn_queryf(db_conn,
        !           408:            "SELECT id FROM nodes WHERE name = '%s'", name);
        !           409: 
        !           410:        if (r) {
        !           411:                if (dbi_result_first_row(r) == 1)
        !           412:                        ret = (int) dbi_result_get_long(r, "id");
        !           413:                dbi_result_free(r);
        !           414:        }
        !           415: 
        !           416:        return ret;
        !           417: }
        !           418: 
        !           419: static inline int insert_node(const char *name, const char *source)
        !           420: {
        !           421:        dbi_result r;
        !           422: 
        !           423:        if (source)
        !           424:                r = dbi_conn_queryf(db_conn,
        !           425:                        "INSERT INTO nodes (name, source) VALUES ('%s', '%s')",
        !           426:                        name, source);
        !           427:        else
        !           428:                r = dbi_conn_queryf(db_conn,
        !           429:                        "INSERT INTO nodes (name) VALUES ('%s')", name);
        !           430: 
        !           431:        if (!r)
        !           432:                return -1;
        !           433: 
        !           434:        dbi_result_free(r);
        !           435: 
        !           436:        return node_exists(name);
        !           437: 
        !           438: }
        !           439: 
        !           440: static inline int cur_hist_index(int index)
        !           441: {
        !           442:        return index == 0 ? (HISTORY_SIZE - 1) : (index - 1);
        !           443: }
        !           444: 
        !           445: struct xdata {
        !           446:        int node_id;
        !           447:        node_t *node;
        !           448: };
        !           449: 
        !           450: static void write_per_attr(stat_attr_t *a, void *arg)
        !           451: {
        !           452:        int attr_id;
        !           453:        int item_id = (int) arg;
        !           454: 
        !           455:        attr_id = attr_exists(type2name(a->a_type), item_id);
        !           456:        if (attr_id < 0) {
        !           457:                attr_id = insert_attr(a, item_id);
        !           458:                if (attr_id < 0)
        !           459:                        return;
        !           460:        } else
        !           461:                up_attr(a, attr_id);
        !           462: 
        !           463:        if (a->a_flags & ATTR_FLAG_HISTORY) {
        !           464:                history_t *h = &((stat_attr_hist_t *) a)->a_hist;
        !           465: 
        !           466:                if (do_read && get_read_interval() != 1.0f) {
        !           467:                        int idx = cur_hist_index(h->h_read.he_index);
        !           468:                        add_history("hist_r", attr_id,
        !           469:                                    &h->h_read.he_last_update,
        !           470:                                    h->h_read.he_rx.hd_data[idx],
        !           471:                                    h->h_read.he_tx.hd_data[idx]);
        !           472:                }
        !           473: 
        !           474:                if (do_sec && diff_now(&h->h_sec.he_last_update) < 0.5f) {
        !           475:                        int idx = cur_hist_index(h->h_sec.he_index);
        !           476:                        add_history("hist_s", attr_id,
        !           477:                                    &h->h_sec.he_last_update,
        !           478:                                    h->h_sec.he_rx.hd_data[idx],
        !           479:                                    h->h_sec.he_tx.hd_data[idx]);
        !           480:                }
        !           481: 
        !           482:                if (do_min && diff_now(&h->h_min.he_last_update) < 30.0f) {
        !           483:                        int idx = cur_hist_index(h->h_min.he_index);
        !           484:                        add_history("hist_m", attr_id,
        !           485:                                    &h->h_min.he_last_update,
        !           486:                                    h->h_min.he_rx.hd_data[idx],
        !           487:                                    h->h_min.he_tx.hd_data[idx]);
        !           488:                }
        !           489: 
        !           490:                if (do_hour && diff_now(&h->h_hour.he_last_update) < 1800.0f) {
        !           491:                        int idx = cur_hist_index(h->h_hour.he_index);
        !           492:                        add_history("hist_h", attr_id,
        !           493:                                    &h->h_hour.he_last_update,
        !           494:                                    h->h_hour.he_rx.hd_data[idx],
        !           495:                                    h->h_hour.he_tx.hd_data[idx]);
        !           496:                }
        !           497: 
        !           498:                if (do_day && diff_now(&h->h_day.he_last_update) < 43200.0f) {
        !           499:                        int idx = cur_hist_index(h->h_day.he_index);
        !           500:                        add_history("hist_d", attr_id,
        !           501:                                    &h->h_day.he_last_update,
        !           502:                                    h->h_day.he_rx.hd_data[idx],
        !           503:                                    h->h_day.he_tx.hd_data[idx]);
        !           504:                }
        !           505:        }
        !           506: }
        !           507: 
        !           508: static void write_per_item(item_t *item, void *arg)
        !           509: {
        !           510:        int item_id;
        !           511:        struct xdata *x = (struct xdata *) arg;
        !           512: 
        !           513:        item_id = item_exists(item, x->node, x->node_id);
        !           514:        if (item_id < 0)
        !           515:                item_id = insert_item(item, x->node, x->node_id);
        !           516: 
        !           517:        if (item_id < 0)
        !           518:                return;
        !           519: 
        !           520:        up_item(item, item_id);
        !           521: 
        !           522:        foreach_attr(item, &write_per_attr, (void *) item_id);
        !           523: }
        !           524: 
        !           525: static void write_per_node(node_t *node, void *arg)
        !           526: {
        !           527:        struct xdata x = { .node = node };
        !           528: 
        !           529:        x.node_id = node_exists(node->n_name);
        !           530: 
        !           531:        if (x.node_id < 0)
        !           532:                x.node_id = insert_node(node->n_name, node->n_from);
        !           533: 
        !           534:        if (x.node_id < 0)
        !           535:                return;
        !           536: 
        !           537:        foreach_item(node, write_per_item, &x);
        !           538: }
        !           539: 
        !           540: void db_draw(void)
        !           541: {
        !           542:        static int rem = 1;
        !           543: 
        !           544:        if (--rem)
        !           545:                return;
        !           546:        else
        !           547:                rem = c_interval;
        !           548: 
        !           549:        foreach_node(write_per_node, NULL);
        !           550: }
        !           551: 
        !           552: static void print_module_help(void)
        !           553: {
        !           554:        printf(
        !           555:        "DB - Database Output\n" \
        !           556:        "\n" \
        !           557:        "  Writes current rate estimations into a database for\n" \
        !           558:        "  other tools to pick up.\n" \
        !           559:        "\n" \
        !           560:        "  Author: Thomas Graf <tgraf@suug.ch>\n" \
        !           561:        "\n" \
        !           562:        "  Options:\n" \
        !           563:        "    driverdir=DIR    Directory containing libdi drivers\n" \
        !           564:        "    driver=DRIVER    DB driver (default: mysql)\n" \
        !           565:        "    host=HOST        Host the database is on (default: localhost)\n" \
        !           566:        "    dbname=NAME      Name of database (default: bmon)\n" \
        !           567:        "    username=NAME    Authentication username (default: bmon)\n" \
        !           568:        "    password=TEXT    Authentication password\n" \
        !           569:        "    mask=MASK        Write selection mask (default: mhd)\n" \
        !           570:        "    interval=SEC     Update interval in seconds (default: 3)\n" \
        !           571:        "\n" \
        !           572:        "  Mask Attributes:\n" \
        !           573:        "    r                Read interval\n" \
        !           574:        "    s                Seconds\n" \
        !           575:        "    m                Minutes\n" \
        !           576:        "    h                Hours\n" \
        !           577:        "    d                Days\n" \
        !           578:        "\n" \
        !           579:        "  Examples:\n" \
        !           580:        "    -O 'db:password=bmon;mask=rmhd'");
        !           581: }
        !           582: 
        !           583: static void db_set_opts(tv_t *attrs)
        !           584: {
        !           585:        while (attrs) {
        !           586:                if (!strcasecmp(attrs->type, "driverdir") && attrs->value)
        !           587:                        c_driverdir = attrs->value;
        !           588:                else if (!strcasecmp(attrs->type, "driver") && attrs->value)
        !           589:                        c_driver = attrs->value;
        !           590:                else if (!strcasecmp(attrs->type, "host") && attrs->value)
        !           591:                        c_host = attrs->value;
        !           592:                else if (!strcasecmp(attrs->type, "username") && attrs->value)
        !           593:                        c_username = attrs->value;
        !           594:                else if (!strcasecmp(attrs->type, "dbname") && attrs->value)
        !           595:                        c_dbname = attrs->value;
        !           596:                else if (!strcasecmp(attrs->type, "password") && attrs->value)
        !           597:                        c_password = attrs->value;
        !           598:                else if (!strcasecmp(attrs->type, "mask") && attrs->value)
        !           599:                        c_mask = attrs->value;
        !           600:                else if (!strcasecmp(attrs->type, "interval") && attrs->value)
        !           601:                        c_interval = strtol(attrs->value, NULL, 0);
        !           602:                else if (!strcasecmp(attrs->type, "help")) {
        !           603:                        print_module_help();
        !           604:                        exit(0);
        !           605:                }
        !           606:                
        !           607:                attrs = attrs->next;
        !           608:        }
        !           609: }
        !           610: 
        !           611: static int db_probe(void)
        !           612: {
        !           613:        if (strchr(c_mask, 'r'))
        !           614:                do_read = 1;
        !           615: 
        !           616:        if (strchr(c_mask, 's'))
        !           617:                do_sec = 1;
        !           618: 
        !           619:        if (strchr(c_mask, 'm'))
        !           620:                do_min = 1;
        !           621: 
        !           622:        if (strchr(c_mask, 'h'))
        !           623:                do_hour = 1;
        !           624: 
        !           625:        if (strchr(c_mask, 'd'))
        !           626:                do_day = 1;
        !           627:                
        !           628:        if (c_password == NULL) {
        !           629:                fprintf(stderr, "You must specify the database password\n");
        !           630:                return 0;
        !           631:        }
        !           632:        
        !           633:        if (dbi_initialize(c_driverdir) < 0) {
        !           634:                fprintf(stderr, "Cannot initialize DBI layer\n");
        !           635:                return 0;
        !           636:        }
        !           637: 
        !           638:        db_conn = dbi_conn_new(c_driver);
        !           639:        if (db_conn == NULL) {
        !           640:                fprintf(stderr, "Cannot initialize connection \"%s\"\n",
        !           641:                    c_driver);
        !           642:                return 0;
        !           643:        }
        !           644:        
        !           645:        dbi_conn_set_option(db_conn, "host", c_host);
        !           646:        dbi_conn_set_option(db_conn, "username", c_username);
        !           647:        dbi_conn_set_option(db_conn, "password", c_password);
        !           648:        dbi_conn_set_option(db_conn, "dbname", c_dbname);
        !           649:        
        !           650:        if (dbi_conn_connect(db_conn) < 0) {
        !           651:                fprintf(stderr, "Cannot open database \"%s\" connection on " \
        !           652:                    "%s@%s\n", c_dbname, c_username, c_host);
        !           653:                return 0;
        !           654:        }
        !           655: 
        !           656:        if (!create_tables()) {
        !           657:                fprintf(stderr, "Could not create tables\n");
        !           658:                return 0;
        !           659:        }
        !           660: 
        !           661:        if (!insert_attr_descs()) {
        !           662:                fprintf(stderr, "Could not insert attribute descriptions\n");
        !           663:                return 0;
        !           664:        }
        !           665: 
        !           666:        return 1;
        !           667: }
        !           668: 
        !           669: static void db_shutdown(void)
        !           670: {
        !           671:        if (db_conn)
        !           672:                dbi_conn_close(db_conn);
        !           673: 
        !           674:        dbi_shutdown();
        !           675: }
        !           676: 
        !           677: static struct output_module db_ops = {
        !           678:        .om_name = "db",
        !           679:        .om_draw = db_draw,
        !           680:        .om_set_opts = db_set_opts,
        !           681:        .om_probe = db_probe,
        !           682:        .om_shutdown db_shutdown,
        !           683: };
        !           684: 
        !           685: static void __init db_init(void)
        !           686: {
        !           687:        register_secondary_output_module(&db_ops);
        !           688: }

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