summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoonsoo Kim <yoonsoo.kim@mongodb.com>2023-01-06 01:01:06 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-01-06 02:00:00 +0000
commit206da68ef3b725bbc3a3b5555802f76f4ed0856d (patch)
treecfe2d5124e99fd5050d21a7107a83868970ea184
parentc8ed1cb8119aedaf03fbd79f2282af975ee2426c (diff)
downloadmongo-206da68ef3b725bbc3a3b5555802f76f4ed0856d.tar.gz
SERVER-72441 Log an error message for remove() only when it's necessary
-rw-r--r--src/mongo/db/storage/named_pipe_posix.cpp45
1 files changed, 31 insertions, 14 deletions
diff --git a/src/mongo/db/storage/named_pipe_posix.cpp b/src/mongo/db/storage/named_pipe_posix.cpp
index 63d955a8df5..b5dfd5dd012 100644
--- a/src/mongo/db/storage/named_pipe_posix.cpp
+++ b/src/mongo/db/storage/named_pipe_posix.cpp
@@ -31,6 +31,7 @@
#include "mongo/db/storage/named_pipe.h"
+#include <cerrno>
#include <cstdio>
#include <fmt/format.h>
#include <string>
@@ -41,6 +42,7 @@
#include "mongo/db/storage/io_error_message.h"
#include "mongo/logv2/log.h"
#include "mongo/stdx/thread.h"
+#include "mongo/util/assert_util.h"
namespace mongo {
using namespace fmt::literals;
@@ -48,14 +50,24 @@ using namespace fmt::literals;
#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kTest
namespace {
-// Removes the named pipe and logs an info message if there's an error. The info message should be
-// fine since this is a test-only implementation.
-void removeAndLog(const char* pipeAbsolutePath) {
- // Suppress the expected non-error "error" ENOENT ("No such file or directory").
- if ((remove(pipeAbsolutePath) < 0) && (errno != ENOENT)) {
- LOGV2_INFO(7097000,
- "Failed to remove",
- "error"_attr = getErrorMessage("remove", pipeAbsolutePath));
+// 'rc' must be the return code from POSIX-like OS I/O APIs.
+inline bool hasSucceeded(int rc) {
+ // POSIX-like I/O APIs return 0 for the successful operation.
+ return rc == 0;
+}
+
+// Removes the named pipe and logs an error message when
+// - either 'ignoreNoEntError' == true and there's an error other than the ENOENT error
+// - or 'ignoreNoEntError' == false and there's any error
+void removeNamedPipe(bool ignoreNoEntError, const char* pipeAbsolutePath) {
+ if (!hasSucceeded(remove(pipeAbsolutePath))) {
+ if (ignoreNoEntError && errno == ENOENT) {
+ return;
+ }
+
+ LOGV2_ERROR(7097000,
+ "Failed to remove",
+ "error"_attr = getErrorMessage("remove", pipeAbsolutePath));
}
}
} // namespace
@@ -63,18 +75,18 @@ void removeAndLog(const char* pipeAbsolutePath) {
NamedPipeOutput::NamedPipeOutput(const std::string& pipeDir, const std::string& pipeRelativePath)
: _pipeAbsolutePath(pipeDir + pipeRelativePath), _ofs() {
// Just in case that uncleaned-up named pipe is still there. This is a test-only implementation
- // and so, it should be fine to just remove it.
- removeAndLog(_pipeAbsolutePath.c_str());
+ // and so, it should be fine to just remove it and ignore the ENOENT error.
+ removeNamedPipe(true /*ignoreNoEntError*/, _pipeAbsolutePath.c_str());
uassert(7005005,
"Failed to create a named pipe, error: {}"_format(
getErrorMessage("mkfifo", _pipeAbsolutePath)),
- mkfifo(_pipeAbsolutePath.c_str(), 0664) == 0);
+ hasSucceeded(mkfifo(_pipeAbsolutePath.c_str(), 0664)));
}
NamedPipeOutput::~NamedPipeOutput() {
close();
// Makes sure that the named pipe is removed.
- removeAndLog(_pipeAbsolutePath.c_str());
+ removeNamedPipe(false /*ignoreNoEntError*/, _pipeAbsolutePath.c_str());
}
void NamedPipeOutput::open() {
@@ -133,16 +145,21 @@ void NamedPipeInput::doOpen() {
// retry) in case the pipe writer has not finished creating the pipe yet.
int retries = 0;
int sleepMs = 1;
+ bool opened;
do {
_ifs.open(_pipeAbsolutePath.c_str(), std::ios::binary | std::ios::in);
- if (!_ifs.is_open()) {
+ opened = _ifs.is_open();
+ if (!opened) {
+ uassert(ErrorCodes::FileNotOpen,
+ "error = {}"_format(getErrorMessage("open", _pipeAbsolutePath)),
+ errno == ENOENT);
stdx::this_thread::sleep_for(stdx::chrono::milliseconds(sleepMs));
++retries;
if (retries % 1000 == 0) {
sleepMs *= 2;
}
}
- } while (!_ifs.is_open() && retries <= 5000);
+ } while (!opened && retries <= 5000);
if (retries > 1000) {
LOGV2_WARNING(7184900,
"NamedPipeInput::doOpen() waited for pipe longer than 1 sec",