Qemu-Monitor - Problem bei Nutzung über Socket
Hab ich mal ausprobiert ... selbst wenn ich ein "print sock.recv(1000)" einbaue bringt es nichts ...
Hab mal "socat" mit "strace" laufen lassen:
Code: Alles auswählen
recvfrom(3, 0x7ffc0239a8e0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
getsockname(5, {sa_family=AF_UNIX}, [112->2]) = 0
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
select(6, [0 5], [1 5], [], NULL) = 3 (in [5], out [1 5])
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239a7a0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
read(5, "QEMU 3.0.0 monitor - type 'help'"..., 8192) = 62
recvfrom(3, 0x7ffc0239a7a0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239aca0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
write(1, "QEMU 3.0.0 monitor - type 'help'"..., 62) = 62
recvfrom(3, 0x7ffc0239aca0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
select(6, [0 5], [1], [], NULL) = 1 (out [1])
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
select(6, [0 5], [], [], NULL) = 1 (in [0])
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239a7a0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
read(0, "system_powerdown\n", 8192) = 17
recvfrom(3, 0x7ffc0239a7a0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239aca0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
write(5, "system_powerdown\n", 17) = 17
recvfrom(3, 0x7ffc0239aca0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
select(6, [0 5], [5], [], NULL) = 2 (in [5], out [5])
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239a7a0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
read(5, "s\33[K\33[Dsy\33[K\33[D\33[Dsys\33[K\33[D\33[D\33["..., 8192) = 480
recvfrom(3, 0x7ffc0239a7a0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239aca0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
write(1, "s\33[K\33[Dsy\33[K\33[D\33[Dsys\33[K\33[D\33[D\33["..., 480) = 480
recvfrom(3, 0x7ffc0239aca0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
select(6, [0 5], [1], [], NULL) = 2 (in [5], out [1])
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239a7a0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
read(5, "\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33["..., 8192) = 73
recvfrom(3, 0x7ffc0239a7a0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239aca0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
write(1, "\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33["..., 73) = 73
recvfrom(3, 0x7ffc0239aca0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
select(6, [0 5], [1], [], NULL) = 1 (out [1])
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
select(6, [0 5], [], [], NULL) = 1 (in [0])
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffc0239a7a0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
read(0, "", 8192) = 0
recvfrom(3, 0x7ffc0239a7a0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
shutdown(5, SHUT_WR) = 0
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
select(6, [5], [], [], {tv_sec=0, tv_usec=500000}) = 0 (Timeout)
recvfrom(3, 0x7ffc0239ad10, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0
shutdown(5, SHUT_RDWR) = 0
recvfrom(3, 0x7ffc0239aff0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
exit_group(0) = ?
+++ exited with 0 +++
Wie müsste ich die Funktion ändern, um da ein "select" einzubauen?
Wobei ich ehrlich zugebe, das die ganze Netzwerk-Programmierung für mich Neuland ist ...
Wobei ich ehrlich zugebe, das die ganze Netzwerk-Programmierung für mich Neuland ist ...
na, du musst halt ein select aus dem Modul select einbauen. Grob so:
Der sollte so lange warten, bis man auf dem socket wieder schreiben kann. Was ggf. eben impliziert, das der "geflusht" ist. An sich ist das alles Standardvorgehen, ich bin mir nur um die Details der Semantik hier mit gepufferten Daten, die dann ggf. noch nicht geschrieben sind auch nicht klar - sowas ist bestimmt in POSIX spezifiziert, aber probieren, studieren, etc...
Code: Alles auswählen
socket.sendall(...)
readlist = [] # wir wollen nix lesen
writelist = [socket] # ggf. socket.fileno(), aber das sollte so gehen
xlist = [] # wir brauchen keine exceptional conditions
select.select(readlist, writelist, xlist)
Den "select" habe ich mal so eingebaut:
Keine Änderung ... VM läuft weiter ...
Code: Alles auswählen
def send(path):
print path
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(path)
sock.sendall("system_powerdown\n")
readlist = [sock]
writelist = [sock]
xlist = []
select.select(readlist, writelist, xlist)
sock.close()
Wenn die "readlist" als einzige nicht leer ist, fährt die VM nicht runter
Wenn alle 3 Listen leer sind schon ... aber das Script durfte ich abbrechen
(Timeout wäre eine nette Idee gewesen, aber da kann ich gleich beim "sleep" bleiben)
Wenn alle 3 Listen leer sind schon ... aber das Script durfte ich abbrechen
(Timeout wäre eine nette Idee gewesen, aber da kann ich gleich beim "sleep" bleiben)
Klar, wenn die alle leer sind, dann ist das ein endloses schlafen. Wie gesagt, was genau da der Unterschied ist, finde ich sehr schwer zu erkennen. Ggf. kannst du das socat nochmal tracen ohne den stoerenden output dazwischen. Denn das read kommt doch von einem anderen Prozess, oder?
@midan23: das select ist überflüssig, denn Du weißt ja, wann Du etwas schreiben willst, und wann du etwas lesen willst.
Was liefert denn `socat` als Ausgabe? Vielleicht war ein `recv` ein bißchen optimistisch. Pack das recv in eine Endlosschleife, denn nach dem Herunterfahren wird ja der Socket definitiv geschlossen:
Was liefert denn `socat` als Ausgabe? Vielleicht war ein `recv` ein bißchen optimistisch. Pack das recv in eine Endlosschleife, denn nach dem Herunterfahren wird ja der Socket definitiv geschlossen:
Code: Alles auswählen
sock.sendall("system_powerdown\n")
while True:
data = sock.recv(1000)
if not data:
break
print(data) # Debug-Ausgabe
sock.close()
Wüsste nicht von welchem Prozess das "read" kommen sollte ...__deets__ hat geschrieben: ↑Mittwoch 14. November 2018, 15:35 Klar, wenn die alle leer sind, dann ist das ein endloses schlafen. Wie gesagt, was genau da der Unterschied ist, finde ich sehr schwer zu erkennen. Ggf. kannst du das socat nochmal tracen ohne den stoerenden output dazwischen. Denn das read kommt doch von einem anderen Prozess, oder?
Gestartet habe ich es einfach mit
Code: Alles auswählen
socat - UNIX:<pfad>
@Sirius3
Socat (gestartet mit "echo "system_powerdown" | socat - UNIX:<pfad>") liefert folgendes:
Code: Alles auswählen
QEMU 3.0.0 monitor - type 'help' for more information
(qemu) system_powerdown
(qemu)
Code: Alles auswählen
QEMU 3.0.0 monitor - type 'help' for more information
(qemu)
sy
sys
syst
syste
system
system_
system_p
system_po
system_pow
system_powe
system_power
system_powerd
system_powerdo
system_powerdow
system_powerdown
(qemu)
Hab ich, ja ...
Im erste Post hatte ich ein die Ausgabe von "echo" über eine Pipe nach "socat" geschickt.
Da ich nicht weiss, wie ich das in Verbindung mit "strace" mache, habe ich es interaktiv genutzt ...
Im erste Post hatte ich ein die Ausgabe von "echo" über eine Pipe nach "socat" geschickt.
Da ich nicht weiss, wie ich das in Verbindung mit "strace" mache, habe ich es interaktiv genutzt ...
na, das macht die Sache strace-maessig natuerlich etwas komplexer, weil er dann einen mainloop aufsetzt etc. Das erklaert dann auch, warum er den string nicht nur schreibt, sondern auch liest - das ist halt deine Eingabe
strace hat auch pipe-support, womit das auch gehen sollte. Wie auch immer genau...
strace hat auch pipe-support, womit das auch gehen sollte. Wie auch immer genau...
Jetzt hab ich den "socat" mal so aufgerufen:
Und hier die letzten Zeilen der "socat.out":
Ich seh da ebenfalls einen "select" ...
Code: Alles auswählen
strace -o socat.out socat - UNIX:<pfad> <<EOT
> system_powerdown
> EOT
Code: Alles auswählen
getsockname(5, {sa_family=AF_UNIX}, [112->2]) = 0
recvfrom(3, 0x7ffd249b15b0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
select(6, [0 5], [1 5], [], NULL) = 4 (in [0 5], out [1 5])
recvfrom(3, 0x7ffd249b15b0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffd249b1040, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
read(0, "system_powerdown\n", 8192) = 17
recvfrom(3, 0x7ffd249b1040, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffd249b1540, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
write(5, "system_powerdown\n", 17) = 17
recvfrom(3, 0x7ffd249b1540, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffd249b1040, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
read(5, "QEMU 3.0.0 monitor - type 'help'"..., 8192) = 326
recvfrom(3, 0x7ffd249b1040, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffd249b1540, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
write(1, "QEMU 3.0.0 monitor - type 'help'"..., 326) = 326
recvfrom(3, 0x7ffd249b1540, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffd249b15b0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
select(6, [0 5], [1 5], [], NULL) = 4 (in [0 5], out [1 5])
recvfrom(3, 0x7ffd249b15b0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffd249b1040, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
read(0, "", 8192) = 0
recvfrom(3, 0x7ffd249b1040, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffd249b1040, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
read(5, "\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33["..., 8192) = 289
recvfrom(3, 0x7ffd249b1040, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffd249b1540, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
write(1, "\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33[D\33["..., 289) = 289
recvfrom(3, 0x7ffd249b1540, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
shutdown(5, SHUT_WR) = 0
recvfrom(3, 0x7ffd249b15b0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
select(6, [5], [1], [], {tv_sec=0, tv_usec=500000}) = 2 (in [5], out [1], left {tv_sec=0, tv_usec=499995})
recvfrom(3, 0x7ffd249b15b0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
recvfrom(3, 0x7ffd249b1040, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
read(5, "", 8192) = 0
recvfrom(3, 0x7ffd249b1040, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
shutdown(5, SHUT_WR) = 0
ioctl(1, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0
shutdown(5, SHUT_RDWR) = 0
recvfrom(3, 0x7ffd249b1890, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Die Ressource ist zur Zeit nicht verfügbar)
exit_group(0) = ?
+++ exited with 0 +++
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Insbesondere wird diese ``QEMU 3.0.0 monitor - type 'help'``-Meldung von QEMU gelesen. Vielleicht erwartet QEMU ja, dass diese Meldung rausgeschrieben werden kann bevor es irgendwelche Kommandos verarbeitet.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Mach leider auch keinen Unterschied ...
Scheint, als ob zwischen "sock.sendall" und "sock.close" eine kurze Wartezeit notwendig ist ...
Hab gerade ein "time.sleep(0.1) versucht ... reicht aus.
Verstehen tu ich es immer noch nicht ... aber da es geht ...
Scheint, als ob zwischen "sock.sendall" und "sock.close" eine kurze Wartezeit notwendig ist ...
Hab gerade ein "time.sleep(0.1) versucht ... reicht aus.
Verstehen tu ich es immer noch nicht ... aber da es geht ...
@midan23: ich verstehe nicht, warum Du hier noch herumprobierst, die Lösung habe ich doch schon gestern gepostet: die while-Schleife mit recv. Das ist die einfachste und sauberste Möglichkeit. `select` braucht man nur, wenn nicht bestimmt ist, ob der Server oder der Client sendet, oder beide gleichzeitig. Bei Dir ist aber die Reihenfolge Client sendet -> Server antwortet klar.