[libvirt] [PATCH v2 2/3] cpu: Implement guestData and update for PPC

Li Zhang zhlcindy at gmail.com
Mon Sep 9 03:19:44 UTC 2013


On 2013年09月06日 19:32, John Ferlan wrote:
> On 09/03/2013 02:28 AM, Li Zhang wrote:
>> From: Li Zhang <zhlcindy at linux.vnet.ibm.com>
>>
>> On Power platform, Power7+ can support Power7 guest.
>> It needs to define XML configuration to specify guest's CPU model.
>>
>> For exmaple:
>>    <cpu match='exact'>
>>      <model>POWER7_v2.1</model>
>>      <vendor>IBM</vendor>
>>    </cpu>
>>
>> Signed-off-by: Li Zhang <zhlcindy at linux.vnet.ibm.com>
>> ---
>>   src/cpu/cpu_powerpc.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++--
>>   1 file changed, 174 insertions(+), 4 deletions(-)
>>
> ...<snip>...
>
> There were Coverity RESOURCE_LEAK's detected in this code - so while
> looking at those I looked at the rest of this function and had a few
> comments...
>
>> +
>> +static virCPUCompareResult
>> +ppcCompute(virCPUDefPtr host,
>> +             const virCPUDefPtr cpu,
>> +             virCPUDataPtr *guestData,
>> +             char **message)
>> +
>> +{
>> +    struct ppc_map *map = NULL;
>> +    struct ppc_model *host_model = NULL;
>> +    struct ppc_model *guest_model = NULL;
>> +
>> +    int ret = 0;
> NOTE: To be consistent should this be 'VIR_CPU_COMPARE_INCOMPATIBLE'
> (e.g. 0)?   or better yet 'VIR_CPU_COMPARE_ERROR' (-1).
OK, I will change it.


>
>> +    virArch arch;
>> +    size_t i;
>> +
>> +    if (cpu->arch != VIR_ARCH_NONE) {
>> +        bool found = false;
>> +
>> +        for (i = 0; i < ARRAY_CARDINALITY(archs); i++) {
>> +            if (archs[i] == cpu->arch) {
>> +                found = true;
>> +                break;
>> +            }
>> +        }
>> +
>> +        if (!found) {
>> +            VIR_DEBUG("CPU arch %s does not match host arch",
>> +                      virArchToString(cpu->arch));
>> +            if (message &&
>> +                virAsprintf(message,
>> +                            _("CPU arch %s does not match host arch"),
>> +                            virArchToString(cpu->arch)) < 0)
>> +                goto error;
>> +            return VIR_CPU_COMPARE_INCOMPATIBLE;
> Why on a "message" do you go to error which changes the return value to
> ERROR, while if message isn't defined you return INCOMPATIBLE?  Seems
> you'd want to set "ret" to INCOMPATIBLE, then goto out (or cleanup).
> Does the caller differentiate ERROR and INCOMPATIBLE?  Does it do
> something different if it passed a message, but you got different return
> values?
>

On a message, if virAsprintf return value < 0, it will goto error which 
means some error happens.

This place return INCOMPATIBLE only if (!found) not if (!message).
It doesn't belong to the block of 'if(message & ...)'.

This means that we can't find out any archs we support matched.
So we need to report INCOMPATIBLE.

We don't alloc any memory here, map, host_model and guest_model are all 
NULL.

>> +        }
>> +        arch = cpu->arch;
>> +    } else {
>> +        arch = host->arch;
>> +    }
>> +
>> +    if (cpu->vendor &&
>> +        (!host->vendor || STRNEQ(cpu->vendor, host->vendor))) {
>> +        VIR_DEBUG("host CPU vendor does not match required CPU vendor %s",
>> +                  cpu->vendor);
>> +        if (message &&
>> +            virAsprintf(message,
>> +                        _("host CPU vendor does not match required "
>> +                        "CPU vendor %s"),
>> +                        cpu->vendor) < 0)
>> +            goto error;
>> +        return VIR_CPU_COMPARE_INCOMPATIBLE;
> Same comment as above
>
>> +    }
>> +
>> +    if (!(map = ppcLoadMap()) ||
>> +        !(host_model = ppcModelFromCPU(host, map)) ||
>> +        !(guest_model = ppcModelFromCPU(cpu, map)))
>> +        goto error;
> If you initialize ret to COMPARE_ERROR, then it's a goto out (or
> cleanup)...  Also the only way these are ever used is if (guestData !=
> NULL), thus why not put them inside the below if condition?

OK, let me clean these goto clause.

>> +
>> +    if (guestData != NULL) {
>> +        if (cpu->type == VIR_CPU_TYPE_GUEST &&
>> +            cpu->match == VIR_CPU_MATCH_STRICT &&
>> +            STRNEQ(guest_model->name, host_model->name)) {
>> +            VIR_DEBUG("host CPU model does not match required CPU model %s",
>> +                      guest_model->name);
>> +            if (message &&
>> +                virAsprintf(message,
>> +                            _("host CPU model does not match required "
>> +                            "CPU model %s"),
>> +                            guest_model->name) < 0)
>> +                goto error;
>> +            return VIR_CPU_COMPARE_INCOMPATIBLE;
> Coverity found a RESOURCE_LEAK here on 'host_model' and 'guest_model'.
> Coverity missed that 'map' is also leaked...

Ah, right. There is memory leak here. Will clean this.

>
> And this would have the same comments as above regarding the goto/return
>
>> +        }
>> +
>> +        if (!(*guestData = ppcMakeCPUData(arch, &guest_model->data)))
>> +            goto error;
> Initializing ret to ERROR would mean this would be a goto out (or cleanup).
>
>> +    }
>> +
>> +    ret = VIR_CPU_COMPARE_IDENTICAL;
>> +
>> +out:
> I think by convention this is usually "cleanup:"
>
>
> John
>
>> +    ppcMapFree(map);
>> +    ppcModelFree(host_model);
>> +    ppcModelFree(guest_model);
>> +    return ret;
>> +
>> +error:
>> +    ret = VIR_CPU_COMPARE_ERROR;
>> +    goto out;
>> +}
>> +
>




More information about the libvir-list mailing list