Date: Wed, 18 Dec 2002 21:38:54 +0100 From: Eirik Nygaard <eirikn@bluezone.no> To: current@FreeBSD.ORG Subject: Re: swapoff code comitted. Message-ID: <20021218203854.GC853@eirikn.net> In-Reply-To: <200212181918.gBIJIOIV093115@apollo.backplane.com> References: <200212151946.gBFJktmo090730@apollo.backplane.com> <20021215223540.GA601@unixpages.org> <200212152247.gBFMlp4d098705@apollo.backplane.com> <20021218182724.GB853@eirikn.net> <200212181918.gBIJIOIV093115@apollo.backplane.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--jKBxcB1XkHIR0Eqt
Content-Type: multipart/mixed; boundary="UfEAyuTBtIjiZzX6"
Content-Disposition: inline
--UfEAyuTBtIjiZzX6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
On Wed, Dec 18, 2002 at 11:18:24AM -0800, Matthew Dillon wrote:
>=20
> :I have made a small patch, added l, s and h switches to show
> :information about the swap devices. And the U switch to swapctl only
> :to remove all activated swap devices.
> :If anything else is needed let me know and I will add it.
> :
> :--=3D20
> :
> :Eirik Nygaard <eirikn@bluezone.no>
> :PGP Key: 83C55EDE
>=20
> That is a pretty good first attempt. I have a few suggests and found=
=20
> one bug. First the bug:
>=20
> :+ is_swapctl ? "lsU" : "");
>=20
> I think that was supposed to be a call to is_swapctl, not a pointer
> to the function.
>=20
> Suggestions: Get rid of the is_swap*() functions and instead use
> av[0] at the top of main() and use strstr() to determine if the
> program is swapon, swapoff, or swapctl. Check against "swapon" and
> "swapoff" and if it is neither then default to swapctl (don't test
> against "swapctl"). Store which program it is in a global variable,
> e.g. an enum like this:
>=20
> enum { SWAPON, SWAPOFF, SWAPCTL } which_prog =3D SWAPCTL;
>=20
> In regards to retrieving swap information, in -current there is a
> sysctl() to do it. Take a look at /usr/src/usr.sbin/pstat/pstat.c
> (in the current source tree), at the swapmode_kvm() and swapmode_sysc=
tl()
> functions. The sysctl is much, much faster then the kvm call because
> the kvm call has to run through the swap radix tree to collect the us=
eage
> information.
>=20
Added the enum instead of is_swap* commands and changed from kvm to
sysctl to get the swap information.
--=20
Eirik Nygaard <eirikn@bluezone.no>
PGP Key: 83C55EDE
--UfEAyuTBtIjiZzX6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="swapctl.diff"
Content-Transfer-Encoding: quoted-printable
? sbin/swapon/.swapon.c.swp
Index: sbin/swapon/Makefile
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sbin/swapon/Makefile,v
retrieving revision 1.7
diff -u -r1.7 Makefile
--- sbin/swapon/Makefile 15 Dec 2002 19:17:56 -0000 1.7
+++ sbin/swapon/Makefile 18 Dec 2002 20:35:53 -0000
@@ -3,7 +3,9 @@
=20
PROG=3D swapon
MAN=3D swapon.8
-LINKS=3D ${BINDIR}/swapon ${BINDIR}/swapoff
-MLINKS=3D swapon.8 swapoff.8
+LINKS=3D ${BINDIR}/swapoff ${BINDIR}/swapon
+LINKS+=3D ${BINDIR}/swapctl ${BINDIR}/swapon
+MLINKS=3D swapoff.8 swapon.8
+MLINKS=3D swapctl.8 swapon.8
=20
.include <bsd.prog.mk>
Index: sbin/swapon/swapon.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sbin/swapon/swapon.c,v
retrieving revision 1.13
diff -u -r1.13 swapon.c
--- sbin/swapon/swapon.c 15 Dec 2002 19:17:56 -0000 1.13
+++ sbin/swapon/swapon.c 18 Dec 2002 20:35:53 -0000
@@ -45,6 +45,11 @@
"$FreeBSD: src/sbin/swapon/swapon.c,v 1.13 2002/12/15 19:17:56 dillon Ex=
p $";
#endif /* not lint */
=20
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/sysctl.h>
+
#include <err.h>
#include <errno.h>
#include <fstab.h>
@@ -52,10 +57,13 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
+
+static void usage(void);
+int swap_on_off(char *name, int ignoreebusy);
+void swaplist(int, int, int);
=20
-static void usage(const char *);
-static int is_swapoff(const char *);
-int swap_on_off(char *name, int ignoreebusy, int do_swapoff);
+enum { SWAPON, SWAPOFF, SWAPCTL } which_prog =3D SWAPCTL;
=20
int
main(int argc, char **argv)
@@ -63,47 +71,80 @@
struct fstab *fsp;
int stat;
int ch, doall;
- int do_swapoff;
- char *pname =3D argv[0];
-
- do_swapoff =3D is_swapoff(pname);
-
+ int sflag =3D 0, lflag =3D 0, hflag =3D 0;
+=09
+ if (strstr(argv[0], "swapon"))
+ which_prog =3D SWAPON;
+ else if (strstr(argv[0], "swapoff"))
+ which_prog =3D SWAPOFF;
+=09
doall =3D 0;
- while ((ch =3D getopt(argc, argv, "a")) !=3D -1)
- switch((char)ch) {
+ while ((ch =3D getopt(argc, argv, "alhsU")) !=3D -1)
+ switch(ch) {
case 'a':
doall =3D 1;
break;
+ case 's':
+ sflag =3D 1;
+ break;
+ case 'l':
+ lflag =3D 1;
+ break;
+ case 'h':
+ hflag =3D 1;
+ break;
+ case 'U':
+ if (which_prog !=3D SWAPON) {
+ doall =3D 1;
+ which_prog =3D SWAPOFF;
+ break;
+ } /* Remove the if if you want the U switch to work with swapon also, d=
on't know if that is wanted */
case '?':
default:
- usage(pname);
+ usage();
}
argv +=3D optind;
-
+=09
stat =3D 0;
- if (doall)
- while ((fsp =3D getfsent()) !=3D NULL) {
- if (strcmp(fsp->fs_type, FSTAB_SW))
- continue;
- if (strstr(fsp->fs_mntops, "noauto"))
- continue;
- if (swap_on_off(fsp->fs_spec, 1, do_swapoff))
- stat =3D 1;
- else
- printf("%s: %sing %s as swap device\n",
- pname, do_swapoff ? "remov" : "add",
- fsp->fs_spec);
+ if (which_prog =3D=3D SWAPON || which_prog =3D=3D SWAPOFF) {
+ if (doall) {
+ while ((fsp =3D getfsent()) !=3D NULL) {
+ if (strcmp(fsp->fs_type, FSTAB_SW))
+ continue;
+ if (strstr(fsp->fs_mntops, "noauto"))
+ continue;
+ if (swap_on_off(fsp->fs_spec, 0))
+ stat =3D 1;
+ else
+ printf("%s: %sing %s as swap device\n",
+ getprogname(), which_prog =3D=3D SWAPOFF ? "remov" : "add",
+ fsp->fs_spec);
+ }
}
- else if (!*argv)
- usage(pname);
- for (; *argv; ++argv)
- stat |=3D swap_on_off(*argv, 0, do_swapoff);
+ else if (!*argv)
+ usage();
+ for (; *argv; ++argv)
+ stat |=3D swap_on_off(*argv, 0);
+ }
+ else {
+ if (lflag =3D=3D 1 || sflag =3D=3D 1)
+ swaplist(lflag, sflag, hflag);
+
+ else=20
+ usage();
+ }
+=09
exit(stat);
}
=20
int
-swap_on_off(char *name, int ignoreebusy, int do_swapoff)
+swap_on_off(char *name, int ignoreebusy)
{
+ int do_swapoff;=20
+=09
+ if (which_prog =3D=3D SWAPOFF)
+ do_swapoff =3D 1;
+=09
if ((do_swapoff ? swapoff(name) : swapon(name)) =3D=3D -1) {
switch (errno) {
case EBUSY:
@@ -120,23 +161,73 @@
}
=20
static void
-usage(const char *pname)
+usage(void)
{
- fprintf(stderr, "usage: %s [-a] [special_file ...]\n", pname);
+ fprintf(stderr, "usage: %s [-a%s] [special_file ...]\n", getprogname(),
+ which_prog =3D=3D SWAPCTL ? "lsU" : "");
exit(1);
}
=20
-static int
-is_swapoff(const char *s)
+/* Some code is based on the code in the swapmode_sysctl command in pstat =
*/
+void
+swaplist(int lflag, int sflag, int hflag)
{
- const char *u;
-
- if ((u =3D strrchr(s, '/')) !=3D NULL)
- ++u;
- else
- u =3D s;
- if (strcmp(u, "swapoff") =3D=3D 0)
- return 1;
- else
- return 0;
+ size_t mibsize, size;
+ struct xswdev xsw;
+ int mib[16], n, pagesize, used, total, i =3D 0;
+=09
+ pagesize =3D getpagesize();
+=09
+ mibsize =3D sizeof mib / sizeof mib[0];
+ if (sysctlnametomib("vm.swap_info", mib, &mibsize) =3D=3D -1)
+ err(1, "sysctlnametomib()");
+=09
+ if (lflag)
+ printf("%-*s %s%10s %s%10s\n",
+ 13, "Device:",=20
+ hflag ? " " : "", "Total:",
+ hflag ? " " : "", "Used:");
+=09
+ used =3D total =3D 0;
+ for (n =3D 0; ; ++n) {
+ mib[mibsize] =3D n;
+ size =3D sizeof xsw;
+ if (sysctl(mib, mibsize + 1, &xsw, &size, NULL, NULL) =3D=3D -1)
+ break;
+ if (xsw.xsw_version !=3D XSWDEV_VERSION)
+ errx(1, "xswdev version mismatch");
+ =09
+ if (lflag) {
+ total =3D xsw.xsw_nblks * pagesize / 1024;
+ used =3D xsw.xsw_used * pagesize / 1024;
+ =09
+ if (hflag) {
+ total =3D total / 1000;
+ used =3D used / 1000;
+ }
+ =09
+ printf("/dev/%-*s %10d%s %10d%s\n",=20
+ 8, devname(xsw.xsw_dev, S_IFCHR),
+ total, hflag ? "M" : "",
+ used, hflag ? "M" : "");
+ }
+ if (sflag) {
+ total +=3D xsw.xsw_nblks * pagesize / 1024;
+ used +=3D xsw.xsw_used * pagesize / 1024;
+ }
+ i++;
+ }
+ if (errno !=3D ENOENT)
+ err(1, "sysctl()");
+=09
+ if (hflag) {
+ total =3D total / 1000;
+ used =3D used / 1000;
+ }
+ if (sflag)
+ printf("Swap: Total: %8d%s Used: %8d%s\n",
+ total, hflag ? "M" : "",
+ used, hflag ? "M" : "");
+=09
}
+
--UfEAyuTBtIjiZzX6--
--jKBxcB1XkHIR0Eqt
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (FreeBSD)
iD8DBQE+ANze1JB0Z4PFXt4RAtKLAJ0a6H4lLvsbdwrebxb8D7+HXrqmHgCfWsZL
c9SG8xvb40X/7PkRLlhXOvE=
=mZ2I
-----END PGP SIGNATURE-----
--jKBxcB1XkHIR0Eqt--
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021218203854.GC853>
