Als ich dieses schrieb, hatte ich gerade den Fall, dass ich die printserv Prozesse alle gekillt hatte und dann mit vertauschten Gerätedateien neu gestartet. Trotzdem wurde auf den selben Drucker umgeleitet wie zuvor. Nur das Vertauschen der Portnummern hatte in dem Fall eine Auswirkung. Ein anderes Mal hatte es hingegen sehr wohl Auswirkungen, die Gerätedateien zu vertauschen. Erklärbar ist so ein Verhalten bislang nicht.Der Name der Datei ist egal, die Major und Minor Nummer nicht. Oder mal anders formuliert, warum übergibt man dem printserv überhaupt den Namen einer Gerätedatei, wenn es nicht von Bedeutung wäre, welches Gerät über diese Datei angesprochen wird?
Wenn ich von "ein anderes Mal" spreche, meine ich immer, dass ich zwischendurch den Hub getrennt und wieder eingesteckt hatte. Das habe ich mittlerweile rund 50 Mal gemacht ohne den Router neu zu starten (und dabei auch festgestellt, dass die USB Device-ID nach 127 wieder mit 0 beginnt (7 Bit)).
Wenn ich rekapituliere, was ich hier schon so alles geschrieben habe, bekomme ich selbst den Eindruck, als sei ich geistig halb umnachtet. Weil ich mal das eine schreibe und dann wieder was völlig Gegensätzliches. Aber das liegt nicht an mir, sondern daran, dass sich das Gerät wirklich völlig unterschiedlich verhält. Und völlig unvorhersehbar. Mal so - und dann mal wieder vollkommen anders.
Auf diese Idee war ich - wie oben gesagt - gekommen, weil es einmal den Fall gab, dass ich bei -d angeben konnte was ich wollte und trotzdem immer auf den selben Drucker gedruckt wurde. Und ja: Es waren zuvor wirklich alle printserv Prozesse gekillt worden. Es sei denn, "ps" macht falsche Angaben.Kurz gesagt, printserv bekommt einen TCP-Port angegeben, unter dem er die Daten annimmt, und eine Gerätedatei, auf die er die Daten schreibt. printserv leitet garantiert nicht die Daten von Port 9104 an Node 0 weiter. Woher sollte er denn wissen, was Du mit Port 9104 vorhast?
Was ich mit "manche Fälle" meinte, war der jeweilige Zustand des Routers nach dem Trennen und wieder Einstecken des USB Hubs. Danach war es in manchen Fällen egal, in welcher Reihenfolge man printserv für die einzelnen Drucker/Nodes startete und in manchen wiederum nicht. Wenn es aber egal war, dann war es das jedes Mal, also so lange, wie der Hub drin steckte. Und wenn nicht, galt dies auch so lange, bis der Hub getrennt wurde. Es klingt alles sehr verwirrend. Wenn man aber davon ausgeht, dass es zwei "Vergabestellen" für Minor-Numbers gibt (Kernel und Script), wie du angedeutet hast, erklärt sich dies.In manchen Fällen geht es jedes Mal, und in anderen Fällen nicht. Mit anderen Worten, es funktioniert nicht jedes Mal. [..]
Das freut mich für Dich, wenn es so ist, aber einige Deiner vorherigen Beiträge habe ich so verstanden, dass dem nicht so ist.
Du willst damit sagen, dass der Kernel schon intern (virtuell) die Nodes vergibt und es dann die Aufgabe des Scripts ist zu erraten, welche Node der Kernel zufällig vergeben hat und diese dann über das Anlegen eines Node-Files zu manifestieren? Na gute Nacht, wenn das so ist! Warum legt der Kernel dann nicht selbst die Gerätedatei unter der richtigen Node an?Es gibt diese feste Verdrahtung nicht. Angenommen Du startest das System, und beide Drucker sind ausgeschaltet oder das Kabel nicht verbunden, was hier aufs gleiche heraus kommt. Du verbindest jetzt zunächst den Drucker auf USB3 das System erkennt einen USB Drucker und vergibt für diesen die Nummer 0. Damit meine ich nicht das Skript, sondern den Kernel selbst.
Wenn es immer so wäre, wäre es schön. Das erklärt aber nicht, warum ich hin und wieder die Gerätedateien beim printserv vertauschen konnte und es keine Änderung bewirkte.Mit anderen Worten, es kommt nicht darauf an, wie die Datei heißt, die mit -d übergeben wird, sondern nur darauf, welche Gerätenummer hinter dieser Datei liegt. Die Gerätenummer legt nämlich fest, welches Geräte zu der Gerätedatei gehört. Und hier wenigstens ist die Zuordnung eindeutig, Minor Nummer 0 gehört zu usblp0 usw.
Stimmt, das war ein Fehler bei mir. Ich hatte gar nicht daran gedacht, dass sich der TCP-Port dadurch ja geändert hat und es deshalb nicht mehr funktionierte. Aber diesen Test hatte ich auch nur einmal durchgeführt.Wenn Du nur einen Drucker entfernst, wird dessen Minor Nummer frei. Wenn dann dieser Drucker (oder ein anderer) wieder verbunden wird, bekommt er die gleiche Minor Nummer, weil es die erste freie Nummer ist. Er kann folglich auch unter dem gleichen Namen wie vorher angesprochen werden. Wenn der Drucker aber an einem anderen USB Port hängt, liest das Skript einen anderen Wert von TOPO aus und wählt daher einen anderen TCP Port für den Drucker aus.
Moment! WO bekommt es die Minor 0? Im Kernel oder vom Script? Das scheinen ja zwei verschiedene Paar Schuhe zu sein. Wenn das so ist, könnte es einen Teil des Durcheinanders erklären. Weil das Script hier quasi "raten" muss.Das ist dann logisch, wenn die Anschlüsse am USB Hub parallel abgefragt werden. Eines der beiden Geräte antwortet einige Sekundenbruchteile früher als das andere, also bekommt es Minor 0, das zweite Geräte bekommt Minor 1, welches auch immer es ist.
Nur um meine Verwirrung mal zu dokumentieren, habe ich ein Beispiel ausgesucht für das, was ich so erlebt habe. Es würde aber deine Aussage mit den unsichtbaren, kernel-internen Node-Nummern untermauern. Ich dokumentierte den Ablauf des Scripts über eine Protokolldatei. Und dabei erlebte ich die auf den ersten Blick verrücktesten Dinge. Hier mal ein Beispiel. lsusb zeigte folgendes:
Code:
BUS=001
DEV=104
VID=1a86
PID=7584
CLS=00
SCL=00
SPEED='full'
VER='1.1'
PROD='USB2.0-Print '
TOPO=22
ISOC=0
INUM=1
ICLS1=07
ISCL1=01
BUS=001
DEV=105
VID=04a9
PID=1051
CLS=00
SCL=00
SPEED='full'
VER='1.1'
MANU='Canon'
PROD='BJC-3000'
SNUM='67H9gp'
TOPO=32
ISOC=0
INUM=1
ICLS1=07
ISCL1=01
Also Device-ID 104 für den USB2.0-Print und ID 105 für den BJC-3000. Ich hatte alle Druckerprozesse mit "remove" über das Script getrennt. Es gab also keine Gerätedateien und keinen printserv Prozess mehr.
Daraufhin wollte ich dann den Drucker mit der ID 105 (BJC-3000) neu hinzufügen. Der chronologische Ablauf ist von oben nach unten. Rot ist der Teil, den ich selbst angestoßen habe. Blau sind die beiden Prozesse, die in der Folge vom Kernel automatisch angestoßen wurden, ohne dass ich dies veranlasst hätte.
Code:
[COLOR="#FF0000"]root@fritz:/etc/hotplug# ./printer add /proc/bus/usb/001/105 1 1 1
Start Script (manuell)
Parameter: >add< >/proc/bus/usb/001/105< >1< >1< >1<
UNUM: 105
UPRT: 3
PORT: 9106
DEVICE: /proc/bus/usb/001/105
DEVID: USB-proc-bus-usb-001-105
HANDLE: /var/USB-proc-bus-usb-001-105-printer
passeeren UNUM_105/UPRT_3/PORT_9106
mknod -m 666 /dev/usb_prntsvr-105.0 c 180 0[/COLOR]
[COLOR="#0000FF"]Start Script (automatisch)
Parameter: >remove< >/proc/bus/usb/001/104< >1< >< ><
UNUM: 104
UPRT: 0
PORT: 9100
DEVICE: /proc/bus/usb/001/104
DEVID: USB-proc-bus-usb-001-104
HANDLE: /var/USB-proc-bus-usb-001-104-printer
passeeren UNUM_104/UPRT_0/PORT_9100[/COLOR]
[COLOR="#FF0000"]/sbin/printserv -d /dev/usb_prntsvr-105.0 -p 9106 -c /dev/console
eventadd 153 # Fehler!!!
eventadd 150 9106
Ende Script UNUM_105/UPRT_3/PORT_9106
vrijgeven UNUM_105/UPRT_3/PORT_9106[/COLOR]
[COLOR="#0000FF"]Ende Script UNUM_104/UPRT_0/PORT_9100
vrijgeven UNUM_104/UPRT_0/PORT_9100
Start Script (automatisch)
Parameter: >add< >/proc/bus/usb/001/106< >1a86< >7584< >0<
UNUM: 106
UPRT: 2
PORT: 9104
DEVICE: /proc/bus/usb/001/106
DEVID: USB-proc-bus-usb-001-106
HANDLE: /var/USB-proc-bus-usb-001-106-printer
passeeren UNUM_106/UPRT_2/PORT_9104
mknod -m 666 /dev/usb_prntsvr-106.1 c 180 1
/sbin/printserv -d /dev/usb_prntsvr-106.1 -p 9104 -c /dev/console
eventadd 150 9104
Ende Script UNUM_106/UPRT_2/PORT_9104
vrijgeven UNUM_106/UPRT_2/PORT_9104[/COLOR]
Obwohl ich eigentlich den Canon-Drucker /proc/bus/usb/001/105 auf USB3/Port9106 manuell hinzufügen wollte, wurde stattdessen der Laserdrucker auf USB2/Port9104 mit der DEV-ID 104 entfernt und mit einer neuen DEV-ID 106 gestartet. Erreichbar ist danach auf Port 9104 nicht der Laserdrucker, sondern der Canon-Drucker. Das zuvor vom Script schon erzeugte Node-File für den Canon-Drucker (mknod -m 666 /dev/usb_prntsvr-105.0 c 180 0) bleibt auch erhalten, obwohl der Start des Printservers für diesen Drucker mit einem Fehler beendet wurde. Wenn der Printserver für den Drucker nicht gestartet werden konnte, sollte das Node-File vorzugsweise entfernt werden. Aber das ist nicht das Problem.
Danach sieht lsusb dann so aus:
Code:
BUS=001
DEV=106
VID=1a86
PID=7584
CLS=00
SCL=00
SPEED='full'
VER='1.1'
PROD='USB2.0-Print '
TOPO=22
ISOC=0
INUM=1
ICLS1=07
ISCL1=01
BUS=001
DEV=105
VID=04a9
PID=1051
CLS=00
SCL=00
SPEED='full'
VER='1.1'
MANU='Canon'
PROD='BJC-3000'
SNUM='67H9gp'
TOPO=32
ISOC=0
INUM=1
ICLS1=07
ISCL1=01
Der Drucker am niedrigeren USB-Port hat nun die höhere ID. Warum der Drucker mit ID 104 (USB2.0-Print) in dem Moment entfernt wurde, als mknod für den Drucker mit der ID 105 (BJC-3000) aufgerufen wurde, bleibt auf den ersten Blick ein Rätsel. Eine Erklärung könnte aber sein, dass der Kernel intern (wie du Anfangs sagtest) die Node 0 für den Drucker 104 (USB2.0-Print) reserviert hatte und ne Krise kriegte, als ich den Drucker 105 (BJC-3000), der eigentlich zur Node 1 gehörte, der Node 0 zuordnen wollte. Danach ist dann unter Port 9104 (der der Node 1 zugeordnet wurde) der Drucker mit ID 105 (BJC-3000) erreichbar, weil dieser ja von Anfang an die Node 1 hatte.
Das stützt alles die Annahme, dass der Kernel seine Nodes intern zuordnet und das Script diese dann erraten muss. Dann verstehe ich allerdings nicht, warum der Kernel nicht immer auch die Scripte in der Reihenfolge startet, in der er die Nodes an die Drucker vergeben hat! Und das tut er definitiv nicht, das belegen meine Protokolle zweifelsfrei. Sonst könnte es ja auch nicht den Fehler mit der Vertauschung geben.
Konkret: Der Kernel vergibt z.B. die Node 0 an Drucker DEV:100 an USB2 und die Node 1 an den Drucker DEV:101 an USB3. Aber er startet das Script zuerst für DEV:101 und danach für DEV:100. Und dann kommt es zur Vertauschung. Hier ein Protokoll so einer Vertauschung:
Code:
[COLOR="#FF0000"]Start Script 1[/COLOR]
[COLOR="#0000FF"]Start Script 2[/COLOR]
[COLOR="#FF0000"]Parameter: >add< >/proc/bus/usb/001/101< >04a9< >1051< >0<
UNUM: 101
UPRT: 3
PORT: 9106
DEVICE: /proc/bus/usb/001/101
DEVID: USB-proc-bus-usb-001-101
HANDLE: /var/USB-proc-bus-usb-001-101-printer
passeeren UNUM_101/UPRT_3/PORT_9106
mknod -m 666 /dev/usb_prntsvr-101.0 c 180 0[/COLOR]
[COLOR="#0000FF"]Parameter: >add< >/proc/bus/usb/001/100< >1a86< >7584< >0<
UNUM: 100
UPRT: 2
PORT: 9104
DEVICE: /proc/bus/usb/001/100
DEVID: USB-proc-bus-usb-001-100
HANDLE: /var/USB-proc-bus-usb-001-100-printer
passeeren UNUM_100/UPRT_2/PORT_9104[/COLOR]
[COLOR="#FF0000"]/sbin/printserv -d /dev/usb_prntsvr-101.0 -p 9106 -c /dev/console
eventadd 150 9106
Ende Script UNUM_101/UPRT_3/PORT_9106
vrijgeven UNUM_101/UPRT_3/PORT_9106[/COLOR]
[COLOR="#0000FF"]mknod -m 666 /dev/usb_prntsvr-100.1 c 180 1
/sbin/printserv -d /dev/usb_prntsvr-100.1 -p 9104 -c /dev/console
eventadd 150 9104
Ende Script UNUM_100/UPRT_2/PORT_9104
vrijgeven UNUM_100/UPRT_2/PORT_9104[/COLOR]
Da haben wir beide uns missverständlich ausgedrückt. Wir sollten immer dazu schreiben, WER die Minor-Number nun vergeben hat. Der Kernel (intern) oder das Script (explizit) durch mknod. Mein sleep funktioniert, wenn die Minor-Nummern vom Kernel immer in der Reihenfolge vergeben werden, in der auch die physikalischen USB-Ports sortiert sind. Sollten die Minor-Nummern allerdings eher in der Reihenfolge vergeben werden, wie die DEV-IDs vergeben wurden, hilft das Script nicht. Dann müsste die Startreihenfolge von den DEV-IDs abhängen und die kann ich nicht direkt heranziehen, um mit sleep zu verzögern. Da müsste man dann etwas tricksen.Damit garantierst Du, dass der Hauptteil vom Skript für die niedrigere Portnummer zuerst ausgeführt wird. Das Skript wird daraufhin für den niedrigeren Port die Minor Nummer 0 verwenden. Du schreibst aber ein paar Sätze weiter oben, dass es völlig zufällig und beliebig zu sein scheint, welche Minor nun letztlich welchem USB-Port zugeordnet wird. Somit ist es nicht wirklich sicher, dass die Zuordnung nachher auch passt. Wenn die Minor Nummer 0 für den Drucker am zweiten Port zugeteilt wurde, wird das Skript trotzdem diese mit dem niedrigeren TCP Port verbinden.
Ich werde das durch Tests nochmal verifizieren. Aber bisher sieht es so aus, als würden die Nodes vom Kernel immer in der Reihenfolge der physikalischen USB-Ports vergeben. Allerdings nur beim Starten des Routers oder Einstecken des Hubs. Umstecken der Drucker im laufenden Betrieb ist mit dieser Topologie wegen der den physikalischen USB-Ports fest zugeordneten TCP-Ports eh strengstens verboten.
Ergänzung: Ich habe den Hub jetzt 20 Mal aus- und eingesteckt. Es hat immer funtkioniert, obwohl laut Protokoll in etwa 50% der Fälle das Script zuerst mit der höheren und danach erst mit der niedrigeren Device-ID gestartet wurde. Sonst kam es dann immer zu Vertauschungen. Seit dem sleep nicht mehr. Das deutet also darauf hin, dass meine Annahme korrekt war. Ich werde jetzt ein neues Image bauen und das sleep in mein Printer-Patchfile einarbeiten.
Zuletzt bearbeitet: