[libvirt] [PATCH] qemu: Search binaries in PATH instead of hardcoding /usr/bin

Matthias Bolte matthias.bolte at googlemail.com
Fri Jan 22 16:28:12 UTC 2010


2010/1/22 Daniel P. Berrange <berrange at redhat.com>:
> On Wed, Jan 20, 2010 at 02:46:10AM +0100, Matthias Bolte wrote:
>> @@ -792,16 +797,30 @@ qemudCapsInitGuest(virCapsPtr caps,
>>       */
>>      if (STREQ(info->arch, hostmachine) ||
>>          (STREQ(hostmachine, "x86_64") && STREQ(info->arch, "i686"))) {
>> -        const char *const kvmbins[] = { "/usr/bin/qemu-kvm", /* Fedora */
>> -                                        "/usr/bin/kvm" }; /* Upstream .spec */
>> +        if (access("/dev/kvm", F_OK) == 0) {
>> +            const char *const kvmbins[] = { "qemu-kvm", /* Fedora */
>> +                                            "kvm" }; /* Upstream .spec */
>> +
>> +            for (i = 0; i < ARRAY_CARDINALITY(kvmbins); ++i) {
>> +                kvmbin = virFindFileInPath(kvmbins[i]);
>> +
>> +                if (kvmbin == NULL || access(kvmbin, X_OK) != 0) {
>> +                    VIR_FREE(kvmbin);
>> +                    continue;
>> +                }
>>
>> -        for (i = 0; i < ARRAY_CARDINALITY(kvmbins); ++i) {
>> -            if (access(kvmbins[i], X_OK) == 0 &&
>> -                access("/dev/kvm", F_OK) == 0) {
>>                  haskvm = 1;
>> -                kvmbin = kvmbins[i];
>> -                if (!binary)
>> -                    binary = kvmbin;
>> +
>> +                if (binary == NULL) {
>> +                    binary = strdup(kvmbin);
>
> Why does this need to strdup(kvmbin), when virFindFileInPath() is
> already returning a newly allocated string ?  Seems like we could
> just avoid that

The common case is binary pointing to a QEMU binary and if KVM could
be used and is available kvmbin points to a KVM enabled QEMU binary.
So the paths a different in the common case. In the cleanup section
both strings need to be freed.

The special case is if binary is NULL but we find a KVM binary, then
binary is strdup'ed from kvmbin. Before this patch binary and kvmbin
were stack allocated and binary = kvmbin was okay. Now binary = kvmbin
would result in a double free with

    VIR_FREE(binary);
    VIR_FREE(kvmbin);

But you're right, I just thought about it and

    binary = strdup(kvmbin);

could be changed back to

    binary = kvmbin;

and the cleanup code could be changed to

    if (binary == kvmbin) {
        /* don't double free */
        VIR_FREE(binary);
    } else {
        VIR_FREE(binary);
        VIR_FREE(kvmbin);
    }

to avoid a double free.

>> +
>> +                    if (binary == NULL) {
>> +                        virReportOOMError(NULL);
>> +                        VIR_FREE(kvmbin);
>> +                        return -1;
>> +                    }
>> +                }
>> +
>>                  break;
>>              }
>
> I think this loop is also leaking 'kvmbin', since it just
> overrwrites 'kvmbin' on each iteration, the final cleanup
> code will only free the last one that was allocated

No leak here. The for loop can be left at 3 points:

- continue; if binary not found or not executable
- return -1; on OOM error
- break; on success

In both negative cases kvmbin is freed.

>> -                return -1;
>> +                goto error;
>>          }
>>      }
>>
>> +    VIR_FREE(binary);
>> +    VIR_FREE(kvmbin);
>> +
>>      return 0;
>> +
>> +no_memory:
>> +    virReportOOMError(NULL);
>> +
>> +error:
>> +    VIR_FREE(binary);
>> +    VIR_FREE(kvmbin);
>> +    virCapabilitiesFreeMachines(machines, nmachines);
>> +
>> +    return -1;
>>  }
>>
>
>
> Generally the patch looks OK though
>
> Daniel
>

Version 2 of the patch is attached.

Matthias
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-qemu-Search-binaries-in-PATH-instead-of-hardcoding_v2.diff
Type: text/x-diff
Size: 10507 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20100122/857c2af1/attachment-0001.bin>


More information about the libvir-list mailing list