diff options
author | kib <kib@FreeBSD.org> | 2011-08-01 19:12:15 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2011-08-01 19:12:15 +0000 |
commit | 96a4fe50dc6672ffdb31086d5b48729efc302158 (patch) | |
tree | a55d3372a1c0309ffec2845bc0c58ca07316fb30 | |
parent | 7db6a1f506944de54734420c7d63567ada0461ab (diff) | |
download | FreeBSD-src-96a4fe50dc6672ffdb31086d5b48729efc302158.zip FreeBSD-src-96a4fe50dc6672ffdb31086d5b48729efc302158.tar.gz |
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
-rw-r--r-- | sys/compat/linprocfs/linprocfs.c | 29 | ||||
-rw-r--r-- | sys/vm/swap_pager.c | 58 | ||||
-rw-r--r-- | sys/vm/swap_pager.h | 3 |
3 files changed, 69 insertions, 21 deletions
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index 692c5a3..8832d3d 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -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, diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index f421e4f..9a818e7 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -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, diff --git a/sys/vm/swap_pager.h b/sys/vm/swap_pager.h index c3366e8..5c716d9 100644 --- a/sys/vm/swap_pager.h +++ b/sys/vm/swap_pager.h @@ -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); |