/* * Save the in-memory database mdb to the disk database dbname. * Return 0 if OK, -1 on error. */ int db_copy_out(DB *mdb, const char *dbname, const char *uname, BTREEINFO *bti) { DB *ddb; DBT key, data; int error, rv, version; if ((ddb = dbopen(dbname, O_RDWR|O_CREAT|O_TRUNC, 0644, DB_BTREE, bti)) == NULL) { warn("creating %s summary", uname); return (-1); } error = 0; for (rv = DB_SEQ(mdb, &key, &data, R_FIRST); rv == 0; rv = DB_SEQ(mdb, &key, &data, R_NEXT)) { if ((rv = DB_PUT(ddb, &key, &data, 0)) < 0) { warn("saving %s summary", uname); error = -1; goto out; } } if (rv < 0) { warn("retrieving %s stats", uname); error = -1; } out: /* Add a version record. */ key.data = (void*)&VERSION_KEY; key.size = sizeof(VERSION_KEY); version = 2; data.data = &version; data.size = sizeof(version); if ((rv = DB_PUT(ddb, &key, &data, 0)) < 0) { warn("add version record to %s stats", uname); error = -1; } else if (rv == 1) { warnx("duplicate version record in %s stats", uname); error = -1; } if (DB_SYNC(ddb, 0) < 0) { warn("syncing %s summary", uname); error = -1; } if (DB_CLOSE(ddb) < 0) { warn("closing %s summary", uname); error = -1; } return error; }
int usracct_update(void) { DB *saved_usracct_db; DBT key, data; BTREEINFO bti; int error, serr, nerr; memset(&bti, 0, sizeof(bti)); bti.compare = uid_compare; saved_usracct_db = dbopen(_PATH_USRACCT, O_RDWR|O_CREAT|O_TRUNC, 0644, DB_BTREE, &bti); if (saved_usracct_db == NULL) { warn("creating user accounting summary"); return (-1); } error = 0; serr = DB_SEQ(usracct_db, &key, &data, R_FIRST); if (serr < 0) { warn("retrieving user accounting stats"); error = -1; } while (serr == 0) { nerr = DB_PUT(saved_usracct_db, &key, &data, 0); if (nerr < 0) { warn("saving user accounting summary"); error = -1; break; } serr = DB_SEQ(usracct_db, &key, &data, R_NEXT); if (serr < 0) { warn("retrieving user accounting stats"); error = -1; break; } } if (DB_SYNC(saved_usracct_db, 0) < 0) { warn("syncing process accounting summary"); error = -1; } if (DB_CLOSE(saved_usracct_db) < 0) { warn("closing process accounting summary"); error = -1; } return error; }
void usracct_print(void) { DBT key, data; struct userinfo uistore, *ui = &uistore; double t; int rv; rv = DB_SEQ(usracct_db, &key, &data, R_FIRST); if (rv < 0) warn("retrieving user accounting stats"); while (rv == 0) { memcpy(ui, data.data, sizeof(struct userinfo)); printf("%-8s %9llu ", user_from_uid(ui->ui_uid, 0), (unsigned long long)ui->ui_calls); t = (double) (ui->ui_utime + ui->ui_stime) / (double) AHZ; if (t < 0.0001) /* kill divide by zero */ t = 0.0001; printf("%12.2f%s ", t / 60.0, "cpu"); /* ui->ui_calls is always != 0 */ if (dflag) printf("%12llu%s", (unsigned long long)(ui->ui_io / ui->ui_calls), "avio"); else printf("%12llu%s", (unsigned long long)ui->ui_io, "tio"); /* t is always >= 0.0001; see above */ if (kflag) printf("%12llu%s", (unsigned long long)(ui->ui_mem / t), "k"); else printf("%12llu%s", (unsigned long long)ui->ui_mem, "k*sec"); printf("\n"); rv = DB_SEQ(usracct_db, &key, &data, R_NEXT); if (rv < 0) warn("retrieving user accounting stats"); } }
/* * 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); }
void usracct_print() { DBT key, data; struct userinfo uistore, *ui = &uistore; double t; int rv; rv = DB_SEQ(usracct_db, &key, &data, R_FIRST); if (rv < 0) warn("retrieving user accounting stats"); while (rv == 0) { memcpy(ui, data.data, sizeof(struct userinfo)); printf("%-*s %9ju ", MAXLOGNAME - 1, user_from_uid(ui->ui_uid, 0), (uintmax_t)ui->ui_calls); #ifdef __APPLE__ t = (double) (ui->ui_utime + ui->ui_stime) / (double) AHZ; if (t < 0.0001) /* kill divide by zero */ t = 0.0001; printf("%12.2f%s ", t / 60.0, "cpu"); /* ui->ui_calls is always != 0 */ if (dflag) printf("%12ju%s", (uintmax_t)(ui->ui_io / ui->ui_calls), "avio"); else printf("%12ju%s", (uintmax_t)ui->ui_io, "tio"); /* t is always >= 0.0001; see above */ if (kflag) printf("%12.0f%s", ui->ui_mem / t, "k"); else printf("%12ju%s", (uintmax_t)ui->ui_mem, "k*sec"); #else t = (ui->ui_utime + ui->ui_stime) / 1000000; if (t < 0.000001) /* kill divide by zero */ t = 0.000001; printf("%12.2f%s ", t / 60.0, "cpu"); /* ui->ui_calls is always != 0 */ if (dflag) printf("%12.0f%s", ui->ui_io / ui->ui_calls, "avio"); else printf("%12.0f%s", ui->ui_io, "tio"); /* t is always >= 0.000001; see above. */ if (kflag) printf("%12.0f%s", ui->ui_mem / t, "k"); else printf("%12.0f%s", ui->ui_mem, "k*sec"); #endif printf("\n"); rv = DB_SEQ(usracct_db, &key, &data, R_NEXT); if (rv < 0) warn("retrieving user accounting stats"); } }
int usracct_init(void) { DB *saved_usracct_db; BTREEINFO bti; int error; int ndups = 0; memset(&bti, 0, sizeof(bti)); bti.compare = uid_compare; usracct_db = dbopen(NULL, O_RDWR|O_CREAT|O_TRUNC, 0644, DB_BTREE, &bti); if (usracct_db == NULL) return (-1); error = 0; if (!iflag) { DBT key, data; int serr, nerr; saved_usracct_db = dbopen(_PATH_USRACCT, O_RDONLY, 0, DB_BTREE, &bti); if (saved_usracct_db == NULL) { error = (errno == ENOENT) ? 0 : -1; if (error) warn("retrieving user accounting summary"); goto out; } serr = DB_SEQ(saved_usracct_db, &key, &data, R_FIRST); if (serr < 0) { warn("retrieving user accounting summary"); error = -1; goto closeout; } while (serr == 0) { nerr = DB_PUT(usracct_db, &key, &data, R_NOOVERWRITE); if (nerr < 0) { warn("initializing user accounting stats"); error = -1; break; } if (nerr == 1) { warnx("duplicate key in `%s': %s", _PATH_USRACCT, fmt(&key)); if (ndups++ == 5) { warnx("too many duplicate keys;" " `%s' possibly corrupted.", _PATH_USRACCT); error = -1; break; } } serr = DB_SEQ(saved_usracct_db, &key, &data, R_NEXT); if (serr < 0) { warn("retrieving user accounting summary"); error = -1; break; } } closeout: if (DB_CLOSE(saved_usracct_db) < 0) { warn("closing user accounting summary"); error = -1; } } out: if (error != 0) usracct_destroy(); return (error); }