5 #include <ashd/utils.h>
15 time_t lastcp, lastar;
20 static struct fileinfo dbserve(struct source *src, char *nm)
22 struct dbsrc *d = src->pdata;
29 memset(&k, 0, sizeof(k));
30 memset(&v, 0, sizeof(v));
31 k.size = strlen(k.data = nm);
32 v.flags = DB_DBT_MALLOC;
34 ret = d->db->get(d->db, NULL, &k, &v, 0);
35 } while(ret == DB_LOCK_DEADLOCK);
46 memset(&retf, 0, sizeof(retf));
47 for(i = 0, retf.mtime = 0; i < 8; i++) {
48 retf.mtime = (retf.mtime << 8) | (*(uint8_t *)hp);
53 if((p = memchr(hp, 0, sz)) == NULL)
58 strcpy(retf.ctype, hp);
60 retf.data = memcpy(smalloc(retf.sz = sz), hp, sz);
66 } else if(ret == DB_NOTFOUND) {
67 return((struct fileinfo){});
69 flog(LOG_ERR, "could not read value of %s in %s: %s", nm, d->envnm, db_strerror(ret));
70 return((struct fileinfo){});
75 flog(LOG_ERR, "entry for %s in %s is corrupted", nm, d->envnm);
77 return((struct fileinfo){});
81 static void dbidle(struct source *src)
83 struct dbsrc *d = src->pdata;
89 if(now - d->lastcp > 1800) {
91 if((ret = d->env->txn_checkpoint(d->env, 5000, 0, 0)) != 0) {
92 flog(LOG_ERR, "could not make db checkpoint in %s: %s", d->envnm, db_strerror(ret));
95 if(now - d->lastar > 7200) {
98 if((ret = d->env->log_archive(d->env, &files, DB_ARCH_REMOVE)) != 0) {
99 flog(LOG_ERR, "could not archive log files in %s: %s", d->envnm, db_strerror(ret));
106 static void enverror(const DB_ENV *env, const char *prefix, const char *msg)
108 flog(LOG_ERR, "dbsource: environment error: %s", msg);
111 struct source *mkdbsrc(char *path, char *envpath)
119 src->serve = dbserve;
121 src->pdata = omalloc(d);
122 if((ret = db_env_create(&d->env, 0)) != 0) {
123 flog(LOG_ERR, "could not create bdb environment: %s", db_strerror(ret));
127 d->envnm = sstrdup(envpath);
129 d->envnm = sstrdup(path);
130 if((p = strrchr(d->envnm, '/')) == NULL) {
132 d->envnm = sstrdup(".");
137 if((ret = d->env->open(d->env, d->envnm, DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN, 0666)) != 0) {
138 flog(LOG_ERR, "could not open bdb environment: %s", db_strerror(ret));
141 d->env->set_lk_detect(d->env, DB_LOCK_RANDOM);
142 d->env->set_errcall(d->env, enverror);
143 if((ret = db_create(&d->db, d->env, 0)) != 0) {
144 flog(LOG_ERR, "could not create bdb database: %s", db_strerror(ret));
148 if((ret = d->db->set_pagesize(d->db, dbpagesize)) != 0) {
149 flog(LOG_ERR, "could not set bdb page size (to %i): %s", dbpagesize, db_strerror(ret));
153 if((ret = d->db->open(d->db, NULL, path, NULL, DB_HASH, DB_AUTO_COMMIT | DB_CREATE, 0666)) != 0) {
154 flog(LOG_ERR, "could not open bdb database: %s", db_strerror(ret));