examples: detect fio backend fd redirection

It's useful to be able to run fio daemonized, and very recent versions of fio
redirect stdout/stderr to /dev/null in order to avoid the problem that
previously caused the plugin to abort. Detect if this redirection has happened
and allow fio to run in this case.

Signed-off-by: John Levon <john.levon@nutanix.com>
Change-Id: I8ec13a4c26a0acc67b15fa5e8502dc28d341e441
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9691
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Andreas Economides <andreas.economides@nutanix.com>
This commit is contained in:
John Levon 2021-09-30 10:34:16 +01:00 committed by Tomasz Zawadzki
parent 6751909838
commit 890b657e6b
2 changed files with 60 additions and 14 deletions

View File

@ -426,6 +426,27 @@ out:
return rc;
}
static bool
fio_redirected_to_dev_null(void)
{
char path[PATH_MAX] = "";
ssize_t ret;
ret = readlink("/proc/self/fd/1", path, sizeof(path));
if (ret == -1 || strcmp(path, "/dev/null") != 0) {
return false;
}
ret = readlink("/proc/self/fd/2", path, sizeof(path));
if (ret == -1 || strcmp(path, "/dev/null") != 0) {
return false;
}
return true;
}
/* Called for each thread to fill in the 'real_file_size' member for
* each file associated with this thread. This is called prior to
* the init operation (spdk_fio_init()) below. This call will occur
@ -439,16 +460,18 @@ spdk_fio_setup(struct thread_data *td)
unsigned int i;
struct fio_file *f;
/* we might be running in a daemonized FIO instance where standard
* input and output were closed and fds 0, 1, and 2 are reused
* for something important by FIO. We can't ensure we won't print
* anything (and so will our dependencies, e.g. DPDK), so abort early.
* (is_backend is an fio global variable)
/*
* If we're running in a daemonized FIO instance, it's possible
* fd 1/2 were re-used for something important by FIO. Newer fio
* versions are careful to redirect those to /dev/null, but if we're
* not, we'll abort early, so we don't accidentally write messages to
* an important file, etc.
*/
if (is_backend) {
if (is_backend && !fio_redirected_to_dev_null()) {
char buf[1024];
snprintf(buf, sizeof(buf),
"SPDK FIO plugin won't work with daemonized FIO server.");
"SPDK FIO plugin is in daemon mode, but stdout/stderr "
"aren't redirected to /dev/null. Aborting.");
fio_server_text_output(FIO_LOG_ERR, buf, sizeof(buf));
return -1;
}

View File

@ -501,6 +501,27 @@ static void parse_pract_flag(int pract)
}
}
static bool
fio_redirected_to_dev_null(void)
{
char path[PATH_MAX] = "";
ssize_t ret;
ret = readlink("/proc/self/fd/1", path, sizeof(path));
if (ret == -1 || strcmp(path, "/dev/null") != 0) {
return false;
}
ret = readlink("/proc/self/fd/2", path, sizeof(path));
if (ret == -1 || strcmp(path, "/dev/null") != 0) {
return false;
}
return true;
}
/* Called once at initialization. This is responsible for gathering the size of
* each "file", which in our case are in the form
* 'key=value [key=value] ... ns=value'
@ -519,16 +540,18 @@ static int spdk_fio_setup(struct thread_data *td)
char *trid_info;
unsigned int i;
/* we might be running in a daemonized FIO instance where standard
* input and output were closed and fds 0, 1, and 2 are reused
* for something important by FIO. We can't ensure we won't print
* anything (and so will our dependencies, e.g. DPDK), so abort early.
* (is_backend is an fio global variable)
/*
* If we're running in a daemonized FIO instance, it's possible
* fd 1/2 were re-used for something important by FIO. Newer fio
* versions are careful to redirect those to /dev/null, but if we're
* not, we'll abort early, so we don't accidentally write messages to
* an important file, etc.
*/
if (is_backend) {
if (is_backend && !fio_redirected_to_dev_null()) {
char buf[1024];
snprintf(buf, sizeof(buf),
"SPDK FIO plugin won't work with daemonized FIO server.");
"SPDK FIO plugin is in daemon mode, but stdout/stderr "
"aren't redirected to /dev/null. Aborting.");
fio_server_text_output(FIO_LOG_ERR, buf, sizeof(buf));
return -1;
}