Also die Minor-Nummer ($MINOR) wird doch für mknod benutzt, also zum Anlegen einer Device-Node. Dabei nimmt das Script die erste unbelegte Zahl von 0 beginnend bis maximal 14.
Genau, die Minor Nummer wird "nur" für mknod verwendet, und für den Dateinamen, der an printserv übergeben wird.
Also wird meinen beiden Druckern per Zufall entweder /dev/usb/lp0 oder /dev/usb/lp1 zugeordnet, um bei diesem Beispiel zu bleiben. Der konkrete Name (lp0 oder usb_prntsvr-0xx.0) ist, wie du schon sagtest, dabei egal. Wenn die Ausgabe tatsächlich nur von der Minor-Number abhängt, warum startet man dann den Printserver-Task (/sbin/printserv) unter Angabe der Node und des zugehörigen TCP-Ports? Er leitet doch eh immer die Daten von Port 9104 an Node 0 weiter, egal welche Node man bei -d angibt (habe ich getestet). Da könnte man die Node auch weglassen.
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? Oder warum macht sich das Skript die Mühe, zwei unterschiedliche Gerätedateien zu erstellen? Und wenn es egal ist, was man bei -d angibt, versuche es doch mal mit /dev/console.
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? Da AVM das Programm nicht dafür ausgelegt hat, mehrere Drucker gleichzeitig anzusprechen, ist dort sicher keine Suche nach dem passenden Drucker eingebaut.
Ich habe das remove und add mittlerweile mehr als 10 mal in unterschiedlicher Reihenfolge, also mit unterschiedlichen Nodes ($MINOR) für die Drucker manuell durchgeführt und es hat in manchen Fällen jedes Mal funktioniert, in anderen wiederum nicht! Es ist kein System erkennbar, wann es geht und wann nicht.
In manchen Fällen geht es jedes Mal, und in anderen Fällen nicht. Mit anderen Worten, es funktioniert nicht jedes Mal.
Und es ist tatsächlich so, dass die Reihenfolge des Anlegens der Node-Files mit mknod die entscheidende Rolle spielt. MINOR Number 0 ist immer der Drucker an USB2 und MINOR Number 1 immer der an USB3.
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.
Ich finde es schon etwas kurios, dass es eine Art "feste Verdrahtung" der Minor-Numbern mit den USB-Ports gibt. Und zwar deshalb, weil die Number 0 nur in meinem Fall für USB-Port 2 steht, denn wenn ich den selben Drucker an USB-Port 1 anschließe, ist die Minor-Number 0 plötzlich fest mit diesem Port verknüpft. Und was ist, wenn ich nur Drucker an USB1 und USB3 habe? Ist dann Node 0 = USB1 und Node 1 = USB3?
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. Danach verbindest Du den anderen Drucker auf USB1, und weil die Nummer 0 schon belegt ist, bekommt dieser die Nummer 1. Wenn aber beide Drucker schon eingeschaltet und verbunden sind, wenn der Hub erkannt wird, werden die Geräte am Hub abgefragt. Wenn dies nacheinander passiert, bekommt der Drucker am niedrigeren USB Port die erste Nummer, also 0, und der andere Drucker bekommt dann die 1 (usw. bei mehreren). Wenn dies parallel passiert, dann bekommt der Drucker die 0, der zuerst geantwortet hat.
Und es ist kurioserweise auch völlig egal, mit welchem Parameter -d der Printserver gestartet wird. Entscheidend ist nur die MINOR Node-Number, mir der das Node-File unter /dev angelegt wurde.
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.
Das erklärt auch, warum der Drucker nicht mehr funktioniert, wenn ich ihn umstecke, z.B. von Port 3 auf Port 1. Dann hat der Drucker, der vorher die Node-Number 1 hatte, zwar weiterhin die Nummer 1, aber hängt nun an einem anderen USB-Port und kann daher nicht mehr angesprochen werden.
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.
Warum gibt man dem Drucker nicht einfach vorzugsweise die Minor-Number, die seinem USB-Port entspricht?
Weil an einem USB Hub auch noch weitere USB Hubs angeschlossen sein können. Das Skript für die Box kann es sich leisten, diesen Fall zu ignorieren, der Linux Kernel kann das nicht. An einem USB Host können 127 USB Geräte angeschlossen werden, und ein moderner PC hat zehn oder noch mehr USB Hosts. Es könnten theoretisch hunderte von USB Geräten an einem System hängen. Was nimmt man dann als die USB Port Nummer? Was, wenn der Drucker nicht am USB Hub hängt, sondern direkt am USB Host?
Logisch ist das alles nicht, zumal ich es ja auch schon hatte, dasss die Nummern-Verteilung "verkehrt herum" funktioniert hat, also Minor 0 zu USB3 und Minor 1 zu USB2. Es scheint völlig zufällig und beliebig zu sein, welche Minor nun letztlich welchem USB-Port zugeordnet wird.
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. Wenn das erste Gerät erkannt wird, kann der Kernel nicht wissen, ob danach keines mehr kommt, noch eines, oder noch hundert. Deswegen bekommen die Geräte jeweils die nächste freie Nummer.
Wie auch immer, ich kam auf die geniale wie auch einfache Idee, einfach Wartezeiten in das Script einzubauen, die abhängig vom USB-Port sind. Das garantiert, dass das Script immer in der Reihenfolge der physikalischen USB-Ports ausgeführt wird. Und seitdem funktioniert es endlich einwandfrei! Ich habe nur ein Sleep dazu eingefügt:
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.
Eine Sekunde reicht völlig, um das Script durchlaufen zu lassen. Im Prinzip könnte man damit sogar die Semaphore abschaffen. Und eine maximale Wartezeit von 15 Sekunden, wenn der Drucker an USB-Port 15 hängt, ist auch akzeptabel.
Bei zwei Druckern muss noch nicht einmal das Skript in 1 Sekunde durchgelaufen sein, es reicht, wenn es genug Zeit hat, die Semaphore zu sperren. Ich kenne außerdem keinen USB Hub mit mehr als 4 Ports und weiß auch nicht, ob die Spezifikation das zulässt.
USB Hubs mit 7 Anschlüssen bestehen aus zwei Hubs zu vier Anschlüssen, an einen der Anschlüsse des ersten Hubs ist intern der zweite Hub verbunden. Man hat folglich drei freie Anschlüsse am ersten Hub und vier freie Anschlüsse am zweiten Hub. Deswegen auch die eher ungewöhnliche Zahl von sieben Anschlüssen.