在 2017/11/13 22:27, Martin Kletzander 写道:
On Mon, Nov 13, 2017 at 09:07:12PM +0800, xinhua.Cao wrote:
在 2017/11/12 22:45, John Ferlan 写道:
On 11/11/2017 03:20 AM, xinhua.Cao wrote:
在 2017/11/11 5:43, John Ferlan 写道:
On 11/06/2017 12:47 AM, xinhua.Cao wrote:
base on commit fe8f1c8b8650c8ab5e7d27338f4538582651bd14, we solve
libvirt coredump problem, but it introduce a memory leak sense:
1. one client register a domain event such as reboot event
2. and client was terminated unexpectly, such as kill -9,
unexpectedly
then this client object will not free at libvirtd service program.
remoteDispatchConnectDomainEventCallbackRegisterAny reference the
client,
but when client was terminated before it call deRegisterAny,the
reference
of client will not reduced to zero. so the memory leak take place.
What's the difference between the path that would terminate
normally and
the one that terminates abnormally. It seems to me there might be
(an)
extra Ref(s) on the client which prevents
virNetServerClientDispose from
calling it's @privateDataFreeFunc which would call
remoteClientFreeFunc
since remoteClientInitHook worked properly.
That's what needs to be found.
If client terminate normally, client would call
virConnectDomainEventDeregisterAny to
clear eventCallbacks. Then libvirt daemon will call
remoteDispatchConnectDomainEventDeregisterAny
-> remoteEventCallbackFree -> virObjectUnref(callback->client) to free
eventCallbacks and unRef client.
just think if client don't call virConnectDomainEventDeregisterAny and
be killed. then there is no way to call call
remoteDispatchConnectDomainEventDeregisterAny ->
remoteEventCallbackFree
-> virObjectUnref(callback->client)
so client's ref can't down to zero. so remoteClientFreeFunc can't be
called. then client object memory leak.
So the client/sample code is not calling Deregister because it has no
"handling" of an abnormal exit. That is no signal handler to call
Deregister in the event some outside force kills the client/sample code
while it's processing.
So a different solution would be to add signal handling to the code in
order to handle the kill and make the Deregister (and close) calls.
signal handler can handle such as kill -15 signal, But can't handle kill
-9 signal.
so we also need to resolve it in libvirt
Basically we need to handle bad behaving clients in the daemon
anyway. I tried
running libvirtd under valgrind and there was no extra leak with a
client which
didn't deregister the callback. How did you encounter this? I really
want to
find the place that I think needs to be changed, but without a
reproducer this
is just a guessing game.
event mechanism is a very complicated. I guess it was freed at libvirtd
deamon quit at qemuStateCleanup
it cleared all event by virObjectUnref(qemu_driver->domainEventState),
so client was also cleared at this
moment. but I can't gdb at this point(qemuStateCleanup) when libvirtd
recieve kill -15 signal.
--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list