Allow defining monitordirs variable: subset/dir of topdirs which will get monitored for updates

This commit is contained in:
Jean-Francois Dockes 2018-04-11 17:45:06 +02:00
parent 68e6b9f8d0
commit 8559572c7e
6 changed files with 90 additions and 28 deletions

View File

@ -585,18 +585,24 @@ pair<int,int> RclConfig::getThrConf(ThrStage who) const
return m_thrConf[who];
}
vector<string> RclConfig::getTopdirs() const
vector<string> RclConfig::getTopdirs(bool formonitor) const
{
vector<string> tdl;
if (!getConfParam("topdirs", &tdl)) {
LOGERR("RclConfig::getTopdirs: no top directories in config or "
"bad list format\n");
if (formonitor) {
if (!getConfParam("monitordirs", &tdl)) {
getConfParam("topdirs", &tdl);
}
} else {
getConfParam("topdirs", &tdl);
}
if (tdl.empty()) {
LOGERR("RclConfig::getTopdirs: nothing to index: topdirs/monitordirs "
" are not set or have a bad list format\n");
return tdl;
}
for (vector<string>::iterator it = tdl.begin(); it != tdl.end(); it++) {
*it = path_tildexpand(*it);
*it = path_canon(*it);
for (auto& dir : tdl) {
dir = path_canon(path_tildexpand(dir));
}
return tdl;
}

View File

@ -182,8 +182,11 @@ class RclConfig {
/** Get list of top directories. This is needed from a number of places
* and needs some cleaning-up code. An empty list is always an error, no
* need for other status */
vector<string> getTopdirs() const;
* need for other status
* @param formonitor if set retrieve the list for real time monitoring
* (if the monitor list does not exist we return the normal one).
*/
vector<string> getTopdirs(bool formonitor = false) const;
string getConfdirPath(const char *varname, const char *dflt) const;
string getCachedirPath(const char *varname, const char *dflt) const;

View File

@ -161,8 +161,9 @@ void *rclMonRcvRun(void *q)
return 0;
}
// Get top directories from config
vector<string> tdl = lconfig.getTopdirs();
// Get top directories from config. Special monitor sublist if
// set, else full list.
vector<string> tdl = lconfig.getTopdirs(true);
if (tdl.empty()) {
LOGERR("rclMonRcvRun:: top directory list (topdirs param.) not found "
"in configuration or topdirs list parse error");

View File

@ -201,6 +201,18 @@ void rclIxIonice(const RclConfig *config)
#endif
}
static void setMyPriority(const RclConfig *config)
{
#ifndef _WIN32
if (setpriority(PRIO_PROCESS, 0, 20) != 0) {
LOGINFO("recollindex: can't setpriority(), errno " << errno << "\n");
}
// Try to ionice. This does not work on all platforms
rclIxIonice(config);
#endif
}
class MakeListWalkerCB : public FsTreeWalkerCB {
public:
MakeListWalkerCB(list<string>& files, const vector<string>& selpats)
@ -316,10 +328,33 @@ static bool checktopdirs(RclConfig *config, vector<string>& nonexist)
vector<string> tdl;
if (!config->getConfParam("topdirs", &tdl)) {
cerr << "No 'topdirs' parameter in configuration\n";
LOGERR("recollindex:No 'topdirs' parameter in configuration\n");;
LOGERR("recollindex:No 'topdirs' parameter in configuration\n");
return false;
}
// If a restricted list for real-time monitoring exists check that
// all entries are descendants from a topdir
vector<string> mondirs;
if (config->getConfParam("monitordirs", &mondirs)) {
for (const auto& sub : mondirs) {
bool found{false};
for (const auto& top : tdl) {
if (path_isdesc(top, sub)) {
found = true;
break;
}
}
if (!found) {
string s("Real time monitoring directory entry " + sub +
" is not part of the topdirs tree\n");
cerr << s;
LOGERR(s);
return false;
}
}
}
for (vector<string>::iterator it = tdl.begin(); it != tdl.end(); it++) {
*it = path_tildexpand(*it);
if (!it->size() || !path_isabsolute(*it)) {
@ -639,14 +674,8 @@ int main(int argc, char **argv)
// Log something at LOGINFO to reset the trace file. Else at level
// 3 it's not even truncated if all docs are up to date.
LOGINFO("recollindex: starting up\n");
#ifndef _WIN32
if (setpriority(PRIO_PROCESS, 0, 20) != 0) {
LOGINFO("recollindex: can't setpriority(), errno " << errno << "\n");
}
// Try to ionice. This does not work on all platforms
rclIxIonice(config);
#endif
setMyPriority(config);
if (op_flags & OPT_r) {
if (argc != 1)
Usage();
@ -732,15 +761,9 @@ int main(int argc, char **argv)
}
// Need to rewrite pid, it changed
pidfile.write_pid();
#ifndef _WIN32
// Not too sure if I have to redo the nice thing after daemon(),
// can't hurt anyway (easier than testing on all platforms...)
if (setpriority(PRIO_PROCESS, 0, 20) != 0) {
LOGINFO("recollindex: can't setpriority(), errno " << errno<< "\n");
}
// Try to ionice. This does not work on all platforms
rclIxIonice(config);
#endif
setMyPriority(config);
if (sleepsecs > 0) {
LOGDEB("recollindex: sleeping " << sleepsecs << "\n");
@ -753,6 +776,7 @@ int main(int argc, char **argv)
}
}
}
if (!(op_flags & OPT_n)) {
makeIndexerOrExit(config, inPlaceReset);
LOGDEB("Recollindex: initial indexing pass before monitoring\n");
@ -776,10 +800,11 @@ int main(int argc, char **argv)
// Note that -n will be inside the reexec when we come
// back, but the monitor will explicitely strip it before
// starting a config change exec to ensure that we do a
// purging pass in this case.
// purging pass in this latter case (full restart).
o_reexec->reexec();
#endif
}
if (updater) {
updater->status.phase = DbIxStatus::DBIXS_MONITOR;
updater->status.fn.clear();

View File

@ -353,6 +353,29 @@ bool path_isroot(const string& path)
return false;
}
bool path_isdesc(const string& _top, const string& _sub)
{
string top = path_canon(_top);
string sub = path_canon(_sub);
path_catslash(top);
path_catslash(sub);
for (;;) {
if (sub == top) {
return true;
}
string::size_type l = sub.size();
sub = path_getfather(sub);
if (sub.size() == l || sub.size() < top.size()) {
// At root or sub shorter than top: done
if (sub == top) {
return true;
} else {
return false;
}
}
}
}
bool path_isabsolute(const string& path)
{
if (!path.empty() && (path[0] == '/'

View File

@ -113,6 +113,10 @@ extern bool path_isabsolute(const std::string& s);
/// Test if path is root (x:/). root is defined by root/.. == root
extern bool path_isroot(const std::string& p);
/// Test if sub is a subdirectory of top. This is a textual test,
/// links not allowed
extern bool path_isdesc(const std::string& top, const std::string& sub);
/// Turn absolute path into file:// url
extern std::string path_pathtofileurl(const std::string& path);