Package: sleepd
Severity: wishlist
Tags: patch
I just scratched an itch: I want my home server to stay up as long as
there are open ssh (or scp, sftp) connections (even if these connections
are idle).
I thus added a command-line option "-p " (for my use case, -p 22).
It scans /proc/net/tcp for users of the port, and if there is more than
one (i.e., the listening sshd plus at least one forked child), it counts
it as an activity.
The included patch applies to sleepd 2.08.
Sleepd 2.08 does not run on my home server (wheezy, amd64) because it
does not provide /sys/class/power_supply (I did not investigate why not;
it does provide functional ACPI). Thus, the patch includes another,
unrelated option "-C" to force use of ACPI. I can tease these two
options apart into separate patches if necessary, but both are trivial.
I'd like to see this patch (or an improved version) applied upstream
(whatever this means, as it is "dead and buried" according to
http://joeyh.name/code/). Or else, please let me know about an
alive-and-well alternative to sleepd.
Justus
-- System Information:
Debian Release: 8.0
APT prefers testing
APT policy: (500, 'testing')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 3.16.0-4-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
--- a/sleepd.c
+++ b/sleepd.c
@@ -58,9 +58,11 @@
#endif
int use_acpi=0;
int force_hal=0;
+int force_acpi=0;
int require_unused_and_battery=0; /* --and or -A option */
double max_loadavg = 0;
int use_utmp=0;
+int port=0;
int use_net=0;
int min_tx=TXRATE;
int min_rx=RXRATE;
@@ -69,7 +71,7 @@
int debug=0;
void usage () {
- fprintf(stderr, "Usage: sleepd [-s command] [-d command] [-u n] [-U n] [-I] [-i n] [-E] [-e filename] [-a] [-l n] [-w] [-n] [-v] [-c n] [-b n] [-A] [-H] [-N [dev] [-t n] [-r n]]\n");
+ fprintf(stderr, "Usage: sleepd [-s command] [-d command] [-u n] [-U n] [-I] [-i n] [-E] [-e filename] [-a] [-l n] [-p n] [-w] [-n] [-v] [-c n] [-b n] [-A] [-C] [-H] [-N [dev] [-t n] [-r n]]\n");
}
void parse_command_line (int argc, char **argv) {
@@ -95,7 +97,9 @@
{"netdev", 2, NULL, 'N'},
{"rx-min", 1, NULL, 'r'},
{"tx-min", 1, NULL, 't'},
+ {"port", 1, NULL, 'p'},
{"force-hal", 0, NULL, 'H'},
+ {"force-acpi", 0, NULL, 'C'},
{"force-upower", 0, NULL, 1},
{0, 0, 0, 0}
};
@@ -111,7 +115,7 @@
char rx_statfile[44];
while (c != -1) {
- c=getopt_long(argc,argv, "s:d:nvu:U:l:wIi:Ee:hac:b:AN::r:t:H", long_options, NULL);
+ c=getopt_long(argc,argv, "s:d:nvu:U:l:p:wIi:Ee:hac:b:AN::r:t:HC", long_options, NULL);
switch (c) {
case 's':
sleep_command=strdup(optarg);
@@ -141,6 +145,9 @@
case 'H':
force_hal=1;
break;
+ case 'C':
+force_acpi=1;
+break;
case 'i':
i = atoi(optarg);
if ((i < 0) || (i >= MAX_IRQS)) {
@@ -231,6 +238,9 @@
case 'r':
min_rx = atoi(optarg);
break;
+ case 'p':
+port = atoi(optarg);
+break;
case 'A':
require_unused_and_battery=1;
break;
@@ -388,6 +398,24 @@
return activity;
}
+int check_port (int activity) {
+ FILE *f = fopen(TCPFILE, "r");
+ if (!f) {
+syslog(LOG_ERR, "cannot open %s", TCPFILE);
+return activity;
+ }
+ char tcpbuf[1024];
+ int portusers = 0;
+ while (fgets(tcpbuf, sizeof(tcpbuf), f)) {
+int tcpport;
+if (sscanf(tcpbuf, "%*d:%*x:%x", &tcpport) == 1 && tcpport == port)
+ portusers++;
+ }
+ fclose(f);
+ if (debug) printf("sleepd: %d users of port %d\n", portusers, port);
+ return (portusers > 1) ? 1 : activity;
+}
+
int check_utmp (int total_unused) {
/* replace total_unused with the minimum of
* total_unused and the shortest utmp idle time. */
@@ -515,6 +543,10 @@
activity=check_net(activity);
}
+ if (port) {
+ activity=check_port(activity);
+ }
+
if ((max_loadavg != 0) &&
(getloadavg(loadavg, 1) == 1) &&
(loadavg[0] >= max_loadavg)) {
@@ -636,8 +668,10 @@
fclose(f);
}
}
-
- if (force_hal
+
+ if (force_acpi)
+ use_acpi = 1;
+ else if (force_hal
#ifdef USE_APM
|| apm_exists() != 0
#else
--- a/sleepd.h
+++ b/sleepd.h
@@ -8,3 +8,4 @@
#define TXRATE 15
#define RXFILE "/sys/class/net/%s/statistics/rx_packets"
#define RXRATE 25
+#define TCPFILE "/proc/net/tcp"
--- a/sleepd.8
+++ b/sleepd.8
@@ -3,7 +3,7 @@
sleepd \- puts a laptop to sleep during inactivity or on low battery
.SH SYNOPSIS
.B sleepd
-.I "[-s command] [-d command] [-u n] [-U n] [-I] [-i n] [-E] [-e filename] [-a] [-l n] [-w] [-n] [-v] [-c n] [-b n] [-A] [-H] [-N [device] [-r n] [-t n]]"
+.I "[-s command] [-d command] [-u n] [-U n] [-I] [-i n] [-E] [-e filename] [-a] [-l n] [-p n] [-w] [-n] [-v] [-c n] [-b n] [-A] [-C] [-H] [-N [device] [-r n] [-t n]]"
.SH DESCRIPTION
.BR sleepd
is a daemon to force laptops to go to sleep after some period of
@@ -97,6 +97,11 @@
Set a baseline receive traffic rate in packets per