static 
void
l_begin_xfer(
    globus_ftp_client_handle_t *        ftp_handle,
    globus_l_ftp_client_restart_plugin_t *  d)
{
    globus_reltime_t                    period;

    if(!d->stall_timeout)
    {
        return;
    }
    d->ticker = 0;
    d->ticker_ftp_handle = ftp_handle;
    d->xfer_running = GLOBUS_TRUE;
    d->ticker_set = GLOBUS_TRUE;
    
    /* start a timer, half of stall timeout */
    /* we won't restart/abort until the 2nd callback with no data */
    GlobusTimeReltimeSet(period, d->stall_timeout/2, 0);
    globus_callback_register_periodic(
        &d->ticker_handle,
        &period,
        &period,
        l_ticker_cb,
        d);
}
int
globus_i_xio_win32_complete_activate(void)
{
    globus_result_t                     result;
    globus_reltime_t                    period;
    GlobusXIOName(globus_i_xio_win32_complete_activate);
    
    GlobusXIOSystemDebugEnter();
    
    if (!globus_i_am_only_thread())
    {
        goto skip_activate;
    }
    GlobusLWin32PollQueueInit();
    win32_mutex_init(&globus_l_xio_win32_poll_lock, 0);
    globus_l_xio_win32_poll_event_sleeping = GLOBUS_FALSE;
    globus_l_xio_win32_poll_event_pending = GLOBUS_FALSE;
    globus_l_xio_win32_poll_free = 0;
    
    globus_l_xio_win32_poll_event = CreateEvent(0, FALSE, FALSE, 0);
    if(globus_l_xio_win32_poll_event == 0)
    {
        goto error_event;
    }
    
    GlobusTimeReltimeSet(period, 0, 0);
    result = globus_callback_register_periodic(
        &globus_l_xio_win32_poll_handle,
        0,
        &period,
        globus_l_xio_win32_poll,
        0);
    if(result != GLOBUS_SUCCESS)
    {
        goto error_periodic;
    }
    
    globus_callback_add_wakeup_handler(
        globus_l_xio_win32_wakeup_handler, 0);
    
skip_activate:
    GlobusXIOSystemDebugExit();
    
    return GLOBUS_SUCCESS;
    
error_periodic:
    CloseHandle(globus_l_xio_win32_poll_event);
    globus_l_xio_win32_poll_event = 0;
error_event:
    win32_mutex_destroy(&globus_l_xio_win32_poll_lock);
    GlobusXIOSystemDebugExitWithError();
    return GLOBUS_FAILURE;
}
/**
 * Periodic poll of file to act like tail -f
 *
 * @param user_arg
 *     Log file parsing state
 */
static
void
globus_l_job_manager_poll_callback(
    void *                              user_arg)
{
    int                                 rc;
    globus_l_job_manager_logfile_state_t *
                                        state = user_arg;
    globus_bool_t                       eof_hit = GLOBUS_FALSE;
    globus_reltime_t                    delay;
    globus_result_t                     result;
    time_t                              poll_time = time(NULL);
    struct tm                           poll_tm, *tm_result;
    struct stat                         stat;
    char *                              today;

    SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_INFO,
            ("globus_l_job_manager_poll_callback()\n"));

    globus_mutex_lock(&globus_l_job_manager_mutex);
    if (shutdown_called)
    {
        SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_INFO,
                ("polling while deactivating"));

        globus_mutex_unlock(&globus_l_job_manager_mutex);
        goto error;
    }
    globus_mutex_unlock(&globus_l_job_manager_mutex);

    if (state->fp != NULL)
    {
        /* Parse data */
        SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_TRACE,
                ("parsing events\n"));
        rc = globus_l_job_manager_parse_events(state);
        if (rc == SEG_JOB_MANAGER_ERROR_LOG_EOF)
        {
            eof_hit = GLOBUS_TRUE;
        }
    }

    if (eof_hit)
    {
        tm_result = globus_libc_gmtime_r(&poll_time, &poll_tm);
        if (tm_result == NULL)
        {
            SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_WARN,
                    ("Couldn't convert to gmtime\n"));
        }
        else
        {
            today = globus_common_create_string(
                    "%s/%4d%02d%02d",
                    state->log_dir,
                    tm_result->tm_year+1900,
                    tm_result->tm_mon+1,
                    tm_result->tm_mday);
            if (today && (strcmp(today, state->path) != 0))
            {
                /* New day... if new file exists and the old one hasn't changed since our
                 * last poll, mark it as old
                 */
                if (globus_l_next_file_exists(state))
                {
                    rc = fstat(fileno(state->fp), &stat);
                    if (rc != -1)
                    {
                        if (ftello(state->fp) == stat.st_size)
                        {
                            state->old_log = GLOBUS_TRUE;
                        }
                    }
                }
            }
            if (today)
            {
                free(today);
            }
        }
    }

    /* If end of log, close this logfile and look for a new one. Also, if
     * the current day's log doesn't exist yet, check for it
     */
    if ((eof_hit && state->old_log) || state->fp == NULL)
    {
        if (state->fp)
        {
            fclose(state->fp);
            state->fp = NULL;
            state->start_timestamp.tm_mday++;
            state->start_timestamp.tm_hour = 0;
            state->start_timestamp.tm_min = 0;
            state->start_timestamp.tm_sec = 0;
            globus_l_job_manager_normalize_date(&state->start_timestamp);
        }

        rc = globus_l_job_manager_find_logfile(state);

        if (rc == GLOBUS_SUCCESS)
        {
            /* Opening a new logfile, run w/out delay */
            state->fp = fopen(state->path, "r");
            if (state->fp == NULL)
            {
                goto error;
            }
            eof_hit = GLOBUS_FALSE;

            GlobusTimeReltimeSet(delay, 0, 0);
        }
        else if (rc == SEG_JOB_MANAGER_ERROR_LOG_NOT_PRESENT)
        {
            /* Current day's logfile not present, wait a bit longer for
             * it to show up
             */
            GlobusTimeReltimeSet(delay, 30, 0);
            eof_hit = GLOBUS_TRUE;
        }
        else
        {
            goto error;
        }
    }
    else if(eof_hit)
    {
        /* eof on current logfile, wait for new data */
        GlobusTimeReltimeSet(delay, 2, 0);
    }
    else
    {
        /* still data available in current file, hurry up! */
        GlobusTimeReltimeSet(delay, 0, 0);
    }

    result = globus_callback_register_oneshot(
            &state->callback,
            &delay,
            globus_l_job_manager_poll_callback,
            state);
    if (result != GLOBUS_SUCCESS)
    {
        goto error;
    }
    SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_INFO,
            ("globus_l_job_manager_poll_callback() exited with/success\n"));
    return;
error:
    globus_mutex_lock(&globus_l_job_manager_mutex);
    if (shutdown_called)
    {
        callback_count--;

        if (callback_count == 0)
        {
            globus_cond_signal(&globus_l_job_manager_cond);
        }
    }
    globus_mutex_unlock(&globus_l_job_manager_mutex);

    SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_WARN,
            ("globus_l_job_manager_poll_callback() exited with/error\n"));
    return;
}
static
int
globus_l_job_manager_module_activate(void)
{
    time_t                              timestamp_val;
    globus_l_job_manager_logfile_state_t *      
                                        logfile_state;
    int                                 rc;
    globus_reltime_t                    delay;
    globus_result_t                     result;
    char *                              scheduler;

    rc = globus_module_activate(GLOBUS_COMMON_MODULE);
    if (rc != GLOBUS_SUCCESS)
    {
        goto activate_common_failed;
    }
    rc = globus_mutex_init(&globus_l_job_manager_mutex, NULL);

    if (rc != GLOBUS_SUCCESS)
    {
        goto mutex_init_failed;
    }
    rc = globus_cond_init(&globus_l_job_manager_cond, NULL);
    if (rc != GLOBUS_SUCCESS)
    {
        goto cond_init_failed;
    }
    shutdown_called = GLOBUS_FALSE;
    callback_count = 0;

    GlobusDebugInit(
        SEG_JOB_MANAGER,
        SEG_JOB_MANAGER_DEBUG_INFO
        SEG_JOB_MANAGER_DEBUG_WARN
        SEG_JOB_MANAGER_DEBUG_ERROR
        SEG_JOB_MANAGER_DEBUG_TRACE);

    logfile_state = calloc(1, sizeof(globus_l_job_manager_logfile_state_t));
    if (logfile_state == NULL)
    {
        goto calloc_state_failed;
    }

    /* Configuration info */
    result = globus_scheduler_event_generator_get_timestamp(&timestamp_val);
    if (result != GLOBUS_SUCCESS)
    {
        goto get_timestamp_failed;
    }

    if (timestamp_val != 0)
    {
        if (globus_libc_gmtime_r(
                &timestamp_val,
                &logfile_state->start_timestamp) == NULL)
        {
            goto gmtime_failed;
        }
    }
    scheduler = globus_libc_getenv(JOB_MANAGER_SEG_SCHEDULER);
    if (scheduler == NULL)
    {
        SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_ERROR,
            ("Error: %s not set\n", JOB_MANAGER_SEG_SCHEDULER));

        result = GLOBUS_FAILURE;
        goto get_scheduler_failed;
    }

    if (getenv(JOB_MANAGER_SEG_LOG_PATH))
    {
        logfile_state->log_dir = strdup(getenv(JOB_MANAGER_SEG_LOG_PATH));
    }
    else
    {
        char * log_dir_pattern = globus_common_create_string(
                "${localstatedir}/lib/globus/globus-seg-%s", scheduler);

        globus_eval_path(log_dir_pattern, &logfile_state->log_dir);
        free(log_dir_pattern);
    }

    if (logfile_state->log_dir == NULL)
    {
        SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_ERROR,
            ("Error: out of memory\n"));
        goto get_path_failed;
    }

    /* Convert timestamp to filename */
    rc = globus_l_job_manager_find_logfile(logfile_state);

    if (rc == GLOBUS_SUCCESS)
    {
        logfile_state->fp = fopen(logfile_state->path, "r");

        if (logfile_state->fp == NULL)
        {
            rc = SEG_JOB_MANAGER_ERROR_OUT_OF_MEMORY;

            goto fopen_failed;
        }
        GlobusTimeReltimeSet(delay, 0, 0);
    }
    else if(rc == SEG_JOB_MANAGER_ERROR_LOG_NOT_PRESENT)
    {
        GlobusTimeReltimeSet(delay, 1, 0);
    }
    else
    {
        goto bad_log_path;
    }

    result = globus_callback_register_oneshot(
            &logfile_state->callback,
            &delay,
            globus_l_job_manager_poll_callback,
            logfile_state);
    if (result != GLOBUS_SUCCESS)
    {
        goto oneshot_failed;
    }
    callback_count++;

    return 0;
oneshot_failed:
    if (logfile_state->fp)
    {
        fclose(logfile_state->fp);
    }
fopen_failed:
    if (logfile_state->path)
    {
        free(logfile_state->path);
    }
bad_log_path:
    free(logfile_state->log_dir);
get_path_failed:
get_scheduler_failed:
get_timestamp_failed:
gmtime_failed:
    free(logfile_state);
calloc_state_failed:
    globus_cond_destroy(&globus_l_job_manager_cond);
cond_init_failed:
    globus_mutex_destroy(&globus_l_job_manager_mutex);
mutex_init_failed:
    globus_module_deactivate(GLOBUS_COMMON_MODULE);
activate_common_failed:
    return 1;
}
예제 #5
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);
}
예제 #6
0
/*
 * Timeout test:
 *  -t server|client
 *     Configure the server or client to cause a timeout. If server is
 *     selected, then it will delay its part of the operation longer than the
 *     timeout value, causing the client to time out (and vice versa).
 *  -T timeout-in-ms
 *     Set the timeout value in ms
 *  -a
 *     Expect / cause the accept operation to delay longer than the timeout.
 *  -r
 *     Expect / cause a read operation to delay longer than the timeout.
 *
 */
int
main(
    int                                 argc,
    char *                              argv[])
{
    int                                 rc;
    char *                              contact = NULL;
    globus_result_t                     result;
    globus_l_timeout_info_t             client_timeout_info;
    globus_l_timeout_info_t             server_timeout_info;
    globus_reltime_t                    timeout;

    client_timeout_info.cause_timeout = GLOBUS_TRUE;
    client_timeout_info.expect_timeout = GLOBUS_FALSE;
    server_timeout_info.cause_timeout = GLOBUS_FALSE;
    server_timeout_info.expect_timeout = GLOBUS_TRUE;

    client_timeout_info.timeout_state =
        GLOBUS_XIO_OPERATION_TYPE_ACCEPT;
    server_timeout_info.timeout_state =
        GLOBUS_XIO_OPERATION_TYPE_ACCEPT;
    client_timeout_info.timeout = 1000;
    server_timeout_info.timeout = 1000;

    while ((rc = getopt(argc, argv, "t:T:arh")) != EOF)
    {
        switch (rc)
        {
            case 'h':
                usage(argv[0]);
                exit(0);
            case 't':
                if (strcmp(optarg, "client") == 0)
                {
                    client_timeout_info.cause_timeout = GLOBUS_TRUE;
                    client_timeout_info.expect_timeout = GLOBUS_FALSE;
                    server_timeout_info.cause_timeout = GLOBUS_FALSE;
                    server_timeout_info.expect_timeout = GLOBUS_TRUE;
                }
                else if (strcmp(optarg, "server") == 0)
                {
                    client_timeout_info.cause_timeout = GLOBUS_FALSE;
                    client_timeout_info.expect_timeout = GLOBUS_TRUE;
                    server_timeout_info.cause_timeout = GLOBUS_TRUE;
                    server_timeout_info.expect_timeout = GLOBUS_FALSE;
                }
                else
                {
                    usage(argv[0]);
                    exit(1);
                }
                break;
            case 'T':
                client_timeout_info.timeout = atoi(optarg);
                server_timeout_info.timeout = atoi(optarg);
                break;
            case 'a':
                client_timeout_info.timeout_state =
                    GLOBUS_XIO_OPERATION_TYPE_ACCEPT;
                server_timeout_info.timeout_state =
                    GLOBUS_XIO_OPERATION_TYPE_ACCEPT;
                break;
            case 'r':
                client_timeout_info.timeout_state =
                    GLOBUS_XIO_OPERATION_TYPE_READ;
                server_timeout_info.timeout_state =
                    GLOBUS_XIO_OPERATION_TYPE_READ;
                break;
            default:
                usage(argv[0]);
                exit(1);
        }
    }

    rc = http_test_initialize(
            &globus_l_tcp_driver,
            &globus_l_http_driver,
            &globus_l_http_stack);

    if (rc != GLOBUS_SUCCESS)
    {
        exit(2);
    }

    globus_mutex_init(&lock, NULL);
    globus_cond_init(&cond, NULL);

    GlobusTimeReltimeSet(timeout,
            0,
            (server_timeout_info.timeout * 1000));

    globus_xio_attr_init(&client_timeout_info.attr);
    globus_xio_attr_init(&server_timeout_info.attr);
    switch (server_timeout_info.timeout_state)
    {
        case GLOBUS_XIO_OPERATION_TYPE_ACCEPT:
            if (client_timeout_info.cause_timeout)
            {
                globus_xio_attr_cntl(
                        server_timeout_info.attr,
                        NULL,
                        GLOBUS_XIO_ATTR_SET_TIMEOUT_ACCEPT,
                        globus_l_timeout_callback,
                        &timeout,
                        NULL);
            }
            else
            {
                fprintf(stderr,
                        "Unable to handle server-caused accept timeout\n");
                exit(6);
            }
            break;

        case GLOBUS_XIO_OPERATION_TYPE_READ:
            if (client_timeout_info.cause_timeout)
            {
                globus_xio_attr_cntl(
                        server_timeout_info.attr,
                        NULL,
                        GLOBUS_XIO_ATTR_SET_TIMEOUT_READ,
                        globus_l_timeout_callback,
                        &timeout,
                        NULL);
            }
            else
            {
                globus_xio_attr_cntl(
                        client_timeout_info.attr,
                        NULL,
                        GLOBUS_XIO_ATTR_SET_TIMEOUT_READ,
                        globus_l_timeout_callback,
                        &timeout,
                        NULL);
            }
            break;

        default:
            fprintf(stderr, "Error: invalid timeout state\n");
            exit(3);
    }

    /* Set up client attributes */
    globus_xio_attr_cntl(
            client_timeout_info.attr,
            globus_l_http_driver,
            GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_METHOD,
            "POST");

    /* Modulate timeout state to causer's related state for delaying */
    if (client_timeout_info.cause_timeout)
    {
        switch (client_timeout_info.timeout_state)
        {
            case GLOBUS_XIO_OPERATION_TYPE_ACCEPT:
                client_timeout_info.timeout_state =
                    GLOBUS_XIO_OPERATION_TYPE_OPEN;
                break;

            case GLOBUS_XIO_OPERATION_TYPE_READ:
                client_timeout_info.timeout_state =
                    GLOBUS_XIO_OPERATION_TYPE_WRITE;
                break;

            case GLOBUS_XIO_OPERATION_TYPE_WRITE:
            case GLOBUS_XIO_OPERATION_TYPE_OPEN:
            case GLOBUS_XIO_OPERATION_TYPE_CLOSE:
            case GLOBUS_XIO_OPERATION_TYPE_FINISHED:
            case GLOBUS_XIO_OPERATION_TYPE_NONE:
            case GLOBUS_XIO_OPERATION_TYPE_DRIVER:
            case GLOBUS_XIO_OPERATION_TYPE_DD:
            case GLOBUS_XIO_OPERATION_TYPE_SERVER_INIT:
                fprintf(stderr,
                        "Error: unexpected state: %d\n",
                        client_timeout_info.state);
                exit(4);
        }
    }
    else
    {
        globus_assert(server_timeout_info.cause_timeout);
        switch (server_timeout_info.timeout_state)
        {
            case GLOBUS_XIO_OPERATION_TYPE_ACCEPT:
                fprintf(stderr,
                        "Invalid option (server-caused accept timeout)\n");
                exit(5);

            case GLOBUS_XIO_OPERATION_TYPE_READ:
                server_timeout_info.timeout_state =
                    GLOBUS_XIO_OPERATION_TYPE_WRITE;
                break;

            case GLOBUS_XIO_OPERATION_TYPE_WRITE:
            case GLOBUS_XIO_OPERATION_TYPE_OPEN:
            case GLOBUS_XIO_OPERATION_TYPE_CLOSE:
            case GLOBUS_XIO_OPERATION_TYPE_FINISHED:
            case GLOBUS_XIO_OPERATION_TYPE_NONE:
            case GLOBUS_XIO_OPERATION_TYPE_DRIVER:
            case GLOBUS_XIO_OPERATION_TYPE_DD:
            case GLOBUS_XIO_OPERATION_TYPE_SERVER_INIT:
                fprintf(stderr,
                        "Error: unexpected state: %d\n",
                        server_timeout_info.state);
                exit(4);
        }
    }

    /* create server */
    server_timeout_info.state = GLOBUS_XIO_OPERATION_TYPE_ACCEPT;
    server_timeout_info.handle = NULL;
    server_timeout_info.result = GLOBUS_SUCCESS;
    server_timeout_info.contact = NULL;
    result = globus_xio_server_create(
            &server_timeout_info.server,
            server_timeout_info.attr,
            globus_l_http_stack);

    result = globus_xio_server_get_contact_string(
            server_timeout_info.server,
            &contact);

    client_timeout_info.contact = globus_common_create_string("http://%s/%s",
            contact,
            "ok");

    /* create client handle */
    client_timeout_info.state = GLOBUS_XIO_OPERATION_TYPE_OPEN;
    client_timeout_info.handle = NULL;
    client_timeout_info.result = GLOBUS_SUCCESS;
    client_timeout_info.server = NULL;

    result = globus_xio_handle_create(
            &client_timeout_info.handle,
            globus_l_http_stack);

    /* oneshot to start server state machine */
    result = globus_callback_register_oneshot(
            NULL,
            &globus_i_reltime_zero,
            state_machine,
            &server_timeout_info);

    /* oneshot to start client state machine */
    result = globus_callback_register_oneshot(
            NULL,
            &globus_i_reltime_zero,
            state_machine,
            &client_timeout_info);

    /* wait for both state machines to terminate */
    globus_mutex_lock(&lock);
    while (client_timeout_info.state != GLOBUS_XIO_OPERATION_TYPE_NONE &&
           server_timeout_info.state != GLOBUS_XIO_OPERATION_TYPE_NONE)
    {
        globus_cond_wait(&cond, &lock);
    }
    globus_mutex_unlock(&lock);
    globus_mutex_destroy(&lock);

    globus_module_deactivate_all();

    return (client_timeout_info.result ||
            server_timeout_info.result ||
            client_timeout_info.expect_timeout ||
            server_timeout_info.expect_timeout);
}
예제 #7
0
static
void
state_machine(
    void *                              user_arg)
{
    globus_reltime_t                    delay;
    globus_result_t                     result;
    globus_l_timeout_info_t *           info = user_arg;

    /* If the timeout is to be caused by this side of the transfer, then check
     * current state, and if it's the timeout state, then we'll clear the
     * cause_timeout flag and then reregister this oneshot with the delay of
     * (timeout * 5) and continue the state machine.
     */

    globus_mutex_lock(&lock);
    if (info->cause_timeout && info->timeout_state == info->state)
    {
        /* register oneshot at (timeout * 5) */
        GlobusTimeReltimeSet(delay,
                0,
                (info->timeout * 5 * 1000));

        info->cause_timeout = GLOBUS_FALSE;
        info->state = GLOBUS_XIO_OPERATION_TYPE_CLOSE;

        globus_callback_register_oneshot(
                NULL,
                &delay,
                state_machine,
                info);
        globus_mutex_unlock(&lock);
        return;
    }

    /* process current state */
    switch (info->state)
    {
        case GLOBUS_XIO_OPERATION_TYPE_ACCEPT:
            globus_assert(info->server);
            result = globus_xio_server_register_accept(
                    info->server,
                    accept_callback,
                    info);
            break;

        case GLOBUS_XIO_OPERATION_TYPE_OPEN:
            result = globus_xio_register_open(
                    info->handle,
                    info->contact,
                    info->attr,
                    open_close_callback,
                    info);
            break;

        case GLOBUS_XIO_OPERATION_TYPE_READ:
            result = globus_xio_register_read(
                    info->handle,
                    info->buffer,
                    sizeof(info->buffer),
                    1,
                    NULL,
                    data_callback,
                    info);
            break;

        case GLOBUS_XIO_OPERATION_TYPE_WRITE:
            strcpy((char *) info->buffer, "ok\n");

            result = globus_xio_register_write(
                    info->handle,
                    info->buffer,
                    strlen((char *) info->buffer),
                    strlen((char *) info->buffer),
                    NULL,
                    data_callback,
                    info);
            break;

        case GLOBUS_XIO_OPERATION_TYPE_CLOSE:
            result = globus_xio_register_close(
                    info->handle,
                    NULL,
                    open_close_callback,
                    info);
            break;

        case GLOBUS_XIO_OPERATION_TYPE_FINISHED:
            globus_cond_signal(&cond);
            info->state = GLOBUS_XIO_OPERATION_TYPE_NONE;
            break;

        case GLOBUS_XIO_OPERATION_TYPE_NONE:
        case GLOBUS_XIO_OPERATION_TYPE_DRIVER:
        case GLOBUS_XIO_OPERATION_TYPE_DD:
        case GLOBUS_XIO_OPERATION_TYPE_SERVER_INIT:
            fprintf(stderr,
                    "Error: unexpected state: %d\n",
                    info->state);
            info->result = GLOBUS_FAILURE;
            info->state = GLOBUS_XIO_OPERATION_TYPE_NONE;
            globus_cond_signal(&cond);
            break;
    }
    globus_mutex_unlock(&lock);
}
static
void
globus_l_popen_waitpid(
    xio_l_popen_handle_t *              handle,
    int                                 opts)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
    int                                 status;
    int                                 rc;
    globus_reltime_t                    delay;
    GlobusXIOName(globus_l_popen_waitpid);

#ifdef WIN32
    result = GlobusXIOErrorSystemResource("not available for windows");
#else
    rc = waitpid(handle->pid, &status, opts);
    if(rc > 0)
    {
        /* if program exited normally, but with a nonzero code OR
         * program exited by signal, and we didn't signal it */
        if(((WIFEXITED(status) && WEXITSTATUS(status) != 0) || 
            (WIFSIGNALED(status) && handle->kill_state != GLOBUS_L_XIO_POPEN_NONE))
            && !handle->ignore_program_errors)
        {
            /* read programs stderr and dump it to an error result */
            globus_size_t                   nbytes = 0;
            globus_xio_iovec_t              iovec;
            char                            buf[8192];

            iovec.iov_base = buf;
            iovec.iov_len = sizeof(buf) - 1;
            
            result = globus_xio_system_file_read(
                handle->err_system, 0, &iovec, 1, 0, &nbytes);
            
            buf[nbytes] = 0;

            if(WIFEXITED(status))
            {
                result = globus_error_put(
                    globus_error_construct_error(
                        GLOBUS_XIO_MODULE,
                        GLOBUS_NULL,
                        GLOBUS_XIO_ERROR_SYSTEM_ERROR,
                        __FILE__,
                        _xio_name,
                        __LINE__,
                        _XIOSL("popened program exited with an error "
                               "(exit code: %d):\n%s"),
                        WEXITSTATUS(status), 
                        buf));
            }
            else
            {
                result = globus_error_put(
                    globus_error_construct_error(
                        GLOBUS_XIO_MODULE,
                        GLOBUS_NULL,
                        GLOBUS_XIO_ERROR_SYSTEM_ERROR,
                        __FILE__,
                        _xio_name,
                        __LINE__,
                        _XIOSL("popened program was terminated by a signal"
                               "(sig: %d)"),
                        WTERMSIG(status)));
            }
        }

        globus_xio_system_file_close(handle->errfd);
        globus_xio_system_file_destroy(handle->err_system);

        globus_xio_driver_finished_close(handle->close_op, result);
        globus_l_xio_popen_handle_destroy(handle);
    }
    else if(rc < 0 || opts == 0)
    {
        /* If the errno is ECHILD, either some other thread or part of the
         * program called wait and got this pid's exit status, or sigaction
         * with SA_NOCLDWAIT prevented the process from becoming a zombie. Not
         * really an error case.
         */
        if (errno != ECHILD)
        {
            result = GlobusXIOErrorSystemError("waitpid", errno);
        }

        globus_xio_system_file_close(handle->errfd);
        globus_xio_system_file_destroy(handle->err_system);

        globus_xio_driver_finished_close(handle->close_op, result);
        globus_l_xio_popen_handle_destroy(handle);
    }
    else
    {
        
        handle->wait_count++;
        
        if(handle->canceled)
        {
            switch(handle->kill_state)
            {
                case GLOBUS_L_XIO_POPEN_NONE:
                    if(handle->wait_count > 5000 / GLOBUS_L_XIO_POPEN_WAITPID_DELAY)
                    {
                        handle->kill_state = GLOBUS_L_XIO_POPEN_TERM;
                        kill(handle->pid, SIGTERM);
                    }
                    break;
                case GLOBUS_L_XIO_POPEN_TERM:
                    if(handle->wait_count > 15000 / GLOBUS_L_XIO_POPEN_WAITPID_DELAY)
                    {
                        handle->kill_state = GLOBUS_L_XIO_POPEN_KILL;
                        kill(handle->pid, SIGKILL);
                    }
                    break;
                default:
                    break;
            } 
        }
        
        GlobusTimeReltimeSet(delay, 0, GLOBUS_L_XIO_POPEN_WAITPID_DELAY);
        globus_callback_register_oneshot(
            NULL,
            &delay,
            globus_l_xio_popen_close_oneshot,
            handle);         
    }

#endif
    GlobusXIOPOpenDebugExit();
}
int main()
{
    int			i;
    int			successful_tests=0;
    globus_reltime_t    delay_time;

    globus_module_activate(GLOBUS_COMMON_MODULE);

    globus_mutex_init(&mutex, GLOBUS_NULL);
    globus_cond_init(&cond, GLOBUS_NULL);

    globus_libc_printf("Testing globus_cond_timedwait()\n\n");

    for(i = 0; tests[i] != GLOBUS_NULL; i++)
    {
	globus_bool_t signalled = GLOBUS_FALSE;
	globus_bool_t timedout = GLOBUS_FALSE;
	globus_bool_t ok;

	globus_libc_printf("Test %d: Signal at %d, timeout at %d\n",
	                   i+1,
	                   tests[i][0],
	                   tests[i][1]);

	done = GLOBUS_FALSE;

        GlobusTimeReltimeSet(delay_time, tests[i][0], 0);	
	globus_callback_register_oneshot(GLOBUS_NULL,
	                                 &delay_time,
					 wakeup_func,
					 GLOBUS_NULL);
	wait_func(tests[i][1],
		  &signalled,
		  &timedout);
	ok = GLOBUS_TRUE;
	if(((tests[i][0] < tests[i][1]) && signalled) ||
	   ((tests[i][0] > tests[i][1]) && !signalled))
	{
	    globus_libc_printf("Test %d: Signalled state as expected\n",
			       i+1);
	}
	else
	{
	    globus_libc_printf("Test %d: Signalled state not as expected\n",
			       i+1);
	    ok = GLOBUS_FALSE;
	}
	if(((tests[i][0] < tests[i][1]) && !timedout) ||
	   ((tests[i][0] > tests[i][1]) && timedout))
	{
	    globus_libc_printf("Test %d: Timedout state as expected\n",
			       i+1);
	}
	else
	{
	    globus_libc_printf("Test %d: Timedout state not as expected\n",
			       i+1);
	    ok = GLOBUS_FALSE;
	}
	globus_libc_printf("Test %d: %s\n",
	                   i+1,
	                   ok ? "SUCCESS" : "FAILED");
	if(ok)
	{
	    successful_tests++;
	}
    }

    if(successful_tests == i)
    {
        globus_libc_printf("--------------------------------\n"
	                   "ALL TESTS COMPLETED SUCCESSFULLY\n"
	                   "--------------------------------\n");
    }
    else
    {
        globus_libc_printf("-----------------------\n"
	                   "%d OF %d TESTS SUCCESSFUL\n"
	                   "-----------------------\n",
	                   successful_tests, i);
    }
    globus_module_deactivate(GLOBUS_COMMON_MODULE);

    return (successful_tests == i) ? 0 : 1;
}
int
globus_i_gass_transfer_fail(
    globus_gass_transfer_request_t		request,
    globus_gass_transfer_request_struct_t *	req,
    globus_gass_transfer_callback_t		callback,
    void *					callback_arg)
{
    int						rc = GLOBUS_SUCCESS;
    globus_reltime_t                            delay_time; 

    switch(req->status)
    {
      case GLOBUS_GASS_TRANSFER_REQUEST_ACTING:
      case GLOBUS_GASS_TRANSFER_REQUEST_ACTING_TO_PENDING:
	req->fail_callback = callback;
	req->fail_callback_arg = callback_arg;
	req->status = GLOBUS_GASS_TRANSFER_REQUEST_ACTING_TO_FAILING;
	req->proto->fail(req->proto,
			 request);
	break;
      case GLOBUS_GASS_TRANSFER_REQUEST_ACTING_TO_FAILING:
	rc = GLOBUS_GASS_TRANSFER_ERROR_DONE;
	break;
      case GLOBUS_GASS_TRANSFER_REQUEST_PENDING:
	req->fail_callback = callback;
	req->fail_callback_arg = callback_arg;
	req->status = GLOBUS_GASS_TRANSFER_REQUEST_FAILED;
	req->proto->fail(req->proto,
			 request);

	/* Drain queue of pending data requests,
	 * call fail callback, and destroy the request
	 */
        GlobusTimeReltimeSet(delay_time, 0, 0);
	globus_callback_register_oneshot(
	    GLOBUS_NULL,
	    &delay_time,
	    globus_l_gass_transfer_drain_callbacks,
	    (void *) request);
	break;
      case GLOBUS_GASS_TRANSFER_REQUEST_FAILED:
      case GLOBUS_GASS_TRANSFER_REQUEST_SERVER_FAIL1:
      case GLOBUS_GASS_TRANSFER_REQUEST_SERVER_FAIL2:
      case GLOBUS_GASS_TRANSFER_REQUEST_SERVER_FAIL3:
      case GLOBUS_GASS_TRANSFER_REQUEST_USER_FAIL:
      case GLOBUS_GASS_TRANSFER_REQUEST_REFERRED:
      case GLOBUS_GASS_TRANSFER_REQUEST_REFERRING:
      case GLOBUS_GASS_TRANSFER_REQUEST_ACTING_TO_REFERRING:
      case GLOBUS_GASS_TRANSFER_REQUEST_DENIED:
      case GLOBUS_GASS_TRANSFER_REQUEST_DONE:
      case GLOBUS_GASS_TRANSFER_REQUEST_FAILING:
      case GLOBUS_GASS_TRANSFER_REQUEST_FINISHING:
	rc = GLOBUS_GASS_TRANSFER_ERROR_DONE;
	break;
      case GLOBUS_GASS_TRANSFER_REQUEST_ACCEPTING:
	req->fail_callback = callback;
	req->fail_callback_arg = callback_arg;
	req->status = GLOBUS_GASS_TRANSFER_REQUEST_SERVER_FAIL1;
	break;
      case GLOBUS_GASS_TRANSFER_REQUEST_STARTING2:
	req->fail_callback = callback;
	req->fail_callback_arg = callback_arg;
	req->status = GLOBUS_GASS_TRANSFER_REQUEST_SERVER_FAIL2;
	break;
      case GLOBUS_GASS_TRANSFER_REQUEST_STARTING3:
	req->fail_callback = callback;
	req->fail_callback_arg = callback_arg;
	req->status = GLOBUS_GASS_TRANSFER_REQUEST_SERVER_FAIL3;
	break;
      case GLOBUS_GASS_TRANSFER_REQUEST_STARTING:
	req->fail_callback = callback;
	req->fail_callback_arg = callback_arg;
	req->status = GLOBUS_GASS_TRANSFER_REQUEST_USER_FAIL;
	break;
      case GLOBUS_GASS_TRANSFER_REQUEST_INVALID:
	break;
    }

    return rc;
}
int
main(
    int                                 argc,
    char **                             argv)
{
    int                                 opt;
    globus_gram_streamer_monitor_t      monitor;
    int                                 rc;
    char                                local_path[16];
    globus_result_t                     result;
    globus_reltime_t                    period;
    globus_module_descriptor_t *        modules[] =
    {
        GLOBUS_COMMON_MODULE,
        GLOBUS_GASS_TRANSFER_MODULE,
        NULL
    };
    globus_module_descriptor_t *        failed_module;

    memset(&monitor, 0, sizeof(globus_gram_streamer_monitor_t));
    globus_mutex_init(&monitor.request.mutex, NULL);
    globus_cond_init(&monitor.request.cond, NULL);

    while ((opt = getopt(argc, argv, "s:p:d:h")) != -1)
    {
        switch (opt)
        {
            case 's':
                monitor.request.job_state_file = optarg;
                /*
                 * Assume that the remote I/O file will not be newer than the
                 * current time
                 */
                monitor.remote_io_url_file_time = time(NULL);
                rc = globus_gram_job_manager_state_file_read(&monitor.request);
                if (rc != GLOBUS_SUCCESS)
                {
                    fprintf(stderr, "%d:Error reading state file %s\n",
                            rc, optarg);
                }
                break;

            case 'p':
                if ((monitor.pid_count+1) == STREAMER_MAX)
                {
                    fprintf(stderr, "%d:Too many pids for streamer\n",
                            GLOBUS_GRAM_PROTOCOL_ERROR_NO_RESOURCES);
                    exit(EXIT_FAILURE);
                }
                monitor.pids[monitor.pid_count++] =
                        (pid_t) strtol(optarg, NULL, 10);
                break;

            case 'd':
                rc = chdir(optarg);
                if (rc != 0)
                {
                    int save_errno = errno;
                    fprintf(stderr,
                            "%d:Error accessing job state directory: %s (%d)\n",
                            GLOBUS_GRAM_PROTOCOL_ERROR_BAD_DIRECTORY,
                            strerror(save_errno),
                            save_errno);
                    exit(EXIT_FAILURE);
                }
                break;
            case 'h':
                printf("Usage: %s -s STATE-FILE -p pid [-p pid]...\n", argv[0]);
                exit(EXIT_SUCCESS);
                break;

            case '?':
            default:
                fprintf(stderr, "%d:Unknown option: %c\n",
                        GLOBUS_GRAM_PROTOCOL_ERROR_GATEKEEPER_MISCONFIGURED, 
                        (char) opt);
                exit(EXIT_FAILURE);
        }
    }

    rc = globus_module_activate_array(modules, &failed_module);
    if (rc != GLOBUS_SUCCESS)
    {
        fprintf(stderr, "%d:Activation failed: %s %d\n",
                GLOBUS_GRAM_PROTOCOL_ERROR_GATEKEEPER_MISCONFIGURED,
                failed_module->module_name,
                rc);
        exit(EXIT_FAILURE);
    }

    strcpy(local_path, "stdout");
    monitor.output_stream.fd = open(local_path, O_RDONLY);

    strcpy(local_path, "stderr");
    monitor.error_stream.fd = open(local_path, O_RDONLY);

    rc = globus_mutex_init(&monitor.mutex, NULL);
    if (rc != GLOBUS_SUCCESS)
    {
        fprintf(stderr, "%d:Mutex init failed\n",
                GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED);
        exit(EXIT_FAILURE);
    }
    rc = globus_cond_init(&monitor.cond, NULL);
    if (rc != GLOBUS_SUCCESS)
    {
        fprintf(stderr, "%d:Mutex init failed\n",
                GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED);
        exit(EXIT_FAILURE);
    }

    globus_mutex_lock(&monitor.mutex);

    GlobusTimeReltimeSet(period, 5, 0);
    result = globus_callback_register_periodic(
            &monitor.local_poll_periodic,
            &globus_i_reltime_zero,
            &period,
            globus_l_gram_streamer_local_poll,
            &monitor);
    if (result != GLOBUS_SUCCESS)
    {
        char * errstr = globus_error_print_friendly(globus_error_peek(result));
        fprintf(stderr, "%d:Initialization error: %s\n",
                GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED,
                errstr);
        free(errstr);
        exit(EXIT_FAILURE);
    }

    result = globus_callback_register_periodic(
            &monitor.waitpids_poll_periodic,
            &globus_i_reltime_zero,
            &period,
            globus_l_gram_streamer_waitpids,
            &monitor);
    if (result != GLOBUS_SUCCESS)
    {
        char * errstr = globus_error_print_friendly(globus_error_peek(result));
        fprintf(stderr, "%d:Initialization error: %s\n",
                GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED,
                errstr);
        free(errstr);
        exit(EXIT_FAILURE);
    }

    rc = globus_l_gram_streamer_get_destinations(
            &monitor);
    if (rc != GLOBUS_SUCCESS)
    {
        exit(EXIT_FAILURE);
    }

    if (monitor.output_stream.fd != -1 &&
        monitor.output_stream.destination != NULL)
    {
        rc = globus_l_gram_streamer_open_destination(
                &monitor,
                &monitor.output_stream);
        if (rc != GLOBUS_SUCCESS)
        {
            fprintf(stderr, "%d:Error opening stdout destination %s (%d)\n",
                    GLOBUS_GRAM_PROTOCOL_ERROR_OPENING_STDOUT,
                    monitor.output_stream.destination,
                    rc);
            exit(EXIT_FAILURE);
        }
        monitor.output_stream.state = GLOBUS_GRAM_STREAM_NEW;
    }
    else
    {
        monitor.output_stream.state = GLOBUS_GRAM_STREAM_NONE;
    }
    if (monitor.error_stream.fd != -1 &&
        monitor.error_stream.destination != NULL)
    {
        rc = globus_l_gram_streamer_open_destination(
                &monitor,
                &monitor.error_stream);
        if (rc != GLOBUS_SUCCESS)
        {
            fprintf(stderr, "%d:Error opening stderr destination %s (%d)\n",
                    GLOBUS_GRAM_PROTOCOL_ERROR_OPENING_STDERR,
                    monitor.error_stream.destination,
                    rc);
            exit(EXIT_FAILURE);
        }
        monitor.error_stream.state = GLOBUS_GRAM_STREAM_NEW;
    }
    else
    {
        monitor.error_stream.state = GLOBUS_GRAM_STREAM_NONE;
    }

    while (monitor.pid_count > 0 ||
           (monitor.output_stream.state != GLOBUS_GRAM_STREAM_NONE &&
            monitor.output_stream.state != GLOBUS_GRAM_STREAM_DONE &&
            monitor.output_stream.state != GLOBUS_GRAM_STREAM_FAIL) ||
           (monitor.error_stream.state != GLOBUS_GRAM_STREAM_NONE &&
            monitor.error_stream.state != GLOBUS_GRAM_STREAM_DONE &&
            monitor.error_stream.state != GLOBUS_GRAM_STREAM_FAIL))
    {
        globus_cond_wait(&monitor.cond, &monitor.mutex);
    }
    if (monitor.output_stream.state == GLOBUS_GRAM_STREAM_DONE)
    {
        printf("%s %s\n",
               monitor.output_stream.source,
               monitor.output_stream.destination);
    }
    if (monitor.error_stream.state == GLOBUS_GRAM_STREAM_DONE)
    {
        printf("%s %s\n",
               monitor.error_stream.source,
               monitor.error_stream.destination);
    }
    globus_mutex_unlock(&monitor.mutex);
    globus_module_deactivate(GLOBUS_GASS_TRANSFER_MODULE);
    globus_module_activate(GLOBUS_COMMON_MODULE);

    exit(EXIT_SUCCESS);
}
void
globus_i_gsc_event_start_perf_restart(
    globus_i_gsc_op_t *                 op)
{
    globus_result_t                     res;
    globus_reltime_t                    delay;
    globus_i_gsc_event_data_t *         event;

    event = &op->event;

    if(op->type != GLOBUS_L_GSC_OP_TYPE_RECV && op->type != GLOBUS_L_GSC_OP_TYPE_SEND)
    {
        return;
    }

    /* performance markers */
    if(((op->type == GLOBUS_L_GSC_OP_TYPE_RECV && 
            op->server_handle->opts.perf_frequency > 0) || 
        (op->type == GLOBUS_L_GSC_OP_TYPE_SEND && 
            op->server_handle->opts.retr_perf_frequency > 0)) &&
        event->event_mask & GLOBUS_GRIDFTP_SERVER_CONTROL_EVENT_PERF)
    {
        event->stripe_count = op->server_handle->stripe_count;
        event->stripe_total = (globus_off_t *)globus_calloc(
            sizeof(globus_off_t) * event->stripe_count, 1);

        /* register periodic for events */
        if(op->type == GLOBUS_L_GSC_OP_TYPE_SEND)
        {
            GlobusTimeReltimeSet(
                delay, op->server_handle->opts.retr_perf_frequency, 0);
        }
        else
        {
            GlobusTimeReltimeSet(
                delay, op->server_handle->opts.perf_frequency, 0);
        }
        event->perf_running = GLOBUS_TRUE;
        res = globus_callback_register_periodic(
            &event->periodic_handle,
            &delay,
            &delay,
            globus_l_gsc_send_perf_marker_cb,
            op);
        if(res != GLOBUS_SUCCESS)
        {
            globus_panic(&globus_i_gsc_module, res, "one shot failed.");
        }
    }

    /* restart markers */
    if(op->server_handle->opts.restart_frequency > 0 &&
        event->event_mask & GLOBUS_GRIDFTP_SERVER_CONTROL_EVENT_RESTART &&
        op->type == GLOBUS_L_GSC_OP_TYPE_RECV)
    {
        GlobusTimeReltimeSet(
            delay, op->server_handle->opts.restart_frequency, 0);
        event->restart_running = GLOBUS_TRUE;
        res = globus_callback_register_periodic(
            &event->restart_handle,
            &delay,
            &delay,
            globus_l_gsc_send_restart_marker_cb,
            op);
        if(res != GLOBUS_SUCCESS)
        {
            globus_panic(&globus_i_gsc_module, res, "one shot failed.");
        }
    }
}
void
test_parse_args(int argc,
		char **argv,
		globus_ftp_client_handleattr_t * handle_attr,
		globus_ftp_client_operationattr_t * operation_attr,
		char **src,
		char **dst)
{
    int c;
    extern char * optarg;
    extern int opterr;
    globus_reltime_t timeout;
    globus_ftp_client_plugin_t *plugin;
    globus_ftp_control_dcau_t dcau;
    globus_abstime_t deadline_time;
    globus_reltime_t interval_time;
    int max_retries;
    long interval;
    long deadline;
    char * subject;

    *src = GLOBUS_NULL;
    *dst = GLOBUS_NULL;

    setvbuf(stdout, 0, _IONBF, 0);
    
#ifdef WIN32
    _setmode(_fileno(stdin), _O_BINARY);
    _setmode(_fileno(stdout), _O_BINARY);
    _setmode(_fileno(stderr), _O_BINARY);
#endif

    opterr = 0;
    while((c = getopt(argc, argv, "-f:a:ps:d:r:zMTc:t:i")) != -1)
    {
	switch(c)
	{
	case 'a':
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_ABORT_PLUGIN_MODULE);

	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_ftp_client_test_abort_plugin_init(plugin);


	    if(atoi(optarg) >= FTP_ABORT_LAST ||
	       atoi(optarg) < 0)
	    {
		printf("Abort plugin argument out of range\n");
		globus_module_deactivate_all();
		exit(1);
	    }
	    globus_ftp_client_test_abort_plugin_set_abort_point(plugin,
							        atoi(optarg));

	    globus_ftp_client_test_abort_plugin_set_abort_counter(
		plugin,
		&test_abort_count);

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;
	case 'p':
	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_module_activate(GLOBUS_FTP_CLIENT_DEBUG_PLUGIN_MODULE);
	    globus_ftp_client_debug_plugin_init(plugin, stderr, "[Debug Plugin]");

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;
	case 'M':
	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_PERF_PLUGIN_MODULE);
	    globus_ftp_client_test_perf_plugin_init(plugin);

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;
	case 'T':
	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_THROUGHPUT_PLUGIN_MODULE);
	    globus_ftp_client_test_throughput_plugin_init(plugin);

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;

	case 'z':
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_PAUSE_PLUGIN_MODULE);

	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_ftp_client_test_pause_plugin_init(plugin);

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;
	case 'r':
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_RESTART_PLUGIN_MODULE);
	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_ftp_client_test_restart_plugin_init(plugin);
	    if(atoi(optarg) >= FTP_RESTART_LAST ||
	       atoi(optarg) < 0)
	    {
		printf("Restart plugin argument out of range\n");
		globus_module_deactivate_all();
		exit(1);
	    }
	    else
	    {
		char *p;
		p = strchr(optarg, ',');
		if(p)
		{
		    GlobusTimeReltimeSet(timeout, atoi(p+1),0);
		}
		else
		{
		    GlobusTimeReltimeSet(timeout, 0, 0);
		}
		globus_ftp_client_test_restart_plugin_set_restart_point(
		    plugin,
		    atoi(optarg),
		    &timeout);
		globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);
	    }

	    break;
	case 's':
	    *src = optarg;
	    break;
	case 'd':
	    *dst = optarg;
	    break;
	case 'c':
	    if(!strcmp(optarg, "none"))
	    {
		dcau.mode = GLOBUS_FTP_CONTROL_DCAU_NONE;
		globus_ftp_client_operationattr_set_dcau(operation_attr,
							  &dcau);
	    }
	    else if(!strcmp(optarg, "self"))
	    {
		dcau.mode = GLOBUS_FTP_CONTROL_DCAU_SELF;
		globus_ftp_client_operationattr_set_dcau(operation_attr,
							  &dcau);
	    }
	    else
	    {
		dcau.mode = GLOBUS_FTP_CONTROL_DCAU_SUBJECT;
		dcau.subject.subject = optarg;
		globus_ftp_client_operationattr_set_dcau(operation_attr,
							  &dcau);
	    }
	    break;
	case 't':
	    if(!strcmp(optarg, "clear"))
	    {
		globus_ftp_client_operationattr_set_data_protection(
			operation_attr,
			GLOBUS_FTP_CONTROL_PROTECTION_CLEAR);
	    }
	    else if(!strcmp(optarg, "safe"))
	    {
		globus_ftp_client_operationattr_set_data_protection(
			operation_attr,
			GLOBUS_FTP_CONTROL_PROTECTION_SAFE);
	    }
	    else if(!strcmp(optarg, "private"))
	    {
		globus_ftp_client_operationattr_set_data_protection(
			operation_attr,
			GLOBUS_FTP_CONTROL_PROTECTION_PRIVATE);
	    }
	    break;
	case 'f':
	    globus_module_activate(GLOBUS_FTP_CLIENT_RESTART_PLUGIN_MODULE);
	    sscanf(optarg, "%d,%ld,%ld", &max_retries, &interval, &deadline);

	    if(interval < 0.1)
	    {
		GlobusTimeReltimeSet(interval_time, 0, 0);
	    }
	    else
	    {
		GlobusTimeReltimeSet(interval_time, interval, 0);
	    }
	    deadline_time.tv_sec = deadline;
	    deadline_time.tv_nsec = 0;

	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_ftp_client_restart_plugin_init(plugin,
		                                  max_retries,
		                                  &interval_time,
						  &deadline_time);
	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);
	    break;

	case 'i':
	    globus_ftp_client_operationattr_set_control_protection(
			operation_attr,
			GLOBUS_FTP_CONTROL_PROTECTION_SAFE);
	    break;
	case '?':
        /*  globus_module_deactivate_all();
	    exit(0); 
	*/
	    break;
	}
    }
    
    subject = globus_libc_getenv("GLOBUS_FTP_CLIENT_TEST_SUBJECT");
    if(subject)
    {
        globus_ftp_client_operationattr_set_authorization(
            operation_attr,
            GSS_C_NO_CREDENTIAL,
            ":globus-mapping:",
            "",
            GLOBUS_NULL,
            subject);
    }
}
예제 #14
0
int
timeout_main(
    int                                     argc,
    char **                                 argv)
{
    int                                     rc;
    globus_xio_stack_t                      stack;
    globus_xio_handle_t                     handle;
    globus_result_t                         res;
    globus_xio_attr_t                       attr;
    int                                     secs;
    int                                     usecs;
    globus_reltime_t                        delay;
    int                                     div = 5;

    globus_l_closed = GLOBUS_FALSE;
    globus_l_timeout = GLOBUS_TRUE;

    rc = globus_module_activate(GLOBUS_XIO_MODULE);
    globus_assert(rc == 0);

    res = globus_xio_attr_init(&attr);
    test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);

    res = globus_xio_stack_init(&stack, NULL);
    test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);

    parse_parameters(argc, argv, stack, attr);

    GlobusTimeReltimeGet(globus_l_test_info.delay, secs, usecs);

    if(secs == 0 && usecs < USEC_THRESHHOLD)
    {
        fprintf(stderr, "ERROR: delay time must be at least %d usecs.\n",
            USEC_THRESHHOLD);
        return 1;
    }

    GlobusTimeReltimeSet(delay, secs/div, usecs/div);
    /* set up timeouts */
    if(strcmp(argv[argc-1], "O") == 0)
    {
        res = globus_xio_attr_cntl(attr, NULL, 
                    GLOBUS_XIO_ATTR_SET_TIMEOUT_OPEN,
                    timeout_cb,
                    &delay,
                    NULL);
    }
    else if(strcmp(argv[argc-1], "D") == 0)
    {
        res = globus_xio_attr_cntl(attr, NULL,
                    GLOBUS_XIO_ATTR_SET_TIMEOUT_READ,
                    timeout_cb,
                    &delay,
                    NULL);
        res = globus_xio_attr_cntl(attr, NULL, 
                    GLOBUS_XIO_ATTR_SET_TIMEOUT_WRITE,
                    timeout_cb,
                    &delay,
                    NULL);
    }
    else if(strcmp(argv[argc-1], "C") == 0)
    {
        res = globus_xio_attr_cntl(attr, NULL, 
                    GLOBUS_XIO_ATTR_SET_TIMEOUT_CLOSE,
                    timeout_cb,
                    &delay,
                    NULL);
    }
    else
    {
        fprintf(stderr, "ERROR: No timeout registered.\n");
        return 1;
    }
    test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);

    globus_mutex_init(&globus_l_mutex, NULL);
    globus_cond_init(&globus_l_cond, NULL);

    res = globus_xio_handle_create(&handle, stack);
    test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);

    res = globus_xio_register_open(
            handle,
            "whatever",
            attr,
            open_cb,
            argv[argc-1]);
    test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);

    globus_mutex_lock(&globus_l_mutex);
    {
        while(!globus_l_closed)
        {
            globus_cond_wait(&globus_l_cond, &globus_l_mutex);
        }
    }
    globus_mutex_unlock(&globus_l_mutex);

    /* run again with an ignored time out */
    globus_l_closed = GLOBUS_FALSE;
    globus_l_timeout = GLOBUS_FALSE;

    res = globus_xio_handle_create(&handle, stack);
    test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);

    res = globus_xio_register_open(
            handle,
            "whatever",
            attr,
            open_cb,
            argv[argc-1]);
    test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);

    globus_mutex_lock(&globus_l_mutex);
    {
        while(!globus_l_closed)
        {
            globus_cond_wait(&globus_l_cond, &globus_l_mutex);
        }
    }
    globus_mutex_unlock(&globus_l_mutex);

    /* shut it down */
    globus_xio_attr_destroy(attr);
    globus_xio_stack_destroy(stack);
 
    test_common_end();

    rc = globus_module_deactivate(GLOBUS_XIO_MODULE);
    globus_assert(rc == 0);

    fprintf(stdout, "Success.\n");

    return 0;
}
예제 #15
0
/*************************************************************************
 *  start
 *  -----
 *  This function is called when a new session is initialized, ie a user 
 *  connects to the server.  This hook gives the dsi an opportunity to
 *  set internal state that will be threaded through to all other
 *  function calls associated with this session.  And an opportunity to
 *  reject the user.
 *
 *  finished_info.info.session.session_arg should be set to an DSI
 *  defined data structure.  This pointer will be passed as the void *
 *  user_arg parameter to all other interface functions.
 * 
 *  NOTE: at nice wrapper function should exist that hides the details 
 *        of the finished_info structure, but it currently does not.  
 *        The DSI developer should jsut follow this template for now
 ************************************************************************/
static
void
globus_l_dsi_rest_start(
    globus_gfs_operation_t              op,
    globus_gfs_session_info_t *         session_info)
{
    globus_l_dsi_rest_handle_t         *dsi_rest_handle;
    globus_result_t                     result = GLOBUS_SUCCESS;

    dsi_rest_handle = malloc(sizeof(globus_l_dsi_rest_handle_t));
    if (dsi_rest_handle == NULL)
    {
        result = GlobusGFSErrorMemory("dsi_rest_handle");
        goto handle_malloc_fail;
    }

    result = globus_xio_driver_load("tcp", &dsi_rest_handle->tcp_driver);
    if (result != GLOBUS_SUCCESS)
    {
        goto tcp_load_fail;
    }
    result = globus_xio_driver_load("http", &dsi_rest_handle->http_driver);
    if (result != GLOBUS_SUCCESS)
    {
        goto http_load_fail;
    }
    result = globus_xio_stack_init(&dsi_rest_handle->server_stack, NULL);
    if (result != GLOBUS_SUCCESS)
    {
        goto stack_init_fail;
    }

    globus_mutex_init(&dsi_rest_handle->mutex, NULL);
    globus_cond_init(&dsi_rest_handle->cond, NULL);

    dsi_rest_handle->terminate = false;
    dsi_rest_handle->terminate_complete = false;

    result = globus_xio_stack_push_driver(
            dsi_rest_handle->server_stack,
            dsi_rest_handle->tcp_driver);
    if (result != GLOBUS_SUCCESS)
    {
        goto stack_push_fail;
    }
    result = globus_xio_stack_push_driver(
            dsi_rest_handle->server_stack,
            dsi_rest_handle->http_driver);
    if (result != GLOBUS_SUCCESS)
    {
        goto stack_push_fail;
    }
    globus_xio_attr_t attr;
    result = globus_xio_attr_init(&attr);

    globus_reltime_t delay;
    GlobusTimeReltimeSet(delay, 1,0);

    result = globus_xio_attr_cntl(
            attr,
            NULL,
            GLOBUS_XIO_ATTR_SET_TIMEOUT_ACCEPT,
            NULL,
            &delay,
            NULL);

    result = globus_xio_server_create(
            &dsi_rest_handle->xio_server,
            attr,
            dsi_rest_handle->server_stack);
    if (result != GLOBUS_SUCCESS)
    {
        goto server_create_fail;
    }
    result = globus_xio_server_get_contact_string(
            dsi_rest_handle->xio_server,
            &dsi_rest_handle->contact_string);
    if (result != GLOBUS_SUCCESS)
    {
        goto get_contact_fail;
    }
    globus_gridftp_server_get_config_string(
            op,
            &dsi_rest_handle->root);
    if (dsi_rest_handle->root == NULL)
    {
        result = GlobusGFSErrorMemory("root");
        goto get_root_fail;
    }
    globus_thread_create(
            &dsi_rest_handle->server_thread,
            NULL,
            globus_l_dsi_rest_thread,
            dsi_rest_handle);

    if (result != GLOBUS_SUCCESS)
    {
get_root_fail:
        free(dsi_rest_handle->contact_string);
get_contact_fail:
        globus_xio_server_close(dsi_rest_handle->xio_server);
server_create_fail:
stack_push_fail:
        globus_xio_stack_destroy(dsi_rest_handle->server_stack);
stack_init_fail:
        globus_xio_driver_unload(dsi_rest_handle->http_driver);
http_load_fail:
        globus_xio_driver_unload(dsi_rest_handle->tcp_driver);
tcp_load_fail:
handle_malloc_fail:
        free(dsi_rest_handle);
        dsi_rest_handle = NULL;
    }

    globus_gridftp_server_finished_session_start(
            op,
            result,
            dsi_rest_handle,
            NULL,
            NULL);
}