Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Aug 2011 19:12:15 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r224582 - in head/sys: compat/linprocfs vm
Message-ID:  <201108011912.p71JCFd6009311@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Mon Aug  1 19:12:15 2011
New Revision: 224582
URL: http://svn.freebsd.org/changeset/base/224582

Log:
  Implement the linprocfs swaps file, providing information about the
  configured swap devices in the Linux-compatible format.
  
  Based on the submission by:	Robert Millan <rmh debian org>
  PR:	kern/159281
  Reviewed by:	bde
  Approved by:	re (kensmith)
  MFC after:	2 weeks

Modified:
  head/sys/compat/linprocfs/linprocfs.c
  head/sys/vm/swap_pager.c
  head/sys/vm/swap_pager.h

Modified: head/sys/compat/linprocfs/linprocfs.c
==============================================================================
--- head/sys/compat/linprocfs/linprocfs.c	Mon Aug  1 19:07:03 2011	(r224581)
+++ head/sys/compat/linprocfs/linprocfs.c	Mon Aug  1 19:12:15 2011	(r224582)
@@ -502,6 +502,33 @@ linprocfs_dostat(PFS_FILL_ARGS)
 	return (0);
 }
 
+static int
+linprocfs_doswaps(PFS_FILL_ARGS)
+{
+	struct xswdev xsw;
+	uintmax_t total, used;
+	int n;
+	char devname[SPECNAMELEN + 1];
+
+	sbuf_printf(sb, "Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
+	mtx_lock(&Giant);
+	for (n = 0; ; n++) {
+		if (swap_dev_info(n, &xsw, devname, sizeof(devname)) != 0)
+			break;
+		total = (uintmax_t)xsw.xsw_nblks * PAGE_SIZE / 1024;
+		used  = (uintmax_t)xsw.xsw_used * PAGE_SIZE / 1024;
+
+		/*
+		 * The space and not tab after the device name is on
+		 * purpose.  Linux does so.
+		 */
+		sbuf_printf(sb, "/dev/%-34s unknown\t\t%jd\t%jd\t-1\n",
+		    devname, total, used);
+	}
+	mtx_unlock(&Giant);
+	return (0);
+}
+
 /*
  * Filler function for proc/uptime
  */
@@ -1490,6 +1517,8 @@ linprocfs_init(PFS_INIT_ARGS)
 	    NULL, NULL, NULL, 0);
 	pfs_create_file(root, "stat", &linprocfs_dostat,
 	    NULL, NULL, NULL, PFS_RD);
+	pfs_create_file(root, "swaps", &linprocfs_doswaps,
+	    NULL, NULL, NULL, PFS_RD);
 	pfs_create_file(root, "uptime", &linprocfs_douptime,
 	    NULL, NULL, NULL, PFS_RD);
 	pfs_create_file(root, "version", &linprocfs_doversion,

Modified: head/sys/vm/swap_pager.c
==============================================================================
--- head/sys/vm/swap_pager.c	Mon Aug  1 19:07:03 2011	(r224581)
+++ head/sys/vm/swap_pager.c	Mon Aug  1 19:12:15 2011	(r224582)
@@ -2365,35 +2365,53 @@ swap_pager_status(int *total, int *used)
 	mtx_unlock(&sw_dev_mtx);
 }
 
-static int
-sysctl_vm_swap_info(SYSCTL_HANDLER_ARGS)
+int
+swap_dev_info(int name, struct xswdev *xs, char *devname, size_t len)
 {
-	int	*name = (int *)arg1;
-	int	error, n;
-	struct xswdev xs;
 	struct swdevt *sp;
-
-	if (arg2 != 1) /* name length */
-		return (EINVAL);
+	char *tmp_devname;
+	int error, n;
 
 	n = 0;
+	error = ENOENT;
 	mtx_lock(&sw_dev_mtx);
 	TAILQ_FOREACH(sp, &swtailq, sw_list) {
-		if (n == *name) {
-			mtx_unlock(&sw_dev_mtx);
-			xs.xsw_version = XSWDEV_VERSION;
-			xs.xsw_dev = sp->sw_dev;
-			xs.xsw_flags = sp->sw_flags;
-			xs.xsw_nblks = sp->sw_nblks;
-			xs.xsw_used = sp->sw_used;
-
-			error = SYSCTL_OUT(req, &xs, sizeof(xs));
-			return (error);
+		if (n != name) {
+			n++;
+			continue;
+		}
+		xs->xsw_version = XSWDEV_VERSION;
+		xs->xsw_dev = sp->sw_dev;
+		xs->xsw_flags = sp->sw_flags;
+		xs->xsw_nblks = sp->sw_nblks;
+		xs->xsw_used = sp->sw_used;
+		if (devname != NULL) {
+			if (vn_isdisk(sp->sw_vp, NULL))
+				tmp_devname = sp->sw_vp->v_rdev->si_name;
+			else
+				tmp_devname = "[file]";
+			strncpy(devname, tmp_devname, len);
 		}
-		n++;
+		error = 0;
+		break;
 	}
 	mtx_unlock(&sw_dev_mtx);
-	return (ENOENT);
+	return (error);
+}
+
+static int
+sysctl_vm_swap_info(SYSCTL_HANDLER_ARGS)
+{
+	struct xswdev xs;
+	int error;
+
+	if (arg2 != 1)			/* name length */
+		return (EINVAL);
+	error = swap_dev_info(*(int *)arg1, &xs, NULL, 0);
+	if (error != 0)
+		return (error);
+	error = SYSCTL_OUT(req, &xs, sizeof(xs));
+	return (error);
 }
 
 SYSCTL_INT(_vm, OID_AUTO, nswapdev, CTLFLAG_RD, &nswapdev, 0,

Modified: head/sys/vm/swap_pager.h
==============================================================================
--- head/sys/vm/swap_pager.h	Mon Aug  1 19:07:03 2011	(r224581)
+++ head/sys/vm/swap_pager.h	Mon Aug  1 19:12:15 2011	(r224582)
@@ -75,7 +75,8 @@ struct swdevt {
 extern int swap_pager_full;
 extern int swap_pager_avail;
 
-struct swdevt;
+struct xswdev;
+int swap_dev_info(int name, struct xswdev *xs, char *devname, size_t len);
 void swap_pager_copy(vm_object_t, vm_object_t, vm_pindex_t, int);
 void swap_pager_freespace(vm_object_t, vm_pindex_t, vm_size_t);
 void swap_pager_swap_init(void);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201108011912.p71JCFd6009311>