⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmstat.c

📁 mmstatd包含一个 C库和服务器
💻 C
字号:
/* $Id: mmstat.c,v 1.3 2003/01/08 20:57:46 mmondor Exp $ *//* * Copyright (C) 2002-2003, Matthew Mondor * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *      This product includes software written by Matthew Mondor. * 4. The name of Matthew Mondor may not be used to endorse or promote *    products derived from this software without specific prior written *    permission. * * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *//* HEADERS */#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#include <sys/uio.h>#include <sys/poll.h>#include <stdlib.h>#include <unistd.h>#include <stdio.h>#include <stdarg.h>#include <syslog.h>#include <mmtypes.h>#include <mmstat.h>#include <mmreadcfg.h>#include <mmstring.h>MMCOPYRIGHT("@(#) Copyright (c) 2002-2003\n\\tMatthew Mondor. All rights reserved.\n");MMRCSID("$Id: mmstat.c,v 1.3 2003/01/08 20:57:46 mmondor Exp $");/* PRIVATE PROTOTYPES */static bool i_mmstat_send(struct log_entry *, int);/* GLOBALS */static struct mmstat_config CONF;static bool mmstat_initialized = FALSE, connect_log = TRUE;static int lsock = -1;static struct sockaddr_un laddr;/* FUNCTIONS *//* Public API mmstat functions */boolmmstat_init(MMSTAT *mms, bool persistant, bool autoflush){    bool ret = FALSE;    if (mmstat_initialized || mmstat_initialize()) {	mms->transaction = FALSE;	mms->persistant = persistant;	mms->autoflush = autoflush;	mms->transact_pos = 0;	ret = TRUE;    }    return (ret);}boolmmstat(MMSTAT *mms, enum stat_type type, int64_t value, char *fmt, ...){    bool ok = FALSE;    struct log_entry *entry;    va_list arg_ptr;    if (type == STAT_RESET || type == STAT_UPDATE || type == STAT_DELETE) {	if (mms->transact_pos < MAX_TRANSACT) {	    /* In case transaction mode is active, make sure to not overflow	     * buffer, and that we write next entry at the right offset.	     * The mmstatd logger process only distinguishes transaction	     * protected requests in that they are all sent in a single packet.	     */	    entry = &(mms->entries[mms->transact_pos]);	    mms->transact_pos++;	    /* Now simply fill new log entry */	    mm_memclr(entry, sizeof(struct log_entry));	    entry->type = type;	    entry->persistant = mms->persistant;	    entry->autoflush = mms->autoflush;	    if (fmt) {		va_start(arg_ptr, fmt);		vsnprintf(entry->key, KEY_SIZE - 1, fmt, arg_ptr);		va_end(arg_ptr);	    }	    if (type == STAT_UPDATE) entry->un.update.modifier = value;	    else if (type == STAT_RESET) entry->un.reset.value = value;	    ok = TRUE;	}    }    if (ok && !mms->transaction) {	/* Not in transaction mode, flush packet to mmstatd immediately */	ok = i_mmstat_send(mms->entries, 1);	mms->transact_pos = 0;    }    return (ok);}boolmmstat_transact(MMSTAT *mms, bool lock){    bool ok = FALSE;    if (lock) {	if (!mms->transaction) {	    /* Start transaction mode */	    mms->transaction = TRUE;	    mms->transact_pos = 0;	    ok = TRUE;	}    } else {	if (mms->transaction) {	    /* End transaction mode, flush transaction queue to mmstatd */	    if (i_mmstat_send(mms->entries, mms->transact_pos)) ok = TRUE;	    mms->transaction = FALSE;	    mms->transact_pos = 0;	}    }    return (ok);}MMSTATRES *mmstat_report(char *fmt, ...){    MMSTATRES *res = NULL;    struct sockaddr_un sun;    va_list arg_ptr;    char key[KEY_SIZE], c;    if (fmt) {	mm_memclr(key, KEY_SIZE);	va_start(arg_ptr, fmt);	vsnprintf(key, KEY_SIZE - 1, fmt, arg_ptr);	va_end(arg_ptr);	connect_log = FALSE;	if (mmstat_initialized || mmstat_initialize()) {	    if ((res = malloc(sizeof(MMSTATRES)))) {		if ((res->fd = socket(AF_LOCAL, SOCK_STREAM, 0)) != -1) {		    mm_memclr(&sun, sizeof(struct sockaddr_un));		    sun.sun_family = AF_UNIX;		    mm_strcpy(sun.sun_path, CONF.STAT_SOCKET);		    if (connect(res->fd, (struct sockaddr *)&sun,				sizeof(struct sockaddr_un)) != -1) {			if ((read(res->fd, &c, 1) == 1) && (c == '+')) {			    if (write(res->fd, "s", 1) == 1 &&				write(res->fd, key, KEY_SIZE) == KEY_SIZE)				return (res);			}		    }		    close(res->fd);		}		free(res);	    }	}    }    return (NULL);}MMSTATENT *mmstat_nextres(MMSTATRES *res){    struct pollfd fds[] = {	{res->fd, POLLIN, 0}    };    for (;;) {	if (poll(fds, 1, -1) == 1) {	    if (fds[0].revents & POLLIN) {		if (read(res->fd, &res->entry, sizeof(MMSTATENT)) ==			sizeof(MMSTATENT))		    return (&res->entry);		else break;	    }	}    }    return (NULL);}MMSTATRES *mmstat_freeres(MMSTATRES *res){    close(res->fd);    free(res);    return (NULL);}boolmmstat_rotate(char *pattern, char *prefix){    struct sockaddr_un sun;    int fd;    char pat[KEY_SIZE], pre[KEY_SIZE], c;    bool ok = FALSE;    if (pattern && prefix) {	mm_memclr(pat, KEY_SIZE);	mm_strncpy(pat, pattern, KEY_SIZE - 1);	mm_memclr(pre, KEY_SIZE);	mm_strncpy(pre, prefix, KEY_SIZE - 1);	connect_log = FALSE;	if (mmstat_initialized || mmstat_initialize()) {	    if ((fd = socket(AF_LOCAL, SOCK_STREAM, 0)) != -1) {		mm_memclr(&sun, sizeof(struct sockaddr_un));		sun.sun_family = AF_UNIX;		mm_strcpy(sun.sun_path, CONF.STAT_SOCKET);		if (connect(fd, (struct sockaddr *)&sun,			    sizeof(struct sockaddr_un)) != -1) {		    if ((read(fd, &c, 1) == 1) && (c == '+')) {			if (write(fd, "r", 1) == 1 &&				write(fd, pat, KEY_SIZE) == KEY_SIZE &&				write(fd, pre, KEY_SIZE) == KEY_SIZE)			    ok = TRUE;		    }		}		close(fd);	    }	}    }    return (ok);}/* Internal functions not available to the public mmstat API */static booli_mmstat_send(struct log_entry *entries, int len){    int l;    bool ok = FALSE;    l = sizeof(struct log_entry) * len;    while (!ok) {    	if (lsock != -1) {    	    if ((send(lsock, entries, l, 0)) == l)    		ok = TRUE;	    else {		close(lsock);		lsock = -1;	    }	}	if (!ok) {	    /* Attempt to re-establish connection to mmstatd(8) */	    syslog(LOG_NOTICE, "mmstat - Re-establishing lost connection");	    if (!mmstat_initialize())		break;	}    }    return (ok);}boolmmstat_initialize(void){    char *conf_file = "/etc/mmstatd.conf", *tmp;    bool ok = FALSE;    CRES cres;    CARG cargs[] = {	{CAT_STR, 1, 31, CAS_UNTOUCHED, "USER", CONF.USER},	{CAT_STR, 1, 255, CAS_UNTOUCHED, "GROUPS", CONF.GROUPS},	{CAT_STR, 1, 31, CAS_UNTOUCHED, "LOG_FACILITY", CONF.LOG_FACILITY},	{CAT_STR, 1, 255, CAS_UNTOUCHED, "PID_FILE", CONF.PID_FILE},	{CAT_STR, 1, 255, CAS_UNTOUCHED, "LOCK_FILE", CONF.LOCK_FILE},	{CAT_STR, 1, 255, CAS_UNTOUCHED, "LOG_SOCKET", CONF.LOG_SOCKET},	{CAT_STR, 1, 255, CAS_UNTOUCHED, "STAT_SOCKET", CONF.STAT_SOCKET},	{CAT_STR, 1, 127, CAS_UNTOUCHED, "ENV_DIR", CONF.ENV_DIR},	{CAT_STR, 1, 31, CAS_UNTOUCHED, "LOG_GROUP", CONF.LOG_GROUP},	{CAT_STR, 1, 31, CAS_UNTOUCHED, "STAT_GROUP", CONF.STAT_GROUP},	{CAT_VAL, 1, 99999999, CAS_UNTOUCHED, "SYNC_INTERVAL",	    &CONF.SYNC_INTERVAL},	{CAT_VAL, 0, 99999999, CAS_UNTOUCHED, "SYNC_BYTES",	    &CONF.SYNC_BYTES},	{CAT_VAL, 1, 99999999, CAS_UNTOUCHED, "MAX_LOGSIZE",	    &CONF.MAX_LOGSIZE},	{CAT_VAL, 1, 9999, CAS_UNTOUCHED, "STATS_RATE", &CONF.STATS_RATE},	{CAT_VAL, 1, 9999, CAS_UNTOUCHED, "STATS_TIME", &CONF.STATS_TIME},	{CAT_END, 0, 0, 0, NULL, NULL}    };    /* Set defaults */    mm_strcpy(CONF.USER, "mmstatd");    mm_strcpy(CONF.GROUPS, "mmstat staff");    mm_strcpy(CONF.LOG_FACILITY, "LOG_AUTHPRIV");    mm_strcpy(CONF.PID_FILE, "/var/mmstatd/mmstatd.pid");    mm_strcpy(CONF.LOG_SOCKET, "/var/mmstatd/mmstatd_log.sock");    mm_strcpy(CONF.STAT_SOCKET, "/var/mmstatd/mmstatd_stat.sock");    mm_strcpy(CONF.ENV_DIR, "/var/mmstatd");    mm_strcpy(CONF.LOG_GROUP, "mmstat");    mm_strcpy(CONF.STAT_GROUP, "staff");    CONF.SYNC_INTERVAL = 1800;    CONF.SYNC_BYTES = 4096;    CONF.MAX_LOGSIZE = 1048576;    CONF.STATS_RATE = 5;    CONF.STATS_TIME = 10;    if ((tmp = getenv("MMSTATCONF")))	conf_file = tmp;    if (mmreadcfg(conf_file, cargs, &cres)) {	if (connect_log) {	    if ((lsock = socket(AF_LOCAL, SOCK_DGRAM, 0)) != -1) {		mm_memclr(&laddr, sizeof(struct sockaddr_un));		mm_strncpy(laddr.sun_path, CONF.LOG_SOCKET, 100);		laddr.sun_family = AF_UNIX;		if ((connect(lsock, (struct sockaddr *)&laddr,				sizeof(struct sockaddr_un))) == -1) {		    close(lsock);		    lsock = -1;		    syslog(LOG_NOTICE, "mmstat_initialize() - connect(%s)",			    CONF.LOG_SOCKET);		}	    } else		syslog(LOG_NOTICE, "mmstat_initialize() - socket()");	    if (lsock != -1)		ok = TRUE;	} else	    ok = TRUE;    } else	syslog(LOG_NOTICE,	       "mmstat_initialize() - mmreadcfg(/etc/mmstatd.conf)");    mmstat_initialized = ok;    return (ok);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -