Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 20 Sep 2015 01:16:43 +1000 (EST)
From:      Ian Smith <smithi@nimnet.asn.au>
To:        Jung-uk Kim <jkim@freebsd.org>
Cc:        Colin Percival <cperciva@freebsd.org>, "freebsd-acpi@freebsd.org" <freebsd-acpi@freebsd.org>
Subject:   Re: disabling sleep when shutting down
Message-ID:  <20150920004041.J29510@sola.nimnet.asn.au>
In-Reply-To: <55FC4F13.3090603@FreeBSD.org>
References:  <55FA3848.7090802@freebsd.org> <55FB233D.2080000@FreeBSD.org> <55FB48E3.20401@freebsd.org> <55FC4F13.3090603@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.

--------------080505010706070807030101
Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
Content-ID: <20150920004041.B29510@sola.nimnet.asn.au>

On Fri, 18 Sep 2015 13:51:15 -0400, Jung-uk Kim wrote:
 > On 09/17/2015 19:12, Colin Percival wrote:
 > > On 09/17/15 13:31, Jung-uk Kim wrote:
 > >> On 09/16/2015 23:49, Colin Percival wrote:
 > >>> I ran into an interesting glitch recently: I told my laptop to
 > >>> shut down, then closed the lid... and it promptly went into S3.
 > >>> When I opened the lid a couple days later, it resumed... and
 > >>> then finished the shutdown which it had started 2 days
 > >>> earlier.
 > >> 
 > >> Please try the attached patch.
 > > 
 > > No, this doesn't do what I wanted.  It might be a good idea anyway,
 > > but your patch only disables suspend once the kernel is trying to
 > > reboot; what I want is to disable suspend a bit earlier -- once
 > > rc.shutdown is running and the userland is trying to shut down,
 > > because at that point unless something breaks horribly we're *about
 > > to* tell the kernel to shut down even though we haven't gotten
 > > there quite yet.
 > 
 > Okay.  The attached patch is a quick-and-dirty & untested hack for you.

That looks .. comprehensive, given that it's run when rc.shutdown is 
called by init(8), if I'm correctly following the train of events from 
shutdown through init (unless -o) and then halt(8) or reboot(8).

Am I right assuming that if one ran say 'shutdown -p +2 [message]' then 
suspending would only be blocked after that interval has elapsed?

And with 'shutdown [-p|-h|-r] now' is there any appreciable delay (like
waiting on anything) before launching rc.shutdown?  i.e. anything that 
aforesaid fast lid-slammer might beat?

"Five minutes before shutdown, or immediately if shutdown is in less 
than 5 minutes, logins are disabled by creating /var/run/nologin and 
copying the warning message there."

Guess I'm still wondering if blocking suspend from shutdown, perhaps 
in a similar timeframe, might better prevent suspend-during-shutdown?

Aside perhaps, a point about acpiconf(8) I discovered tonight: every 
version of the man page since at least 5.5 states that S5 (soft off) is 
an option for -s.  That was true at 5.5, however acpiconf.c at least 
from 8.2 through 9.3 to HEAD (checked just now) allows only S1 to S4.

Noticed that because I was trying to find what else apart from shutdown, 
halt -p and the power button could initiate a poweroff halt.  Are there 
other ways, apart from doing it like acpiconf does?

cheers, Ian
--------------080505010706070807030101
Content-Type: TEXT/X-PATCH; NAME=acpi.diff
Content-ID: <20150920004041.P29510@sola.nimnet.asn.au>
Content-Description: 
Content-Disposition: ATTACHMENT; FILENAME=acpi.diff

Index: etc/rc.shutdown
===================================================================
--- etc/rc.shutdown	(revision 287937)
+++ etc/rc.shutdown	(working copy)
@@ -43,6 +43,9 @@ HOME=/
 PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin
 export HOME PATH
 
+# Temporarily block any suspend requests.
+acpiconf -b 1 >/dev/null 2>&1
+
 . /etc/rc.subr
 
 load_rc_config 'XXX'
@@ -109,5 +112,8 @@ fi
 # Insert other shutdown procedures here
 
 
+# Unblock suspend requests.
+acpiconf -b 0 >/dev/null 2>&1
+
 echo '.'
 exit 0
Index: sys/dev/acpica/acpi.c
===================================================================
--- sys/dev/acpica/acpi.c	(revision 287937)
+++ sys/dev/acpica/acpi.c	(working copy)
@@ -98,6 +98,9 @@ struct callout	acpi_sleep_timer;
 /* Bitmap of device quirks. */
 int		acpi_quirks;
 
+/* Block suspend requests. */
+static int	acpi_sleep_blocked;
+
 /* Supported sleep states. */
 static BOOLEAN	acpi_sleep_states[ACPI_S_STATE_COUNT];
 
@@ -2574,10 +2577,12 @@ acpi_ReqSleepState(struct acpi_softc *sc, int stat
     if (!acpi_sleep_states[state])
 	return (EOPNOTSUPP);
 
-    /* If a suspend request is already in progress, just return. */
-    if (sc->acpi_next_sstate != 0) {
+    /*
+     * If a reboot/shutdown/suspend request is already in progress
+     * or suspend is explicitly disabled, just return.
+     */
+    if (rebooting || sc->acpi_next_sstate != 0 || acpi_sleep_blocked)
 	return (0);
-    }
 
     /* Wait until sleep is enabled. */
     while (sc->acpi_sleep_disabled) {
@@ -3568,6 +3573,9 @@ acpiioctl(struct cdev *dev, u_long cmd, caddr_t ad
 	error = *(int *)addr;
 	error = acpi_AckSleepState(sc->acpi_clone, error);
 	break;
+    case ACPIIO_BLKSLPSTATE:
+	acpi_sleep_blocked = *(int *)addr;
+	break;
     case ACPIIO_SETSLPSTATE:	/* DEPRECATED */
 	state = *(int *)addr;
 	if (state < ACPI_STATE_S0 || state > ACPI_S_STATES_MAX)
Index: sys/dev/acpica/acpiio.h
===================================================================
--- sys/dev/acpica/acpiio.h	(revision 287937)
+++ sys/dev/acpica/acpiio.h	(working copy)
@@ -41,6 +41,9 @@
 /* Allow suspend to continue (0) or abort it (errno). */
 #define ACPIIO_ACKSLPSTATE	_IOW('P', 5, int)
 
+/* Allow suspend request (0) or block it. */
+#define ACPIIO_BLKSLPSTATE	_IOW('P', 6, int)
+
 struct acpi_battinfo {
     int	 cap;				/* percent */
     int	 min;				/* remaining time (in minutes) */
Index: usr.sbin/acpi/acpiconf/acpiconf.8
===================================================================
--- usr.sbin/acpi/acpiconf/acpiconf.8	(revision 287937)
+++ usr.sbin/acpi/acpiconf/acpiconf.8	(working copy)
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 10, 2014
+.Dd September 18, 2015
 .Dt ACPICONF 8
 .Os
 .Sh NAME
@@ -35,6 +35,7 @@
 .Nd control ACPI power management
 .Sh SYNOPSIS
 .Nm
+.Op Fl b Ar block
 .Op Fl h
 .Op Fl i Ar batt
 .Op Fl k Ar ack
@@ -45,7 +46,10 @@ The
 utility allows the user control of the ACPI power management
 functions.
 The following command-line options are recognized:
-.Bl -tag -width ".Fl s Ar type"
+.Bl -tag -width ".Fl b Ar block"
+.It Fl b Ar block
+Block or unblock suspend requests using the argument provided.
+.Sy Most users should not use this option directly.
 .It Fl h
 Displays a summary of available options.
 .It Fl i Ar batt
Index: usr.sbin/acpi/acpiconf/acpiconf.c
===================================================================
--- usr.sbin/acpi/acpiconf/acpiconf.c	(revision 287937)
+++ usr.sbin/acpi/acpiconf/acpiconf.c	(working copy)
@@ -77,6 +77,17 @@ acpi_sleep_ack(int err_val)
 		err(EX_IOERR, "ack sleep type failed");
 }
 
+/* Block or unblock suspend requests. */
+static void
+acpi_sleep_block(int block)
+{
+	int ret;
+
+	ret = ioctl(acpifd, ACPIIO_BLKSLPSTATE, &block);
+	if (ret != 0)
+		err(EX_IOERR, "%sblock sleep failed", block ? "" : "un");
+}
+
 /* should be a acpi define, but doesn't appear to be */
 #define UNKNOWN_CAP 0xffffffff
 #define UNKNOWN_VOLTAGE 0xffffffff
@@ -213,8 +224,11 @@ main(int argc, char *argv[])
 
 	sleep_type = -1;
 	acpi_init();
-	while ((c = getopt(argc, argv, "hi:k:s:")) != -1) {
+	while ((c = getopt(argc, argv, "b:hi:k:s:")) != -1) {
 		switch (c) {
+		case 'b':
+			acpi_sleep_block(atoi(optarg));
+			break;
 		case 'i':
 			acpi_battinfo(atoi(optarg));
 			break;

--------------080505010706070807030101
Content-Type: TEXT/PLAIN; CHARSET=us-ascii
Content-ID: <20150920004041.U29510@sola.nimnet.asn.au>
Content-Description: 
Content-Disposition: INLINE

_______________________________________________
freebsd-acpi@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-acpi
To unsubscribe, send any mail to "freebsd-acpi-unsubscribe@freebsd.org"
--------------080505010706070807030101--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150920004041.J29510>