get_poller_status.c
Pollerプロセスの状態を取得します。
get_poller_status.c
—
C source code,
5 KB (5639 bytes)
ファイルコンテンツ
/*
* Licensing:
* Some parts of this code is imported from Zabbix-2.0.10 and
* util-linux-ng-2.17.2/sys-utils/ipcs.c. But, licensing detail is
* not written in ipcs.c...
* So, I decided the license to GPLv3.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/times.h>
#if defined (__GLIBC__) && __GLIBC__ >= 2
#define KEY __key
#else
#define KEY key
#endif
#ifndef HAVE_UNION_SEMUN
/* according to X/OPEN we have to define it ourselves */
union semun {
int val;
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
#endif
#define ZBX_PROCESS_STATE_COUNT 2
#define ZBX_PROCESS_TYPE_POLLER 0
#define ZBX_PROCESS_TYPE_COUNT 21 /* number of process types */
#define MAX_HISTORY 60
typedef struct {
unsigned short h_counter[ZBX_PROCESS_STATE_COUNT][MAX_HISTORY];
unsigned short counter[ZBX_PROCESS_STATE_COUNT];
clock_t last_ticks;
unsigned char last_state;
}
zbx_stat_process_t;
typedef struct {
zbx_stat_process_t **process;
int first;
int count;
}
zbx_selfmon_collector_t;
#define CONFIG_FILE "/etc/zabbix/zabbix_server.conf"
#define ZBX_IPC_SELFMON_ID 'S'
void mutex_lock(int semid, int mutex_selfmon)
{
struct sembuf sem_lock;
sem_lock.sem_num = mutex_selfmon;
sem_lock.sem_op = -1;
sem_lock.sem_flg = SEM_UNDO;
if (semop(semid, &sem_lock, 1) == -1) {
fprintf(stderr, "cannnot access semaphore\n");
exit(EXIT_FAILURE);
}
}
void mutex_unlock(int semid, int mutex_selfmon)
{
struct sembuf sem_unlock;
sem_unlock.sem_num = mutex_selfmon;
sem_unlock.sem_op = 1;
sem_unlock.sem_flg = SEM_UNDO;
if (semop(semid, &sem_unlock, 1) == -1) {
fprintf(stderr, "cannnot access semaphore\n");
exit(EXIT_FAILURE);
}
}
int get_shmid(char *conf)
{
key_t shm_key;
int maxid, id, shmid = -1;
struct shmid_ds shmseg;
struct shminfo shminfo;
struct ipc_perm *ipcp = &shmseg.shm_perm;
if ((shm_key = ftok(conf, ZBX_IPC_SELFMON_ID)) == -1) {
fprintf(stderr, "cannot create IPC key for a self-monitoring collector\n");
goto out;
}
fprintf(stdout, "shm_key = 0x%08x\n", shm_key);
if ((maxid = shmctl(0, SHM_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0) {
fprintf(stderr, "kernel not configured for shared memory\n");
goto out;
}
for (id = 0; id <= maxid; id++) {
shmid = shmctl(id, SHM_STAT, &shmseg);
if (shmid < 0)
continue;
if (shm_key == ipcp->KEY)
break;
}
if (shmid < 0 || id > maxid) {
fprintf(stdout, "cannot find shared memory for a self-monitoring collector\n");
shmid = -1;
}
fprintf(stdout, "shmid = %-10d\n", shmid);
out:
return shmid;
}
int get_semid(char *conf)
{
key_t sem_key;
int maxid, semid = -1, id;
struct semid_ds semary;
struct seminfo seminfo;
struct ipc_perm *ipcp = &semary.sem_perm;
union semun arg;
if ((sem_key = ftok(conf, (int)'z')) == -1) {
fprintf(stderr, "cannot create IPC key for a self-monitoring collector\n");
goto out;
}
fprintf(stdout, "sem_key = 0x%08x\n", sem_key);
arg.array = (ushort *) (void *) &seminfo;
maxid = semctl(0, 0, SEM_INFO, arg);
if (maxid < 0) {
fprintf(stderr, "kernel not configured for semaphores\n");
goto out;
}
for (id = 0; id <= maxid; id++) {
arg.buf = (struct semid_ds *) &semary;
semid = semctl(id, 0, SEM_STAT, arg);
if (semid < 0)
continue;
if (sem_key == ipcp->KEY)
break;
}
if (semid < 0 || id > maxid) {
fprintf(stdout, "cannot find semaphore for a self-monitoring collector\n");
semid = -1;
}
fprintf(stdout, "semid = %-10d\n", semid);
out:
return semid;
}
void usage(char *prog)
{
fprintf(stderr, "Usage: %s [-c config_file] [-p poller_process] -z zabbix_version\n", prog);
}
int get_mutex_selfmon(char *zop)
{
int zver;
zop += 4;
zver = atoi(zop);
if (zver < 0) return -1;
else if (zver < 7) return 7;
else return 6;
}
int main(int argc, char *argv[])
{
int retval = 1, i, opt;
static char *conf_file = CONFIG_FILE;
int poller_process = 5;
int mutex_selfmon, zflag = 0;
int shmid, semid;
zbx_selfmon_collector_t *collector;
char *p;
zbx_stat_process_t *process;
while ((opt = getopt(argc, argv, "c:p:z:")) != -1) {
switch (opt) {
case 'c':
conf_file = optarg;
break;
case 'p':
poller_process = atoi(optarg);
break;
case 'z':
if (strncmp(optarg, "2.0.", 4) != 0) {
usage(argv[0]);
exit(EXIT_FAILURE);
}
if ((mutex_selfmon = get_mutex_selfmon(optarg)) == -1) {
fprintf(stderr, "incorrect zabbix version\n");
exit(EXIT_FAILURE);
}
zflag = 1;
break;
default: /* '?' */
usage(argv[0]);
exit(EXIT_FAILURE);
}
}
if (zflag == 0) {
usage(argv[0]);
exit(EXIT_FAILURE);
}
if ((shmid = get_shmid(conf_file)) == -1) goto out;
if ((semid = get_semid(conf_file)) == -1) goto out;
if ((p = (char *)shmat(shmid, NULL, 0)) == (void *)(-1)) {
fprintf(stderr, "cannot attach shared memory for a self-monitoring collector\n");
goto out;
}
mutex_lock(semid, mutex_selfmon);
collector = (zbx_selfmon_collector_t *)p;
p += sizeof(zbx_selfmon_collector_t);
p += sizeof(zbx_stat_process_t *) * ZBX_PROCESS_TYPE_COUNT;
process = (zbx_stat_process_t *)p;
for (i = 0; i < poller_process; i++) {
fprintf(stdout, "Poller[%d] last_ticks = %ld\n", i, process[i].last_ticks);
}
mutex_unlock(semid, mutex_selfmon);
shmdt(collector);
retval = 0;
out:
return retval;
}

