X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=frontends%2Fovdb_monitor.c;fp=frontends%2Fovdb_monitor.c;h=0000000000000000000000000000000000000000;hb=b7a32e2d73e3ab1add8208d3e157f7269a31ef4d;hp=3fbd9b7e2230f5f3e22ee4088278b5b2f1ee53a2;hpb=ac902a8299ff4469b356836f431ead31c3377377;p=inn-innduct.git diff --git a/frontends/ovdb_monitor.c b/frontends/ovdb_monitor.c deleted file mode 100644 index 3fbd9b7..0000000 --- a/frontends/ovdb_monitor.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * ovdb_monitor - * Performs database maintenance tasks - * + Transaction checkpoints - * + Deadlock detection - * + Transaction log removal - */ - -#include "config.h" -#include "clibrary.h" -#include "portable/setproctitle.h" -#include "portable/wait.h" -#include -#include -#include - -#include "inn/innconf.h" -#include "inn/messages.h" -#include "libinn.h" -#include "ov.h" - -#include "../storage/ovdb/ovdb.h" -#include "../storage/ovdb/ovdb-private.h" - -#ifndef USE_BERKELEY_DB - -int main(int argc UNUSED, char **argv UNUSED) -{ - exit(0); -} - -#else /* USE_BERKELEY_DB */ - -static int signalled = 0; -static void sigfunc(int sig UNUSED) -{ - signalled = 1; -} - - -static pid_t deadlockpid = 0; -static pid_t checkpointpid = 0; -static pid_t logremoverpid = 0; - -static int putpid(const char *path) -{ - char buf[30]; - int fd = open(path, O_WRONLY|O_TRUNC|O_CREAT, 0664); - if(!fd) { - syswarn("cannot open %s", path); - return -1; - } - snprintf(buf, sizeof(buf), "%d\n", getpid()); - if(write(fd, buf, strlen(buf)) < 0) { - syswarn("cannot write to %s", path); - close(fd); - return -1; - } - close(fd); - return 0; -} - -static void deadlock(void) -{ - int ret, status = 0; - u_int32_t atype = DB_LOCK_YOUNGEST; - - if(ovdb_open_berkeleydb(OV_WRITE, 0)) - _exit(1); - - setproctitle("deadlock"); - - while(!signalled) { -#if DB_VERSION_MAJOR == 2 - ret = lock_detect(OVDBenv->lk_info, 0, atype); -#elif DB_VERSION_MAJOR == 3 - ret = lock_detect(OVDBenv, 0, atype, NULL); -#else - ret = OVDBenv->lock_detect(OVDBenv, 0, atype, NULL); -#endif - if(ret != 0) { - warn("OVDB: lock_detect: %s", db_strerror(ret)); - status = 1; - break; - } - sleep(30); - } - - ovdb_close_berkeleydb(); - _exit(status); -} - -static void checkpoint(void) -{ - int ret, status = 0; - DB *db; -#if DB_VERSION_MAJOR == 2 - DB_INFO dbinfo; -#endif - - if(ovdb_open_berkeleydb(OV_WRITE, 0)) - _exit(1); - - setproctitle("checkpoint"); - - /* Open a database and close it. This is so a necessary initialization - gets performed (by the db->open function). */ - -#if DB_VERSION_MAJOR == 2 - memset(&dbinfo, 0, sizeof dbinfo); - ret = db_open("version", DB_BTREE, DB_CREATE, 0666, OVDBenv, &dbinfo, &db); - if (ret != 0) { - warn("OVDB: checkpoint: db_open failed: %s", db_strerror(ret)); - _exit(1); - } -#else - ret = db_create(&db, OVDBenv, 0); - if (ret != 0) { - warn("OVDB: checkpoint: db_create: %s", db_strerror(ret)); - _exit(1); - } -#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1) - ret = db->open(db, NULL, "version", NULL, DB_BTREE, DB_CREATE, 0666); -#else - ret = db->open(db, "version", NULL, DB_BTREE, DB_CREATE, 0666); -#endif - if (ret != 0) { - db->close(db, 0); - warn("OVDB: checkpoint: version open: %s", db_strerror(ret)); - _exit(1); - } -#endif - db->close(db, 0); - - - while(!signalled) { -#if DB_VERSION_MAJOR == 2 - ret = txn_checkpoint(OVDBenv->tx_info, 2048, 1); -#elif DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0 - ret = txn_checkpoint(OVDBenv, 2048, 1); -#elif DB_VERSION_MAJOR == 3 - ret = txn_checkpoint(OVDBenv, 2048, 1, 0); -#elif DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 1 - ret = OVDBenv->txn_checkpoint(OVDBenv, 2048, 1, 0); -#else - OVDBenv->txn_checkpoint(OVDBenv, 2048, 1, 0); -#endif -#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1) - sleep(30); -#else - if(ret != 0 && ret != DB_INCOMPLETE) { - warn("OVDB: txn_checkpoint: %s", db_strerror(ret)); - status = 1; - break; - } - if(ret == DB_INCOMPLETE) - sleep(2); - else - sleep(30); -#endif - } - - ovdb_close_berkeleydb(); - _exit(status); -} - -static void logremover(void) -{ - int ret, status = 0; - char **listp, **p; - - if(ovdb_open_berkeleydb(OV_WRITE, 0)) - _exit(1); - - setproctitle("logremover"); - - while(!signalled) { -#if DB_VERSION_MAJOR == 2 - ret = log_archive(OVDBenv->lg_info, &listp, DB_ARCH_ABS, malloc); -#elif DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR <= 2 - ret = log_archive(OVDBenv, &listp, DB_ARCH_ABS, malloc); -#elif DB_VERSION_MAJOR == 3 - ret = log_archive(OVDBenv, &listp, DB_ARCH_ABS); -#else - ret = OVDBenv->log_archive(OVDBenv, &listp, DB_ARCH_ABS); -#endif - if(ret != 0) { - warn("OVDB: log_archive: %s", db_strerror(ret)); - status = 1; - break; - } - if(listp != NULL) { - for(p = listp; *p; p++) - unlink(*p); - free(listp); - } - sleep(45); - } - - ovdb_close_berkeleydb(); - _exit(status); -} - -static int start_process(pid_t *pid, void (*func)(void)) -{ - pid_t child; - - switch(child = fork()) { - case 0: - (*func)(); - _exit(0); - case -1: - syswarn("cannot fork"); - return -1; - default: - *pid = child; - return 0; - } - /*NOTREACHED*/ -} - -static void cleanup(int status) -{ - int cs; - - if(deadlockpid) - kill(deadlockpid, SIGTERM); - if(checkpointpid) - kill(checkpointpid, SIGTERM); - if(logremoverpid) - kill(logremoverpid, SIGTERM); - - xsignal(SIGINT, SIG_DFL); - xsignal(SIGTERM, SIG_DFL); - xsignal(SIGHUP, SIG_DFL); - - if(deadlockpid) - waitpid(deadlockpid, &cs, 0); - if(checkpointpid) - waitpid(checkpointpid, &cs, 0); - if(logremoverpid) - waitpid(logremoverpid, &cs, 0); - - unlink(concatpath(innconf->pathrun, OVDB_MONITOR_PIDFILE)); - exit(status); -} - -static void monitorloop(void) -{ - int cs, restartit; - pid_t child; - - while(!signalled) { - child = waitpid(-1, &cs, WNOHANG); - if(child > 0) { - if(WIFSIGNALED(cs)) { - restartit = 0; - } else { - if(WEXITSTATUS(cs) == 0) - restartit = 1; - else - restartit = 0; - } - if(child == deadlockpid) { - deadlockpid = 0; - if(restartit && start_process(&deadlockpid, deadlock)) - cleanup(1); - } else if(child == checkpointpid) { - checkpointpid = 0; - if(restartit && start_process(&checkpointpid, checkpoint)) - cleanup(1); - } else if(child == logremoverpid) { - logremoverpid = 0; - if(restartit && start_process(&logremoverpid, logremover)) - cleanup(1); - } - if(!restartit) - cleanup(1); - } - sleep(20); - } - cleanup(0); -} - - -int main(int argc, char **argv) -{ - char *pidfile; - - setproctitle_init(argc, argv); - - openlog("ovdb_monitor", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG); - message_program_name = "ovdb_monitor"; - - if(argc != 2 || strcmp(argv[1], SPACES)) - die("should be started by ovdb_init"); - message_handlers_warn(1, message_log_syslog_err); - message_handlers_die(1, message_log_syslog_err); - - if (!innconf_read(NULL)) - exit(1); - - if(strcmp(innconf->ovmethod, "ovdb")) - die("ovmethod not set to ovdb in inn.conf"); - if(!ovdb_check_user()) - die("command must be run as user " NEWSUSER); - if(!ovdb_getlock(OVDB_LOCK_ADMIN)) - die("cannot lock database"); - - xsignal(SIGINT, sigfunc); - xsignal(SIGTERM, sigfunc); - xsignal(SIGHUP, sigfunc); - - pidfile = concatpath(innconf->pathrun, OVDB_MONITOR_PIDFILE); - if(putpid(pidfile)) - exit(1); - if(start_process(&deadlockpid, deadlock)) - cleanup(1); - if(start_process(&checkpointpid, checkpoint)) - cleanup(1); - if(start_process(&logremoverpid, logremover)) - cleanup(1); - - monitorloop(); - - /* Never reached. */ - return 1; -} - -#endif /* USE_BERKELEY_DB */ -