summaryrefslogtreecommitdiffstats
path: root/sbin/swapon/swapon.c
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2002-12-28 23:39:47 +0000
committerdillon <dillon@FreeBSD.org>2002-12-28 23:39:47 +0000
commit954749368bc34b7171791be6b1d30aecadb50e11 (patch)
treef87b03e74c9c1e6b9ae164fdbff1e750ba3e8f40 /sbin/swapon/swapon.c
parentf0efa00b3b41ee7113be124c8fcbebe862fb6536 (diff)
downloadFreeBSD-src-954749368bc34b7171791be6b1d30aecadb50e11.zip
FreeBSD-src-954749368bc34b7171791be6b1d30aecadb50e11.tar.gz
Add 'swapctl' - as a hardlink to swapon/swapoff, and augment swapon with
swapctl functionality. The idea is to create a swapctl command that is fairly close to the OpenBSD and NetBSD version. FreeBSD does not implement swap priority (and it would be a mistake if we did) so we didn't bother with that part of it. Submitted by: Eirik Nygaard <eirikn@bluezone.no> Augmented by: dillon (extensively) Reviewed by: David Schultz <dschultz@uclink.Berkeley.EDU>
Diffstat (limited to 'sbin/swapon/swapon.c')
-rw-r--r--sbin/swapon/swapon.c219
1 files changed, 177 insertions, 42 deletions
diff --git a/sbin/swapon/swapon.c b/sbin/swapon/swapon.c
index 51042bc..d908b4a 100644
--- a/sbin/swapon/swapon.c
+++ b/sbin/swapon/swapon.c
@@ -45,6 +45,11 @@ static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
+#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,59 +57,122 @@ static const char rcsid[] =
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
+
+static void usage(void);
+static int swap_on_off(char *name, int ignoreebusy);
+static void swaplist(int, int, int);
-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 } orig_prog, which_prog = SWAPCTL;
int
main(int argc, char **argv)
{
struct fstab *fsp;
+ char *ptr;
int stat;
int ch, doall;
- int do_swapoff;
- char *pname = argv[0];
-
- do_swapoff = is_swapoff(pname);
+ int sflag = 0, lflag = 0, hflag = 0;
+ if ((ptr = strrchr(argv[0], '/')) == NULL)
+ ptr = argv[0];
+ if (strstr(ptr, "swapon"))
+ which_prog = SWAPON;
+ else if (strstr(ptr, "swapoff"))
+ which_prog = SWAPOFF;
+ orig_prog = which_prog;
+
doall = 0;
- while ((ch = getopt(argc, argv, "a")) != -1)
- switch((char)ch) {
+ while ((ch = getopt(argc, argv, "AadlhksU")) != -1) {
+ switch(ch) {
+ case 'A':
+ if (which_prog == SWAPCTL) {
+ doall = 1;
+ which_prog = SWAPON;
+ } else {
+ usage();
+ }
+ break;
case 'a':
- doall = 1;
+ if (which_prog == SWAPON || which_prog == SWAPOFF)
+ doall = 1;
+ else
+ which_prog = SWAPON;
+ break;
+ case 'd':
+ if (which_prog == SWAPCTL)
+ which_prog = SWAPOFF;
+ else
+ usage();
+ break;
+ case 's':
+ sflag = 1;
+ break;
+ case 'l':
+ lflag = 1;
+ break;
+ case 'h':
+ hflag = 'M';
+ break;
+ case 'k':
+ hflag = 'K';
+ break;
+ case 'U':
+ if (which_prog == SWAPCTL) {
+ doall = 1;
+ which_prog = SWAPOFF;
+ } else {
+ usage();
+ }
break;
case '?':
default:
- usage(pname);
+ usage();
}
+ }
argv += optind;
stat = 0;
- if (doall)
- while ((fsp = getfsent()) != 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))
+ if (which_prog == SWAPON || which_prog == SWAPOFF) {
+ if (doall) {
+ while ((fsp = getfsent()) != 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 = 1;
+ } else {
+ printf("%s: %sing %s as swap device\n",
+ getprogname(), which_prog == SWAPOFF ? "remov" : "add",
+ fsp->fs_spec);
+ }
+ }
+ }
+ else if (!*argv)
+ usage();
+ for (; *argv; ++argv) {
+ if (swap_on_off(*argv, 0)) {
stat = 1;
- else
+ } else if (orig_prog == SWAPCTL) {
printf("%s: %sing %s as swap device\n",
- pname, do_swapoff ? "remov" : "add",
- fsp->fs_spec);
+ getprogname(), which_prog == SWAPOFF ? "remov" : "add",
+ *argv);
+ }
}
- else if (!*argv)
- usage(pname);
- for (; *argv; ++argv)
- stat |= swap_on_off(*argv, 0, do_swapoff);
+ } else {
+ if (lflag || sflag)
+ swaplist(lflag, sflag, hflag);
+ else
+ usage();
+ }
exit(stat);
}
-int
-swap_on_off(char *name, int ignoreebusy, int do_swapoff)
+static int
+swap_on_off(char *name, int ignoreebusy)
{
- if ((do_swapoff ? swapoff(name) : swapon(name)) == -1) {
+ if ((which_prog == SWAPOFF ? swapoff(name) : swapon(name)) == -1) {
switch (errno) {
case EBUSY:
if (!ignoreebusy)
@@ -120,23 +188,90 @@ swap_on_off(char *name, int ignoreebusy, int do_swapoff)
}
static void
-usage(const char *pname)
+usage(void)
{
- fprintf(stderr, "usage: %s [-a] [special_file ...]\n", pname);
+ fprintf(stderr, "usage: %s ", getprogname());
+ switch(orig_prog) {
+ case SWAPOFF:
+ fprintf(stderr, "[-a] [special_file ...]\n");
+ break;
+ case SWAPON:
+ fprintf(stderr, "[-a] [special_file ...]\n");
+ break;
+ case SWAPCTL:
+ fprintf(stderr, "[-lshAU] [-a/-d special_file ...]\n");
+ break;
+ }
exit(1);
}
-static int
-is_swapoff(const char *s)
+static void
+swaplist(int lflag, int sflag, int hflag)
{
- const char *u;
-
- if ((u = strrchr(s, '/')) != NULL)
- ++u;
- else
- u = s;
- if (strcmp(u, "swapoff") == 0)
- return 1;
- else
- return 0;
+ size_t mibsize, size;
+ struct xswdev xsw;
+ int mib[16], n, pagesize;
+ size_t hlen;
+ long blocksize;
+ long long total = 0;
+ long long used = 0;
+ long long tmp_total;
+ long long tmp_used;
+
+ pagesize = getpagesize();
+ switch(hflag) {
+ case 'K':
+ blocksize = 1024;
+ hlen = 10;
+ break;
+ case 'M':
+ blocksize = 1024 * 1024;
+ hlen = 10;
+ break;
+ default:
+ getbsize(&hlen, &blocksize);
+ break;
+ }
+
+ mibsize = sizeof mib / sizeof mib[0];
+ if (sysctlnametomib("vm.swap_info", mib, &mibsize) == -1)
+ err(1, "sysctlnametomib()");
+
+ if (lflag) {
+ char buf[32];
+ snprintf(buf, sizeof(buf), "%ld-blocks", blocksize);
+ printf("%-13s %*s %*s\n",
+ "Device:",
+ hlen, buf,
+ hlen, "Used:");
+ }
+
+ for (n = 0; ; ++n) {
+ mib[mibsize] = n;
+ size = sizeof xsw;
+ if (sysctl(mib, mibsize + 1, &xsw, &size, NULL, NULL) == -1)
+ break;
+ if (xsw.xsw_version != XSWDEV_VERSION)
+ errx(1, "xswdev version mismatch");
+
+ tmp_total = (long long)xsw.xsw_nblks * pagesize / blocksize;
+ tmp_used = (long long)xsw.xsw_used * pagesize / blocksize;
+ total += tmp_total;
+ used += tmp_used;
+ if (lflag) {
+ printf("/dev/%-8s %*lld %*lld\n",
+ devname(xsw.xsw_dev, S_IFCHR),
+ hlen, tmp_total,
+ hlen, tmp_used);
+ }
+ }
+ if (errno != ENOENT)
+ err(1, "sysctl()");
+
+ if (sflag) {
+ printf("Total: %*lld %*lld\n",
+ hlen, total,
+ hlen, used);
+ }
}
+
OpenPOWER on IntegriCloud