void * tc_helper_thread(void *t_context) { int rc = 0; struct thread_context *tctx = (struct thread_context *)t_context; int old_state, old_type; rc = pthread_mutex_lock(&tctx->helper_mutex); if (rc) { printf("%s: pthread_mutex_lock failed with rc = %d, errno = %d \n", rc, errno); pthread_exit(&rc); } /* notify main thread to proceed creating other master thread */ rc = pthread_cond_broadcast(&tctx->helper_cond); if (rc) { printf(" %s: pthread_cond_broadcast failed with rc = %d, errno = %d \n", __FUNCTION__, rc, errno); pthread_exit(&rc); } rc = pthread_mutex_unlock(&tctx->helper_mutex); if (rc) { printf(" %s: pthread_mutex_unlock failed failed with rc = %d, errno = %d \n", __FUNCTION__, rc, errno); pthread_exit(&rc); } pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_state); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old_type); /* creates a cancellation point in the calling thread */ pthread_testcancel(); rc = recv_arp_reply(tctx); if(rc) { printf("Error recv packets on interface %s, errno = %d \n", &tctx->source.name, errno); } pthread_exit(&rc); }
void reload(GLOBAL *g, struct pinger_module *p) { QueryHandle *res; int i, j, nc=0, n=2; char *hoststr; struct net *nets = (struct net *) malloc(sizeof(struct net)); char *netnames = strdup(p->networks); char *netname = strdup(netnames); while( n>1 ) { n = sscanf(netnames, "%s %[._a-zA-Z0-9- ]", netname, netnames); if( strlen(netname) ) { res = g->db_pquery(g->conn, "SELECT name, domain, address, INET_ATON(mask) AS mask, interface, gateway FROM networks WHERE UPPER(name)=UPPER('?')", netname); if(g->db_nrows(res)) { nets = (struct net *) realloc(nets, (sizeof(struct net) * (nc+1))); nets[nc].address = inet_addr(g->db_get_data(res,0,"address")); nets[nc].mask = inet_addr(g->db_get_data(res,0,"mask")); nc++; } g->db_free(&res); } } free(netname); free(netnames); if(!nc) { res = g->db_query(g->conn, "SELECT name, domain, address, INET_ATON(mask) AS mask, interface, gateway FROM networks"); for(nc=0; nc<g->db_nrows(res); nc++) { nets = (struct net*) realloc(nets, (sizeof(struct net) * (nc+1))); nets[nc].address = inet_addr(g->db_get_data(res,nc,"address")); nets[nc].mask = inet_addr(g->db_get_data(res,nc,"mask")); } g->db_free(&res); } res = g->db_pquery(g->conn, "SELECT id, INET_NTOA(ipaddr) AS ip FROM nodes"); for(i=0; i<g->db_nrows(res); i++) { unsigned long ip = inet_addr(g->db_get_data(res,i,"ip")); for(j=0; j<nc; j++) if((ip & nets[j].mask) == nets[j].address) break; if(j!=nc) { hosts = (struct host*) realloc(hosts, sizeof(struct host) * (nh + 1)); hosts[nh].id = strdup(g->db_get_data(res,i,"id")); hosts[nh].ipaddr = ip; hosts[nh].active = 0; nh++; } } g->db_free(&res); /***********************************************************/ get_ifaces(); // activate nodes with interface's IPs because module can't recive // "ping" response when source IP == destination IP for(j=0; j<descs_count; j++) for(i=0; i<nh; i++) if( hosts[i].ipaddr == descs[j].ip) { hosts[i].active = 1; break; } // run "pinger" switch (fork()) { case -1: syslog(LOG_CRIT,"[%s/pinger] Fork: %s", p->base.instance, strerror(errno)); break; case 0: send_arp_reqs(); exit(0); break; default: signal(SIGINT, sig_int); recv_arp_reply(); hoststr = strdup("0"); j = 0; for(i=0; i<nh; i++) if(hosts[i].active) { hoststr = realloc(hoststr, sizeof(char *) * (strlen(hoststr) + strlen(hosts[i].id) + 1)); strcat(hoststr, ","); strcat(hoststr, hosts[i].id); j++; } if(j) { if(p->use_secure_function) // works with postgres only g->db_pexec(g->conn, "SELECT set_lastonline(ARRAY[?])", hoststr); else g->db_pexec(g->conn, "UPDATE nodes SET lastonline=%NOW% WHERE id IN (?)", hoststr); } free(hoststr); break; } #ifdef DEBUG1 syslog(LOG_INFO,"DEBUG: [%s/pinger] reloaded", p->base.instance); #endif // cleanup for(i=0; i<nh; i++) free(hosts[i].id); free(hosts); free(nets); free(p->networks); }