/****************************************************************************** * * * Function: init_collector_data * * * * Purpose: Allocate memory for collector * * * * Author: Eugene Grigorjev * * * * Comments: Unix version allocates memory as shared. * * * ******************************************************************************/ void init_collector_data() { const char *__function_name = "init_collector_data"; int cpu_count; size_t sz, sz_cpu; #ifndef _WINDOWS key_t shm_key; #endif zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); cpu_count = zbx_get_cpu_num(); sz = sizeof(ZBX_COLLECTOR_DATA); #ifdef _WINDOWS sz_cpu = sizeof(PERF_COUNTER_DATA *) * (cpu_count + 1); collector = zbx_malloc(collector, sz + sz_cpu); memset(collector, 0, sz + sz_cpu); collector->cpus.cpu_counter = (PERF_COUNTER_DATA **)(collector + 1); collector->cpus.count = cpu_count; #else sz_cpu = sizeof(ZBX_SINGLE_CPU_STAT_DATA) * (cpu_count + 1); if (-1 == (shm_key = zbx_ftok(CONFIG_FILE, ZBX_IPC_COLLECTOR_ID))) { zabbix_log(LOG_LEVEL_CRIT, "cannot create IPC key for collector"); exit(EXIT_FAILURE); } if (-1 == (shm_id = zbx_shmget(shm_key, sz + sz_cpu))) { zabbix_log(LOG_LEVEL_CRIT, "cannot allocate shared memory for collector"); exit(EXIT_FAILURE); } if ((void *)(-1) == (collector = shmat(shm_id, NULL, 0))) { zabbix_log(LOG_LEVEL_CRIT, "cannot attach shared memory for collector: %s", zbx_strerror(errno)); exit(EXIT_FAILURE); } collector->cpus.cpu = (ZBX_SINGLE_CPU_STAT_DATA *)(collector + 1); collector->cpus.count = cpu_count; collector->diskstat_shmid = NONEXISTENT_SHMID; if (ZBX_MUTEX_ERROR == zbx_mutex_create_force(&diskstats_lock, ZBX_MUTEX_DISKSTATS)) { zbx_error("cannot create mutex for disk statistics collector"); exit(EXIT_FAILURE); } #endif #ifdef _AIX memset(&collector->vmstat, 0, sizeof(collector->vmstat)); #endif zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: diskstat_shm_init * * * * Purpose: Allocate shared memory for collecting disk statistics * * * ******************************************************************************/ void diskstat_shm_init() { #ifndef _WINDOWS key_t shm_key; size_t shm_size; /* initially allocate memory for collecting statistics for only 1 disk */ shm_size = sizeof(ZBX_DISKDEVICES_DATA); if (-1 == (shm_key = zbx_ftok(CONFIG_FILE, ZBX_IPC_COLLECTOR_DISKSTAT))) { zabbix_log(LOG_LEVEL_CRIT, "cannot create IPC key for disk statistics collector"); exit(EXIT_FAILURE); } if (-1 == (collector->diskstat_shmid = zbx_shmget(shm_key, shm_size))) { zabbix_log(LOG_LEVEL_CRIT, "cannot allocate shared memory for disk statistics collector"); exit(EXIT_FAILURE); } if ((void *)(-1) == (diskdevices = shmat(collector->diskstat_shmid, NULL, 0))) { zabbix_log(LOG_LEVEL_CRIT, "cannot attach shared memory for disk statistics collector: %s", zbx_strerror(errno)); exit(EXIT_FAILURE); } diskdevices->count = 0; diskdevices->max_diskdev = 1; my_diskstat_shmid = collector->diskstat_shmid; zabbix_log(LOG_LEVEL_DEBUG, "diskstat_shm_init() allocated initial shm segment id:%d" " for disk statistics collector", collector->diskstat_shmid); #endif }
/****************************************************************************** * * * Function: diskstat_shm_extend * * * * Purpose: create a new, larger disk statistics shared memory segment and * * copy data from the old one. * * * ******************************************************************************/ void diskstat_shm_extend() { #ifndef _WINDOWS const char *__function_name = "diskstat_shm_extend"; key_t shm_key; size_t old_shm_size, new_shm_size; int old_shmid, new_shmid, old_max, new_max; ZBX_DISKDEVICES_DATA *new_diskdevices; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); /* caclulate the size of the new shared memory segment */ old_max = diskdevices->max_diskdev; if (old_max < 4) new_max = old_max + 1; else if (old_max < 256) new_max = old_max * 2; else new_max = old_max + 256; old_shm_size = sizeof(ZBX_DISKDEVICES_DATA) + sizeof(ZBX_SINGLE_DISKDEVICE_DATA) * (old_max - 1); new_shm_size = sizeof(ZBX_DISKDEVICES_DATA) + sizeof(ZBX_SINGLE_DISKDEVICE_DATA) * (new_max - 1); /* Create the new shared memory segment. The same key is used. */ if (-1 == (shm_key = zbx_ftok(CONFIG_FILE, ZBX_IPC_COLLECTOR_DISKSTAT))) { zabbix_log(LOG_LEVEL_CRIT, "cannot create IPC key for extending disk statistics collector"); exit(EXIT_FAILURE); } /* zbx_shmget() will: */ /* - see that a shared memory segment with this key exists */ /* - mark it for deletion */ /* - create a new segment with this key, but with a different id */ if (-1 == (new_shmid = zbx_shmget(shm_key, new_shm_size))) { zabbix_log(LOG_LEVEL_CRIT, "cannot allocate shared memory for extending disk statistics collector"); exit(EXIT_FAILURE); } if ((void *)(-1) == (new_diskdevices = shmat(new_shmid, NULL, 0))) { zabbix_log(LOG_LEVEL_CRIT, "cannot attach shared memory for extending disk statistics collector: %s", zbx_strerror(errno)); exit(EXIT_FAILURE); } /* copy data from the old segment */ memcpy(new_diskdevices, diskdevices, old_shm_size); new_diskdevices->max_diskdev = new_max; /* delete the old segment */ if (-1 == shmdt((void *) diskdevices)) { zabbix_log(LOG_LEVEL_CRIT, "cannot detach from disk statistics collector shared memory"); exit(EXIT_FAILURE); } /* switch to the new segment */ old_shmid = collector->diskstat_shmid; collector->diskstat_shmid = new_shmid; my_diskstat_shmid = collector->diskstat_shmid; diskdevices = new_diskdevices; zabbix_log(LOG_LEVEL_DEBUG, "End of %s() extended diskstat shared memory: old_max:%d new_max:%d old_size:%d" " new_size:%d old_shmid:%d new_shmid:%d", __function_name, old_max, new_max, old_shm_size, new_shm_size, old_shmid, collector->diskstat_shmid); #endif }
void zbx_mem_create(zbx_mem_info_t **info, key_t shm_key, int lock_name, zbx_uint64_t size, const char *descr, const char *param, int allow_oom) { const char *__function_name = "zbx_mem_create"; int shm_id, index; void *base; descr = ZBX_NULL2STR(descr); param = ZBX_NULL2STR(param); zabbix_log(LOG_LEVEL_DEBUG, "In %s() descr:'%s' param:'%s' size:" ZBX_FS_SIZE_T, __function_name, descr, param, (zbx_fs_size_t)size); /* allocate shared memory */ if (4 != ZBX_PTR_SIZE && 8 != ZBX_PTR_SIZE) { zabbix_log(LOG_LEVEL_CRIT, "failed assumption about pointer size (" ZBX_FS_SIZE_T " not in {4, 8})", (zbx_fs_size_t)ZBX_PTR_SIZE); exit(FAIL); } if (!(MEM_MIN_SIZE <= size && size <= MEM_MAX_SIZE)) { zabbix_log(LOG_LEVEL_CRIT, "requested size " ZBX_FS_SIZE_T " not within bounds [" ZBX_FS_UI64 " <= size <= " ZBX_FS_UI64 "]", (zbx_fs_size_t)size, MEM_MIN_SIZE, MEM_MAX_SIZE); exit(FAIL); } if (-1 == (shm_id = zbx_shmget(shm_key, size))) { zabbix_log(LOG_LEVEL_CRIT, "cannot allocate shared memory for %s", descr); exit(FAIL); } if ((void *)(-1) == (base = shmat(shm_id, NULL, 0))) { zabbix_log(LOG_LEVEL_CRIT, "cannot attach shared memory for %s: %s", descr, zbx_strerror(errno)); exit(FAIL); } /* allocate zbx_mem_info_t structure, its buckets, and description inside shared memory */ *info = ALIGN8(base); (*info)->shm_id = shm_id; (*info)->orig_size = size; size -= (void *)(*info + 1) - base; base = (void *)(*info + 1); (*info)->buckets = ALIGNPTR(base); memset((*info)->buckets, 0, MEM_BUCKET_COUNT * ZBX_PTR_SIZE); size -= (void *)((*info)->buckets + MEM_BUCKET_COUNT) - base; base = (void *)((*info)->buckets + MEM_BUCKET_COUNT); zbx_strlcpy(base, descr, size); (*info)->mem_descr = base; size -= strlen(descr) + 1; base += strlen(descr) + 1; zbx_strlcpy(base, param, size); (*info)->mem_param = base; size -= strlen(param) + 1; base += strlen(param) + 1; (*info)->allow_oom = allow_oom; /* allocate mutex */ if (ZBX_NO_MUTEX != lock_name) { (*info)->use_lock = 1; if (ZBX_MUTEX_ERROR == zbx_mutex_create_force(&((*info)->mem_lock), lock_name)) { zabbix_log(LOG_LEVEL_CRIT, "cannot create mutex for %s", descr); exit(FAIL); } } else (*info)->use_lock = 0; /* prepare shared memory for further allocation by creating one big chunk */ (*info)->lo_bound = ALIGN8(base); (*info)->hi_bound = ALIGN8(base + size - 8); (*info)->total_size = (zbx_uint64_t)((*info)->hi_bound - (*info)->lo_bound - 2 * MEM_SIZE_FIELD); index = mem_bucket_by_size((*info)->total_size); (*info)->buckets[index] = (*info)->lo_bound; mem_set_chunk_size((*info)->buckets[index], (*info)->total_size); mem_set_prev_chunk((*info)->buckets[index], NULL); mem_set_next_chunk((*info)->buckets[index], NULL); (*info)->used_size = 0; (*info)->free_size = (*info)->total_size; zabbix_log(LOG_LEVEL_DEBUG, "valid user addresses: [%p, %p] total size: " ZBX_FS_SIZE_T, (*info)->lo_bound + MEM_SIZE_FIELD, (*info)->hi_bound - MEM_SIZE_FIELD, (zbx_fs_size_t)(*info)->total_size); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: init_selfmon_collector * * * * Purpose: Initialize structures and prepare state * * for self-monitoring collector * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ void init_selfmon_collector() { const char *__function_name = "init_selfmon_collector"; size_t sz, sz_array, sz_process[ZBX_PROCESS_TYPE_COUNT], sz_total; key_t shm_key; char *p; clock_t ticks; struct tms buf; unsigned char process_type; int process_num, process_forks; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); sz_total = sz = sizeof(zbx_selfmon_collector_t); sz_total += sz_array = sizeof(zbx_stat_process_t *) * ZBX_PROCESS_TYPE_COUNT; for (process_type = 0; process_type < ZBX_PROCESS_TYPE_COUNT; process_type++) sz_total += sz_process[process_type] = sizeof(zbx_stat_process_t) * get_process_type_forks(process_type); zabbix_log(LOG_LEVEL_DEBUG, "%s() size:%d", __function_name, (int)sz_total); if (-1 == (shm_key = zbx_ftok(CONFIG_FILE, ZBX_IPC_SELFMON_ID))) { zabbix_log(LOG_LEVEL_CRIT, "Cannot create IPC key for a self-monitoring collector"); exit(FAIL); } if (ZBX_MUTEX_ERROR == zbx_mutex_create_force(&sm_lock, ZBX_MUTEX_SELFMON)) { zbx_error("Unable to create mutex for a self-monitoring collector"); exit(FAIL); } if (-1 == (shm_id = zbx_shmget(shm_key, sz_total))) { zabbix_log(LOG_LEVEL_CRIT, "Cannot allocate shared memory for a self-monitoring collector"); exit(FAIL); } if ((void *)(-1) == (p = shmat(shm_id, NULL, 0))) { zabbix_log(LOG_LEVEL_CRIT, "Cannot attach shared memory for a self-monitoring collector [%s]", strerror(errno)); exit(FAIL); } collector = (zbx_selfmon_collector_t *)p; p += sz; collector->process = (zbx_stat_process_t **)p; p += sz_array; ticks = times(&buf); for (process_type = 0; process_type < ZBX_PROCESS_TYPE_COUNT; process_type++) { collector->process[process_type] = (zbx_stat_process_t *)p; p += sz_process[process_type]; memset(collector->process[process_type], 0, sz_process[process_type]); process_forks = get_process_type_forks(process_type); for (process_num = 0; process_num < process_forks; process_num++) { collector->process[process_type][process_num].last_ticks = ticks; collector->process[process_type][process_num].last_state = ZBX_PROCESS_STATE_BUSY; } } zabbix_log(LOG_LEVEL_DEBUG, "End of %s() collector:%p", __function_name, collector); }