Exemple #1
0
int
event_queue_free(struct event_queue *eq)
{
  assert(eq != NULL);

  if(!event_queue_empty(eq))
    return(-1);

  /* 
  if(eq->thread_id)
    pthread_cancel(eq->thread_id);
  */

  pthread_rwlock_destroy(&eq->update_lock);
  pthread_mutex_destroy(&eq->cond_lock);
  pthread_cond_destroy(&eq->ready_cond);
#if defined(INTERLOGD_HANDLE_CMD) && defined(INTERLOGD_FLUSH)
  pthread_cond_destroy(&eq->flush_cond);
#endif

  if(eq->dest_name)
	  free(eq->dest_name);
  if(eq->dest)
	  free(eq->dest);
  if(eq->owner) 
	  free(eq->owner);

  free(eq);

  return(0);
}
Exemple #2
0
/* Send events from the queue. Return 0 on error. */
static int flush_events (struct client *cli)
{
	enum noblock_io_status st = NB_IO_OK;

	LOCK (cli->events_mtx);
	while (!event_queue_empty(&cli->events)
			&& (st = event_send_noblock(cli->socket, &cli->events))
			== NB_IO_OK)
		;
	UNLOCK (cli->events_mtx);

	return st != NB_IO_ERR ? 1 : 0;
}
Exemple #3
0
/* Add clients file descriptors to fds. */
static void add_clients_fds (fd_set *read, fd_set *write)
{
	int i;

	for (i = 0; i < CLIENTS_MAX; i++)
		if (clients[i].socket != -1) {
			if (locking_client() == -1 || is_locking(&clients[i]))
				FD_SET (clients[i].socket, read);

			LOCK (clients[i].events_mtx);
			if (!event_queue_empty(&clients[i].events))
				FD_SET (clients[i].socket, write);
			UNLOCK (clients[i].events_mtx);
		}
}
int
event_queue_send(struct event_queue *eq)
{
	OutputPlugin *output = (OutputPlugin*)eq->plugin_data;
	edg_wll_Context context;
	edg_wll_Event *notif_event;
    edg_wll_JobStat *state_out;
    il_octet_string_t event;
    char *jobstat_char;
	int ret;

	assert(output != NULL);

	edg_wll_InitContext(&context);

	while(!event_queue_empty(eq)) {
	    struct server_msg *msg;
	    cms::TextMessage *cms_msg;
	    char *s;
	    unsigned int i;
	    std::string val;

	    if(event_queue_get(eq, &msg) < 0) {
	    	goto err;
	    }

	    try {
	    	if(decode_il_msg(&event, msg->msg) < 0) {
	    		set_error(IL_LBAPI, EINVAL, "event_queue_send: error parsing notification event data");
	    		goto err;
	    	}
	    	ret=edg_wll_ParseNotifEvent(context, event.data, &notif_event);
	    	if(ret) {
	    		set_error(IL_LBAPI, ret, "event_queue_send: error parsing notification event");
	    		goto err;
	    	}
	        jobstat_char = glite_lbu_UnescapeXML((const char *) notif_event->notification.jobstat);
	        if (jobstat_char == NULL) {
	            set_error(IL_LBAPI, EINVAL, "event_queue_send: error unescaping job status");
	            goto err;
	        }
	        if ( edg_wll_ParseJobStat(context, jobstat_char, strlen(jobstat_char), state_out)) {
	        	set_error(IL_LBAPI, EINVAL, "event_queue_send: error parsing job status");
	        	goto err;
	        }


	    	cms_msg = output->session->createTextMessage();
	    	/* ownerDn */
	    	val.assign(state_out->owner);
	    	cms_msg->setStringProperty("ownerDn", val);
	    	/* voname */
	    	s = edg_wll_JDLField(state_out,"VirtualOrganisation");
	    	val.assign(s);
	    	free(s);
	    	cms_msg->setStringProperty("voname", val);
	    	/* bkHost */
	    	glite_jobid_getServerParts(state_out->jobId, &s, &i);
	    	val.assign(s);
	    	free(s);
	    	cms_msg->setStringProperty("bkHost", val);
	    	/* networkServer */
	    	/* TODO: XXX cut out hostname */
	    	val.assign(state_out->network_server);
	    	cms_msg->setStringProperty("networkHost", val);
	    	timeval2str(&state_out->lastUpdateTime, &s);
	    	val.assign(s);
	    	if(s) free(s);
	    	cms_msg->setStringProperty("lastUpdateTime", val);
	    	/* stateName */
	    	s = edg_wll_StatToString(state_out->state);
	    	val.assign(s);
	    	if(s) free(s);
	    	cms_msg->setStringProperty("stateName", val);
	    	timeval2str(&state_out->stateEnterTime, &s);
	    	val.assign(s);
	    	if(s) free(s);
	    	cms_msg->setStringProperty("stateStartTime", val);
	    	/* condorId */
	    	val.assign(state_out->condorId);
	    	cms_msg->setStringProperty("condorId", val);
	    	/* destSite */
	    	val.assign(state_out->destination);
	    	cms_msg->setStringProperty("destSite", val);
	    	/* exitCode */
	    	cms_msg->setIntProperty("exitCode", state_out->exit_code);
	    	/* doneCode */
	    	cms_msg->setIntProperty("doneCode", state_out->done_code);
	    	/* statusReason */
	    	val.assign(state_out->reason);
	    	cms_msg->setStringProperty("statusReason", val);

	    	free(event.data);
	    	edg_wll_FreeEvent(notif_event);
	    	free(notif_event);
	    	edg_wll_FreeStatus(state_out);
	    	free(state_out);
	    	free(jobstat_char);
	    } catch(cms::CMSException &e) {
	    	goto err;
	    }

	    try {
	    	output->send(cms_msg);
		    delete cms_msg;
	    	if(event_store_commit(msg->es, msg->ev_len, queue_list_is_log(eq), msg->generation) < 0) {
	    		/* failure committing message, this is bad */
	    		goto err;
	    	}
	        event_queue_remove(eq);
	        eq->first_event_sent = 1;
	    } catch(cms::CMSException &e) {
		    delete cms_msg;
	    	output->cleanup();
	    	eq->timeout = TIMEOUT;
	    	edg_wll_FreeContext(context);
	    	return 0;
	    }
	}
	edg_wll_FreeContext(context);
	return 1;

err:
	if(event.data) {
		free(event.data);
	}
	if(notif_event) {
    	edg_wll_FreeEvent(notif_event);
    	free(notif_event);
	}
	if(jobstat_char) {
		free(jobstat_char);
	}
	if(state_out) {
		edg_wll_FreeStatus(state_out);
		free(state_out);
	}
	return -1;
}
int
event_queue_send(struct event_queue *eq, struct queue_thread *me)
{
	OutputPlugin *output = (OutputPlugin*)eq->plugin_data;
	edg_wll_Context context;
	edg_wll_Event *notif_event;
	edg_wll_JobStat state_out;
	il_octet_string_t event;
	char *jobstat_char;
	int ret;

	assert(output != NULL);

	edg_wll_InitContext(&context);

	while(!event_queue_empty(eq)) {
	    struct server_msg *msg;
	    cms::Message *cms_msg = NULL;

	    if(event_queue_get(eq, me, &msg) == 0) {
		    break;
	    }

	    if(0 == msg->len) {
		    glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG,
				     "    not sending empty message at offset %ld for job %s",
				     msg->offset, msg->job_id_s);
		    if(event_store_commit(msg->es, msg->ev_len, 0, msg->generation) < 0) {
			    /* failure committing message, this is bad */
			    goto err;
		    }
		    event_queue_remove(eq, me);
		    continue;
	    }

	    glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, 
			     "    trying to deliver event at offset %ld for job %s",
			     msg->offset, msg->job_id_s);
	    
	    if(decode_il_msg(&event, msg->msg + 17) < 0) {
		    set_error(IL_LBAPI, EINVAL, "event_queue_send: error parsing notification event data");
		    goto err;
	    }
	    ret=edg_wll_ParseNotifEvent(context, event.data, &notif_event);
	    if(ret) {
		    set_error(IL_LBAPI, ret, "event_queue_send: error parsing notification event");
		    goto err;
	    }
	    jobstat_char = glite_lbu_UnescapeXML((const char *) notif_event->notification.jobstat);
	    if (jobstat_char == NULL) {
		    set_error(IL_LBAPI, EINVAL, "event_queue_send: error unescaping job status");
		    goto err;
	    }
	    if ( edg_wll_ParseJobStat(context, jobstat_char, strlen(jobstat_char), &state_out)) {
		    set_error(IL_LBAPI, EINVAL, "event_queue_send: error parsing job status");
		    fprintf(stderr, "Status string: %s\n", jobstat_char);
		    goto err;
	    }
	    
	    try {
		    cms_msg = output->createMessage(state_out);
		    
		    free(event.data); event.data = NULL;
		    edg_wll_FreeEvent(notif_event);
		    free(notif_event); notif_event = NULL;
		    edg_wll_FreeStatus(&state_out);
		    free(jobstat_char); jobstat_char = NULL;
		    
		    output->send(cms_msg); 
		    delete cms_msg;
		    if(event_store_commit(msg->es, msg->ev_len, 0, msg->generation) < 0) {
			    /* failure committing message, this is bad */
			    goto err;
		    }
		    glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, 
				     "    event sent to %s", eq->dest_name);
		    
	    } catch(cms::CMSException &e) {
		    if(cms_msg) {
			    delete cms_msg;
		    }
		    me->timeout = TIMEOUT;
		    edg_wll_FreeContext(context);
		    set_error(IL_DL, 0, e.what());
		    return 0;
	    }
	    event_queue_remove(eq, me);
	    me->first_event_sent = 1;
	    eq->last_sent = time(NULL);
	}
	edg_wll_FreeContext(context);
	return 1;

err:
	if(event.data) {
		free(event.data);
	}
	if(notif_event) {
		edg_wll_FreeEvent(notif_event);
		free(notif_event);
	}
	if(jobstat_char) {
		free(jobstat_char);
	}
	edg_wll_FreeStatus(&state_out);

	return -1;
}
Exemple #6
0
/* 
 * Send all events from the queue.
 *   Returns: -1 - system error, 0 - not send, 1 - queue empty
 */
int 
event_queue_send(struct event_queue *eq, struct queue_thread *me)
{
  assert(eq != NULL);
  assert(me != NULL);

#ifdef LB_PERF
  if(!nosend) {
#endif
  if(me->gss.context == NULL)
    return(0);
#ifdef LB_PERF
  }
#endif

  /* feed the server with events */
  while (!event_queue_empty(eq)) {
    struct server_msg *msg;
    char *rep;
    int  ret, code, code_min;
    size_t bytes_sent;
    struct timeval tv;
    edg_wll_GssStatus gss_stat;

    clear_error();

    if(event_queue_get(eq, me, &msg) == 0) 
      return(1);

    glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, 
		     "    trying to deliver event at offset %ld for job %s", 
		     msg->offset, msg->job_id_s);

#ifdef LB_PERF
    if(!nosend) {
#endif
	if (msg->len) {
	    tv.tv_sec = TIMEOUT;
	    tv.tv_usec = 0;
	    ret = edg_wll_gss_write_full(&me->gss, msg->msg, msg->len, &tv, &bytes_sent, &gss_stat);
	    if(ret < 0) {
	      if (ret == EDG_WLL_GSS_ERROR_ERRNO && errno == EPIPE && me->first_event_sent )
	        me->timeout = 0;
	      else
	        me->timeout = TIMEOUT;
	      server_msg_release(msg);
	      return(0);
	    }
 	    
	    if((code = get_reply(eq, me, &rep, &code_min)) < 0) {
		    /* could not get the reply properly, so try again later */
		    if (me->first_event_sent) {
			/* could be expected server connection preemption */
			clear_error();
			me->timeout = 1;
		    } else {
			me->timeout = TIMEOUT;
		        glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_WARN, "  error reading server %s reply: %s", 
					 eq->dest_name, error_get_msg());
                    }
		    server_msg_release(msg);
		    return(0);
	    }
	}
	else { code = LB_OK; code_min = 0; rep = strdup("not sending empty message"); }
#ifdef LB_PERF
    } else {
	    glite_wll_perftest_consumeEventIlMsg(msg->msg+17);
	    code = LB_OK;
	    rep = strdup("OK");
    }
#endif
    
    glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, 
		     "    event sent, server %s replied with %d, %s", 
		     eq->dest_name, code, rep);
    free(rep);

    /* the reply is back here */
    switch(code) {
      
	    /* NOT USED: case LB_TIME: */
    case LB_NOMEM:
	    /* NOT USED: case LB_SYS:  */
	    /* NOT USED: case LB_AUTH: */
    case LB_DBERR:
	    /* check minor code */
	    if(!(ENOENT == code_min)) {
		    /* non fatal errors (for us) */
		    me->timeout = TIMEOUT;
		    server_msg_release(msg);
		    return(0);
	    }
	
    case LB_OK:
      /* event 'successfully' delivered */
      
    case LB_PERM:
    default: /* LB_PROTO */
      /* the event was not accepted by the server */
      /* update the event pointer */
      if(event_store_commit(msg->es, msg->ev_len, queue_list_is_log(eq), msg->generation) < 0) {
	      /* failure committing message, this is bad */
	      server_msg_release(msg);
	      return(-1);
      }
      /* if we have just delivered priority message from the queue, send confirmation */
      ret = 1;
#if defined(INTERLOGD_EMS)
      if(server_msg_is_priority(msg) &&
	 ((ret=confirm_msg(msg, code, code_min)) < 0))
	return(ret);
#endif

      if((ret == 0) &&
	 (error_get_maj() != IL_OK))
	      glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_ERROR, 
			       "send_event: %s", 
			       error_get_msg());
	
      event_queue_remove(eq, me);
      me->first_event_sent = 1;
      eq->last_sent = time(NULL);
      break;
      
    } /* switch */
  } /* while */

  return(1);

} /* send_events */
Exemple #7
0
uint8_t get_event(void)
{
	return event_queue_empty() ? EV_NONE : event_queue[(event_queue_tail++) & (EVENT_QUEUE_SIZE - 1)];
}
Exemple #8
0
static
int
handle_cmd(il_octet_string_t *event, long offset)
{
	char *job_id_s;
	struct event_queue *eq;
	int  num_replies, num_threads = 0;
	int  timeout, result;
	long receipt;
	struct timespec endtime;
	struct timeval  tv;

	/* parse command */
	if(parse_cmd(event->data, &job_id_s, &receipt, &timeout) < 0)
		return(0);

#if defined(INTERLOGD_FLUSH)
	glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, "received FLUSH command");

	/* catchup with all neccessary event files */
	if(job_id_s) {
		struct event_store *es = event_store_find(job_id_s, NULL);

		if(es == NULL) {
			goto cmd_error;
		}
		result = event_store_recover(es);
		/* NOTE: if flush had been stored in file, there would have been
		   no need to lock the event_store at all */
		event_store_release(es);
		if(result < 0) {
			glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_ERROR, 
					 "  error trying to catch up with event file: %s",
					 error_get_msg());
			clear_error();
		}
	} else
	  /* this call does not fail :-) */
	  event_store_recover_all();

	glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, "  alerting threads to report status");

	/* prevent threads from reporting too early */
	if(pthread_mutex_lock(&flush_lock) < 0) {
		/*** this error is considered too serious to allow the program run anymore!
		     set_error(IL_SYS, errno, "pthread_mutex_lock: error locking flush lock");
		     goto cmd_error;
		*/
		abort();
	}

	/* wake up all threads */
	if(job_id_s) {
		/* find appropriate queue */
		eq = queue_list_get(job_id_s);
		if(eq == NULL) goto cmd_error;
		if(!event_queue_empty(eq) && !queue_list_is_log(eq)) {
			num_threads++;
			event_queue_cond_lock(eq);
			eq->flushing = 1;
			event_queue_wakeup(eq);
			event_queue_cond_unlock(eq);
		}
	} else {
		/* iterate over event queues */
		for(eq=queue_list_first(); eq != NULL; eq=queue_list_next()) {
			if(!event_queue_empty(eq) && !queue_list_is_log(eq)) {
				num_threads++;
				event_queue_cond_lock(eq);
				eq->flushing = 1;
				event_queue_wakeup(eq);
				event_queue_cond_unlock(eq);
			}
		}
	}
	if(!bs_only) {
		eq = queue_list_get(NULL);
		if(eq == NULL) goto cmd_error;
		if(!event_queue_empty(eq)) {
			num_threads++;
			event_queue_cond_lock(eq);
			eq->flushing = 1;
			event_queue_wakeup(eq);
			event_queue_cond_unlock(eq);
		}
	}

	/* wait for thread replies */
	num_replies = 0;
	result = 1;
	gettimeofday(&tv, NULL);
	endtime.tv_sec = tv.tv_sec + timeout;
	endtime.tv_nsec = 1000 * tv.tv_usec;
	while(num_replies < num_threads) {
		int ret;
		if((ret=pthread_cond_timedwait(&flush_cond, &flush_lock, &endtime)) < 0) {
			char buf[256];

			il_strerror_r(errno, buf, sizeof(buf));
			glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_ERROR, 
					 "    error waiting for thread reply: %s", 
					 buf);
			result = (ret == ETIMEDOUT) ? 0 : -1;
			break;
		}

		/* collect results from reporting threads */
		if(job_id_s) {
			/* find appropriate queue */
			eq = queue_list_get(job_id_s);
			if(eq == NULL) goto cmd_error;
			if(!queue_list_is_log(eq)) {
				event_queue_cond_lock(eq);
				if(eq->flushing == 2) {
					eq->flushing = 0;
					num_replies++;
					result = ((result == 1) || (eq->flush_result < 0))  ?
						eq->flush_result : result;
				}
				event_queue_cond_unlock(eq);
			}
		} else {
			/* iterate over event queues */
			for(eq=queue_list_first(); eq != NULL; eq=queue_list_next()) {
				if(!queue_list_is_log(eq)) {
					event_queue_cond_lock(eq);
					if(eq->flushing == 2) {
						eq->flushing = 0;
						num_replies++;
						glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, 
								 "    thread reply: %d", 
								 eq->flush_result);
						result = ((result == 1) || (eq->flush_result < 0))  ?
							eq->flush_result : result;
					}
					event_queue_cond_unlock(eq);
				}
			}
		}
		if(!bs_only) {
			eq = queue_list_get(NULL);
			if(eq == NULL) goto cmd_error;
			event_queue_cond_lock(eq);
			if(eq->flushing == 2) {
				eq->flushing = 0;
				num_replies++;
				result = ((result == 1) || (eq->flush_result < 0))  ?
					eq->flush_result : result;
			}
			event_queue_cond_unlock(eq);
		}
	}

	/* prevent deadlock in next flush */
	if(pthread_mutex_unlock(&flush_lock) < 0)
		abort();


	/* report back to local logger */
	switch(result) {
	case 1:
		result = 0; break;
	case 0:
		result = EDG_WLL_IL_EVENTS_WAITING; break;
	default:
		result = EDG_WLL_IL_SYS; break;
	}
	if(job_id_s) free(job_id_s);
	result = send_confirmation(receipt, result);
	if(result <= 0)
		glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_ERROR, 
				 "handle_cmd: error sending status: %s", 
				 error_get_msg());
	return(1);


cmd_error:
	if(job_id_s) free(job_id_s);
	return(-1);
#else
	return(0);
#endif /* INTERLOGD_FLUSH */
}