static void s_hup_handler(int sig) { (void)sig; if (lagopus_log_get_destination() == LAGOPUS_LOG_EMIT_TO_FILE) { lagopus_msg_info("The log file turned over.\n"); (void)lagopus_log_reinitialize(); lagopus_msg_info("The log file turned over.\n"); } }
lagopus_result_t port_config(struct bridge *bridge, struct ofp_port_mod *port_mod, struct ofp_error *error) { struct port *port; struct ofp_port *ofp_port; uint32_t oldconfig, newconfig; if (port_mod->port_no != OFPP_CONTROLLER) { port = port_lookup(&bridge->ports, port_mod->port_no); if (port == NULL) { error->type = OFPET_PORT_MOD_FAILED; error->code = OFPPMFC_BAD_PORT; lagopus_msg_info("port config: %d: no such port (%d:%d)\n", port_mod->port_no, error->type, error->code); return LAGOPUS_RESULT_OFP_ERROR; } ofp_port = &port->ofp_port; if (port->interface == NULL) { error->type = OFPET_PORT_MOD_FAILED; error->code = OFPPMFC_BAD_HW_ADDR; lagopus_msg_info("port config: %d: do not assigned interface (%d:%d)\n", port_mod->port_no, error->type, error->code); return LAGOPUS_RESULT_OFP_ERROR; } } else { port = NULL; /* XXX shut out warning */ ofp_port = &bridge->controller_port; } /* XXX write lock for thread safe */ if ((port_mod->config & (uint32_t)~port_mod->mask) != 0) { error->type = OFPET_PORT_MOD_FAILED; error->code = OFPPMFC_BAD_CONFIG; lagopus_msg_info("port config: " "config(0x%x) and mask(0x%x) inconsistency (%d:%d)\n", port_mod->config, port_mod->mask, error->type, error->code); return LAGOPUS_RESULT_OFP_ERROR; } oldconfig = ofp_port->config; newconfig = oldconfig; newconfig &= (uint32_t)~port_mod->mask; newconfig |= port_mod->config; ofp_port->config = newconfig; /* advertise, depend on lower driver */ if ((oldconfig != newconfig || ofp_port->advertised != port_mod->advertise) && port_mod->port_no != OFPP_CONTROLLER) { ofp_port->advertised = port_mod->advertise; lagopus_change_physical_port(port); } /* XXX unlock */ return LAGOPUS_RESULT_OK; }
/* Add a new bridge. */ lagopus_result_t bridge_add(struct bridge_list *bridge_list, const char *name, uint64_t dpid) { struct bridge *bridge; /* Find bridge. */ bridge = bridge_lookup(bridge_list, name); if (bridge != NULL) { return LAGOPUS_RESULT_ALREADY_EXISTS; } /* Allocate a new bridge. */ bridge = bridge_alloc(name); if (bridge == NULL) { return LAGOPUS_RESULT_NO_MEMORY; } /* If given dpid is zero, generate random dpid value. */ if (dpid == 0) { dpid = bridge_dpid_generate(); } bridge->dpid = dpid; flowdb_wrlock(NULL); TAILQ_INSERT_TAIL(bridge_list, bridge, entry); flowdb_wrunlock(NULL); lagopus_msg_info("Bridge %s dpid:%0" PRIx64 " is added\n", name, dpid); return LAGOPUS_RESULT_OK; }
lagopus_result_t snmpmgr_start(void) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; (void)lagopus_mutex_lock(&snmp_state_lock); if (state == SNMPMGR_RUNNABLE) { if (is_thread == false) { state = SNMPMGR_RUNNING; (void)lagopus_mutex_unlock(&snmp_state_lock); /* open the session to AgentX master agent here. */ init_snmp(SNMP_TYPE); /* send_*_trap always return SNMP_ERR_NOERROR */ (void)send_coldStart_trap(); ret = LAGOPUS_RESULT_OK; lagopus_msg_info("SNMP manager started.\n"); } else { /* Note: * If is_thread is true, init_snmp and send_coldStart_trap * are called inside snmpmgr_thread_loop */ (void)lagopus_mutex_unlock(&snmp_state_lock); ret = lagopus_thread_start(&snmpmgr, false); } } else { (void)lagopus_mutex_unlock(&snmp_state_lock); ret = LAGOPUS_RESULT_NOT_STARTED; } return ret; }
static inline void s_shutdown(shutdown_grace_level_t level) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; if ((ret = global_state_request_shutdown(level)) == LAGOPUS_RESULT_OK) { lagopus_msg_info("The shutdown request accepted.\n"); } else { lagopus_perror(ret); lagopus_msg_error("Can't request shutdown.\n"); } }
static lagopus_result_t snmpmgr_thread_loop(const lagopus_thread_t *selfptr, void *arg) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; lagopus_chrono_t interval = DEFAULT_SNMPMGR_LOOP_INTERVAL_NSEC; global_state_t global_state; shutdown_grace_level_t l; (void)selfptr; (void)arg; /* open the session to AgentX master agent here. */ init_snmp(SNMP_TYPE); /* wait all modules start */ if ((ret = global_state_wait_for(GLOBAL_STATE_STARTED, &global_state, &l, -1 /* forever! */)) != LAGOPUS_RESULT_OK) { lagopus_perror(ret); } else { if (global_state != GLOBAL_STATE_STARTED) { lagopus_exit_fatal("must not happen. die!\n"); } } /* all modules have started, then send a coldStart trap */ (void)send_coldStart_trap(); lagopus_msg_info("SNMP manager started (as a thread).\n"); /* main loop */ while (keep_running) { (void)lagopus_mutex_lock(&snmp_lock); ret = internal_snmpmgr_poll(interval); (void)lagopus_mutex_unlock(&snmp_lock); if (ret != LAGOPUS_RESULT_OK && ret != LAGOPUS_RESULT_TIMEDOUT) { lagopus_msg_warning("failed to poll SNMP AgentX request: %s", lagopus_error_get_string(ret)); } check_status_and_send_traps(); } /* stop SNMP */ snmp_shutdown(SNMP_TYPE); (void)lagopus_mutex_lock(&snmp_state_lock); if (state != SNMPMGR_RUNNABLE) { state = SNMPMGR_NONE; } (void)lagopus_mutex_unlock(&snmp_state_lock); return LAGOPUS_RESULT_OK; }
static void app_lcore_io_tx_cleanup(struct app_lcore_params_io *lp) { unsigned i; for (i = 0; i < lp->tx.n_nic_ports; i ++) { uint8_t portid = lp->tx.nic_ports[i]; /* Flush TX and RX queues. */ lagopus_msg_info("Cleanup physical port %u\n", portid); rte_eth_dev_stop(portid); rte_eth_dev_close(portid); } }
lagopus_result_t load_conf_initialize(int argc, const char *const argv[], void *extarg, lagopus_thread_t **retptr) { (void) argc; (void) argv; (void) extarg; (void) retptr; lagopus_msg_info("load_conf_initiaize.\n"); pthread_once(&initialized, initialize_internal); return LAGOPUS_RESULT_OK; }
static void s_term_handler(int sig) { lagopus_result_t r = LAGOPUS_RESULT_ANY_FAILURES; global_state_t gs = GLOBAL_STATE_UNKNOWN; if ((r = global_state_get(&gs)) == LAGOPUS_RESULT_OK) { if ((int)gs == (int)GLOBAL_STATE_STARTED) { shutdown_grace_level_t l = SHUTDOWN_UNKNOWN; if (sig == SIGTERM || sig == SIGINT) { l = SHUTDOWN_GRACEFULLY; } else if (sig == SIGQUIT) { l = SHUTDOWN_RIGHT_NOW; } if (IS_VALID_SHUTDOWN(l) == true) { lagopus_msg_info("About to request shutdown(%s)...\n", (l == SHUTDOWN_RIGHT_NOW) ? "RIGHT_NOW" : "GRACEFULLY"); if ((r = global_state_request_shutdown(l)) == LAGOPUS_RESULT_OK) { lagopus_msg_info("The shutdown request accepted.\n"); } else { lagopus_perror(r); lagopus_msg_error("can't request shutdown.\n"); } } } else if ((int)gs < (int)GLOBAL_STATE_STARTED) { if (sig == SIGTERM || sig == SIGINT || sig == SIGQUIT) { s_got_term_sig = true; } } else { lagopus_msg_debug(5, "The system is already shutting down.\n"); } } }
static int check_cert_chain(const SSL *ssl) { int ret = -1; char *issuer = NULL, *subject = NULL; X509 *peer = NULL; if (SSL_get_verify_result(ssl) != X509_V_OK) { lagopus_msg_warning("SSL_get_verify_result() failed.\n"); return -1; } peer = SSL_get_peer_certificate(ssl); if (peer == NULL) { lagopus_msg_warning("SSL_get_peer_certificate() failed.\n"); return -1; } issuer = X509_NAME_oneline(X509_get_issuer_name(peer), NULL, 0); if (issuer == NULL) { lagopus_msg_warning("no memory, get_issuer_name failed.\n"); ret = -1; goto done; } subject = X509_NAME_oneline(X509_get_subject_name(peer), NULL, 0); if (issuer == NULL) { lagopus_msg_warning("no memory, get_subject_name failed.\n"); ret = -1; goto done; } if (check_certificates != NULL) { if (check_certificates(issuer, subject) == LAGOPUS_RESULT_OK) { ret = 0; } else { ret = -1; } lagopus_msg_info("issuer:[%s], subject:[%s] ret: %d\n", issuer, subject, ret); } else { lagopus_msg_warning("check_certificates function is null.\n"); } done: free(issuer); free(subject); X509_free(peer); return ret; }
lagopus_result_t dp_thread_shutdown(lagopus_thread_t *threadptr, lagopus_mutex_t *lockptr, bool *runptr, shutdown_grace_level_t level) { bool is_valid = false; lagopus_chrono_t nsec; lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; lagopus_msg_info("shutdown called\n"); lagopus_mutex_lock(lockptr); if (*runptr == false) { goto done; } ret = lagopus_thread_is_valid(threadptr, &is_valid); if (ret != LAGOPUS_RESULT_OK || is_valid == false) { lagopus_perror(ret); goto done; } /* XXX UP TO main() */ switch (level) { case SHUTDOWN_RIGHT_NOW: nsec = TIMEOUT_SHUTDOWN_RIGHT_NOW; break; case SHUTDOWN_GRACEFULLY: nsec = TIMEOUT_SHUTDOWN_GRACEFULLY; break; default: lagopus_msg_fatal("unknown shutdown level %d\n", level); ret = LAGOPUS_RESULT_ANY_FAILURES; goto done; } *runptr = false; ret = lagopus_thread_wait(threadptr, nsec); if (ret != LAGOPUS_RESULT_OK) { lagopus_perror(ret); goto done; } done: lagopus_mutex_unlock(lockptr); return ret; }
void dp_finalproc(const lagopus_thread_t *t, bool is_canceled, void *arg) { bool is_valid = false; struct dataplane_arg *dparg; lagopus_result_t ret; (void) is_canceled; dparg = arg; lagopus_msg_info("finalproc in %p\n", *dparg->threadptr); if (*t != *dparg->threadptr) { lagopus_exit_fatal("other threads worked t:%p, my_thread:%p\n", *t, *dparg->threadptr); } ret = lagopus_thread_is_valid(dparg->threadptr, &is_valid); if (ret != LAGOPUS_RESULT_OK || is_valid == false) { lagopus_perror(ret); return; } }
static lagopus_result_t ofp_role_write(struct channel *channel, void *val) { struct role_write_vars *v = val; if (channel_is_alive(channel) == true) { /* packet filtering. */ if (channel_role_channel_check_mask(channel, v->type, v->reason) == true) { v->ret = ofp_write_channel(channel, v->pbuf); } else { /* Not send packet. */ v->ret = LAGOPUS_RESULT_OK; } } else { lagopus_msg_info("Channel is not alive, drop asynchronous message(%s)\n", ofp_type_str(v->type)); /* Not send packet. */ v->ret = LAGOPUS_RESULT_OK; } return LAGOPUS_RESULT_OK; }
static SSL_CTX *get_ssl_ctx(char *ca_dir, char *cert, char *key) { SSL_CTX *ssl_ctx; const SSL_METHOD *method; lagopus_msg_info("ca_dir:[%s], cert:[%s], key:[%s]\n", ca_dir, cert, key); method = TLSv1_method(); ssl_ctx = SSL_CTX_new(method); if (ssl_ctx == NULL) { lagopus_msg_warning("no memory.\n"); return NULL; } /* add client cert. */ if (SSL_CTX_use_certificate_file(ssl_ctx, cert, SSL_FILETYPE_PEM) != 1) { lagopus_msg_warning("SSL_CTX_use_certificate_file(%s) fail.\n", cert); SSL_CTX_free(ssl_ctx); return NULL; } /* add client private key. */ if (SSL_CTX_use_PrivateKey_file(ssl_ctx, key, SSL_FILETYPE_PEM) != 1) { lagopus_msg_warning("SSL_CTX_use_PrivateKey_file(%s) fail.\n", key); SSL_CTX_free(ssl_ctx); return NULL; } /* loading ca cert */ if (SSL_CTX_load_verify_locations(ssl_ctx, NULL, ca_dir) != 1) { lagopus_msg_warning("SSL_CTX_load_verify_locations(%s) fail.\n", ca_dir); SSL_CTX_free(ssl_ctx); return NULL; } SSL_CTX_set_verify_depth(ssl_ctx, 1);/* XXX depth is configurable? */ SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback); return ssl_ctx; }
lagopus_result_t lagopus_get_port_statistics(lagopus_hashmap_t *hm, struct ofp_port_stats_request *request, struct port_stats_list *list, struct ofp_error *error) { struct port *port; if (request->port_no == OFPP_ANY) { lagopus_hashmap_iterate(hm, port_do_stats_iterate, list); } else { if (lagopus_hashmap_find(hm, (void *)request->port_no, &port) != LAGOPUS_RESULT_OK) { error->type = OFPET_BAD_REQUEST; error->code = OFPBRC_BAD_PORT; lagopus_msg_info("port stats: %d: no such port (%d:%d)\n", request->port_no, error->type, error->code); return LAGOPUS_RESULT_OFP_ERROR; } port_add_stats(port, list); } return LAGOPUS_RESULT_OK; }
void dp_freeproc(const lagopus_thread_t *t, void *arg) { bool is_valid = false; struct dataplane_arg *dparg; lagopus_result_t ret; dparg = arg; lagopus_msg_info("freeproc in\n"); if (*t != *dparg->threadptr) { lagopus_exit_fatal("other threads worked %p, %p", *t, *dparg->threadptr); } ret = lagopus_thread_is_valid(dparg->threadptr, &is_valid); if (ret != LAGOPUS_RESULT_OK || is_valid == false) { lagopus_perror(ret); return; } /* ADD delete ports? */ lagopus_mutex_destroy(dparg->lock); *dparg->lock = NULL; }
lagopus_result_t ofp_role_channel_write(struct pbuf *pbuf, uint64_t dpid, uint8_t type, uint8_t reason) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; if (pbuf != NULL) { struct role_write_vars v; v.type = type; v.reason = reason; v.pbuf = pbuf; v.ret = LAGOPUS_RESULT_ANY_FAILURES; ret = channel_mgr_dpid_iterate(dpid, ofp_role_write, (void *) &v); if (ret != LAGOPUS_RESULT_OK) { if (ret == LAGOPUS_RESULT_NOT_OPERATIONAL || ret == LAGOPUS_RESULT_NOT_FOUND) { lagopus_msg_info("Channel is not alive, drop asynchronous message(%s)\n", ofp_type_str(v.type)); /* Not send packet. */ ret = LAGOPUS_RESULT_OK; } else { ret = v.ret; } } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } if (ret == LAGOPUS_RESULT_OK && pbuf != NULL) { /* move getp to putp. */ pbuf_getp_set(pbuf, pbuf_putp_get(pbuf)); } return ret; }
static void initialize_internal(void) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; void *logger_client_arg = NULL; char *master_agentx_socket = NULL; char *ping_interval_string = NULL; uint16_t ping_interval = 0; state = SNMPMGR_NONE; /* `is_thread` is able to be changed only once here */ is_thread = is_thread_dummy; if (is_thread == false && thdptr_dummy != NULL) { *thdptr_dummy = NULL; } else if (thdptr_dummy != NULL) { *thdptr_dummy = &snmpmgr; } else { /* never reached! */ return; } if (lagopus_mutex_create(&snmp_lock) != LAGOPUS_RESULT_OK) { return; } if (lagopus_mutex_create(&snmp_state_lock) != LAGOPUS_RESULT_OK) { return; } snmp_set_do_debugging(false); /* setup Net-SNMP logger to use the lagopus logging function */ if (snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_LOGGING, snmp_log_callback_wrapper, logger_client_arg) != SNMPERR_SUCCESS) { return; } snmp_enable_calllog(); /* setup the SNMP module to be Agentx subagent */ netsnmp_enable_subagent(); #ifdef THE_CONFSYS_ERA master_agentx_socket = config_get("snmp master-agentx-socket WORD"); if (master_agentx_socket == NULL) { config_set_default("snmp master-agentx-socket WORD", (char *)DEFAULT_SNMPMGR_AGENTX_SOCKET); master_agentx_socket = config_get("snmp master-agentx-socket WORD"); } #else /* * FIXME: * Fetch it from the datastore. */ master_agentx_socket = (char *)DEFAULT_SNMPMGR_AGENTX_SOCKET; #endif /* THE_CONFSYS_ERA */ lagopus_msg_debug(25, "master agentx socket is %s\n", master_agentx_socket); if (netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, master_agentx_socket) != SNMPERR_SUCCESS) { initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR; return; } /* don't read/write configuration files */ if (netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_PERSIST_STATE, true) != SNMPERR_SUCCESS) { initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR; return; } if (netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DISABLE_PERSISTENT_LOAD, true) != SNMPERR_SUCCESS) { initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR; return; } /* the interval [sec] to send ping to AgentX master agent */ #ifdef THE_CONFSYS_ERA ping_interval_string = config_get("snmp ping-interval-second 1-255"); if (ping_interval_string != NULL && (ret = check_ping_interval(ping_interval_string, &ping_interval)) != LAGOPUS_RESULT_OK) { config_set_default("snmp ping-interval-second 1-255", (char *) __STR__(DEFAULT_SNMPMGR_AGENTX_PING_INTERVAL_SEC)); ping_interval_string = config_get("snmp ping-interval-second 1-255"); ping_interval = DEFAULT_SNMPMGR_AGENTX_PING_INTERVAL_SEC; /* default value */ } #else /* * FIXME: * Fetch it from the datastore. */ ping_interval = DEFAULT_SNMPMGR_AGENTX_PING_INTERVAL_SEC; #endif /* THE_CONFSYS_ERA */ if (netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL, (int)ping_interval) != SNMPERR_SUCCESS) { initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR; return; } if (init_agent(SNMP_TYPE) != SNMPERR_SUCCESS) { initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR; return; } if ((ret = lagopus_hashmap_create(&iftable_entry_hash, LAGOPUS_HASHMAP_TYPE_STRING, delete_entry)) != LAGOPUS_RESULT_OK) { lagopus_perror(ret); exit(1); } init_ifTable(); init_ifNumber(); init_dot1dBaseBridgeAddress(); init_dot1dBaseNumPorts(); init_dot1dBasePortTable(); init_dot1dBaseType(); if (is_thread == false) { initialize_ret = LAGOPUS_RESULT_OK; } else { keep_running = true; initialize_ret = lagopus_thread_create(&snmpmgr, snmpmgr_thread_loop, snmpmgr_thread_finally_called, NULL, "snmpmgr", NULL); } lagopus_msg_info("SNMP manager initialized.\n"); }
static lagopus_result_t connect_tls(struct session *s, const char *host, const char *port) { int ret; BIO *sbio; (void) host; (void) port; lagopus_msg_info("tls handshake start.\n"); if (IS_TLS_NOT_INIT(s)) { SSL_CTX *ssl_ctx; ssl_ctx = get_ssl_ctx(GET_TLS_CTX(s)->ca_dir, GET_TLS_CTX(s)->cert, GET_TLS_CTX(s)->key); if (ssl_ctx == NULL) { lagopus_msg_warning("get_ssl_ctx() fail.\n"); return LAGOPUS_RESULT_TLS_CONN_ERROR; } GET_TLS_CTX(s)->ctx = ssl_ctx; } if (GET_TLS_CTX(s)->ssl == NULL) { SSL *ssl; ssl = SSL_new(GET_TLS_CTX(s)->ctx); if (ssl == NULL) { lagopus_msg_warning("no memory.\n"); return LAGOPUS_RESULT_TLS_CONN_ERROR; } GET_TLS_CTX(s)->ssl = ssl; } if (SSL_get_rbio(GET_TLS_CTX(s)->ssl) == NULL) { sbio = BIO_new_socket(s->sock, BIO_NOCLOSE); SSL_set_bio(GET_TLS_CTX(s)->ssl, sbio, sbio); } ret = SSL_connect(GET_TLS_CTX(s)->ssl); if (ret == 0) { lagopus_msg_warning("tls handshake failed.\n"); return LAGOPUS_RESULT_TLS_CONN_ERROR; } else if (ret < 0 && (SSL_get_error(GET_TLS_CTX(s)->ssl, ret) != SSL_ERROR_WANT_READ && SSL_get_error(GET_TLS_CTX(s)->ssl, ret) != SSL_ERROR_WANT_READ)) { lagopus_msg_warning("tls error (%s:%d).\n", ERR_error_string((unsigned long) SSL_get_error(GET_TLS_CTX(s)->ssl, ret), NULL), (int) SSL_get_error(GET_TLS_CTX(s)->ssl, ret)); return LAGOPUS_RESULT_TLS_CONN_ERROR; } else if (ret < 0) { lagopus_msg_info("tls error (%s:%d), but continue.\n", ERR_error_string((unsigned long) SSL_get_error(GET_TLS_CTX(s)->ssl, ret), NULL), (int) SSL_get_error(GET_TLS_CTX(s)->ssl, ret)); return LAGOPUS_RESULT_EINPROGRESS; } else { ret = check_cert_chain(GET_TLS_CTX(s)->ssl); if (ret < 0) { lagopus_msg_warning("certificate error.\n"); return LAGOPUS_RESULT_TLS_CONN_ERROR; } GET_TLS_CTX(s)->verified = true; lagopus_msg_info("tls handshake end.\n"); } return LAGOPUS_RESULT_OK; }
static inline int s_do_main(int argc, const char *const argv[], int ipcfd) { lagopus_result_t st = LAGOPUS_RESULT_ANY_FAILURES; lagopus_msg_info("Initializing all the modules.\n"); (void)global_state_set(GLOBAL_STATE_INITIALIZING); if ((st = lagopus_module_initialize_all(argc, (const char *const *)argv)) == LAGOPUS_RESULT_OK && s_got_term_sig == false) { lagopus_msg_info("All the modules are initialized.\n"); lagopus_msg_info("Starting all the modules.\n"); (void)global_state_set(GLOBAL_STATE_STARTING); if ((st = lagopus_module_start_all()) == LAGOPUS_RESULT_OK && s_got_term_sig == false) { shutdown_grace_level_t l = SHUTDOWN_UNKNOWN; lagopus_msg_info("All the modules are started and ready to go.\n"); config_propagate_lagopus_conf(); (void)global_state_set(GLOBAL_STATE_STARTED); if (ipcfd >= 0) { int zero = 0; (void)write(ipcfd, (void *)&zero, sizeof(int)); (void)close(ipcfd); ipcfd = -1; } lagopus_msg_info("The Lagopus is a go.\n"); s_gen_pidfile(); while ((st = global_state_wait_for_shutdown_request(&l, REQ_TIMEDOUT)) == LAGOPUS_RESULT_TIMEDOUT) { lagopus_msg_debug(5, "Waiting for the shutdown request...\n"); } if (st == LAGOPUS_RESULT_OK) { (void)global_state_set(GLOBAL_STATE_ACCEPT_SHUTDOWN); if ((st = lagopus_module_shutdown_all(l)) == LAGOPUS_RESULT_OK) { if ((st = lagopus_module_wait_all(s_to)) == LAGOPUS_RESULT_OK) { lagopus_msg_info("Shutdown succeeded.\n"); } else if (st == LAGOPUS_RESULT_TIMEDOUT) { do_cancel: lagopus_msg_warning("Trying to stop forcibly...\n"); if ((st = lagopus_module_stop_all()) == LAGOPUS_RESULT_OK) { if ((st = lagopus_module_wait_all(s_to)) == LAGOPUS_RESULT_OK) { lagopus_msg_warning("Stopped forcibly.\n"); } } } } else if (st == LAGOPUS_RESULT_TIMEDOUT) { goto do_cancel; } } } } lagopus_module_finalize_all(); if (st != LAGOPUS_RESULT_OK) { lagopus_msg_warning("Bailed out, anyway. The latest result status is:" "%s\n", lagopus_error_get_string(st)); if (ipcfd >= 0) { int one = 1; (void)write(ipcfd, (void *)&one, sizeof(int)); (void)close(ipcfd); } } s_del_pidfile(); return (st == LAGOPUS_RESULT_OK) ? 0 : 1; }