/*
- * $Id: main.c,v 1.12 2009-10-18 17:50:13 didg Exp $
- *
* Copyright (C) Joerg Lenneis 2003
* Copyright (c) Frank Lahm 2009
* All Rights Reserved. See COPYING.
#include <netatalk/endian.h>
#include <atalk/cnid_dbd_private.h>
#include <atalk/logger.h>
+#include <atalk/volinfo.h>
#include "db_param.h"
#include "dbif.h"
*/
#define DBOPTIONS (DB_CREATE | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN | DB_RECOVER)
-static DBD *dbd;
+/* Global, needed by pack.c:idxname() */
+struct volinfo volinfo;
+static DBD *dbd;
static int exit_sig = 0;
static void sig_exit(int signo)
1: Success, if transactions are used commit.
0: Failure, but we continue to serve requests. If transactions are used abort/rollback.
- -1: Fatal error, either from the database or from the socket. Abort the transaction if applicable
+ -1: Fatal error, either from t
+ he database or from the socket. Abort the transaction if applicable
(which might fail as well) and then exit.
We always try to notify the client process about the outcome, the result field
else
timeout = 1;
- if ((cret = comm_rcv(&rqst, timeout, &set)) < 0)
+ if ((cret = comm_rcv(&rqst, timeout, &set, &now)) < 0)
return -1;
- now = time(NULL);
-
if (cret == 0) {
/* comm_rcv returned from select without receiving anything. */
- if (exit_sig)
+ if (exit_sig) {
/* Received signal (TERM|INT) */
return 0;
- if (dbp->idle_timeout && comm_nbe() <= 0 && (now - time_last_rqst) > dbp->idle_timeout)
+ }
+ if (now - time_last_rqst >= dbp->idle_timeout && comm_nbe() <= 0) {
/* Idle timeout */
return 0;
+ }
+ /* still active connections, reset time_last_rqst */
+ time_last_rqst = now;
} else {
/* We got a request */
time_last_rqst = now;
ret = 1;
break;
case CNID_DBD_OP_ADD:
- ret = dbd_add(dbd, &rqst, &rply);
+ ret = dbd_add(dbd, &rqst, &rply, 0);
break;
case CNID_DBD_OP_GET:
ret = dbd_get(dbd, &rqst, &rply);
ret = dbd_resolve(dbd, &rqst, &rply);
break;
case CNID_DBD_OP_LOOKUP:
- ret = dbd_lookup(dbd, &rqst, &rply);
+ ret = dbd_lookup(dbd, &rqst, &rply, 0);
break;
case CNID_DBD_OP_UPDATE:
ret = dbd_update(dbd, &rqst, &rply);
case CNID_DBD_OP_REBUILD_ADD:
ret = dbd_rebuild_add(dbd, &rqst, &rply);
break;
+ case CNID_DBD_OP_SEARCH:
+ ret = dbd_search(dbd, &rqst, &rply);
+ break;
default:
LOG(log_error, logtype_cnid, "loop: unknown op %d", rqst.op);
ret = -1;
break;
}
-
+
if ((cret = comm_snd(&rply)) < 0 || ret < 0) {
dbif_txn_abort(dbd);
return -1;
Shall we checkpoint bdb ?
"flush_interval" seconds passed ?
*/
- if (now > time_next_flush) {
+ if (now >= time_next_flush) {
LOG(log_info, logtype_cnid, "Checkpointing BerkeleyDB for volume '%s'", dbp->dir);
if (dbif_txn_checkpoint(dbd, 0, 0, 0) < 0)
return -1;
if (fcntl(lockfd, F_SETLK, &lock) < 0) {
if (errno == EACCES || errno == EAGAIN) {
+ LOG(log_error, logtype_cnid, "get_lock: locked");
exit(0);
} else {
LOG(log_error, logtype_cnid, "main: fcntl F_WRLCK lockfile: %s", strerror(errno));
struct db_param *dbp;
int err = 0;
int lockfd, ctrlfd, clntfd;
- char *dir, *logconfig;
+ char *logconfig;
set_processname("cnid_dbd");
exit(1);
}
- dir = argv[1];
ctrlfd = atoi(argv[2]);
clntfd = atoi(argv[3]);
logconfig = strdup(argv[4]);
setuplog(logconfig);
- switch_to_user(dir);
+ /* Load .volinfo file */
+ if (loadvolinfo(argv[1], &volinfo) == -1) {
+ LOG(log_error, logtype_cnid, "Cant load volinfo for \"%s\"", argv[1]);
+ exit(EXIT_FAILURE);
+ }
+ /* Put "/.AppleDB" at end of volpath, get path from volinfo file */
+ char dbpath[MAXPATHLEN+1];
+ if ((strlen(volinfo.v_dbpath) + strlen("/.AppleDB")) > MAXPATHLEN ) {
+ LOG(log_error, logtype_cnid, "CNID db pathname too long: \"%s\"", volinfo.v_dbpath);
+ exit(EXIT_FAILURE);
+ }
+ strncpy(dbpath, volinfo.v_dbpath, MAXPATHLEN - strlen("/.AppleDB"));
+ strcat(dbpath, "/.AppleDB");
+
+ if (vol_load_charsets(&volinfo) == -1) {
+ LOG(log_error, logtype_cnid, "Error loading charsets!");
+ exit(EXIT_FAILURE);
+ }
+ LOG(log_debug, logtype_cnid, "db dir: \"%s\"", dbpath);
+
+ switch_to_user(dbpath);
/* Before we do anything else, check if there is an instance of cnid_dbd
running already and silently exit if yes. */
lockfd = get_lock();
- LOG(log_info, logtype_cnid, "Startup, DB dir %s", dir);
-
set_signal();
/* SIGINT and SIGTERM are always off, unless we are in pselect */
block_sigs_onoff(1);
- if ((dbp = db_param_read(dir, CNID_DBD)) == NULL)
+ if ((dbp = db_param_read(dbpath)) == NULL)
exit(1);
LOG(log_maxdebug, logtype_cnid, "Finished parsing db_param config file");
}
LOG(log_debug, logtype_cnid, "Finished opening BerkeleyDB databases");
- if (dbd_stamp(dbd) < 0) {
- dbif_close(dbd);
- exit(5);
- }
- LOG(log_maxdebug, logtype_cnid, "Finished checking database stamp");
-
if (comm_init(dbp, ctrlfd, clntfd) < 0) {
dbif_close(dbd);
exit(3);
if (dbif_close(dbd) < 0)
err++;
- if (dbif_prep_upgrade(dir) < 0)
+ if (dbif_env_remove(dbpath) < 0)
err++;
free_lock(lockfd);