git: 1aa249c93588 - main - swapoff(8): add -f flag

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sat, 04 Dec 2021 22:21:10 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=1aa249c935884d4c0c096c00facbb22f214128cc

commit 1aa249c935884d4c0c096c00facbb22f214128cc
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-11-29 16:30:09 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-12-04 22:20:58 +0000

    swapoff(8): add -f flag
    
    to force swapout by ignoring the heuristic that calculates amount of
    allocated memory against total of RAM plus remaining swap.
    
    Reviewed by:    markj
    Discussed with: alc
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D33165
---
 sbin/swapon/swapon.8 | 16 +++++++++++-----
 sbin/swapon/swapon.c | 23 ++++++++++++++++++-----
 2 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/sbin/swapon/swapon.8 b/sbin/swapon/swapon.8
index 7ae28031dc1e..0146a7750e12 100644
--- a/sbin/swapon/swapon.8
+++ b/sbin/swapon/swapon.8
@@ -28,7 +28,7 @@
 .\"     @(#)swapon.8	8.1 (Berkeley) 6/5/93
 .\" $FreeBSD$
 .\"
-.Dd May 19, 2020
+.Dd November 29, 2021
 .Dt SWAPON 8
 .Os
 .Sh NAME
@@ -42,9 +42,9 @@
 .Nm swapoff
 .Oo Fl F Ar fstab
 .Oc
-.Fl aLq | Ar
+.Fl afLq | Ar
 .Nm swapctl
-.Op Fl AghklmsU
+.Op Fl AfghklmsU
 .Oo
 .Fl a Ar
 |
@@ -125,8 +125,14 @@ informational messages will not be
 written to standard output when a swap device is removed.
 Note that
 .Nm swapoff
-will fail and refuse to remove a swap device if there is insufficient
-VM (memory + remaining swap devices) to run the system.
+will fail and refuse to remove a swap device if a very conservative
+check does not conclude that there is sufficient VM (memory +
+remaining swap devices) to run the system.
+The
+.Fl f
+option turns off this check, which could deadlock the system
+if there is insufficient swap space remaining.
+.Pp
 The
 .Nm swapoff
 utility
diff --git a/sbin/swapon/swapon.c b/sbin/swapon/swapon.c
index 5adc870adf59..d644d99e7913 100644
--- a/sbin/swapon/swapon.c
+++ b/sbin/swapon/swapon.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/sysctl.h>
 #include <sys/wait.h>
 #include <vm/vm_param.h>
+#include <vm/swap_pager.h>
 
 #include <err.h>
 #include <errno.h>
@@ -78,7 +79,7 @@ static int run_cmd(int *, const char *, ...) __printflike(2, 3);
 
 static enum { SWAPON, SWAPOFF, SWAPCTL } orig_prog, which_prog = SWAPCTL;
 
-static int Eflag, qflag;
+static int Eflag, fflag, qflag;
 
 int
 main(int argc, char **argv)
@@ -101,7 +102,7 @@ main(int argc, char **argv)
 	
 	doall = 0;
 	etc_fstab = NULL;
-	while ((ch = getopt(argc, argv, "AadEghklLmqsUF:")) != -1) {
+	while ((ch = getopt(argc, argv, "AadEfghklLmqsUF:")) != -1) {
 		switch(ch) {
 		case 'A':
 			if (which_prog == SWAPCTL) {
@@ -128,6 +129,12 @@ main(int argc, char **argv)
 			else
 				usage();
 			break;
+		case 'f':
+			if (which_prog == SWAPOFF)
+				fflag = 1;
+			else
+				usage();
+			break;
 		case 'g':
 			hflag = 'G';
 			break;
@@ -782,12 +789,18 @@ swapon_trim(const char *name)
 static const char *
 swap_on_off_sfile(const char *name, int doingall)
 {
+	struct swapoff_new_args sa;
 	int error;
 
 	if (which_prog == SWAPON)
 		error = Eflag ? swapon_trim(name) : swapon(name);
-	else /* SWAPOFF */
-		error = swapoff(name);
+	else { /* SWAPOFF */
+		bzero(&sa, sizeof(sa));
+		sa.name = name;
+		if (fflag)
+			sa.flags |= SWAPOFF_FORCE;
+		error = swapoff((const char *)&sa);
+	}
 
 	if (error == -1) {
 		switch (errno) {
@@ -820,7 +833,7 @@ usage(void)
 	    fprintf(stderr, "[-F fstab] -aLq | [-E] file ...\n");
 	    break;
 	case SWAPOFF:
-	    fprintf(stderr, "[-F fstab] -aLq | file ...\n");
+	    fprintf(stderr, "[-F fstab] -afLq | file ...\n");
 	    break;
 	case SWAPCTL:
 	    fprintf(stderr, "[-AghklmsU] [-a file ... | -d file ...]\n");