[libvirt] [PATCH] build: Embed dbus_message_unref in virdbus

Adding dbus_message_unref() into virDBusMessageDecodeArgs() makes sure that the message gets unref'd, thus making one more pure dbus call not necessary. Even though we are calling a lot of dbus_* functions outside virdbus (which should be fixed in the future IMHO), this patch fixes only this one instance because it merely aims to fix a build-breaker caused by improperly included dbus.h. The message printed when failing (using --without-dbus) is: util/virsystemd.c: In function 'virSystemdPMSupportTarget': util/virsystemd.c:367:5: error: implicit declaration of function 'dbus_message_unref' [-Werror=implicit-function-declaration] dbus_message_unref(message); ^ Signed-off-by: Martin Kletzander <mkletzan@redhat.com> --- Notes: I checked that we're not unreffing the message twice anywhere, but I wanted to check there is no crash if we do unref it twice. While trying whether double unreffing the message breaks anything, I saw that dbus_message_unref() has a refcount and it cleans structure when the refcount reaches 0, the cleansing means it sets it to -1 as well. OK, so it doesn't break anything, but the allocated structure is still not free()'d. I ran virsystemdtest under valgrind and saw that the message is really not free()'d. But here comes the best part; out of 6 test functions, only 3 of them are causing a leak and adding VIR_FREE(msg) to any test function other than the last one (which gets rid of one leak out of three) causes a segfault. I though dbus has it's own memory management or whatever, but looking at the backtrace, the crash happens when we are allocating DBusMessageIter *newiter one function later than the VIR_FREE(msg) is done (and msg is local to that function, btw). Even though this has nothing to do with the patch sent, I'd appreciate any explanation from anyone more dbus-knowledgeable than me (most probably anyone). src/util/virdbus.c | 1 + src/util/virsystemd.c | 3 +-- tests/virdbustest.c | 6 ------ 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/util/virdbus.c b/src/util/virdbus.c index 0cd3858..aef1d34 100644 --- a/src/util/virdbus.c +++ b/src/util/virdbus.c @@ -1112,6 +1112,7 @@ int virDBusMessageDecodeArgs(DBusMessage* msg, } ret = virDBusMessageIterDecode(&iter, types, args); + dbus_message_unref(msg); cleanup: return ret; diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c index e9ca564..9f67ac0 100644 --- a/src/util/virsystemd.c +++ b/src/util/virsystemd.c @@ -1,7 +1,7 @@ /* * virsystemd.c: helpers for using systemd APIs * - * Copyright (C) 2013 Red Hat, Inc. + * Copyright (C) 2013, 2014 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -364,7 +364,6 @@ virSystemdPMSupportTarget(const char *methodName, bool *result) ret = 0; cleanup: - dbus_message_unref(message); VIR_FREE(response); return ret; diff --git a/tests/virdbustest.c b/tests/virdbustest.c index a798fbe..50578d9 100644 --- a/tests/virdbustest.c +++ b/tests/virdbustest.c @@ -121,7 +121,6 @@ static int testMessageSimple(const void *args ATTRIBUTE_UNUSED) VIR_FREE(out_string); VIR_FREE(out_signature); VIR_FREE(out_objectpath); - dbus_message_unref(msg); return ret; } @@ -171,7 +170,6 @@ static int testMessageVariant(const void *args ATTRIBUTE_UNUSED) cleanup: VIR_FREE(out_str1); VIR_FREE(out_str2); - dbus_message_unref(msg); return ret; } @@ -224,7 +222,6 @@ static int testMessageArray(const void *args ATTRIBUTE_UNUSED) cleanup: VIR_FREE(out_str1); VIR_FREE(out_str2); - dbus_message_unref(msg); return ret; } @@ -322,7 +319,6 @@ static int testMessageArrayRef(const void *args ATTRIBUTE_UNUSED) for (i = 0; i < out_nstrv2; i++) VIR_FREE(out_strv2[i]); VIR_FREE(out_strv2); - dbus_message_unref(msg); return ret; } @@ -397,7 +393,6 @@ static int testMessageStruct(const void *args ATTRIBUTE_UNUSED) VIR_FREE(out_string); VIR_FREE(out_signature); VIR_FREE(out_objectpath); - dbus_message_unref(msg); return ret; } @@ -467,7 +462,6 @@ static int testMessageDict(const void *args ATTRIBUTE_UNUSED) VIR_FREE(out_key1); VIR_FREE(out_key2); VIR_FREE(out_key3); - dbus_message_unref(msg); return ret; } -- 1.9.2

On Mon, Apr 14, 2014 at 01:41:18PM +0200, Martin Kletzander wrote:
Adding dbus_message_unref() into virDBusMessageDecodeArgs() makes sure that the message gets unref'd, thus making one more pure dbus call not necessary. Even though we are calling a lot of dbus_* functions outside virdbus (which should be fixed in the future IMHO), this patch fixes only this one instance because it merely aims to fix a build-breaker caused by improperly included dbus.h. The message printed when failing (using --without-dbus) is:
diff --git a/src/util/virdbus.c b/src/util/virdbus.c index 0cd3858..aef1d34 100644 --- a/src/util/virdbus.c +++ b/src/util/virdbus.c @@ -1112,6 +1112,7 @@ int virDBusMessageDecodeArgs(DBusMessage* msg, }
ret = virDBusMessageIterDecode(&iter, types, args); + dbus_message_unref(msg);
cleanup: return ret;
NACK, this is basically reverting the change I did previously and will break the firewall patches I have pending. commit dc7f3ffc023e3decf6aca3a2cfba2d884f0413a4 Author: Daniel P. Berrange <berrange@redhat.com> Date: Wed Mar 19 10:55:13 2014 +0000 Remove bogus unref in virDBusMessageRead The virDBusMessageRead method should not have side-effects on the message parameter passed in, so unref'ing it is wrong. The caller should unref only when they decided they are done with it. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> diff --git a/src/util/virdbus.c b/src/util/virdbus.c index ecfe9f6..cbaf995 100644 --- a/src/util/virdbus.c +++ b/src/util/virdbus.c @@ -1421,7 +1421,6 @@ int virDBusMessageRead(DBusMessage *msg, ret = virDBusMessageDecodeArgs(msg, types, args); va_end(args); - dbus_message_unref(msg); return ret; } Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Mon, Apr 14, 2014 at 01:02:02PM +0100, Daniel P. Berrange wrote:
On Mon, Apr 14, 2014 at 01:41:18PM +0200, Martin Kletzander wrote:
Adding dbus_message_unref() into virDBusMessageDecodeArgs() makes sure that the message gets unref'd, thus making one more pure dbus call not necessary. Even though we are calling a lot of dbus_* functions outside virdbus (which should be fixed in the future IMHO), this patch fixes only this one instance because it merely aims to fix a build-breaker caused by improperly included dbus.h. The message printed when failing (using --without-dbus) is:
diff --git a/src/util/virdbus.c b/src/util/virdbus.c index 0cd3858..aef1d34 100644 --- a/src/util/virdbus.c +++ b/src/util/virdbus.c @@ -1112,6 +1112,7 @@ int virDBusMessageDecodeArgs(DBusMessage* msg, }
ret = virDBusMessageIterDecode(&iter, types, args); + dbus_message_unref(msg);
cleanup: return ret;
NACK, this is basically reverting the change I did previously and will break the firewall patches I have pending.
OK, this makes sense if we do one of the following: a) Implement a virDBusMessageUnref() which does the same thing if we have dbus, which would be no-op otherwise, thus making pure dbus_* calls completely wrapped such uses or b) encapsulate systemd checks for pm-utils in ifdef WITH_SYSTEMD_DAEMON like this: diff --git i/src/util/virnodesuspend.c w/src/util/virnodesuspend.c index 59b84ef..20b85b8 100644 --- i/src/util/virnodesuspend.c +++ w/src/util/virnodesuspend.c @@ -1,6 +1,7 @@ /* * virnodesuspend.c: Support for suspending a node (host machine) * + * Copyright (C) 2014 Red Hat, Inc. * Copyright (C) 2011 Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> * * This library is free software; you can redistribute it and/or @@ -269,6 +270,7 @@ virNodeSuspendSupportsTargetPMUtils(unsigned int target, bool *supported) } #endif +#ifdef WITH_SYSTEMD_DAEMON static int virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported) { @@ -292,6 +294,7 @@ virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported) return ret; } +#endif /* WITH_SYSTEMD_DAEMON */ /** * virNodeSuspendSupportsTarget: @@ -310,14 +313,23 @@ virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported) static int virNodeSuspendSupportsTarget(unsigned int target, bool *supported) { - int ret; + int ret = 0; + +#ifdef WITH_SYSTEMD_DAEMON + if (virNodeSuspendSupportsTargetSystemd(target, supported) == 0) + goto cleanup; +#endif - ret = virNodeSuspendSupportsTargetSystemd(target, supported); #ifdef WITH_PM_UTILS - if (ret < 0) - ret = virNodeSuspendSupportsTargetPMUtils(target, supported); + if (virNodeSuspendSupportsTargetPMUtils(target, supported) == 0) + goto cleanup; #endif + ret = -1; + virReportSystemError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to get supported suspend types")); + + cleanup: return ret; } diff --git i/src/util/virsystemd.c w/src/util/virsystemd.c index e9ca564..d953f8a 100644 --- i/src/util/virsystemd.c +++ w/src/util/virsystemd.c @@ -1,7 +1,7 @@ /* * virsystemd.c: helpers for using systemd APIs * - * Copyright (C) 2013 Red Hat, Inc. + * Copyright (C) 2013, 2014 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -326,6 +326,7 @@ virSystemdNotifyStartup(void) #endif } +#ifdef WITH_SYSTEMD_DAEMON static int virSystemdPMSupportTarget(const char *methodName, bool *result) { @@ -370,6 +371,17 @@ virSystemdPMSupportTarget(const char *methodName, bool *result) return ret; } +#else /* ! WITH_SYSTEMD_DAEMON */ + +static int +virSystemdPMSupportTarget(const char *methodName ATTRIBUTE_UNUSED, + bool *result ATTRIBUTE_UNUSED) +{ + return -1; +} + +#endif /* ! WITH_SYSTEMD_DAEMON */ + int virSystemdCanSuspend(bool *result) { return virSystemdPMSupportTarget("CanSuspend", result); -- Martin

On Mon, Apr 14, 2014 at 02:20:11PM +0200, Martin Kletzander wrote:
On Mon, Apr 14, 2014 at 01:02:02PM +0100, Daniel P. Berrange wrote:
On Mon, Apr 14, 2014 at 01:41:18PM +0200, Martin Kletzander wrote:
Adding dbus_message_unref() into virDBusMessageDecodeArgs() makes sure that the message gets unref'd, thus making one more pure dbus call not necessary. Even though we are calling a lot of dbus_* functions outside virdbus (which should be fixed in the future IMHO), this patch fixes only this one instance because it merely aims to fix a build-breaker caused by improperly included dbus.h. The message printed when failing (using --without-dbus) is:
diff --git a/src/util/virdbus.c b/src/util/virdbus.c index 0cd3858..aef1d34 100644 --- a/src/util/virdbus.c +++ b/src/util/virdbus.c @@ -1112,6 +1112,7 @@ int virDBusMessageDecodeArgs(DBusMessage* msg, }
ret = virDBusMessageIterDecode(&iter, types, args); + dbus_message_unref(msg);
cleanup: return ret;
NACK, this is basically reverting the change I did previously and will break the firewall patches I have pending.
OK, this makes sense if we do one of the following:
a) Implement a virDBusMessageUnref() which does the same thing if we have dbus, which would be no-op otherwise, thus making pure dbus_* calls completely wrapped such uses or
b) encapsulate systemd checks for pm-utils in ifdef WITH_SYSTEMD_DAEMON like this:
diff --git i/src/util/virnodesuspend.c w/src/util/virnodesuspend.c index 59b84ef..20b85b8 100644 --- i/src/util/virnodesuspend.c +++ w/src/util/virnodesuspend.c @@ -1,6 +1,7 @@ /* * virnodesuspend.c: Support for suspending a node (host machine) * + * Copyright (C) 2014 Red Hat, Inc. * Copyright (C) 2011 Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> * * This library is free software; you can redistribute it and/or @@ -269,6 +270,7 @@ virNodeSuspendSupportsTargetPMUtils(unsigned int target, bool *supported) } #endif
+#ifdef WITH_SYSTEMD_DAEMON static int virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported) { @@ -292,6 +294,7 @@ virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported)
return ret; } +#endif /* WITH_SYSTEMD_DAEMON */
/** * virNodeSuspendSupportsTarget: @@ -310,14 +313,23 @@ virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported) static int virNodeSuspendSupportsTarget(unsigned int target, bool *supported) { - int ret; + int ret = 0; + +#ifdef WITH_SYSTEMD_DAEMON + if (virNodeSuspendSupportsTargetSystemd(target, supported) == 0) + goto cleanup; +#endif
- ret = virNodeSuspendSupportsTargetSystemd(target, supported); #ifdef WITH_PM_UTILS - if (ret < 0) - ret = virNodeSuspendSupportsTargetPMUtils(target, supported); + if (virNodeSuspendSupportsTargetPMUtils(target, supported) == 0) + goto cleanup; #endif
+ ret = -1; + virReportSystemError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to get supported suspend types")); + + cleanup: return ret; }
diff --git i/src/util/virsystemd.c w/src/util/virsystemd.c index e9ca564..d953f8a 100644 --- i/src/util/virsystemd.c +++ w/src/util/virsystemd.c @@ -1,7 +1,7 @@ /* * virsystemd.c: helpers for using systemd APIs * - * Copyright (C) 2013 Red Hat, Inc. + * Copyright (C) 2013, 2014 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -326,6 +326,7 @@ virSystemdNotifyStartup(void) #endif }
+#ifdef WITH_SYSTEMD_DAEMON static int virSystemdPMSupportTarget(const char *methodName, bool *result) { @@ -370,6 +371,17 @@ virSystemdPMSupportTarget(const char *methodName, bool *result) return ret; }
+#else /* ! WITH_SYSTEMD_DAEMON */ + +static int +virSystemdPMSupportTarget(const char *methodName ATTRIBUTE_UNUSED, + bool *result ATTRIBUTE_UNUSED) +{ + return -1; +} + +#endif /* ! WITH_SYSTEMD_DAEMON */
How about making this method return '0' instead of '-1'. After all, if we haven't built systemd,then logging it doesn't support the PM mode being queried. That way we don't need conditionals for the callers of this method - they'll just do the right thing. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Mon, Apr 14, 2014 at 01:33:21PM +0100, Daniel P. Berrange wrote:
On Mon, Apr 14, 2014 at 02:20:11PM +0200, Martin Kletzander wrote:
On Mon, Apr 14, 2014 at 01:02:02PM +0100, Daniel P. Berrange wrote:
On Mon, Apr 14, 2014 at 01:41:18PM +0200, Martin Kletzander wrote:
Adding dbus_message_unref() into virDBusMessageDecodeArgs() makes sure that the message gets unref'd, thus making one more pure dbus call not necessary. Even though we are calling a lot of dbus_* functions outside virdbus (which should be fixed in the future IMHO), this patch fixes only this one instance because it merely aims to fix a build-breaker caused by improperly included dbus.h. The message printed when failing (using --without-dbus) is:
diff --git a/src/util/virdbus.c b/src/util/virdbus.c index 0cd3858..aef1d34 100644 --- a/src/util/virdbus.c +++ b/src/util/virdbus.c @@ -1112,6 +1112,7 @@ int virDBusMessageDecodeArgs(DBusMessage* msg, }
ret = virDBusMessageIterDecode(&iter, types, args); + dbus_message_unref(msg);
cleanup: return ret;
NACK, this is basically reverting the change I did previously and will break the firewall patches I have pending.
OK, this makes sense if we do one of the following:
a) Implement a virDBusMessageUnref() which does the same thing if we have dbus, which would be no-op otherwise, thus making pure dbus_* calls completely wrapped such uses or
b) encapsulate systemd checks for pm-utils in ifdef WITH_SYSTEMD_DAEMON like this:
diff --git i/src/util/virnodesuspend.c w/src/util/virnodesuspend.c index 59b84ef..20b85b8 100644 --- i/src/util/virnodesuspend.c +++ w/src/util/virnodesuspend.c @@ -1,6 +1,7 @@ /* * virnodesuspend.c: Support for suspending a node (host machine) * + * Copyright (C) 2014 Red Hat, Inc. * Copyright (C) 2011 Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> * * This library is free software; you can redistribute it and/or @@ -269,6 +270,7 @@ virNodeSuspendSupportsTargetPMUtils(unsigned int target, bool *supported) } #endif
+#ifdef WITH_SYSTEMD_DAEMON static int virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported) { @@ -292,6 +294,7 @@ virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported)
return ret; } +#endif /* WITH_SYSTEMD_DAEMON */
/** * virNodeSuspendSupportsTarget: @@ -310,14 +313,23 @@ virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported) static int virNodeSuspendSupportsTarget(unsigned int target, bool *supported) { - int ret; + int ret = 0; + +#ifdef WITH_SYSTEMD_DAEMON + if (virNodeSuspendSupportsTargetSystemd(target, supported) == 0) + goto cleanup; +#endif
- ret = virNodeSuspendSupportsTargetSystemd(target, supported); #ifdef WITH_PM_UTILS - if (ret < 0) - ret = virNodeSuspendSupportsTargetPMUtils(target, supported); + if (virNodeSuspendSupportsTargetPMUtils(target, supported) == 0) + goto cleanup; #endif
[1]
+ ret = -1; + virReportSystemError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to get supported suspend types")); + + cleanup: return ret; }
diff --git i/src/util/virsystemd.c w/src/util/virsystemd.c index e9ca564..d953f8a 100644 --- i/src/util/virsystemd.c +++ w/src/util/virsystemd.c @@ -1,7 +1,7 @@ /* * virsystemd.c: helpers for using systemd APIs * - * Copyright (C) 2013 Red Hat, Inc. + * Copyright (C) 2013, 2014 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -326,6 +326,7 @@ virSystemdNotifyStartup(void) #endif }
+#ifdef WITH_SYSTEMD_DAEMON static int virSystemdPMSupportTarget(const char *methodName, bool *result) { @@ -370,6 +371,17 @@ virSystemdPMSupportTarget(const char *methodName, bool *result) return ret; }
+#else /* ! WITH_SYSTEMD_DAEMON */ + +static int +virSystemdPMSupportTarget(const char *methodName ATTRIBUTE_UNUSED, + bool *result ATTRIBUTE_UNUSED) +{ + return -1; +} + +#endif /* ! WITH_SYSTEMD_DAEMON */
How about making this method return '0' instead of '-1'. After all, if we haven't built systemd,then logging it doesn't support the PM mode being queried. That way we don't need conditionals for the callers of this method - they'll just do the right thing.
But then virNodeSuspendSupportsTarget() [1] will succeed without querying anything else. Or have I misunderstood and you meant changing virNodeSuspendSupportsTarget() so that it queries everything possible until supported != true? Martin

On Mon, Apr 14, 2014 at 02:51:18PM +0200, Martin Kletzander wrote:
On Mon, Apr 14, 2014 at 01:33:21PM +0100, Daniel P. Berrange wrote:
On Mon, Apr 14, 2014 at 02:20:11PM +0200, Martin Kletzander wrote:
On Mon, Apr 14, 2014 at 01:02:02PM +0100, Daniel P. Berrange wrote:
On Mon, Apr 14, 2014 at 01:41:18PM +0200, Martin Kletzander wrote:
Adding dbus_message_unref() into virDBusMessageDecodeArgs() makes sure that the message gets unref'd, thus making one more pure dbus call not necessary. Even though we are calling a lot of dbus_* functions outside virdbus (which should be fixed in the future IMHO), this patch fixes only this one instance because it merely aims to fix a build-breaker caused by improperly included dbus.h. The message printed when failing (using --without-dbus) is:
diff --git a/src/util/virdbus.c b/src/util/virdbus.c index 0cd3858..aef1d34 100644 --- a/src/util/virdbus.c +++ b/src/util/virdbus.c @@ -1112,6 +1112,7 @@ int virDBusMessageDecodeArgs(DBusMessage* msg, }
ret = virDBusMessageIterDecode(&iter, types, args); + dbus_message_unref(msg);
cleanup: return ret;
NACK, this is basically reverting the change I did previously and will break the firewall patches I have pending.
OK, this makes sense if we do one of the following:
a) Implement a virDBusMessageUnref() which does the same thing if we have dbus, which would be no-op otherwise, thus making pure dbus_* calls completely wrapped such uses or
b) encapsulate systemd checks for pm-utils in ifdef WITH_SYSTEMD_DAEMON like this:
diff --git i/src/util/virnodesuspend.c w/src/util/virnodesuspend.c index 59b84ef..20b85b8 100644 --- i/src/util/virnodesuspend.c +++ w/src/util/virnodesuspend.c @@ -1,6 +1,7 @@ /* * virnodesuspend.c: Support for suspending a node (host machine) * + * Copyright (C) 2014 Red Hat, Inc. * Copyright (C) 2011 Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> * * This library is free software; you can redistribute it and/or @@ -269,6 +270,7 @@ virNodeSuspendSupportsTargetPMUtils(unsigned int target, bool *supported) } #endif
+#ifdef WITH_SYSTEMD_DAEMON static int virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported) { @@ -292,6 +294,7 @@ virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported)
return ret; } +#endif /* WITH_SYSTEMD_DAEMON */
/** * virNodeSuspendSupportsTarget: @@ -310,14 +313,23 @@ virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported) static int virNodeSuspendSupportsTarget(unsigned int target, bool *supported) { - int ret; + int ret = 0; + +#ifdef WITH_SYSTEMD_DAEMON + if (virNodeSuspendSupportsTargetSystemd(target, supported) == 0) + goto cleanup; +#endif
- ret = virNodeSuspendSupportsTargetSystemd(target, supported); #ifdef WITH_PM_UTILS - if (ret < 0) - ret = virNodeSuspendSupportsTargetPMUtils(target, supported); + if (virNodeSuspendSupportsTargetPMUtils(target, supported) == 0) + goto cleanup; #endif
[1]
+ ret = -1; + virReportSystemError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to get supported suspend types")); + + cleanup: return ret; }
diff --git i/src/util/virsystemd.c w/src/util/virsystemd.c index e9ca564..d953f8a 100644 --- i/src/util/virsystemd.c +++ w/src/util/virsystemd.c @@ -1,7 +1,7 @@ /* * virsystemd.c: helpers for using systemd APIs * - * Copyright (C) 2013 Red Hat, Inc. + * Copyright (C) 2013, 2014 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -326,6 +326,7 @@ virSystemdNotifyStartup(void) #endif }
+#ifdef WITH_SYSTEMD_DAEMON static int virSystemdPMSupportTarget(const char *methodName, bool *result) { @@ -370,6 +371,17 @@ virSystemdPMSupportTarget(const char *methodName, bool *result) return ret; }
+#else /* ! WITH_SYSTEMD_DAEMON */ + +static int +virSystemdPMSupportTarget(const char *methodName ATTRIBUTE_UNUSED, + bool *result ATTRIBUTE_UNUSED) +{ + return -1; +} + +#endif /* ! WITH_SYSTEMD_DAEMON */
How about making this method return '0' instead of '-1'. After all, if we haven't built systemd,then logging it doesn't support the PM mode being queried. That way we don't need conditionals for the callers of this method - they'll just do the right thing.
But then virNodeSuspendSupportsTarget() [1] will succeed without querying anything else. Or have I misunderstood and you meant changing virNodeSuspendSupportsTarget() so that it queries everything possible until supported != true?
Hmm, actually I see there's a flaw in virNodeSuspendSupportsTarget in the way it deals with fallback. It is not distinguishing between the case that systemd login1 servie is not available, from the case where checking returns a hard error. Basically when systemd is compiled out, we need to make it appear that login1 is not available. So IMHO virSystemdCanXXXX needs to have 3 return values 1: service available, *result gives value 0: service not available. -1: error querying service Then virNodeSuspendSupportsTarget, should only fallback to trying the pm-utils code when ret == 0. Then when systemd is compiled out, we can return ret ==0. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Mon, Apr 14, 2014 at 02:29:36PM +0100, Daniel P. Berrange wrote:
On Mon, Apr 14, 2014 at 02:51:18PM +0200, Martin Kletzander wrote:
On Mon, Apr 14, 2014 at 01:33:21PM +0100, Daniel P. Berrange wrote:
On Mon, Apr 14, 2014 at 02:20:11PM +0200, Martin Kletzander wrote:
On Mon, Apr 14, 2014 at 01:02:02PM +0100, Daniel P. Berrange wrote:
On Mon, Apr 14, 2014 at 01:41:18PM +0200, Martin Kletzander wrote:
Adding dbus_message_unref() into virDBusMessageDecodeArgs() makes sure that the message gets unref'd, thus making one more pure dbus call not necessary. Even though we are calling a lot of dbus_* functions outside virdbus (which should be fixed in the future IMHO), this patch fixes only this one instance because it merely aims to fix a build-breaker caused by improperly included dbus.h. The message printed when failing (using --without-dbus) is:
diff --git a/src/util/virdbus.c b/src/util/virdbus.c index 0cd3858..aef1d34 100644 --- a/src/util/virdbus.c +++ b/src/util/virdbus.c @@ -1112,6 +1112,7 @@ int virDBusMessageDecodeArgs(DBusMessage* msg, }
ret = virDBusMessageIterDecode(&iter, types, args); + dbus_message_unref(msg);
cleanup: return ret;
NACK, this is basically reverting the change I did previously and will break the firewall patches I have pending.
OK, this makes sense if we do one of the following:
a) Implement a virDBusMessageUnref() which does the same thing if we have dbus, which would be no-op otherwise, thus making pure dbus_* calls completely wrapped such uses or
b) encapsulate systemd checks for pm-utils in ifdef WITH_SYSTEMD_DAEMON like this:
diff --git i/src/util/virnodesuspend.c w/src/util/virnodesuspend.c index 59b84ef..20b85b8 100644 --- i/src/util/virnodesuspend.c +++ w/src/util/virnodesuspend.c @@ -1,6 +1,7 @@ /* * virnodesuspend.c: Support for suspending a node (host machine) * + * Copyright (C) 2014 Red Hat, Inc. * Copyright (C) 2011 Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> * * This library is free software; you can redistribute it and/or @@ -269,6 +270,7 @@ virNodeSuspendSupportsTargetPMUtils(unsigned int target, bool *supported) } #endif
+#ifdef WITH_SYSTEMD_DAEMON static int virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported) { @@ -292,6 +294,7 @@ virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported)
return ret; } +#endif /* WITH_SYSTEMD_DAEMON */
/** * virNodeSuspendSupportsTarget: @@ -310,14 +313,23 @@ virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported) static int virNodeSuspendSupportsTarget(unsigned int target, bool *supported) { - int ret; + int ret = 0; + +#ifdef WITH_SYSTEMD_DAEMON + if (virNodeSuspendSupportsTargetSystemd(target, supported) == 0) + goto cleanup; +#endif
- ret = virNodeSuspendSupportsTargetSystemd(target, supported); #ifdef WITH_PM_UTILS - if (ret < 0) - ret = virNodeSuspendSupportsTargetPMUtils(target, supported); + if (virNodeSuspendSupportsTargetPMUtils(target, supported) == 0) + goto cleanup; #endif
[1]
+ ret = -1; + virReportSystemError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to get supported suspend types")); + + cleanup: return ret; }
diff --git i/src/util/virsystemd.c w/src/util/virsystemd.c index e9ca564..d953f8a 100644 --- i/src/util/virsystemd.c +++ w/src/util/virsystemd.c @@ -1,7 +1,7 @@ /* * virsystemd.c: helpers for using systemd APIs * - * Copyright (C) 2013 Red Hat, Inc. + * Copyright (C) 2013, 2014 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -326,6 +326,7 @@ virSystemdNotifyStartup(void) #endif }
+#ifdef WITH_SYSTEMD_DAEMON static int virSystemdPMSupportTarget(const char *methodName, bool *result) { @@ -370,6 +371,17 @@ virSystemdPMSupportTarget(const char *methodName, bool *result) return ret; }
+#else /* ! WITH_SYSTEMD_DAEMON */ + +static int +virSystemdPMSupportTarget(const char *methodName ATTRIBUTE_UNUSED, + bool *result ATTRIBUTE_UNUSED) +{ + return -1; +} + +#endif /* ! WITH_SYSTEMD_DAEMON */
How about making this method return '0' instead of '-1'. After all, if we haven't built systemd,then logging it doesn't support the PM mode being queried. That way we don't need conditionals for the callers of this method - they'll just do the right thing.
But then virNodeSuspendSupportsTarget() [1] will succeed without querying anything else. Or have I misunderstood and you meant changing virNodeSuspendSupportsTarget() so that it queries everything possible until supported != true?
Hmm, actually I see there's a flaw in virNodeSuspendSupportsTarget in the way it deals with fallback. It is not distinguishing between the case that systemd login1 servie is not available, from the case where checking returns a hard error.
Basically when systemd is compiled out, we need to make it appear that login1 is not available.
So IMHO virSystemdCanXXXX needs to have 3 return values
1: service available, *result gives value 0: service not available. -1: error querying service
Then virNodeSuspendSupportsTarget, should only fallback to trying the pm-utils code when ret == 0.
We usually use ret == 0 as complete success, so I'd flip the meaning of 1 and 0 (if you don't want to use -1 and -2 for different errors as in other APIs), but otherwise it should fix the problem, so I'm sending it as a v2 when tested. Martin
Then when systemd is compiled out, we can return ret ==0.
Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
participants (2)
-
Daniel P. Berrange
-
Martin Kletzander