/******************************************************************************
 *                                                                            *
 * 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);
}
Example #2
0
/******************************************************************************
 *                                                                            *
 * 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
}
Example #3
0
/******************************************************************************
 *                                                                            *
 * 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
}
Example #4
0
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);
}
Example #5
0
/******************************************************************************
 *                                                                            *
 * 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);
}