If a stream gets a server initiated abort, the client may still
send an abort request before it receives the server side abort.
This causes the server to send back another abort for the
stream. Since the protocol defines that abort is the last thing
to be sent, the client gets confused by this second abort from
the server. If the stream is already shutdown, just drop any
client requested abort, rather than sending back another message.
This fixes the regression from previous versions.
Tested as follows
In one virsh session
virsh # start foo
virsh # console foo
In other virsh session
virsh # destroy foo
The first virsh session should be able to continue issuing
commands without error. Prior to this patch it saw
virsh # list
error: Failed to list active domains
error: An error occurred, but the cause is unknown
virsh # list
error: Failed to list active domains
error: no call waiting for reply with prog 536903814 vers 1 serial 9
* src/rpc/virnetserverprogram.c: Drop abort requests
for streams which no longer exist
We ignore any stream data packets which come in for streams which
are not registered, since these packets are async and do not have
a reply. If we get a stream control packet though we must send back
an actual error, otherwise a (broken) client may hang forever
making it hard to diagnose the client bug.
* src/rpc/virnetserverprogram.c: Send back error for unexpected
stream control messages
If a message packet for a invalid stream is received it is just
free'd. This is not good because it doesn't let the client RPC
request counter decrement. If a stream is shutdown with pending
packets the message also isn't released properly because of an
incorrect header type
* daemon/stream.c: Fix message header type
* src/rpc/virnetserverprogram.c: Send dummy reply instead of
free'ing ignored stream message
On stream completion it is neccessary to send back a
message with an empty payload. The message header was
not being filled out correctly, since we were not writing
any payload. Add a method for encoding an empty payload
which updates the message headers correctly.
* src/rpc/virnetmessage.c, src/rpc/virnetmessage.h: Add
a virNetMessageEncodePayloadEmpty method
* src/rpc/virnetserverprogram.c: Write empty payload on
stream completion
To facilitate creation of new daemons providing XDR RPC services,
pull a lot of the libvirtd daemon code into a set of reusable
objects.
* virNetServer: A server contains one or more services which
accept incoming clients. It maintains the list of active
clients. It has a list of RPC programs which can be used
by clients. When clients produce a complete RPC message,
the server passes this onto the corresponding program for
handling, and queues any response back with the client.
* virNetServerClient: Encapsulates a single client connection.
All I/O for the client is handled, reading & writing RPC
messages.
* virNetServerProgram: Handles processing and dispatch of
RPC method calls for a single RPC (program,version).
Multiple programs can be registered with the server.
* virNetServerService: Encapsulates socket(s) listening for
new connections. Each service listens on a single host/port,
but may have multiple sockets if on a dual IPv4/6 host.
Each new daemon now merely has to define the list of RPC procedures
& their handlers. It does not need to deal with any network related
functionality at all.