[libvirt-users] event handler

good day to all. i still have not solved my problem with event handling. currently i have following code void libvirt_eventloop_thr_func() { while(true) //TODO: stop somehow on exit { if(virEventRunDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to run event loop: %s\n", err && err->message ? err->message : "Unknown error"); } } } ... virSetErrorFunc(NULL, libvirt_error_handler); libvirt_connection = virConnectOpen("qemu:///system"); if (virEventRegisterDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to register event implementation: %s\n", err && err->message ? err->message: "Unknown error"); return -1; } { int callback = virConnectDomainEventRegisterAny(libvirt_connection, NULL, VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_CALLBACK(domain_event_handler), NULL, NULL); if(callback == -1) { std::cout<<"Error: failed to register domain event handle callback\n"; return -1; } } boost::thread(boost::bind(&libvirt_eventloop_thr_func)); ... libvirt_eventloop_thr_func() called, and locked on virEventRunDefaultImpl(), can it be called in thread, and if no, how should i use it correctly ? sorry for asking again, but i really can't solve it myself. thx in advance.

On 14.10.2013 02:42, Alexandr wrote:
good day to all. i still have not solved my problem with event handling. currently i have following code
void libvirt_eventloop_thr_func() { while(true) //TODO: stop somehow on exit { if(virEventRunDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to run event loop: %s\n", err && err->message ? err->message : "Unknown error"); } } }
...
virSetErrorFunc(NULL, libvirt_error_handler); libvirt_connection = virConnectOpen("qemu:///system");
Move this line ^^^ ...
if (virEventRegisterDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to register event implementation: %s\n", err && err->message ? err->message: "Unknown error"); return -1; } { int callback = virConnectDomainEventRegisterAny(libvirt_connection, NULL, VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_CALLBACK(domain_event_handler), NULL, NULL); if(callback == -1) { std::cout<<"Error: failed to register domain event handle callback\n"; return -1; } }
boost::thread(boost::bind(&libvirt_eventloop_thr_func));
... over here. The virConnectOpen detects if there's an even loop registered. And in your case you don't have any registered when calling it. Michal

Michal Privoznik писал 2013-10-14 08:48:
On 14.10.2013 02:42, Alexandr wrote:
good day to all. i still have not solved my problem with event handling. currently i have following code
void libvirt_eventloop_thr_func() { while(true) //TODO: stop somehow on exit { if(virEventRunDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to run event loop: %s\n", err && err->message ? err->message : "Unknown error"); } } }
...
virSetErrorFunc(NULL, libvirt_error_handler); libvirt_connection = virConnectOpen("qemu:///system");
Move this line ^^^ ...
if (virEventRegisterDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to register event implementation: %s\n", err && err->message ? err->message: "Unknown error"); return -1; } { int callback = virConnectDomainEventRegisterAny(libvirt_connection, NULL, VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_CALLBACK(domain_event_handler), NULL, NULL); if(callback == -1) { std::cout<<"Error: failed to register domain event handle callback\n"; return -1; } }
boost::thread(boost::bind(&libvirt_eventloop_thr_func));
... over here. The virConnectOpen detects if there's an even loop registered. And in your case you don't have any registered when calling it.
Michal
thank you very match, it now working as expected, but one thing are missed from documentations, current api docs says what i do not need to call virInitialize(), but if i call virEventRegisterDefaultImpl() without calling virInitialize() programm crashing (i have not used virInitialize() in my programm, just virConnectOpen() as docs said). problem solved now.

On 14.10.2013 10:33, Alexandr wrote:
Michal Privoznik писал 2013-10-14 08:48:
On 14.10.2013 02:42, Alexandr wrote:
good day to all. i still have not solved my problem with event handling. currently i have following code
void libvirt_eventloop_thr_func() { while(true) //TODO: stop somehow on exit { if(virEventRunDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to run event loop: %s\n", err && err->message ? err->message : "Unknown error"); } } }
...
virSetErrorFunc(NULL, libvirt_error_handler); libvirt_connection = virConnectOpen("qemu:///system");
Move this line ^^^ ...
if (virEventRegisterDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to register event implementation: %s\n", err && err->message ? err->message: "Unknown error"); return -1; } { int callback = virConnectDomainEventRegisterAny(libvirt_connection, NULL, VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_CALLBACK(domain_event_handler), NULL, NULL); if(callback == -1) { std::cout<<"Error: failed to register domain event handle callback\n"; return -1; } }
boost::thread(boost::bind(&libvirt_eventloop_thr_func));
... over here. The virConnectOpen detects if there's an even loop registered. And in your case you don't have any registered when calling it.
Michal
thank you very match, it now working as expected, but one thing are missed from documentations, current api docs says what i do not need to call virInitialize(), but if i call virEventRegisterDefaultImpl() without calling virInitialize() programm crashing (i have not used virInitialize() in my programm, just virConnectOpen() as docs said). problem solved now.
From virInitialize documentation [1]:
"The only time it would be necessary to call virInitialize is if the application did not invoke virConnectOpen as its first API call." Which is your case. But if you believe this can be written better, propose a patch and I'll review it. Michal 1: http://libvirt.org/html/libvirt-libvirt.html#virInitialize

Michal Privoznik писал 2013-10-14 11:39:
On 14.10.2013 10:33, Alexandr wrote:
Michal Privoznik писал 2013-10-14 08:48:
On 14.10.2013 02:42, Alexandr wrote:
good day to all. i still have not solved my problem with event handling. currently i have following code
void libvirt_eventloop_thr_func() { while(true) //TODO: stop somehow on exit { if(virEventRunDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to run event loop: %s\n", err && err->message ? err->message : "Unknown error"); } } }
...
virSetErrorFunc(NULL, libvirt_error_handler); libvirt_connection = virConnectOpen("qemu:///system");
Move this line ^^^ ...
if (virEventRegisterDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to register event implementation: %s\n", err && err->message ? err->message: "Unknown error"); return -1; } { int callback = virConnectDomainEventRegisterAny(libvirt_connection, NULL, VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_CALLBACK(domain_event_handler), NULL, NULL); if(callback == -1) { std::cout<<"Error: failed to register domain event handle callback\n"; return -1; } }
boost::thread(boost::bind(&libvirt_eventloop_thr_func));
... over here. The virConnectOpen detects if there's an even loop registered. And in your case you don't have any registered when calling it.
Michal
thank you very match, it now working as expected, but one thing are missed from documentations, current api docs says what i do not need to call virInitialize(), but if i call virEventRegisterDefaultImpl() without calling virInitialize() programm crashing (i have not used virInitialize() in my programm, just virConnectOpen() as docs said). problem solved now.
From virInitialize documentation [1]:
"The only time it would be necessary to call virInitialize is if the application did not invoke virConnectOpen as its first API call."
Which is your case. But if you believe this can be written better, propose a patch and I'll review it.
Michal
1: http://libvirt.org/html/libvirt-libvirt.html#virInitialize
yes, i read this, but my first api call is virSetErrorFunc(), and this api call working fine without virInitialize(), this create a little confusion. i think i can't help with documentation, english is not my native language and it is hard to me to write on it, and mostly impossible to write correctly.

On 14.10.2013 10:57, Alexandr wrote:
Michal Privoznik писал 2013-10-14 11:39:
On 14.10.2013 10:33, Alexandr wrote:
Michal Privoznik писал 2013-10-14 08:48:
On 14.10.2013 02:42, Alexandr wrote:
good day to all. i still have not solved my problem with event handling. currently i have following code
void libvirt_eventloop_thr_func() { while(true) //TODO: stop somehow on exit { if(virEventRunDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to run event loop: %s\n", err && err->message ? err->message : "Unknown error"); } } }
...
virSetErrorFunc(NULL, libvirt_error_handler); libvirt_connection = virConnectOpen("qemu:///system");
Move this line ^^^ ...
if (virEventRegisterDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to register event implementation: %s\n", err && err->message ? err->message: "Unknown error"); return -1; } { int callback = virConnectDomainEventRegisterAny(libvirt_connection, NULL, VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_CALLBACK(domain_event_handler), NULL, NULL); if(callback == -1) { std::cout<<"Error: failed to register domain event handle callback\n"; return -1; } }
boost::thread(boost::bind(&libvirt_eventloop_thr_func));
... over here. The virConnectOpen detects if there's an even loop registered. And in your case you don't have any registered when calling it.
Michal
thank you very match, it now working as expected, but one thing are missed from documentations, current api docs says what i do not need to call virInitialize(), but if i call virEventRegisterDefaultImpl() without calling virInitialize() programm crashing (i have not used virInitialize() in my programm, just virConnectOpen() as docs said). problem solved now.
From virInitialize documentation [1]:
"The only time it would be necessary to call virInitialize is if the application did not invoke virConnectOpen as its first API call."
Which is your case. But if you believe this can be written better, propose a patch and I'll review it.
Michal
1: http://libvirt.org/html/libvirt-libvirt.html#virInitialize
yes, i read this, but my first api call is virSetErrorFunc(), and this api call working fine without virInitialize(), this create a little confusion.
The fact that some functions *seem* to work well even without virInitialize() called doesn't mean that you shouldn't call it. When I started to write some programs involving libvirt I've looked into virsh.c a lot and basically copied the main structure. virsh is guaranteed to work and use the correct sequence of APIs. The other option is to look at examples, e.g. event-test [2]. Michal 2: http://libvirt.org/git/?p=libvirt.git;a=blob;f=examples/domain-events/events...

Michal Privoznik писал 2013-10-14 12:04:
On 14.10.2013 10:57, Alexandr wrote:
Michal Privoznik писал 2013-10-14 11:39:
On 14.10.2013 10:33, Alexandr wrote:
Michal Privoznik писал 2013-10-14 08:48:
On 14.10.2013 02:42, Alexandr wrote:
good day to all. i still have not solved my problem with event handling. currently i have following code
void libvirt_eventloop_thr_func() { while(true) //TODO: stop somehow on exit { if(virEventRunDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to run event loop: %s\n", err && err->message ? err->message : "Unknown error"); } } }
...
virSetErrorFunc(NULL, libvirt_error_handler); libvirt_connection = virConnectOpen("qemu:///system");
Move this line ^^^ ...
if (virEventRegisterDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to register event implementation: %s\n", err && err->message ? err->message: "Unknown error"); return -1; } { int callback = virConnectDomainEventRegisterAny(libvirt_connection, NULL, VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_CALLBACK(domain_event_handler), NULL, NULL); if(callback == -1) { std::cout<<"Error: failed to register domain event handle callback\n"; return -1; } }
boost::thread(boost::bind(&libvirt_eventloop_thr_func));
... over here. The virConnectOpen detects if there's an even loop registered. And in your case you don't have any registered when calling it.
Michal
thank you very match, it now working as expected, but one thing are missed from documentations, current api docs says what i do not need to call virInitialize(), but if i call virEventRegisterDefaultImpl() without calling virInitialize() programm crashing (i have not used virInitialize() in my programm, just virConnectOpen() as docs said). problem solved now.
From virInitialize documentation [1]:
"The only time it would be necessary to call virInitialize is if the application did not invoke virConnectOpen as its first API call."
Which is your case. But if you believe this can be written better, propose a patch and I'll review it.
Michal
1: http://libvirt.org/html/libvirt-libvirt.html#virInitialize
yes, i read this, but my first api call is virSetErrorFunc(), and this api call working fine without virInitialize(), this create a little confusion.
The fact that some functions *seem* to work well even without virInitialize() called doesn't mean that you shouldn't call it. When I started to write some programs involving libvirt I've looked into virsh.c a lot and basically copied the main structure. virsh is guaranteed to work and use the correct sequence of APIs. The other option is to look at examples, e.g. event-test [2].
Michal
2: http://libvirt.org/git/?p=libvirt.git;a=blob;f=examples/domain-events/events...
maybe write something like "virInitialize() must be first api call except situations when first call is virConnectOpen()" ?
participants (2)
-
Alexandr
-
Michal Privoznik