From 23d0216a27287de4a39cb6f9b75370915a005408 Mon Sep 17 00:00:00 2001 From: bartfaik04 Date: Sat, 31 May 2025 13:26:44 +0200 Subject: [PATCH 1/4] Usermanager protected with lock_guards --- src/usermanager.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/usermanager.h b/src/usermanager.h index 972d358..f80be14 100644 --- a/src/usermanager.h +++ b/src/usermanager.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "locations.h" std::vector splitLogFile(const std::string& input, char delimiter); @@ -13,6 +14,7 @@ class userManager { private: std::map users; + std::mutex mtx; public: @@ -23,6 +25,7 @@ public: void addUser(std::string &user) { + std::lock_guard lock(mtx); if (users.count(user) == 0) { users[user] = false; @@ -31,16 +34,19 @@ public: void removeUser(std::string &user) { + std::lock_guard lock(mtx); users.erase(user); } bool isContains(std::string &user) { + std::lock_guard lock(mtx); return users.count(user) == 1; } void setUserFlagged(std::string &user) { + std::lock_guard lock(mtx); if (users.count(user) == 1) { users[user] = true; @@ -49,6 +55,7 @@ public: void setUserUnflagged(std::string &user) { + std::lock_guard lock(mtx); if (users.count(user) == 1) { users[user] = false; @@ -57,6 +64,7 @@ public: void unflagAllUsers() { + std::lock_guard lock(mtx); for (std::map::iterator it = users.begin(); it != users.end(); ++it) { it->second = false; @@ -67,6 +75,8 @@ public: { std::vector ret; + std::lock_guard lock(mtx); + for (std::map::iterator it = users.begin(); it != users.end(); ++it) { ret.push_back(it->first); @@ -79,6 +89,8 @@ public: { std::vector ret; + std::lock_guard lock(mtx); + for (std::map::iterator it = users.begin(); it != users.end(); ++it) { if (it->second) -- 2.49.1 From f886dc7162d3dc36de916db4a2a6c5af49e385f9 Mon Sep 17 00:00:00 2001 From: bartfaik04 Date: Sat, 31 May 2025 15:00:38 +0200 Subject: [PATCH 2/4] Multi-process logic changed to multi-thread logic --- src/main.cpp | 137 +++++++++++++++------------------------------- src/usermanager.h | 13 +++++ 2 files changed, 58 insertions(+), 92 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bd9b6d4..fd4c844 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,119 +1,72 @@ +#include #include +#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include "locations.h" +#include +#include +#include #include "usermanager.h" -#include "guarder.h" -#define MAXNAMESIZE 255 -#define SCAN_DONE_SIG SIGRTMIN #define SCAN_CMD_USR "docker exec --user www-data nextcloud /var/www/html/occ files:scan --path=" -int p1[2]; -guarder guard; userManager manager; +std::condition_variable cv; +std::mutex mtx; -void flushManagerToPipe() +void readingThreadFunc() { - if (!guard.isFlagOn()) - { - std::vector users = manager.getFlaggedUsers(); + FILE *logpipe = popen(LOGFILE, "r"); + std::array buffer; + + while (fgets(buffer.data(), buffer.size(), logpipe) != nullptr) + { + std::string line(buffer.data()); + + if (line.find('|') == std::string::npos) + continue; + + std::vector x = splitLogFile(line, '|'); + std::string user(x.at(USER_LOG_LOCATION)); - for (std::vector::iterator it = users.begin(); it != users.end(); ++it) { - int size = it->size(); - write(p1[1], &size, sizeof(int)); - write(p1[1], it->data(), size * sizeof(char)); + std::lock_guard lock(mtx); + manager.addUser(user); + manager.setUserFlagged(user); } - manager.unflagAllUsers(); + cv.notify_one(); + + std::cout << "User find: " << user << std::endl; } } -void handler(int sig) +void scannerThreadFunc() { - if (sig == SCAN_DONE_SIG) + std::unique_lock lock(mtx); + while (true) { - flushManagerToPipe(); + cv.wait(lock, [] + { return manager.isAnybodyInQueue(); }); + + std::vector scanUsers = manager.getFlaggedUsers(); + manager.unflagAllUsers(); + + for (std::vector::iterator it = scanUsers.begin(); it != scanUsers.end(); it++) + { + system((std::string(SCAN_CMD_USR) + *it).c_str()); + } } } int main() { - openlog("ncsambawatcher", LOG_PID | LOG_CONS, LOG_USER); - pipe(p1); + std::thread readingThread(readingThreadFunc); + std::thread scannerThread(scannerThreadFunc); - pid_t parent = getpid(); - pid_t child = fork(); + readingThread.join(); + scannerThread.join(); - if (child > 0) // parent - { - signal(SCAN_DONE_SIG, handler); - close(p1[0]); // read - - FILE *logpipe = popen(LOGFILE, "r"); - std::array buffer; - - while (fgets(buffer.data(), buffer.size(), logpipe) != nullptr) - { - std::string line(buffer.data()); - - if (line.find('|') == std::string::npos) - continue; - - std::vector x = splitLogFile(line, '|'); - std::string user(x.at(USER_LOG_LOCATION)); - manager.addUser(user); - manager.setUserFlagged(user); - - std::cout << "User find: " << user << std::endl; - - flushManagerToPipe(); - } - - fclose(logpipe); - close(p1[1]); // write - } - else // child - { - close(p1[1]); // write - - int size; - char *buffer = nullptr; - - while (read(p1[0], &size, sizeof(int))) - { - if (buffer == nullptr) - buffer = new char[size]; - - read(p1[0], buffer, size * sizeof(char)); - std::string name(buffer); - - std::cout << "Scan received for: " << name << std::endl; - - guard.setFlagOn(); - system((std::string(SCAN_CMD_USR) + name).data()); - guard.setFlagOff(); - - kill(parent, SCAN_DONE_SIG); - - if (buffer != nullptr) - { - delete[] buffer; - buffer = nullptr; - } - } - - close(p1[0]); // read - } - - closelog(); - - return EXIT_SUCCESS; + return 0; } \ No newline at end of file diff --git a/src/usermanager.h b/src/usermanager.h index f80be14..a313083 100644 --- a/src/usermanager.h +++ b/src/usermanager.h @@ -101,6 +101,19 @@ public: return ret; } + + bool isAnybodyInQueue() + { + std::lock_guard lock(mtx); + + for (std::map::iterator it = users.begin(); it != users.end(); ++it) + { + if (it->second) + return true; + } + + return false; + } }; #endif // _USERMAN_H \ No newline at end of file -- 2.49.1 From c57b022278c9036ad4cb9b9608cf9318620e684e Mon Sep 17 00:00:00 2001 From: bartfaik04 Date: Sun, 1 Jun 2025 12:12:59 +0200 Subject: [PATCH 3/4] Replace scan to a child process --- src/main.cpp | 38 ++++++++++++++++++++++++++++++++++---- src/usermanager.h | 15 ++++++++------- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index fd4c844..0a16c9a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,10 @@ #include +#include +#include #include #include #include +#include #include #include #include @@ -45,18 +48,45 @@ void readingThreadFunc() void scannerThreadFunc() { std::unique_lock lock(mtx); + std::vector childrens; while (true) { cv.wait(lock, [] - { return manager.isAnybodyInQueue(); }); + { return manager.isAnybodyFlagged(); }); - std::vector scanUsers = manager.getFlaggedUsers(); + std::set scanUsers = manager.getFlaggedUsers(); manager.unflagAllUsers(); - for (std::vector::iterator it = scanUsers.begin(); it != scanUsers.end(); it++) + lock.unlock(); + childrens.clear(); + + for (const std::string& user : scanUsers) { - system((std::string(SCAN_CMD_USR) + *it).c_str()); + pid_t child = fork(); + + if (child < 0) + { + std::cerr << "Fork failed for: " << user << std::endl; + } + else if (child == 0) // child + { + std::string cmd = (std::string(SCAN_CMD_USR) + user); + execl("/bin/sh", "sh", "-c", cmd.c_str(), static_cast(nullptr)); + std::cerr << "Scan failed" << std::endl; + _exit(EXIT_FAILURE); + } + else // parent + { + childrens.push_back(child); + } } + + for (const pid_t& pid : childrens) + { + waitpid(pid, nullptr, 0); + } + + lock.lock(); } } diff --git a/src/usermanager.h b/src/usermanager.h index a313083..5a7ea14 100644 --- a/src/usermanager.h +++ b/src/usermanager.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include "locations.h" @@ -71,23 +72,23 @@ public: } } - std::vector getUsers() + std::set getUsers() { - std::vector ret; + std::set ret; std::lock_guard lock(mtx); for (std::map::iterator it = users.begin(); it != users.end(); ++it) { - ret.push_back(it->first); + ret.insert(it->first); } return ret; } - std::vector getFlaggedUsers() + std::set getFlaggedUsers() { - std::vector ret; + std::set ret; std::lock_guard lock(mtx); @@ -95,14 +96,14 @@ public: { if (it->second) { - ret.push_back(it->first); + ret.insert(it->first); } } return ret; } - bool isAnybodyInQueue() + bool isAnybodyFlagged() { std::lock_guard lock(mtx); -- 2.49.1 From 1113a21b2d53176992e65b686f1d11f926876d28 Mon Sep 17 00:00:00 2001 From: bartfaik04 Date: Sun, 1 Jun 2025 12:15:52 +0200 Subject: [PATCH 4/4] Update ncsambawatcher.service --- configs/ncsambawatcher.service | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configs/ncsambawatcher.service b/configs/ncsambawatcher.service index c2330c1..f4f35f3 100644 --- a/configs/ncsambawatcher.service +++ b/configs/ncsambawatcher.service @@ -1,6 +1,7 @@ [Unit] Description=A service which scan Nextcloud folders -After=network.target +After=network.target docker.service +Requires=docker.service [Service] ExecStart=/usr/bin/ncsambawatcher -- 2.49.1