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