recollindex: make sure that the computed lock file path is the same in all cases. Take the lock in a number of forgotten cases

This commit is contained in:
Jean-Francois Dockes 2020-08-31 11:28:44 +02:00
parent 20e845709e
commit 5ea2f7cc64
2 changed files with 122 additions and 127 deletions

View File

@ -1398,7 +1398,9 @@ string RclConfig::getPidfile() const
if (p) { if (p) {
string base = path_canon(p); string base = path_canon(p);
string digest, hex; string digest, hex;
MD5String(getConfDir(), digest); string cfdir = path_canon(getConfDir());
path_catslash(cfdir);
MD5String(cfdir, digest);
MD5HexPrint(digest, hex); MD5HexPrint(digest, hex);
return path_cat(base, "/recoll-" + hex + "-index.pid"); return path_cat(base, "/recoll-" + hex + "-index.pid");
} }

View File

@ -71,7 +71,6 @@ static int op_flags;
#define OPT_R 0x20 #define OPT_R 0x20
#define OPT_S 0x40 #define OPT_S 0x40
#define OPT_Z 0x80 #define OPT_Z 0x80
#define OPT_b 0x100
#define OPT_c 0x200 #define OPT_c 0x200
#define OPT_e 0x400 #define OPT_e 0x400
#define OPT_f 0x800 #define OPT_f 0x800
@ -119,8 +118,7 @@ public:
} }
} }
virtual bool update() virtual bool update() {
{
// Update the status file. Avoid doing it too often. Always do // Update the status file. Avoid doing it too often. Always do
// it at the end (status DONE) // it at the end (status DONE)
if (status.phase == DbIxStatus::DBIXS_DONE || if (status.phase == DbIxStatus::DBIXS_DONE ||
@ -478,29 +476,29 @@ static const char usage [] =
static void Usage() static void Usage()
{ {
FILE *fp = (op_flags & OPT_h) ? stdout : stderr; FILE *fp = (op_flags & OPT_h) ? stdout : stderr;
fprintf(fp, "%s: Usage: %s", path_getsimple(thisprog).c_str(), usage); fprintf(fp, "%s: Usage: %s", path_getsimple(thisprog).c_str(), usage);
fprintf(fp, "Recoll version: %s\n", Rcl::version_string().c_str()); fprintf(fp, "Recoll version: %s\n", Rcl::version_string().c_str());
exit((op_flags & OPT_h)==0); exit((op_flags & OPT_h)==0);
} }
static RclConfig *config; static RclConfig *config;
static void lockorexit(Pidfile *pidfile, RclConfig *config) static void lockorexit(Pidfile *pidfile, RclConfig *config)
{ {
PRETEND_USE(config); PRETEND_USE(config);
pid_t pid; pid_t pid;
if ((pid = pidfile->open()) != 0) { if ((pid = pidfile->open()) != 0) {
if (pid > 0) { if (pid > 0) {
cerr << "Can't become exclusive indexer: " << pidfile->getreason() cerr << "Can't become exclusive indexer: " << pidfile->getreason()
<< ". Return (other pid?): " << pid << endl; << ". Return (other pid?): " << pid << endl;
#ifndef _WIN32 #ifndef _WIN32
// Have a look at the status file. If the other process is // Have a look at the status file. If the other process is
// a monitor we can tell it to start an incremental pass // a monitor we can tell it to start an incremental pass
// by touching the configuration file // by touching the configuration file
DbIxStatus status; DbIxStatus status;
readIdxStatus(config, status); readIdxStatus(config, status);
if (status.hasmonitor) { if (status.hasmonitor) {
string cmd("touch "); string cmd("touch ");
string path = path_cat(config->getConfDir(), "recoll.conf"); string path = path_cat(config->getConfDir(), "recoll.conf");
cmd += path; cmd += path;
@ -511,19 +509,19 @@ if (status.hasmonitor) {
cerr << "Monitoring indexer process was notified of " cerr << "Monitoring indexer process was notified of "
"indexing request\n"; "indexing request\n";
} }
} }
#endif #endif
} else { } else {
cerr << "Can't become exclusive indexer: " << pidfile->getreason() cerr << "Can't become exclusive indexer: " << pidfile->getreason()
<< endl; << endl;
} }
exit(1); exit(1);
} }
if (pidfile->write_pid() != 0) { if (pidfile->write_pid() != 0) {
cerr << "Can't become exclusive indexer: " << pidfile->getreason() << cerr << "Can't become exclusive indexer: " << pidfile->getreason() <<
endl; endl;
exit(1); exit(1);
} }
} }
static string reasonsfile; static string reasonsfile;
@ -599,13 +597,13 @@ static std::string orig_cwd;
#if USE_WMAIN #if USE_WMAIN
int wmain(int argc, wchar_t *argv[]) int wmain(int argc, wchar_t *argv[])
#else #else
int main(int argc, char *argv[]) int main(int argc, char *argv[])
#endif #endif
{ {
#ifndef _WIN32
// The reexec struct is used by the daemon to shed memory after // The reexec struct is used by the daemon to shed memory after
// the initial indexing pass and to restart when the configuration // the initial indexing pass and to restart when the configuration
// changes // changes
#ifndef _WIN32
o_reexec = new ReExec; o_reexec = new ReExec;
o_reexec->init(argc, argv); o_reexec->init(argc, argv);
#endif #endif
@ -613,7 +611,8 @@ int wmain(int argc, wchar_t *argv[])
vector<string> args = argstovector(argc, argv); vector<string> args = argstovector(argc, argv);
// Passing args through a temp file: this is used on Windows to // Passing args through a temp file: this is used on Windows to
// avoid issues with charsets in args (avoid using wmain) // avoid issues with charsets in args (thought to avoid using
// wmain, which proved false, but the args file was kept)
if (args.size() == 1 && args[0][0] != '-') { if (args.size() == 1 && args[0][0] != '-') {
args = fileToArgs(args[0]); args = fileToArgs(args[0]);
} }
@ -631,7 +630,6 @@ int wmain(int argc, wchar_t *argv[])
} }
for (unsigned int cidx = 1; cidx < arg.size(); cidx++) { for (unsigned int cidx = 1; cidx < arg.size(); cidx++) {
switch (arg[cidx]) { switch (arg[cidx]) {
case 'b': op_flags |= OPT_b; break;
case 'c': op_flags |= OPT_c; if (aremain < 2) Usage(); case 'c': op_flags |= OPT_c; if (aremain < 2) Usage();
a_config = args[argidx+1]; argidx++; goto b1; a_config = args[argidx+1]; argidx++; goto b1;
#ifdef RCL_MONITOR #ifdef RCL_MONITOR
@ -675,9 +673,10 @@ int wmain(int argc, wchar_t *argv[])
if (op_flags & OPT_h) if (op_flags & OPT_h)
Usage(); Usage();
#ifndef RCL_MONITOR #ifndef RCL_MONITOR
if (op_flags & (OPT_m | OPT_w|OPT_x)) { if (op_flags & (OPT_m | OPT_w|OPT_x)) {
cerr << "Sorry, -m not available: real-time monitoring was not " cerr << "-m not available: real-time monitoring was not "
"configured in this build\n"; "configured in this build\n";
exit(1); exit(1);
} }
@ -720,15 +719,24 @@ int wmain(int argc, wchar_t *argv[])
cerr << "Warning: invalid paths in topdirs, skippedPaths or " cerr << "Warning: invalid paths in topdirs, skippedPaths or "
"daemSkippedPaths:\n"; "daemSkippedPaths:\n";
} }
for (vector<string>::const_iterator it = nonexist.begin(); for (const auto& entry : nonexist) {
it != nonexist.end(); it++) { out << entry << endl;
out << *it << endl;
} }
} }
if ((op_flags & OPT_E)) { if ((op_flags & OPT_E)) {
exit(0); exit(0);
} }
if (op_flags & OPT_l) {
if (aremain != 0)
Usage();
vector<string> stemmers = ConfIndexer::getStemmerNames();
for (const auto& stemmer : stemmers) {
cout << stemmer << endl;
}
exit(0);
}
orig_cwd = path_cwd(); orig_cwd = path_cwd();
string rundir; string rundir;
config->getConfParam("idxrundir", rundir); config->getConfParam("idxrundir", rundir);
@ -770,6 +778,7 @@ int wmain(int argc, wchar_t *argv[])
Pidfile pidfile(config->getPidfile()); Pidfile pidfile(config->getPidfile());
updater = new MyUpdater(config); updater = new MyUpdater(config);
lockorexit(&pidfile, config);
// Log something at LOGINFO to reset the trace file. Else at level // 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. // 3 it's not even truncated if all docs are up to date.
@ -789,8 +798,6 @@ int wmain(int argc, wchar_t *argv[])
flushIdxReasons(); flushIdxReasons();
exit(status ? 0 : 1); exit(status ? 0 : 1);
} else if (op_flags & (OPT_i|OPT_e)) { } else if (op_flags & (OPT_i|OPT_e)) {
lockorexit(&pidfile, config);
list<string> filenames; list<string> filenames;
if (aremain == 0) { if (aremain == 0) {
// Read from stdin // Read from stdin
@ -822,20 +829,12 @@ int wmain(int argc, wchar_t *argv[])
} }
flushIdxReasons(); flushIdxReasons();
exit(status ? 0 : 1); exit(status ? 0 : 1);
} else if (op_flags & OPT_l) {
if (aremain != 0)
Usage();
vector<string> stemmers = ConfIndexer::getStemmerNames();
for (vector<string>::const_iterator it = stemmers.begin();
it != stemmers.end(); it++) {
cout << *it << endl;
}
exit(0);
} else if (op_flags & OPT_s) { } else if (op_flags & OPT_s) {
if (aremain != 1) if (aremain != 1)
Usage(); Usage();
string lang = args[argidx++]; aremain--; string lang = args[argidx++]; aremain--;
exit(!createstemdb(config, lang)); exit(!createstemdb(config, lang));
#ifdef RCL_USE_ASPELL #ifdef RCL_USE_ASPELL
} else if (op_flags & OPT_S) { } else if (op_flags & OPT_S) {
makeIndexerOrExit(config, false); makeIndexerOrExit(config, false);
@ -846,7 +845,6 @@ int wmain(int argc, wchar_t *argv[])
} else if (op_flags & OPT_m) { } else if (op_flags & OPT_m) {
if (aremain != 0) if (aremain != 0)
Usage(); Usage();
lockorexit(&pidfile, config);
if (updater) { if (updater) {
updater->status.hasmonitor = true; updater->status.hasmonitor = true;
} }
@ -925,14 +923,10 @@ int wmain(int argc, wchar_t *argv[])
exit(monret == false); exit(monret == false);
#endif // MONITOR #endif // MONITOR
} else if (op_flags & OPT_b) { }
cerr << "Not yet" << endl;
return 1;
} else {
lockorexit(&pidfile, config);
makeIndexerOrExit(config, inPlaceReset); makeIndexerOrExit(config, inPlaceReset);
bool status = confindexer->index(rezero, ConfIndexer::IxTAll, bool status = confindexer->index(rezero, ConfIndexer::IxTAll, indexerFlags);
indexerFlags);
// Record success of indexing pass with failed files retries. // Record success of indexing pass with failed files retries.
if (status && !(indexerFlags & ConfIndexer::IxFNoRetryFailed)) { if (status && !(indexerFlags & ConfIndexer::IxFNoRetryFailed)) {
checkRetryFailed(config, true); checkRetryFailed(config, true);
@ -950,5 +944,4 @@ int wmain(int argc, wchar_t *argv[])
} }
flushIdxReasons(); flushIdxReasons();
return !status; return !status;
}
} }