MXS-1705 Try with O_DIRECT, if fails try without
Instead of trying to figure out whether the kernel supports O_DIRECT in conjunction with pipes, let's just use it and if it fails, try without O_DIRECT. Case in point, based on circumstantial evidence it seems that in a container context, it may appear as if the kernel supports O_DIRECT when it in reality does not. So better to use brute-force.
This commit is contained in:
@ -16,7 +16,6 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/utsname.h>
|
|
||||||
#include <maxscale/debug.h>
|
#include <maxscale/debug.h>
|
||||||
#include <maxscale/log_manager.h>
|
#include <maxscale/log_manager.h>
|
||||||
#include "internal/worker.hh"
|
#include "internal/worker.hh"
|
||||||
@ -27,11 +26,9 @@ namespace
|
|||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
bool initialized;
|
bool initialized;
|
||||||
int pipe_flags;
|
|
||||||
} this_unit =
|
} this_unit =
|
||||||
{
|
{
|
||||||
false,
|
false
|
||||||
O_NONBLOCK | O_CLOEXEC
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -67,63 +64,6 @@ bool MessageQueue::init()
|
|||||||
{
|
{
|
||||||
ss_dassert(!this_unit.initialized);
|
ss_dassert(!this_unit.initialized);
|
||||||
|
|
||||||
/* From "man 7 pipe"
|
|
||||||
* ----
|
|
||||||
*
|
|
||||||
* O_NONBLOCK enabled, n <= PIPE_BUF
|
|
||||||
* If there is room to write n bytes to the pipe, then write(2)
|
|
||||||
* succeeds immediately, writing all n bytes; otherwise write(2)
|
|
||||||
* fails, with errno set to EAGAIN.
|
|
||||||
*
|
|
||||||
* ... (On Linux, PIPE_BUF is 4096 bytes.)
|
|
||||||
*
|
|
||||||
* ----
|
|
||||||
*
|
|
||||||
* As O_NONBLOCK is set and the messages are less than 4096 bytes,
|
|
||||||
* O_DIRECT should not be needed and we should be safe without it.
|
|
||||||
*
|
|
||||||
* However, to be in the safe side, if we run on kernel version >= 3.4
|
|
||||||
* we use it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
utsname u;
|
|
||||||
|
|
||||||
if (uname(&u) == 0)
|
|
||||||
{
|
|
||||||
char* p;
|
|
||||||
char* zMajor = strtok_r(u.release, ".", &p);
|
|
||||||
char* zMinor = strtok_r(NULL, ".", &p);
|
|
||||||
|
|
||||||
if (zMajor && zMinor)
|
|
||||||
{
|
|
||||||
int major = atoi(zMajor);
|
|
||||||
int minor = atoi(zMinor);
|
|
||||||
|
|
||||||
if (major >= 3 && minor >= 4)
|
|
||||||
{
|
|
||||||
// O_DIRECT for pipes is supported from kernel 3.4 onwards.
|
|
||||||
this_unit.pipe_flags |= O_DIRECT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MXS_NOTICE("O_DIRECT is not supported for pipes on Linux kernel %s "
|
|
||||||
"(supported from version 3.4 onwards), NOT using it.",
|
|
||||||
u.release);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MXS_WARNING("Syntax used in utsname.release seems to have changed, "
|
|
||||||
"not able to figure out current kernel version. Assuming "
|
|
||||||
"O_DIRECT is not supported for pipes.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MXS_WARNING("uname() failed, assuming O_DIRECT is not supported for pipes: %s",
|
|
||||||
mxs_strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
this_unit.initialized = true;
|
this_unit.initialized = true;
|
||||||
|
|
||||||
return this_unit.initialized;
|
return this_unit.initialized;
|
||||||
@ -144,7 +84,23 @@ MessageQueue* MessageQueue::create(Handler* pHandler)
|
|||||||
MessageQueue* pThis = NULL;
|
MessageQueue* pThis = NULL;
|
||||||
|
|
||||||
int fds[2];
|
int fds[2];
|
||||||
if (pipe2(fds, this_unit.pipe_flags) == 0)
|
|
||||||
|
int rv = pipe2(fds, O_NONBLOCK | O_CLOEXEC | O_DIRECT);
|
||||||
|
|
||||||
|
if ((rv != 0) && (errno == EINVAL))
|
||||||
|
{
|
||||||
|
// Ok, apparently the kernel does not support O_DIRECT. Let's try without.
|
||||||
|
rv = pipe2(fds, O_NONBLOCK | O_CLOEXEC);
|
||||||
|
|
||||||
|
if (rv == 0)
|
||||||
|
{
|
||||||
|
// Succeeded, so apparently it was the missing support for O_DIRECT.
|
||||||
|
MXS_WARNING("Platform does not support O_DIRECT in conjunction with pipes, "
|
||||||
|
"using without.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rv == 0)
|
||||||
{
|
{
|
||||||
int read_fd = fds[0];
|
int read_fd = fds[0];
|
||||||
int write_fd = fds[1];
|
int write_fd = fds[1];
|
||||||
|
|||||||
Reference in New Issue
Block a user