Mehrere Drucker, printserv-Prozesse und semaphore-Problem

Ich finde es recht gewagt, in einem international verwendeten Open-Source oder GPL-Projekt andere Bezeichnungen als englische zu verwenden.
Die AVM Firmware ist weder international noch Open-Source. Und die niederländischen Ausdrücke kann man als Fachbegriffe sehen, während zum Beispiel "free" statt "vrijgeven" eher mit der Funktion zum Freigeben von Speicher in Verbindung gebracht würde.
Mir war auch vollkommen neu, dass man im Shell-Script mit "# includes" einbetten kann. Bisher dachte ich, dass das nur mit "source" geht und es sich bei "# includes" lediglich um einen Kommentar handelt. Auf der Fritzbox ist offenbar alles etwas anders.
Die Shell der Fritzbox ist eine ganz normale Shell, da ist nichts anders als bei anderen Systemen. Alle Zeilen, die mit '#' anfangen, sind tatsächlich Kommentare. Für das Include wird der Operator '.' verwendet. Bash kennt dafür auch das Kommando 'source', die ursprüngliche Bourne Shell und POSIX aber nicht. Die Zeile, die das Einlesen übernimmt, ist diese:
Code:
test -f /etc/hotplug/rc.usbsema && . /etc/hotplug/rc.usbsema


Ich tendiere daher derzeit dazu, Freetz wieder den Rücken zu kehren und auf speed2fritz zurückzusatteln.
Mit anderen Worten, es lohnt sich nicht, dem Problem weiter nachzugehen.
Das deutet darauf hin, dass da noch jemand anderes rein schreibt. Vielleicht irgendein anderes Fritzbox-Script?
/sbin/printserv schreibt auf /var/log/printer_status.

Die Protokolle sahen nach dem Neustart genauso aus wie zuvor, mit einer einzigen Ausnahme:

Code:
root@fritz:/var/mod/root# cat /var/log/printer_id
:       003: USB USB2.0-Print  (Port 9104)      004: Canon BJC-3000 (Port 9106)

Im Grunde ist das natürlich auch richtig, aber es fällt auf, dass die Reihenfolge der Drucker hier anders ist als oben. Vielleicht ist das ein Hinweis auf das Problem...

Vermutlich hat es mit der Reihenfolge zu tun.
Wenn Du sagst "im Grunde richtig", heißt das dann, dass die Zuordnung von Drucker auf Ports korrekt angezeigt wird und trotzdem die Ausgabe auf den falschen Drucker kommt?

Leider zeigt das lsusb den Wert TOPO= nur dann an, wenn man es auch mit der Option -t aufruft. Wir bräuchten also den Inhalt von cat /proc/bus/usb/devices und von lsusb -t von beiden Fällen.
Der Wert von TOPO wird verwendet, um die Portnummer zu bestimmen, an der der Drucker hängt.
 
1. Wenn du die Box neu startest, funktionieren die Drucker nach dem Neustart korrekt?
Meist ja. Aber ich benutze diese Freetz-Version für mehrere Drucker auch erst seit einigen Tagen. Seitdem hatte ich es zweimal, dass die Drucker vertauscht waren. Ich vermute ganz stark (bin mir aber nicht 100% sicher), dass die richtige (oder auch falsche) Zuordnung der Drucker grundsätzlich beim Starten der Box geschieht und dann so erhalten bleibt bis zum nächsten Neustart. Ob die Zuordnung nach dem Start korrekt oder falsch ist, ist nach meinem Dafürhalten reiner Zufall. Bisher habe ich die Box noch nicht so oft neu gestartet, aber ich würde sagen, dass die Zuordnung der Drucker in etwa 20-30% der Fälle falsch ist.

2. Ist die Zuordnung nach einem Neustart immer gleich oder kann es da auch schon vorkommen, dass die Drucker nicht immer die gleiche id haben?
Die Drucker haben nicht immer die gleiche ID (siehe oben die verschiedenen Inhalte von /var/log/printer_id). Aber sie haben laut dieser Datei und laut der Benutzeroberfläche der Fritzbox immer die scheinbar korrekte Port-Zuordnung. Doch wird im Fehlerfall die angegebene Portzuordnung gar nicht verwendet, sondern eine vertauschte.

3. Nach einer Weile sind die Zuordnungen dann vertauscht? Kannst du das im Webinterface, in cat /proc/bus/usb/devices oder in der /var/log/printer_id an einer Änderung festmachen? Muss ja irgendwo ersichtlich sein, dass sich die Zuordnung verändert hat?
Ich glaube nicht, dass die Zuordnungen erst nach einer Weile vertauscht sind. Wenn sie vertauscht sind, dann schon direkt nach dem Booten der Box. Der Fehler in der Zuordnung kann weder in /proc/bus/usb/devices noch in /var/log/printer_id festgemacht werden. In beiden Dateien wird die richtige Zuordnung angezeigt. Benutzt wird aber im Fehlerfall definitiv eine andere Zuordnung! Dass die Zuordnung falsch ist, ist zumindest in diesen Dateien nicht ersichtlich.
 
Die AVM Firmware ist weder international noch Open-Source.
Ich schrieb aber auch "Open Source oder GPL"! Und wenn ich nicht völlig blöde bin, steht die Firmware der Fritzbox unter der GPL. Und wenn dem so ist, ist sie potenziell auch automatisch in einem internationalen Umfeld angesiedelt, wenn sie international verbreitet ist. Aber wir müssen uns nicht um des Kaisers Bart streiten. free würde ich auch nicht verwenden, aber z.B. etwas aussagekräftiges wie z.B. free_sema oder fsema.

Die Zeile, die das Einlesen übernimmt, ist diese:
Code:
test -f /etc/hotplug/rc.usbsema && . /etc/hotplug/rc.usbsema
Erstmal ganz herzlichen Dank für deine Erklärung!

Oh Mann! Das ist echt mächtig kryptisch. Zumal man das Leerzeichen zwischen dem Punkt und dem Slash extrem leicht übersehen kann. Und "&&" bzw. "||" (in einer logischen Abfrage!) als Ausführungs-Symbole für den Fall, dass die Aussage wahr bzw. falsch ist, ist auch extrem gruselig, zumal diese eigentlich fest für eine logische UND bzw. ODER Verknüpfung reserviert sind. Das tut ja richtig weh. :-/ So etwas zu verwenden ist kühn, zumal wenn es sowas wie if, else und fi gibt.

Mit anderen Worten, es lohnt sich nicht, dem Problem weiter nachzugehen.
Nur dann, wenn das Problem nicht gelöst werden kann. Sonst schon. Die Möglichkeit, zwei Drucker zu verwenden, hat durchaus ihren Charme. Außerdem dürfte eine Lösung des Problems wohl auch für andere hilfreich sein, denn ich kann mir nicht vorstellen, dass ich das einzige "Problemkind" bin.

Wenn Du sagst "im Grunde richtig", heißt das dann, dass die Zuordnung von Drucker auf Ports korrekt angezeigt wird und trotzdem die Ausgabe auf den falschen Drucker kommt?
GENAU SO ist es!

Leider zeigt das lsusb den Wert TOPO= nur dann an, wenn man es auch mit der Option -t aufruft. Wir bräuchten also den Inhalt von cat /proc/bus/usb/devices und von lsusb -t von beiden Fällen.
Der Wert von TOPO wird verwendet, um die Portnummer zu bestimmen, an der der Drucker hängt.
Tja, das wusste ich nicht. /proc/bus/usb/devices ist aber in beiden Fällen völlig identisch. Das habe ich schon überprüft und ein Compare gemacht. Wie die Ausgabe von "lsusb -t" ist, weiß ich nicht. Das werde ich nachholen, sobald der Fehler wieder auftritt.
 
Zuletzt bearbeitet:
Wenn die Zuordnung richtig angezeigt wird, tatsächlich aber falsch ist, solltest Du auch noch lsof mit auf die Box bringen (nicht unbedingt ins Flash), um festzustellen, welcher printserv welchen Port offen hat. Denk außerdem an #21 wegen lsusb -t und TOPO.
 
Vielen Dank! Werde ich alles tun. Ich werde nachher mal durch eine Reihe von Neustarts das Problem zu reproduzieren versuchen.
 
[..], solltest Du auch noch lsof mit auf die Box bringen (nicht unbedingt ins Flash)
Hast du ne Ahnung, ob ich das Binary irgendwo finde? Ich habe ewig rumgesucht - ohne Erfolg. Möchte nicht unbedingt nur dafür ein neues Image bauen und flashen...
 
Im menuconfig lsof unter Debug Packages auswählen, make eingeben und dann das Binary aus packages/target.../lsof/.../lsof per scp/ftp/nas auf die Box kopieren...
 
Ich schrieb aber auch "Open Source oder GPL"
Mit Open Source meinte ich alles, wo die Quellen verfügbar sind.
Die Firmware ist auch nicht GPL. Die Firmware enthält Komponenten, die unter der GPL stehen, sowie andere Open Source Komponenten, die nicht unter der GPL stehen. Sie enthält außerdem noch einiges an AVM Programmen. Für die GPL Programme gibt AVM (meistens verspätet, teils unvollständig) die Quellen heraus. Für OpenSSL, das nicht unter der GPL steht, gibt es von AVM keine Quellen. AVM hat auch schon mal vor Gericht argumentiert, dass das Verändern der Firmware ihre Urheberrechte verletzt. Kurz gesagt, die Firmware als ganzes ist nicht GPL, und hier geht es um ein Skript von AVM.

Tja, das wusste ich nicht. /proc/bus/usb/devices ist aber in beiden Fällen völlig identisch. Das habe ich schon überprüft und ein Compare gemacht. Wie die Ausgabe von "lsusb -t" ist, weiß ich nicht. Das werde ich nachholen, sobald der Fehler wieder auftritt.
Ich wusste das mit -t vorher auch nicht, sonst hätte ich es gleich geschrieben. Ich weiß nicht, was der Sinn davon ist, TOPO nicht gleich auszugeben, vielleicht braucht es einige Millisekunden länger.
Wenn aber /proc/bus/usb/devices in beiden Fällen Byte für Byte identisch ist, wird auch die Ausgabe von lsusb die gleiche sein.

Ich denke, Du kannst Dir auch lsof erstmal sparen.
Versuche mal die Vertauschung zu reproduzieren und schau dann man nach
Code:
ls -l /dev/usb_prntsvr*
ps | grep printserv
Vermutlich reicht es, den USB-Hub von der Box zu trennen und wieder einzustecken, um das neu Erkennen der Drucker auszulösen, sonst eben Reboots der Box.

Das Skript legt einfach nacheinander lp0, lp1 usw. an, weiß aber nicht, wie diese tatsächlich zugeordnet sind. Wenn der Kernel also in kurzem zeitlichem Abstand zwei neue Drucker erkennt, wird das Skript für beide gestartet. Wenn aber aus irgend einem Grund das Skript für den zweiten Drucker zuerst ausgeführt wird, dann bekommt dieser zweite Drucker lp0 statt lp1 und die Zuordnung ist vertauscht. Daher kann man froh sein, dass es in der überwiegenden Zahl der Fälle funktioniert hat.
 
Die Firmware enthält Komponenten, die unter der GPL stehen, sowie andere Open Source Komponenten, die nicht unter der GPL stehen.
Sicher, dass der Kernel und seine Module nicht unter GPL stehen, ist nachvollziehbar. Das ist bei Android ja auch nicht anders. Aber die Nutzung von GPL-Komponenten zur Erstellung von Komponenten, die nicht der GPL unterliegen, ist ein Unterlaufen der Lizenzpolitik, eine Urheberrechtsverletzung und damit ebenfalls illegal. Ich finde, dies wird in der Rechtsprechung viel zu wenig gewürdigt. Bei der Klage von AVM wurde dies aber gewürdigt und die Klage gegen AVM entschieden, womit sich unsere Aktivitäten bei der Modifikation der Firmware absolut in der Legalität bewegen. Dieser Artikel geht einem da runter wie Öl und man könnte täglich ein Gläschen Sekt drauf trinken. ;)

Dass AVM derart kryptische Skripte verwendet, wirft kein gutes Licht auf die Grundqualifikation der Entwickler. Die einzige Entschuldigung könnte sein, dass bei den älteren Fritzbox-Modellen der Speicher noch knapp war und man die Skripte so platzsparend wie möglich programmieren wollte. Wobei wir dann wieder bei den "Zuse-Zeiten" angelangt wären... :)

Sodele, nun aber zum Thema: Die Reproduktion des Fehlers ist viel einfacher als gedacht. In 50% der Fälle wird die Zuordnung falsch durchgeführt. Ich wundere mich daher SEHR, dass das noch niemandem bisher aufgefallen ist! Ich habe auch die entsprechenden Files erzeugt. Ich hatte lsof schon compiliert und auf die Box gepackt, bevor ich deine Message gelesen hatte. Ich sende die Ausgaben von lsof daher im Anhang gepackt, da sie rund 260 kb groß sind. Die Dateien mit der Endung "ok" sind für den Fall, dass die Drucker korrekt zugeordnet waren, die Endung "false" steht für den umgekehrten Fall.

Code:
ls -l /dev/usb_prntsvr*
ps | grep printserv

ergibt im korrekten Fall:

Code:
root@fritz:/var/mod/root# ls -l /dev/usb_prntsvr*
crw-rw-rw-    1 root     root      180,   0 Mar  3 02:31 /dev/usb_prntsvr-029.0
crw-rw-rw-    1 root     root      180,   1 Mar  3 02:31 /dev/usb_prntsvr-030.1
root@fritz:/var/mod/root# ps | grep printserv
 7436 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-029.0 -p 9104 -c
 7437 root       764 S N  /sbin/printserv -d /dev/usb_prntsvr-029.0 -p 9104 -c
 7438 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-029.0 -p 9104 -c
 7440 root       760 S N  /sbin/printserv -d /dev/usb_prntsvr-029.0 -p 9104 -c
 7487 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-030.1 -p 9106 -c
 7488 root       764 S N  /sbin/printserv -d /dev/usb_prntsvr-030.1 -p 9106 -c
 7489 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-030.1 -p 9106 -c
 7491 root       760 S N  /sbin/printserv -d /dev/usb_prntsvr-030.1 -p 9106 -c
 7556 root      1064 S    {busybox} grep printserv
root@fritz:/var/mod/root#

und im Fehlerfall:

Code:
root@fritz:/var/mod/root# ls -l /dev/usb_prntsvr*
crw-rw-rw-    1 root     root      180,   1 Mar  3 02:29 /dev/usb_prntsvr-020.1
crw-rw-rw-    1 root     root      180,   0 Mar  3 02:29 /dev/usb_prntsvr-021.0
root@fritz:/var/mod/root# ps | grep printserv
 5936 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-021.0 -p 9106 -c
 5937 root       764 S N  /sbin/printserv -d /dev/usb_prntsvr-021.0 -p 9106 -c
 5938 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-021.0 -p 9106 -c
 5954 root       760 S N  /sbin/printserv -d /dev/usb_prntsvr-021.0 -p 9106 -c
 5995 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-020.1 -p 9104 -c
 5996 root       764 S N  /sbin/printserv -d /dev/usb_prntsvr-020.1 -p 9104 -c
 5997 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-020.1 -p 9104 -c
 5999 root       760 S N  /sbin/printserv -d /dev/usb_prntsvr-020.1 -p 9104 -c
 6066 root      1064 S    {busybox} grep printserv
root@fritz:/var/mod/root#

Vermutlich reicht es, den USB-Hub von der Box zu trennen und wieder einzustecken, um das neu Erkennen der Drucker auszulösen, sonst eben Reboots der Box.

Ja, das neu Anschließen funktioniert. Aber die Gefahr besteht, dass die Box (sei es durch Stromausfall oder ein internes Problem) unbeaufsichtigt neu startet. Werden die Drucker in dem Fall falsch zugeordnet, gibt es ein erhebliches Problem. Ich möchte danach nicht eine leere Tonerpatrone wechseln und 200 Blatt Papier in den Mülleimer werfen müssen.

Das Skript legt einfach nacheinander lp0, lp1 usw. an, weiß aber nicht, wie diese tatsächlich zugeordnet sind.
Hüstel. Und es gibt Leute, die eine Zuordnung per Zufallsprinzip okay finden?

Daher kann man froh sein, dass es in der überwiegenden Zahl der Fälle funktioniert hat.
Bei mir sind es leider nur genau 50%. Da die Drucker über einen Hub angeschlossen sind, werden sie beide immer ziemlich gleichzeitig erkannt. Ich denke, eine Nachbesserung ist an diesem Skript ganz dringend erforderlich. Was ich auch nicht verstehe: Wieso wird in /var/log/printer_id immer die korrekte Port-Zuordnung angezeigt, diese aber nicht so umgesetzt wie angezeigt? Wenn sie korrekt angezeigt wird, müsste es doch auch möglich sein, diese so umzusetzen?! Zur Not anhand von USB VID und PID. Außerdem ist TOPO auch in beiden Fällen identisch, im Fehlerfall ebenso wie im korrekten Fall. Wenn TOPO also die Portnummer bestimmt, dürfte es den Fehler nicht geben.
 

Anhänge

  • multi_printer.zip
    23 KB · Aufrufe: 4
Zuletzt bearbeitet:
Sicher, dass der Kernel und seine Module nicht unter GPL stehen, ist nachvollziehbar.
Der Kernel steht unter der GPL, und dass AVM Module ohne Quelltext heraus gibt, die Inline Funktionen der Kernel Header nutzen, ist zumindest grenzwertig. Aber bisher hat noch keiner was dagegen getan.
Dass AVM derart kryptische Skripte verwendet, wirft kein gutes Licht auf die Grundqualifikation der Entwickler.
Genau, entweder glaubt AVM, was sie da gemacht haben ist so toll, dass es kein anderer haben soll, oder sie wollen nicht, dass man sieht, wie da geschludert wurde. Wobei ich an diesem Skript nichts besonders schlimm finde.

Sodele, nun aber zum Thema: Die Reproduktion des Fehlers ist viel einfacher als gedacht. In 50% der Fälle wird die Zuordnung falsch durchgeführt. Ich wundere mich daher SEHR, dass das noch niemandem bisher aufgefallen ist!
Ich vermute, dass es doch nicht so verbreitet ist, mehr als einen Drucker an die Box zu hängen. Wie schon geschrieben ist es eher Zufall, wenn es funktioniert, wobei ich vermute, dass es bei thimo regelmäßig funktioniert hat. Dies wäre zum Beispiel der Fall, wenn man nicht beide Drucker gleichzeitig einschaltet, sondern nur bei Bedarf, oder wenn der eine Drucker/Adapter regelmäßig langsamer reagiert als der andere und daher die Reihenfolge immer die gleiche ist.
Ich sende die Ausgaben von lsof daher im Anhang gepackt, da sie rund 260 kb groß sind.
Mich hätte nur die Ausgabe für die printserv Prozesse interessiert, und inzwischen hat sich das sowieso erledigt.

ergibt im korrekten Fall:
Code:
 7436 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-029.0 -p 9104 -c
 7487 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-030.1 -p 9106 -c
und im Fehlerfall:
Code:
 5936 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-021.0 -p 9106 -c
 5995 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-020.1 -p 9104 -c
Die Gerätenummer (.0 und .1 hinten) scheint in beiden Fällen korrekt zu sein, d.h. wenn ich Dich richtig verstanden habe, hättest Du im Fehlerfall auch Gerät 0 auf Port 9104 und nicht 9106 haben wollen. Was unterschiedlich ist, sind die dreistelligen Nummern davor.
Ja, das neu Anschließen funktioniert. Aber die Gefahr besteht, dass die Box (sei es durch Stromausfall oder ein internes Problem) unbeaufsichtigt neu startet.
Und es gibt Leute, die eine Zuordnung per Zufallsprinzip okay finden?
Damit war gemeint, zum Testen das Problem schneller reproduzieren zu können, also ohne jedes mal einen Reboot. Es war nicht gemeint, den Hub so oft zu trennen, bis die Zuordnung stimmt.
Vermutlich wird diese Konstellatioon nicht häufig verwendet, und beim Threadersteller hat sie vermutlich funktioniert.
Bei mir sind es leider nur genau 50%. Da die Drucker über einen Hub angeschlossen sind, werden sie beide immer ziemlich gleichzeitig erkannt. Ich denke, eine Nachbesserung ist an diesem Skript ganz dringend erforderlich. Was ich auch nicht verstehe: Wieso wird in /var/log/printer_id immer die korrekte Port-Zuordnung angezeigt, diese aber nicht so umgesetzt wie angezeigt? Wenn sie korrekt angezeigt wird, müsste es doch auch möglich sein, diese so umzusetzen?! Zur Not anhand von USB VID und PID. Außerdem ist TOPO auch in beiden Fällen identisch, im Fehlerfall ebenso wie im korrekten Fall. Wenn TOPO also die Portnummer bestimmt, dürfte es den Fehler nicht geben.
Das Problem ist nicht, über TOPO den korrekten Drucker zu finden, der Teil funktioniert anscheinend zuverlässig. Das Problem ist, dass das Skript einfach die nächste freie Gerätenummer sucht, ab Zeile 70 "Get next USB minor number...". Das funktioniert alles bestens, solange nicht zwei Drucker in undefinierter Reihenfolge gleichzeitig erkannt werden.
Das Skript wird anscheinend aufgerufen, wenn ein neues USB Gerät erkannt wird, nicht zwangsläufig ein Drucker. Ob es ein Drucker ist, wird erst in Zeile 61 überprüft. Erst wenn ein Drucker erkannt wurde, wird überhaupt das Modul usblp in Zeile 95 geladen, also sogar nachdem in Zeile 82 die Gerätedatei erstellt wurde.
Wie es aussieht, ist bei Dir die Zuordnung der Drucker zu lp0 und lp1 fest, zumindest in den beiden Beispielen. Unterschiedlich ist aber die Reihenfolge, in der die USB Geräte erkannt werden (020/021 und 029/030). Es kann aber auch sein, dass auch das nur zufällig bei beiden Beispielen gleich ist. Vielleicht ist auch die Zuordnung lp0/lp1 zu den Druckern zufällig, und wenn beides vertauscht ist, passt es wieder.

Kurz gesagt, wenn man will, das es zuverlässig funktioniert, darf man nicht einfach die nächste frei Nummer nehmen und hoffen, dass es funktioniert. Die Zuordnung der Drucker auf lp0/lp1 bekommt man aber frühestens heraus, nachdem das usblp Modul geladen ist. Es ist dann auch die Frage, ob man unbedingt das Modul usblp erst bei Bedarf laden und bei Nichtgebrauch wieder entfernen will. Auf jeden Fall müsste man das Event Handling ändern und irgendwo her die korrekte Zuordnung auslesen.
 
Es gibt übrigens noch viel verrücktere Dinge:

Ich habe jetzt mal testhalber die Drucker einzeln aus- und eingestöpselt. Wenn ich zuerst den Drucker an USB3 einstecke und dann den an USB2, stimmt die Zuordnung immer. Stecke ich aber zuerst den Drucker an USB2 ein und dann den an USB3, bleiben alle Druckaufträge nur in er Warteschlange hängen. Nichts wird mehr gedruckt. Ziehe ich dann den Drucker an USB3 ab, werden plötzlich wie von Geisterhand alle ausstehenden Aufträge an USB2 gedruckt. Normal ist das keinesfalls.

Nachdem ich mehrfach die Drucker abgezogen und eingesteckt hatte, ging übrigens irgendwann gar nichts mehr: Obwohl alle Drucker und Druckprozesse korrekt im System angezeigt wurden, blieben die Aufträge nur in der Warteschlange hängen. Oder sie wurden alternativ sofort versendet, kamen aber nie beim Drucker an. Momentan ist es so, dass ich die Drucker ein- und ausstöpseln kann wie ich will, die Prozesse im System immer korrekt angezeigt werden, aber überhaupt kein Drucken mehr möglich ist: Alles hängt nur in der Warteschlange. Und das, obwohl die printserv Prozesse korrekt angezeigt werden. Das Problem kann wohl nur durch einen Neustart der Box behoben werden. Insgesamt scheint mir diese Druckergeschichte mehr als nur ein wenig buggy und höchst unzuverlässig zu sein!
 
Das AVM printserv Programm ist nicht dafür ausgelegt, mehrere Drucker anzusprechen. Dies ist im Patch bzw. in der Diskussion dazu auch erwähnt, siehe Stelle stoppen mit SIGKILL statt SIGTERM. Wizu braucht es außerdem vier Threads, um ein paar Daten zu einem Drucker zu senden? Das sinnvollste wäre, das Programm durch ein eigenes zu ersetzen.
 
So, es fehlten noch ein paar Antworten:

Die Gerätenummer (.0 und .1 hinten) scheint in beiden Fällen korrekt zu sein, d.h. wenn ich Dich richtig verstanden habe, hättest Du im Fehlerfall auch Gerät 0 auf Port 9104 und nicht 9106 haben wollen. Was unterschiedlich ist, sind die dreistelligen Nummern davor.
Wenn die Geräte-ID 0 bzw. 1 eine feste Zuordnung zu einem physikalischen Drucker bezeichnet, sollte die selbe ID auch immer dem selben Port zugeordnet werden (logischerweise!).

Was ich aber nicht verstehe: Das Script erzeugt doch die Portnummern und ihre Zuordnung selbst, oder nicht? Wenn das Script die Zuordnung selbst bestimmen kann und die IDs der Drucker immer eindeutig sind (entweder durch die USB VID/PID (32 Bit) oder durch den Wert unter "TOPO"), sollte es doch eine Leichtigkeit sein, den richtigen Port immer explizit dem richtigen Drucker zuzuordnen?! Oder verstehe ich da etwas falsch?

Das Problem ist nicht, über TOPO den korrekten Drucker zu finden, der Teil funktioniert anscheinend zuverlässig. Das Problem ist, dass das Skript einfach die nächste freie Gerätenummer sucht, ab Zeile 70 "Get next USB minor number...". Das funktioniert alles bestens, solange nicht zwei Drucker in undefinierter Reihenfolge gleichzeitig erkannt werden.
Um an meinen obigen Satz anzuknüpfen: Dann müsste man eben nicht nur die nächste USB ID suchen, sondern auch nachschauen, welcher Drucker unter dieser ID hängt. Also erstmal alle Drucker mit ihren VID/PID- oder TOPO-Angaben zusammensuchen, dann (nach VID/PID oder TOPO) sortieren und in dieser Reihenfolge den Ports zuordnen. Dann sollte es doch funktionieren?! Leider bin ich nicht so fit im Scripting, dass ich das ohne größeren Aufwand selbst realisieren könnte.

Wie es aussieht, ist bei Dir die Zuordnung der Drucker zu lp0 und lp1 fest, zumindest in den beiden Beispielen. Unterschiedlich ist aber die Reihenfolge, in der die USB Geräte erkannt werden (020/021 und 029/030). Es kann aber auch sein, dass auch das nur zufällig bei beiden Beispielen gleich ist.
Zumindest die Angabe unter TOPO ist - soweit ich das bisher gesehen habe - immer die selbe bei jedem Drucker.

Auf jeden Fall müsste man das Event Handling ändern und irgendwo her die korrekte Zuordnung auslesen.
Aber "lsusb -t" funktioniert doch auch ohne das usblp Modul, oder? Dann könnte man doch VID/PID oder TOPO für die Zuordnung nehmen?!

Leider findet man auch nirgendwo Informationen darüber, was beim Aufruf des printer-scripts in den Parametern $1 bis $5 übergeben wird. Wüsste man das, könnte man das Script halbwegs verstehen oder auch debuggen... Hast du ne Ahnung, was $1 bis $5 sind?
 
Zuletzt bearbeitet:
Also ich habe mir das Script nun nochmal ganz intensiv angeschaut. Und ich bin der Auffassung, dass alles korrekt funktionieren müsste. Es passiert folgendes:

Als Parameter $2 wird das File für die technische Beschreibung des zu installierenden USB-Devices (hotplug path) übergeben. Bei mir:

/proc/bus/usb/001/003
/proc/bus/usb/001/004

Die Inhalte sind:

Code:
root@fritz:/dev# lsusb -s -t -h /proc/bus/usb/001/003
BUS=001
DEV=003
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

root@fritz:/dev# lsusb -s -t -h /proc/bus/usb/001/004
BUS=001
DEV=004
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

Aus den Informationen MANU, PROD und TOPO baut das Script am Ende auch die Infos für /var/log/printer_id zusammen. Wobei der physkalische USB-Port die erste Ziffer von TOPO ist (UPRT, ist bei mir dann 2 bzw. 3). Und aus diesem physikalischen USB-Port wird dann auch der Listen-Port für den Drucker gebaut: PORT=$((9100 + 2 * UPRT)). Zu deutsch: Es werden die systeminternen Hardware-Infos genommen, um den zum physikalischen USB-Port zugehörigen Drucker zu bestimmen! Deshalb wird die Zuordnung auch stets in der Fritzbox-Oberfläche richtig angegeben. Selbst dann, wenn sie eigentlich falsch ist.

Die Prozerdur "# Get next USB minor number..." hat nichts mit der Zuordnung des Ports zu tun. Diese dient nur dazu, die nächste, freie Minor-Number ($MINOR) für den Device-Node (mknod) zu erhalten, unter dem das File für den Drucker dann angelegt wird. Es hat nichts mit der Port-Zuordnung zu tun. Außerdem wird dabei auch getestet, ob mehr als 15 Drucker angeschlossen sind.

Ab "# Find device's strings..." wird dann nur noch die Info für /var/log/printer_id zusammengebaut. Das hat auch keine Wirkung auf die Port-Zuordnung.

Erst ab "# Starting printserver..." gehts wirklich um die Wurst. Da wird dann folgendes ausgeführt:

Code:
/sbin/printserv -d /dev/usb_prntsvr-$UNUM.$MINOR -p $PORT -c /dev/console;
Dies ergibt konkret:
/sbin/printserv -d /dev/usb_prntsvr-003.0 -p 9104 -c /dev/console
oder:
/sbin/printserv -d /dev/usb_prntsvr-004.1 -p 9106 -c /dev/console

$UNUM ist die Nummer aus dem als Parameter $2 übergebenen Hotplug-Path, der die physikalische Beschreibung des USB-Geräts (über lsusb) liefert. $MINOR ist eine im Grunde bedeutungslose Zahl, die nur die nächste, freie Datei-Nummer angibt. $PORT ist der ebenfalls über lsusb aus TOPO generierte TCP-Port, der daher unabdingbar(!) mit dem physikalischen USB-Port und dem dort angeschlossenen Drucker gekoppelt ist, weil er über lsusb aus dem hotplug path für den Drucker gelesen wurde. Zu Deutsch: Das Script KANN die Zuordnung nicht falsch machen! Dies ist technisch völlig ausgeschlossen.

Das kuriose ist ja auch, dass sowohl die über lsusb angezeigten Printer die korrekte USB-Portzuordnung haben, als auch die TCP-Listener für diese Drucker auf den richtigen Ports horchen, wie lsof und auch "ps w" zeigen. Das heißt, dass das Script alles vollkommen richtig gemacht hat. Trotzdem gehen die Daten an die falschen Drucker.

Nachdem die Zuordnung falsch war, habe ich mal per telnet in der Shell manuell über das printer-script mit "remove" die beiden Druckerprozesse gekillt und dann dann mit "add" die Drucker wieder hinzugefügt, aber ohne die Drucker vorher vom Hub abzustöpseln!!! Danach stimmte die Zuordnung wieder und die Daten gingen an die richtigen Drucker. Auch das zeigt, dass das Script korrekt arbeitet! Und was total irre ist: Sowohl vor meinem manuellen Eingriff, als auch danach zeigten "ps w", lsusb als auch lsof die gleichen Zuordnungs-Daten an. Das ist völlig gaga und für mich nicht mehr nachvollziehbar! Dann habe ich den Hub mal wieder ab- und angestöpselt und schon waren die Zuordnungen wieder verkehrt. Dann wieder manuell remove und add gemacht und schon funktionierte es wieder. Das Problem tritt also NUR auf, wenn die Scripte zu kurz nacheinander ausgeführt werden. Das deutet irgendwie stark auf ein Semaphoren-Problem oder ähnliches hin.
 
Zuletzt bearbeitet:
Wenn die Geräte-ID 0 bzw. 1 eine feste Zuordnung zu einem physikalischen Drucker bezeichnet, sollte die selbe ID auch immer dem selben Port zugeordnet werden (logischerweise!).
Das ist keine Geräte-Id, es ist die Device Minor Nummer. Wenn Du beide Drucker entfernst und dann zuerst irgend einen einsteckst, bekommt der die Nummer 0 und danach der nächste die Nummer 1, unabhängig vom Drucker. Ich gehe davon aus, dass das Skript zuverlässig funktioniert, wenn man die Drucker von Hand einschaltet oder in den Hub einsteckt.
Das Script erzeugt doch die Portnummern und ihre Zuordnung selbst, oder nicht? Wenn das Script die Zuordnung selbst bestimmen kann und die IDs der Drucker immer eindeutig sind (entweder durch die USB VID/PID (32 Bit) oder durch den Wert unter "TOPO"), sollte es doch eine Leichtigkeit sein, den richtigen Port immer explizit dem richtigen Drucker zuzuordnen?
Das Skript erkennt über TOPO den Port der USB Hubs und ordnet dem korrekt den richtigen TCP Port zu. Was es nicht richtig macht, und in der jetzigen Form auch nicht machen kann, ist die richtige Device Minor Nummer erraten, die der Drucker bekommen wird. Zumindest dann nicht, wenn beide Geräte gleichzeitig bekannt werden, also Boot der Box oder Einstecken des Hubs, und das Skript für beide Drucker gleichzeitig in undefinierter Reihenfolge aufgerufen wird. Selbst wenn Du noch eine Erkennung von VID/PID hinzufügen würdest, würde es das Problem nicht lösen, weil die Erkennung ja auch so schon über TOPO funktioniert. Hinzu käme, dass bei der Erkennung über VID/PID Konfiguration notwendig wäre, was im Moment nicht der Fall ist.
Dann müsste man eben nicht nur die nächste USB ID suchen, sondern auch nachschauen, welcher Drucker unter dieser ID hängt. Also erstmal alle Drucker mit ihren VID/PID- oder TOPO-Angaben zusammensuchen, dann (nach VID/PID oder TOPO) sortieren und in dieser Reihenfolge den Ports zuordnen. Dann sollte es doch funktionieren?! Leider bin ich nicht so fit im Scripting, dass ich das ohne größeren Aufwand selbst realisieren könnte.

Zumindest die Angabe unter TOPO ist - soweit ich das bisher gesehen habe - immer die selbe bei jedem Drucker.
Es wird eben nicht die nächste USB Id gesucht, sondern die nächste freie Device Minor Nummer. Und das wird sogar gemacht, bevor das Modul usblp geladen ist, und somit bevor die Device Minor Nummer überhaupt vergeben wird. Die Idee, alle Drucker aufzulisten und nach VID/PID oder TOPO oder was auch immer zu sortieren, führt auch nicht weiter, um Gegenteil. Mal angenommen, Du schaltest einen Drucker zuerst ein. Er ist somit der erste Drucker, sortiert nach VID/PID oder TOPO oder was auch immer und bekäme den ersten Port. Dann erst schaltest Du den zweiten Drucker ein. Dieser kommt nach der gewählten Sortierung vorher, daher sollte er den ersten TCP Port haben. Was jetzt? TCP Ports neu zuordnen, und plötzlich ist der gleiche TCP Port mit einem anderen Drucker verbunden? In jedem Fall ist die Zuordnung der TCP Ports zu den Druckern davon abhängig, welche und in welcher Reihenfolge eingeschaltet wurden.
Du könntest jetzt sagen, das interessiert Dich nicht, bei Dir sind immer beide eingeschaltet. Aber es wird immer einer von beiden zuerst erkannt, und nicht immer der gleiche, deswegen hast Du ja hier das Problem.

Wie schon geschrieben, ist das Problem nicht lsusb oder TOPO, sondern die Device Minor Nummer. Und diese gibt es erst, wenn das Modul usblp geladen ist, also beim ersten Drucker erst nach dem Start des Skripts, wenn das Modul geladen wird. Außerdem müsste man noch einen Weg finden, tatsächlich die richtige Nummer zu finden.
Leider findet man auch nirgendwo Informationen darüber, was beim Aufruf des printer-scripts in den Parametern $1 bis $5 übergeben wird. Wüsste man das, könnte man das Script halbwegs verstehen oder auch debuggen... Hast du ne Ahnung, was $1 bis $5 sind?
Das lässt sich recht einfach herausfinden. Mache eine Kopie des Skripts und mounte diese dann mit der Option bind über das ursprüngliche Skript. Dann kannst Du die Kopie ändern, insbesondere also die Parameter in eine Datei schreiben. Dann musst Du nur noch den Hub aus/einstecken und Du solltest die Parameter in der Datei finden. Denke daran, dass das Skript mehrfach aufgerufen wird, also entweder an eine Datei anhängen oder in verschiedene Dateien schreiben.
Wenn Du schon dabei bist, gib nicht nur die Parameter, sondern auch das Environment aus.
 
Bitte entschuldige! Ich hatte gestern meine erste Nachricht geschrieben, als ich mich noch nicht intensiver mit dem Script auseinandergesetzt hatte. Ich hätte diese erste Nachricht lieber bearbeiten sollen, statt eine neue Nachricht zu schreiben! Was du geschrieben hast, hatte ich dann später auch schon selbst festgestellt.

Aber: An der Device Minor Number liegt es nicht, ob der Drucker funktioniert oder nicht!

Schau dir mal folgendes an (ich habe bei "ps w" die irrelevanten Zeilen gelöscht):

Code:
root@fritz:/var/mod/root# ps w
  PID USER       VSZ STAT COMMAND
11849 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-044.1 -p 9106 -c /dev/console
11850 root       764 S N  /sbin/printserv -d /dev/usb_prntsvr-044.1 -p 9106 -c /dev/console
11851 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-044.1 -p 9106 -c /dev/console
11853 root       760 S N  /sbin/printserv -d /dev/usb_prntsvr-044.1 -p 9106 -c /dev/console
12144 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-045.0 -p 9104 -c /dev/console
12145 root       764 S N  /sbin/printserv -d /dev/usb_prntsvr-045.0 -p 9104 -c /dev/console
12146 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-045.0 -p 9104 -c /dev/console
12147 root       760 S N  /sbin/printserv -d /dev/usb_prntsvr-045.0 -p 9104 -c /dev/console
root@fritz:/var/mod/root# /etc/hotplug/printer remove /proc/bus/usb/001/044 1 1
sh: can't kill pid 12201: No such process
root@fritz:/var/mod/root# /etc/hotplug/printer remove /proc/bus/usb/001/045 1 1
sh: can't kill pid 12218: No such process
root@fritz:/var/mod/root# lsusb -t -s -h /proc/bus/usb/001/044
BUS=001
DEV=044
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

root@fritz:/var/mod/root# lsusb -t -s -h /proc/bus/usb/001/045
BUS=001
DEV=045
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

root@fritz:/var/mod/root# /etc/hotplug/printer add /proc/bus/usb/001/044 1 1
root@fritz:/var/mod/root# /etc/hotplug/printer add /proc/bus/usb/001/045 1 1
root@fritz:/var/mod/root# ps w
  PID USER       VSZ STAT COMMAND
12321 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-044.0 -p 9106 -c /dev/console
12322 root       764 S N  /sbin/printserv -d /dev/usb_prntsvr-044.0 -p 9106 -c /dev/console
12323 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-044.0 -p 9106 -c /dev/console
12324 root       760 S N  /sbin/printserv -d /dev/usb_prntsvr-044.0 -p 9106 -c /dev/console
12377 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-045.1 -p 9104 -c /dev/console
12378 root       764 S N  /sbin/printserv -d /dev/usb_prntsvr-045.1 -p 9104 -c /dev/console
12379 root       756 S N  /sbin/printserv -d /dev/usb_prntsvr-045.1 -p 9104 -c /dev/console
12380 root       760 S N  /sbin/printserv -d /dev/usb_prntsvr-045.1 -p 9104 -c /dev/console
root@fritz:/var/mod/root#

Einmal hat der BJC-3000 die Minor Number 0 und einmal die 1 und in beiden Fällen funktioniert er korrekt!

Es hat also damit nichts zu tun, sondern nur damit, ob das Script schnell nacheinander (zeitgleich???) oder mit kleinem zeitlichem Abstand ausgeführt wird. Ich gehe mal davon aus, dass die Semaphoren-Geschichte funktioniert. Falls nämlich nicht, könnte das die Probleme erklären. Ansonsten ist das Ganze nicht erklärbar!

Ich kümmere mich nachher nochmal darum.
 
Zuletzt bearbeitet:
Ich sehe gerade, dass ich #34 übersehen habe. #35 war die Antwort auf #33. Vielleicht hat sich #34 damit teilweise auch erledigt, aber ich habe den Eindruck, nicht ganz.
Also ich habe mir das Script nun nochmal ganz intensiv angeschaut. Und ich bin der Auffassung, dass alles korrekt funktionieren müsste.
Das meinte der Autor auch, und wenn es funktionieren würde, würdest Du Dich nicht weiter damit befassen.

Als Parameter $2 wird das File für die technische Beschreibung des zu installierenden USB-Devices (hotplug path) übergeben. Bei mir:

/proc/bus/usb/001/003
/proc/bus/usb/001/004

Aus den Informationen MANU, PROD und TOPO baut das Script am Ende auch die Infos für /var/log/printer_id zusammen. Wobei der physkalische USB-Port die erste Ziffer von TOPO ist (UPRT, ist bei mir dann 2 bzw. 3). Und aus diesem physikalischen USB-Port wird dann auch der Listen-Port für den Drucker gebaut: PORT=$((9100 + 2 * UPRT)). Zu deutsch: Es werden die systeminternen Hardware-Infos genommen, um den zum physikalischen USB-Port zugehörigen Drucker zu bestimmen! Deshalb wird die Zuordnung auch stets in der Fritzbox-Oberfläche richtig angegeben. Selbst dann, wenn sie eigentlich falsch ist.
Ich hatte bereits geschrieben, dass dieser Teil des Skripts funktioniert, hier ist nichts falsch.
Die Prozerdur "# Get next USB minor number..." hat nichts mit der Zuordnung des Ports zu tun. Diese dient nur dazu, die nächste, freie Minor-Number ($MINOR) für den Device-Node (mknod) zu erhalten, unter dem das File für den Drucker dann angelegt wird. Es hat nichts mit der Port-Zuordnung zu tun.
...
$MINOR ist eine im Grunde bedeutungslose Zahl, die nur die nächste, freie Datei-Nummer angibt.
...
Zu Deutsch: Das Script KANN die Zuordnung nicht falsch machen! Dies ist technisch völlig ausgeschlossen.
Die Device Nummer hat alles mit der Zuordnung der Drucker zu tun. Der Name der Datei spielt keine Rolle. Ob die Datei /dev/usb/lp0 oder /dev/usb_prntsvr-045.0 heißt, es hängt von der Major und Minor Device Nummer ab, wohin Ausgaben auf diese Datei landen. Die Major Nummer ist aber fix und nicht der Grund für die Probleme hier.
Der erste USB Drucker, der vom System erkannt wird, bekommt die Minor Nummer 0, und der nächste bekommt die 1, usw. Die Reihenfolge, in der die USB Geräte erkannt werden, ist aber offensichtlich nicht zwangsläufig die gleiche, in der die USB Geräte als Drucker identifiziert werden.

Nachdem die Zuordnung falsch war, habe ich mal per telnet in der Shell manuell über das printer-script mit "remove" die beiden Druckerprozesse gekillt und dann dann mit "add" die Drucker wieder hinzugefügt, aber ohne die Drucker vorher vom Hub abzustöpseln!!! Danach stimmte die Zuordnung wieder und die Daten gingen an die richtigen Drucker. Auch das zeigt, dass das Script korrekt arbeitet!
Dann versuche mal das gleiche, aber mit umgekehrter Reihenfolge beim manuellen Hinzufügen der Drucker, ggf. mehrfach.

Aber: An der Device Minor Number liegt es nicht, ob der Drucker funktioniert oder nicht!

Schau dir mal folgendes an
...
Einmal hat der BJC-3000 die Minor Number 0 und einmal die 1 und in beiden Fällen funktioniert er korrekt!
Das spricht dafür, dass auch die Zuordnung der Minor Nummer zu den Druckern nicht fest ist.
 
Die Device Nummer hat alles mit der Zuordnung der Drucker zu tun. Der Name der Datei spielt keine Rolle.
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. Wenn also z.B. die Nummer 1 schon existiert, aber die 0 noch nicht, wird die 0 genommen. Ich zitiere mal einen Auszug aus

http://www.lanana.org/docs/device-list/devices-2.6+.txt:

Code:
180 char	USB devices
		  0 = /dev/usb/lp0	First USB printer
		    ...
		 15 = /dev/usb/lp15	16th USB printer
		 16 = /dev/usb/mouse0	First USB mouse
		    ...
		 31 = /dev/usb/mouse15	16th USB mouse
		 32 = /dev/usb/ez0	First USB firmware loader
		    ...
		 47 = /dev/usb/ez15	16th USB firmware loader
		 48 = /dev/usb/scanner0	First USB scanner
		    ...
		 63 = /dev/usb/scanner15 16th USB scanner
		 64 = /dev/usb/rio500	Diamond Rio 500
		 65 = /dev/usb/usblcd	USBLCD Interface ([email protected])
		 66 = /dev/usb/cpad0	Synaptics cPad (mouse/LCD)

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.

Dann versuche mal das gleiche, aber mit umgekehrter Reihenfolge beim manuellen Hinzufügen der Drucker, ggf. mehrfach.
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.

Das spricht dafür, dass auch die Zuordnung der Minor Nummer zu den Druckern nicht fest ist.
Die Frage ist, nach welchen Kriterien wird sie festgelegt?
 
Zuletzt bearbeitet:
Gelöst

Hi Ralf,

es war alles so, wie du gesagt hast. Ich habe jetzt das Script mit einer detaillierten Debug-Ausgabe versehen, die in ein Logfile schreibt. Da kann man dann auch wunderbar sehen, wie die nebenläufigen Prozesse parallel laufen, blockiert werden, wieder starten und dass auch die Semaphore funktioniert.

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. 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? Alles SEHR seltsam! 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.

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. Dat is doch allet Murks! :confused: Warum gibt man dem Drucker nicht einfach vorzugsweise die Minor-Number, die seinem USB-Port entspricht??? 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.

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:

Code:
USBLOCKFILE=/var/USBLOCK_printer
test -f /etc/hotplug/rc.usbsema && . /etc/hotplug/rc.usbsema

[COLOR="#FF0000"]sleep $UPRT[/COLOR]

passeeren

case $1 in

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.
 
Zuletzt bearbeitet:
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.
 
Zuletzt bearbeitet:
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.