X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fcnid_dbd%2Fmain.c;h=b8906f902bdcc3579a382b2502bc966c8c027ad7;hb=84c3a8f52deced7429f9d72276232ee282b3b823;hp=4f5fd725b09fc4bbba95b5dca23d202a9af216d9;hpb=dd07aea71f86aa97f05db188c49e0a3c035ee41c;p=netatalk.git diff --git a/etc/cnid_dbd/main.c b/etc/cnid_dbd/main.c index 4f5fd725..b8906f90 100644 --- a/etc/cnid_dbd/main.c +++ b/etc/cnid_dbd/main.c @@ -24,12 +24,15 @@ #include #include -#include +#include +#include +#include #include "db_param.h" #include "dbif.h" #include "dbd.h" #include "comm.h" +#include "pack.h" /* Note: DB_INIT_LOCK is here so we can run the db_* utilities while netatalk is running. @@ -37,9 +40,6 @@ */ #define DBOPTIONS (DB_CREATE | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN) -/* Global, needed by pack.c:idxname() */ -struct volinfo volinfo; - static DBD *dbd; static int exit_sig = 0; static int db_locked; @@ -273,56 +273,81 @@ static void set_signal(void) /* ------------------------ */ int main(int argc, char *argv[]) { + EC_INIT; struct db_param *dbp; - int err = 0; - int ctrlfd, clntfd; + int delete_bdb = 0; + int ctrlfd = -1, clntfd = -1; char *logconfig; + AFPObj obj = { 0 }; + struct vol *vol; + char *volpath = NULL; + bstring dbpath; + + while (( ret = getopt( argc, argv, "dF:l:p:t:v")) != -1 ) { + switch (ret) { + case 'd': + delete_bdb = 1; + break; + case 'F': + obj.cmdlineconfigfile = strdup(optarg); + break; + case 'p': + volpath = strdup(optarg); + break; + case 'l': + clntfd = atoi(optarg); + break; + case 't': + ctrlfd = atoi(optarg); + break; + case 'v': + printf("cnid_dbd (Netatalk %s)\n", VERSION); + return -1; + } + } + + if (ctrlfd == -1 || clntfd == -1 || !volpath) { + LOG(log_error, logtype_cnid, "main: bad IPC fds"); + exit(EXIT_FAILURE); + } + + EC_ZERO( afp_config_parse(&obj) ); set_processname("cnid_dbd"); + setuplog(obj.options.logconfig, obj.options.logfile); - /* FIXME: implement -d from cnid_metad */ - if (argc != 5) { - LOG(log_error, logtype_cnid, "main: not enough arguments"); - exit(1); - } + EC_ZERO( load_volumes(&obj, NULL) ); + EC_NULL( vol = getvolbypath(volpath) ); - ctrlfd = atoi(argv[2]); - clntfd = atoi(argv[3]); - logconfig = strdup(argv[4]); - setuplog(logconfig); + pack_setvol(vol); - /* 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"); + EC_NULL( dbpath = bfromcstr(vol->v_dbpath) ); + EC_ZERO( bcatcstr(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); + LOG(log_debug, logtype_cnid, "db dir: \"%s\"", bdata(dbpath)); - switch_to_user(dbpath); + switch_to_user(bdata(dbpath)); /* Get db lock */ - if ((db_locked = get_lock(LOCK_EXCL, dbpath)) == -1) { + if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) == -1) { LOG(log_error, logtype_cnid, "main: fatal db lock error"); - exit(1); + EC_FAIL; } if (db_locked != LOCK_EXCL) { /* Couldn't get exclusive lock, try shared lock */ if ((db_locked = get_lock(LOCK_SHRD, NULL)) != LOCK_SHRD) { LOG(log_error, logtype_cnid, "main: fatal db lock error"); - exit(1); + EC_FAIL; + } + } + + if (delete_bdb && (db_locked == LOCK_EXCL)) { + LOG(log_warning, logtype_cnid, "main: too many CNID db opening attempts, wiping the slate clean"); + chdir(bdata(dbpath)); + system("rm -f cnid2.db lock log.* __db.*"); + if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) != LOCK_EXCL) { + LOG(log_error, logtype_cnid, "main: fatal db lock error"); + EC_FAIL; } } @@ -331,59 +356,66 @@ int main(int argc, char *argv[]) /* SIGINT and SIGTERM are always off, unless we are in pselect */ block_sigs_onoff(1); - if ((dbp = db_param_read(dbpath)) == NULL) - exit(1); + if ((dbp = db_param_read(bdata(dbpath))) == NULL) + EC_FAIL; LOG(log_maxdebug, logtype_cnid, "Finished parsing db_param config file"); - if (NULL == (dbd = dbif_init(dbpath, "cnid2.db"))) - exit(2); + if (NULL == (dbd = dbif_init(bdata(dbpath), "cnid2.db"))) + EC_FAIL; /* Only recover if we got the lock */ if (dbif_env_open(dbd, dbp, (db_locked == LOCK_EXCL) ? DBOPTIONS | DB_RECOVER : DBOPTIONS) < 0) - exit(2); /* FIXME: same exit code as failure for dbif_open() */ + EC_FAIL; LOG(log_debug, logtype_cnid, "Finished initializing BerkeleyDB environment"); if (dbif_open(dbd, dbp, 0) < 0) { - dbif_close(dbd); - exit(2); + ret = -1; + goto close_db; } + LOG(log_debug, logtype_cnid, "Finished opening BerkeleyDB databases"); /* Downgrade db lock */ if (db_locked == LOCK_EXCL) { if (get_lock(LOCK_UNLOCK, NULL) != 0) { - dbif_close(dbd); - exit(2); + ret = -1; + goto close_db; } + if (get_lock(LOCK_SHRD, NULL) != LOCK_SHRD) { - dbif_close(dbd); - exit(2); + ret = -1; + goto close_db; } } if (comm_init(dbp, ctrlfd, clntfd) < 0) { - dbif_close(dbd); - exit(3); + ret = -1; + goto close_db; } - if (loop(dbp) < 0) - err++; + if (loop(dbp) < 0) { + ret = -1; + goto close_db; + } +close_db: if (dbif_close(dbd) < 0) - err++; + ret = -1; + + if (dbif_env_remove(bdata(dbpath)) < 0) + ret = -1; - if (dbif_env_remove(dbpath) < 0) - err++; +EC_CLEANUP: + if (ret != 0) + exit(1); - if (err) - exit(4); - else if (exit_sig) + if (exit_sig) LOG(log_info, logtype_cnid, "main: Exiting on signal %i", exit_sig); else LOG(log_info, logtype_cnid, "main: Idle timeout, exiting"); - return 0; + EC_EXIT; }