Example #1
0
int main(void)
{
    Dict *dict;
    Octstr *foo, *bar;
    unsigned long i;

    gwlib_init();

    foo = octstr_imm("foo");
    bar = octstr_imm("bar");

    debug("",0,"Dict simple test.");
    dict = dict_create(10, NULL);
    dict_put(dict, foo, bar);
    info(0, "foo gives %s", octstr_get_cstr(dict_get(dict, foo)));
    if (dict_key_count(dict) == 1)
        info(0, "there is but one foo.");
    else
        error(0, "key count is %ld, should be 1.", dict_key_count(dict));
    dict_destroy(dict);

    debug("",0,"Dict extended/huge test.");
    dict = dict_create(HUGE_SIZE, (void (*)(void *))octstr_destroy);
    for (i = 1; i <= HUGE_SIZE; i++) {
        unsigned long val;
        Octstr *okey, *oval;
        uuid_t id;
        char key[UUID_STR_LEN + 1];
        uuid_generate(id);
        uuid_unparse(id, key);
        val = gw_rand();
        okey = octstr_create(key);
        oval = octstr_format("%ld", val);
        dict_put(dict, okey, oval);
    }
    gwthread_sleep(5); /* give hash table some time */
    if (dict_key_count(dict) == HUGE_SIZE)
        info(0, "ok, got %d entries in the dictionary.", HUGE_SIZE);
    else
        error(0, "key count is %ld, should be %d.", dict_key_count(dict), HUGE_SIZE);
    dict_destroy(dict);

    gwlib_shutdown();
    return 0;
}
Example #2
0
static void set_zero(Octstr *ostr)
{
    octstr_set_char(ostr, (1 + (int) (octstr_len(ostr) *gw_rand()/
                                      (RAND_MAX+1.0))), '\0');
}
Example #3
0
static Boxc *route_msg(List *route_info, Msg *msg)
{
    AddrPar *ap;
    Boxc *conn, *best;
    int i, b, len;
    
    ap = gwlist_search(route_info, msg, cmp_route);
    if (ap == NULL) {
	    debug("bb.boxc", 0, "Did not find previous routing info for WDP, "
	    	  "generating new");
route:

	    if (gwlist_len(wapbox_list) == 0)
	        return NULL;

	    gwlist_lock(wapbox_list);

	/* take random wapbox from list, and then check all wapboxes
	 * and select the one with lowest load level - if tied, the first
	 * one
	 */
	    len = gwlist_len(wapbox_list);
	    b = gw_rand() % len;
	    best = gwlist_get(wapbox_list, b);

	    for(i = 0; i < gwlist_len(wapbox_list); i++) {
	        conn = gwlist_get(wapbox_list, (i+b) % len);
	        if (conn != NULL && best != NULL)
		        if (conn->load < best->load)
		            best = conn;
	    }
	    if (best == NULL) {
	        warning(0, "wapbox_list empty!");
	        gwlist_unlock(wapbox_list);
	        return NULL;
	    }
	    conn = best;
	    conn->load++;	/* simulate new client until we get new values */
	
	    ap = gw_malloc(sizeof(AddrPar));
	    ap->address = octstr_duplicate(msg->wdp_datagram.source_address);
	    ap->port = msg->wdp_datagram.source_port;
	    ap->wapboxid = conn->id;
	    gwlist_produce(route_info, ap);

	    gwlist_unlock(wapbox_list);
    } else
	    conn = gwlist_search(wapbox_list, ap, cmp_boxc);

    if (conn == NULL) {
	/* routing failed; wapbox has disappeared!
	 * ..remove routing info and re-route   */

	    debug("bb.boxc", 0, "Old wapbox has disappeared, re-routing");

	    gwlist_delete_equal(route_info, ap);
	    ap_destroy(ap);
	    goto route;
    }
    return conn;
}
Example #4
0
/*
 * Route the incoming message to one of the following input queues:
 *   a specific smsbox conn
 *   a random smsbox conn if no shortcut routing and msg->sms.boxc_id match
 *
 * BEWARE: All logic inside here should be fast, hence speed processing
 * optimized, because every single MO message passes this function and we 
 * have to ensure that no unncessary overhead is done.
 */
int route_incoming_to_boxc(Msg *msg)
{
    Boxc *bc = NULL, *best = NULL;
    Octstr *s, *r, *rs;
    long len, b, i;
    int full_found = 0;

    s = r = NULL;
    gw_assert(msg_type(msg) == sms);

    /* msg_dump(msg, 0); */

    /* 
     * We have a specific route to pass this msg to smsbox-id 
     * Lookup the connection in the dictionary.
     */
    gw_rwlock_rdlock(smsbox_list_rwlock);
    if (gwlist_len(smsbox_list) == 0) {
        gw_rwlock_unlock(smsbox_list_rwlock);
    	warning(0, "smsbox_list empty!");
        if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(incoming_sms)) {
            gwlist_produce(incoming_sms, msg);
	    return 0;
         }
         else
             return -1;
    }

    if (octstr_len(msg->sms.boxc_id) > 0) {
        
        bc = dict_get(smsbox_by_id, msg->sms.boxc_id);
        if (bc == NULL) {
            /*
             * something is wrong, this was the smsbox connection we used
             * for sending, so it seems this smsbox is gone
             */
            warning(0,"Could not route message to smsbox id <%s>, smsbox is gone!",
                    octstr_get_cstr(msg->sms.boxc_id));
        }
    }
    else {
        /*
         * Check if we have a "smsbox-route" for this msg.
         * Where the shortcode route has a higher priority then the smsc-id rule.
         * Highest priority has the combined <shortcode>:<smsc-id> route.
         */
        Octstr *os = octstr_format("%s:%s", 
                                   octstr_get_cstr(msg->sms.receiver),
                                   octstr_get_cstr(msg->sms.smsc_id));
        s = (msg->sms.smsc_id ? dict_get(smsbox_by_smsc, msg->sms.smsc_id) : NULL);
        r = (msg->sms.receiver ? dict_get(smsbox_by_receiver, msg->sms.receiver) : NULL);
        rs = (os ? dict_get(smsbox_by_smsc_receiver, os) : NULL);
        octstr_destroy(os); 
        bc = rs ? dict_get(smsbox_by_id, rs) : 
            (r ? dict_get(smsbox_by_id, r) : (s ? dict_get(smsbox_by_id, s) : NULL));
    }

    /* check if we found our routing */
    if (bc != NULL) {
        if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(bc->incoming)) {
            gwlist_produce(bc->incoming, msg);
            gw_rwlock_unlock(smsbox_list_rwlock);
            return 1; /* we are done */
        }
        else {
            gw_rwlock_unlock(smsbox_list_rwlock);
            return -1;
        }
    }
    else if (s != NULL || r != NULL || octstr_len(msg->sms.boxc_id) > 0) {
        gw_rwlock_unlock(smsbox_list_rwlock);
        /*
         * we have routing defined, but no smsbox connected at the moment.
         * put msg into global incoming queue and wait until smsbox with
         * such boxc_id connected.
         */
        if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(incoming_sms)) {
            gwlist_produce(incoming_sms, msg);
            return 0;
        }
        else
            return -1;
    }

    /*
     * ok, none of the routing things applied previously, so route it to
     * a random smsbox.
     */

    /* take random smsbox from list, and then check all smsboxes
     * and select the one with lowest load level - if tied, the first
     * one
     */
    len = gwlist_len(smsbox_list);
    b = gw_rand() % len;

    for(i = 0; i < gwlist_len(smsbox_list); i++) {
	bc = gwlist_get(smsbox_list, (i+b) % len);

        if (bc->boxc_id != NULL || bc->routable == 0)
            bc = NULL;

        if (bc != NULL && max_incoming_sms_qlength > 0 &&
            gwlist_len(bc->incoming) > max_incoming_sms_qlength) {
            full_found = 1;
            bc = NULL;
        }

        if ((bc != NULL && best != NULL && bc->load < best->load) ||
             (bc != NULL && best == NULL)) {
	    best = bc;
        }
    }

    if (best != NULL) {
        best->load++;
        gwlist_produce(best->incoming, msg);
    }

    gw_rwlock_unlock(smsbox_list_rwlock);

    if (best == NULL && full_found == 0) {
	warning(0, "smsbox_list empty!");
        if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(incoming_sms)) {
            gwlist_produce(incoming_sms, msg);
	    return 0;
         }
         else
             return -1;
    }
    else if (best == NULL && full_found == 1)
        return -1;

    return 1;
}
Example #5
0
void gw_em_listener(void *arg)
{
    fd_set in_pipes;
    int i,j;
    int *job_id;
    int greater, rc, rcm;
    char c;

    char info[GW_EM_MAX_INFO];
    char s_job_id[GW_EM_MAX_JOB_ID];
    char result[GW_EM_MAX_RESULT];
    char action[GW_EM_MAX_ACTION];
    char str[GW_EM_MAX_STRING];

    int fd;
    gw_job_t *job;
    time_t now;

    char contact_file[PATH_MAX];
    FILE *file;

    gw_em_mad_t *em_mad;

    char *ptmp;

    int *fds;
    int num_fds;
    gw_em_mad_t **em_mads;

    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

    fds = (int *) malloc(sizeof(int)*gw_conf.number_of_users*GW_MAX_MADS);

    em_mads = (gw_em_mad_t **) malloc(sizeof(gw_em_mad_t *) *
                                      gw_conf.number_of_users * GW_MAX_MADS);
    while (1)
    {
        greater = gw_user_pool_set_em_pipes(&in_pipes, fds, &num_fds, em_mads, gw_em.um_em_pipe_r);

        rc = select( greater+1, &in_pipes, NULL, NULL, NULL);

        if ( rc <= 0 )
            continue;

        for (i=0; i<num_fds; i++)
        {
            fd = fds[i];

            if ( FD_ISSET(fd, &in_pipes) )
            {
                if ( fd == gw_em.um_em_pipe_r )
                {
                    rc = read(fd, (void *) &c, sizeof(char));
#ifdef GWEMDEBUG
                    gw_log_print("EM",'D',"Updating MAD pipes (action is %c)\n",c);
#endif
                    continue;
                }

#ifdef GWEMDEBUG
                gw_log_print("EM",'D',"Reading from MAD pipe %i.\n",i);
#endif

                j = 0;

                do
                {
                    rc = read(fd, (void *) &c, sizeof(char));
                    str[j++] = c;
                }
                while ((rc > 0) && (c != '\n') && (j < (GW_EM_MAX_STRING-1)));

                str[j] = '\0';

                if (rc <= 0)
                {
                    gw_log_print("EM",'W',"Error reading MAD (%s) message\n",
                                 em_mads[i]->name);

                    rcm = gw_em_mad_reload(em_mads[i]);

                    if ( rcm == 0 )
                    {
                        gw_log_print("EM",'I',"MAD (%s) successfully reloaded\n",
                                     em_mads[i]->name);

                        gw_job_pool_em_recover(em_mads[i], &(gw_em.am));
                    }
                    else
                    {
                        gw_log_print("EM",'E',"Error reloading MAD (%s)\n",
                                     em_mads[i]->name);

                        em_mads[i]->mad_em_pipe = -1;
                    }
                    continue;
                }

                sscanf(str,"%" GW2STR(GW_EM_MAX_ACTION) "s %"
                       GW2STR(GW_EM_MAX_JOB_ID) "s %"
                       GW2STR(GW_EM_MAX_RESULT) "s %"
                       GW2STR(GW_EM_MAX_INFO) "[^\n]",
                       action, s_job_id, result, info);

#ifdef GWEMDEBUG
                gw_log_print("EM",'D',"MAD message received:\"%s %s %s %s\".\n",
                             action, s_job_id, result, info);
#endif
                if (s_job_id[0] == '-')
                    continue;

                job_id = (int *) malloc (sizeof(int));

                *job_id = atoi(s_job_id);

                job = gw_job_pool_get(*job_id, GW_TRUE);

                if (job == NULL)
                {
                    gw_log_print("EM",'W',"MAD message for job %s, but it does not exist: \"%s %s %s %s\".\n",
                                 s_job_id,action, s_job_id, result, info);
                    free(job_id);

                    continue;
                }
                if (job->job_state != GW_JOB_STATE_PRE_WRAPPER
                        && job->job_state != GW_JOB_STATE_WRAPPER
                        && job->job_state != GW_JOB_STATE_MIGR_CANCEL
                        && job->job_state != GW_JOB_STATE_STOP_CANCEL
                        && job->job_state != GW_JOB_STATE_KILL_CANCEL)
                {
                    gw_log_print("EM",'W',"MAD message for job %i but not in an execution state.\n",
                                 *job_id);

                    free(job_id);
                    pthread_mutex_unlock(&(job->mutex));
                    continue;
                }
                else if ( job->em_state == GW_EM_STATE_HARD_KILL )
                {
                    gw_log_print("EM",'W',"MAD message for job %i but it is being killed (hard).\n",
                                 *job_id);

                    free(job_id);
                    pthread_mutex_unlock(&(job->mutex));
                    continue;
                }

                if (strcmp(action, "SUBMIT") == 0)
                {
                    if (strcmp(result, "FAILURE") == 0)
                    {
                        gw_job_print(job, "EM",'E',"Job submission failed: %s\n",
                                     info);
                        gw_log_print("EM",'E',"Submission of job %d failed: %s.\n",
                                     job->id, info);

                        gw_am_trigger(&(gw_em.am), "GW_EM_STATE_FAILED",
                                      (void *) job_id);
                    }
                    else /* Save persistent job contact */
                    {
                        snprintf(contact_file, PATH_MAX-1,
                                 GW_VAR_DIR "/%i/job.contact",
                                 job->id);

                        file = fopen(contact_file, "w");

                        if ( file != NULL )
                        {
                            fprintf(file, "%s\n", info);
                            fclose(file);
                        }

                        gw_am_trigger(&(gw_em.am), "GW_EM_STATE_PENDING",
                                      (void *) job_id);
                    }
                }
                else if (strcmp(action, "CANCEL") == 0)
                {
                    if (strcmp(result, "SUCCESS") == 0)
                    {
                        gw_job_print(job, "EM",'I',"Job cancel succeeded.\n");
                        gw_log_print("EM",'I',"Cancel of job %i succeeded.\n", *job_id);
                    }
                    else
                    {
                        gw_job_print(job, "EM",'E',"Job cancel failed (%s).\n",info);
                        gw_log_print("EM",'E',"Cancel of job %d failed: %s.\n",job->id, info);
                    }
                }
                else if (strcmp(action, "POLL") == 0)
                {
                    if (strcmp(result, "SUCCESS") == 0)
                    {
                        now = time(NULL);
                        job->next_poll_time = now + gw_conf.poll_interval/2
                                              + gw_rand(gw_conf.poll_interval);

                        gw_job_print(job, "EM",'E',"Job poll OK (%s), will poll again in %d seconds.\n",
                                     info, job->next_poll_time - now);

                        if (strcmp(info, "PENDING") == 0)
                            gw_am_trigger(&(gw_em.am), "GW_EM_STATE_PENDING",
                                          (void *) job_id);

                        else if (strcmp(info, "SUSPENDED") == 0)
                            gw_am_trigger(&(gw_em.am), "GW_EM_STATE_SUSPENDED",
                                          (void *) job_id);

                        else if (strcmp(info, "ACTIVE") == 0)
                            gw_am_trigger(&(gw_em.am),"GW_EM_STATE_ACTIVE",
                                          (void *) job_id);

                        else if (strstr(info, "DONE") != NULL)
                        {
                            ptmp = strstr(info,"DONE:");

                            if ((ptmp != NULL) && (strlen(ptmp+5) > 0))/*No-wrapper mode*/
                                job->exit_code=atoi(ptmp+5);

                            gw_am_trigger(&(gw_em.am), "GW_EM_STATE_DONE",
                                          (void *) job_id);
                        }
                        else if (strcmp(info, "FAILED") == 0)
                            gw_am_trigger(&(gw_em.am), "GW_EM_STATE_FAILED",
                                          (void *) job_id);
                    }
                    else
                    {
                        job->history->failed_polls++;

                        em_mad = job->history->em_mad;

                        if ( job->history->failed_polls == 3 )
                        {
                            gw_job_print(job, "EM",'E',"Job poll failed (%s), assuming the job is done.\n",info);

                            gw_am_trigger(&(gw_em.am), "GW_EM_STATE_DONE", (void *) job_id);
                        }
                        else
                        {
                            now = time(NULL);
                            job->next_poll_time = now + gw_conf.poll_interval*job->history->failed_polls
                                                  + gw_rand(gw_conf.poll_interval*job->history->failed_polls);

                            gw_job_print(job, "EM",'E',"Job poll failed (%s), will poll again in %d seconds.\n",
                                         info, job->next_poll_time - now);

                            free(job_id);
                        }
                    }
                }
                else if (strcmp(action, "RECOVER") == 0)
                {
                    if (strcmp(result, "SUCCESS") == 0)
                    {
                        if (strcmp(info, "PENDING") == 0)
                            gw_am_trigger(&(gw_em.am), "GW_EM_STATE_PENDING",
                                          (void *) job_id);
                        else if (strcmp(info, "SUSPENDED") == 0)
                            gw_am_trigger(&(gw_em.am), "GW_EM_STATE_SUSPENDED",
                                          (void *) job_id);
                        else if (strcmp(info, "ACTIVE") == 0)
                            gw_am_trigger(&(gw_em.am),"GW_EM_STATE_ACTIVE",
                                          (void *) job_id);
                        else if (strstr(info, "DONE") != NULL)
                        {
                            ptmp = strstr(info,"DONE:");

                            if ((ptmp != NULL) && (strlen(ptmp+5) > 0))/*No-wrapper mode*/
                                job->exit_code = atoi(ptmp+5);

                            gw_am_trigger(&(gw_em.am), "GW_EM_STATE_DONE",
                                          (void *) job_id);
                        }
                        else if (strcmp(info, "FAILED") == 0)
                        {
                            /* Do not retry */
                            job->history->tries= job->template.number_of_retries;

                            gw_am_trigger(&(gw_em.am), "GW_EM_STATE_FAILED",
                                          (void *) job_id);
                        }
                    }
                    else
                    {
                        gw_job_print(job,"EM",'E',"Job recover failed (%s), assuming the job is done.\n", info);
                        gw_log_print("EM",'E',"Recover of job %i failed.\n", *job_id);

                        gw_am_trigger(&(gw_em.am), "GW_EM_STATE_DONE", (void *) job_id);
                    }
                }
Example #6
0
void gw_em_submit(void *_job_id)
{
    int           job_id;
    gw_job_t      *job;
    char          *rsl=NULL;
    char          *contact;
    gw_job_state_t state;
    char          rsl_filename[2048];
    FILE          *fd;
    time_t        now;
	
    /* ----------------------------------------------------------- */  
    /* 0.- Get job pointer, check if it exits and lock mutex       */
    /* ----------------------------------------------------------- */  

    if ( _job_id != NULL )
    {
        job_id = *( (int *) _job_id );	
        job = gw_job_pool_get(job_id, GW_TRUE);
	
        if ( job == NULL )
        {
            gw_log_print("EM",'E',"Job %s no longer exists (PENDING).\n",
                    job_id);
            return;
        }
    }
    else
        return;

    if (job->history == NULL) 
    {
        gw_log_print("EM",'E',"History of job %s doesn't exists\n",
                job_id);
        free(_job_id);
        pthread_mutex_unlock(&(job->mutex));				
        return;
    }

    state = job->job_state;
	
    /* ----------------------------------------------------------- */  
    /* 1.- Get execution MAD for this host                         */
    /* ----------------------------------------------------------- */  

    job->em_state = GW_EM_STATE_INIT;
    job->history->counter = -1;    

    if ( job->job_state == GW_JOB_STATE_PRE_WRAPPER )
    {
        contact = job->history->em_fork_rc;
        rsl     = (char *) job->history->em_mad->pre_wrapper_rsl((void *) job);    
    }
    else
    {
        contact = job->history->em_rc;
        rsl     = (char *) job->history->em_mad->wrapper_rsl((void *) job);    		
    }
	
    if ( rsl == NULL )
    {
        job->em_state = GW_EM_STATE_FAILED;
        
        gw_log_print("EM",'E',"Job %i failed, could not generate RSL.\n", job_id);        
		gw_am_trigger(gw_em.dm_am, "GW_DM_WRAPPER_FAILED", _job_id);
        
        pthread_mutex_unlock(&(job->mutex));
        
        return;
    }
    
    sprintf(rsl_filename, "%s/job.rsl.%i", job->directory,job->restarted);
    
    fd = fopen(rsl_filename,"w");
    if (fd != NULL )
    {
        gw_job_print(job,"EM",'I',"Submitting wrapper to %s, RSL used is in %s.\n",contact,rsl_filename);
    	fprintf(fd,"%s",rsl);
    	fclose(fd);
    }
    else
    {
        job->em_state = GW_EM_STATE_FAILED;
        
        gw_log_print("EM",'E',"Job %i failed, could not open RSL file.\n", job_id);
        gw_job_print(job,"EM",'E',"Job failed, could not open RSL file %s.\n",rsl_filename);
		
        gw_am_trigger(gw_em.dm_am, "GW_DM_WRAPPER_FAILED", _job_id);
        
        pthread_mutex_unlock(&(job->mutex));
        
        return;    	
    }

    /* -------------------------------------------------------------------- */

    now = time(NULL);

    job->next_poll_time = now + gw_conf.poll_interval/2
            + gw_rand(gw_conf.poll_interval);            /* randomize polls */

    gw_job_print(job,"EM",'I',"Job will be polled in %d seconds.\n",
            job->next_poll_time-now);

    job->last_checkpoint_time = 0;
	
    job->history->stats[LAST_SUSPENSION_TIME] = now;
    job->history->stats[SUSPENSION_TIME]      = 0;
    job->history->stats[ACTIVE_TIME]          = 0;

    job->history->tries++;
        
    /* -------------------------------------------------------------------- */
    
    pthread_mutex_unlock(&(job->mutex));
    
    gw_em_mad_submit(job->history->em_mad, job_id, contact, rsl_filename);

    /* -------------------------------------------------------------------- */
    
    free(_job_id);
    
    free(rsl);
}