From: mwilck@suse.com
To: Sagi Grimberg <sagi@grimberg.me>, Hannes Reinecke <hare@suse.de>,
Keith Busch <kbusch@kernel.org>
Cc: Chaitanya Kulkarni <Chaitanya.Kulkarni@wdc.com>,
linux-nvme@lists.infradead.org,
Enzo Matsumiya <ematsumiya@suse.de>,
Martin Wilck <mwilck@suse.com>
Subject: [PATCH v2 10/16] monitor: discover from conf file on startup
Date: Sat, 6 Mar 2021 01:36:53 +0100 [thread overview]
Message-ID: <20210306003659.21207-11-mwilck@suse.com> (raw)
In-Reply-To: <20210306003659.21207-1-mwilck@suse.com>
From: Martin Wilck <mwilck@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
_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme
next prev parent reply other threads:[~2021-03-06 0:49 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-06 0:36 [PATCH v2 00/16] nvme-cli: add "nvme monitor" subcommand mwilck
2021-03-06 0:36 ` [PATCH v2 01/16] fabrics: export symbols required for monitor functionality mwilck
2021-03-06 0:36 ` [PATCH v2 02/16] nvme-cli: add code for event and timeout handling mwilck
2021-03-17 0:32 ` Martin Wilck
2021-03-19 16:42 ` Martin Wilck
2021-03-30 22:06 ` Martin Wilck
2021-03-06 0:36 ` [PATCH v2 03/16] monitor: add basic "nvme monitor" functionality mwilck
2021-03-06 0:36 ` [PATCH v2 04/16] monitor: implement uevent handling mwilck
2021-03-06 0:36 ` [PATCH v2 05/16] conn-db: add simple connection registry mwilck
2021-03-06 0:36 ` [PATCH v2 06/16] monitor: monitor_discovery(): try to reuse existing controllers mwilck
2021-03-06 0:36 ` [PATCH v2 07/16] monitor: kill running discovery tasks on exit mwilck
2021-03-06 0:36 ` [PATCH v2 08/16] monitor: add option --cleanup / -C mwilck
2021-03-06 0:36 ` [PATCH v2 09/16] monitor: handling of add/remove uevents for nvme controllers mwilck
2021-03-06 0:36 ` mwilck [this message]
2021-03-06 0:36 ` [PATCH v2 11/16] monitor: watch discovery.conf with inotify mwilck
2021-03-06 0:36 ` [PATCH v2 12/16] monitor: add parent/child messaging and "notify" message exchange mwilck
2021-03-06 0:36 ` [PATCH v2 13/16] monitor: add "query device" " mwilck
2021-03-06 0:36 ` [PATCH v2 14/16] completions: add completions for nvme monitor mwilck
2021-03-06 0:36 ` [PATCH v2 15/16] nvmf-autoconnect: add unit file for nvme-monitor.service mwilck
2021-03-06 0:36 ` [PATCH v2 16/16] nvme-monitor(1): add man page for nvme-monitor mwilck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210306003659.21207-11-mwilck@suse.com \
--to=mwilck@suse.com \
--cc=Chaitanya.Kulkarni@wdc.com \
--cc=ematsumiya@suse.de \
--cc=hare@suse.de \
--cc=kbusch@kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=sagi@grimberg.me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).