From owner-freebsd-emulation@FreeBSD.ORG Sat Jul 30 17:32:48 2011 Return-Path: Delivered-To: freebsd-emulation@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A8D2E1065675; Sat, 30 Jul 2011 17:32:48 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id ED33E8FC08; Sat, 30 Jul 2011 17:32:47 +0000 (UTC) Received: from deviant.kiev.zoral.com.ua (root@deviant.kiev.zoral.com.ua [10.1.1.148]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id p6UHWen2064517 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 30 Jul 2011 20:32:40 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4) with ESMTP id p6UHWewZ028869; Sat, 30 Jul 2011 20:32:40 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4/Submit) id p6UHWdfe028868; Sat, 30 Jul 2011 20:32:39 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Sat, 30 Jul 2011 20:32:39 +0300 From: Kostik Belousov To: Robert Millan Message-ID: <20110730173239.GA17489@deviant.kiev.zoral.com.ua> References: Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="rwb68Uo94/+7gMfP" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean X-Spam-Status: No, score=-3.3 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00, DNS_FROM_OPENWHOIS autolearn=no version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: freebsd-hackers@freebsd.org, freebsd-emulation@freebsd.org Subject: Re: kern/159281: [PATCH] Linux-like /proc/swaps for linprocfs X-BeenThere: freebsd-emulation@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Development of Emulators of other operating systems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 30 Jul 2011 17:32:48 -0000 --rwb68Uo94/+7gMfP Content-Type: text/plain; charset=koi8-r Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Sat, Jul 30, 2011 at 01:06:48AM +0200, Robert Millan wrote: > Hi Kostik, >=20 > 2011/7/29 Kostik Belousov : > > 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(): > > =9A =9A =9A =9A =9A =9A =9A =9Aif (vn_isdisk(sp->sw_vp, NULL)) > > =9A =9A =9A =9A =9A =9A =9A =9A =9A =9A =9A =9Adevname =3D sp->sw_vp->v= _rdev->si_name; > > =9A =9A =9A =9A =9A =9A =9A =9Aelse > > =9A =9A =9A =9A =9A =9A =9A =9A =9A =9A =9A =9Adevname =3D "[file]"; > > This could be another function that returns swap information by index. >=20 > Here's a patch with the changes you requested. >=20 There are several issues in the patch that I see, not counting minor stylistic bugs. First, the sw_dev_mtx should be kept until all the data is read from the xs. The locking there is somewhat vague, the original code was probably correct because sysctl handler is not marked mpsafe, and all functions changing the swtailq hold Giant. Second, my proposal contains a flaw. Namely, if some swap device was removed between calls to swap_info and swap_devname calls, we get mangled list. The third problem, which is not fixed, and which I do not want to handle, is that the swap devices list can be changed between calls to swap_devname(= ), changing device indexes and thus making the output mangled. Should the swap device name be separated from 'unknown' word by space or by tab ? I updated your patch, hopefully fixing the issues. Do you have comments or objections ? diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linpro= cfs.c index 692c5a3..0733913 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -502,6 +502,30 @@ linprocfs_dostat(PFS_FILL_ARGS) return (0); } =20 +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 =3D 0; ; n++) { + if (swap_dev_info(n, &xsw, devname, sizeof(devname)) !=3D 0) + break; + + total =3D (long long)xsw.xsw_nblks * PAGE_SIZE / 1024; + used =3D (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 +1514,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..5929871 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -2365,35 +2365,58 @@ swap_pager_status(int *total, int *used) mtx_unlock(&sw_dev_mtx); } =20 -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 =3D (int *)arg1; - int error, n; - struct xswdev xs; struct swdevt *sp; - - if (arg2 !=3D 1) /* name length */ - return (EINVAL); + char *tmp_devname; + int error, n; =20 n =3D 0; + error =3D ENOENT; mtx_lock(&sw_dev_mtx); TAILQ_FOREACH(sp, &swtailq, sw_list) { - if (n =3D=3D *name) { - mtx_unlock(&sw_dev_mtx); - xs.xsw_version =3D XSWDEV_VERSION; - xs.xsw_dev =3D sp->sw_dev; - xs.xsw_flags =3D sp->sw_flags; - xs.xsw_nblks =3D sp->sw_nblks; - xs.xsw_used =3D sp->sw_used; - - error =3D SYSCTL_OUT(req, &xs, sizeof(xs)); - return (error); + if (n !=3D name) { + n++; + continue; } - n++; + + xs->xsw_version =3D XSWDEV_VERSION; + xs->xsw_dev =3D sp->sw_dev; + xs->xsw_flags =3D sp->sw_flags; + xs->xsw_nblks =3D sp->sw_nblks; + xs->xsw_used =3D sp->sw_used; + if (devname !=3D NULL) { + if (vn_isdisk(sp->sw_vp, NULL)) { + tmp_devname =3D + sp->sw_vp->v_rdev->si_name; + } else + tmp_devname =3D "[file]"; + strncpy(devname, tmp_devname, len); + } + error =3D 0; + break; } mtx_unlock(&sw_dev_mtx); - return (ENOENT); + return (error); +} + +static int +sysctl_vm_swap_info(SYSCTL_HANDLER_ARGS) +{ + int *name =3D (int *)arg1; + int error; + struct xswdev xs; + + if (arg2 !=3D 1) /* name length */ + return (EINVAL); + + error =3D swap_dev_info(*name, &xs, NULL, 0); + if (error !=3D 0) + return (error); + + error =3D SYSCTL_OUT(req, &xs, sizeof(xs)); + return (error); } =20 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..d7b0f5e 100644 --- a/sys/vm/swap_pager.h +++ b/sys/vm/swap_pager.h @@ -76,6 +76,8 @@ extern int swap_pager_full; extern int swap_pager_avail; =20 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); --rwb68Uo94/+7gMfP Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (FreeBSD) iEYEARECAAYFAk40QDcACgkQC3+MBN1Mb4iLaQCfVGDRkZXlUAA4Jq1qbfbpnYtR cmgAoNiAxP0/hLGsVJomShY6io1TEDYS =HiWn -----END PGP SIGNATURE----- --rwb68Uo94/+7gMfP--