/* * Print the status of each queue listed or all the queues. */ void status(int argc, char **argv) { int c, status; char *cp1, *cp2; char prbuf[100]; if (argc == 1 || (argc == 2 && strcmp(argv[1], "all") == 0)) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; cp2 = bp; while ((c = *cp2++) && c != '|' && c != ':' && (cp1 - prbuf) < sizeof(prbuf) - 1) *cp1++ = c; *cp1 = '\0'; prstat(); } return; } while (--argc) { printer = *++argv; if ((status = cgetent(&bp, printcapdb, printer)) == -2) { printf("cannot open printer description file\n"); continue; } else if (status == -1) { printf("unknown printer %s\n", printer); continue; } else if (status == -3) fatal("potential reference loop detected in printcap file"); prstat(); } }
static int dir(int argc, char **argv) { int i = 0, r; char buf[BUF_SIZ]; if (argc > 2) { printf("usage: %s [file]\n", argv[0]); return 1; } if (argc == 2) { r = stat(argv[1], &sbuf); if (r < 0) { printf("stat(%s) failed: %d\n", buf, r); return 0; } prstat(argv[1]); return 0; } while (1) { r = getdirent(i, buf, BUF_SIZ); if (r < 0) { printf("dirent(%d) failed: %d\n", i, r); break; } else if (!r) { break; } #if 0 printf("dirent(%d): \"%s\"\n", i, buf); #endif r = stat(buf, &sbuf); if (r < 0) { printf("stat(%s) failed: %d\n", buf, r); break; } prstat(buf); i++; } return 0; }
int main(int argc, char *argv[]) { int i, rc; MDB_env *env; MDB_txn *txn; MDB_dbi dbi; MDB_stat mst; MDB_envinfo mei; char *prog = argv[0]; char *envname; char *subname = NULL; int alldbs = 0, envinfo = 0, envflags = 0, freinfo = 0, rdrinfo = 0; if (argc < 2) { usage(prog); } /* -a: print stat of main DB and all subDBs * -s: print stat of only the named subDB * -e: print env info * -f: print freelist info * -r: print reader info * -n: use NOSUBDIR flag on env_open * -V: print version and exit * (default) print stat of only the main DB */ while ((i = getopt(argc, argv, "Vaefnrs:")) != EOF) { switch(i) { case 'V': printf("%s\n", MDB_VERSION_STRING); exit(0); break; case 'a': if (subname) usage(prog); alldbs++; break; case 'e': envinfo++; break; case 'f': freinfo++; break; case 'n': envflags |= MDB_NOSUBDIR; break; case 'r': rdrinfo++; break; case 's': if (alldbs) usage(prog); subname = optarg; break; default: usage(prog); } } if (optind != argc - 1) usage(prog); envname = argv[optind]; rc = mdb_env_create(&env); if (rc) { fprintf(stderr, "mdb_env_create failed, error %d %s\n", rc, mdb_strerror(rc)); return EXIT_FAILURE; } if (alldbs || subname) { mdb_env_set_maxdbs(env, 4); } rc = mdb_env_open(env, envname, envflags | MDB_RDONLY, 0664); if (rc) { fprintf(stderr, "mdb_env_open failed, error %d %s\n", rc, mdb_strerror(rc)); goto env_close; } if (envinfo) { (void)mdb_env_stat(env, &mst); (void)mdb_env_info(env, &mei); printf("Environment Info\n"); printf(" Map address: %p\n", mei.me_mapaddr); printf(" Map size: %"Z"u\n", mei.me_mapsize); printf(" Page size: %u\n", mst.ms_psize); printf(" Max pages: %"Z"u\n", mei.me_mapsize / mst.ms_psize); printf(" Number of pages used: %"Z"u\n", mei.me_last_pgno+1); printf(" Last transaction ID: %"Z"u\n", mei.me_last_txnid); printf(" Max readers: %u\n", mei.me_maxreaders); printf(" Number of readers used: %u\n", mei.me_numreaders); } if (rdrinfo) { printf("Reader Table Status\n"); rc = mdb_reader_list(env, (MDB_msg_func *)fputs, stdout); if (rdrinfo > 1) { int dead; mdb_reader_check(env, &dead); printf(" %d stale readers cleared.\n", dead); rc = mdb_reader_list(env, (MDB_msg_func *)fputs, stdout); } if (!(subname || alldbs || freinfo)) goto env_close; } rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); if (rc) { fprintf(stderr, "mdb_txn_begin failed, error %d %s\n", rc, mdb_strerror(rc)); goto env_close; } if (freinfo) { MDB_cursor *cursor; MDB_val key, data; size_t pages = 0, *iptr; printf("Freelist Status\n"); dbi = 0; rc = mdb_cursor_open(txn, dbi, &cursor); if (rc) { fprintf(stderr, "mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc)); goto txn_abort; } rc = mdb_stat(txn, dbi, &mst); if (rc) { fprintf(stderr, "mdb_stat failed, error %d %s\n", rc, mdb_strerror(rc)); goto txn_abort; } prstat(&mst); while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { iptr = data.mv_data; pages += *iptr; if (freinfo > 1) { char *bad = ""; size_t pg, prev; ssize_t i, j, span = 0; j = *iptr++; for (i = j, prev = 1; --i >= 0; ) { pg = iptr[i]; if (pg <= prev) bad = " [bad sequence]"; prev = pg; pg += span; for (; i >= span && iptr[i-span] == pg; span++, pg++) ; } printf(" Transaction %"Z"u, %"Z"d pages, maxspan %"Z"d%s\n", *(size_t *)key.mv_data, j, span, bad); if (freinfo > 2) { for (--j; j >= 0; ) { pg = iptr[j]; for (span=1; --j >= 0 && iptr[j] == pg+span; span++) ; printf(span>1 ? " %9"Z"u[%"Z"d]\n" : " %9"Z"u\n", pg, span); } } } } mdb_cursor_close(cursor); printf(" Free pages: %"Z"u\n", pages); } rc = mdb_open(txn, subname, 0, &dbi); if (rc) { fprintf(stderr, "mdb_open failed, error %d %s\n", rc, mdb_strerror(rc)); goto txn_abort; } rc = mdb_stat(txn, dbi, &mst); if (rc) { fprintf(stderr, "mdb_stat failed, error %d %s\n", rc, mdb_strerror(rc)); goto txn_abort; } printf("Status of %s\n", subname ? subname : "Main DB"); prstat(&mst); if (alldbs) { MDB_cursor *cursor; MDB_val key; rc = mdb_cursor_open(txn, dbi, &cursor); if (rc) { fprintf(stderr, "mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc)); goto txn_abort; } while ((rc = mdb_cursor_get(cursor, &key, NULL, MDB_NEXT_NODUP)) == 0) { char *str; MDB_dbi db2; if (memchr(key.mv_data, '\0', key.mv_size)) continue; str = malloc(key.mv_size+1); memcpy(str, key.mv_data, key.mv_size); str[key.mv_size] = '\0'; rc = mdb_open(txn, str, 0, &db2); if (rc == MDB_SUCCESS) printf("Status of %s\n", str); free(str); if (rc) continue; rc = mdb_stat(txn, db2, &mst); if (rc) { fprintf(stderr, "mdb_stat failed, error %d %s\n", rc, mdb_strerror(rc)); goto txn_abort; } prstat(&mst); mdb_close(env, db2); } mdb_cursor_close(cursor); } if (rc == MDB_NOTFOUND) rc = MDB_SUCCESS; mdb_close(env, dbi); txn_abort: mdb_txn_abort(txn); env_close: mdb_env_close(env); return rc ? EXIT_FAILURE : EXIT_SUCCESS; }
int main(int argc, char *argv[]) { int o, rc; MDBX_env *env; MDBX_txn *txn; MDBX_dbi dbi; MDBX_stat mst; MDBX_envinfo mei; char *prog = argv[0]; char *envname; char *subname = NULL; int alldbs = 0, envinfo = 0, envflags = 0, freinfo = 0, rdrinfo = 0; if (argc < 2) { usage(prog); } /* -a: print stat of main DB and all subDBs * -s: print stat of only the named subDB * -e: print env info * -f: print freelist info * -r: print reader info * -n: use NOSUBDIR flag on env_open * -V: print version and exit * (default) print stat of only the main DB */ while ((o = getopt(argc, argv, "Vaefnrs:")) != EOF) { switch (o) { case 'V': printf("%s (%s, build %s)\n", mdbx_version.git.describe, mdbx_version.git.datetime, mdbx_build.datetime); exit(EXIT_SUCCESS); break; case 'a': if (subname) usage(prog); alldbs++; break; case 'e': envinfo++; break; case 'f': freinfo++; break; case 'n': envflags |= MDBX_NOSUBDIR; break; case 'r': rdrinfo++; break; case 's': if (alldbs) usage(prog); subname = optarg; break; default: usage(prog); } } if (optind != argc - 1) usage(prog); #if defined(_WIN32) || defined(_WIN64) SetConsoleCtrlHandler(ConsoleBreakHandlerRoutine, true); #else #ifdef SIGPIPE signal(SIGPIPE, signal_handler); #endif #ifdef SIGHUP signal(SIGHUP, signal_handler); #endif signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); #endif /* !WINDOWS */ envname = argv[optind]; rc = mdbx_env_create(&env); if (rc) { fprintf(stderr, "mdbx_env_create failed, error %d %s\n", rc, mdbx_strerror(rc)); return EXIT_FAILURE; } if (alldbs || subname) { mdbx_env_set_maxdbs(env, 4); } rc = mdbx_env_open(env, envname, envflags | MDBX_RDONLY, 0664); if (rc) { fprintf(stderr, "mdbx_env_open failed, error %d %s\n", rc, mdbx_strerror(rc)); goto env_close; } if (envinfo || freinfo) { (void)mdbx_env_info(env, &mei, sizeof(mei)); } else { /* LY: zap warnings from gcc */ memset(&mei, 0, sizeof(mei)); } if (envinfo) { (void)mdbx_env_stat(env, &mst, sizeof(mst)); printf("Environment Info\n"); printf(" Pagesize: %u\n", mst.ms_psize); if (mei.mi_geo.lower != mei.mi_geo.upper) { printf(" Dynamic datafile: %" PRIu64 "..%" PRIu64 " bytes (+%" PRIu64 "/-%" PRIu64 "), %" PRIu64 "..%" PRIu64 " pages (+%" PRIu64 "/-%" PRIu64 ")\n", mei.mi_geo.lower, mei.mi_geo.upper, mei.mi_geo.grow, mei.mi_geo.shrink, mei.mi_geo.lower / mst.ms_psize, mei.mi_geo.upper / mst.ms_psize, mei.mi_geo.grow / mst.ms_psize, mei.mi_geo.shrink / mst.ms_psize); printf(" Current datafile: %" PRIu64 " bytes, %" PRIu64 " pages\n", mei.mi_geo.current, mei.mi_geo.current / mst.ms_psize); } else { printf(" Fixed datafile: %" PRIu64 " bytes, %" PRIu64 " pages\n", mei.mi_geo.current, mei.mi_geo.current / mst.ms_psize); } printf(" Current mapsize: %" PRIu64 " bytes, %" PRIu64 " pages \n", mei.mi_mapsize, mei.mi_mapsize / mst.ms_psize); printf(" Number of pages used: %" PRIu64 "\n", mei.mi_last_pgno + 1); printf(" Last transaction ID: %" PRIu64 "\n", mei.mi_recent_txnid); printf(" Tail transaction ID: %" PRIu64 " (%" PRIi64 ")\n", mei.mi_latter_reader_txnid, mei.mi_latter_reader_txnid - mei.mi_recent_txnid); printf(" Max readers: %u\n", mei.mi_maxreaders); printf(" Number of readers used: %u\n", mei.mi_numreaders); } else { /* LY: zap warnings from gcc */ memset(&mst, 0, sizeof(mst)); } if (rdrinfo) { printf("Reader Table Status\n"); rc = mdbx_reader_list(env, (MDBX_msg_func *)fputs, stdout); if (rdrinfo > 1) { int dead; mdbx_reader_check(env, &dead); printf(" %d stale readers cleared.\n", dead); rc = mdbx_reader_list(env, (MDBX_msg_func *)fputs, stdout); } if (!(subname || alldbs || freinfo)) goto env_close; } rc = mdbx_txn_begin(env, NULL, MDBX_RDONLY, &txn); if (rc) { fprintf(stderr, "mdbx_txn_begin failed, error %d %s\n", rc, mdbx_strerror(rc)); goto env_close; } if (freinfo) { MDBX_cursor *cursor; MDBX_val key, data; pgno_t pages = 0, *iptr; pgno_t reclaimable = 0; printf("Freelist Status\n"); dbi = 0; rc = mdbx_cursor_open(txn, dbi, &cursor); if (rc) { fprintf(stderr, "mdbx_cursor_open failed, error %d %s\n", rc, mdbx_strerror(rc)); goto txn_abort; } rc = mdbx_dbi_stat(txn, dbi, &mst, sizeof(mst)); if (rc) { fprintf(stderr, "mdbx_dbi_stat failed, error %d %s\n", rc, mdbx_strerror(rc)); goto txn_abort; } prstat(&mst); while ((rc = mdbx_cursor_get(cursor, &key, &data, MDBX_NEXT)) == MDBX_SUCCESS) { if (user_break) { rc = MDBX_EINTR; break; } iptr = data.iov_base; const pgno_t number = *iptr++; pages += number; if (envinfo && mei.mi_latter_reader_txnid > *(size_t *)key.iov_base) reclaimable += number; if (freinfo > 1) { char *bad = ""; pgno_t prev = MDBX_PNL_ASCENDING ? NUM_METAS - 1 : (pgno_t)mei.mi_last_pgno + 1; pgno_t span = 1; for (unsigned i = 0; i < number; ++i) { pgno_t pg = iptr[i]; if (MDBX_PNL_DISORDERED(prev, pg)) bad = " [bad sequence]"; prev = pg; while (i + span < number && iptr[i + span] == (MDBX_PNL_ASCENDING ? pgno_add(pg, span) : pgno_sub(pg, span))) ++span; } printf(" Transaction %" PRIaTXN ", %" PRIaPGNO " pages, maxspan %" PRIaPGNO "%s\n", *(txnid_t *)key.iov_base, number, span, bad); if (freinfo > 2) { for (unsigned i = 0; i < number; i += span) { const pgno_t pg = iptr[i]; for (span = 1; i + span < number && iptr[i + span] == (MDBX_PNL_ASCENDING ? pgno_add(pg, span) : pgno_sub(pg, span)); ++span) ; if (span > 1) printf(" %9" PRIaPGNO "[%" PRIaPGNO "]\n", pg, span); else printf(" %9" PRIaPGNO "\n", pg); } } } } mdbx_cursor_close(cursor); switch (rc) { case MDBX_SUCCESS: case MDBX_NOTFOUND: break; case MDBX_EINTR: fprintf(stderr, "Interrupted by signal/user\n"); goto txn_abort; default: fprintf(stderr, "mdbx_cursor_get failed, error %d %s\n", rc, mdbx_strerror(rc)); goto txn_abort; } if (envinfo) { uint64_t value = mei.mi_mapsize / mst.ms_psize; double percent = value / 100.0; printf("Page Allocation Info\n"); printf(" Max pages: %" PRIu64 " 100%%\n", value); value = mei.mi_last_pgno + 1; printf(" Pages used: %" PRIu64 " %.1f%%\n", value, value / percent); value = mei.mi_mapsize / mst.ms_psize - (mei.mi_last_pgno + 1); printf(" Remained: %" PRIu64 " %.1f%%\n", value, value / percent); value = mei.mi_last_pgno + 1 - pages; printf(" Used now: %" PRIu64 " %.1f%%\n", value, value / percent); value = pages; printf(" Unallocated: %" PRIu64 " %.1f%%\n", value, value / percent); value = pages - reclaimable; printf(" Detained: %" PRIu64 " %.1f%%\n", value, value / percent); value = reclaimable; printf(" Reclaimable: %" PRIu64 " %.1f%%\n", value, value / percent); value = mei.mi_mapsize / mst.ms_psize - (mei.mi_last_pgno + 1) + reclaimable; printf(" Available: %" PRIu64 " %.1f%%\n", value, value / percent); } else printf(" Free pages: %" PRIaPGNO "\n", pages); } rc = mdbx_dbi_open(txn, subname, 0, &dbi); if (rc) { fprintf(stderr, "mdbx_open failed, error %d %s\n", rc, mdbx_strerror(rc)); goto txn_abort; } rc = mdbx_dbi_stat(txn, dbi, &mst, sizeof(mst)); if (rc) { fprintf(stderr, "mdbx_dbi_stat failed, error %d %s\n", rc, mdbx_strerror(rc)); goto txn_abort; } printf("Status of %s\n", subname ? subname : "Main DB"); prstat(&mst); if (alldbs) { MDBX_cursor *cursor; MDBX_val key; rc = mdbx_cursor_open(txn, dbi, &cursor); if (rc) { fprintf(stderr, "mdbx_cursor_open failed, error %d %s\n", rc, mdbx_strerror(rc)); goto txn_abort; } while ((rc = mdbx_cursor_get(cursor, &key, NULL, MDBX_NEXT_NODUP)) == 0) { char *str; MDBX_dbi db2; if (memchr(key.iov_base, '\0', key.iov_len)) continue; str = mdbx_malloc(key.iov_len + 1); memcpy(str, key.iov_base, key.iov_len); str[key.iov_len] = '\0'; rc = mdbx_dbi_open(txn, str, 0, &db2); if (rc == MDBX_SUCCESS) printf("Status of %s\n", str); mdbx_free(str); if (rc) continue; rc = mdbx_dbi_stat(txn, db2, &mst, sizeof(mst)); if (rc) { fprintf(stderr, "mdbx_dbi_stat failed, error %d %s\n", rc, mdbx_strerror(rc)); goto txn_abort; } prstat(&mst); mdbx_dbi_close(env, db2); } mdbx_cursor_close(cursor); } if (rc == MDBX_NOTFOUND) rc = MDBX_SUCCESS; mdbx_dbi_close(env, dbi); txn_abort: mdbx_txn_abort(txn); env_close: mdbx_env_close(env); return rc ? EXIT_FAILURE : EXIT_SUCCESS; }