libhammer_volinfo_t libhammer_get_volinfo(const char *path) { struct hammer_pseudofs_data *pfs_od; struct hammer_ioc_pfs_iterate pi; struct hammer_ioc_info info; libhammer_pfsinfo_t pfstmp; libhammer_volinfo_t hvi; int error = 0; int fd; if ((fd = open(path, O_RDONLY)) < 0) return NULL; hvi = _libhammer_malloc(sizeof(*hvi)); TAILQ_INIT(&hvi->list_pseudo); if ((ioctl(fd, HAMMERIOC_GET_INFO, &info)) < 0) { libhammer_free_volinfo(hvi); close(fd); return NULL; } /* Fill volume information */ snprintf(hvi->vol_name, TXTLEN, "%s", info.vol_name); hvi->vol_fsid = info.vol_fsid; hvi->version = info.version; hvi->nvolumes = info.nvolumes; hvi->inodes = info.inodes; hvi->bigblocks = info.bigblocks; hvi->freebigblocks = info.freebigblocks; hvi->rsvbigblocks = info.rsvbigblocks; bzero(&pi, sizeof(pi)); pi.ondisk = _libhammer_malloc(sizeof(*pfs_od)); while(error == 0) { error = ioctl(fd, HAMMERIOC_PFS_ITERATE, &pi); if (error == 0 && ((pi.head.flags & HAMMER_PFSD_DELETED) == 0)) { /* * XXX - In the case the path passed is on PFS#0 but it * is not the mountpoint itself, it could produce a * wrong type of PFS. */ pfstmp = _libhammer_malloc(sizeof(*pfstmp)); pfs_od = pi.ondisk; pfstmp->ismaster = (pfs_od->mirror_flags & HAMMER_PFSD_SLAVE) ? 0 : 1; if (pi.pos == 0) pfstmp->mountedon = strdup(path); else pfstmp->mountedon = libhammer_find_pfs_mount(pi.pos, hvi->vol_fsid, pfstmp->ismaster); /* * Fill in structs used in the library. We don't rely on * HAMMER own struct but we do fill our own. */ pfstmp->version = hvi->version; pfstmp->pfs_id = pi.pos; pfstmp->mirror_flags = pfs_od->mirror_flags; pfstmp->beg_tid = pfs_od->sync_beg_tid; pfstmp->end_tid = pfs_od->sync_end_tid; pfstmp->snapcount = count_snapshots(hvi->version, pfstmp->snapshots, pfstmp->mountedon, &pfstmp->head.error); TAILQ_INSERT_TAIL(&hvi->list_pseudo, pfstmp, entries); } pi.pos++; } free(pi.ondisk); close (fd); return (hvi); }
void show_info(char *path) { libhammer_volinfo_t hvi; libhammer_pfsinfo_t pi, pi_first; int64_t usedbigblocks; int64_t usedbytes, rsvbytes; int64_t totalbytes, freebytes; int error; char *fsid; char buf[6]; u_int32_t sc; fsid = NULL; usedbigblocks = 0; usedbytes = totalbytes = rsvbytes = freebytes = 0; sc = error = 0; hvi = libhammer_get_volinfo(path); if (hvi == NULL) { perror("libhammer_get_volinfo"); exit(EXIT_FAILURE); } /* Find out the UUID strings */ uuid_to_string(&hvi->vol_fsid, &fsid, NULL); /* Volume information */ fprintf(stdout, "Volume identification\n"); fprintf(stdout, "\tLabel %s\n", hvi->vol_name); fprintf(stdout, "\tNo. Volumes %d\n", hvi->nvolumes); fprintf(stdout, "\tFSID %s\n", fsid); fprintf(stdout, "\tHAMMER Version %d\n", hvi->version); /* Big blocks information */ usedbigblocks = hvi->bigblocks - hvi->freebigblocks; fprintf(stdout, "Big block information\n"); fprintf(stdout, "\tTotal %10jd\n", (intmax_t)hvi->bigblocks); fprintf(stdout, "\tUsed %10jd (%.2lf%%)\n" "\tReserved %10jd (%.2lf%%)\n" "\tFree %10jd (%.2lf%%)\n", (intmax_t)usedbigblocks, percent(usedbigblocks, hvi->bigblocks), (intmax_t)hvi->rsvbigblocks, percent(hvi->rsvbigblocks, hvi->bigblocks), (intmax_t)(hvi->freebigblocks - hvi->rsvbigblocks), percent(hvi->freebigblocks - hvi->rsvbigblocks, hvi->bigblocks)); fprintf(stdout, "Space information\n"); /* Space information */ totalbytes = (hvi->bigblocks << HAMMER_LARGEBLOCK_BITS); usedbytes = (usedbigblocks << HAMMER_LARGEBLOCK_BITS); rsvbytes = (hvi->rsvbigblocks << HAMMER_LARGEBLOCK_BITS); freebytes = ((hvi->freebigblocks - hvi->rsvbigblocks) << HAMMER_LARGEBLOCK_BITS); fprintf(stdout, "\tNo. Inodes %10jd\n", (intmax_t)hvi->inodes); humanize_number(buf, sizeof(buf) - (totalbytes < 0 ? 0 : 1), totalbytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B); fprintf(stdout, "\tTotal size %6s (%jd bytes)\n", buf, (intmax_t)totalbytes); humanize_number(buf, sizeof(buf) - (usedbytes < 0 ? 0 : 1), usedbytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B); fprintf(stdout, "\tUsed %6s (%.2lf%%)\n", buf, percent(usedbytes, totalbytes)); humanize_number(buf, sizeof(buf) - (rsvbytes < 0 ? 0 : 1), rsvbytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B); fprintf(stdout, "\tReserved %6s (%.2lf%%)\n", buf, percent(rsvbytes, totalbytes)); humanize_number(buf, sizeof(buf) - (freebytes < 0 ? 0 : 1), freebytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B); fprintf(stdout, "\tFree %6s (%.2lf%%)\n", buf, percent(freebytes, totalbytes)); /* Pseudo-filesystem information */ fprintf(stdout, "PFS information\n"); fprintf(stdout, "\tPFS ID Mode Snaps Mounted on\n"); /* Iterate all the PFSs found */ pi_first = libhammer_get_first_pfs(hvi); for (pi = pi_first; pi != NULL; pi = libhammer_get_next_pfs(pi)) { fprintf(stdout, "\t%6d %-6s", pi->pfs_id, (pi->ismaster ? "MASTER" : "SLAVE")); snprintf(buf, 6, "%d", pi->snapcount); fprintf(stdout, " %6s ", (pi->head.error && pi->snapcount == 0) ? "-" : buf); if (pi->mountedon) fprintf(stdout, "%s", pi->mountedon); else fprintf(stdout, "not mounted"); fprintf(stdout, "\n"); } free(fsid); libhammer_free_volinfo(hvi); }