setup lockfile for monitor
This commit is contained in:
parent
b905d16f72
commit
16472b30a7
@ -2,7 +2,7 @@
|
|||||||
#define _RCLMON_H_INCLUDED_
|
#define _RCLMON_H_INCLUDED_
|
||||||
#include "autoconfig.h"
|
#include "autoconfig.h"
|
||||||
#ifdef RCL_MONITOR
|
#ifdef RCL_MONITOR
|
||||||
/* @(#$Id: rclmon.h,v 1.3 2006-10-23 15:01:12 dockes Exp $ (C) 2006 J.F.Dockes */
|
/* @(#$Id: rclmon.h,v 1.4 2006-10-24 12:48:08 dockes Exp $ (C) 2006 J.F.Dockes */
|
||||||
/**
|
/**
|
||||||
* Definitions for the real-time monitoring recoll.
|
* Definitions for the real-time monitoring recoll.
|
||||||
* We're interested in file modifications, deletions and renaming.
|
* We're interested in file modifications, deletions and renaming.
|
||||||
@ -24,6 +24,9 @@ using std::string;
|
|||||||
using std::multimap;
|
using std::multimap;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitoring event: something changed in the filesystem
|
||||||
|
*/
|
||||||
class RclMonEvent {
|
class RclMonEvent {
|
||||||
public:
|
public:
|
||||||
enum EvType {RCLEVT_NONE, RCLEVT_MODIFY, RCLEVT_DELETE,
|
enum EvType {RCLEVT_NONE, RCLEVT_MODIFY, RCLEVT_DELETE,
|
||||||
@ -34,8 +37,12 @@ class RclMonEvent {
|
|||||||
RclMonEvent() : m_etyp(RCLEVT_NONE) {}
|
RclMonEvent() : m_etyp(RCLEVT_NONE) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitoring event queue. This is the shared object between the main thread
|
||||||
|
* (which does the actual indexing work), and the monitoring thread which
|
||||||
|
* receives events from FAM / inotify / etc.
|
||||||
|
*/
|
||||||
class RclEQData;
|
class RclEQData;
|
||||||
|
|
||||||
class RclMonEventQueue {
|
class RclMonEventQueue {
|
||||||
public:
|
public:
|
||||||
RclMonEventQueue();
|
RclMonEventQueue();
|
||||||
@ -62,7 +69,15 @@ class RclMonEventQueue {
|
|||||||
RclEQData *m_data;
|
RclEQData *m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern RclMonEventQueue rclEQ;
|
/** Start monitoring on the topdirs described in conf */
|
||||||
extern bool startMonitor(RclConfig *conf, bool nofork);
|
extern bool startMonitor(RclConfig *conf, bool nofork);
|
||||||
|
|
||||||
|
/** Main routine for the event receiving thread */
|
||||||
|
extern void *rclMonRcvRun(void *);
|
||||||
|
|
||||||
|
/** There can only be one of us. Name of the lock file inside the config
|
||||||
|
* directory. We write our pid in there */
|
||||||
|
#define RCL_MONITOR_PIDFILENAME "rclmonpid"
|
||||||
|
|
||||||
#endif // RCL_MONITOR
|
#endif // RCL_MONITOR
|
||||||
#endif /* _RCLMON_H_INCLUDED_ */
|
#endif /* _RCLMON_H_INCLUDED_ */
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#ifdef RCL_MONITOR
|
#ifdef RCL_MONITOR
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#$Id: rclmonprc.cpp,v 1.3 2006-10-22 14:47:13 dockes Exp $ (C) 2006 J.F.Dockes";
|
static char rcsid[] = "@(#$Id: rclmonprc.cpp,v 1.4 2006-10-24 12:48:09 dockes Exp $ (C) 2006 J.F.Dockes";
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -28,14 +28,22 @@ static char rcsid[] = "@(#$Id: rclmonprc.cpp,v 1.3 2006-10-22 14:47:13 dockes Ex
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#include "debuglog.h"
|
#include "debuglog.h"
|
||||||
#include "rclmon.h"
|
#include "rclmon.h"
|
||||||
#include "debuglog.h"
|
#include "debuglog.h"
|
||||||
#include "indexer.h"
|
#include "indexer.h"
|
||||||
|
#include "pathut.h"
|
||||||
|
|
||||||
typedef map<string, RclMonEvent> queue_type;
|
typedef map<string, RclMonEvent> queue_type;
|
||||||
|
|
||||||
|
/** Private part of RclEQ: things that we don't wish to exist in the interface
|
||||||
|
* include file.
|
||||||
|
*/
|
||||||
class RclEQData {
|
class RclEQData {
|
||||||
public:
|
public:
|
||||||
queue_type m_queue;
|
queue_type m_queue;
|
||||||
@ -51,16 +59,18 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
RclMonEventQueue rclEQ;
|
static RclMonEventQueue rclEQ;
|
||||||
|
|
||||||
RclMonEventQueue::RclMonEventQueue()
|
RclMonEventQueue::RclMonEventQueue()
|
||||||
{
|
{
|
||||||
m_data = new RclEQData;
|
m_data = new RclEQData;
|
||||||
}
|
}
|
||||||
|
|
||||||
RclMonEventQueue::~RclMonEventQueue()
|
RclMonEventQueue::~RclMonEventQueue()
|
||||||
{
|
{
|
||||||
delete m_data;
|
delete m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RclMonEventQueue::empty()
|
bool RclMonEventQueue::empty()
|
||||||
{
|
{
|
||||||
return m_data == 0 ? true : m_data->m_queue.empty();
|
return m_data == 0 ? true : m_data->m_queue.empty();
|
||||||
@ -138,22 +148,91 @@ bool RclMonEventQueue::pushEvent(const RclMonEvent &ev)
|
|||||||
{
|
{
|
||||||
LOGDEB2(("RclMonEventQueue::pushEvent for %s\n", ev.m_path.c_str()));
|
LOGDEB2(("RclMonEventQueue::pushEvent for %s\n", ev.m_path.c_str()));
|
||||||
lock();
|
lock();
|
||||||
// It seems that a newer event always override any older. TBVerified ?
|
// It seems that a newer event is always correct to override any
|
||||||
|
// older. TBVerified ?
|
||||||
m_data->m_queue[ev.m_path] = ev;
|
m_data->m_queue[ev.m_path] = ev;
|
||||||
pthread_cond_broadcast(&m_data->m_cond);
|
pthread_cond_broadcast(&m_data->m_cond);
|
||||||
unlock();
|
unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static string pidfile;
|
||||||
|
/** There can only be one real time indexing process running */
|
||||||
|
static bool processlock(const string &confdir)
|
||||||
|
{
|
||||||
|
pidfile = path_cat(confdir, RCL_MONITOR_PIDFILENAME);
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
int fd = open(pidfile.c_str(), O_RDWR|O_CREAT|O_EXCL, 0644);
|
||||||
|
if (fd < 0) {
|
||||||
|
if (errno != EEXIST) {
|
||||||
|
LOGERR(("processlock: cant create %s, errno %d\n",
|
||||||
|
pidfile.c_str(), errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((fd = open(pidfile.c_str(), O_RDONLY)) < 0) {
|
||||||
|
LOGERR(("processlock: cant open existing %s, errno %d\n",
|
||||||
|
pidfile.c_str(), errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
char buf[20];
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
if (read(fd, buf, 19) < 0) {
|
||||||
|
LOGERR(("processlock: cant read existing %s, errno %d\n",
|
||||||
|
pidfile.c_str(), errno));
|
||||||
|
close(fd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
int pid = atoi(buf);
|
||||||
|
if (pid <= 0 || (kill(pid, 0) < 0 && errno == ESRCH)) {
|
||||||
|
// File exists but no process
|
||||||
|
if (unlink(pidfile.c_str()) < 0) {
|
||||||
|
LOGERR(("processlock: cant unlink existing %s, errno %d\n",
|
||||||
|
pidfile.c_str(), errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Let's retry
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// Other process running
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// File could be created, write my pid in there
|
||||||
|
char buf[20];
|
||||||
|
sprintf(buf, "%d\n", getpid());
|
||||||
|
if (write(fd, buf, strlen(buf)+1) != int(strlen(buf)+1)) {
|
||||||
|
LOGERR(("processlock: cant write to %s, errno %d\n",
|
||||||
|
pidfile.c_str(), errno));
|
||||||
|
close(fd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
// Ok
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void processunlock()
|
||||||
|
{
|
||||||
|
unlink(pidfile.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
pthread_t rcv_thrid;
|
pthread_t rcv_thrid;
|
||||||
void *rcv_result;
|
|
||||||
extern void *rclMonRcvRun(void *);
|
|
||||||
|
|
||||||
bool startMonitor(RclConfig *conf, bool nofork)
|
bool startMonitor(RclConfig *conf, bool nofork)
|
||||||
{
|
{
|
||||||
|
if (!processlock(conf->getConfDir())) {
|
||||||
|
LOGERR(("startMonitor: lock error. Other process running ?\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
atexit(processunlock);
|
||||||
|
|
||||||
rclEQ.setConfig(conf);
|
rclEQ.setConfig(conf);
|
||||||
if (pthread_create(&rcv_thrid, 0, &rclMonRcvRun, &rclEQ) != 0) {
|
if (pthread_create(&rcv_thrid, 0, &rclMonRcvRun, &rclEQ) != 0) {
|
||||||
LOGERR(("start_monitoring: cant create event-receiving thread\n"));
|
LOGERR(("startMonitor: cant create event-receiving thread\n"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user