int flom_daemon_mngmnt_shutdown(flom_config_t *config, flom_conns_t *conns, guint id) { enum Exception { NONE } excp; int ret_cod = FLOM_RC_INTERNAL_ERROR; FLOM_TRACE(("flom_daemon_mngmnt_shutdown\n")); TRY { struct flom_msg_s *msg = flom_conns_get_msg(conns, id); int immediate = msg->body.mngmnt_8.action_data.shutdown.immediate; if (immediate) { FLOM_TRACE(("flom_daemon_mngmnt_shutdown: immediate shutdown, " "exiting...\n")); syslog(LOG_NOTICE, FLOM_SYSLOG_FLM007N); exit(0); } else { FLOM_TRACE(("flom_daemon_mngmnt_shutdown: quiesce shutdown in " "progress...\n")); syslog(LOG_NOTICE, FLOM_SYSLOG_FLM008N); flom_config_set_lifespan(NULL, FLOM_SHUTDOWN_QUIESCE_GRACE_TIME); } THROW(NONE); } CATCH { switch (excp) { case NONE: ret_cod = FLOM_RC_OK; break; default: ret_cod = FLOM_RC_INTERNAL_ERROR; } /* switch (excp) */ } /* TRY-CATCH */ FLOM_TRACE(("flom_daemon_mngmnt_shutdown/excp=%d/" "ret_cod=%d/errno=%d\n", excp, ret_cod, errno)); return ret_cod; }
int flom_handle_init(flom_handle_t *handle) { enum Exception { G_TRY_MALLOC_ERROR1 , G_TRY_MALLOC_ERROR2 , CONFIG_INIT_ERROR , NONE } excp; int ret_cod = FLOM_RC_INTERNAL_ERROR; /* check flom library is initialized */ if (FLOM_RC_OK != (ret_cod = flom_init_check())) return ret_cod; FLOM_TRACE(("flom_handle_init\n")); TRY { /* memory reset */ memset(handle, 0, sizeof(flom_handle_t)); /* allocate memory for connection data structure */ if (NULL == (handle->conn = g_try_malloc0( sizeof(flom_conn_t)))) THROW(G_TRY_MALLOC_ERROR1); /* allocate memory for configuration data structure */ if (NULL == (handle->config = g_try_malloc0( sizeof(flom_config_t)))) THROW(G_TRY_MALLOC_ERROR2); /* initialize config object */ if (FLOM_RC_OK != (ret_cod = flom_config_clone(handle->config))) THROW(CONFIG_INIT_ERROR); /* clients can not fork a new flom daemon: this restriction is * necessary to avoid the side effects related to daemonization that * can affect a general purpose environment... This is a CLIENT!!! */ flom_config_set_lifespan(handle->config, 0); /* state reset */ handle->state = FLOM_HANDLE_STATE_INIT; THROW(NONE); } CATCH { switch (excp) { case G_TRY_MALLOC_ERROR1: case G_TRY_MALLOC_ERROR2: ret_cod = FLOM_RC_G_TRY_MALLOC_ERROR; break; case CONFIG_INIT_ERROR: break; case NONE: ret_cod = FLOM_RC_OK; break; default: ret_cod = FLOM_RC_INTERNAL_ERROR; } /* switch (excp) */ } /* TRY-CATCH */ /* clean memory if an error occurred */ if (NONE != excp) { if (NULL != handle->config) { flom_config_free(handle->config); g_free(handle->config); handle->config = NULL; } /* if (NULL != handle->config) */ if (NULL != handle->conn) { g_free(handle->conn); handle->conn = NULL; } /* if (NULL != handle->conn) */ } /* if (NONE != excp) */ FLOM_TRACE(("flom_handle_init/excp=%d/" "ret_cod=%d/errno=%d\n", excp, ret_cod, errno)); return ret_cod; }
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; }