From 620bd2637b40d718dd5886ce7df0a19b73ea8875 Mon Sep 17 00:00:00 2001 From: Maksym Telychko Date: Tue, 24 Mar 2020 17:41:04 +0200 Subject: MTX-3262 mpower: lockfile rewrite for interprocess communication safety Previous implementation was not thread/interprocess safe due to pid management Fixes: Single instance guard. --- src/MTS_IO_LockFile.cpp | 92 ++++++++++++++----------------------------------- 1 file changed, 25 insertions(+), 67 deletions(-) (limited to 'src/MTS_IO_LockFile.cpp') diff --git a/src/MTS_IO_LockFile.cpp b/src/MTS_IO_LockFile.cpp index b74ba73..4312ce4 100644 --- a/src/MTS_IO_LockFile.cpp +++ b/src/MTS_IO_LockFile.cpp @@ -18,9 +18,9 @@ * */ -/*! +/*! \file MTS_IO_LockFile.cpp - \brief A brief description + \brief A brief description \date Oct 8, 2014 \author sgodinez @@ -29,13 +29,7 @@ #include #include -#include -#include -#include #include -#include -#include -#include #include using namespace MTS::IO; @@ -43,79 +37,43 @@ using namespace MTS::IO; LockFile::LockFile(const std::string& sFile) : m_sFile(sFile) , m_iLockFd(-1) +, m_iLockErr(-1) { - } -LockFile::~LockFile() { +LockFile::~LockFile() +{ unlock(); } -bool LockFile::lock(uint32_t attemptMillis) { - if(isLocked()) { +bool LockFile::lock(uint32_t attemptMillis) +{ + if (isLocked()) return true; - } MTS::Timer timer; - timer.start(); - while(timer.getMillis() < attemptMillis) { - m_iLockFd =::open(m_sFile.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0644); - if (m_iLockFd < 0) { - // device already locked -> bail out - printWarning("LockFile| Failed to Lock [%s] [%d][%s]", m_sFile.c_str(), errno, strerror(errno)); - - //Check if lock file's process still exists - std::string sResult; - if(MTS::System::readFile(m_sFile, sResult) == 0 && sResult.size() > 0) { - struct stat sts; - std::string sProc = "/proc/" + MTS::Text::trim(sResult); - if (stat(sProc.c_str(), &sts) == -1 && errno == ENOENT) { - printWarning("LockFile| Current Lock's Process [%s] does not exist. Removing lock.", sResult.c_str()); - // process doesn't exist -> remove file - ::unlink(m_sFile.c_str()); - } - } - - } else { - //TODO: Investigate using flock in addition to minicom-style lock : flock(m_iLockFd, LOCK_EX | LOCK_NB); - - // %4d to make concurrent mgetty (if any) happy. - // Mgetty treats 4-bytes lock files as binary, - // not text, PID. Making 5+ char file. Brrr... - char buf[256] = {0}; - size_t written = 0; - - sprintf(buf, "%4d\n", getpid()); - size_t wsize = strlen(buf); - - written = write(m_iLockFd, buf, wsize); - - if (wsize != written) { - printError("LockFile| Error writing to lock file [%s] [%d][%s]", m_sFile.c_str(), errno, strerror(errno)); - close(m_iLockFd); - return false; - } - else { - close(m_iLockFd); - return true; - } - } - uint32_t randomSleepTime = ((rand() % 10) + 1) * 100000; //Sleep from 100ms to 1 Second - ::usleep(randomSleepTime); + m_iLockFd = ::open(m_sFile.c_str(), O_CREAT | O_RDWR, 0666); + while (timer.getMillis() < attemptMillis) { + m_iLockErr = ::flock(m_iLockFd, LOCK_EX | LOCK_NB); + if (m_iLockErr == 0) + return true; + ::usleep(((rand() % 10) + 1) * 100000); //Sleep from 100ms to 1 Second } + ::close(m_iLockFd); + m_iLockFd = -1; return false; } -void LockFile::unlock() { - if(isLocked()) { - ::unlink(m_sFile.c_str()); - //TODO: flock cleanup : flock(m_iLockFd, LOCK_UN); - m_iLockFd = -1; - } +void LockFile::unlock() +{ + ::flock(m_iLockFd, LOCK_UN); + ::close(m_iLockFd); + m_iLockFd = -1; + m_iLockErr = -1; } -bool LockFile::isLocked() { - return m_iLockFd >= 0; +bool LockFile::isLocked() +{ + return m_iLockErr == 0; } - -- cgit v1.2.3 From 2418037578c64516803d0ac261545c1b8fb69ac2 Mon Sep 17 00:00:00 2001 From: Maksym Telychko Date: Tue, 24 Mar 2020 19:13:58 +0200 Subject: MTX-3262 mpower lockfile: additional fd check on lock --- src/MTS_IO_LockFile.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'src/MTS_IO_LockFile.cpp') diff --git a/src/MTS_IO_LockFile.cpp b/src/MTS_IO_LockFile.cpp index 4312ce4..842ffb7 100644 --- a/src/MTS_IO_LockFile.cpp +++ b/src/MTS_IO_LockFile.cpp @@ -48,19 +48,23 @@ LockFile::~LockFile() bool LockFile::lock(uint32_t attemptMillis) { - if (isLocked()) + if (isLocked()) { return true; + } - MTS::Timer timer; - timer.start(); m_iLockFd = ::open(m_sFile.c_str(), O_CREAT | O_RDWR, 0666); - while (timer.getMillis() < attemptMillis) { - m_iLockErr = ::flock(m_iLockFd, LOCK_EX | LOCK_NB); - if (m_iLockErr == 0) - return true; - ::usleep(((rand() % 10) + 1) * 100000); //Sleep from 100ms to 1 Second + if (m_iLockFd >= 0) { + MTS::Timer timer; + timer.start(); + while (timer.getMillis() < attemptMillis) { + m_iLockErr = ::flock(m_iLockFd, LOCK_EX | LOCK_NB); + if (m_iLockErr == 0) { + return true; + } + ::usleep(((rand() % 10) + 1) * 100000); //Sleep from 100ms to 1 Second + } + ::close(m_iLockFd); } - ::close(m_iLockFd); m_iLockFd = -1; return false; } -- cgit v1.2.3 From b565b66b48e2ced3a6b2c6c327e458213b08201e Mon Sep 17 00:00:00 2001 From: Maksym Telychko Date: Wed, 25 Mar 2020 22:28:30 +0200 Subject: MTX-3262 mpower lockfile: flock error check --- src/MTS_IO_LockFile.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/MTS_IO_LockFile.cpp') diff --git a/src/MTS_IO_LockFile.cpp b/src/MTS_IO_LockFile.cpp index 842ffb7..ce6655c 100644 --- a/src/MTS_IO_LockFile.cpp +++ b/src/MTS_IO_LockFile.cpp @@ -60,6 +60,8 @@ bool LockFile::lock(uint32_t attemptMillis) m_iLockErr = ::flock(m_iLockFd, LOCK_EX | LOCK_NB); if (m_iLockErr == 0) { return true; + } else if (errno != EWOULDBLOCK) { + break; } ::usleep(((rand() % 10) + 1) * 100000); //Sleep from 100ms to 1 Second } -- cgit v1.2.3 From eb58146a8e5387968a2b45367ad7fd29f6db2fbe Mon Sep 17 00:00:00 2001 From: Maksym Telychko Date: Mon, 30 Mar 2020 14:36:58 +0300 Subject: MTX-3262 mpower lockfile: fix file access rights --- src/MTS_IO_LockFile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/MTS_IO_LockFile.cpp') diff --git a/src/MTS_IO_LockFile.cpp b/src/MTS_IO_LockFile.cpp index ce6655c..7f84f42 100644 --- a/src/MTS_IO_LockFile.cpp +++ b/src/MTS_IO_LockFile.cpp @@ -52,7 +52,7 @@ bool LockFile::lock(uint32_t attemptMillis) return true; } - m_iLockFd = ::open(m_sFile.c_str(), O_CREAT | O_RDWR, 0666); + m_iLockFd = ::open(m_sFile.c_str(), O_CREAT | O_RDWR, 0644); if (m_iLockFd >= 0) { MTS::Timer timer; timer.start(); -- cgit v1.2.3