Пример #1
0
int flom_init_check(void)
{
    int mutex_locked = FALSE;
    int ret_cod = FLOM_RC_OK;
    
    /* initialize only if not already initialized! */
    if (!flom_init_flag) {
        /* this is a synchronization hole... see below */
        /* synchronize this critical section */
        g_static_mutex_lock(&flom_init_mutex);
        mutex_locked = TRUE;
        /* dummy loop, necessary because I need break instruction ;) */
        while (TRUE) {
            /* stop if another thread performed initialization in the
               during synchronization hole (unlikely but not impossible) */
            if (flom_init_flag)
                break;
            /* initialize trace component */
            FLOM_TRACE_INIT;
            /* initialize regular expression table */
            if (FLOM_RC_OK != (ret_cod = global_res_name_preg_init()))
                break;
            /* reset global configuration */
            flom_config_reset(NULL);
            /* initialize configuration with standard system, standard
               user and user customized config files */
            if (FLOM_RC_OK != (ret_cod = flom_config_init(NULL, NULL)))
                break;
            if (NULL != flom_config_get_command_trace_file(NULL))
                /* change trace destination if necessary */
                FLOM_TRACE_REOPEN(flom_config_get_command_trace_file(NULL),
                                  flom_config_get_append_trace_file(NULL));
            /* check configuration */
            if (FLOM_RC_OK != (ret_cod = flom_config_check(NULL)))
                break;
            /* initialization completed */
            flom_init_flag = TRUE;
            /* exit loop after exactly one cycle */
            break; 
        } /* while (TRUE) */

    } /* if (!flom_init_flag) */
    
    if (mutex_locked)
        g_static_mutex_unlock(&flom_init_mutex);
    return ret_cod;
}
Пример #2
0
int main (int argc, char *argv[])
{
    GError *error = NULL;
    GOptionContext *option_context;
    int child_status = 0;
    int ret_cod = FLOM_RC_INTERNAL_ERROR;
    struct flom_conn_data_s cd;
    char locked_element[100];

    option_context = g_option_context_new("[-- command to execute]");
    g_option_context_add_main_entries(option_context, entries, NULL);
    if (!g_option_context_parse(option_context, &argc, &argv, &error)) {
        g_print("option parsing failed: %s\n", error->message);
        exit(FLOM_ES_GENERIC_ERROR);
    }
    g_option_context_free(option_context);

    if (print_version) {
        g_print("FLoM: Free LOck Manager\n"
                "Copyright (c) 2013-2014, Christian Ferrari; "
                "all rights reserved.\n"
                "License: GPL (GNU Public License) version 2\n"
                "Package name: %s; package version: %s; release date: %s\n"
                "Access http://sourceforge.net/projects/flom/ for "
                "project community activities\n",
                FLOM_PACKAGE_NAME, FLOM_PACKAGE_VERSION, FLOM_PACKAGE_DATE);
        exit(FLOM_ES_OK);
    }

    /* initialize trace destination if necessary */
    FLOM_TRACE_INIT;
    
    /* initialize regular expression table */
    if (FLOM_RC_OK != (ret_cod = global_res_name_preg_init())) {
        g_print("global_res_name_preg_init: ret_cod=%d\n", ret_cod);
        exit(FLOM_ES_GENERIC_ERROR);
    }

    /* reset global configuration */
    flom_config_reset(NULL);
    /* initialize configuration with standard system, standard user and
       user customized config files */
    if (FLOM_RC_OK != (ret_cod = flom_config_init(NULL, config_file))) {
        g_print("flom_config_init: ret_cod=%d\n", ret_cod);
        exit(FLOM_ES_GENERIC_ERROR);
    }
    /* overrides configuration with command line passed arguments */
    if (NULL != daemon_trace_file)
        flom_config_set_daemon_trace_file(NULL, daemon_trace_file);
    if (NULL != command_trace_file)
        flom_config_set_command_trace_file(NULL, command_trace_file);
    if (verbose)
        flom_config_set_verbose(NULL, verbose);
    if (NULL != resource_name)
        if (FLOM_RC_OK != (ret_cod = flom_config_set_resource_name(
                               NULL, resource_name))) {
            g_print("flom_config_set_resource_name: ret_cod=%d\n", ret_cod);
            exit(FLOM_ES_GENERIC_ERROR);
        }
    if (0 > resource_quantity)
        g_warning("Resource quantity ignored because negative values (%d) "
                  "are meaningless\n", resource_quantity);
    else if (0 < resource_quantity)
        flom_config_set_resource_quantity(NULL, resource_quantity);

    if (NULL != resource_wait) {
        flom_bool_value_t fbv;
        if (FLOM_BOOL_INVALID == (
                fbv = flom_bool_value_retrieve(resource_wait))) {
            g_print("resource-wait: '%s' is an invalid value\n",
                    resource_wait);
            exit(FLOM_ES_GENERIC_ERROR);
        }
        flom_config_set_resource_wait(NULL, fbv);
    }
    if (FLOM_NETWORK_WAIT_TIMEOUT != resource_timeout) {
        /* timeout is useless if no wait was specified */
        if (FLOM_BOOL_NO == flom_config_get_resource_wait(NULL))
            g_warning("Timeout ignored because 'no wait' behavior was "
                      "specified\n");
        else
            flom_config_set_resource_timeout(NULL, resource_timeout);
    }
    if (NULL != lock_mode) {
        flom_lock_mode_t flm;
        if (FLOM_LOCK_MODE_INVALID == (
                flm = flom_lock_mode_retrieve(lock_mode))) {
            g_print("lock-mode: '%s' is an invalid value\n", lock_mode);
            exit(FLOM_ES_GENERIC_ERROR);
        }
        flom_config_set_lock_mode(NULL, flm);
    }
    if (NULL != resource_create) {
        flom_bool_value_t fbv;
        if (FLOM_BOOL_INVALID == (
                fbv = flom_bool_value_retrieve(resource_create))) {
            g_print("resource-create: '%s' is an invalid value\n",
                    resource_create);
            exit(FLOM_ES_GENERIC_ERROR);
        }
        flom_config_set_resource_create(NULL, fbv);
    }
    flom_config_set_resource_idle_lifespan(NULL, resource_idle_lifespan);
    if (NULL != socket_name) {
        if (FLOM_RC_OK != (ret_cod = flom_config_set_socket_name(
                               NULL, socket_name))) {
            g_print("socket-name: '%s' is an invalid value\n", socket_name);
            g_print("flom_client_connect: ret_cod=%d (%s)\n",
                    ret_cod, flom_strerror(ret_cod));
            exit(FLOM_ES_GENERIC_ERROR);
        }
    }
    if (_DEFAULT_DAEMON_LIFESPAN != daemon_lifespan) {
        flom_config_set_lifespan(NULL, daemon_lifespan);
    }
    if (NULL != unicast_address) {
        flom_config_set_unicast_address(NULL, unicast_address);
    }
    if (_DEFAULT_DAEMON_PORT != unicast_port) {
        flom_config_set_unicast_port(NULL, unicast_port);
    }
    if (NULL != multicast_address) {
        flom_config_set_multicast_address(NULL, multicast_address);
    }
    if (_DEFAULT_DAEMON_PORT != multicast_port) {
        flom_config_set_multicast_port(NULL, multicast_port);
    }
    if (_DEFAULT_DISCOVERY_ATTEMPTS != discovery_attempts) {
        flom_config_set_discovery_attempts(NULL, discovery_attempts);
    }
    if (_DEFAULT_DISCOVERY_TIMEOUT != discovery_timeout) {
        flom_config_set_discovery_timeout(NULL, discovery_timeout);
    }
    if (_DEFAULT_DISCOVERY_TTL != discovery_ttl) {
        flom_config_set_discovery_ttl(NULL, discovery_ttl);
    }
    if (_DEFAULT_TCP_KEEPALIVE_TIME != tcp_keepalive_time) {
        flom_config_set_tcp_keepalive_time(NULL, tcp_keepalive_time);
    }
    if (_DEFAULT_TCP_KEEPALIVE_INTVL != tcp_keepalive_intvl) {
        flom_config_set_tcp_keepalive_intvl(NULL, tcp_keepalive_intvl);
    }
    if (_DEFAULT_TCP_KEEPALIVE_PROBES != tcp_keepalive_probes) {
        flom_config_set_tcp_keepalive_probes(NULL, tcp_keepalive_probes);
    }
    if (NULL != flom_config_get_command_trace_file(NULL))
        /* change trace destination if necessary */
        FLOM_TRACE_REOPEN(flom_config_get_command_trace_file(NULL));

    /* print configuration */
    if (flom_config_get_verbose(NULL))
        flom_config_print(NULL);

    /* check configuration */
    if (FLOM_RC_OK != (ret_cod = flom_config_check(NULL))) {
        g_warning("Configuration is not valid, cannot go on!\n");
        exit(FLOM_ES_GENERIC_ERROR);        
    }

    /* check if the command is asking daemon termination */
    if (quiesce_exit || immediate_exit) {
        g_print("Starting FLoM daemon %s shutdown...\n",
                immediate_exit ? "immediate" : "quiesce");
        flom_client_shutdown(NULL, immediate_exit);
        exit(0);
    }
    
    /* check the command is not null */
    if (NULL == command_argv) {
        g_warning("No command to execute!\n");
        exit(FLOM_ES_UNABLE_TO_EXECUTE_COMMAND);        
    }

    /* open connection to a valid flom lock manager... */
    if (FLOM_RC_OK != (ret_cod = flom_client_connect(NULL, &cd, TRUE))) {
        g_print("flom_client_connect: ret_cod=%d (%s)\n",
                ret_cod, flom_strerror(ret_cod));
        exit(FLOM_ES_GENERIC_ERROR);
    }

    /* sending lock command */
    ret_cod = flom_client_lock(NULL, &cd,
                               flom_config_get_resource_timeout(NULL),
                               locked_element, sizeof(locked_element));
    switch (ret_cod) {
        case FLOM_RC_OK: /* OK, go on */
            if (flom_config_get_verbose(NULL) && '\0' != locked_element[0])
                g_print("Locked element is '%s'\n", locked_element);
            break;
        case FLOM_RC_LOCK_BUSY: /* busy */
            g_print("Resource already locked, the lock cannot be obtained\n");
            /* gracefully disconnect from daemon */
            if (FLOM_RC_OK != (ret_cod = flom_client_disconnect(&cd))) {
                g_print("flom_client_unlock: ret_cod=%d (%s)\n",
                        ret_cod, flom_strerror(ret_cod));
            }
            exit(FLOM_ES_RESOURCE_BUSY);
            break;
        case FLOM_RC_LOCK_CANT_WAIT: /* can't wait, leaving... */
            g_print("The resource could be available in the future, but the "
                    "requester can't wait\n");
            /* gracefully disconnect from daemon */
            if (FLOM_RC_OK != (ret_cod = flom_client_disconnect(&cd))) {
                g_print("flom_client_unlock: ret_cod=%d (%s)\n",
                        ret_cod, flom_strerror(ret_cod));
            }
            exit(FLOM_ES_REQUESTER_CANT_WAIT);
            break;
        case FLOM_RC_LOCK_IMPOSSIBLE: /* impossible */
            g_print("Resource will never satisfy the request, the lock "
                    "cannot be obtained\n");
            /* gracefully disconnect from daemon */
            if (FLOM_RC_OK != (ret_cod = flom_client_disconnect(&cd))) {
                g_print("flom_client_unlock: ret_cod=%d (%s)\n",
                        ret_cod, flom_strerror(ret_cod));
            }
            exit(FLOM_ES_GENERIC_ERROR);
            break;
        case FLOM_RC_NETWORK_TIMEOUT: /* timeout expired, busy resource */
            g_print("The lock was not obtained because timeout "
                    "(%d milliseconds) expired\n",
                    flom_config_get_resource_timeout(NULL));
            /* gracefully disconnect from daemon */
            if (FLOM_RC_OK != (ret_cod = flom_client_disconnect(&cd))) {
                g_print("flom_client_unlock: ret_cod=%d (%s)\n",
                        ret_cod, flom_strerror(ret_cod));
            }
            exit(FLOM_ES_RESOURCE_BUSY);
            break;            
        default:
            g_print("flom_client_lock: ret_cod=%d (%s)\n",
                    ret_cod, flom_strerror(ret_cod));
            exit(FLOM_ES_GENERIC_ERROR);
    } /* switch (ret_cod) */

    /* execute the command */
    if (FLOM_RC_OK != (ret_cod = flom_exec(command_argv, locked_element,
                                           &child_status))) {
        guint i, num;
        g_print("Unable to execute command: '");
        num = g_strv_length(command_argv);
        for (i=0; i<num; ++i)
            g_print("%s", command_argv[i]);
        g_print("'\n");
        exit(FLOM_ES_UNABLE_TO_EXECUTE_COMMAND);
    }
    
    /* sending unlock command */
    if (FLOM_RC_OK != (ret_cod = flom_client_unlock(NULL, &cd))) {
        g_print("flom_client_unlock: ret_cod=%d (%s)\n",
                ret_cod, flom_strerror(ret_cod));
        exit(FLOM_ES_GENERIC_ERROR);
    }

    /* gracefully disconnect from daemon */
    if (FLOM_RC_OK != (ret_cod = flom_client_disconnect(&cd))) {
        g_print("flom_client_unlock: ret_cod=%d (%s)\n",
                ret_cod, flom_strerror(ret_cod));
    }

    g_strfreev (command_argv);
    command_argv = NULL;

    /* release config data */
    flom_config_free(NULL);
    /* release regular expression data */
    global_res_name_preg_free();
    
	return child_status;
}