int usracct_add(const struct cmdinfo *ci) { DBT key, data; struct userinfo newui; uid_t uid; int rv; uid = ci->ci_uid; key.data = &uid; key.size = sizeof uid; rv = DB_GET(usracct_db, &key, &data, 0); if (rv < 0) { warn("get key %u from user accounting stats", uid); return (-1); } else if (rv == 0) { /* it's there; copy whole thing */ /* add the old data to the new data */ bcopy(data.data, &newui, data.size); if (newui.ui_uid != uid) { warnx("key %u != expected record number %u", newui.ui_uid, uid); warnx("inconsistent user accounting stats"); return (-1); } } else { /* it's not there; zero it and copy the key */ bzero(&newui, sizeof newui); newui.ui_uid = ci->ci_uid; } newui.ui_calls += ci->ci_calls; newui.ui_utime += ci->ci_utime; newui.ui_stime += ci->ci_stime; newui.ui_mem += ci->ci_mem; newui.ui_io += ci->ci_io; data.data = &newui; data.size = sizeof newui; rv = DB_PUT(usracct_db, &key, &data, 0); if (rv < 0) { warn("add key %u to user accounting stats", uid); return (-1); } else if (rv != 0) { warnx("DB_PUT returned 1"); return (-1); } return (0); }
/* * Create the in-memory database, *mdb. * If iflag is not set, fill-in mdb with the records of the disk-based * database dbname. * Upgrade old-version records by calling v1_to_v2. * Return 0 if OK, -1 on error. */ int db_copy_in(DB **mdb, const char *dbname, const char *uname, BTREEINFO *bti, int (*v1_to_v2)(DBT *key, DBT *data)) { DBT key, data; DB *ddb; int error, rv, version; if ((*mdb = dbopen(NULL, O_RDWR, 0, DB_BTREE, bti)) == NULL) return (-1); if (iflag) return (0); if ((ddb = dbopen(dbname, O_RDONLY, 0, DB_BTREE, bti)) == NULL) { if (errno == ENOENT) return (0); warn("retrieving %s summary", uname); db_destroy(*mdb, uname); return (-1); } error = 0; /* Obtain/set version. */ version = 1; key.data = (void*)&VERSION_KEY; key.size = sizeof(VERSION_KEY); rv = DB_GET(ddb, &key, &data, 0); if (rv < 0) { warn("get version key from %s stats", uname); error = -1; goto closeout; } else if (rv == 0) { /* It's there; verify version. */ if (data.size != sizeof(version)) { warnx("invalid version size %zd in %s", data.size, uname); error = -1; goto closeout; } memcpy(&version, data.data, data.size); if (version != 2) { warnx("unsupported version %d in %s", version, uname); error = -1; goto closeout; } } for (rv = DB_SEQ(ddb, &key, &data, R_FIRST); rv == 0; rv = DB_SEQ(ddb, &key, &data, R_NEXT)) { /* See if this is a version record. */ if (key.size == sizeof(VERSION_KEY) && memcmp(key.data, VERSION_KEY, sizeof(VERSION_KEY)) == 0) continue; /* Convert record from v1, if needed. */ if (version == 1 && v1_to_v2(&key, &data) < 0) { warn("converting %s stats", uname); error = -1; goto closeout; } /* Copy record to the in-memory database. */ if ((rv = DB_PUT(*mdb, &key, &data, 0)) < 0) { warn("initializing %s stats", uname); error = -1; goto closeout; } } if (rv < 0) { warn("retrieving %s summary", uname); error = -1; } closeout: if (DB_CLOSE(ddb) < 0) { warn("closing %s summary", uname); error = -1; } if (error) db_destroy(*mdb, uname); return (error); }
/* search the cache for an object, and if it is not found, thaw it. this code is probably a little bigger than it needs be because I had fun and unrolled all the pointer juggling inline. */ Object * cache_get(int oid) { Cache *cp; int hv = 0; Object *ret; static const char *nmmesg = "cache_get: cannot allocate memory"; /* firewall */ if(!cache_initted) { #ifdef CACHE_VERBOSE writelog(); fprintf(stderr, "cache_get: cache not initted\n"); #endif return((Object *)0); } #ifdef CACHE_DEBUG printf("get #%d\n",oid); #endif if (oid < 0) return((Object *)0); cs_reads++; hv = objid_hash(oid,cwidth); /* search active chain first */ for(cp = sys_c[hv].ahead; cp != (Cache *)0; cp = cp->nxt) { if(!(cp->flg & C_DEAD) && cp->oid == oid) { cs_rhits++; cs_ahits++; #ifdef CACHE_DEBUG printf("return #%d active cache %d\n",cp->oid,cp->op); #endif return(cp->op); } } /* search in-active chain second */ for(cp = sys_c[hv].ohead; cp != (Cache *)0; cp = cp->nxt) { if(!(cp->flg & C_DEAD) && cp->oid == oid) { /* dechain from in-active chain */ if(cp->nxt == (Cache *)0) sys_c[hv].otail = cp->prv; else cp->nxt->prv = cp->prv; if(cp->prv == (Cache *)0) sys_c[hv].ohead = cp->nxt; else cp->prv->nxt = cp->nxt; /* insert at head of active chain */ cp->nxt = sys_c[hv].ahead; if(sys_c[hv].ahead == (Cache *)0) sys_c[hv].atail = cp; cp->prv = (Cache *)0; if(cp->nxt != (Cache *)0) cp->nxt->prv = cp; sys_c[hv].ahead = cp; /* done */ cs_rhits++; #ifdef CACHE_DEBUG printf("return #%d old cache %d\n",cp->oid,cp->op); #endif return(cp->op); } } /* DARN IT - at this point we have a certified, type-A cache miss */ /* thaw the object from wherever. */ if((ret = DB_GET(oid)) == (Object *)0) { cs_fails++; #ifdef CACHE_DEBUG printf("#%d not in db\n",oid); #endif return((Object *)0); } cs_dbreads++; /* if there are no old cache object holders left, allocate one */ if(sys_c[hv].otail == (Cache *)0) { if((cp = (Cache *)malloc(sizeof(Cache))) == (Cache *)0) panic(nmmesg); cp->oid = oid; cp->flg = C_NOFLG; /* linkit at head of active chain */ cp->nxt = sys_c[hv].ahead; if(sys_c[hv].ahead == (Cache *)0) sys_c[hv].atail = cp; cp->prv = (Cache *)0; if(cp->nxt != (Cache *)0) cp->nxt->prv = cp; sys_c[hv].ahead = cp; cs_objects++; #ifdef CACHE_DEBUG printf("return #%d loaded into cache %d\n",cp->oid,cp->op); #endif return(cp->op = ret); } /* unlink old cache chain tail */ cp = sys_c[hv].otail; if(cp->prv != (Cache *)0) { sys_c[hv].otail = cp->prv; cp->prv->nxt = cp->nxt; } else /* took last one */ sys_c[hv].ohead = sys_c[hv].otail = (Cache *)0; /* if there is a dirty object still in memory, write it */ if((cp->flg & C_DIRTY) && cp->oid >= 0 && cp->op != (Object *)0) { #ifdef CACHE_DEBUG printf("clean #%d from cache %d\n",cp->oid,cp->op); #endif if(DB_PUT(cp->op,cp->oid)) return((Object *)0); cs_dbwrites++; } /* free object's data */ if(cp->op != (Object *)0) free_object(cp->op); cp->op = ret; cp->oid = oid; cp->flg = C_NOFLG; /* relink at head of active chain */ cp->nxt = sys_c[hv].ahead; if(sys_c[hv].ahead == (Cache *)0) sys_c[hv].atail = cp; cp->prv = (Cache *)0; if(cp->nxt != (Cache *)0) cp->nxt->prv = cp; sys_c[hv].ahead = cp; #ifdef CACHE_DEBUG printf("return #%d loaded into cache %d\n",cp->oid,cp->op); #endif return(ret); }