/*
- $Id: cmd_dbd.c,v 1.26 2010-04-20 16:46:20 hat001 Exp $
-
Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
This program is free software; you can redistribute it and/or modify
static void usage (void)
{
- printf("Usage: dbd [-e|-v|-x] -d [-i] | -s [-c|-n]| -r [-c|-f] | -u <path to netatalk volume>\n"
+ printf("Usage: dbd [-e|-t|-v|-x] -d [-i] | -s [-c|-n]| -r [-c|-f] | -u <path to netatalk volume>\n"
"dbd can dump, scan, reindex and rebuild Netatalk dbd CNID databases.\n"
"dbd must be run with appropiate permissions i.e. as root.\n\n"
"Main commands are:\n"
"General options:\n"
" -e only work on inactive volumes and lock them (exclusive)\n"
" -x rebuild indexes (just for completeness, mostly useless!)\n"
+ " -t show statistics while running\n"
" -v verbose\n\n"
"WARNING:\n"
"For -r -f restore of the CNID database from the adouble files, the CNID must of course\n"
/* Inhereting perms in ad_mkdir etc requires this */
ad_setfuid(0);
- while ((c = getopt(argc, argv, ":cdefinrsuvx")) != -1) {
+ while ((c = getopt(argc, argv, ":cdefinrstuvx")) != -1) {
switch(c) {
case 'c':
flags |= DBD_FLAGS_CLEANUP;
case 'r':
rebuild = 1;
break;
+ case 't':
+ flags |= DBD_FLAGS_STATS;
+ break;
case 'u':
prep_upgrade = 1;
break;
}
/* Cleanup */
+ dbd_log(LOGDEBUG, "Closing db");
if (! nocniddb && dbif_close(dbd) < 0) {
dbd_log( LOGSTD, "Error closing database");
goto exit_failure;
continue;
}
+ /**************************************************************************
+ Statistics
+ **************************************************************************/
+ static unsigned long long statcount = 0;
+ static time_t t = 0;
+
+ if (t == 0)
+ t = time(NULL);
+
+ statcount++;
+ if ((statcount % 10000) == 0) {
+ if (dbd_flags & DBD_FLAGS_STATS)
+ dbd_log(LOGSTD, "Scanned: %10llu, time: %10llu s",
+ statcount, (unsigned long long)(time(NULL) - t));
+ }
+
/**************************************************************************
Tests
**************************************************************************/
/* Now add this object to our rebuild dbd */
if (cnid) {
rqst.cnid = rply.cnid;
- dbd_rebuild_add(dbd_rebuild, &rqst, &rply);
+ ret = dbd_rebuild_add(dbd_rebuild, &rqst, &rply);
+ dbif_txn_close(dbd_rebuild, ret);
if (rply.result != CNID_DBD_RES_OK) {
dbd_log( LOGDEBUG, "Fatal error adding CNID: %u for '%s/%s' to in-memory rebuild-db",
cnid, cwdbuf, ep->d_name);
*/
static void delete_orphaned_cnids(DBD *dbd, DBD *dbd_rebuild, dbd_flags_t flags)
{
- int ret, deleted = 0;
+ int ret = 0, deleted = 0;
cnid_t dbd_cnid = 0, rebuild_cnid = 0;
struct cnid_dbd_rqst rqst;
struct cnid_dbd_rply rply;
if (alarmed)
longjmp(jmp, 1); /* this jumps back to cmd_dbd_scanvol() */
- if (deleted > 50) {
+ if (deleted > 1000) {
deleted = 0;
if (dbif_txn_checkpoint(dbd, 0, 0, 0) < 0) {
dbd_log(LOGSTD, "Error checkpointing!");
return;
}
+static const char *get_tmpdb_path(void)
+{
+ pid_t pid = getpid();
+ static char path[MAXPATHLEN];
+ snprintf(path, MAXPATHLEN, "/tmp/tmpdb-dbd.%u", pid);
+ if (mkdir(path, 0755) != 0)
+ return NULL;
+ return path;
+}
+
/*
Main func called from cmd_dbd.c
*/
{
int ret = 0;
struct db_param db_param = { 0 };
+ const char *tmpdb_path = NULL;
/* Set cachesize for in-memory rebuild db */
db_param.cachesize = 128 * 1024 * 1024; /* 128 MB */
/* Get volume stamp */
dbd_getstamp(dbd, &rqst, &rply);
if (rply.result != CNID_DBD_RES_OK)
- goto exit_cleanup;
+ goto exit;
memcpy(stamp, rply.name, CNID_DEV_LEN);
/* open/create rebuild dbd, copy rootinfo key */
- if (NULL == (dbd_rebuild = dbif_init(NULL, NULL)))
- return -1;
- if (0 != (dbif_open(dbd_rebuild, &db_param, 0)))
- return -1;
- if (0 != (dbif_copy_rootinfokey(dbd, dbd_rebuild)))
- goto exit_cleanup;
+ tmpdb_path = get_tmpdb_path();
+ if (NULL == (dbd_rebuild = dbif_init(tmpdb_path, "cnid2.db"))) {
+ ret = -1;
+ goto exit;
+ }
+
+ if (dbif_env_open(dbd_rebuild,
+ &db_param,
+ DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN) < 0) {
+ dbd_log(LOGSTD, "error opening tmp database!");
+ goto exit;
+ }
+
+ if (0 != (dbif_open(dbd_rebuild, NULL, 0))) {
+ ret = -1;
+ goto exit;
+ }
+
+ if (0 != (dbif_copy_rootinfokey(dbd, dbd_rebuild))) {
+ ret = -1;
+ goto exit;
+ }
}
- if (setjmp(jmp) != 0)
- goto exit_cleanup; /* Got signal, jump from dbd_readdir */
+ if (setjmp(jmp) != 0) {
+ ret = 0; /* Got signal, jump from dbd_readdir */
+ goto exit;
+ }
/* scanvol */
- if ( (scanvol(volinfo, flags)) != 0)
- return -1;
+ if ( (scanvol(volinfo, flags)) != 0) {
+ ret = -1;
+ goto exit;
+ }
if (! nocniddb) {
/* We can only do this in exclusive mode, otherwise we might delete CNIDs added from
delete_orphaned_cnids(dbd, dbd_rebuild, flags);
}
-exit_cleanup:
- if (! nocniddb)
+exit:
+ if (dbd_rebuild) {
+ dbd_log(LOGDEBUG, "Closing tmp db");
dbif_close(dbd_rebuild);
+#if 0
+ if (tmpdb_path) {
+ char cmd[8 + MAXPATHLEN];
+ snprintf(cmd, 8 + MAXPATHLEN, "rm -f %s/*", tmpdb_path);
+ dbd_log( LOGDEBUG, "Removing temp database '%s'", tmpdb_path);
+ system(cmd);
+ snprintf(cmd, 8 + MAXPATHLEN, "rmdir %s", tmpdb_path);
+ system(cmd);
+ }
+#endif
+ }
return ret;
}