コード例 #1
0
ファイル: logger.c プロジェクト: 1514louluo/lagopus
static void
s_once_proc(void) {
  char *dbg_lvl_str = getenv("LAGOPUS_LOG_DEBUGLEVEL");
  char *logfile = getenv("LAGOPUS_LOG_FILE");
  uint16_t d = 0;
  lagopus_log_destination_t log_dst = LAGOPUS_LOG_EMIT_TO_UNKNOWN;

  if (IS_VALID_STRING(dbg_lvl_str) == true) {
    uint16_t tmp = 0;
    if (lagopus_str_parse_uint16(dbg_lvl_str, &tmp) == LAGOPUS_RESULT_OK) {
      d = tmp;
    }
  }
  if ((logfile = s_validate_path(logfile, s_is_valid_path)) != NULL) {
    log_dst = LAGOPUS_LOG_EMIT_TO_FILE;
  }

  if (lagopus_log_initialize(log_dst, logfile, false, true, d) !=
      LAGOPUS_RESULT_OK) {
    lagopus_exit_error(1, "logger initialization error.\n");
  }

  if (d > 0) {
    lagopus_msg_debug(d, "Logger debug level is set to: %d.\n", d);
  }

#ifdef HAVE_PROCFS_SELF_EXE
  if (readlink("/proc/self/exe", s_exefile, PATH_MAX) != -1) {
    (void)lagopus_set_command_name(s_exefile);
    lagopus_msg_debug(10, "set the command name '%s'.\n",
                      lagopus_get_command_name());
  }
#endif /* HAVE_PROCFS_SELF_EXE */
}
コード例 #2
0
ファイル: session.c プロジェクト: tidatida/lagopus
/* Set socket buffer size to val. */
static void
socket_buffer_size_set(int sock, int optname, int val) {
  int ret;
  int size;
  socklen_t len = sizeof(size);

  /* Get current buffer size. */
  ret = getsockopt(sock, SOL_SOCKET, optname, &size, &len);
  if (ret < 0) {
    return;
  }

  /* If the buffer size is less than val, try to increase it. */
  if (size < val) {
    size = val;
    len = sizeof(size);
    ret = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &size, len);
    if (ret < 0) {
      return;
    }
  }

  /* Get buffer size. */
  ret = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &size, &len);
  if (ret < 0) {
    return;
  }

  /* Logging. */
  if (optname == SO_SNDBUF) {
    lagopus_msg_debug(10, "SO_SNDBUF buffer size is %d\n", size);
  } else {
    lagopus_msg_debug(10, "SO_RCVBUF buffer size is %d\n", size);
  }
}
コード例 #3
0
ファイル: session_tls.c プロジェクト: D-TOKIOKA/lagopus
static lagopus_result_t
connect_check_tls(struct session *s) {
  long res = -1;
  X509 *peer = NULL;
  lagopus_result_t ret = 0;

  lagopus_msg_debug(10, "connect check in\n");
  if (IS_CTX_NULL(s)) {
    lagopus_msg_warning("session ctx is null.\n");
    return LAGOPUS_RESULT_INVALID_ARGS;
  }

  if (IS_TLS_NOT_INIT(s) == false) {
    res = SSL_get_verify_result(GET_TLS_CTX(s)->ssl);
    peer = SSL_get_peer_certificate(GET_TLS_CTX(s)->ssl);
  }

  if (res != X509_V_OK || peer == NULL
      || GET_TLS_CTX(s)->verified == false) {
    ret = connect_tls(s, NULL, NULL);
  }
  lagopus_msg_debug(10, "connect check out ret:%d\n", (int) ret);

  return ret;
}
コード例 #4
0
ファイル: check5-b.c プロジェクト: D-TOKIOKA/lagopus
static void
s_sighandler(int sig) {
  lagopus_msg_debug(5, "got a signal %d\n", sig);
  if (sig == SIGINT) {
    lagopus_msg_debug(5, "WILL EXIT.\n");

    is_signaled = true;
    s_stop_all();

    lagopus_msg_debug(5, "STOPPED ALL.\n");
  }
}
コード例 #5
0
ファイル: pipeline_stage.c プロジェクト: tidatida/lagopus
static void
s_dtors(void) {
  if (lagopus_module_is_unloading() &&
      lagopus_module_is_finalized_cleanly()) {
    s_final();

    lagopus_msg_debug(10, "The pipeline stage module is finalized.\n");
  } else {
    lagopus_msg_debug(10, "The pipeline stage module is not finalized "
                      "because of module finalization problem.\n");
  }
}
コード例 #6
0
lagopus_result_t
check_packet_parse_array_expect_error(ofp_handler_proc_t handler_proc,
                                      const char *packet[],
                                      int array_len,
                                      const struct ofp_error *expected_error) {

  lagopus_result_t res = LAGOPUS_RESULT_ANY_FAILURES;
  struct channel *channel = create_data_channel();
  struct ofp_header xid_header;
  struct pbuf *pbuf;
  struct ofp_error error;
  bool error_has_occurred = false;
  int i;
  for (i = 0; i < array_len; i++) {
    lagopus_msg_debug(1, "packet[%d] start ... %s\n", i, packet[i]);
    /* create packet */
    create_packet(packet[i], &pbuf);
    /* parse header */
    if (ofp_header_decode_sneak_test(pbuf, &xid_header) !=
        LAGOPUS_RESULT_OK) {
      pbuf_free(pbuf);
      s_destroy_static_data();
      TEST_FAIL_MESSAGE("handler_test_utils.c: cannot decode header\n");
      return LAGOPUS_RESULT_OFP_ERROR;
    }
    /* call func & check */
    res = (handler_proc)(channel, pbuf, &xid_header, &error);
    lagopus_msg_debug(1, "packet[%d] done ... %s\n", i,
                      lagopus_error_get_string(res));
    if (res == LAGOPUS_RESULT_OK) {
      TEST_ASSERT_EQUAL_MESSAGE(0, pbuf->plen,
                                "handler_test_utils.c: packet data len error.");
    } else if (res == LAGOPUS_RESULT_OFP_ERROR) {
      error_has_occurred = true;
      if (expected_error != NULL) {
        TEST_ASSERT_EQUAL_OFP_ERROR(expected_error, &error);
      }
      pbuf_free(pbuf);
      break;
    }
    /* free */
    pbuf_free(pbuf);
  }

  /* free */
  s_destroy_static_data();

  if (error_has_occurred == true) {
    TEST_ASSERT_EQUAL_OFP_ERROR(expected_error, &error);
  }

  return res;
}
コード例 #7
0
ファイル: gstate.c プロジェクト: 1514louluo/lagopus
static void
s_dtors(void) {
  if (lagopus_module_is_unloading() &&
      lagopus_module_is_finalized_cleanly()) {

    s_final();

    lagopus_msg_debug(10, "The global status tracker finalized.\n");
  } else {
    lagopus_msg_debug(10, "The global status tracker is not finalized "
                      "because of module finalization problem.\n");
  }
}
コード例 #8
0
ファイル: check7.c プロジェクト: AkiraSuu/lagopus
static inline void
a_obj_destroy(a_obj_t o) {
  lagopus_msg_debug(1, "enter.\n");

  if (o != NULL) {
    if (o->m_lock != NULL) {
      (void)lagopus_mutex_lock(&(o->m_lock));
      (void)lagopus_mutex_unlock(&(o->m_lock));
      (void)lagopus_mutex_destroy(&(o->m_lock));
    }
    free((void *)o);
  }

  lagopus_msg_debug(1, "leave.\n");
}
コード例 #9
0
ファイル: snmp_cmd.c プロジェクト: JackieXie168/lagopus
static lagopus_result_t
s_parse_snmp(datastore_interp_t *iptr,
             datastore_interp_state_t state,
             size_t argc, const char *const argv[],
             lagopus_hashmap_t *hptr,
             datastore_update_proc_t u_proc,
             datastore_enable_proc_t e_proc,
             datastore_serialize_proc_t s_proc,
             datastore_destroy_proc_t d_proc,
             lagopus_dstring_t *result) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  size_t i;

  (void)iptr;
  (void)state;
  (void)argc;
  (void)hptr;
  (void)u_proc;
  (void)e_proc;
  (void)s_proc;
  (void)d_proc;

  for (i = 0; i < argc; i++) {
    lagopus_msg_debug(1, "argv[" PFSZS(4, u) "]:\t'%s'\n", i, argv[i]);
  }

  argv++;
  if (IS_VALID_STRING(*argv) == false) {
    ret = s_parse_snmp_show(result);
  } else {
    ret = s_parse_snmp_internal(argv, result);
  }

  return ret;
}
コード例 #10
0
static void
pipeline_freeup(const lagopus_pipeline_stage_t *sptr) {
  (void)sptr;

  lagopus_msg_debug(1, "called.\n");
  called_func_count(PIPELINE_FUNC_FREEUP);
}
コード例 #11
0
static void
pipeline_pre_pause(const lagopus_pipeline_stage_t *sptr) {
  (void)sptr;

  lagopus_msg_debug(1, "called.\n");
  called_func_count(PIPELINE_FUNC_PRE_PAUSE);
}
コード例 #12
0
ファイル: check12.c プロジェクト: D-TOKIOKA/lagopus
static lagopus_result_t
s_setup(const lagopus_pipeline_stage_t *sptr) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  test_stage_t t = (test_stage_t)(*sptr);

  lagopus_msg_debug(1, "called.\n");

  t->m_counts = (size_t *)malloc(sizeof(size_t) *
                                 t->m_stg.m_n_workers);
  if (t->m_counts != NULL &&
      (ret = lagopus_mutex_create(&(t->m_lock))) == LAGOPUS_RESULT_OK) {
    size_t i;

    for (i = 0; i < t->m_stg.m_n_workers; i++) {
      t->m_counts[i] = 0LL;
    }

    ret = LAGOPUS_RESULT_OK;
  } else {
    if (t->m_counts == NULL) {
      ret = LAGOPUS_RESULT_NO_MEMORY;
    }
  }

  return ret;
}
コード例 #13
0
ファイル: ofp_role.c プロジェクト: D-TOKIOKA/lagopus
lagopus_result_t
ofp_role_channel_update(struct channel *channel,
                        struct ofp_role_request *role_request,
                        uint64_t dpid) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  uint32_t current_role;

  if (channel != NULL && role_request != NULL) {
    current_role = channel_role_get(channel);
    /* Not change. */
    if (role_request->role == current_role ||
        role_request->role == OFPCR_ROLE_NOCHANGE) {
      lagopus_msg_debug(1, "Role not change (%u).\n",
                        role_request->role);
      role_request->role = current_role;
      ret = LAGOPUS_RESULT_OK;
    } else {
      if (current_role == OFPCR_ROLE_MASTER) {
        /* every other master controller to slave. */
        channel_mgr_dpid_iterate(dpid, change_master2slave, NULL);
      }
      channel_role_set(channel, role_request->role);
      ret = LAGOPUS_RESULT_OK;
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
コード例 #14
0
ファイル: dummy-module.c プロジェクト: AkiraSuu/lagopus
static void
s_dummy_thd_destroy(const lagopus_thread_t *tptr, void *arg) {
  (void)tptr;
  (void)arg;

  lagopus_msg_debug(5, "called.\n");
}
コード例 #15
0
ファイル: dummy-module.c プロジェクト: AkiraSuu/lagopus
static lagopus_result_t
dummy_module_start(void) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  lagopus_msg_debug(5, "called.\n");

  if (s_thd != NULL) {

    s_lock();
    {
      if (s_is_initialized == true) {
        ret = lagopus_thread_start(&s_thd, false);
        if (ret == LAGOPUS_RESULT_OK) {
          s_do_loop = true;
        }
      } else {
        ret = LAGOPUS_RESULT_INVALID_STATE_TRANSITION;
      }
    }
    s_unlock();

  } else {
    ret = LAGOPUS_RESULT_INVALID_OBJECT;
  }

  return ret;
}
コード例 #16
0
ファイル: dummy-module.c プロジェクト: AkiraSuu/lagopus
static lagopus_result_t
dummy_module_shutdown(shutdown_grace_level_t l) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  lagopus_msg_debug(5, "called.\n");

  if (s_thd != NULL) {

    s_lock();
    {
      if (s_is_initialized == true) {
        if (l == SHUTDOWN_GRACEFULLY) {
          s_is_gracefull = true;
        }
        s_do_loop = false;
        ret = LAGOPUS_RESULT_OK;
      } else {
        ret = LAGOPUS_RESULT_INVALID_STATE_TRANSITION;
      }
    }
    s_unlock();

  } else {
    ret = LAGOPUS_RESULT_INVALID_OBJECT;
  }

  return ret;
}
コード例 #17
0
ファイル: check0.c プロジェクト: JackieXie168/lagopus
static void
s_dtors(void) {
  s_final();

  lagopus_msg_debug(10, "datastore object \"%s\" finalized.\n",
                    MY_COMMAND_NAME);
}
コード例 #18
0
ファイル: logger.c プロジェクト: D-TOKIOKA/lagopus
static void
s_once_proc(void) {
  char *dbg_lvl_str = getenv("LAGOPUS_LOG_DEBUGLEVEL");
  char *logfile = getenv("LAGOPUS_LOG_FILE");
  uint16_t d = 0;
  lagopus_log_destination_t log_dst = LAGOPUS_LOG_EMIT_TO_UNKNOWN;

  if (IS_VALID_STRING(dbg_lvl_str) == true) {
    uint16_t tmp = 0;
    if (lagopus_str_parse_uint16(dbg_lvl_str, &tmp) == LAGOPUS_RESULT_OK) {
      d = tmp;
    }
  }
  if ((logfile = s_validate_path(logfile, s_is_valid_path)) != NULL) {
    log_dst = LAGOPUS_LOG_EMIT_TO_FILE;
  }

  if (lagopus_log_initialize(log_dst, logfile, false, true, d) !=
      LAGOPUS_RESULT_OK) {
    lagopus_exit_error(1, "logger initialization error.\n");
  }

  if (d > 0) {
    lagopus_msg_debug(d, "Logger debug level is set to: %d.\n", d);
  }
}
コード例 #19
0
ファイル: check0.c プロジェクト: JackieXie168/lagopus
static void
s_ctors(void) {
  s_init();

  lagopus_msg_debug(10, "datastore object \"%s\" initialzied.\n",
                    MY_COMMAND_NAME);
}
コード例 #20
0
ファイル: dummy-module.c プロジェクト: AkiraSuu/lagopus
static lagopus_result_t
s_dummy_thd_main(const lagopus_thread_t *tptr, void *arg) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  global_state_t s;
  shutdown_grace_level_t l;

  (void)tptr;
  (void)arg;

  lagopus_msg_debug(5, "waiting for the gala opening...\n");

  ret = global_state_wait_for(GLOBAL_STATE_STARTED, &s, &l, -1LL);
  if (ret == LAGOPUS_RESULT_OK &&
      s == GLOBAL_STATE_STARTED) {

    s_is_started = true;

    lagopus_msg_debug(5, "gala opening.\n");

    /*
     * The main task loop.
     */
    while (s_do_loop == true) {
      lagopus_msg_debug(6, "looping...\n");
      (void)lagopus_chrono_nanosleep(1000LL * 1000LL * 500LL, NULL);
      /*
       * Create an explicit cancalation point since this loop has
       * none of it.
       */
      pthread_testcancel();
    }
    if (s_is_gracefull == true) {
      /*
       * This is just emulating/mimicking a graceful shutdown by
       * sleep().  Don't do this on actual modules.
       */
      lagopus_msg_debug(5, "mimicking gracefull shutdown...\n");
      sleep(5);
      lagopus_msg_debug(5, "mimicking gracefull shutdown done.\n");
      ret = LAGOPUS_RESULT_OK;
    } else {
      ret = 1LL;
    }
  }

  return ret;
}
コード例 #21
0
ファイル: check7.c プロジェクト: AkiraSuu/lagopus
static void
s_finalize(const lagopus_thread_t *tptr, bool is_canceled, void *arg) {
  (void)arg;
  (void)tptr;

  lagopus_msg_debug(1, "called. %s.\n",
                    (is_canceled == false) ? "finished" : "canceled");
}
コード例 #22
0
ファイル: check10-a.c プロジェクト: 1514louluo/lagopus
static void
s_finalize(const lagopus_pipeline_stage_t *sptr,
           bool is_canceled) {
  (void)sptr;

  lagopus_msg_debug(1, "%s.\n",
                    (is_canceled == false) ? "exit normally" : "canceled");
}
コード例 #23
0
ファイル: check10-b.c プロジェクト: AkiraSuu/lagopus
static lagopus_result_t
s_setup(const lagopus_pipeline_stage_t *sptr) {
  (void)sptr;

  lagopus_msg_debug(1, "called.\n");

  return LAGOPUS_RESULT_OK;
}
コード例 #24
0
ファイル: session.c プロジェクト: tidatida/lagopus
lagopus_result_t
session_poll(lagopus_session_t s[], int n, int timeout) {
  int i, n_events = 0;
  lagopus_result_t ret;
  struct pollfd pollfd[MAX_EVENTS];

  if (n > MAX_EVENTS) {
    return LAGOPUS_RESULT_INVALID_ARGS;
  }

  for (i = 0; i < n; i++) {
    if ((s[i]->events & POLLIN) && (SBUF_UNREAD_LEN(s[i]) > 0)) {
      s[i]->revents = POLLIN;
      n_events++;
    } else {
      pollfd[i].fd = s[i]->sock;
      pollfd[i].events = s[i]->events;
      pollfd[i].revents = 0;
    }
  }

  if (n_events > 0) {
    return n_events;
  }

  lagopus_msg_debug(10, "%d events pollin.\n", n);
  n_events = poll(pollfd, (nfds_t) n, timeout);
  lagopus_msg_debug(10, "%d events pollout.\n", n_events);
  if (n_events == 0) {
    ret = LAGOPUS_RESULT_TIMEDOUT;
  } else if (n_events < 0) {
    if (errno == EINTR) {
      ret = LAGOPUS_RESULT_INTERRUPTED;
    } else {
      ret = LAGOPUS_RESULT_POSIX_API_ERROR;
    }
  } else {
    ret = n_events;
  }

  for (i = 0; i < n; i++) {
    s[i]->revents = pollfd[i].revents;
  }

  return ret;
}
コード例 #25
0
static lagopus_result_t
pipeline_setup(const lagopus_pipeline_stage_t *sptr) {
  (void)sptr;

  lagopus_msg_debug(1, "called.\n");
  called_func_count(PIPELINE_FUNC_SETUP);

  return LAGOPUS_RESULT_OK;
}
コード例 #26
0
ファイル: check5-b.c プロジェクト: D-TOKIOKA/lagopus
static lagopus_result_t
s_test_thread_main(const lagopus_thread_t *tptr, void *arg) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  lagopus_chrono_t *dates = NULL;

  (void)arg;

  if (tptr != NULL) {
    test_thread_t tt = (test_thread_t)*tptr;


    if (tt != NULL) {
      ssize_t i;
      lagopus_chrono_t now;
      dates = (lagopus_chrono_t *)
              malloc(sizeof(lagopus_chrono_t) * (size_t)tt->m_n_puts);
      if (dates == NULL) {
        goto done;
      }

      /*
       * Ready, steady,
       */
      (void)lagopus_mutex_lock(&(tt->m_start_lock));
      /*
       * go.
       */
      (void)lagopus_mutex_unlock(&(tt->m_start_lock));

      for (i = 0; i < tt->m_n_puts; i++) {
        WHAT_TIME_IS_IT_NOW_IN_NSEC(dates[i]);
      }
      if (lagopus_bbq_put_n(&(tt->m_q), (void **)dates,
                            (size_t)tt->m_n_puts,
                            lagopus_chrono_t, -1LL, NULL) !=
          (lagopus_result_t)tt->m_n_puts) {
        goto done;
      }

      now = -1LL;
      if (lagopus_bbq_put(&(tt->m_q), &now, lagopus_chrono_t, -1LL) !=
          LAGOPUS_RESULT_OK) {
        goto done;
      }
      ret = tt->m_n_puts;

      lagopus_msg_debug(1, "Done, ret = " PFSZS(020, d)
                        ", req = " PFSZS(020, u) ".\n",
                        (size_t)ret, (size_t)tt->m_n_puts);
    }
  }

done:
  free((void *)dates);

  return ret;
}
コード例 #27
0
ファイル: dummy-module.c プロジェクト: AkiraSuu/lagopus
static lagopus_result_t
dummy_module_initialize(int argc,
                        const char *const argv[],
                        void *extarg,
                        lagopus_thread_t **thdptr) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  (void)extarg;

  lagopus_msg_debug(5, "called.\n");

  if (thdptr != NULL) {
    *thdptr = NULL;
  }

  s_lock();
  {
    if (s_is_initialized == false) {
      int i;

      lagopus_msg_debug(5, "argc: %d\n", argc);
      for (i = 0; i < argc; i++) {
        lagopus_msg_debug(5, "%5d: '%s'\n", i, argv[i]);
      }

      ret = lagopus_thread_create(&s_thd,
                                  s_dummy_thd_main,
                                  s_dummy_thd_finalize,
                                  s_dummy_thd_destroy,
                                  "dummy", NULL);
      if (ret == LAGOPUS_RESULT_OK) {
        s_is_initialized = true;
        if (thdptr != NULL) {
          *thdptr = &s_thd;
        }
      }
    } else {
      ret = LAGOPUS_RESULT_OK;
    }
  }
  s_unlock();

  return ret;
}
コード例 #28
0
ファイル: ofp_bridgeq_mgr.c プロジェクト: D-TOKIOKA/lagopus
void
ofp_bridgeq_free(struct ofp_bridgeq *bridgeq,
                 bool force) {
  uint64_t i;

  if (bridgeq != NULL) {
    bridgeq_lock(bridgeq);

    if (bridgeq->refs > 1 && force == false) {
      /* bridgeq is busy. */
      lagopus_msg_debug(500, "bridgeq(dpid = %"PRIu64") is busy.\n",
                        bridgeq->ofp_bridge->dpid);
      bridgeq->refs--;
      bridgeq_unlock(bridgeq);
    } else {
      lagopus_msg_debug(500, "bridgeq(dpid = %"PRIu64") is free.\n",
                        bridgeq->ofp_bridge->dpid);
      if (bridgeq->ofp_bridge != NULL) {
        ofp_bridge_destroy(bridgeq->ofp_bridge);
        bridgeq->ofp_bridge = NULL;
      }

      /* destroy polls. */
      for (i = 0; i < MAX_BRIDGE_POLLS; i++) {
        if (bridgeq->polls[i] != NULL) {
          lagopus_qmuxer_poll_destroy(&(bridgeq->polls[i]));
          bridgeq->polls[i] = NULL;
        }
      }
      for (i = 0; i < MAX_BRIDGE_DP_POLLS; i++) {
        if (bridgeq->dp_polls[i] != NULL) {
          lagopus_qmuxer_poll_destroy(&(bridgeq->dp_polls[i]));
          bridgeq->dp_polls[i] = NULL;
        }
      }
      bridgeq_unlock(bridgeq);
      if (bridgeq->lock != NULL) {
        lagopus_mutex_destroy(&(bridgeq->lock));
        bridgeq->lock = NULL;
      }
      free(bridgeq);
    }
  }
}
コード例 #29
0
ファイル: check10-b.c プロジェクト: AkiraSuu/lagopus
static lagopus_result_t
s_sched(const lagopus_pipeline_stage_t *sptr,
        void *buf, size_t n) {
  (void)sptr;
  (void)buf;

  lagopus_msg_debug(1, "called.\n");

  return (lagopus_result_t)n;
}
コード例 #30
0
ファイル: check10-a.c プロジェクト: 1514louluo/lagopus
static lagopus_result_t
s_shutdown(const lagopus_pipeline_stage_t *sptr,
           shutdown_grace_level_t l) {
  (void)sptr;

  lagopus_msg_debug(1, "called with \"%s\".\n",
                    (l == SHUTDOWN_RIGHT_NOW) ? "right now" : "gracefully");

  return LAGOPUS_RESULT_OK;
}