indexing: create lock / pid file
This commit is contained in:
parent
9d26fe43cf
commit
166399fd62
@ -850,6 +850,10 @@ string RclConfig::getStopfile()
|
|||||||
{
|
{
|
||||||
return path_cat(getConfDir(), "stoplist.txt");
|
return path_cat(getConfDir(), "stoplist.txt");
|
||||||
}
|
}
|
||||||
|
string RclConfig::getPidfile()
|
||||||
|
{
|
||||||
|
return path_cat(getConfDir(), "index.pid");
|
||||||
|
}
|
||||||
|
|
||||||
list<string>& RclConfig::getSkippedNames()
|
list<string>& RclConfig::getSkippedNames()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -135,6 +135,8 @@ class RclConfig {
|
|||||||
string getDbDir();
|
string getDbDir();
|
||||||
/** Get stoplist file name */
|
/** Get stoplist file name */
|
||||||
string getStopfile();
|
string getStopfile();
|
||||||
|
/** Get indexing pid file */
|
||||||
|
string getPidfile();
|
||||||
|
|
||||||
/** Get list of skipped file names for current keydir */
|
/** Get list of skipped file names for current keydir */
|
||||||
list<string>& getSkippedNames();
|
list<string>& getSkippedNames();
|
||||||
|
|||||||
@ -206,6 +206,16 @@ RclConfig *RclConfig::getMainConfig()
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lockorexit(Pidfile *pidfile)
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
if ((pid = pidfile->open()) != 0) {
|
||||||
|
cerr << "Can't become exclusive indexer: " << pidfile->getreason() <<
|
||||||
|
". Return (other pid?): " << pid << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, const char **argv)
|
int main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
string a_config;
|
string a_config;
|
||||||
@ -268,12 +278,16 @@ int main(int argc, const char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
bool rezero(op_flags & OPT_z);
|
bool rezero(op_flags & OPT_z);
|
||||||
|
Pidfile pidfile(config->getPidfile());
|
||||||
|
|
||||||
if (setpriority(PRIO_PGRP, 0, 20) != 0) {
|
if (setpriority(PRIO_PGRP, 0, 20) != 0) {
|
||||||
LOGINFO(("recollindex: can't setpriority(), errno %d\n", errno));
|
LOGINFO(("recollindex: can't setpriority(), errno %d\n", errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op_flags & (OPT_i|OPT_e)) {
|
if (op_flags & (OPT_i|OPT_e)) {
|
||||||
|
lockorexit(&pidfile);
|
||||||
|
pidfile.write_pid();
|
||||||
|
|
||||||
list<string> filenames;
|
list<string> filenames;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
@ -316,6 +330,7 @@ int main(int argc, const char **argv)
|
|||||||
} else if (op_flags & OPT_m) {
|
} else if (op_flags & OPT_m) {
|
||||||
if (argc != 0)
|
if (argc != 0)
|
||||||
Usage();
|
Usage();
|
||||||
|
lockorexit(&pidfile);
|
||||||
if (!(op_flags&OPT_D)) {
|
if (!(op_flags&OPT_D)) {
|
||||||
LOGDEB(("recollindex: daemonizing\n"));
|
LOGDEB(("recollindex: daemonizing\n"));
|
||||||
daemon(0,0);
|
daemon(0,0);
|
||||||
@ -325,6 +340,7 @@ int main(int argc, const char **argv)
|
|||||||
if (setpriority(PRIO_PGRP, 0, 20) != 0) {
|
if (setpriority(PRIO_PGRP, 0, 20) != 0) {
|
||||||
LOGINFO(("recollindex: can't setpriority(), errno %d\n", errno));
|
LOGINFO(("recollindex: can't setpriority(), errno %d\n", errno));
|
||||||
}
|
}
|
||||||
|
pidfile.write_pid();
|
||||||
if (sleepsecs > 0) {
|
if (sleepsecs > 0) {
|
||||||
LOGDEB(("recollindex: sleeping %d\n", sleepsecs));
|
LOGDEB(("recollindex: sleeping %d\n", sleepsecs));
|
||||||
sleep(sleepsecs);
|
sleep(sleepsecs);
|
||||||
@ -356,6 +372,8 @@ int main(int argc, const char **argv)
|
|||||||
cerr << "Not yet" << endl;
|
cerr << "Not yet" << endl;
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
|
lockorexit(&pidfile);
|
||||||
|
pidfile.write_pid();
|
||||||
confindexer = new ConfIndexer(config, &updater);
|
confindexer = new ConfIndexer(config, &updater);
|
||||||
bool status = confindexer->index(rezero, ConfIndexer::IxTAll);
|
bool status = confindexer->index(rezero, ConfIndexer::IxTAll);
|
||||||
if (!status)
|
if (!status)
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
/*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -17,6 +15,9 @@
|
|||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <qthread.h>
|
#include <qthread.h>
|
||||||
#include <qmutex.h>
|
#include <qmutex.h>
|
||||||
@ -27,6 +28,7 @@
|
|||||||
#include "idxthread.h"
|
#include "idxthread.h"
|
||||||
#include "smallut.h"
|
#include "smallut.h"
|
||||||
#include "rclinit.h"
|
#include "rclinit.h"
|
||||||
|
#include "pathut.h"
|
||||||
|
|
||||||
static int stopindexing;
|
static int stopindexing;
|
||||||
static int startindexing;
|
static int startindexing;
|
||||||
@ -79,16 +81,26 @@ void IdxThread::run()
|
|||||||
myconf->setKeyDir("");
|
myconf->setKeyDir("");
|
||||||
myconf->getConfParam("loglevel", &loglevel);
|
myconf->getConfParam("loglevel", &loglevel);
|
||||||
DebugLog::getdbl()->setloglevel(loglevel);
|
DebugLog::getdbl()->setloglevel(loglevel);
|
||||||
ConfIndexer *indexer = new ConfIndexer(myconf, this);
|
|
||||||
if (indexer->index(rezero, ConfIndexer::IxTAll)) {
|
Pidfile pidfile(myconf->getPidfile());
|
||||||
indexingstatus = IDXTS_OK;
|
if (pidfile.open() != 0) {
|
||||||
indexingReason = "";
|
|
||||||
} else {
|
|
||||||
indexingstatus = IDXTS_ERROR;
|
indexingstatus = IDXTS_ERROR;
|
||||||
indexingReason = "Indexing failed: " + indexer->getReason();
|
indexingReason = "Indexing failed: other process active? " +
|
||||||
|
pidfile.getreason();
|
||||||
|
} else {
|
||||||
|
pidfile.write_pid();
|
||||||
|
ConfIndexer *indexer = new ConfIndexer(myconf, this);
|
||||||
|
if (indexer->index(rezero, ConfIndexer::IxTAll)) {
|
||||||
|
indexingstatus = IDXTS_OK;
|
||||||
|
indexingReason = "";
|
||||||
|
} else {
|
||||||
|
indexingstatus = IDXTS_ERROR;
|
||||||
|
indexingReason = "Indexing failed: " + indexer->getReason();
|
||||||
|
}
|
||||||
|
pidfile.close();
|
||||||
|
delete indexer;
|
||||||
}
|
}
|
||||||
rezero = false;
|
rezero = false;
|
||||||
delete indexer;
|
|
||||||
action_mutex.lock();
|
action_mutex.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,11 @@ static char rcsid[] = "@(#$Id: pathut.cpp,v 1.23 2008-11-24 15:47:40 dockes Exp
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
// Let's include all files where statfs can be defined and hope for no
|
// Let's include all files where statfs can be defined and hope for no
|
||||||
// conflict...
|
// conflict...
|
||||||
#ifdef HAVE_SYS_MOUNT_H
|
#ifdef HAVE_SYS_MOUNT_H
|
||||||
@ -452,6 +456,96 @@ bool printableUrl(const string &fcharset, const string &in, string &out)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Pidfile::~Pidfile()
|
||||||
|
{
|
||||||
|
if (m_fd >= 0)
|
||||||
|
::close(m_fd);
|
||||||
|
m_fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t Pidfile::read_pid()
|
||||||
|
{
|
||||||
|
int fd = ::open(m_path.c_str(), O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
return (pid_t)-1;
|
||||||
|
|
||||||
|
char buf[16];
|
||||||
|
int error;
|
||||||
|
int i = read(fd, buf, sizeof(buf) - 1);
|
||||||
|
error = errno;
|
||||||
|
::close(fd);
|
||||||
|
if (i <= 0)
|
||||||
|
return (pid_t)-1;
|
||||||
|
buf[i] = '\0';
|
||||||
|
char *endptr;
|
||||||
|
pid_t pid = strtol(buf, &endptr, 10);
|
||||||
|
if (endptr != &buf[i])
|
||||||
|
return (pid_t)-1;
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pidfile::flopen()
|
||||||
|
{
|
||||||
|
const char *path = m_path.c_str();
|
||||||
|
int operation = LOCK_EX | LOCK_NB;
|
||||||
|
if ((m_fd = ::open(path, O_RDWR|O_CREAT, 0644)) == -1) {
|
||||||
|
m_reason = "Open failed";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (flock(m_fd, operation) == -1) {
|
||||||
|
int serrno = errno;
|
||||||
|
(void)::close(m_fd);
|
||||||
|
errno = serrno;
|
||||||
|
m_reason = "flock failed";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ftruncate(m_fd, 0) != 0) {
|
||||||
|
/* can't happen [tm] */
|
||||||
|
int serrno = errno;
|
||||||
|
(void)::close(m_fd);
|
||||||
|
errno = serrno;
|
||||||
|
m_reason = "ftruncate failed";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t Pidfile::open()
|
||||||
|
{
|
||||||
|
if (flopen() < 0) {
|
||||||
|
return read_pid();
|
||||||
|
}
|
||||||
|
return (pid_t)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pidfile::write_pid()
|
||||||
|
{
|
||||||
|
/* truncate to allow multiple calls */
|
||||||
|
if (ftruncate(m_fd, 0) == -1) {
|
||||||
|
m_reason = "ftruncate failed";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
char pidstr[20];
|
||||||
|
sprintf(pidstr, "%u", int(getpid()));
|
||||||
|
lseek(m_fd, 0, 0);
|
||||||
|
if (::write(m_fd, pidstr, strlen(pidstr)) != (ssize_t)strlen(pidstr)) {
|
||||||
|
m_reason = "write failed";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pidfile::close()
|
||||||
|
{
|
||||||
|
return ::close(m_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pidfile::remove()
|
||||||
|
{
|
||||||
|
return unlink(m_path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
#else // TEST_PATHUT
|
#else // TEST_PATHUT
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -522,7 +616,7 @@ int main(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
if (argc != 1) {
|
if (argc != 1) {
|
||||||
fprintf(stderr, "Usage: fsocc: trpathut <path>\n");
|
fprintf(stderr, "Usage: fsocc: trpathut <path>\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -537,6 +631,21 @@ int main(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
printf("pc %d, megabytes %ld\n", pc, blocks);
|
printf("pc %d, megabytes %ld\n", pc, blocks);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
Pidfile pidfile("/tmp/pathutpidfile");
|
||||||
|
pid_t pid;
|
||||||
|
if ((pid = pidfile.open()) != 0) {
|
||||||
|
cerr << "open failed. reason: " << pidfile.getreason() <<
|
||||||
|
" return " << pid << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
pidfile.write_pid();
|
||||||
|
sleep(10);
|
||||||
|
pidfile.close();
|
||||||
|
pidfile.remove();
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -101,4 +101,30 @@ private:
|
|||||||
string m_reason;
|
string m_reason;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Lock/pid file class. This is quite close to the pidfile_xxx
|
||||||
|
/// utilities in FreeBSD with a bit more encapsulation. I'd have used
|
||||||
|
/// the freebsd code if it was available elsewhere
|
||||||
|
class Pidfile {
|
||||||
|
public:
|
||||||
|
Pidfile(const string& path) : m_path(path), m_fd(-1) {}
|
||||||
|
~Pidfile();
|
||||||
|
/// Open/create the pid file.
|
||||||
|
/// @return 0 if ok, > 0 for pid of existing process, -1 for other error.
|
||||||
|
pid_t open();
|
||||||
|
/// Write pid into the pid file
|
||||||
|
/// @return 0 ok, -1 error
|
||||||
|
int write_pid();
|
||||||
|
/// Close the pid file (unlocks)
|
||||||
|
int close();
|
||||||
|
/// Delete the pid file
|
||||||
|
int remove();
|
||||||
|
const string& getreason() {return m_reason;}
|
||||||
|
private:
|
||||||
|
string m_path;
|
||||||
|
int m_fd;
|
||||||
|
string m_reason;
|
||||||
|
pid_t read_pid();
|
||||||
|
int flopen();
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _PATHUT_H_INCLUDED_ */
|
#endif /* _PATHUT_H_INCLUDED_ */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user