/****************************************************************************** * * * Comments: counter is removed from the collector and * * the memory is freed - do not use it again * * * ******************************************************************************/ void remove_perf_counter(PERF_COUNTER_DATA *counter) { PERF_COUNTER_DATA *cptr; if (NULL == counter || NULL == ppsd.pPerfCounterList) return; zbx_mutex_lock(&perfstat_access); if (counter == ppsd.pPerfCounterList) { ppsd.pPerfCounterList = counter->next; } else { for (cptr = ppsd.pPerfCounterList; ; cptr = cptr->next) { if (cptr->next == counter) { cptr->next = counter->next; break; } } } zbx_mutex_unlock(&perfstat_access); PdhRemoveCounter(counter->handle); zbx_free(counter->name); zbx_free(counter->counterpath); zbx_free(counter->value_array); zbx_free(counter); }
static void free_perf_counter_list() { PERF_COUNTER_DATA *cptr; zbx_mutex_lock(&perfstat_access); while (NULL != ppsd.pPerfCounterList) { cptr = ppsd.pPerfCounterList; ppsd.pPerfCounterList = cptr->next; zbx_free(cptr->name); zbx_free(cptr->counterpath); zbx_free(cptr->value_array); zbx_free(cptr); } zbx_mutex_unlock(&perfstat_access); }
/****************************************************************************** * * * Function: node_sync_lock * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ void node_sync_lock(int nodeid) { zbx_mutex_lock(&node_sync_access); }
/****************************************************************************** * * * Function: zbx_mutex_create_ext * * * * Purpose: Create the mutex * * * * Parameters: mutex - handle of mutex * * name - name of mutex (index for nix system) * * forced - remove mutex if exists (only for nix) * * * * Return value: If the function succeeds, then return SUCCEED, * * FAIL on an error * * * * Author: Eugene Grigorjev * * * * Comments: use alias 'zbx_mutex_create' and 'zbx_mutex_create_force' * * * ******************************************************************************/ int zbx_mutex_create_ext(ZBX_MUTEX *mutex, ZBX_MUTEX_NAME name, unsigned char forced) { #ifdef _WINDOWS if (NULL == (*mutex = CreateMutex(NULL, FALSE, name))) { zbx_error("error on mutex creating: %s", strerror_from_system(GetLastError())); return FAIL; } #else #define ZBX_MAX_ATTEMPTS 10 int attempts = 0, i; key_t sem_key; union semun semopts; struct semid_ds seminfo; if (-1 == (sem_key = ftok(CONFIG_FILE, (int)'z'))) { zbx_error("cannot create IPC key for path '%s', try to create for path '.': %s", CONFIG_FILE, zbx_strerror(errno)); if (-1 == (sem_key = ftok(".", (int)'z'))) { zbx_error("cannot create IPC key for path '.': %s", zbx_strerror(errno)); return FAIL; } } lbl_create: if (-1 != ZBX_SEM_LIST_ID || -1 != (ZBX_SEM_LIST_ID = semget(sem_key, ZBX_MUTEX_COUNT, IPC_CREAT | IPC_EXCL | 0600 /* 0022 */)) ) { /* set default semaphore value */ semopts.val = 1; for (i = 0; ZBX_MUTEX_COUNT > i; i++) { if (-1 == semctl(ZBX_SEM_LIST_ID, i, SETVAL, semopts)) { zbx_error("semaphore [%i] error in semctl(SETVAL): %s", name, zbx_strerror(errno)); return FAIL; } zbx_mutex_lock(&i); /* call semop to update sem_otime */ zbx_mutex_unlock(&i); /* release semaphore */ } } else if (EEXIST == errno) { ZBX_SEM_LIST_ID = semget(sem_key, 0 /* get reference */, 0600 /* 0022 */); if (1 == forced) { if (0 != semctl(ZBX_SEM_LIST_ID, 0, IPC_RMID, 0)) { zbx_error("cannot recreate Zabbix semaphores for IPC key 0x%lx Semaphore ID %ld: %s", sem_key, ZBX_SEM_LIST_ID, zbx_strerror(errno)); exit(EXIT_FAILURE); } /* semaphore is successfully removed */ ZBX_SEM_LIST_ID = -1; if (ZBX_MAX_ATTEMPTS < ++attempts) { zbx_error("cannot recreate Zabbix semaphores for IPC key 0x%lx: too many attempts", sem_key); exit(EXIT_FAILURE); } if ((ZBX_MAX_ATTEMPTS / 2) < attempts) zbx_sleep(1); goto lbl_create; } semopts.buf = &seminfo; /* wait for initialization */ for (i = 0; ZBX_MUTEX_MAX_TRIES > i; i++) { if (-1 == semctl(ZBX_SEM_LIST_ID, 0, IPC_STAT, semopts)) { zbx_error("semaphore [%i] error in semctl(IPC_STAT): %s", name, zbx_strerror(errno)); break; } if (0 != semopts.buf->sem_otime) goto lbl_return; zbx_sleep(1); } zbx_error("semaphore [%i] not initialized", name); return FAIL; } else { zbx_error("cannot create Semaphore: %s", zbx_strerror(errno)); return FAIL; } lbl_return: *mutex = name; mutexes++; #endif /* _WINDOWS */ return SUCCEED; }
/****************************************************************************** * * * Function: zbx_mutex_create_ext * * * * Purpose: Create the mutex * * * * Parameters: mutex - handle of mutex * * name - name of mutex (index for nix system) * * forced - remove mutex if exists (only for nix) * * * * Return value: If the function succeeds, then return ZBX_MUTEX_OK, * * ZBX_MUTEX_ERROR on an error * * * * Author: Eugene Grigorjev * * * * Comments: you can use alias 'zbx_mutex_create' and 'zbx_mutex_create_force'* * * ******************************************************************************/ int zbx_mutex_create_ext(ZBX_MUTEX *mutex, ZBX_MUTEX_NAME name, unsigned char forced) { #if defined(_WINDOWS) if(NULL == ((*mutex) = CreateMutex(NULL, FALSE, name))) { zbx_error("Error on mutex creating. [%s]", strerror_from_system(GetLastError())); return ZBX_MUTEX_ERROR; } #else /* not _WINDOWS */ #define ZBX_MAX_ATTEMPTS 10 int attempts = 0, i; key_t sem_key; union semun semopts; struct semid_ds seminfo; if (-1 == (sem_key = ftok(CONFIG_FILE, (int)'z'))) { zbx_error("Can not create IPC key for path '%s', try to create for path '.' [%s]", CONFIG_FILE, strerror(errno)); if (-1 == (sem_key = ftok(".", (int)'z'))) { zbx_error("Can not create IPC key for path '.' [%s]", strerror(errno)); return ZBX_MUTEX_ERROR; } } lbl_create: if (-1 != ZBX_SEM_LIST_ID || -1 != (ZBX_SEM_LIST_ID = semget(sem_key, ZBX_MUTEX_COUNT, IPC_CREAT | IPC_EXCL | 0600 /* 0022 */)) ) { /* set default semaphore value */ semopts.val = 1; for (i = 0; i < ZBX_MUTEX_COUNT; i++) { if (-1 == semctl(ZBX_SEM_LIST_ID, i, SETVAL, semopts)) { zbx_error("Semaphore [%i] error in semctl(SETVAL) [%s]", name, strerror(errno)); return ZBX_MUTEX_ERROR; } zbx_mutex_lock(&i); /* call semop to update sem_otime */ zbx_mutex_unlock(&i); /* release semaphore */ } } else if (errno == EEXIST) { ZBX_SEM_LIST_ID = semget(sem_key, 0 /* get reference */, 0600 /* 0022 */); if (forced) { if (0 != semctl(ZBX_SEM_LIST_ID, 0, IPC_RMID, 0)) { zbx_error("Can't recreate Zabbix semaphores for IPC key 0x%lx Semaphore ID %ld. %s.", sem_key, ZBX_SEM_LIST_ID, strerror(errno)); exit(FAIL); } /* Semaphore is successfully removed */ ZBX_SEM_LIST_ID = -1; if (++attempts > ZBX_MAX_ATTEMPTS) { zbx_error("Can't recreate Zabbix semaphores for IPC key 0x%lx. [too many attempts]", sem_key); exit(FAIL); } if (attempts > (ZBX_MAX_ATTEMPTS / 2)) { zbx_sleep(1); } goto lbl_create; } semopts.buf = &seminfo; /* wait for initialization */ for (i = 0; i < ZBX_MUTEX_MAX_TRIES; i++) { if (-1 == semctl(ZBX_SEM_LIST_ID, 0, IPC_STAT, semopts)) { zbx_error("Semaphore [%i] error in semctl(IPC_STAT). %s.", name, strerror(errno)); break; } if(semopts.buf->sem_otime !=0 ) goto lbl_return; zbx_sleep(1); } zbx_error("Semaphore [%i] not initialized", name); return ZBX_MUTEX_ERROR; } else { zbx_error("Can not create Semaphore [%s]", strerror(errno)); return ZBX_MUTEX_ERROR; } lbl_return: *mutex = name; mutexes++; #endif /* _WINDOWS */ return ZBX_MUTEX_OK; }
/****************************************************************************** * * * Comments: if the specified counter exists or a new is successfully * * added, a pointer to that counter is returned, NULL otherwise * * * ******************************************************************************/ PERF_COUNTER_DATA *add_perf_counter(const char *name, const char *counterpath, int interval) { const char *__function_name = "add_perf_counter"; PERF_COUNTER_DATA *cptr; char *alias_name; PDH_STATUS pdh_status; int result = FAIL; assert(counterpath); zabbix_log(LOG_LEVEL_DEBUG, "In %s() counter:'%s' interval:%d", __function_name, counterpath, interval); if (SUCCEED != perf_collector_started()) { zabbix_log(LOG_LEVEL_WARNING, "PerfCounter '%s' FAILED: collector is not started!", counterpath); return NULL; } if (1 > interval || 900 < interval) { zabbix_log(LOG_LEVEL_WARNING, "PerfCounter '%s' FAILED: interval value out of range", counterpath); return NULL; } for (cptr = ppsd.pPerfCounterList; ; cptr = cptr->next) { /* add new parameters */ if (NULL == cptr) { cptr = (PERF_COUNTER_DATA *)zbx_malloc(cptr, sizeof(PERF_COUNTER_DATA)); /* initialize the counter */ memset(cptr, 0, sizeof(PERF_COUNTER_DATA)); if (NULL != name) cptr->name = strdup(name); cptr->counterpath = strdup(counterpath); cptr->interval = interval; cptr->value_current = -1; cptr->value_array = (double *)zbx_malloc(cptr->value_array, sizeof(double) * interval); /* add the counter to the query */ pdh_status = zbx_PdhAddCounter(__function_name, cptr, ppsd.pdh_query, counterpath, &cptr->handle); zbx_mutex_lock(&perfstat_access); cptr->next = ppsd.pPerfCounterList; ppsd.pPerfCounterList = cptr; zbx_mutex_unlock(&perfstat_access); if (ERROR_SUCCESS != pdh_status && PDH_CSTATUS_NO_INSTANCE != pdh_status) { zabbix_log(LOG_LEVEL_WARNING, "cannot add performance counter \"%s\": invalid format", counterpath); cptr = NULL; /* indicate a failure */ } result = SUCCEED; break; } if (NULL != name && 0 == strcmp(cptr->name, name)) break; if (NULL == name && 0 == strcmp(cptr->counterpath, counterpath) && cptr->interval == interval) break; } if (FAIL == result) { zabbix_log(LOG_LEVEL_DEBUG, "%s() counter '%s' already exists", __function_name, counterpath); } else if (NULL != name) { alias_name = zbx_dsprintf(NULL, "__UserPerfCounter[%s]", name); add_alias(name, alias_name); zbx_free(alias_name); } return cptr; }