Date: Thu, 25 May 2006 14:24:01 +0200 From: "Beat Gaetzi" <beat@chruetertee.ch> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/97896: [patch] proper system shut down on low battery level Message-ID: <4461DC32003CBA75@mail21.bluewin.ch> (added by postmaster@bluewin.ch) Resent-Message-ID: <200605251230.k4PCUN64043845@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 97896 >Category: bin >Synopsis: [patch] proper system shut down on low battery level >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Thu May 25 12:30:23 GMT 2006 >Closed-Date: >Last-Modified: >Originator: Beat Gätzi >Release: FreeBSD 6.1-RELEASE i386 >Organization: >Environment: System: FreeBSD daedalus.network.local 6.1-RELEASE FreeBSD 6.1-RELEASE #0: Sat May 6 12:37:33 CEST 2006 beat@daedalus.network.local:/usr/obj/usr/src/sys/BEASTIE i386 >Description: If the notebook battery is empty, the system switches off without a proper system shut down. The attached patch adds two new options to the powerd which give the user a warning if the battery level is low and shut down the system if the user doesn't care about the warning. >How-To-Repeat: >Fix: --- powerd.patch begins here --- diff -ruN /usr/src/usr.sbin/powerd.ori/powerd.8 /usr/src/usr.sbin/powerd/powerd.8 --- /usr/src/usr.sbin/powerd.ori/powerd.8 Thu May 25 13:16:20 2006 +++ /usr/src/usr.sbin/powerd/powerd.8 Thu May 25 13:04:53 2006 @@ -39,7 +39,9 @@ .Op Fl p Ar ival .Op Fl P Ar pidfile .Op Fl r Ar percent +.Op Fl s Ar percent .Op Fl v +.Op Fl w Ar percent .Sh DESCRIPTION The .Nm @@ -92,11 +94,17 @@ adaptive mode should consider the CPU running and increase performance. The default is 65% or lower. +.It Fl s Ar percent +Specifies the battery level on which a warning message will be sent to all +user terminals. .It Fl v Verbose mode. Messages about power changes will be printed to stdout and .Nm will operate in the foreground. +.It Fl w Ar percent +Specifies the battery level on which the system will be shut down +automatically. .El .Sh SEE ALSO .Xr acpi 4 , diff -ruN /usr/src/usr.sbin/powerd.ori/powerd.c /usr/src/usr.sbin/powerd/powerd.c --- /usr/src/usr.sbin/powerd.ori/powerd.c Thu May 25 13:16:20 2006 +++ /usr/src/usr.sbin/powerd/powerd.c Thu May 25 13:39:24 2006 @@ -31,6 +31,7 @@ #include <sys/param.h> #include <sys/ioctl.h> #include <sys/sysctl.h> +#include <sys/syslog.h> #include <sys/resource.h> #include <sys/socket.h> #include <sys/time.h> @@ -39,11 +40,14 @@ #include <err.h> #include <errno.h> #include <fcntl.h> +#include <getopt.h> #include <libutil.h> +#include <paths.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <time.h> #include <unistd.h> #ifdef USE_APM @@ -357,7 +361,7 @@ { fprintf(stderr, -"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-n mode] [-p ival] [-r %%] [-P pidfile]\n"); +"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-n mode] [-p ival] [-r %%] [-s %%] [-w %%] [-P pidfile]\n"); exit(1); } @@ -368,26 +372,33 @@ fd_set fdset; int nfds; struct pidfh *pfh = NULL; + char wcmd[MAXPATHLEN + 4]; const char *pidfile = NULL; long idle, total; - int curfreq, *freqs, i, *mwatts, numfreqs; - int ch, mode, mode_ac, mode_battery, mode_none; + int batt, curfreq, *freqs, i, *mwatts, numfreqs; + int ch, mode, mode_ac, mode_battery, mode_none, sflag; + int batt_shutdown, batt_warning, shutdown_status; uint64_t mjoules_used; size_t len; + FILE *pf; /* Default mode for all AC states is adaptive. */ mode_ac = mode_battery = mode_none = MODE_ADAPTIVE; cpu_running_mark = DEFAULT_ACTIVE_PERCENT; cpu_idle_mark = DEFAULT_IDLE_PERCENT; poll_ival = DEFAULT_POLL_INTERVAL; + batt_shutdown = 0; + batt_warning = 0; mjoules_used = 0; + sflag = 0; + shutdown_status = 0; vflag = 0; /* User must be root to control frequencies. */ if (geteuid() != 0) errx(1, "must be root to run"); - while ((ch = getopt(argc, argv, "a:b:i:n:p:P:r:v")) != EOF) + while ((ch = getopt(argc, argv, "a:b:i:n:p:P:r:s:vw:")) != EOF) switch (ch) { case 'a': parse_mode(optarg, &mode_ac, ch); @@ -424,6 +435,28 @@ usage(); } break; + case 's': + batt_shutdown = atoi(optarg); + sflag = 1; + batt_warning = batt_shutdown + 2; + if (batt_shutdown < 0 || batt_shutdown > 100) { + warnx("%d is not a valid percent", + batt_shutdown); + usage(); + } + break; + case 'w': + batt_warning = atoi(optarg); + if (batt_warning < 0 || batt_warning> 100) { + warnx("%d is not a valid percent", + batt_warning); + usage(); + } + if (batt_warning <= batt_shutdown) { + warnx("battery warning value must be greater than battery shut down value"); + usage(); + } + break; case 'v': vflag = 1; break; @@ -446,6 +479,13 @@ len = 4; if (sysctlnametomib("dev.cpu.0.freq_levels", levels_mib, &len)) err(1, "lookup freq_levels"); + if (sflag == 1) { + len = sizeof(batt); + if (sysctlbyname("hw.acpi.battery.life", &batt, &len, NULL, 0)) { + err(1, "lookup battery life"); + sflag = 0; + } + } /* Check if we can read the idle time and supported freqs. */ if (read_usage_times(NULL, NULL)) @@ -519,6 +559,40 @@ break; default: errx(1, "invalid AC line status %d", acline_status); + } + + if (sflag == 1) { + if (acline_status == SRC_BATTERY) { + len = sizeof(batt); + if (sysctlbyname("hw.acpi.battery.life", &batt, &len, NULL, 0)) + err(1, "lookup battery life"); + if (batt <= batt_warning) { + if (shutdown_status == 0) { + if (vflag) + warnx("Running out of battery! System will shut down automatically"); + (void)snprintf(wcmd, sizeof(wcmd), "%s -n", _PATH_WALL); + if (!(pf = popen(wcmd, "w"))) { + syslog(LOG_ERR, "powerd: can't find %s: %m", + _PATH_WALL); + } + (void)fprintf(pf, + "\nReconnect power IMMEDIATELY or system will shut down\n\n"); + (void)pclose(pf); + shutdown_status = 1; + } + } + if (batt <= batt_shutdown) { + if (shutdown_status == 1) { + if (vflag) + warnx("The System is shutting down"); + sflag = 0; + syslog(LOG_ERR, + "system shut down by powerd because of low battery"); + system("shutdown -p now Automatic system shut down by powerd &"); + shutdown_status = 2; + } + } + } } /* Read the current frequency. */ --- powerd.patch ends here --- >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4461DC32003CBA75>