static uint maxvol;
#define MAXSPAWN 3 /* Max times respawned in.. */
-#define TESTTIME 42 /* this much seconds apfd client tries to *
+#define TESTTIME 10 /* this much seconds apfd client tries to *
* to reconnect every 5 secondes, catch it */
#define MAXVOLS 4096
#define DEFAULTHOST "localhost"
char *v_path;
pid_t pid;
time_t tm; /* When respawned last */
- int count; /* Times respawned in the last TESTTIME secondes */
+ unsigned int count; /* Times respawned in the last TESTTIME secondes */
int control_fd; /* file descriptor to child cnid_dbd process */
};
static void daemon_exit(int i)
{
- server_unlock(_PATH_CNID_METAD_LOCK);
exit(i);
}
/* ------------------ */
-static void sigterm_handler(int sig)
+static void sig_handler(int sig)
{
switch( sig ) {
- case SIGTERM :
- LOG(log_info, logtype_afpd, "shutting down on signal %d", sig );
+ case SIGTERM:
+ case SIGQUIT:
+ LOG(log_note, logtype_afpd, "shutting down on %s",
+ sig == SIGTERM ? "SIGTERM" : "SIGQUIT");
break;
default :
LOG(log_error, logtype_afpd, "unexpected signal: %d", sig);
return -1;
}
} else {
- /* we have a slot but no process, check for respawn too fast */
- if ( (t < (up->tm + TESTTIME)) /* We're in the respawn time window */
- &&
- (up->count > MAXSPAWN) ) { /* ...and already tried to fork too often */
- LOG(log_maxdebug, logtype_cnid, "maybe_start_dbd: respawn too fast just exiting");
- return -1; /* just exit, dont sleep, because we might have work to do for another client */
- }
- if ( t >= (up->tm + TESTTIME) ) { /* out of respawn too fast windows reset the count */
- LOG(log_maxdebug, logtype_cnid, "maybe_start_dbd: respawn window ended");
- up->tm = t;
- up->count = 0;
+ /* we have a slot but no process */
+ if (up->count > 0) {
+ /* check for respawn too fast */
+ if (t < (up->tm + TESTTIME)) {
+ /* We're in the respawn time window */
+ if (up->count > MAXSPAWN) {
+ /* ...and already tried to fork too often */
+ LOG(log_maxdebug, logtype_cnid, "maybe_start_dbd: respawning too fast");
+ return -1; /* just exit, dont sleep, because we might have work to do for another client */
+ }
+ } else {
+ /* out of respawn too fast windows reset the count */
+ LOG(log_info, logtype_cnid, "maybe_start_dbd: respawn window ended");
+ up->count = 0;
+ }
}
up->count++;
- LOG(log_maxdebug, logtype_cnid, "maybe_start_dbd: respawn count now is: %u", up->count);
+ up->tm = t;
+ LOG(log_maxdebug, logtype_cnid, "maybe_start_dbd: respawn count: %u", up->count);
if (up->count > MAXSPAWN) {
/* We spawned too fast. From now until the first time we tried + TESTTIME seconds
we will just return -1 above */
- LOG(log_maxdebug, logtype_cnid, "maybe_start_dbd: reached MAXSPAWN threshhold");
- }
+ LOG(log_info, logtype_cnid, "maybe_start_dbd: reached MAXSPAWN threshhold");
+ }
}
/*
}
/* ------------------ */
-static int set_dbdir(char *dbdir)
+static int set_dbdir(const char *dbdir, const char *vpath)
{
- int len;
+ EC_INIT;
+ int status;
struct stat st;
+ bstring oldpath, newpath;
+ char *cmd_argv[4];
+
+ LOG(log_debug, logtype_cnid, "set_dbdir: volume: %s, db path: %s", vpath, dbdir);
- len = strlen(dbdir);
+ EC_NULL_LOG( oldpath = bformat("%s/%s/", vpath, DBHOME) );
+ EC_NULL_LOG( newpath = bformat("%s/%s/", dbdir, DBHOME) );
- if (stat(dbdir, &st) < 0 && mkdir(dbdir, 0755) < 0) {
+ if (lstat(dbdir, &st) < 0 && mkdir(dbdir, 0755) < 0) {
LOG(log_error, logtype_cnid, "set_dbdir: mkdir failed for %s", dbdir);
- return -1;
+ EC_FAIL;
}
- if (dbdir[len - 1] != '/') {
- strcat(dbdir, "/");
- len++;
+ if (lstat(bdata(oldpath), &st) == 0 && lstat(bdata(newpath), &st) != 0 && errno == ENOENT) {
+ /* There's an .AppleDB in the volume root, we move it */
+ cmd_argv[0] = "mv";
+ cmd_argv[1] = bdata(oldpath);
+ cmd_argv[2] = (char *)dbdir;
+ cmd_argv[3] = NULL;
+ if (run_cmd("mv", cmd_argv) != 0) {
+ LOG(log_error, logtype_cnid, "set_dbdir: moving CNID db from \"%s\" to \"%s\" failed",
+ bdata(oldpath), dbdir);
+ EC_FAIL;
+ }
+
}
- strcpy(dbdir + len, DBHOME);
- if (stat(dbdir, &st) < 0 && mkdir(dbdir, 0755 ) < 0) {
- LOG(log_error, logtype_cnid, "set_dbdir: mkdir failed for %s", dbdir);
- return -1;
+
+ if (lstat(bdata(newpath), &st) < 0 && mkdir(bdata(newpath), 0755 ) < 0) {
+ LOG(log_error, logtype_cnid, "set_dbdir: mkdir failed for %s", bdata(newpath));
+ EC_FAIL;
}
- return 0;
+
+EC_CLEANUP:
+ bdestroy(oldpath);
+ bdestroy(newpath);
+ EC_EXIT;
}
/* ------------------ */
daemon_exit(EXITERR_SYS);
}
- /* Catch SIGTERM */
- sv.sa_handler = sigterm_handler;
+ /* Catch SIGTERM and SIGQUIT */
+ sv.sa_handler = sig_handler;
sigfillset(&sv.sa_mask );
if (sigaction(SIGTERM, &sv, NULL ) < 0 ) {
LOG(log_error, logtype_afpd, "sigaction: %s", strerror(errno) );
daemon_exit(EXITERR_SYS);
}
+ if (sigaction(SIGQUIT, &sv, NULL ) < 0 ) {
+ LOG(log_error, logtype_afpd, "sigaction: %s", strerror(errno) );
+ daemon_exit(EXITERR_SYS);
+ }
/* Ignore the rest */
sv.sa_handler = SIG_IGN;
/* block everywhere but in pselect */
sigemptyset(&set);
sigaddset(&set, SIGCHLD);
- sigprocmask(SIG_BLOCK, &set, NULL);
+ sigprocmask(SIG_SETMASK, &set, NULL);
}
static int setlimits(void)
}
}
- /* Check for PID lockfile */
- if (check_lockfile("cnid_metad", _PATH_CNID_METAD_LOCK))
- return -1;
-
if (!debug && daemonize(0, 0) != 0)
exit(EXITERR_SYS);
- /* Create PID lockfile */
- if (create_lockfile("cnid_metad", _PATH_CNID_METAD_LOCK))
- return -1;
-
- if (afp_config_parse(&obj) != 0)
+ if (afp_config_parse(&obj, "cnid_metad") != 0)
daemon_exit(1);
- set_processname("cnid_metad");
- setuplog(obj.options.logconfig, obj.options.logfile);
-
if (load_volumes(&obj, NULL) != 0)
daemon_exit(1);
if (srv[i].pid == pid) {
srv[i].pid = 0;
close(srv[i].control_fd);
- free(srv[i].v_path);
- srv[i].v_path = NULL;
break;
}
}
if (WIFEXITED(status)) {
LOG(log_info, logtype_cnid, "cnid_dbd[%i] exited with exit code %i",
pid, WEXITSTATUS(status));
+ } else {
+ /* cnid_dbd did a clean exit probably on idle timeout, reset bookkeeping */
+ srv[i].tm = 0;
+ srv[i].count = 0;
}
- else if (WIFSIGNALED(status)) {
+ if (WIFSIGNALED(status)) {
LOG(log_info, logtype_cnid, "cnid_dbd[%i] got signal %i",
pid, WTERMSIG(status));
}
}
volpath[len] = '\0';
+ LOG(log_debug, logtype_cnid, "main: request for volume: %s", volpath);
if (load_volumes(&obj, NULL) != 0) {
LOG(log_severe, logtype_cnid, "main: error reloading config");
goto loop_end;
}
- if (set_dbdir(vol->v_dbpath) < 0) {
+ LOG(log_maxdebug, logtype_cnid, "main: dbpath: %s", vol->v_dbpath);
+
+ if (set_dbdir(vol->v_dbpath, volpath) < 0) {
goto loop_end;
}