示例#1
0
void *
globus_fifo_dequeue(    
    globus_fifo_t *                                 fifo)
{
    void *                                          datum;
    struct globus_fifo_s *                          s_fifo;
    
    assert(fifo != GLOBUS_NULL);
    s_fifo = *fifo;
    assert(s_fifo != GLOBUS_NULL);

    if(globus_list_empty(s_fifo->head)) 
		return GLOBUS_NULL;

    datum = globus_list_remove ((globus_list_t **) &(s_fifo->head), 
			      (globus_list_t *) s_fifo->head);

    if(globus_list_empty (s_fifo->head)) 
    {
        s_fifo->tail = s_fifo->head;
    }

	s_fifo->size--;
  
	return datum;
}
示例#2
0
void
globus_i_module_dump(
    FILE *				out_f)
{
    globus_list_t *			module_list;

    globus_libc_fprintf(out_f, "==========\nModule List\n----------\n");
    
    module_list = globus_l_module_list;
    while(!globus_list_empty(module_list))
    {
	globus_list_t *			client_list;
	globus_l_module_entry_t *	module_entry;

	module_entry = globus_list_first(module_list);
	module_list = globus_list_rest(module_list);

	globus_libc_fprintf(out_f, "%s; cnt=%d",
		module_entry->descriptor->module_name,
		module_entry->reference_count);

	client_list = module_entry->clients;

	if (!globus_list_empty(client_list))
	{
	    void *			client_entry;
	    globus_l_module_entry_t *	client_module_entry;
	    
	    client_entry = globus_list_first(client_list);
	    client_list = globus_list_rest(client_list);
	    client_module_entry =
		globus_hashtable_lookup(&globus_l_module_table, client_entry);
	    globus_libc_fprintf(out_f, "; clients=%s",
		    client_module_entry->descriptor->module_name);
	    
	    while(!globus_list_empty(client_list))
	    {
		client_entry = globus_list_first(client_list);
		client_list = globus_list_rest(client_list);
		client_module_entry =
		    globus_hashtable_lookup(&globus_l_module_table,
					    client_entry);
		globus_libc_fprintf(out_f, ",%s",
			client_module_entry->descriptor->module_name);
	    }
	}

	globus_libc_fprintf(out_f, "\n");
    }

    globus_libc_fprintf(out_f, "==========\n");
}
static
void
globus_l_gss_free_test_cases()
{
    compare_name_test_case_t            *test_case, *tmp_case;
    gss_name_t                          name1, name2;
    globus_list_t *                     tmp;
    OM_uint32                           minor_status;

    while (!globus_list_empty(test_cases))
    {
        test_case = globus_list_first(test_cases);
        free(test_case->test_name);
        name1 = test_case->name1;
        name2 = test_case->name2;

        for (tmp = test_cases;
             !globus_list_empty(tmp);
             tmp = globus_list_rest(tmp))
        {
            tmp_case = globus_list_first(tmp);

            if (name1 == tmp_case->name1 ||
                name2 == tmp_case->name1)
            {
                tmp_case->name1 = NULL;
            }
            if (name1 == tmp_case->name2 ||
                name2 == tmp_case->name2)
            {
                tmp_case->name2 = NULL;
            }
        }
        gss_release_name(&minor_status, &name1);
        if (name1 != name2)
        {
            gss_release_name(&minor_status, &name2);
        }
        if (test_case->name_token1)
        {
            free(test_case->name_token1);
        }
        if (test_case->name_token2)
        {
            free(test_case->name_token2);
        }
        free(test_case);
        globus_list_remove(&test_cases, test_cases);
    }
}
示例#4
0
static bool
rsl_to_classad(globus_rsl_t * rsl, classad::ClassAd &ad)
{
    if (g_globus_activated)
    {
        globus_module_activate(GLOBUS_RSL_MODULE);
        g_globus_activated = true;
    }
    if (!rsl) { return true; }
    if (!globus_rsl_is_boolean(rsl)) { return false; }

    globus_list_t * ops = globus_rsl_boolean_get_operand_list(rsl);
    while (!globus_list_empty(ops))
    {
        globus_rsl_t *op_rsl = static_cast<globus_rsl_t*>(globus_list_first(ops));
        ops = globus_list_rest(ops);
        if (!op_rsl) { continue; }

        if (globus_rsl_is_relation(op_rsl))
        {
            char * attr = globus_rsl_relation_get_attribute(op_rsl);
            globus_rsl_value_t * value = globus_rsl_relation_get_value_sequence(op_rsl);
            if (!attr || !value) { continue; }
            globus_rsl_value_t * single_value = globus_rsl_relation_get_single_value(op_rsl);
            if (single_value) { value = single_value; }

            classad::ExprTree *expr = NULL;

            if (!value_to_expr(value, expr) || !expr) { continue; }

            ad.Insert(attr, expr);
        }
    }
    return true;
}
示例#5
0
globus_result_t
globus_xio_driver_safe_table_from_string(
    char *                              driver_string,
    globus_hashtable_t *                safe_table)
{
    globus_result_t                     result;
    globus_xio_driver_list_ent_t *      d_ent;
    globus_list_t *                     driver_list = NULL;

    /* take advantage of xio function to load drivers */

    result = globus_xio_driver_list_from_string(
        driver_string, &driver_list, NULL);
    if(result != GLOBUS_SUCCESS)
    {
        goto error;
    }

    while(!globus_list_empty(driver_list))
    {
        d_ent = (globus_xio_driver_list_ent_t *)
            globus_list_remove(&driver_list, driver_list);

        globus_hashtable_insert(safe_table, d_ent->driver_name, d_ent);
    }

    return GLOBUS_SUCCESS;

error:

    return result;
}
示例#6
0
globus_result_t
globus_xio_driver_list_to_stack_attr(
    globus_list_t *                     driver_list,
    globus_xio_stack_t                  stack,
    globus_xio_attr_t                   attr)
{
    globus_xio_driver_list_ent_t *      ent; 
    globus_list_t *                     list;

    for(list = driver_list;
        !globus_list_empty(list);
        list = globus_list_rest(list))
    {
        ent = (globus_xio_driver_list_ent_t *) globus_list_first(list);

        globus_xio_stack_push_driver(stack, ent->driver);

        if(ent->opts != NULL)
        {
            /* ignore error */
            globus_xio_attr_cntl(
                attr,
                ent->driver,
                GLOBUS_XIO_SET_STRING_OPTIONS,
                ent->opts);
        }
    }

    return GLOBUS_SUCCESS;
}
示例#7
0
void
globus_xio_driver_list_destroy(
    globus_list_t *                     driver_list,
    globus_bool_t                       unload)
{
    globus_xio_driver_list_ent_t *      ent;
    globus_list_t *                     list;

    for(list = driver_list;
        !globus_list_empty(list);
        list = globus_list_rest(list))
    {
        ent = (globus_xio_driver_list_ent_t *) globus_list_first(list);

        if(ent->driver_name != NULL)
        {
            globus_free(ent->driver_name);
        }
        if(ent->opts != NULL)
        {
            globus_free(ent->opts);
        }
        if(unload)
        {
            globus_xio_driver_unload(ent->driver);
        }
        globus_free(ent);
    }
}
示例#8
0
globus_fifo_t *
globus_fifo_copy (
    const globus_fifo_t *                                 fifo)
{
    globus_fifo_t *                                 copy;
    struct globus_fifo_s *                          s_copy;
    struct globus_fifo_s *                          s_fifo;

    if (fifo == GLOBUS_NULL) 
		return NULL;
    s_fifo = *fifo;
    if(s_fifo==GLOBUS_NULL) 
		return NULL;

    copy = globus_malloc (sizeof(globus_fifo_t));
    if (copy == NULL) 
		return NULL;

    globus_fifo_init(copy);

    s_copy = *copy;
    s_copy->head = globus_list_copy(s_fifo->head);
    s_copy->tail = s_copy->head;

    while(!globus_list_empty(globus_list_rest(s_copy->tail))) 
    {
        s_copy->tail = globus_list_rest (s_copy->tail);
    }
 
	s_copy->size = s_fifo->size;
	return copy;
}
示例#9
0
/*
 * globus_module_deactivate_all()
 */
int
globus_module_deactivate_all(void)
{
    /*
     * If module activation hasn't been initialized then return an error
     */
    if (!globus_i_module_initialized)
    {
	return GLOBUS_FAILURE;
    }
    
    globus_l_module_mutex_lock(&globus_l_module_mutex);
    {
	globus_bool_t			 deactivated_one;

	deactivated_one = GLOBUS_TRUE;

	while(deactivated_one)
	{
	    globus_list_t *		module_list;

	    module_list = globus_l_module_list;
	    deactivated_one = GLOBUS_FALSE;

	    while(!globus_list_empty(module_list))
	    {
		globus_l_module_entry_t *module_entry;

		module_entry = globus_list_first(module_list);
		module_list = globus_list_rest(module_list);
	    
		if(globus_list_empty(module_entry->clients) &&
		   module_entry->reference_count > 0)
		{
		    globus_l_module_mutex_unlock(&globus_l_module_mutex);
		    globus_module_deactivate(module_entry->descriptor);
		    globus_l_module_mutex_lock(&globus_l_module_mutex);
		    deactivated_one = GLOBUS_TRUE;
		}
	    }
	}
    }
    globus_l_module_mutex_unlock(&globus_l_module_mutex);

    return GLOBUS_SUCCESS;
}
示例#10
0
void *
globus_fifo_remove(
    globus_fifo_t *                                 fifo, 
    void *                                          datum)
{
    globus_list_t *                                 iter_prev;
    globus_list_t *                                 iter;
    struct globus_fifo_s *                          s_fifo;
    
    assert(fifo != GLOBUS_NULL);
    s_fifo = *fifo;
    assert(s_fifo != GLOBUS_NULL);

    if(globus_list_empty(s_fifo->head)) 
		return GLOBUS_NULL;

    iter_prev = GLOBUS_NULL;
    iter = s_fifo->head;
    while((!globus_list_empty(iter))
	  && (globus_list_first(iter) != datum)) 
	{
        iter_prev = iter;
        iter = globus_list_rest(iter);
    }

    if(!globus_list_empty(iter)) 
    {
        /* iter is the element to remove, iter_prev is the previous */
        if(iter == s_fifo->tail) 
        {
            /* make sure tail doesn't dangle */
            s_fifo->tail = iter_prev;
        }
        globus_list_remove (&(s_fifo->head), iter);

		s_fifo->size--;
        return datum;
    }
    else
    {
        return GLOBUS_NULL;
    }
}
示例#11
0
void *
globus_fifo_tail_peek(
    globus_fifo_t *                                 fifo)
{
    struct globus_fifo_s *                          s_fifo;
    
    assert(fifo != GLOBUS_NULL);
    s_fifo = *fifo;
    assert(s_fifo != GLOBUS_NULL);
    assert(!globus_list_empty(s_fifo->tail));

    return globus_list_first(s_fifo->tail);
}
示例#12
0
/**
 * @brief Call Context Post Close
 * @ingroup globus_net_manager_context
 * @details
 * Call the chain of post_close() functions in a context with the given
 * task_id, transport, contact information, and attributes. If any manager in
 * the context returns an error, the subsequent managers will not be called.
 *
 * @param [in] context
 *     The context to call functions in.
 * @param [in] task_id
 *     The task_id associated with this network operation.
 * @param [in] transport
 *     The transport driver associated with this network operation.
 * @param [in] local_contact
 *     The string representation of the local address of the socket.
 * @param [in] remote_contact
 *     The string representation of the remote address of the socket
 * @param [in] attr_array
 *     The set of attributes to pass to the managers.
 *
 * @return
 *     On success, this function returns GLOBUS_SUCCESS. If any manager
 *     returns an error, the post_close calls stop and the error is returned
 *     to the caller.
 */
globus_result_t
globus_net_manager_context_post_close(
    globus_net_manager_context_t        context,
    const char                         *task_id,
    const char                         *transport,
    const char                         *local_contact,
    const char                         *remote_contact,
    const globus_net_manager_attr_t    *attr_array)
{
    globus_i_net_manager_context_t *    ctx = context;
    globus_list_t *                     list;
    globus_result_t                     result = GLOBUS_SUCCESS;
    globus_i_net_manager_context_entry_t * ent;

    if(!ctx || !task_id || !transport || !attr_array ||
        !local_contact || !remote_contact)
    {
        result = GlobusNetManagerErrorParameter("No parameter may be NULL.");
        goto error_bad_args;
    }

    for(list = ctx->managers; 
        !globus_list_empty(list) && result == GLOBUS_SUCCESS; 
        list = globus_list_rest(list))
    {            
        ent = globus_list_first(list);
        
        if(ent->manager->post_close)
        {
            result = ent->manager->post_close(
                ent->manager,
                ent->attrs,
                task_id,
                transport,
                local_contact,
                remote_contact,
                attr_array);
            if(result != GLOBUS_SUCCESS)
            {
                result = GlobusNetManagerErrorManager(
                    result, ent->manager->name, "post_close");
            }                
        }
    }
    
    return result;

error_bad_args:
    return result;
}
static
void
globus_l_gram_staging_list_free(
    globus_list_t **                    staging_list)
{
    globus_gram_job_manager_staging_info_t *
                                        info;
    while (!globus_list_empty(*staging_list))
    {
        info = globus_list_remove(staging_list, *staging_list);
        globus_rsl_value_free_recursive(info->from);
        globus_rsl_value_free_recursive(info->to);
        free(info->evaled_from);
        free(info->evaled_to);
        free(info);
    }
}
示例#14
0
globus_result_t
globus_xio_string_cntl_string_list(
    void *                              attr,
    const char *                        key,
    const char *                        val,
    int                                 cmd,
    globus_xio_driver_attr_cntl_t       cntl_func)
{
    int                                 i = 0;
    globus_list_t *                     val_list;
    globus_list_t *                     list;
    char **                             argv;
    int                                 argc;
    globus_result_t                     result;
    int                                 del;

    /* delimitor is the first character */
    if(val == NULL)
    {
        return GLOBUS_SUCCESS;
    }

    del = (int)*val;
    val++;

    val_list = globus_list_from_string(val, del, NULL);
    list = val_list;

    argc = globus_list_size(list);
    argv = (char **) calloc(argc+1, sizeof(char *));
    i = argc - 1;
    while(!globus_list_empty(list))
    {
        argv[i] = (char *)globus_list_first(list);
        list = globus_list_rest(list);
        i--;
    }

    result = globus_xio_string_cntl_bouncer(cntl_func, attr, cmd, argv);

    globus_list_destroy_all(val_list, globus_libc_free);
    globus_free(argv);
    
    return result;
}
示例#15
0
void
globus_args_option_instance_list_free( globus_list_t **  list )
{
    globus_args_option_instance_t  *   t;
    
    while(!globus_list_empty(*list))
    {
        t = (globus_args_option_instance_t *)
            globus_list_remove(list, *list);
	globus_assert(t);
	if (t->values)
	    free( t->values );
	globus_free(t);
        
    }
    
    return;
}
void
globus_i_gass_transfer_keyvalue_destroy(
    globus_list_t **				list)
{
    globus_list_t *				tmp;
    globus_gass_transfer_keyvalue_t *		kv;

    tmp = *list;

    while(!globus_list_empty(tmp))
    {
	kv = globus_list_remove(list,
				tmp);
	tmp = *list;
	globus_free(kv->key);
	globus_free(kv->value);
	globus_free(kv);
    }
}
int
globus_gram_job_manager_validation_destroy(
    globus_list_t *                     validation_records)
{
    globus_list_t *                     tmp;
    globus_rvf_record_t *               record;

    tmp = validation_records;

    while (!globus_list_empty(tmp))
    {
        record = globus_list_first(tmp);
        tmp = globus_list_rest(tmp);

        globus_l_gram_job_manager_validation_record_free(record);
    }
    globus_list_free(validation_records);

    return GLOBUS_SUCCESS;
}
示例#18
0
void
globus_usage_stats_handle_destroy(
    globus_usage_stats_handle_t         vhandle)
{
#ifndef TARGET_ARCH_ARM
    globus_i_usage_stats_handle_t *     handle =
    (globus_i_usage_stats_handle_t *) vhandle;

    if(handle)
    {
        if(handle->targets)
        {
            globus_list_destroy_all(handle->targets, globus_libc_free);
        }
    
        if(handle->xio_desc_list)
        {
            globus_xio_data_descriptor_t *  dd;
            
            while (!globus_list_empty (handle->xio_desc_list)) 
            {
                if((dd = globus_list_remove(
                    &handle->xio_desc_list, handle->xio_desc_list)) != NULL)
                {
                    globus_xio_data_descriptor_destroy(*dd);
                    globus_free(dd);
                }
            }
        }
        if(handle->xio_handle)
        {
            globus_xio_close(handle->xio_handle, NULL);
        }
        
        globus_mutex_destroy(&handle->mutex);

        globus_free(handle);
    }
#endif
}
示例#19
0
void
globus_module_print_activated_versions(
    FILE *                              stream,
    globus_bool_t                       verbose)
{
    /*
     * If module activation hasn't been initialized then there are no
     * activated modules
     */
    if(!globus_i_module_initialized)
    {
        return;
    }
    
    globus_l_module_mutex_lock(&globus_l_module_mutex);
    {
        globus_list_t *		        module_list;
        
        module_list = globus_l_module_list;
        while(!globus_list_empty(module_list))
        {
            globus_l_module_entry_t *       module_entry;
    
            module_entry = globus_list_first(module_list);
            module_list = globus_list_rest(module_list);
            
            if(module_entry->reference_count > 0)
            {
                globus_version_print(
                    module_entry->descriptor->module_name,
                    module_entry->descriptor->version,
                    stream,
                    verbose);
            }
        }
    }
    globus_l_module_mutex_unlock(&globus_l_module_mutex);

    return;
}
示例#20
0
globus_xio_driver_list_ent_t *
globus_xio_driver_list_find_driver(
    globus_list_t *                     driver_list,
    const char *                        driver_name)
{
    globus_xio_driver_list_ent_t *      ent;
    globus_list_t *                     list;


    for(list = driver_list;
        !globus_list_empty(list);
        list = globus_list_rest(list))
    {
        ent = (globus_xio_driver_list_ent_t *) globus_list_first(list);

        if(strcmp(ent->driver_name, driver_name) == 0)
        {
            return ent;
        }
    }

    return NULL;
}
/**
 * Check that a relation for a required RSL attribute is present.
 *
 * @param attributes
 *        List of relations which are part of the job request's
 *        RSL.
 * @param attribute_name
 *        The name of the attribute to search for.
 */
static
globus_bool_t
globus_l_gram_job_manager_attribute_exists(
    globus_list_t *                        attributes,
    char *                                attribute_name)
{
    char *                                tmp;
    globus_rsl_t *                        relation;

    while(!globus_list_empty(attributes))
    {
        relation = globus_list_first(attributes);
        attributes = globus_list_rest(attributes);
        tmp = globus_rsl_relation_get_attribute(relation);

        if(globus_l_gram_job_manager_validation_string_match(
                    tmp,
                    attribute_name))
        {
            return GLOBUS_TRUE;
        }
    }
    return GLOBUS_FALSE;
}
globus_result_t
globus_net_manager_context_post_listen(
    globus_net_manager_context_t        context,
    const char                         *task_id,
    const char                         *transport,
    const char                         *local_contact,
    const globus_net_manager_attr_t    *attr_array,
    char                              **local_contact_out,
    globus_net_manager_attr_t         **attr_array_out)
{
    globus_i_net_manager_context_t *    ctx = context;
    globus_list_t *                     list;
    globus_result_t                     result = GLOBUS_SUCCESS;
    globus_net_manager_attr_t *         tmp_attr_array = NULL;
    char *                              tmp_local_contact = NULL;
    globus_i_net_manager_context_entry_t * ent;
    GlobusNetManagerName(globus_net_manager_context_post_listen);
    
    if(!ctx || !task_id || !transport || !attr_array || !attr_array_out ||
        !local_contact || !local_contact_out)
    {
        result = GlobusNetManagerErrorParameter("No parameter may be NULL.");
        goto error_bad_args;
    }
    
    for(list = ctx->managers; 
        !globus_list_empty(list) && result == GLOBUS_SUCCESS; 
        list = globus_list_rest(list))
    {            
        ent = globus_list_first(list);
        
        if(ent->manager->post_listen)
        {   
            globus_net_manager_attr_t *     ret_attr_array = NULL;
            char *                          ret_local_contact = NULL;
            
            result = ent->manager->post_listen(
                ent->manager,
                ent->attrs,
                task_id,
                transport,
                tmp_local_contact ? tmp_local_contact : local_contact,
                tmp_attr_array ? tmp_attr_array : attr_array,
                &ret_local_contact,
                &ret_attr_array);
            if(result != GLOBUS_SUCCESS)
            {
                result = GlobusNetManagerErrorManager(
                    result, ent->manager->name, "post_listen");
            }
                
            if(ret_attr_array != NULL)
            {
                globus_net_manager_attr_array_delete(tmp_attr_array);
                tmp_attr_array = ret_attr_array;
            }
            if(ret_local_contact != NULL)
            {
                if(tmp_local_contact)
                {
                    globus_free(tmp_local_contact);
                }
                tmp_local_contact = ret_local_contact;
            }
        }
    }
    
    *attr_array_out = tmp_attr_array;
    *local_contact_out = tmp_local_contact;

    return result;

error_bad_args:
    return result;
}
示例#23
0
int
main(
    int                                 argc,
    char **                             argv)
{
    int                                 rc;
    globus_gram_job_manager_config_t    config;
    globus_gram_job_manager_t           manager;
    char *                              sleeptime_str;
    long                                sleeptime = 0;
    globus_bool_t                       debug_mode_service = GLOBUS_FALSE;
    globus_bool_t                       located_active_jm = GLOBUS_FALSE;
    int                                 http_body_fd = -1;
    int                                 context_fd = -1;
    gss_cred_id_t                       cred = GSS_C_NO_CREDENTIAL;
    OM_uint32                           major_status, minor_status;
    pid_t                               forked_starter = 0;
    globus_bool_t                       cgi_invoked = GLOBUS_FALSE;
    int                                 lock_tries_left = 10;

    if ((sleeptime_str = getenv("GLOBUS_JOB_MANAGER_SLEEP")))
    {
        sleeptime = atoi(sleeptime_str);
        sleep(sleeptime);
    }
    if (getenv("GATEWAY_INTERFACE"))
    {
        cgi_invoked = GLOBUS_TRUE;
    }
    /*
     * Stdin and stdout point at socket to client
     * Make sure no buffering.
     * stderr may also, depending on the option in the grid-services
     */
    setbuf(stdout,NULL);
    /* Don't export these to the perl scripts */
    fcntl(STDIN_FILENO, F_SETFD, (int) 1);
    fcntl(STDOUT_FILENO, F_SETFD, (int) 1);
    fcntl(STDERR_FILENO, F_SETFD, (int) 1);

    /*
     * At least have minimal POSIX path for job environment via extra
     * environment values
     */
    if(getenv("PATH") == NULL)
    {
        char * path;
        char default_path[] = "/usr/bin:/bin";
        size_t pathlen;

        pathlen = confstr(_CS_PATH, NULL, (size_t) 0);

        if (pathlen < sizeof(default_path))
        {
            pathlen = sizeof(default_path);
        }
        path = malloc(pathlen);
        path[0] = 0;

        (void) confstr(_CS_PATH, path, pathlen);
        if (path[0] == 0)
        {
            strncpy(path, default_path, pathlen);
        }
        setenv("PATH", path, 1);
    }

    /* Force non-threaded execution for now */
    globus_thread_set_model(GLOBUS_THREAD_MODEL_NONE);

    /* Activate a common before parsing command-line so that
     * things work. Note that we can't activate everything yet because we might
     * set the GLOBUS_TCP_PORT_RANGE after parsing command-line args and we
     * need that set before activating XIO.
     */
    rc = globus_module_activate(GLOBUS_COMMON_MODULE);
    if (rc != GLOBUS_SUCCESS)
    {
        fprintf(stderr, "Error activating GLOBUS_COMMON_MODULE\n");
        exit(1);
    }

    /* Parse command line options to get jobmanager configuration */
    rc = globus_gram_job_manager_config_init(&config, argc, argv);
    if (rc != GLOBUS_SUCCESS)
    {
        reply_and_exit(NULL, rc, NULL);
    }

    globus_thread_key_create(
            &globus_i_gram_request_key,
            NULL);

    rc = globus_gram_job_manager_logging_init(&config);
    if (rc != GLOBUS_SUCCESS)
    {
        exit(1);
    }
    if (getenv("GRID_SECURITY_HTTP_BODY_FD") == NULL && !cgi_invoked)
    {
        debug_mode_service = GLOBUS_TRUE;
    }
    /* Set environment variables from configuration */
    if(config.globus_location != NULL)
    {
        globus_libc_setenv("GLOBUS_LOCATION",
                           config.globus_location,
                           GLOBUS_TRUE);
    }
    if(config.tcp_port_range != NULL)
    {
        globus_libc_setenv("GLOBUS_TCP_PORT_RANGE",
                           config.tcp_port_range,
                           GLOBUS_TRUE);
    }
    if(config.tcp_source_range != NULL)
    {
        globus_libc_setenv("GLOBUS_TCP_SOURCE_RANGE",
                           config.tcp_source_range,
                           GLOBUS_TRUE);
    }

    /* Activate all of the modules we will be using */
    rc = globus_l_gram_job_manager_activate();
    if(rc != GLOBUS_SUCCESS)
    {
        exit(1);
    }

    /*
     * Get the delegated credential (or the default credential if we are
     * run without a client. Don't care about errors in the latter case.
     */
    major_status = globus_gss_assist_acquire_cred(
            &minor_status,
            GSS_C_BOTH,
            &cred);
    if ((!debug_mode_service) && GSS_ERROR(major_status))
    {
        globus_gss_assist_display_status(
                stderr,
                "Error acquiring security credential\n",
                major_status,
                minor_status,
                0);
        exit(1);
    }

    if (cred != GSS_C_NO_CREDENTIAL)
    {
        unsigned long hash;
        char * newtag;

        rc = globus_gram_gsi_get_dn_hash(
                cred,
                &hash);
        if (rc == GLOBUS_SUCCESS)
        {
            newtag = globus_common_create_string("%s%s%lx",
                    strcmp(config.service_tag, "untagged") == 0
                            ? "" : config.service_tag,
                    strcmp(config.service_tag, "untagged") == 0
                            ? "" : ".",
                    hash);
            free(config.service_tag);
            config.service_tag = newtag;
        }
    }

    /*
     * Remove delegated proxy from disk.
     */
    if ((!debug_mode_service) && getenv("X509_USER_PROXY") != NULL)
    {
        remove(getenv("X509_USER_PROXY"));
        unsetenv("X509_USER_PROXY");
    }

    /* Set up LRM-specific state based on our configuration. This will create
     * the job contact listener, start the SEG if needed, and open the log
     * file if needed.
     */
    rc = globus_gram_job_manager_init(&manager, cred, &config);
    if(rc != GLOBUS_SUCCESS)
    {
        reply_and_exit(NULL, rc, manager.gt3_failure_message);
    }

    /*
     * Pull out file descriptor numbers for security context and job request
     * from the environment (set by the gatekeeper)
     */
    if (cgi_invoked)
    {
        http_body_fd = 0;
        context_fd = -1;
    }
    else if (!debug_mode_service)
    {
        char * fd_env = getenv("GRID_SECURITY_HTTP_BODY_FD");

        rc = sscanf(fd_env ? fd_env : "-1", "%d", &http_body_fd);
        if (rc != 1 || http_body_fd < 0)
        {
            fprintf(stderr, "Error locating http body fd\n");
            exit(1);
        }
        fcntl(http_body_fd, F_SETFD, 1);

        fd_env = getenv("GRID_SECURITY_CONTEXT_FD");
        rc = sscanf(fd_env ? fd_env : "-1", "%d", &context_fd);
        if (rc != 1 || context_fd < 0)
        {
            fprintf(stderr, "Error locating security context fd\n");
            exit(1);
        }
        fcntl(context_fd, F_SETFD, 1);
    }


    /* Redirect stdin from /dev/null, we'll handle stdout after the reply is
     * sent
     */
    if (!cgi_invoked)
    {
        freopen("/dev/null", "r", stdin);
    }

    /* Here we'll either become the active job manager to process all
     * jobs for this user/host/lrm combination, or we'll hand off the
     * file descriptors containing the info to the active job manager
     */
    while (!located_active_jm)
    {
        /* We'll try to get the lock file associated with being the
         * active job manager here. If we get the OLD_JM_ALIVE error
         * somebody else has it
         */
        rc = globus_gram_job_manager_startup_lock(
                &manager,
                &manager.lock_fd);
        if (rc == GLOBUS_SUCCESS)
        {
            /* We've acquired the lock. We will fork a new process to act like
             * all other job managers which don't have the lock, and continue
             * on in this process managing jobs for this LRM.  Note that the
             * child process does not inherit the lock
             */
            if (!debug_mode_service)
            {
                int save_errno = 0;

                /* We've acquired the manager lock */
                forked_starter = fork();
                save_errno = errno;

                if (forked_starter < 0)
                {
                    if (sleeptime != 0)
                    {
                        sleep(sleeptime);
                    }

                    fprintf(stderr, "fork failed: %s", strerror(save_errno));
                    exit(1);
                }
                else if (forked_starter == 0)
                {
                    /* We are the child process. We'll close our reference to
                     * the lock and let the other process deal with jobs
                     */
                    close(manager.lock_fd);
                    manager.lock_fd = -1;
                }
                globus_logging_update_pid();
                if (sleeptime != 0)
                {
                    sleep(sleeptime);
                }

            }

            if (manager.lock_fd >= 0)
            {
                /* We hold the manager lock, so we'll store our credential, and
                 * then, try to accept socket connections. If the socket
                 * connections fail, we'll exit, and another process
                 * will be forked to handle them.
                 */
                rc = globus_gram_job_manager_gsi_write_credential(
                        NULL,
                        cred,
                        manager.cred_path);

                if (rc != GLOBUS_SUCCESS)
                {
                    fprintf(stderr, "write cred failed\n");
                    exit(1);
                }
                if (!debug_mode_service)
                {
                    close(http_body_fd);
                    http_body_fd = -1;
                }

                rc = globus_gram_job_manager_startup_socket_init(
                        &manager,
                        &manager.active_job_manager_handle,
                        &manager.socket_fd);
                if (rc != GLOBUS_SUCCESS)
                {
                    /* This releases our lock. Either the child process will
                     * attempt to acquire the lock again or some another job
                     * manager will acquire the lock
                     */
                    exit(0);
                }
                assert(manager.socket_fd != -1);
            }
        }
        else if (rc != GLOBUS_GRAM_PROTOCOL_ERROR_OLD_JM_ALIVE)
        {
            /* Some system error. Try again */
            if (--lock_tries_left == 0)
            {
                reply_and_exit(NULL, rc, "Unable to create lock file");
            }
            sleep(1);
            continue;
        }

        /* If manager.socket_fd != -1 then we are the main job manager for this
         * LRM.
         * We will restart all existing jobs and then allow the startup
         * socket to accept new jobs from other job managers.
         */
        if (manager.socket_fd != -1)
        {
            /* Look up cputype/manufacturer if not known yet */
            globus_l_gram_cputype_and_manufacturer(manager.config);

            GlobusTimeAbstimeGetCurrent(manager.usagetracker->jm_start_time);            
            globus_i_gram_usage_stats_init(&manager);
            globus_i_gram_usage_start_session_stats(&manager);

            located_active_jm = GLOBUS_TRUE;

            /* Load existing jobs. The show must go on if this fails, unless it
             * fails with a misconfiguration error
             */
            rc = globus_gram_job_manager_request_load_all(
                    &manager);
            if (rc == GLOBUS_GRAM_PROTOCOL_ERROR_GATEKEEPER_MISCONFIGURED)
            {
                if (forked_starter > 0)
                {
                    kill(forked_starter, SIGTERM);
                    forked_starter = 0;
                }
                reply_and_exit(NULL, rc, manager.gt3_failure_message);
            }
            if (context_fd != -1)
            {
                close(context_fd);
                context_fd = -1;
            }
            freopen("/dev/null", "a", stdout);

            /* At this point, seg_last_timestamp is the earliest last timestamp 
             * for any pre-existing jobs. If that is 0, then we don't have any
             * existing jobs so we'll just ignore seg events prior to now.
             */
            if (manager.seg_last_timestamp == 0)
            {
                manager.seg_last_timestamp = time(NULL);
            }

            /* Start off the SEG if we need it.
             */
            if (config.seg_module != NULL || 
                strcmp(config.jobmanager_type, "fork") == 0 ||
                strcmp(config.jobmanager_type, "condor") == 0)
            {
                rc = globus_gram_job_manager_init_seg(&manager);

                /* TODO: If SEG load fails and load_all added some to the 
                 * job_id hash, they will need to be pushed into the state
                 * machine so that polling fallback can happen.
                 */
                if (rc != GLOBUS_SUCCESS)
                {
                    config.seg_module = NULL;
                }
            }
            /* GRAM-128:
             * Register a periodic event to process the GRAM jobs that were
             * reloaded from their job state files at job manager start time.
             * This will acquire and then release a reference to each job,
             * which, behind the scenes, will kick of the state machine
             * for that job if needed.
             */
            if (!globus_list_empty(manager.pending_restarts))
            {
                globus_reltime_t        restart_period;

                GlobusTimeReltimeSet(restart_period, 1, 0);

                rc = globus_callback_register_periodic(
                        &manager.pending_restart_handle,
                        NULL,
                        &restart_period,
                        globus_l_gram_process_pending_restarts,
                        &manager);
                        
            }

            {
                globus_reltime_t        expire_period;

                GlobusTimeReltimeSet(expire_period, 1, 0);

                rc = globus_callback_register_periodic(
                    &manager.expiration_handle,
                    NULL,
                    &expire_period,
                    globus_gram_job_manager_expire_old_jobs,
                    &manager);
            }

            {
                globus_reltime_t        lockcheck_period;

                GlobusTimeReltimeSet(lockcheck_period, 60, 0);

                rc = globus_callback_register_periodic(
                    &manager.lockcheck_handle,
                    NULL,
                    &lockcheck_period,
                    globus_l_gram_lockcheck,
                    &manager);
            }

            {
                globus_reltime_t        idlescript_period;

                GlobusTimeReltimeSet(idlescript_period, 60, 0);

                rc = globus_callback_register_periodic(
                    &manager.idle_script_handle,
                    NULL,
                    &idlescript_period,
                    globus_gram_script_close_idle,
                    &manager);
            }
        }
        else if (http_body_fd >= 0)
        {
            /* If manager.socket_fd == -1 then we are either the child from the
             * fork or another process started somehow (either command-line
             * invocation or via a job submit). If we have a client, then we'll
             * send our fds to the job manager with the lock and let it process
             * the job.
             *
             * If this succeeds, we set located_active_jm and leave the loop.
             * Otherwise, we try again.
             */
            if (context_fd >= 0)
            {
                rc = globus_gram_job_manager_starter_send(
                        &manager,
                        http_body_fd,
                        context_fd,
                        fileno(stdout),
                        cred);
            }
            else
            {
                rc = globus_gram_job_manager_starter_send_v2(
                        &manager,
                        cred);
            }
            if (rc == GLOBUS_SUCCESS)
            {
                located_active_jm = GLOBUS_TRUE;
                close(http_body_fd);
                if (context_fd >= 0)
                {
                    close(context_fd);
                }
                manager.done = GLOBUS_TRUE;
            }
            else
            {
                globus_libc_usleep(250000);
            }
        }
        else
        {
            /* We were started by hand, but another process is currently the
             * main job manager
             */
            unsigned long realpid = 0;
            FILE * pidin = fopen(manager.pid_path, "r");
            fscanf(pidin, "%lu", &realpid);
            fclose(pidin);

            fprintf(stderr, "Other job manager process with pid %lu running and processing jobs\n",
                    realpid);

            exit(0);
        }
    }

    /* Ignore SIGCHILD, and automatically reap child processes. Because of the
     * fork() above to delegate to another job manager process, and the use of
     * sub-processes to invoke the perl modules, we create some other
     * processes. We don't care too much how they exit, so we'll just make sure
     * we don't create zombies out of them.
     */
    {
        struct sigaction act;

        act.sa_handler = SIG_IGN;
        sigemptyset(&act.sa_mask);
        sigaddset(&act.sa_mask, SIGCHLD);
#ifdef SA_NOCLDWAIT
        act.sa_flags = SA_NOCLDWAIT;
#else
        /* This may leave zombies running on non-POSIX systems like Hurd */
        act.sa_flags = 0;
#endif
        sigaction(SIGCHLD, &act, NULL);
    }

    /* Enable log rotation via SIGUSR1 */
    {
        struct sigaction act;
        act.sa_handler = globus_i_job_manager_log_rotate;
        sigemptyset(&act.sa_mask);
        sigaddset(&act.sa_mask, SIGUSR1);
        act.sa_flags = 0;
        sigaction(SIGUSR1, &act, NULL);
    }
    
    GlobusGramJobManagerLock(&manager);
    if (manager.socket_fd != -1 &&
        globus_hashtable_empty(&manager.request_hash) &&
        manager.grace_period_timer == GLOBUS_NULL_HANDLE)
    {
        globus_gram_job_manager_set_grace_period_timer(&manager);
    }


    /* For the active job manager, this will block until all jobs have
     * terminated. For any other job manager, the monitor.done is set to
     * GLOBUS_TRUE and this falls right through.
     */
    while (! manager.done)
    {
        GlobusGramJobManagerWait(&manager);
    }
    if (manager.expiration_handle != GLOBUS_NULL_HANDLE)
    {
        globus_callback_unregister(manager.expiration_handle, NULL, NULL, NULL);
    }
    if (manager.lockcheck_handle != GLOBUS_NULL_HANDLE)
    {
        globus_callback_unregister(manager.lockcheck_handle, NULL, NULL, NULL);
    }
    if (manager.idle_script_handle != GLOBUS_NULL_HANDLE)
    {
        globus_callback_unregister(manager.idle_script_handle, NULL, NULL, NULL);
    }
    GlobusGramJobManagerUnlock(&manager);

    globus_gram_job_manager_log(
            &manager,
            GLOBUS_GRAM_JOB_MANAGER_LOG_DEBUG,
            "event=gram.end "
            "level=DEBUG "
            "\n");

    /* Clean-up to do if we are the active job manager only */
    if (manager.socket_fd != -1)
    {
        globus_gram_job_manager_script_close_all(&manager);
        globus_i_gram_usage_end_session_stats(&manager);
        globus_i_gram_usage_stats_destroy(&manager);
        remove(manager.pid_path);
        remove(manager.cred_path);
        remove(manager.socket_path);
        remove(manager.lock_path);
    }
    globus_gram_job_manager_logging_destroy();
    globus_gram_job_manager_destroy(&manager);
    globus_gram_job_manager_config_destroy(&config);

    rc = globus_l_gram_deactivate();
    if (rc != GLOBUS_SUCCESS)
    {
        fprintf(stderr, "deactivation failed with rc=%d\n",
                rc);
        exit(1);
    }

/*
    {
        const char * gk_jm_id_var = "GATEKEEPER_JM_ID";
        const char * gk_jm_id = globus_libc_getenv(gk_jm_id_var);

        globus_gram_job_manager_request_acct(
                request,
                "%s %s JM exiting\n",
                gk_jm_id_var, gk_jm_id ? gk_jm_id : "none");
    }
*/


    return(0);
}
static
int
globus_l_staging_replace_one_stream(
    globus_gram_jobmanager_request_t *  request,
    char *                              parameter,
    char *                              cached_destination,
    globus_list_t *                     list,
    globus_bool_t                       single)
{
    globus_rsl_value_t                  from_cached;
    globus_rsl_value_t                  *to = NULL;
    globus_rsl_value_t                  *tag = NULL;
    char                                *evaled_to = NULL;
    char                                *evaled_tag = NULL;
    char                                *fname = NULL;
    unsigned long                       timestamp = GLOBUS_GASS_CACHE_TIMESTAMP_UNKNOWN;
    int                                 rc = GLOBUS_SUCCESS;
    static const char                   gass_cache_scheme[] = "x-gass-cache://";

    from_cached.type = GLOBUS_RSL_VALUE_LITERAL;
    from_cached.value.literal.string = cached_destination;
    /*
     * First element of the list is the destination, the second is the
     * (optional) tag. Both (if present) must be something that 
     * evaluates to a string and not a sequence.
     */
    to = globus_list_first(list);
    list = globus_list_rest(list);
    if (!globus_list_empty(list))
    {
        tag = globus_list_first(list);
        list = globus_list_rest(list);
    }

    if (globus_rsl_value_is_sequence(to) || 
        ((tag != NULL) && globus_rsl_value_is_sequence(tag)) ||
        list != NULL)
    {
        rc = GLOBUS_GRAM_PROTOCOL_ERROR_RSL_STDOUT;

        goto bad_value;
    }

    rc = globus_gram_job_manager_rsl_evaluate_value(
            &request->symbol_table,
            to,
            &evaled_to);
    if (rc != GLOBUS_SUCCESS)
    {
        goto bad_value;
    }

    /* If it evaluates to a string, and is not an x-gass-cache URL,
     * then tag must be NULL
     */
    if (strncmp(evaled_to,
                gass_cache_scheme,
                sizeof(gass_cache_scheme)-1) != 0 &&
        tag != NULL)
    {
        rc = GLOBUS_GRAM_PROTOCOL_ERROR_RSL_STDOUT;
        free(evaled_to);
        goto bad_value;
    }

    if (tag != NULL)
    {
        /* If there's a tag, evaluate it and add it to the cache file
         * so that the file won't get erased when the job terminates
         */
        rc = globus_gram_job_manager_rsl_evaluate_value(
                &request->symbol_table,
                tag,
                &evaled_tag);
        if (rc != GLOBUS_SUCCESS)
        {
            goto bad_value;
        }
        rc = globus_gass_cache_add(
                request->cache_handle,
                evaled_to,
                evaled_tag,
                GLOBUS_TRUE,
                &timestamp,
                &fname);
        if (rc != GLOBUS_GASS_CACHE_ADD_NEW &&
            rc != GLOBUS_GASS_CACHE_ADD_EXISTS)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_OPENING_STDOUT;
            goto bad_value;
        }
        free(fname);
        rc = globus_gass_cache_add_done(
                request->cache_handle,
                evaled_to,
                evaled_tag,
                timestamp);
        if (rc != GLOBUS_SUCCESS)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_OPENING_STDOUT;
            goto bad_value;
        }
    }

    /* If there is more than one output destination, or this one is
     * a non-local destination, then add it to the streamout list
     */
    if ((!single) ||
            (strstr(evaled_to, "://") != NULL &&
             strncmp(evaled_to, gass_cache_scheme,
                    sizeof(gass_cache_scheme)-1) != 0))
    {
        rc = globus_l_gram_job_manager_staging_add_pair(
                request,
                &from_cached,
                to,
                "filestreamout");
        free(evaled_to);
        evaled_to = NULL;
        if (rc != GLOBUS_SUCCESS)
        {
            goto bad_value;
        }
    }
    else if (strstr(evaled_to, "://") == NULL)
    {
        /* If it's a local file, check that it is writable */
        int tmpfd;

        tmpfd = open(evaled_to, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
        if (tmpfd < 0)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_OPENING_STDOUT;
            free(evaled_to);
            goto bad_value;
        }
        else
        {
            close(tmpfd);
        }
    }
    if (evaled_to)
    {
        free(evaled_to);
    }

    if (rc != GLOBUS_SUCCESS)
    {
bad_value:
        /* Normalize error types to match the RSL attribute that we are
         * processing
         */
        if (strcmp(parameter, GLOBUS_GRAM_PROTOCOL_STDERR_PARAM) == 0)
        {
            switch (rc)
            {
                case GLOBUS_GRAM_PROTOCOL_ERROR_RSL_STDOUT:
                    rc = GLOBUS_GRAM_PROTOCOL_ERROR_RSL_STDERR;
                    break;
                case GLOBUS_GRAM_PROTOCOL_ERROR_OPENING_STDOUT:
                    rc = GLOBUS_GRAM_PROTOCOL_ERROR_OPENING_STDERR;
                    break;
                default:
                    break;
            }
        }
    }
    return rc;
}
static
int
globus_l_staging_replace_stream(
    globus_gram_jobmanager_request_t *  request,
    char *                              parameter,
    char *                              cached_destination)
{
    globus_list_t *                     list;
    globus_rsl_value_t                  *to;
    globus_rsl_value_t                  from_cached;
    globus_bool_t                       single;
    int                                 rc = GLOBUS_SUCCESS;

    list = globus_rsl_param_get_values(
            request->rsl,
            parameter);

    if (list == NULL)
    {
        /* Attempting to replace something that was never in the job
         * RSL---too bad
         */
        return GLOBUS_SUCCESS;
    }
    from_cached.type = GLOBUS_RSL_VALUE_LITERAL;
    from_cached.value.literal.string = cached_destination;

    /* The stdout and stderr attributes can occur in two forms:
     * - stdout = destination [tag]
     * - stdout = (destination [tag])+
     * That is, either as a sequence of 1 or 2 values, or as a sequence of
     * sequences.
     *
     * In either form, if there is only one destination, and it's a local file
     * or x-gass-cache URL, we can safely write directly to that file and don't
     * need it to be staged after the job completes. Otherwise, we'll have to
     * write to the stdout (stderr) file in the job directory and copy it
     * during the STAGE_OUT state.
     */
    if (! globus_rsl_value_is_sequence(globus_list_first(list)))
    {
        rc = globus_l_staging_replace_one_stream(
                request,
                parameter,
                cached_destination,
                list,
                GLOBUS_TRUE);
    }
    else
    {
        single = (globus_list_size(list) == 1);

        while (!globus_list_empty(list))
        {
            globus_list_t                   *sequence_list;

            to = globus_list_first(list);
            list = globus_list_rest(list);

            if (!globus_rsl_value_is_sequence(to))
            {
                /* Bare value instead of a sequence */
                rc = GLOBUS_GRAM_PROTOCOL_ERROR_RSL_STDOUT;
                goto bad_value;
            }

            sequence_list = globus_rsl_value_sequence_get_value_list(to);

            rc = globus_l_staging_replace_one_stream(
                    request,
                    parameter,
                    cached_destination,
                    sequence_list,
                    single);

            if (rc != GLOBUS_SUCCESS)
            {
                goto bad_value;
            }

        }
    }

    if (rc != GLOBUS_SUCCESS)
    {
bad_value:
        /* Normalize error types to match the RSL attribute that we are
         * processing
         */
        if (strcmp(parameter, GLOBUS_GRAM_PROTOCOL_STDERR_PARAM) == 0)
        {
            switch (rc)
            {
                case GLOBUS_GRAM_PROTOCOL_ERROR_RSL_STDOUT:
                    rc = GLOBUS_GRAM_PROTOCOL_ERROR_RSL_STDERR;
                    break;
                case GLOBUS_GRAM_PROTOCOL_ERROR_OPENING_STDOUT:
                    rc = GLOBUS_GRAM_PROTOCOL_ERROR_OPENING_STDERR;
                    break;
                default:
                    break;
            }
        }
    }
    return rc;
}
/**
 * Add default values to RSL and verify required parameters
 *
 * Inserts default values to RSL when an RSL parameter is not defined
 * in it. After this is complete, it checks that all RSL parameters
 * with the "required_when" flag set are present in the RSL tree.
 *
 * @param request
 *        Request which contains the RSL tree to validate.
 * @param when
 *        Which RSL validation time scope we will use to decide
 *        whether to use the default values or not.
 */
static
int
globus_l_gram_job_manager_insert_default_rsl(
    globus_gram_jobmanager_request_t *  request,
    globus_rsl_t *                      rsl,
    globus_gram_job_manager_validation_when_t
                                        when)
{
    globus_rvf_record_t *               record;
    globus_list_t **                    attributes;
    globus_rsl_t *                      new_relation;
    char *                              new_relation_str;
    globus_list_t *                     validation_records;
    int                                 rc = GLOBUS_SUCCESS;

    attributes = globus_rsl_boolean_get_operand_list_ref(rsl);

    validation_records = request->manager->validation_records;

    while(!globus_list_empty(validation_records))
    {
        record = globus_list_first(validation_records);
        validation_records = globus_list_rest(validation_records);

        if(record->default_value && (record->default_when&when))
        {
            if(!globus_l_gram_job_manager_attribute_exists(
                        *attributes,
                        record->attribute))
            {
                new_relation_str = globus_common_create_string(
                        "%s = %s",
                        record->attribute,
                        record->default_value);

                globus_gram_job_manager_request_log(
                        request,
                        GLOBUS_GRAM_JOB_MANAGER_LOG_TRACE,
                        "event=gram.validate_rsl.info "
                        "level=TRACE "
                        "msg=\"Inserting default RSL for attribute\" "
                        "attribute=%s "
                        "default=\"%s\" "
                        "\n",
                        record->attribute,
                        record->default_value);

                new_relation = globus_rsl_parse(new_relation_str);

                globus_list_insert(attributes, new_relation);

                free(new_relation_str);
            }
        }
        if(record->required_when & when)
        {
            if(!globus_l_gram_job_manager_attribute_exists(
                        *attributes,
                        record->attribute))
            {
                rc = globus_l_gram_job_manager_missing_value_error(
                            record->attribute);

                globus_gram_job_manager_request_log(
                        request,
                        GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
                        "event=gram.validate_rsl.end "
                        "level=ERROR "
                        "msg=\"RSL missing required attribute\" "
                        "attribute=%s "
                        "\n",
                        record->attribute);

                return rc;
            }
        }
    }
    return rc;
}
/**
 * Validate RSL attributes
 *
 * Checks that all of the RSL attributes in the request's RSL match
 * a validation record. If an RSL has an enumerated list of values,
 * then the value of the RSL is compared against that list.
 *
 * @param request
 *        The job request containing the RSL to validate.
 * @param when
 *        Which RSL validation time scope we will use to decide
 *        whether to use the default values or not.
 */
static
int
globus_l_gram_job_manager_check_rsl_attributes(
    globus_gram_jobmanager_request_t *  request,
    globus_rsl_t *                      rsl,
    globus_gram_job_manager_validation_when_t
                                        when)
{
    globus_list_t *                     operands;
    globus_list_t *                     node;
    globus_rsl_t *                      relation;
    char *                              attribute;
    char *                              value_str;
    globus_rvf_record_t *               record;
    globus_rsl_value_t *                value;
    int                                 rc = GLOBUS_SUCCESS;
    static const char *                 operation_types[] =
    {
        "??",
        "=",
        "!=",
        ">",
        ">=",
        "<",
        "<=",
        "??",
        "&",
        "|",
        "+"
    };

    operands = globus_rsl_boolean_get_operand_list(rsl);

    /* Check to make sure that every attribute is recognized by this
     * job manager.
     */
    while(!globus_list_empty(operands))
    {
        relation = globus_list_first(operands);
        operands = globus_list_rest(operands);

        if (!globus_rsl_is_relation(relation))
        {
            int operator = globus_rsl_boolean_get_operator(relation);
            if (operator > 10 || operator < 0)
            {
                operator = 0;
            }

            globus_gram_job_manager_request_log(
                    request,
                    GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
                    "event=gram.validate_rsl.end "
                    "level=ERROR "
                    "msg=\"Required RSL relation, got boolean\" "
                    "operator=%s "
                    "status=%d "
                    "\n",
                    operation_types[operator],
                    -GLOBUS_GRAM_PROTOCOL_ERROR_BAD_RSL);
            if (request->gt3_failure_message == NULL)
            {
                request->gt3_failure_message = globus_common_create_string(
                        "Required RSL relation, got boolean %s",
                        operation_types[operator]);
            }
        }
        else if (!globus_rsl_is_relation_eq(relation))
        {
            int operator = globus_rsl_relation_get_operator(relation);

            if (operator > 10 || operator < 0)
            {
                operator = 0;
            }

            globus_gram_job_manager_request_log(
                    request,
                    GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
                    "event=gram.validate_rsl.end "
                    "level=ERROR "
                    "msg=\"Unsupported RSL operation\" "
                    "attribute=%s "
                    "operator=%s "
                    "status=%d "
                    "\n",
                    globus_rsl_relation_get_attribute(relation),
                    operation_types[operator],
                    -GLOBUS_GRAM_PROTOCOL_ERROR_BAD_RSL);

            if (request->gt3_failure_message == NULL)
            {
                request->gt3_failure_message = globus_common_create_string(
                        "the job manager does not support the RSL operator "
                        "\"%s\" for the %s attribute",
                        operation_types[operator],
                        globus_rsl_relation_get_attribute(relation));
            }
            return GLOBUS_GRAM_PROTOCOL_ERROR_BAD_RSL;
        }
        attribute = globus_rsl_relation_get_attribute(relation);

        node = globus_list_search_pred(
                request->manager->validation_records,
                globus_l_gram_job_manager_attribute_match,
                attribute);

        if(!node)
        {
            globus_gram_job_manager_request_log(
                    request,
                    GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
                    "event=gram.validate_rsl.end "
                    "level=ERROR "
                    "msg=\"Unsupported RSL attribute\" "
                    "attribute=%s "
                    "status=%d "
                    "\n",
                    globus_rsl_relation_get_attribute(relation),
                    -GLOBUS_GRAM_PROTOCOL_ERROR_BAD_RSL);

            if (request->gt3_failure_message == NULL)
            {
                request->gt3_failure_message = globus_common_create_string(
                        "the RSL attribute \"%s\" is not supported by the LRM adapter",
                        globus_rsl_relation_get_attribute(relation));
            }
            return GLOBUS_GRAM_PROTOCOL_ERROR_PARAMETER_NOT_SUPPORTED;
        }

        record = globus_list_first(node);

        /* Check valid_when */
        if((record->valid_when & when) == 0)
        {
            const char * whenstr = "unknown operation";

            switch(when)
            {
              case GLOBUS_GRAM_VALIDATE_JOB_SUBMIT:
                whenstr = "submit";
                rc = GLOBUS_GRAM_PROTOCOL_ERROR_INVALID_SUBMIT_ATTRIBUTE;
                break;
              case GLOBUS_GRAM_VALIDATE_JOB_MANAGER_RESTART:
                whenstr = "restart";
                rc = GLOBUS_GRAM_PROTOCOL_ERROR_INVALID_RESTART_ATTRIBUTE;
                break;
              case GLOBUS_GRAM_VALIDATE_STDIO_UPDATE:
                whenstr = "stdio_update";
                rc = GLOBUS_GRAM_PROTOCOL_ERROR_INVALID_STDIO_UPDATE_ATTRIBUTE;
                break;
            }

            globus_gram_job_manager_request_log(
                    request,
                    GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
                    "event=gram.validate_rsl.end "
                    "level=ERROR "
                    "msg=\"Invalid RSL attribute for operation\" "
                    "attribute=%s "
                    "operation=%s "
                    "status=%d "
                    "\n",
                    globus_rsl_relation_get_attribute(relation),
                    whenstr,
                    -rc);
            if (request->gt3_failure_message == NULL)
            {
                request->gt3_failure_message = globus_common_create_string(
                        "Invalid RSL attribute \"%s\" for %s",
                        globus_rsl_relation_get_attribute(relation),
                        whenstr);
            }
            return rc;
        }
        /* Check enumerated values if applicable */
        if(record->enumerated_values)
        {
            value = globus_rsl_relation_get_single_value(relation);

            if(!value)
            {
                return
                    globus_l_gram_job_manager_validation_rsl_error(attribute);
            }
            value_str = globus_rsl_value_literal_get_string(value);
            if(!value_str)
            {
                return globus_l_gram_job_manager_validation_rsl_error(
                        attribute);
            }
            if(strstr(record->enumerated_values, value_str) == GLOBUS_NULL)
            {
                rc = globus_l_gram_job_manager_validation_value_error(
                            request,
                            attribute,
                            value_str,
                            record->enumerated_values);

                globus_gram_job_manager_request_log(
                        request,
                        GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
                        "event=gram.validate_rsl.end "
                        "level=ERROR "
                        "msg=\"RSL attribute value not in enumeration\" "
                        "attribute=%s "
                        "value=%s "
                        "enumeration=\"%s\" "
                        "status=%d "
                        "\n",
                        record->attribute,
                        value_str,
                        record->enumerated_values,
                        -rc);

                return rc;
            }
        }
    }

    return GLOBUS_SUCCESS;
}
示例#28
0
static bool
value_to_expr(globus_rsl_value_t * value, classad::ExprTree*& expr)
{
    if (globus_rsl_value_is_literal(value))
    {
        char * literal = globus_rsl_value_literal_get_string(value);
        if (!literal) { return false; }
        classad::Value val;
        try
        {
            val.SetIntegerValue(boost::lexical_cast<long long>(literal));
        }
        catch (const boost::bad_lexical_cast &)
        {
            try
            {
                val.SetRealValue(boost::lexical_cast<double>(literal));
            }
            catch (const boost::bad_lexical_cast &)
            {
                std::string lower = literal;
                boost::algorithm::to_lower(lower);
                if (lower == "true") { val.SetBooleanValue(true); }
                else if (lower == "false") { val.SetBooleanValue(false); }
                else { val.SetStringValue(literal); }
            }
        }
        expr = classad::Literal::MakeLiteral(val);
        if (!expr) { return false; }
        return true;
    }
    else if (globus_rsl_value_is_sequence(value))
    {
        globus_list_t * value_list = globus_rsl_value_sequence_get_value_list(value);
        if (!value_list) { return false; }

        classad::ExprList expr_list;
        while (!globus_list_empty(value_list))
        {
            globus_rsl_value_t *list_item = static_cast<globus_rsl_value_t*>(globus_list_first(value_list));
            value_list = globus_list_rest(value_list);
            if (!list_item) { continue; }

            classad::ExprTree *expr_item = NULL;
            if (!value_to_expr(list_item, expr_item) || !expr_item) { continue; }

            expr_list.push_back(expr_item);
        }
        expr = expr_list.Copy();
        return expr ? true : false;
    }
    else if (globus_rsl_value_is_concatenation(value))
    {
        globus_rsl_value_t *left_value = globus_rsl_value_concatenation_get_left(value);
        globus_rsl_value_t *right_value = globus_rsl_value_concatenation_get_right(value);
        if (!left_value || !right_value) { return false; }

        classad::ExprTree *left_expr = NULL, *right_expr = NULL;
        if (!value_to_expr(left_value, left_expr) || !left_expr || !value_to_expr(right_value, right_expr) || !right_expr) { return false; }
        std::vector<classad::ExprTree*> argList; argList.push_back(left_expr); argList.push_back(right_expr);

        expr = classad::FunctionCall::MakeFunctionCall("strcat", argList);
        return expr ? true : false;
    }
    else if (globus_rsl_value_is_variable(value))
    {
        char * char_variable_name = globus_rsl_value_variable_get_name(value);
        char * default_value = globus_rsl_value_variable_get_default(value);
        if (!char_variable_name) { return false; }

        // Canonical forms of Globus RSL strip out all underscores and makes the string
        // lowercase.  As ClassAds are case-preserving (and underscores are significant),
        // we just do the former transform.
        std::string variable_name(char_variable_name);
        boost::algorithm::replace_all(variable_name, "_", "");

        if (default_value)
        {
            // ifThenElse(isUndefined(variable_name), default_value, variable_name)
            std::vector<classad::ExprTree*> ifArgList;

            classad::ExprTree *attr1 = classad::AttributeReference::MakeAttributeReference(NULL, variable_name);
            if (!attr1) { return false; }
            std::vector<classad::ExprTree*> argList; argList.push_back(attr1);
            classad::ExprTree *isUndefined = classad::FunctionCall::MakeFunctionCall("isUndefined", argList);
            ifArgList.push_back(isUndefined);

            classad::Value val; val.SetStringValue(default_value);
            classad::ExprTree *lit = classad::Literal::MakeLiteral(val);
            if (!lit) { return false; }
            ifArgList.push_back(lit);

            classad::ExprTree *attr2 = classad::AttributeReference::MakeAttributeReference(NULL, variable_name);
            if (!attr2) { return false; }
            ifArgList.push_back(attr2);

            expr = classad::FunctionCall::MakeFunctionCall("ifThenElse", ifArgList);
        }
        else
        {
            expr = classad::AttributeReference::MakeAttributeReference(NULL, variable_name);
        }
        return expr ? true : false;
    }
    return false;
}
int
globus_gram_job_manager_staging_write_state(
    globus_gram_jobmanager_request_t *  request,
    FILE *                              fp)
{
    globus_list_t *                     tmp_list;
    globus_gram_job_manager_staging_info_t *
                                        info;
    char *                              tmp_str;
    int                                 rc;

    rc = fprintf(fp, "%d\n", globus_list_size(request->stage_in_todo));

    if (rc < 0)
    {
        return GLOBUS_FAILURE;
    }

    tmp_list = request->stage_in_todo;
    while(!globus_list_empty(tmp_list))
    {
        info = globus_list_first(tmp_list);
        tmp_list = globus_list_rest(tmp_list);

        tmp_str = globus_rsl_value_unparse(info->from);
        rc = fprintf(fp, "%s\n", tmp_str);
        free(tmp_str);
        if (rc < 0)
        {
            return GLOBUS_FAILURE;
        }

        tmp_str = globus_rsl_value_unparse(info->to);
        rc = fprintf(fp, "%s\n", tmp_str);
        free(tmp_str);
        if (rc < 0)
        {
            return GLOBUS_FAILURE;
        }
    }
    rc = fprintf(fp, "%d\n", globus_list_size(request->stage_in_shared_todo));
    if (rc < 0)
    {
        return GLOBUS_FAILURE;
    }
    tmp_list = request->stage_in_shared_todo;
    while(!globus_list_empty(tmp_list))
    {
        info = globus_list_first(tmp_list);
        tmp_list = globus_list_rest(tmp_list);

        tmp_str = globus_rsl_value_unparse(info->from);
        rc = fprintf(fp, "%s\n", tmp_str);
        free(tmp_str);
        if (rc < 0)
        {
            return GLOBUS_FAILURE;
        }

        tmp_str = globus_rsl_value_unparse(info->to);
        rc = fprintf(fp, "%s\n", tmp_str);
        free(tmp_str);
        if (rc < 0)
        {
            return GLOBUS_FAILURE;
        }
    }
    rc = fprintf(fp, "%d\n", globus_list_size(request->stage_out_todo));
    if (rc < 0)
    {
        return GLOBUS_FAILURE;
    }
    tmp_list = request->stage_out_todo;
    while(!globus_list_empty(tmp_list))
    {
        info = globus_list_first(tmp_list);
        tmp_list = globus_list_rest(tmp_list);

        tmp_str = globus_rsl_value_unparse(info->from);
        rc = fprintf(fp, "%s\n", tmp_str);
        free(tmp_str);

        if (rc < 0)
        {
            return GLOBUS_FAILURE;
        }

        tmp_str = globus_rsl_value_unparse(info->to);
        rc = fprintf(fp, "%s\n", tmp_str);
        free(tmp_str);
        if (rc < 0)
        {
            return GLOBUS_FAILURE;
        }
    }
    rc = fprintf(fp, "%d\n", globus_list_size(request->stage_stream_todo));
    tmp_list = request->stage_stream_todo;
    while(!globus_list_empty(tmp_list))
    {
        info = globus_list_first(tmp_list);
        tmp_list = globus_list_rest(tmp_list);

        tmp_str = globus_rsl_value_unparse(info->from);
        rc = fprintf(fp, "%s\n", tmp_str);
        free(tmp_str);

        if (rc < 0)
        {
            return GLOBUS_FAILURE;
        }

        tmp_str = globus_rsl_value_unparse(info->to);
        rc = fprintf(fp, "%s\n", tmp_str);
        free(tmp_str);
        if (rc < 0)
        {
            return GLOBUS_FAILURE;
        }
    }
    return GLOBUS_SUCCESS;
}
int
globus_gram_job_manager_staging_create_list(
    globus_gram_jobmanager_request_t *  request)
{
    int                                 i;
    int                                 rc;
    globus_rsl_value_t *                from;
    globus_rsl_value_t *                to;
    globus_list_t *                     list;
    globus_list_t *                     pairs;
    char *                              can_stage_list[] =
    {
        GLOBUS_GRAM_PROTOCOL_FILE_STAGE_IN_PARAM,
        GLOBUS_GRAM_PROTOCOL_FILE_STAGE_IN_SHARED_PARAM,
        GLOBUS_GRAM_PROTOCOL_FILE_STAGE_OUT_PARAM,
        NULL
    };
    int                                 errors_list[] =
    {
        GLOBUS_GRAM_PROTOCOL_ERROR_RSL_FILE_STAGE_IN,
        GLOBUS_GRAM_PROTOCOL_ERROR_RSL_FILE_STAGE_IN_SHARED,
        GLOBUS_GRAM_PROTOCOL_ERROR_RSL_FILE_STAGE_OUT,
        0
    };

    if(request->jm_restart)
    {
        return GLOBUS_SUCCESS;
    }

    for(i = 0; can_stage_list[i] != NULL; i++)
    {
        list = globus_rsl_param_get_values(request->rsl, can_stage_list[i]);

        if(!list)
        {
            continue;
        }

        while(!globus_list_empty(list))
        {
            pairs = globus_rsl_value_sequence_get_value_list(
                    globus_list_first(list));
            list = globus_list_rest(list);

            if(globus_list_size(pairs) != 2)
            {
                rc = errors_list[i];
                goto failed_adding_exit;
            }

            from = globus_list_first(pairs);
            to = globus_list_first(globus_list_rest(pairs));

            rc = globus_l_gram_job_manager_staging_add_pair(
                    request,
                    from,
                    to,
                    can_stage_list[i]);

            if(rc != GLOBUS_SUCCESS)
            {
                goto failed_adding_exit;
                
            }
        }
    }

    rc = globus_gram_job_manager_streaming_list_replace(request);

failed_adding_exit:
    if (rc != GLOBUS_SUCCESS)
    {
        globus_gram_job_manager_staging_free_all(request);
    }
    return rc;
}