[[Vorlage(Archiviert, )]] {{{#!vorlage Wissen [:Pakete installieren: Installation von Programmen] [:Editor: Einen Editor öffnen] [:sudo: Root-Rechte] [:Terminal: Ein Terminal öffnen] [:Rechte: Rechte für Dateien und Ordner ändern] }}} [[Inhaltsverzeichnis()]] 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 [wikipedia: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 [http://www.vdr-wiki.de/wiki/index.php/ACPI_Wakeup vdr-Wiki] {de}.) Nutzt man zusätzlich [:Wake_on_LAN: Wake-on-LAN], kann das Aufwecken auch bei Bedarf erfolgen. Bei diesem Skript handelt es sich um eine modifzierte bzw. erweiterte Version des [:Skripte/Auto_OFF: 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. {{{#!code bash # 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]: {{{#!vorlage Befehl sudo touch /etc/autosuspend_resumeplan }}} == Das Skript == Das Skript wird als '''/usr/local/sbin/autosuspend.sh''' abgelegt: {{{#!code bash #!/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: {{{#!vorlage Befehl 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 [:Cron: 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: {{{#!vorlage Befehl 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''': {{{#!vorlage Tabelle 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: {{{#!code 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 [http://askubuntu.com/questions/8112/how-do-i-detect-when-the-system-suspends/8124#8124 askubuntu.com] {en} 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: {{{#!vorlage Paketinstallation etherwake, universe }}} === 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. {{{#!code bash #!/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: {{{#!code sh /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: {{{#!vorlage Warnung Hierfür wird die Verwendung von [:Archiv/pm-utils: `pm-utils`] vorausgesetzt. }}} Der folgende Befehl erstellt automatisch eine Konfigurationsdatei für `pm-utils`, die das Skript auch beim Resume aufruft. {{{#!vorlage Befehl 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 [http://synthesis.tobiasquetschke.de/andere-rechner-aufwecken-wenn-ein-windows-7-c tobiasqeutschke.de] {de} eine Anleitung, für Windows XP wird noch eine erstellt werden. #tag: System, Shell, Server, Programmierung