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);
}
示例#2
0
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);

}