[PATCH v2 10/16] monitor: discover from conf file on startup
mwilck at suse.com
mwilck at suse.com
Sat Mar 6 00:36:53 GMT 2021
From: Martin Wilck <mwilck at suse.com>
Implement discovery from /etc/nvme/discovery.conf on startup of
the monitor.
The monitor needs to call discover_from_conf_file() in order to
be able to do discovery at startup. discover_from_conf_file() takes
the argconfig_commandline_options argument from fabrics_discover().
By moving these options into a static variable, we can avoid passing
them as function argument. This makes it possible to use
discover_from_conf_file() from the monitor without making the
options for fabric_discover() globally visible.
---
fabrics.c | 67 +++++++++++++++++++++++++++----------------------------
fabrics.h | 5 +++++
monitor.c | 58 +++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 94 insertions(+), 36 deletions(-)
diff --git a/fabrics.c b/fabrics.c
index 5012519..b195d0e 100644
--- a/fabrics.c
+++ b/fabrics.c
@@ -85,7 +85,6 @@ struct connect_args {
struct connect_args *tracked_ctrls;
#define PATH_NVME_FABRICS "/dev/nvme-fabrics"
-#define PATH_NVMF_DISC "/etc/nvme/discovery.conf"
#define PATH_NVMF_HOSTNQN "/etc/nvme/hostnqn"
#define PATH_NVMF_HOSTID "/etc/nvme/hostid"
#define MAX_DISC_ARGS 10
@@ -1439,8 +1438,9 @@ int do_discover(char *argstr, bool connect, enum nvme_print_flags flags)
return ret;
}
-static int discover_from_conf_file(const char *desc, char *argstr,
- const struct argconfig_commandline_options *opts, bool connect)
+static OPT_ARGS(discover_opts);
+
+int discover_from_conf_file(const char *desc, char *argstr, bool connect)
{
FILE *f;
char line[256], *ptr, *all_args, *args, **argv;
@@ -1480,7 +1480,7 @@ static int discover_from_conf_file(const char *desc, char *argstr,
while ((ptr = strsep(&args, " =\n")) != NULL)
argv[argc++] = ptr;
- err = argconfig_parse(argc, argv, desc, opts);
+ err = argconfig_parse(argc, argv, desc, discover_opts);
if (err)
goto free_and_continue;
@@ -1523,41 +1523,40 @@ out:
return ret;
}
+static OPT_ARGS(discover_opts) = {
+ OPT_LIST("transport", 't', &fabrics_cfg.transport, "transport type"),
+ OPT_LIST("traddr", 'a', &fabrics_cfg.traddr, "transport address"),
+ OPT_LIST("trsvcid", 's', &fabrics_cfg.trsvcid, "transport service id (e.g. IP port)"),
+ OPT_LIST("host-traddr", 'w', &fabrics_cfg.host_traddr, "host traddr (e.g. FC WWN's)"),
+ OPT_LIST("hostnqn", 'q', &fabrics_cfg.hostnqn, "user-defined hostnqn (if default not used)"),
+ OPT_LIST("hostid", 'I', &fabrics_cfg.hostid, "user-defined hostid (if default not used)"),
+ OPT_LIST("raw", 'r', &fabrics_cfg.raw, "raw output file"),
+ OPT_LIST("device", 'd', &fabrics_cfg.device, "use existing discovery controller device"),
+ OPT_INT("keep-alive-tmo", 'k', &fabrics_cfg.keep_alive_tmo, "keep alive timeout period in seconds"),
+ OPT_INT("reconnect-delay", 'c', &fabrics_cfg.reconnect_delay, "reconnect timeout period in seconds"),
+ OPT_INT("ctrl-loss-tmo", 'l', &fabrics_cfg.ctrl_loss_tmo, "controller loss timeout period in seconds"),
+ OPT_INT("tos", 'T', &fabrics_cfg.tos, "type of service"),
+ OPT_FLAG("hdr_digest", 'g', &fabrics_cfg.hdr_digest, "enable transport protocol header digest (TCP transport)"),
+ OPT_FLAG("data_digest", 'G', &fabrics_cfg.data_digest, "enable transport protocol data digest (TCP transport)"),
+ OPT_INT("nr-io-queues", 'i', &fabrics_cfg.nr_io_queues, "number of io queues to use (default is core count)"),
+ OPT_INT("nr-write-queues", 'W', &fabrics_cfg.nr_write_queues, "number of write queues to use (default 0)"),
+ OPT_INT("nr-poll-queues", 'P', &fabrics_cfg.nr_poll_queues, "number of poll queues to use (default 0)"),
+ OPT_INT("queue-size", 'Q', &fabrics_cfg.queue_size, "number of io queue elements to use (default 128)"),
+ OPT_FLAG("persistent", 'p', &fabrics_cfg.persistent, "persistent discovery connection"),
+ OPT_FLAG("quiet", 'S', &fabrics_cfg.quiet, "suppress already connected errors"),
+ OPT_FLAG("matching", 'm', &fabrics_cfg.matching_only, "connect only records matching the traddr"),
+ OPT_FMT("output-format", 'o', &fabrics_cfg.output_format, "Output format: normal|json|binary"),
+ OPT_END()
+};
+
int fabrics_discover(const char *desc, int argc, char **argv, bool connect)
{
char argstr[BUF_SIZE];
int ret;
enum nvme_print_flags flags;
- bool quiet = false;
-
- OPT_ARGS(opts) = {
- OPT_LIST("transport", 't', &fabrics_cfg.transport, "transport type"),
- OPT_LIST("traddr", 'a', &fabrics_cfg.traddr, "transport address"),
- OPT_LIST("trsvcid", 's', &fabrics_cfg.trsvcid, "transport service id (e.g. IP port)"),
- OPT_LIST("host-traddr", 'w', &fabrics_cfg.host_traddr, "host traddr (e.g. FC WWN's)"),
- OPT_LIST("hostnqn", 'q', &fabrics_cfg.hostnqn, "user-defined hostnqn (if default not used)"),
- OPT_LIST("hostid", 'I', &fabrics_cfg.hostid, "user-defined hostid (if default not used)"),
- OPT_LIST("raw", 'r', &fabrics_cfg.raw, "raw output file"),
- OPT_LIST("device", 'd', &fabrics_cfg.device, "existing discovery controller device"),
- OPT_INT("keep-alive-tmo", 'k', &fabrics_cfg.keep_alive_tmo, "keep alive timeout period in seconds"),
- OPT_INT("reconnect-delay", 'c', &fabrics_cfg.reconnect_delay, "reconnect timeout period in seconds"),
- OPT_INT("ctrl-loss-tmo", 'l', &fabrics_cfg.ctrl_loss_tmo, "controller loss timeout period in seconds"),
- OPT_INT("tos", 'T', &fabrics_cfg.tos, "type of service"),
- OPT_FLAG("hdr_digest", 'g', &fabrics_cfg.hdr_digest, "enable transport protocol header digest (TCP transport)"),
- OPT_FLAG("data_digest", 'G', &fabrics_cfg.data_digest, "enable transport protocol data digest (TCP transport)"),
- OPT_INT("nr-io-queues", 'i', &fabrics_cfg.nr_io_queues, "number of io queues to use (default is core count)"),
- OPT_INT("nr-write-queues", 'W', &fabrics_cfg.nr_write_queues, "number of write queues to use (default 0)"),
- OPT_INT("nr-poll-queues", 'P', &fabrics_cfg.nr_poll_queues, "number of poll queues to use (default 0)"),
- OPT_INT("queue-size", 'Q', &fabrics_cfg.queue_size, "number of io queue elements to use (default 128)"),
- OPT_FLAG("persistent", 'p', &fabrics_cfg.persistent, "persistent discovery connection"),
- OPT_FLAG("quiet", 'S', &quiet, "suppress already connected errors"),
- OPT_FLAG("matching", 'm', &fabrics_cfg.matching_only, "connect only records matching the traddr"),
- OPT_FMT("output-format", 'o', &fabrics_cfg.output_format, output_format),
- OPT_END()
- };
fabrics_cfg.tos = -1;
- ret = argconfig_parse(argc, argv, desc, opts);
+ ret = argconfig_parse(argc, argv, desc, discover_opts);
if (ret)
goto out;
@@ -1572,7 +1571,7 @@ int fabrics_discover(const char *desc, int argc, char **argv, bool connect)
}
}
- if (quiet)
+ if (fabrics_cfg.quiet)
log_level = LOG_WARNING;
if (fabrics_cfg.device && !strcmp(fabrics_cfg.device, "none"))
@@ -1581,7 +1580,7 @@ int fabrics_discover(const char *desc, int argc, char **argv, bool connect)
fabrics_cfg.nqn = NVME_DISC_SUBSYS_NAME;
if (!fabrics_cfg.transport && !fabrics_cfg.traddr) {
- ret = discover_from_conf_file(desc, argstr, opts, connect);
+ ret = discover_from_conf_file(desc, argstr, connect);
} else {
set_discovery_kato(&fabrics_cfg);
diff --git a/fabrics.h b/fabrics.h
index 41e6a2d..128f251 100644
--- a/fabrics.h
+++ b/fabrics.h
@@ -38,6 +38,7 @@ struct fabrics_config {
int data_digest;
bool persistent;
bool matching_only;
+ bool quiet;
const char *output_format;
};
extern struct fabrics_config fabrics_cfg;
@@ -45,11 +46,15 @@ extern struct fabrics_config fabrics_cfg;
extern const char *const trtypes[];
#define BUF_SIZE 4096
+#define PATH_NVMF_CFG_DIR "/etc/nvme"
+#define FILE_NVMF_DISC "discovery.conf"
+#define PATH_NVMF_DISC PATH_NVMF_CFG_DIR "/" FILE_NVMF_DISC
int build_options(char *argstr, int max_len, bool discover);
int do_discover(char *argstr, bool connect, enum nvme_print_flags flags);
int ctrl_instance(const char *device);
char *parse_conn_arg(const char *conargs, const char delim, const char *field);
int remove_ctrl(int instance);
+int discover_from_conf_file(const char *desc, char *argstr, bool connect);
#endif
diff --git a/monitor.c b/monitor.c
index 43d3084..95dea19 100644
--- a/monitor.c
+++ b/monitor.c
@@ -477,12 +477,20 @@ static int handle_epoll_err(int errcode)
default:
break;
}
+
co = conndb_find_by_pid(pid);
if (!co) {
- msg(LOG_ERR, "no connection found for discovery task %ld\n",
- (long)pid);
+ if (!WIFEXITED(wstatus))
+ msg(LOG_WARNING, "child %ld didn't exit normally\n",
+ (long)pid);
+ else if (WEXITSTATUS(wstatus) != 0)
+ msg(LOG_NOTICE, "child %ld exited with status \"%s\"\n",
+ (long)pid, strerror(WEXITSTATUS(wstatus)));
+ else
+ msg(LOG_DEBUG, "child %ld exited normally\n", (long)pid);
continue;
}
+
if (!WIFEXITED(wstatus)) {
msg(LOG_WARNING, "child %ld didn't exit normally\n",
(long)pid);
@@ -572,6 +580,45 @@ static int monitor_remove_discovery_ctrl(struct nvme_connection *co,
return CD_CB_OK;
}
+static int monitor_discover_from_conf_file(void)
+{
+ char argstr[BUF_SIZE];
+ pid_t pid;
+ int rc;
+
+ pid = fork();
+ if (pid == -1) {
+ msg(LOG_ERR, "failed to fork discovery task: %m");
+ return -errno;
+ } else if (pid > 0) {
+ msg(LOG_DEBUG, "started discovery task %ld from conf file\n",
+ (long)pid);
+ return 0;
+ }
+
+ child_reset_signals();
+
+ msg(LOG_NOTICE, "starting discovery from conf file\n");
+
+ fabrics_cfg.nqn = NVME_DISC_SUBSYS_NAME;
+ fabrics_cfg.tos = -1;
+ fabrics_cfg.persistent = true;
+
+ rc = discover_from_conf_file("Discover NVMeoF subsystems from " PATH_NVMF_DISC,
+ argstr, mon_cfg.autoconnect);
+
+ exit(-rc);
+ /* not reached */
+ return rc;
+}
+
+static int discovery_from_conf_file_cb(struct event *ev __attribute__((unused)),
+ unsigned int __attribute__((unused)) ep_events)
+{
+ monitor_discover_from_conf_file();
+ return EVENTCB_CLEANUP;
+}
+
static int monitor_parse_opts(const char *desc, int argc, char **argv)
{
bool quiet = false;
@@ -638,6 +685,7 @@ int aen_monitor(const char *desc, int argc, char **argv)
struct udev *udev __cleanup__(cleanup_udevp) = NULL;
struct udev_monitor *monitor __cleanup__(cleanup_monitorp) = NULL;
struct udev_monitor_event udev_event = { .e.fd = -1, };
+ struct event startup_discovery_event = { .fd = -1, };
sigset_t wait_mask;
ret = monitor_parse_opts(desc, argc, argv);
@@ -663,6 +711,12 @@ int aen_monitor(const char *desc, int argc, char **argv)
goto out;
}
+ startup_discovery_event =
+ TIMER_EVENT_ON_STACK(discovery_from_conf_file_cb, 0);
+ if ((ret = event_add(mon_dsp, &startup_discovery_event)) != 0)
+ msg(LOG_ERR, "failed to register initial discovery timer: %s\n",
+ strerror(-ret));
+
ret = create_udev_monitor(udev, &monitor);
if (ret != 0)
goto out;
--
2.29.2
More information about the Linux-nvme
mailing list