commit bcb85a04ccf31b4f3f93b04914759d3d58eb71de
Author: Antonio Huete <tuxillo@quantumachine.net>
Date:   Wed Nov 4 04:57:23 2009 +0100

    hammer - Add PFS details to the 'info' directive.

diff --git a/sbin/hammer/cmd_info.c b/sbin/hammer/cmd_info.c
index 23230ef..5b97ac3 100644
--- a/sbin/hammer/cmd_info.c
+++ b/sbin/hammer/cmd_info.c
@@ -36,6 +36,7 @@
 #include <libutil.h>
 
 void	show_info(char *path);
+char	*find_pfs_mount(int pfsid, uuid_t parentuuid, int ismaster);
 double	percent(int64_t value, int64_t total);
 
 void
@@ -54,25 +55,33 @@ hammer_cmd_info(void)
 			if ((strcmp(fstype, "hammer")) == 0)
 				show_info(path);
 		}
-	}
-	else
+	} else {
 		fprintf(stdout, "No mounted filesystems found\n");
+	}
 
 }
 
 void show_info(char *path) {
 
-	int64_t	usedbigblocks, bytes;
-	struct	hammer_ioc_info info;
-	char	buf[6];
-	int 	fd;
-	char 	*fsid, *fstype;
-
-	fsid = fstype = NULL;
+	struct	    hammer_ioc_snapshot snapinfo;
+    struct	    hammer_pseudofs_data pfs_od;
+    struct	    hammer_ioc_pseudofs_rw pfs;
+	int64_t	    usedbigblocks, bytes;
+	struct	    hammer_ioc_info info;
+    int         fd, pfs_id, ismaster;
+    char	    *fsid, *fstype;
+	char	    *mountedon;
+	char	    buf[6];
+	u_int32_t   sc;
+
+	fsid = fstype = mountedon = NULL;
 	usedbigblocks = 0;
+	pfs_id = 1;	      /* Do not include PFS#0 */
 	bytes = 0;
+	sc = 0;
 
 	bzero(&info, sizeof(struct hammer_ioc_info));
+	bzero(&snapinfo, sizeof(struct hammer_ioc_snapshot));
 
 	/* Try to get a file descriptor based on the path given */
 	fd = open(path, O_RDONLY);
@@ -129,6 +138,110 @@ void show_info(char *path) {
 	bytes = ((info.freebigblocks - info.rsvbigblocks) << HAMMER_LARGEBLOCK_BITS);
 	humanize_number(buf, sizeof(buf)  - (bytes < 0 ? 0 : 1), bytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B);
 	fprintf(stdout, "\tFree space     %6s\n\n", buf);
+
+	/* Pseudo-filesystem information */
+	fprintf(stdout, "PFS information\n");
+	fprintf(stdout, "\tPFS-Id\tMode\tSnaps\tMounted-on\n");
+
+	while(pfs_id < HAMMER_MAX_PFS) {
+                bzero(&pfs, sizeof(pfs));
+                bzero(&pfs_od, sizeof(pfs_od));
+                pfs.pfs_id = pfs_id;
+                pfs.ondisk = &pfs_od;
+                pfs.bytes = sizeof(pfs_od);
+                pfs.version = HAMMER_IOC_PSEUDOFS_VERSION;
+                if (ioctl(fd, HAMMERIOC_GET_PSEUDOFS, &pfs) >= 0) {
+
+		     if (ioctl(fd, HAMMERIOC_GET_SNAPSHOT, &snapinfo) >= 0)
+			  sc = snapinfo.count;
+
+		     ismaster = (pfs_od.mirror_flags & HAMMER_PFSD_SLAVE) ? 0 : 1;
+		     mountedon = find_pfs_mount(pfs_id, info.vol_fsid, ismaster);
+
+		     fprintf(stdout, "\t%05d\t%6s\t%5u\t", pfs_id, (ismaster ? "MASTER" : "SLAVE"), sc);
+		     if (mountedon)
+			  fprintf(stdout, "%s", mountedon);
+		     else
+			  fprintf(stdout, "not-mounted");
+
+		fprintf(stdout, "\n");
+		}
+		pfs_id++;
+        }
+
+	fprintf(stdout, "\n\n");	/* In the case multiple volumes, two new-line separation */
+
+	free(fsid);
+	free(mountedon);
+}
+
+char *find_pfs_mount(int pfsid, uuid_t parentuuid, int ismaster) {
+
+     struct    hammer_ioc_info hi;
+     struct    statfs *mntbuf;
+     int       mntsize, curmount, fd;
+     size_t    mntbufsize;
+     char      *retval, *trailstr;
+
+     retval = NULL;
+
+     /* Do not continue if there are no mounted filesystems */
+     mntsize = getfsstat(NULL, 0, MNT_NOWAIT);
+     if (mntsize <= 0)
+	  return retval;
+
+     mntbufsize = (mntsize) * sizeof(struct statfs);
+     mntbuf = malloc(mntbufsize);
+     if (mntbuf == NULL) {
+	  perror("show_info");
+	  exit(EXIT_FAILURE);
+     }
+
+     mntsize = getfsstat(mntbuf, (long)mntbufsize, MNT_NOWAIT);
+     curmount = mntsize - 1;
+
+     asprintf(&trailstr, ":%05d", pfsid);
+
+     /*
+      * Iterate all the mounted points looking for the PFS passed to
+      * this function.
+      */
+     while(curmount >= 0) {
+         /*
+          * We need to avoid that PFS belonging to other HAMMER
+          * filesystems are showed as mounted, so we compare
+          * against the FSID, which is presumable to be unique.
+          */
+         bzero(&hi, sizeof(hi));
+         if ((fd = open(mntbuf[curmount].f_mntfromname, O_RDONLY)) < 0) {
+             curmount--;
+             continue;
+         }
+
+         if ((ioctl(fd, HAMMERIOC_GET_INFO, &hi)) < 0) {
+             curmount--;
+             continue;
+         }
+
+         if (strstr(mntbuf[curmount].f_mntfromname, trailstr) != NULL &&
+             (uuid_compare(&hi.vol_fsid, &parentuuid, NULL)) == 0) {
+             if (ismaster) {
+                 if (strstr(mntbuf[curmount].f_mntfromname, "@@-1") != NULL) {
+                     retval = strdup(mntbuf[curmount].f_mntonname);
+                     break;
+                 }
+             } else {
+                 if (strstr(mntbuf[curmount].f_mntfromname, "@@0x") != NULL ) {
+                     retval = strdup(mntbuf[curmount].f_mntonname);
+                     break;
+                 }
+             }
+         }
+         curmount--;
+     }
+
+     free(trailstr);
+     return retval;
 }
 
 double percent(int64_t value, int64_t total) {
diff --git a/sbin/hammer/hammer.8 b/sbin/hammer/hammer.8
index ba63643..e7d4d2e 100644
--- a/sbin/hammer/hammer.8
+++ b/sbin/hammer/hammer.8
@@ -1,12 +1,12 @@
 .\" Copyright (c) 2007 The DragonFly Project.  All rights reserved.
-.\" 
+.\"
 .\" This code is derived from software contributed to The DragonFly Project
 .\" by Matthew Dillon <dillon@backplane.com>
-.\" 
+.\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
 .\" are met:
-.\" 
+.\"
 .\" 1. Redistributions of source code must retain the above copyright
 .\"    notice, this list of conditions and the following disclaimer.
 .\" 2. Redistributions in binary form must reproduce the above copyright
@@ -16,7 +16,7 @@
 .\" 3. Neither the name of The DragonFly Project nor the names of its
 .\"    contributors may be used to endorse or promote products derived
 .\"    from this software without specific, prior written permission.
-.\" 
+.\"
 .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@@ -29,10 +29,10 @@
 .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
-.\" 
+.\"
 .\" $DragonFly: src/sbin/hammer/hammer.8,v 1.58 2008/11/13 02:04:27 dillon Exp $
 .\"
-.Dd September 28, 2009
+.Dd November 2, 2009
 .Dt HAMMER 8
 .Os
 .Sh NAME
@@ -298,8 +298,8 @@ Generate the top 32 bits of a
 Shows extended information about all the mounted
 .Nm HAMMER
 file systems.
-At the moment volume identification, big-blocks information and space details
-are shown.
+At the moment volume identification, big-blocks information, space and
+and pseudo-filesystem (PFS) details are shown.
 .\" ==== cleanup ====
 .It Cm cleanup Op Ar filesystem ...
 This is a meta-command which executes snapshot, prune, rebalance and reblock
commit b6929a2ef113ad08de460c9cc7749171a4171d32
Author: Antonio Huete <tuxillo@quantumachine.net>
Date:   Wed Nov 4 05:17:45 2009 +0100

    hammer - Add PFS details to the 'info' directive.

diff --git a/sbin/hammer/cmd_info.c b/sbin/hammer/cmd_info.c
index 23230ef..e1bc44e 100644
--- a/sbin/hammer/cmd_info.c
+++ b/sbin/hammer/cmd_info.c
@@ -36,6 +36,7 @@
 #include <libutil.h>
 
 void	show_info(char *path);
+char	*find_pfs_mount(int pfsid, uuid_t parentuuid, int ismaster);
 double	percent(int64_t value, int64_t total);
 
 void
@@ -54,25 +55,33 @@ hammer_cmd_info(void)
 			if ((strcmp(fstype, "hammer")) == 0)
 				show_info(path);
 		}
-	}
-	else
+	} else {
 		fprintf(stdout, "No mounted filesystems found\n");
+	}
 
 }
 
 void show_info(char *path) {
 
-	int64_t	usedbigblocks, bytes;
-	struct	hammer_ioc_info info;
-	char	buf[6];
-	int 	fd;
-	char 	*fsid, *fstype;
-
-	fsid = fstype = NULL;
+    struct	    hammer_ioc_snapshot snapinfo;
+    struct	    hammer_pseudofs_data pfs_od;
+    struct	    hammer_ioc_pseudofs_rw pfs;
+    int64_t	    usedbigblocks, bytes;
+    struct	    hammer_ioc_info info;
+    int         fd, pfs_id, ismaster;
+    char	    *fsid, *fstype;
+    char	    *mountedon;
+    char	    buf[6];
+    u_int32_t   sc;
+
+	fsid = fstype = mountedon = NULL;
 	usedbigblocks = 0;
+	pfs_id = 1;	      /* Do not include PFS#0 */
 	bytes = 0;
+	sc = 0;
 
 	bzero(&info, sizeof(struct hammer_ioc_info));
+	bzero(&snapinfo, sizeof(struct hammer_ioc_snapshot));
 
 	/* Try to get a file descriptor based on the path given */
 	fd = open(path, O_RDONLY);
@@ -128,7 +137,111 @@ void show_info(char *path) {
 
 	bytes = ((info.freebigblocks - info.rsvbigblocks) << HAMMER_LARGEBLOCK_BITS);
 	humanize_number(buf, sizeof(buf)  - (bytes < 0 ? 0 : 1), bytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B);
-	fprintf(stdout, "\tFree space     %6s\n\n", buf);
+	fprintf(stdout, "\tFree space     %6s\n", buf);
+
+	/* Pseudo-filesystem information */
+	fprintf(stdout, "PFS information\n");
+	fprintf(stdout, "\tPFS-Id\tMode\tSnaps\tMounted-on\n");
+
+	while(pfs_id < HAMMER_MAX_PFS) {
+                bzero(&pfs, sizeof(pfs));
+                bzero(&pfs_od, sizeof(pfs_od));
+                pfs.pfs_id = pfs_id;
+                pfs.ondisk = &pfs_od;
+                pfs.bytes = sizeof(pfs_od);
+                pfs.version = HAMMER_IOC_PSEUDOFS_VERSION;
+                if (ioctl(fd, HAMMERIOC_GET_PSEUDOFS, &pfs) >= 0) {
+
+		     if (ioctl(fd, HAMMERIOC_GET_SNAPSHOT, &snapinfo) >= 0)
+			  sc = snapinfo.count;
+
+		     ismaster = (pfs_od.mirror_flags & HAMMER_PFSD_SLAVE) ? 0 : 1;
+		     mountedon = find_pfs_mount(pfs_id, info.vol_fsid, ismaster);
+
+		     fprintf(stdout, "\t%05d\t%6s\t%5u\t", pfs_id, (ismaster ? "MASTER" : "SLAVE"), sc);
+		     if (mountedon)
+			  fprintf(stdout, "%s", mountedon);
+		     else
+			  fprintf(stdout, "not-mounted");
+
+		fprintf(stdout, "\n");
+		}
+		pfs_id++;
+        }
+
+	fprintf(stdout, "\n\n");	/* In the case multiple volumes, two new-line separation */
+
+	free(fsid);
+	free(mountedon);
+}
+
+char *find_pfs_mount(int pfsid, uuid_t parentuuid, int ismaster) {
+
+     struct    hammer_ioc_info hi;
+     struct    statfs *mntbuf;
+     int       mntsize, curmount, fd;
+     size_t    mntbufsize;
+     char      *retval, *trailstr;
+
+     retval = NULL;
+
+     /* Do not continue if there are no mounted filesystems */
+     mntsize = getfsstat(NULL, 0, MNT_NOWAIT);
+     if (mntsize <= 0)
+	  return retval;
+
+     mntbufsize = (mntsize) * sizeof(struct statfs);
+     mntbuf = malloc(mntbufsize);
+     if (mntbuf == NULL) {
+	  perror("show_info");
+	  exit(EXIT_FAILURE);
+     }
+
+     mntsize = getfsstat(mntbuf, (long)mntbufsize, MNT_NOWAIT);
+     curmount = mntsize - 1;
+
+     asprintf(&trailstr, ":%05d", pfsid);
+
+     /*
+      * Iterate all the mounted points looking for the PFS passed to
+      * this function.
+      */
+     while(curmount >= 0) {
+         /*
+          * We need to avoid that PFS belonging to other HAMMER
+          * filesystems are showed as mounted, so we compare
+          * against the FSID, which is presumable to be unique.
+          */
+         bzero(&hi, sizeof(hi));
+         if ((fd = open(mntbuf[curmount].f_mntfromname, O_RDONLY)) < 0) {
+             curmount--;
+             continue;
+         }
+
+         if ((ioctl(fd, HAMMERIOC_GET_INFO, &hi)) < 0) {
+             curmount--;
+             continue;
+         }
+
+         if (strstr(mntbuf[curmount].f_mntfromname, trailstr) != NULL &&
+             (uuid_compare(&hi.vol_fsid, &parentuuid, NULL)) == 0) {
+             if (ismaster) {
+                 if (strstr(mntbuf[curmount].f_mntfromname, "@@-1") != NULL) {
+                     retval = strdup(mntbuf[curmount].f_mntonname);
+                     break;
+                 }
+             } else {
+                 if (strstr(mntbuf[curmount].f_mntfromname, "@@0x") != NULL ) {
+                     retval = strdup(mntbuf[curmount].f_mntonname);
+                     break;
+                 }
+             }
+         }
+         curmount--;
+     }
+
+     free(trailstr);
+     return retval;
 }
 
 double percent(int64_t value, int64_t total) {
diff --git a/sbin/hammer/hammer.8 b/sbin/hammer/hammer.8
index ba63643..e7d4d2e 100644
--- a/sbin/hammer/hammer.8
+++ b/sbin/hammer/hammer.8
@@ -1,12 +1,12 @@
 .\" Copyright (c) 2007 The DragonFly Project.  All rights reserved.
-.\" 
+.\"
 .\" This code is derived from software contributed to The DragonFly Project
 .\" by Matthew Dillon <dillon@backplane.com>
-.\" 
+.\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
 .\" are met:
-.\" 
+.\"
 .\" 1. Redistributions of source code must retain the above copyright
 .\"    notice, this list of conditions and the following disclaimer.
 .\" 2. Redistributions in binary form must reproduce the above copyright
@@ -16,7 +16,7 @@
 .\" 3. Neither the name of The DragonFly Project nor the names of its
 .\"    contributors may be used to endorse or promote products derived
 .\"    from this software without specific, prior written permission.
-.\" 
+.\"
 .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@@ -29,10 +29,10 @@
 .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
-.\" 
+.\"
 .\" $DragonFly: src/sbin/hammer/hammer.8,v 1.58 2008/11/13 02:04:27 dillon Exp $
 .\"
-.Dd September 28, 2009
+.Dd November 2, 2009
 .Dt HAMMER 8
 .Os
 .Sh NAME
@@ -298,8 +298,8 @@ Generate the top 32 bits of a
 Shows extended information about all the mounted
 .Nm HAMMER
 file systems.
-At the moment volume identification, big-blocks information and space details
-are shown.
+At the moment volume identification, big-blocks information, space and
+and pseudo-filesystem (PFS) details are shown.
 .\" ==== cleanup ====
 .It Cm cleanup Op Ar filesystem ...
 This is a meta-command which executes snapshot, prune, rebalance and reblock
