[libvirt] [PATCH] network: fix network driver startup for qemu:///session
Eric Blake
eblake at redhat.com
Thu May 2 18:22:14 UTC 2013
On 05/02/2013 12:06 PM, Laine Stump wrote:
> This should resolve https://bugzilla.redhat.com/show_bug.cgi?id=958907
>
> Recent new addition of code to read/write active network state to the
> NETWORK_STATE_DIR in the network driver broke startup for
> qemu:///session. The network driver had several state file paths
> hardcoded to /var, which could never possibly work in session mode.
>
> This patch modifies *all* state files to use a variable string that is
> set differently according to whether or not we're running privileged.
>
> There are very definitely other problems preventing dnsmasq and radvd
> from running in non-privileged mode, but it's more consistent to have
> the directories used by them be determined in the same fashion.
> ---
> src/network/bridge_driver.c | 155 ++++++++++++++++++++++++++++----------------
> 1 file changed, 100 insertions(+), 55 deletions(-)
>
>
> -#define NETWORK_PID_DIR LOCALSTATEDIR "/run/libvirt/network"
So previously, this constant represented the network runtime directory
relative to the configured state dir (default /var in a distro
installation)...
> -#define NETWORK_STATE_DIR LOCALSTATEDIR "/lib/libvirt/network"
> +#define NETWORK_PID_DIR "/run/libvirt/network"
Now it is just the relative suffix of an (as-yet) unspecified prefix...
> @@ -84,6 +83,10 @@ struct network_driver {
> iptablesContext *iptables;
> char *networkConfigDir;
> char *networkAutostartDir;
> + char *stateDir;
> + char *pidDir;
> + char *dnsmasqStateDir;
> + char *radvdStateDir;
...where the appropriate prefix is computed at initialization and stored
for later use...
> char *logDir;
> dnsmasqCapsPtr dnsmasqCaps;
> };
> @@ -133,8 +136,8 @@ networkDnsmasqLeaseFileNameDefault(const char *netname)
> {
> char *leasefile;
>
> - ignore_value(virAsprintf(&leasefile, DNSMASQ_STATE_DIR "/%s.leases",
> - netname));
> + ignore_value(virAsprintf(&leasefile, "%s/%s.leases",
> + driverState->dnsmasqStateDir, netname));
...all uses now use the computed value instead of the hard-coded macro...
> @@ -374,27 +380,59 @@ networkStateInitialize(bool privileged,
> networkDriverLock(driverState);
>
> if (privileged) {
> - if (virAsprintf(&driverState->logDir,
> - "%s/log/libvirt/qemu", LOCALSTATEDIR) == -1)
> - goto out_of_memory;
> -
> - if ((base = strdup(SYSCONFDIR "/libvirt")) == NULL)
> + if (((base = strdup(SYSCONFDIR "/libvirt")) == NULL) ||
> + ((driverState->logDir
> + = strdup(LOCALSTATEDIR "/log/libvirt/qemu")) == NULL) ||
> + ((driverState->stateDir
> + = strdup(LOCALSTATEDIR NETWORK_STATE_DIR)) == NULL) ||
...privileged initialization uses LOCALSTATEDIR as its location where
the now-relative NETWORK_STATE_DIR is placed,...[1]
> + ((driverState->pidDir
> + = strdup(LOCALSTATEDIR NETWORK_PID_DIR)) == NULL) ||
> + ((driverState->dnsmasqStateDir
> + = strdup(LOCALSTATEDIR DNSMASQ_STATE_DIR)) == NULL) ||
> + ((driverState->radvdStateDir
> + = strdup(LOCALSTATEDIR RADVD_STATE_DIR)) == NULL)) {
> goto out_of_memory;
> + }
> } else {
> char *userdir = virGetUserCacheDirectory();
userdir is now malloc'd...[2]
>
> if (!userdir)
> goto error;
>
> + userdir = virGetUserConfigDirectory();
[2]...but this overwrites it. Oops.
> + if (virAsprintf(&base, "%s", userdir) < 0) {
> + VIR_FREE(userdir);
> + goto out_of_memory;
> + }
> + VIR_FREE(userdir);
Huh? Simplify this to:
base = virGetUserConfigDirectory();
no need to waste a malloc on userdir, just to re-malloc an identical
copy of it into base via a beefy virAsprintf call.
> +
> if (virAsprintf(&driverState->logDir,
> - "%s/qemu/log", userdir) == -1) {
> + "%s/qemu/log", userdir) < 0) {
Huh? Use-after-free of userdir. Did you mean base?
> VIR_FREE(userdir);
> goto out_of_memory;
> }
> VIR_FREE(userdir);
>
> - userdir = virGetUserConfigDirectory();
> - if (virAsprintf(&base, "%s", userdir) == -1) {
> + if (!(userdir = virGetUserRuntimeDirectory()))
> + goto error;
> +
> + if (virAsprintf(&driverState->stateDir,
> + "%s" NETWORK_STATE_DIR, userdir) < 0) {
[2]...for non-privileged code, we are now using the directory relative
to the user directory. The idea makes sense, but your implementation of
the idea on the qemu:///session side of things needs work.
> + if (virAsprintf(&driverState->pidDir,
> + "%s" NETWORK_PID_DIR, userdir) < 0) {
> + VIR_FREE(userdir);
> + goto out_of_memory;
> + }
> + if (virAsprintf(&driverState->dnsmasqStateDir,
> + "%s" DNSMASQ_STATE_DIR, userdir) < 0) {
> + VIR_FREE(userdir);
> + goto out_of_memory;
> + }
> + if (virAsprintf(&driverState->radvdStateDir,
> + "%s" RADVD_STATE_DIR, userdir) < 0) {
> VIR_FREE(userdir);
> goto out_of_memory;
That's a lot of VIR_FREE(userdir) calls; can you just pre-initialize it
to NULL and just blindly move the VIR_FREE(userdir) into the
out_of_memory label? Or even chain the conditionals:
if (virAsprintf(&driverState->pidDir,
"%s" NETWORK_PID_DIR, userdir) < 0 ||
virAsprintf(&driverState->dnsmasqStateDir,
"%s" DNSMASQ_STATE_DIR, userdir) < 0 || ...
Looking forward to v2.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 621 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20130502/25f5d36d/attachment-0001.sig>
More information about the libvir-list
mailing list