void * logfile_thread(void *arg) { DB_ENV *dbenv; int ret; char **begin, **list; dbenv = arg; dbenv->errx(dbenv, "Log file removal thread: %lu", (u_long)pthread_self()); /* Check once every 5 minutes. */ for (;; sleep(300)) { /* Get the list of log files. */ if ((ret = dbenv->log_archive(dbenv, &list, DB_ARCH_ABS)) != 0) { dbenv->err(dbenv, ret, "DB_ENV->log_archive"); exit (1); } /* Remove the log files. */ if (list != NULL) { for (begin = list; *list != NULL; ++list) if ((ret = remove(*list)) != 0) { dbenv->err(dbenv, ret, "remove %s", *list); exit (1); } free (begin); } } /* NOTREACHED */ }
void *db_maint(void *arg) { DB_ENV *dbenv = arg; int i, ret; char **begin, **list; for(;; sleep(db_maint_delay * 60)) { if((ret = dbenv->txn_checkpoint(dbenv, 0, 0, DB_FORCE)) != 0) { NETERROR(MRADC, ("db_maint thread: checkpoint failed: %d\n", ret)); } if((ret = dbenv->log_archive(dbenv, &list, DB_ARCH_ABS)) != 0) { NETERROR(MRADC, ("db_maint thread: log archive failed: %d\n", ret)); } if(list != NULL) { for(begin = list; *list != NULL; ++list) { if((ret = remove(*list)) != 0) { NETERROR(MRADC, ("db_maint thread: remove %s failed: %d\n", *list, ret)); } } free(begin); } } }
static void cleanup() { int rc; DB *db; DB_ENV *dbenv; rc = get_db(&db, 0); assert(! rc); rc = get_dbenv(&dbenv, 0); assert(! rc); if (dbkey.data) free(dbkey.data); if (db) call_db(db->close(db, 0), "DB close"); if (dbenv) { rc = call_db(db_create(&db, dbenv, 0), "db_create"); if (!rc) if (! db->remove(db, "tls_stats.db", 0, 0)) syslog(LOG_NOTICE, "Unused database tls_stats.db removed"); call_db(dbenv->txn_checkpoint(dbenv, 100 * 1024, 24 * 60, 0), "txn_checkpoint"); call_db(dbenv->log_archive(dbenv, NULL, DB_ARCH_REMOVE), "log_archive"); call_db(dbenv->close(dbenv, 0), "DB_ENV close"); } policy_cleanup(); }
/* * This should be done before the program is open for business. * As such, it does not need to be reentrant. */ int open_db_env(char *topdir) { DB_ENV *tmpenv = NULL; int st; struct stat64 sbuf; char logdir[MAXPATHLEN+1]; char tmpdir[MAXPATHLEN+1]; char *dirarr[3]; int i; if (topdir == NULL) { return (-1); } snprintf(logdir, sizeof (tmpdir), "%s/.logs", topdir); snprintf(tmpdir, sizeof (tmpdir), "%s/.tmp", topdir); dirarr[0] = topdir; dirarr[1] = logdir; dirarr[2] = tmpdir; /* first, set up the environment */ st = db_env_create(&tmpenv, 0); if (st != 0) { return (st); } /* make sure the directories exist */ for (i = 0; i < 3; i++) { st = stat64(dirarr[i], &sbuf); if ((st != 0) && (errno == ENOENT)) { st = mkdirp(dirarr[i], 0744); if (st == 0) { st = stat64(dirarr[i], &sbuf); } } if ((st == 0) && (!S_ISDIR(sbuf.st_mode))) { st = -1; break; } } if (st != 0) { return (st); } st = tmpenv->set_data_dir(tmpenv, topdir); if (st != 0) { return (st); } st = tmpenv->set_lg_dir(tmpenv, logdir); if (st != 0) { return (st); } st = tmpenv->set_tmp_dir(tmpenv, tmpdir); if (st != 0) { return (st); } st = tmpenv->set_flags(tmpenv, env_fl, 1); if (st != 0) { return (st); } /* overall database cache size */ st = tmpenv->set_cachesize(tmpenv, 0, (60 * MEGA), 1); st = tmpenv->set_shm_key(tmpenv, FSM_SHM_MASTER_KEY); if (st != 0) { return (st); } /* log buffer in memory */ st = tmpenv->set_lg_bsize(tmpenv, (30 * MEGA)); if (st != 0) { return (st); } /* set up additional error logging */ tmpenv->set_errcall(tmpenv, fsmdb_log_err); /* Increase the number of locks available */ tmpenv->set_lk_max_locks(tmpenv, 10000); tmpenv->set_lk_max_lockers(tmpenv, 10000); tmpenv->set_lk_max_objects(tmpenv, 10000); /* Increase the number of concurrent transactions available */ /* Note: Default in 4.4-20 is '20'. In later versions it's 100 */ tmpenv->set_tx_max(tmpenv, 100); st = tmpenv->open(tmpenv, topdir, env_ofl, 0644); if (st != 0) { /* check for a major failure */ if (st == DB_RUNRECOVERY) { st = tmpenv->open(tmpenv, topdir, env_ffl, 0644); } /* log catastrophic failure and remove all db files. */ if (st == DB_RUNRECOVERY) { fsmdb_log_err(dbEnv, NULL, "Database files corrupt, cannot recover. " "Files will be removed. Please re-index any " "recovery points to regenerate the database."); fsmdb_remove_all(topdir); } } if (st != 0) { return (st); } /* clear out unneeded log files */ tmpenv->log_archive(tmpenv, NULL, DB_ARCH_REMOVE); /* all set, ready to use */ dbEnv = tmpenv; return (st); }