ubuntuusers.de

AutoSuspend

Archivierte Anleitung

Dieser Artikel wurde archiviert. Das bedeutet, dass er nicht mehr auf Richtigkeit überprüft oder anderweitig gepflegt wird. Der Inhalt wurde für keine aktuell unterstützte Ubuntu-Version getestet. Wenn du Gründe für eine Wiederherstellung siehst, melde dich bitte in der Diskussion zum Artikel. Bis dahin bleibt die Seite für weitere Änderungen gesperrt.

Dieses AutoSuspend-Skript versetzt den Computer bei Nichtbenutzung automatisch in den Standby-Modus (je nach Verfügbarkeit: Hybrid-Standby, Suspend-To-RAM oder Suspend-To-Disk). Es kann so helfen, Strom zu sparen, da beispielsweise ein Heimserver meist nur zu bestimmten Zeiten genutzt, aber aufgrund des hohen Aufwandes auch ungern heruntergefahren wird. Das Skript ist darüber hinaus in der Lage ‒ sofern das System dies unterstützt ‒ den Computer automatisch per ACPI zu bestimmten Zeiten wieder aufzuwecken. Soll der Computer in regelmäßigen Abständen neu gestartet werden, so kann dieses Skript auch einen wöchentlichen Reboot durchführen. (Weitere Informationen zum ACPI-Wakeup finden sich im vdr-Wiki 🇩🇪.) Nutzt man zusätzlich Wake-on-LAN, kann das Aufwecken auch bei Bedarf erfolgen.

Bei diesem Skript handelt es sich um eine modifzierte bzw. erweiterte Version des Auto OFF-Skriptes.

Vorbereitungen

Damit das Skript genutzt werden kann, wird das vorinstallierte Paket

  • pm-utils

benötigt (siehe auch Archiv/pm-utils).

Konfigurationsdateien

Das Skript benötigt zwei Konfigurationsdateien in /etc.

Zunächst wird /etc/autosuspend in einem Editor[2] mit Rootrechten[3] angelegt. Diese Datei dient der benutzerspezifischen Konfiguration des Skriptes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Turn on auto suspend
AUTO_SUSPEND='yes'

# Turning suspend by day (8 a.m. to 3 a.m.) off
DONT_SUSPEND_BY_DAY='no'

# Automatically reboot once a week when the system isn't in use
REBOOT_ONCE_PER_WEEK='yes'

# Daemons that always have one process running, only if more that one process is active we prevent the suspend
# The values are used with grep, so just a unique portion is sufficient
DAEMONS=''

# Important applications that shall prevent the suspend
# The values are used with grep, so just a unique portion is sufficient
APPLICATIONS='"^nxagent$" "^rsnapshot$" "^wsus$" "^wget$" "^screen$" "^mlnetp$" "^apt-get$" "^aptitude$" "^dpkg$" "^cp$"'

# Network IP range for checking any open samba connections
# The value is used with grep, so just a unique portion is sufficient
SAMBANETWORK='192.168.1.'

# Names or IP for computers that shall prevent the suspend
# We ping these computers in the list to check whether they are active.
CLIENTS='COMPUTER1 COMPUTER2'

Dann muss noch /etc/autosuspend_resumeplan erzeugt werden, diese Datei kann leer sein und daher mithilfe von touch erstellt werden[4]:

sudo touch /etc/autosuspend_resumeplan 

Das Skript

Das Skript wird als /usr/local/sbin/autosuspend.sh abgelegt:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/bin/bash

. /etc/autosuspend

logit()
{
	logger -p local0.notice -s -- AutoSuspend: $*
	return 0
}

IsOnline()
{
	for i in $*; do
		ping $i -c1
		if [ "$?" == "0" ]; then
		  logit "PC $i is still active, auto suspend terminated"
		  return 1
		fi
	done
	return 0
}

IsRunning()
{
	for i in $*; do
		if [ `pgrep -c $i` -gt 0 ] ; then
			logit "$i still active, auto suspend terminated"
			return 1
		fi
	done
	return 0
}

IsDaemonActive()
{
	for i in $*; do
		if [ `pgrep -c $i` -gt 1 ] ; then
			logit "$i still active, auto suspend terminated"
			return 1
		fi
	done
	return 0
}

IsBusy()
{
	# Samba
	if [ "x$SAMBANETWORK" != "x" ]; then
		if [ `/usr/bin/smbstatus -b | grep $SAMBANETWORK | wc -l ` != "0" ]; then
		  logit "samba connected, auto suspend terminated"
		  return 1
		fi
	fi

	#daemons that always have one process running
	IsDaemonActive $DAEMONS
	if [ "$?" == "1" ]; then
		return 1
	fi

	#backuppc, wget, wsus, ....
	IsRunning $APPLICATIONS
	if [ "$?" == "1" ]; then
			return 1
	fi

	# Read logged users
	USERCOUNT=`who | wc -l`;
	# No Suspend if there are any users logged in
	test $USERCOUNT -gt 0 && { logit "some users still connected, auto suspend terminated"; return 1; }

	IsOnline $CLIENTS
	if [ "$?" == "1" ]; then
		return 1
	fi

	return 0
}

COUNTFILE="/var/spool/suspend_counter"
OFFFILE="/var/spool/suspend_off"

# turns off the auto suspend
if [ -e $OFFFILE ]; then
	logit "auto suspend is turned off by existents of $OFFFILE"
	exit 0
fi

if [ "$AUTO_SUSPEND" = "true" ] || [ "$AUTO_SUSPEND" = "yes" ] ; then
	IsBusy
	if [ "$?" == "0" ]; then
		# was it not busy already last time? Then suspend.
		if [ -e $COUNTFILE ]; then
			# only auto-suspend at night
			if [ \( "$DONT_SUSPEND_BY_DAY" != "true" -a "$DONT_SUSPEND_BY_DAY" != "yes" \) -o \( "`date +%H`" -ge "3" -a "`date +%H`" -lt "8" \) ]; then
				# notice resume-plan
				NEXTWAKE="0"
				while read line; do
					if [ "`date +%s -d \"$line\"`" -gt "`date +%s`" -a  \( "`date +%s -d \"$line\"`" -lt "$NEXTWAKE" -o "$NEXTWAKE" = "0" \) ]; then
						NEXTWAKE="`date +%s -d \"$line\"`"
					fi
				done < /etc/autosuspend_resumeplan
				if [ "$NEXTWAKE" -gt "`date +%s`" ]; then
					if [ "$NEXTWAKE" -gt "`expr \"\`date +%s\`\" + 1800`" ]; then
						echo "0" > /sys/class/rtc/rtc0/wakealarm
						echo "$NEXTWAKE" > /sys/class/rtc/rtc0/wakealarm
						logit "will resume at $NEXTWAKE"
					else
						logit "do not suspend because would have been awaken within next 30 minutes"
						exit 0
					fi
				fi
				# and suspend or reboot:
				rm -f $COUNTFILE
				if [ \( "$REBOOT_ONCE_PER_WEEK" = "true" -o "$REBOOT_ONCE_PER_WEEK" = "yes" \) -a "`echo \"scale=2; ( \`cat /proc/uptime | cut -d' ' -f1-1\` / 3600 / 24 ) >= 7\" | bc`" -gt 0 ]; then
					logit "REBOOTING THE MACHINE BECAUSE IT HAS BEEN RUNNING FOR MORE THAN A WEEK"
					shutdown -r now
				else
					logit "AUTO SUSPEND CAUSED"
					( test ! -x "/usr/bin/pm-is-supported" && ( logit "cannot check the system's suspend ability. aborting" || /bin/true ) ) || \
					( /usr/bin/pm-is-supported --suspend-hybrid && /usr/sbin/pm-suspend-hybrid ) || \
					( /usr/bin/pm-is-supported --suspend && /usr/sbin/pm-suspend ) || \
					( /usr/bin/pm-is-supported --hibernate && /usr/sbin/pm-hibernate ) || \
					logit "NEITHER SUSPEND NOR RESUME ARE NOT SUPPORTED BY THIS SYSTEM!!! aborting"
				fi
			else
				logit "did not auto suspend because it is broad day"
			fi
			exit 0
		else
			# shut down next time
			touch $COUNTFILE
			logit "marked for suspend in next try"
			exit 0
		fi
	else
		rm -f $COUNTFILE
		logit "aborted"
		exit 0
	fi
fi

logit "malfunction"
exit 1

Es muss ausführbar[5] gemacht werden, z.B. mit:

sudo chown root:root /usr/local/sbin/autosuspend.sh
sudo chmod u+x /usr/local/sbin/autosuspend.sh 

Per Cronjob ausführen

Nun muss noch ein Cronjob angelegt werden, damit das Skript überhaupt aufgerufen wird. Hier im Beispiel wird das Skript viertelstündig gestartet, der Computer würde also nach einer halben Stunde Inaktivität in den Standby versetzt (respektive neugestartet).

Zum Erstellen des Cronjobs kann folgender Befehl genutzt werden:

echo "*/15 * * * * root /usr/local/sbin/autosuspend.sh" | sudo tee -a /etc/crontab 

Funktionen

Das Skript kann prüfen, ob

  • bestimmte Programme laufen

  • bestimmte Dämonen aktiv sind

  • noch Samba Verbindungen aktiv sind

  • User eingeloggt sind

  • andere PCs noch eingeschaltet sind

NFS wird nicht auf aktive Verbindungen überwacht. Man kann sich behelfen, indem stattdessen geprüft wird, ob der Client-PC eingeschaltet ist.

Konfiguration

Dauerlauf erzwingen

Die automatische Versetzung des Computers in den Standbymodus (das automatische Neustarten) kann auf folgende Weisen verhindert werden:

  • Indem die Datei /var/spool/suspend_off erzeugt wird. (siehe man touch)

  • In der Konfigurationsdatei /etc/autosuspend den Schalter AUTO_SUSPEND=no aufnehmen.

Den Computer regelmäßig neustarten

Setzt man in der Konfigurationsdatei /etc/autosuspend den Schalter REBOOT_ONCE_PER_WEEK auf yes, wird der Computer nicht in den Standby versetzt, sondern stattdessen neugestartet, wenn er bereits länger als eine Woche läuft.

Tagsüber nicht abschalten

Ist in der o.g. Konfigurationsdatei der Schalter DONT_SUSPEND_BY_DAY=yes gesetzt, wird der Computer nur zwischen 3 Uhr und 8 Uhr in den Standby versetzt, damit er tagsüber schnell zur Verfügung steht (und ggf. Komponenten wie Festplatten nicht ständig ein- und ausgeschaltet werden).

Weitere Parameter

Erklärung der weiteren Schalter in der Datei /etc/autosuspend:

Schalter Erklärung
DAEMONS Hier kann eine Liste von Dämonen eingetragen werden, die den Standby-Modus (das Herunterfahren) verhindern sollen. Damit dies geschieht, müssen jedoch mindestens zwei Instanzen dieser Programme aktiv sein. Die Prüfung erfolgt mit grep, sodass auch reguläre Ausdrücke möglich sind.
APPLICATIONS Hier kann eine Liste von Programmen eingetragen werden, die den Standby-Modus (das Herunterfahren) verhindern sollen. Die Prüfung erfolgt mit grep, sodass auch reguläre Ausdrücke möglich sind.
SAMBANETWORK Hier kann ein Netzwerk eingetragen werden, das auf Samba-Verbindungen geprüft wird. Die Prüfung erfolgt mithilfe von grep, sodass ein Teil der Netzwerk-Adresse (z.B. 192.168.1.) oder ein von unterstützter regulärer Ausdruck eingetragen werden muss. Eine geöffnete Samba-Verbindung verhindert, dass der Rechner in den Standby-Modus versetzt (heruntergefahren) wird.
CLIENTS Enthält eine Liste von Rechnern, deren Zustand automatisch per Ping geprüft wird. Ist noch einer von ihnen aktiv, wird der Rechner nicht in den Standby-Modus versetzt (heruntergefahren).

Den Rechner zu bestimmten Zeiten reaktivieren

In der Datei /etc/autosuspend_resumeplan können Termine eingetragen werden, an denen der Computer aufwachen soll. Sie werden mithilfe von date geparst, müssen also im richtigen Format eingetragen werden. Beispiel:

1
2
16:00
16:00 tomorrow

Das Skript verwendet immer den frühsten in der Zukunft liegenden Termin. (Achtung: 16:00 wird von date, auch wenn es schon 17 Uhr ist, noch als "16 Uhr heute" interpretiert!)

Log-Datei über Suspends und Resumes

Zwar erzeugt das Script bereits Einträge in /var/log/syslog, einige werden jedoch die Resume- und Suspend-Vorgänge separat loggen wollen. Mit den pm-utils geht das sehr einfach. Ein Beispiel-Skript ist auf askubuntu.com 🇬🇧 verfügbar.

Server durch andere Computer reaktivieren

Nun, da der Rechner durch das Skript automatisch in den Standby gesetzt wird, ist es sinnvoll, ihn automatisch zu reaktivieren, wenn andere Rechner auf ihn zugreifen sollen (sofern es sich um einen Server handelt).

Ubuntu-Clients

Unter Ubuntu lässt sich das relativ einfach lösen.

Schritt 1

Benötigtes Paket installieren:

  • etherwake (universe)

Befehl zum Installieren der Pakete:

sudo apt-get install etherwake 

Oder mit apturl installieren, Link: apt://etherwake

Schritt 2

Skript zum Aufwecken einrichten:

Hierzu muss die MAC-Adresse des Servers bekannt sein und für die Variable MAC eingetragen werden. Sie kann auf dem Server mithilfe von ifconfig ermittelt werden. Gegebenfalls muss auch das Interface angepasst werden.

1
2
3
4
#!/bin/bash
INTERFACE="eth0"
MAC="00:AA:BB:CC:DD:EE"
etherwake -i "$INTERFACE" "$MAC"

Dieses wird als /usr/local/sbin/wakeserver.sh gespeichert und für root ausführbar gemacht [5].

Schritt 3

Skript beim Systemstart aufrufen:

Hier zu muss in /etc/rc.local vor exit 0 folgendes ergänzt werden:

1
/usr/local/sbin/wakeserver.sh

Schritt 4

Den Server nicht nur aufwecken, wenn der Client bootet, sondern auch wenn er selbst aus einem Standby erwacht:

Achtung!

Hierfür wird die Verwendung von pm-utils vorausgesetzt.

Der folgende Befehl erstellt automatisch eine Konfigurationsdatei für pm-utils, die das Skript auch beim Resume aufruft.

echo -ne '#!/bin/sh\ncase "$1" in\n\tresume|thaw)\n\t\t/usr/local/sbin/wakeserver.sh\n\t\t;;\nesac\n' | sudo tee /etc/pm/sleep.d/90_wakeserver 

Sollte der Befehl mit Wlan nicht zufriedenstellend funktionieren, sei hiermit auf die Diskussion zum Artikel verwiesen.

Windows-Clients

Für Windows Vista und Windows 7 existiert auf tobiasqeutschke.de 🇩🇪 eine Anleitung, für Windows XP wird noch eine erstellt werden.

Diese Revision wurde am 5. Februar 2020 19:59 von Heinrich_Schwietering erstellt.
Die folgenden Schlagworte wurden dem Artikel zugewiesen: Server, Shell, System, Programmierung