[libvirt] [PATCH 0/2] Domain event example C code misues api

From: "Jesse J. Cook" <jcook@camber.com> The example program makes a call to virEventRegisterDefaultImpl before calling virConnectOpen without a call to virInitialize. Interestingly enough, the example code works. However, once you introduce a call to g_string_new it breaks. This can result in unintentional misuse of the API. Relates to: Red Hat Bugzilla – Bug 961155 Jesse J. Cook (2): dom event example: init before register event impl dom event example: Add error check to impl call examples/domain-events/events-c/event-test.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) -- 1.7.10.4

From: "Jesse J. Cook" <jesse.j.cook@member.fsf.org> In the domain-events example C code virEventRegisterDefaultImpl was being called before virConnectOpen without first calling virInitialize. While this code worked, it is incorrect. Adding a call to g_string_new prior to the call to virEventRegisterDefaultImpl would cause the code to break. This fix will help avoid unintentional misue of the API. Relates to: Ret Hat Bugzilla - Bug 961155 --- examples/domain-events/events-c/event-test.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c index ede9796..09ec6aa 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -468,6 +468,12 @@ int main(int argc, char **argv) return -1; } + if(0 != virInitialize()) { + virErrorPtr err = virGetLastError(); + fprintf(stderr, "Failed to initialize: %s\n", + err && err->message ? err->message: "Unknown error"); + } + virEventRegisterDefaultImpl(); virConnectPtr dconn = NULL; -- 1.7.10.4

On 09.05.2013 23:17, Jesse J. Cook wrote:
From: "Jesse J. Cook" <jesse.j.cook@member.fsf.org>
In the domain-events example C code virEventRegisterDefaultImpl was being called before virConnectOpen without first calling virInitialize. While this code worked, it is incorrect. Adding a call to g_string_new prior to the call to virEventRegisterDefaultImpl would cause the code to break. This fix will help avoid unintentional misue of the API.
Not even g_string_new but even our doc require virInitialize to be called prior any libvirt API other than virConnectOpen*(). This rule includes VirEventRegisterDefaultImpl().
Relates to: Ret Hat Bugzilla - Bug 961155 --- examples/domain-events/events-c/event-test.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c index ede9796..09ec6aa 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -468,6 +468,12 @@ int main(int argc, char **argv) return -1; }
+ if(0 != virInitialize()) {
Actually, we prefer the other way: if (virInitialize() < 0) {
+ virErrorPtr err = virGetLastError(); + fprintf(stderr, "Failed to initialize: %s\n", + err && err->message ? err->message: "Unknown error");
s/:/ :/ Moreover, we should return here, shouldn't we? And are we save to call virGetLastError()? I don't think so. I mean, the first thing that virInitialize() does, is thread library initialize (on linux it's nada function, but not on windows), then it initialize thread local variable - the virError object. And what if this fails for some reason - then virgetLastError may access invalid memory. So I thing we should just fprintf(stderr, "Failed to initialize libvirt");
+ } + virEventRegisterDefaultImpl();
virConnectPtr dconn = NULL;
However, this is a nasty violation of our own rules, so ACK with this squashed in: diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c index 09ec6aa..0f7be55 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -468,10 +468,9 @@ int main(int argc, char **argv) return -1; } - if(0 != virInitialize()) { - virErrorPtr err = virGetLastError(); - fprintf(stderr, "Failed to initialize: %s\n", - err && err->message ? err->message: "Unknown error"); + if (virInitialize() < 0) { + fprintf(stderr, "Failed to initialize libvirt"); + return -1; } virEventRegisterDefaultImpl(); Michal

From: "Jesse J. Cook" <jesse.j.cook@member.fsf.org> Added error checking to virEventRegisterDefaultImpl call for consistency. --- examples/domain-events/events-c/event-test.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c index 09ec6aa..046c36e 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -474,7 +474,11 @@ int main(int argc, char **argv) err && err->message ? err->message: "Unknown error"); } - virEventRegisterDefaultImpl(); + if(0 != virEventRegisterDefaultImpl()) { + virErrorPtr err = virGetLastError(); + fprintf(stderr, "Failed to register event implementation: %s\n", + err && err->message ? err->message: "Unknown error"); + } virConnectPtr dconn = NULL; dconn = virConnectOpenAuth(argc > 1 ? argv[1] : NULL, -- 1.7.10.4

On 09.05.2013 23:17, Jesse J. Cook wrote:
From: "Jesse J. Cook" <jesse.j.cook@member.fsf.org>
Added error checking to virEventRegisterDefaultImpl call for consistency. --- examples/domain-events/events-c/event-test.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c index 09ec6aa..046c36e 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -474,7 +474,11 @@ int main(int argc, char **argv) err && err->message ? err->message: "Unknown error"); }
- virEventRegisterDefaultImpl(); + if(0 != virEventRegisterDefaultImpl()) {
We tend to write it vice versa. Moreover, there should be a space between 'if' and '(': if (virEventRegisterDefaultImpl() < 0) {
+ virErrorPtr err = virGetLastError();
But here is it perfectly safe to call virGetLastError() because the only way we could get here is where virInitialize reported success.
+ fprintf(stderr, "Failed to register event implementation: %s\n", + err && err->message ? err->message: "Unknown error");
Again, we should return -1 here.
+ }
virConnectPtr dconn = NULL; dconn = virConnectOpenAuth(argc > 1 ? argv[1] : NULL,
ACK with this squashed in: diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c index bee3f78..301caad 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -473,10 +473,11 @@ int main(int argc, char **argv) return -1; } - if(0 != virEventRegisterDefaultImpl()) { + if (virEventRegisterDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to register event implementation: %s\n", err && err->message ? err->message: "Unknown error"); + return -1; } virConnectPtr dconn = NULL; Michal

On 09.05.2013 23:17, Jesse J. Cook wrote:
From: "Jesse J. Cook" <jcook@camber.com>
The example program makes a call to virEventRegisterDefaultImpl before calling virConnectOpen without a call to virInitialize. Interestingly enough, the example code works. However, once you introduce a call to g_string_new it breaks. This can result in unintentional misuse of the API.
Relates to: Red Hat Bugzilla – Bug 961155
Jesse J. Cook (2): dom event example: init before register event impl dom event example: Add error check to impl call
examples/domain-events/events-c/event-test.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
I've squashed in both fixes and pushed. Michal
participants (2)
-
Jesse J. Cook
-
Michal Privoznik