IOCTL Befehl für Watchdog

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Alex66955
User
Beiträge: 9
Registriert: Donnerstag 1. Juli 2010, 12:11

Hallo Community,

Habe folgendes Problem:
Versuche über eine IOCTL Anweisung den TimeOut für den Linux Watchdog (/dev/watchdog) zu setzen. Hintergrund ist bei Absturz des Skripts der Timeout des watchdog das System neustartet.

bisheriger Code:

Code: Alles auswählen

import sys,os, fcntl, array

watchdog = open("/dev/watchdog", "wb")
wd_fd = watchdog.fileno()
wd_buf = array.array("i", [180])

#0x0080 zum setzen des timeouts
fcntl.ioctl(wd_fd, 0x0080, wd_buf)
Fehlermeldung: "ioctl with mutable buffer will mutate the buffer by default in 2.5"
Watchdog API:
http://www.mjmwired.net/kernel/Document ... og-api.txt

Sieht jemand meinen Fehler?

Gruß
Alex
BlackJack

@Alex66955: Ist da denn ein wirklicher Fehler? Du schreibst zwar "Fehlermeldung:" aber ist das vielleicht nicht nur eine Warnung das sich das Verhalten der Funktion in Python 2.5 gegenüber 2.4 verändert hat, wenn man das vierte Argument nicht explizit angibt? Womit man die Warnung dann übrigens auch wegbekommen sollte.
Alex66955
User
Beiträge: 9
Registriert: Donnerstag 1. Juli 2010, 12:11

BlackJack hat geschrieben:@Alex66955: Ist da denn ein wirklicher Fehler? Du schreibst zwar "Fehlermeldung:" aber ist das vielleicht nicht nur eine Warnung das sich das Verhalten der Funktion in Python 2.5 gegenüber 2.4 verändert hat, wenn man das vierte Argument nicht explizit angibt? Womit man die Warnung dann übrigens auch wegbekommen sollte.
Hast Recht war nur eine Warnmeldung.
Beim hinzufügen einer 0 als viertes Argument bekomme ich folgendes (das 4. Argument ist zuständig für mutate_flag):
"IOERROR: [ERRNO 25] Inappropriate ioctl for device"

Also scheint was mit meinen Angaben für den IOCTL Befehl nicht zustimmen.

der equivalente "C" code zum ändern des TimeOuts ist:

Code: Alles auswählen

87	For some drivers it is possible to modify the watchdog timeout on the
88	fly with the SETTIMEOUT ioctl, those drivers have the WDIOF_SETTIMEOUT
89	flag set in their option field.  The argument is an integer
90	representing the timeout in seconds.  The driver returns the real
91	timeout used in the same variable, and this timeout might differ from
92	the requested one due to limitation of the hardware.
93	
94	    int timeout = 45;
95	    ioctl(fd, WDIOC_SETTIMEOUT, &timeout);
96	    printf("The timeout was set to %d seconds\n", timeout);
Diverse kleine Änderungen führten immer zur selben Fehlermeldung
BlackJack

@Alex66955: Und was passiert bei `True` als viertem Wert?
Alex66955
User
Beiträge: 9
Registriert: Donnerstag 1. Juli 2010, 12:11

BlackJack hat geschrieben:@Alex66955: Und was passiert bei `True` als viertem Wert?
Selbe Fehlermeldung: "IOERROR: [ERRNO 25] Inappropriate ioctl for device"

:(
BlackJack

@Alex66955: Stimmt die 0x80 denn? Bei mir auf dem Desktop-Rechner scheint das zum Beispiel 0xc0045706 zu sein.
Alex66955
User
Beiträge: 9
Registriert: Donnerstag 1. Juli 2010, 12:11

BlackJack hat geschrieben:@Alex66955: Stimmt die 0x80 denn? Bei mir auf dem Desktop-Rechner scheint das zum Beispiel 0xc0045706 zu sein.
Ich hab nochmal nachgesehen. Also in der Header Datei von watchdog steht:

#define WDIOC_SETTIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
#define WDIOF_SETTIMEOUT 0x0080 /* Set timeout (in seconds) */

Also nehme ich mal an ich muss die 6 nehmen. An der Fehlermeldung ändert sich aber leider nichts.

Quelle vom Watchdog header:
http://tomoyo.sourceforge.jp/cgi-bin/lx ... watchdog.h
BlackJack

@Alex66955: Du musst nicht die 6 nehmen sondern das, was bei dem Makro als Ergebnis herauskommt. Bei mir ist das besagter Wert.
Alex66955
User
Beiträge: 9
Registriert: Donnerstag 1. Juli 2010, 12:11

BlackJack hat geschrieben:@Alex66955: Du musst nicht die 6 nehmen sondern das, was bei dem Makro als Ergebnis herauskommt. Bei mir ist das besagter Wert.
Dachte eins von beiden müsste es sein Also "0x0080 " oder "6" weil das ja dem entsprechendem Befehl entspricht.

Wie bekomme ich den das direkte Ergebnis des "C"-Macro zurück? Sicher dass, das Ergebnis nicht "0x0080 " oder "6" ist?
BlackJack

@Alex66955: Ich hatte mir einfach ein kleines C-Programm geschrieben, das den Wert ausgibt:

Code: Alles auswählen

#include <stdio.h>
#include <linux/watchdog.h>

int main(void)
{
    printf("%x\n", WDIOC_SETTIMEOUT);
    return 0;
}
Wenn das Ergebnis einfach 6 wäre, bräuchte man das Makro ja nicht.
Alex66955
User
Beiträge: 9
Registriert: Donnerstag 1. Juli 2010, 12:11

Okay bekomme ebenfalls 0xc0045706 heraus.

Bei aktueller Änderung:

Code: Alles auswählen

import sys,os, fcntl, array

watchdog = open("/dev/watchdog", "wb")
wd_fd = watchdog.fileno()
wd_buf = array.array("i", [180])

fcntl.ioctl(wd_fd, 0xc0045706, wd_buf)
Kommt die Fehlermeldung: "OverflowError: long int too large to convert to int"
Also scheint mit dem neuen Wert nich zufrieden zu sein
BlackJack

Naja, die Zahl ist zu gross für ein vorzeichenbehaftetes 32-Bit Integer. Dann musst Du halt die Dezimalschreibweise und vorzeichenbehaftet nehmen: -1073457402
Alex66955
User
Beiträge: 9
Registriert: Donnerstag 1. Juli 2010, 12:11

BlackJack hat geschrieben:Naja, die Zahl ist zu gross für ein vorzeichenbehaftetes 32-Bit Integer. Dann musst Du halt die Dezimalschreibweise und vorzeichenbehaftet nehmen: -1073457402
Super Vielen Dank. Funktioniert alles ;). Obwohl ich sehr überrascht bin.
Bei der Umrechnung muss man nur drauf achten in das 4 Byte 2er Complement umzurechnen. Warum nochmal die Vorzeichen Ändernung`?
BlackJack

@Alex66955: Die API will ein `int` haben und das gibt's in Python 2.x halt nur mit Vorzeichen, also ist 0xc0045706 zu gross für ein `int`.
Antworten