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
[-- Attachment #1 --]
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
[-- Attachment #2 --]
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;
[-- Attachment #3 --]
_______________________________________________
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"
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150920004041.J29510>
