Date: Sat, 30 Jul 2011 01:06:48 +0200 From: Robert Millan <rmh@debian.org> To: Kostik Belousov <kostikbel@gmail.com> Cc: freebsd-hackers@freebsd.org, freebsd-emulation@freebsd.org Subject: Re: kern/159281: [PATCH] Linux-like /proc/swaps for linprocfs Message-ID: <CAOfDtXOJjOoQA8yNFPVdQRqCqr-Vc5nscMbgOLGLMuvTP9mp1w@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Hi Kostik,
2011/7/29 Kostik Belousov <kostikbel@gmail.com>:
> The patch is too hackish, IMHO.
> I would prefer to have an exported kernel function that fills xswdev
> by index, used both by vm_swap_info and linprocfs.
>
> For the device name, you would use sw_vp->v_rdev->si_name, see, for
> instance, the following fragment in the swapoff_all():
> if (vn_isdisk(sp->sw_vp, NULL))
> devname = sp->sw_vp->v_rdev->si_name;
> else
> devname = "[file]";
> This could be another function that returns swap information by index.
Here's a patch with the changes you requested.
--
Robert Millan
[-- Attachment #2 --]
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -502,6 +502,32 @@
return (0);
}
+static int
+linprocfs_doswaps(PFS_FILL_ARGS)
+{
+ struct xswdev xsw;
+ int n;
+ long long total, used;
+ char devname[SPECNAMELEN + 1];
+
+ sbuf_printf(sb, "Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
+
+ for (n = 0; ; n++) {
+ if (swap_info(n, &xsw) != 0)
+ break;
+
+ if (swap_devname(n, devname, sizeof(devname)) != 0)
+ break;
+
+ total = (long long)xsw.xsw_nblks * PAGE_SIZE / 1024;
+ used = (long long)xsw.xsw_used * PAGE_SIZE / 1024;
+
+ sbuf_printf(sb, "/dev/%-34s unknown\t\t%lld\t%lld\t-1\n", devname, total, used);
+ }
+
+ return (0);
+}
+
/*
* Filler function for proc/uptime
*/
@@ -1490,6 +1516,8 @@
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,
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -2315,6 +2315,31 @@
return (0);
}
+int
+swap_devname(int name, char *devname, size_t len)
+{
+ int n;
+ struct swdevt *sp;
+ char *tmp_devname;
+
+ n = 0;
+ mtx_lock(&sw_dev_mtx);
+ TAILQ_FOREACH(sp, &swtailq, sw_list) {
+ if (n == name) {
+ 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);
+ mtx_unlock(&sw_dev_mtx);
+ return (0);
+ }
+ n++;
+ }
+ mtx_unlock(&sw_dev_mtx);
+ return (ENOENT);
+}
+
void
swapoff_all(void)
{
@@ -2365,30 +2390,24 @@
mtx_unlock(&sw_dev_mtx);
}
-static int
-sysctl_vm_swap_info(SYSCTL_HANDLER_ARGS)
+int
+swap_info(int name, struct xswdev *xs)
{
- int *name = (int *)arg1;
int error, n;
- struct xswdev xs;
struct swdevt *sp;
- if (arg2 != 1) /* name length */
- return (EINVAL);
-
n = 0;
mtx_lock(&sw_dev_mtx);
TAILQ_FOREACH(sp, &swtailq, sw_list) {
- if (n == *name) {
+ 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;
+ 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);
+ return (0);
}
n++;
}
@@ -2396,6 +2415,24 @@
return (ENOENT);
}
+static int
+sysctl_vm_swap_info(SYSCTL_HANDLER_ARGS)
+{
+ int *name = (int *)arg1;
+ int error;
+ struct xswdev xs;
+
+ if (arg2 != 1) /* name length */
+ return (EINVAL);
+
+ error = swap_info(*name, &xs);
+ if (error != 0)
+ return (error);
+
+ error = SYSCTL_OUT(req, &xs, sizeof(xs));
+ return (error);
+}
+
SYSCTL_INT(_vm, OID_AUTO, nswapdev, CTLFLAG_RD, &nswapdev, 0,
"Number of swap devices");
SYSCTL_NODE(_vm, OID_AUTO, swap_info, CTLFLAG_RD, sysctl_vm_swap_info,
--- a/sys/vm/swap_pager.h
+++ b/sys/vm/swap_pager.h
@@ -83,6 +83,8 @@
int swap_pager_reserve(vm_object_t, vm_pindex_t, vm_size_t);
void swap_pager_status(int *total, int *used);
void swapoff_all(void);
+int swap_info(int name, struct xswdev *xs);
+int swap_devname(int name, char *devname, size_t len);
#endif /* _KERNEL */
#endif /* _VM_SWAP_PAGER_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAOfDtXOJjOoQA8yNFPVdQRqCqr-Vc5nscMbgOLGLMuvTP9mp1w>
