Return the number of disks present in the configuration of the test
domain when called with @errors as NULL and @maxerrors as 0.
Otherwise report an error for every second disk, assigning available
error codes in a cyclic order.
Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com>
---
src/test/test_driver.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index a06d1fc402..527c2f5d3b 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -3046,6 +3046,47 @@ static int testDomainSetAutostart(virDomainPtr domain,
return 0;
}
+static int testDomainGetDiskErrors(virDomainPtr dom,
+ virDomainDiskErrorPtr errors,
+ unsigned int maxerrors,
+ unsigned int flags)
+{
+ virDomainObjPtr vm = NULL;
+ int ret = -1;
+ size_t i;
+ int n = 0;
+ int codes[] = {VIR_DOMAIN_DISK_ERROR_UNSPEC, VIR_DOMAIN_DISK_ERROR_NO_SPACE};
+ size_t ncodes = sizeof(codes) / sizeof(codes[0]);
+
+ virCheckFlags(0, -1);
+
+ if (!(vm = testDomObjFromDomain(dom)))
+ goto cleanup;
+
+ if (virDomainObjCheckActive(vm) < 0)
+ goto cleanup;
+
+ if (!errors) {
+ ret = vm->def->ndisks;
+ } else {
+ for (i = 1; i < vm->def->ndisks && n < maxerrors; i += 2) {
+ if (VIR_STRDUP(errors[n].disk, vm->def->disks[i]->dst) < 0)
+ goto cleanup;
+ errors[n].error = codes[n % ncodes];
+ n++;
+ }
+ ret = n;
+ }
+
+ cleanup:
+ virDomainObjEndAPI(&vm);
+ if (ret < 0) {
+ for (i = 0; i < n; i++)
+ VIR_FREE(errors[i].disk);
+ }
+ return ret;
+}
+
static char *testDomainGetSchedulerType(virDomainPtr domain ATTRIBUTE_UNUSED,
int *nparams)
{
@@ -6832,6 +6873,7 @@ static virHypervisorDriver testHypervisorDriver = {
.domainUndefineFlags = testDomainUndefineFlags, /* 0.9.4 */
.domainGetAutostart = testDomainGetAutostart, /* 0.3.2 */
.domainSetAutostart = testDomainSetAutostart, /* 0.3.2 */
+ .domainGetDiskErrors = testDomainGetDiskErrors, /* 5.4.0 */
.domainGetSchedulerType = testDomainGetSchedulerType, /* 0.3.2 */
.domainGetSchedulerParameters = testDomainGetSchedulerParameters, /* 0.3.2 */
.domainGetSchedulerParametersFlags = testDomainGetSchedulerParametersFlags, /* 0.9.2 */
--
2.21.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On 5/13/19 1:26 AM, Ilias Stamatis wrote:
> Return the number of disks present in the configuration of the test
> domain when called with @errors as NULL and @maxerrors as 0.
>
> Otherwise report an error for every second disk, assigning available
> error codes in a cyclic order.
>
> Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com>
> ---
> src/test/test_driver.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 42 insertions(+)
>
> diff --git a/src/test/test_driver.c b/src/test/test_driver.c
> index a06d1fc402..527c2f5d3b 100644
> --- a/src/test/test_driver.c
> +++ b/src/test/test_driver.c
> @@ -3046,6 +3046,47 @@ static int testDomainSetAutostart(virDomainPtr domain,
> return 0;
> }
>
> +static int testDomainGetDiskErrors(virDomainPtr dom,
> + virDomainDiskErrorPtr errors,
> + unsigned int maxerrors,
> + unsigned int flags)
> +{
> + virDomainObjPtr vm = NULL;
> + int ret = -1;
> + size_t i;
> + int n = 0;
> + int codes[] = {VIR_DOMAIN_DISK_ERROR_UNSPEC, VIR_DOMAIN_DISK_ERROR_NO_SPACE};
> + size_t ncodes = sizeof(codes) / sizeof(codes[0]);
We have ARRAY_CARDINALITY() for this.
Also, there's no need to create @codes array as we'll see later.
> +
> + virCheckFlags(0, -1);
> +
> + if (!(vm = testDomObjFromDomain(dom)))
> + goto cleanup;
> +
> + if (virDomainObjCheckActive(vm) < 0)
> + goto cleanup;
> +
> + if (!errors) {
> + ret = vm->def->ndisks;
Tiny nitpick, we tend to put the longer body first, which in this case
is the else branch.
> + } else {
> + for (i = 1; i < vm->def->ndisks && n < maxerrors; i += 2) {
> + if (VIR_STRDUP(errors[n].disk, vm->def->disks[i]->dst) < 0)
> + goto cleanup;
> + errors[n].error = codes[n % ncodes];
This can be simplified. This enum in question is guaranteed to have
continuous items and _LAST to be the last item. Hence, this can be
rewritten as:
errors[i].error = (i % (VIR_DOMAIN_DISK_ERROR_LAST - 1)) + 1;
But if we want to simplify it a little bit more (so that
VIR_DOMAIN_DISK_ERROR_NONE is possible too) we can do it like this:
errors[i].error = i % VIR_DOMAIN_DISK_ERROR_LAST;
This immediatelly drops @codes, @ncodes and @n variables.
Also, there's MIN() macro ;-)
Yeah, libvirt has a lot of marcos and helpers and it's not obvious at
the first glance, but I guess that's like so with every bigger project,
isn't it?
> + n++;
> + }
> + ret = n;
> + }
> +
> + cleanup:
> + virDomainObjEndAPI(&vm);
> + if (ret < 0) {
> + for (i = 0; i < n; i++)
> + VIR_FREE(errors[i].disk);
> + }
> + return ret;
> +}
> +
> static char *testDomainGetSchedulerType(virDomainPtr domain ATTRIBUTE_UNUSED,
> int *nparams)
> {
> @@ -6832,6 +6873,7 @@ static virHypervisorDriver testHypervisorDriver = {
> .domainUndefineFlags = testDomainUndefineFlags, /* 0.9.4 */
> .domainGetAutostart = testDomainGetAutostart, /* 0.3.2 */
> .domainSetAutostart = testDomainSetAutostart, /* 0.3.2 */
> + .domainGetDiskErrors = testDomainGetDiskErrors, /* 5.4.0 */
> .domainGetSchedulerType = testDomainGetSchedulerType, /* 0.3.2 */
> .domainGetSchedulerParameters = testDomainGetSchedulerParameters, /* 0.3.2 */
> .domainGetSchedulerParametersFlags = testDomainGetSchedulerParametersFlags, /* 0.9.2 */
I'm cleaning the patch as outlined, ACKing and pushing.
Michal
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Mon, May 13, 2019 at 2:38 PM Michal Privoznik <mprivozn@redhat.com> wrote:
>
> On 5/13/19 1:26 AM, Ilias Stamatis wrote:
> > Return the number of disks present in the configuration of the test
> > domain when called with @errors as NULL and @maxerrors as 0.
> >
> > Otherwise report an error for every second disk, assigning available
> > error codes in a cyclic order.
> >
> > Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com>
> > ---
> > src/test/test_driver.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 42 insertions(+)
> >
> > diff --git a/src/test/test_driver.c b/src/test/test_driver.c
> > index a06d1fc402..527c2f5d3b 100644
> > --- a/src/test/test_driver.c
> > +++ b/src/test/test_driver.c
> > @@ -3046,6 +3046,47 @@ static int testDomainSetAutostart(virDomainPtr domain,
> > return 0;
> > }
> >
> > +static int testDomainGetDiskErrors(virDomainPtr dom,
> > + virDomainDiskErrorPtr errors,
> > + unsigned int maxerrors,
> > + unsigned int flags)
> > +{
> > + virDomainObjPtr vm = NULL;
> > + int ret = -1;
> > + size_t i;
> > + int n = 0;
> > + int codes[] = {VIR_DOMAIN_DISK_ERROR_UNSPEC, VIR_DOMAIN_DISK_ERROR_NO_SPACE};
> > + size_t ncodes = sizeof(codes) / sizeof(codes[0]);
>
> We have ARRAY_CARDINALITY() for this.
> Also, there's no need to create @codes array as we'll see later.
Aah, okay, I wasn't aware of this macro!
>
> > +
> > + virCheckFlags(0, -1);
> > +
> > + if (!(vm = testDomObjFromDomain(dom)))
> > + goto cleanup;
> > +
> > + if (virDomainObjCheckActive(vm) < 0)
> > + goto cleanup;
> > +
> > + if (!errors) {
> > + ret = vm->def->ndisks;
>
> Tiny nitpick, we tend to put the longer body first, which in this case
> is the else branch.
Hmm, I would normally do it like that but I noticed this in the "Curly
braces" section of the Contributor guidelines [1]:
"""Also, if the else block is much shorter than the if block, consider
negating the if-condition and swapping the bodies, putting the short
block first and making the longer, multi-line block be the else
block."""
So what is the case?
>
> > + } else {
> > + for (i = 1; i < vm->def->ndisks && n < maxerrors; i += 2) {
> > + if (VIR_STRDUP(errors[n].disk, vm->def->disks[i]->dst) < 0)
> > + goto cleanup;
> > + errors[n].error = codes[n % ncodes];
>
> This can be simplified. This enum in question is guaranteed to have
> continuous items and _LAST to be the last item. Hence, this can be
> rewritten as:
>
> errors[i].error = (i % (VIR_DOMAIN_DISK_ERROR_LAST - 1)) + 1;
>
I am aware of this but I wasn't sure if it would be very clean if I
started adding -1s and +1s in places.
> But if we want to simplify it a little bit more (so that
> VIR_DOMAIN_DISK_ERROR_NONE is possible too) we can do it like this:
>
> errors[i].error = i % VIR_DOMAIN_DISK_ERROR_LAST;
Hmm, in the documentation for this function [2] it is stated that:
"""Disks with no error will not be returned in the @errors array."""
So it seems to me that VIR_DOMAIN_DISK_ERROR_NONE shouldn't be
included. What do you think?
>
> This immediatelly drops @codes, @ncodes and @n variables.
> Also, there's MIN() macro ;-)
Cool, but where exactly do you suggest using MIN() here? Or you're
just mentioning it?
> Yeah, libvirt has a lot of marcos and helpers and it's not obvious at
> the first glance, but I guess that's like so with every bigger project,
> isn't it?
Yes, and I find these wrappers very useful / handy ;)
>
> > + n++;
> > + }
> > + ret = n;
> > + }
> > +
> > + cleanup:
> > + virDomainObjEndAPI(&vm);
> > + if (ret < 0) {
> > + for (i = 0; i < n; i++)
> > + VIR_FREE(errors[i].disk);
> > + }
> > + return ret;
> > +}
> > +
> > static char *testDomainGetSchedulerType(virDomainPtr domain ATTRIBUTE_UNUSED,
> > int *nparams)
> > {
> > @@ -6832,6 +6873,7 @@ static virHypervisorDriver testHypervisorDriver = {
> > .domainUndefineFlags = testDomainUndefineFlags, /* 0.9.4 */
> > .domainGetAutostart = testDomainGetAutostart, /* 0.3.2 */
> > .domainSetAutostart = testDomainSetAutostart, /* 0.3.2 */
> > + .domainGetDiskErrors = testDomainGetDiskErrors, /* 5.4.0 */
> > .domainGetSchedulerType = testDomainGetSchedulerType, /* 0.3.2 */
> > .domainGetSchedulerParameters = testDomainGetSchedulerParameters, /* 0.3.2 */
> > .domainGetSchedulerParametersFlags = testDomainGetSchedulerParametersFlags, /* 0.9.2 */
>
>
> I'm cleaning the patch as outlined, ACKing and pushing.
Sure, or I could fix it if you wanted.
Thank you very much!
Ilias
[1] https://libvirt.org/hacking.html#curly_braces
[2] https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetDiskErrors
>
> Michal
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On 5/13/19 9:04 AM, Ilias Stamatis wrote:
> On Mon, May 13, 2019 at 2:38 PM Michal Privoznik <mprivozn@redhat.com> wrote:
>>
>> On 5/13/19 1:26 AM, Ilias Stamatis wrote:
>>> Return the number of disks present in the configuration of the test
>>> domain when called with @errors as NULL and @maxerrors as 0.
>>>
>>> Otherwise report an error for every second disk, assigning available
>>> error codes in a cyclic order.
>>>
>>> Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com>
>>> ---
>>> src/test/test_driver.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 42 insertions(+)
>>>
>>> diff --git a/src/test/test_driver.c b/src/test/test_driver.c
>>> index a06d1fc402..527c2f5d3b 100644
>>> --- a/src/test/test_driver.c
>>> +++ b/src/test/test_driver.c
>>> @@ -3046,6 +3046,47 @@ static int testDomainSetAutostart(virDomainPtr domain,
>>> return 0;
>>> }
>>>
>>> +static int testDomainGetDiskErrors(virDomainPtr dom,
>>> + virDomainDiskErrorPtr errors,
>>> + unsigned int maxerrors,
>>> + unsigned int flags)
>>> +{
[...]
>>> + n++;
>>> + }
>>> + ret = n;
>>> + }
>>> +
>>> + cleanup:
>>> + virDomainObjEndAPI(&vm);
>>> + if (ret < 0) {
>>> + for (i = 0; i < n; i++)
>>> + VIR_FREE(errors[i].disk);
>>> + }
The above got changed to :
+ cleanup:
+ virDomainObjEndAPI(&vm);
+ if (ret < 0) {
+ for (i = 0; i < MIN(vm->def->ndisks, maxerrors); i++)
+ VIR_FREE(errors[i].disk);
+ }
and Coverity got a wee bit grumpy for a couple of reasons...
- The virDomainObjEndAPI will set @vm = NULL which makes the MIN
statement quite unhappy if ret < 0
- However, just moving that to after the if condition isn't good
enough since the testDomObjFromDomain could causes us to jump to
cleanup: with @vm = NULL (easily solved by return -1 there instead).
John
[...]
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Tue, May 14, 2019 at 12:40 PM John Ferlan <jferlan@redhat.com> wrote:
>
>
>
> On 5/13/19 9:04 AM, Ilias Stamatis wrote:
> > On Mon, May 13, 2019 at 2:38 PM Michal Privoznik <mprivozn@redhat.com> wrote:
> >>
> >> On 5/13/19 1:26 AM, Ilias Stamatis wrote:
> >>> Return the number of disks present in the configuration of the test
> >>> domain when called with @errors as NULL and @maxerrors as 0.
> >>>
> >>> Otherwise report an error for every second disk, assigning available
> >>> error codes in a cyclic order.
> >>>
> >>> Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com>
> >>> ---
> >>> src/test/test_driver.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> >>> 1 file changed, 42 insertions(+)
> >>>
> >>> diff --git a/src/test/test_driver.c b/src/test/test_driver.c
> >>> index a06d1fc402..527c2f5d3b 100644
> >>> --- a/src/test/test_driver.c
> >>> +++ b/src/test/test_driver.c
> >>> @@ -3046,6 +3046,47 @@ static int testDomainSetAutostart(virDomainPtr domain,
> >>> return 0;
> >>> }
> >>>
> >>> +static int testDomainGetDiskErrors(virDomainPtr dom,
> >>> + virDomainDiskErrorPtr errors,
> >>> + unsigned int maxerrors,
> >>> + unsigned int flags)
> >>> +{
>
> [...]
>
> >>> + n++;
> >>> + }
> >>> + ret = n;
> >>> + }
> >>> +
> >>> + cleanup:
> >>> + virDomainObjEndAPI(&vm);
> >>> + if (ret < 0) {
> >>> + for (i = 0; i < n; i++)
> >>> + VIR_FREE(errors[i].disk);
> >>> + }
>
> The above got changed to :
>
> + cleanup:
> + virDomainObjEndAPI(&vm);
> + if (ret < 0) {
> + for (i = 0; i < MIN(vm->def->ndisks, maxerrors); i++)
> + VIR_FREE(errors[i].disk);
> + }
I think this change is incorrect and a bug lies in here.
If VIR_STRDUP fails above, memory for less than MIN(vm->def->ndisks,
maxerrors) will have been allocated, and then in the cleanup code
we'll call VIR_FREE with pointers that haven't been previously
allocated.
>
> and Coverity got a wee bit grumpy for a couple of reasons...
>
> - The virDomainObjEndAPI will set @vm = NULL which makes the MIN
> statement quite unhappy if ret < 0
> - However, just moving that to after the if condition isn't good
> enough since the testDomObjFromDomain could causes us to jump to
> cleanup: with @vm = NULL (easily solved by return -1 there instead).
>
> John
>
>
>
> [...]
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On 5/14/19 12:50 PM, Ilias Stamatis wrote:
> On Tue, May 14, 2019 at 12:40 PM John Ferlan <jferlan@redhat.com> wrote:
>>
>>
>>
>> On 5/13/19 9:04 AM, Ilias Stamatis wrote:
>>> On Mon, May 13, 2019 at 2:38 PM Michal Privoznik <mprivozn@redhat.com> wrote:
>>>>
>>>> On 5/13/19 1:26 AM, Ilias Stamatis wrote:
>>>>> Return the number of disks present in the configuration of the test
>>>>> domain when called with @errors as NULL and @maxerrors as 0.
>>>>>
>>>>> Otherwise report an error for every second disk, assigning available
>>>>> error codes in a cyclic order.
>>>>>
>>>>> Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com>
>>>>> ---
>>>>> src/test/test_driver.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>>>>> 1 file changed, 42 insertions(+)
>>>>>
>>>>> diff --git a/src/test/test_driver.c b/src/test/test_driver.c
>>>>> index a06d1fc402..527c2f5d3b 100644
>>>>> --- a/src/test/test_driver.c
>>>>> +++ b/src/test/test_driver.c
>>>>> @@ -3046,6 +3046,47 @@ static int testDomainSetAutostart(virDomainPtr domain,
>>>>> return 0;
>>>>> }
>>>>>
>>>>> +static int testDomainGetDiskErrors(virDomainPtr dom,
>>>>> + virDomainDiskErrorPtr errors,
>>>>> + unsigned int maxerrors,
>>>>> + unsigned int flags)
>>>>> +{
>>
>> [...]
>>
>>>>> + n++;
>>>>> + }
>>>>> + ret = n;
>>>>> + }
>>>>> +
>>>>> + cleanup:
>>>>> + virDomainObjEndAPI(&vm);
>>>>> + if (ret < 0) {
>>>>> + for (i = 0; i < n; i++)
>>>>> + VIR_FREE(errors[i].disk);
>>>>> + }
>>
>> The above got changed to :
>>
>> + cleanup:
>> + virDomainObjEndAPI(&vm);
>> + if (ret < 0) {
>> + for (i = 0; i < MIN(vm->def->ndisks, maxerrors); i++)
>> + VIR_FREE(errors[i].disk);
>> + }
>
> I think this change is incorrect and a bug lies in here.
>
> If VIR_STRDUP fails above, memory for less than MIN(vm->def->ndisks,
> maxerrors) will have been allocated, and then in the cleanup code
> we'll call VIR_FREE with pointers that haven't been previously
> allocated.
That isn't a problem. User has to passed an array that we can touch. If
they store some data in it, well, their fault - how are we supposed to
return anything if we can't touch the array?
>
>>
>> and Coverity got a wee bit grumpy for a couple of reasons...
>>
>> - The virDomainObjEndAPI will set @vm = NULL which makes the MIN
>> statement quite unhappy if ret < 0
>> - However, just moving that to after the if condition isn't good
>> enough since the testDomObjFromDomain could causes us to jump to
>> cleanup: with @vm = NULL (easily solved by return -1 there instead).
Yep, I'll be posting patch soon.
Michal
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Tue, May 14, 2019 at 5:04 PM Michal Privoznik <mprivozn@redhat.com> wrote:
>
> On 5/14/19 12:50 PM, Ilias Stamatis wrote:
> > On Tue, May 14, 2019 at 12:40 PM John Ferlan <jferlan@redhat.com> wrote:
> >>
> >>
> >>
> >> On 5/13/19 9:04 AM, Ilias Stamatis wrote:
> >>> On Mon, May 13, 2019 at 2:38 PM Michal Privoznik <mprivozn@redhat.com> wrote:
> >>>>
> >>>> On 5/13/19 1:26 AM, Ilias Stamatis wrote:
> >>>>> Return the number of disks present in the configuration of the test
> >>>>> domain when called with @errors as NULL and @maxerrors as 0.
> >>>>>
> >>>>> Otherwise report an error for every second disk, assigning available
> >>>>> error codes in a cyclic order.
> >>>>>
> >>>>> Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com>
> >>>>> ---
> >>>>> src/test/test_driver.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> >>>>> 1 file changed, 42 insertions(+)
> >>>>>
> >>>>> diff --git a/src/test/test_driver.c b/src/test/test_driver.c
> >>>>> index a06d1fc402..527c2f5d3b 100644
> >>>>> --- a/src/test/test_driver.c
> >>>>> +++ b/src/test/test_driver.c
> >>>>> @@ -3046,6 +3046,47 @@ static int testDomainSetAutostart(virDomainPtr domain,
> >>>>> return 0;
> >>>>> }
> >>>>>
> >>>>> +static int testDomainGetDiskErrors(virDomainPtr dom,
> >>>>> + virDomainDiskErrorPtr errors,
> >>>>> + unsigned int maxerrors,
> >>>>> + unsigned int flags)
> >>>>> +{
> >>
> >> [...]
> >>
> >>>>> + n++;
> >>>>> + }
> >>>>> + ret = n;
> >>>>> + }
> >>>>> +
> >>>>> + cleanup:
> >>>>> + virDomainObjEndAPI(&vm);
> >>>>> + if (ret < 0) {
> >>>>> + for (i = 0; i < n; i++)
> >>>>> + VIR_FREE(errors[i].disk);
> >>>>> + }
> >>
> >> The above got changed to :
> >>
> >> + cleanup:
> >> + virDomainObjEndAPI(&vm);
> >> + if (ret < 0) {
> >> + for (i = 0; i < MIN(vm->def->ndisks, maxerrors); i++)
> >> + VIR_FREE(errors[i].disk);
> >> + }
> >
> > I think this change is incorrect and a bug lies in here.
> >
> > If VIR_STRDUP fails above, memory for less than MIN(vm->def->ndisks,
> > maxerrors) will have been allocated, and then in the cleanup code
> > we'll call VIR_FREE with pointers that haven't been previously
> > allocated.
>
> That isn't a problem. User has to passed an array that we can touch. If
> they store some data in it, well, their fault - how are we supposed to
> return anything if we can't touch the array?
I'm not sure I understand exactly what you mean.
We can touch the array of course.
What I'm saying is that we allocate memory with VIR_STRDUP for each
errors[i].disk, but if the call fails we free this memory on our own.
However how it is implemented now we might call VIR_FREE on pointers
for which we have *not* allocated any memory.
Because in the first loop, VIR_STRDUP might fail and send us to
"cleanup". But then on cleanup we iterate over the whole errors array.
Isn't this incorrect? Do I understand something wrong?
>
> >
> >>
> >> and Coverity got a wee bit grumpy for a couple of reasons...
> >>
> >> - The virDomainObjEndAPI will set @vm = NULL which makes the MIN
> >> statement quite unhappy if ret < 0
> >> - However, just moving that to after the if condition isn't good
> >> enough since the testDomObjFromDomain could causes us to jump to
> >> cleanup: with @vm = NULL (easily solved by return -1 there instead).
>
> Yep, I'll be posting patch soon.
>
> Michal
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On 5/14/19 5:24 PM, Ilias Stamatis wrote:
> On Tue, May 14, 2019 at 5:04 PM Michal Privoznik <mprivozn@redhat.com> wrote:
>>
>> On 5/14/19 12:50 PM, Ilias Stamatis wrote:
>>> On Tue, May 14, 2019 at 12:40 PM John Ferlan <jferlan@redhat.com> wrote:
>>>>
>>>>
>>>>
>>>> On 5/13/19 9:04 AM, Ilias Stamatis wrote:
>>>>> On Mon, May 13, 2019 at 2:38 PM Michal Privoznik <mprivozn@redhat.com> wrote:
>>>>>>
>>>>>> On 5/13/19 1:26 AM, Ilias Stamatis wrote:
>>>>>>> Return the number of disks present in the configuration of the test
>>>>>>> domain when called with @errors as NULL and @maxerrors as 0.
>>>>>>>
>>>>>>> Otherwise report an error for every second disk, assigning available
>>>>>>> error codes in a cyclic order.
>>>>>>>
>>>>>>> Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com>
>>>>>>> ---
>>>>>>> src/test/test_driver.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>>>>>>> 1 file changed, 42 insertions(+)
>>>>>>>
>>>>>>> diff --git a/src/test/test_driver.c b/src/test/test_driver.c
>>>>>>> index a06d1fc402..527c2f5d3b 100644
>>>>>>> --- a/src/test/test_driver.c
>>>>>>> +++ b/src/test/test_driver.c
>>>>>>> @@ -3046,6 +3046,47 @@ static int testDomainSetAutostart(virDomainPtr domain,
>>>>>>> return 0;
>>>>>>> }
>>>>>>>
>>>>>>> +static int testDomainGetDiskErrors(virDomainPtr dom,
>>>>>>> + virDomainDiskErrorPtr errors,
>>>>>>> + unsigned int maxerrors,
>>>>>>> + unsigned int flags)
>>>>>>> +{
>>>>
>>>> [...]
>>>>
>>>>>>> + n++;
>>>>>>> + }
>>>>>>> + ret = n;
>>>>>>> + }
>>>>>>> +
>>>>>>> + cleanup:
>>>>>>> + virDomainObjEndAPI(&vm);
>>>>>>> + if (ret < 0) {
>>>>>>> + for (i = 0; i < n; i++)
>>>>>>> + VIR_FREE(errors[i].disk);
>>>>>>> + }
>>>>
>>>> The above got changed to :
>>>>
>>>> + cleanup:
>>>> + virDomainObjEndAPI(&vm);
>>>> + if (ret < 0) {
>>>> + for (i = 0; i < MIN(vm->def->ndisks, maxerrors); i++)
>>>> + VIR_FREE(errors[i].disk);
>>>> + }
>>>
>>> I think this change is incorrect and a bug lies in here.
>>>
>>> If VIR_STRDUP fails above, memory for less than MIN(vm->def->ndisks,
>>> maxerrors) will have been allocated, and then in the cleanup code
>>> we'll call VIR_FREE with pointers that haven't been previously
>>> allocated.
>>
>> That isn't a problem. User has to passed an array that we can touch. If
>> they store some data in it, well, their fault - how are we supposed to
>> return anything if we can't touch the array?
>
> I'm not sure I understand exactly what you mean.
>
> We can touch the array of course.
>
> What I'm saying is that we allocate memory with VIR_STRDUP for each
> errors[i].disk, but if the call fails we free this memory on our own.
>
> However how it is implemented now we might call VIR_FREE on pointers
> for which we have *not* allocated any memory.
>
> Because in the first loop, VIR_STRDUP might fail and send us to
> "cleanup". But then on cleanup we iterate over the whole errors array.
>
> Isn't this incorrect? Do I understand something wrong?
Ah, now I get it. If user passes an array that is not zeroed out then we
might end up passing a random pointer to free(). How about this then?
if (ret < 0) {
while (i > 0)
VIR_FREE(errors[i--].disk);
}
Michal
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Wed, May 15, 2019 at 10:14 AM Michal Privoznik <mprivozn@redhat.com> wrote:
>
> On 5/14/19 5:24 PM, Ilias Stamatis wrote:
> > On Tue, May 14, 2019 at 5:04 PM Michal Privoznik <mprivozn@redhat.com> wrote:
> >>
> >> On 5/14/19 12:50 PM, Ilias Stamatis wrote:
> >>> On Tue, May 14, 2019 at 12:40 PM John Ferlan <jferlan@redhat.com> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 5/13/19 9:04 AM, Ilias Stamatis wrote:
> >>>>> On Mon, May 13, 2019 at 2:38 PM Michal Privoznik <mprivozn@redhat.com> wrote:
> >>>>>>
> >>>>>> On 5/13/19 1:26 AM, Ilias Stamatis wrote:
> >>>>>>> Return the number of disks present in the configuration of the test
> >>>>>>> domain when called with @errors as NULL and @maxerrors as 0.
> >>>>>>>
> >>>>>>> Otherwise report an error for every second disk, assigning available
> >>>>>>> error codes in a cyclic order.
> >>>>>>>
> >>>>>>> Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com>
> >>>>>>> ---
> >>>>>>> src/test/test_driver.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> >>>>>>> 1 file changed, 42 insertions(+)
> >>>>>>>
> >>>>>>> diff --git a/src/test/test_driver.c b/src/test/test_driver.c
> >>>>>>> index a06d1fc402..527c2f5d3b 100644
> >>>>>>> --- a/src/test/test_driver.c
> >>>>>>> +++ b/src/test/test_driver.c
> >>>>>>> @@ -3046,6 +3046,47 @@ static int testDomainSetAutostart(virDomainPtr domain,
> >>>>>>> return 0;
> >>>>>>> }
> >>>>>>>
> >>>>>>> +static int testDomainGetDiskErrors(virDomainPtr dom,
> >>>>>>> + virDomainDiskErrorPtr errors,
> >>>>>>> + unsigned int maxerrors,
> >>>>>>> + unsigned int flags)
> >>>>>>> +{
> >>>>
> >>>> [...]
> >>>>
> >>>>>>> + n++;
> >>>>>>> + }
> >>>>>>> + ret = n;
> >>>>>>> + }
> >>>>>>> +
> >>>>>>> + cleanup:
> >>>>>>> + virDomainObjEndAPI(&vm);
> >>>>>>> + if (ret < 0) {
> >>>>>>> + for (i = 0; i < n; i++)
> >>>>>>> + VIR_FREE(errors[i].disk);
> >>>>>>> + }
> >>>>
> >>>> The above got changed to :
> >>>>
> >>>> + cleanup:
> >>>> + virDomainObjEndAPI(&vm);
> >>>> + if (ret < 0) {
> >>>> + for (i = 0; i < MIN(vm->def->ndisks, maxerrors); i++)
> >>>> + VIR_FREE(errors[i].disk);
> >>>> + }
> >>>
> >>> I think this change is incorrect and a bug lies in here.
> >>>
> >>> If VIR_STRDUP fails above, memory for less than MIN(vm->def->ndisks,
> >>> maxerrors) will have been allocated, and then in the cleanup code
> >>> we'll call VIR_FREE with pointers that haven't been previously
> >>> allocated.
> >>
> >> That isn't a problem. User has to passed an array that we can touch. If
> >> they store some data in it, well, their fault - how are we supposed to
> >> return anything if we can't touch the array?
> >
> > I'm not sure I understand exactly what you mean.
> >
> > We can touch the array of course.
> >
> > What I'm saying is that we allocate memory with VIR_STRDUP for each
> > errors[i].disk, but if the call fails we free this memory on our own.
> >
> > However how it is implemented now we might call VIR_FREE on pointers
> > for which we have *not* allocated any memory.
> >
> > Because in the first loop, VIR_STRDUP might fail and send us to
> > "cleanup". But then on cleanup we iterate over the whole errors array.
> >
> > Isn't this incorrect? Do I understand something wrong?
>
>
> Ah, now I get it. If user passes an array that is not zeroed out then we
> might end up passing a random pointer to free(). How about this then?
>
> if (ret < 0) {
> while (i > 0)
> VIR_FREE(errors[i--].disk);
> }
>
Yes, this would work I think. And then the other changes in the
cleanup etc are not needed.
Ie it can be again:
if (!(vm = testDomObjFromDomain(dom)))
goto cleanup;
instead of "return -1" which is more consistent with the rest of the code.
However the code now returns errors for all disks. I thought we wanted
to report errors only for some of them?
In that case we would need to use the @n variable, as it was
initially. It is used in the same way in the qemu driver.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On 5/15/19 11:49 AM, Ilias Stamatis wrote:
> On Wed, May 15, 2019 at 10:14 AM Michal Privoznik <mprivozn@redhat.com> wrote:
>>
>> On 5/14/19 5:24 PM, Ilias Stamatis wrote:
>>> On Tue, May 14, 2019 at 5:04 PM Michal Privoznik <mprivozn@redhat.com> wrote:
>>>>
>>>> On 5/14/19 12:50 PM, Ilias Stamatis wrote:
>>>>> On Tue, May 14, 2019 at 12:40 PM John Ferlan <jferlan@redhat.com> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 5/13/19 9:04 AM, Ilias Stamatis wrote:
>>>>>>> On Mon, May 13, 2019 at 2:38 PM Michal Privoznik <mprivozn@redhat.com> wrote:
>>>>>>>>
>>>>>>>> On 5/13/19 1:26 AM, Ilias Stamatis wrote:
>>>>>>>>> Return the number of disks present in the configuration of the test
>>>>>>>>> domain when called with @errors as NULL and @maxerrors as 0.
>>>>>>>>>
>>>>>>>>> Otherwise report an error for every second disk, assigning available
>>>>>>>>> error codes in a cyclic order.
>>>>>>>>>
>>>>>>>>> Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com>
>>>>>>>>> ---
>>>>>>>>> src/test/test_driver.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>>>>>>>>> 1 file changed, 42 insertions(+)
>>>>>>>>>
>>>>>>>>> diff --git a/src/test/test_driver.c b/src/test/test_driver.c
>>>>>>>>> index a06d1fc402..527c2f5d3b 100644
>>>>>>>>> --- a/src/test/test_driver.c
>>>>>>>>> +++ b/src/test/test_driver.c
>>>>>>>>> @@ -3046,6 +3046,47 @@ static int testDomainSetAutostart(virDomainPtr domain,
>>>>>>>>> return 0;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> +static int testDomainGetDiskErrors(virDomainPtr dom,
>>>>>>>>> + virDomainDiskErrorPtr errors,
>>>>>>>>> + unsigned int maxerrors,
>>>>>>>>> + unsigned int flags)
>>>>>>>>> +{
>>>>>>
>>>>>> [...]
>>>>>>
>>>>>>>>> + n++;
>>>>>>>>> + }
>>>>>>>>> + ret = n;
>>>>>>>>> + }
>>>>>>>>> +
>>>>>>>>> + cleanup:
>>>>>>>>> + virDomainObjEndAPI(&vm);
>>>>>>>>> + if (ret < 0) {
>>>>>>>>> + for (i = 0; i < n; i++)
>>>>>>>>> + VIR_FREE(errors[i].disk);
>>>>>>>>> + }
>>>>>>
>>>>>> The above got changed to :
>>>>>>
>>>>>> + cleanup:
>>>>>> + virDomainObjEndAPI(&vm);
>>>>>> + if (ret < 0) {
>>>>>> + for (i = 0; i < MIN(vm->def->ndisks, maxerrors); i++)
>>>>>> + VIR_FREE(errors[i].disk);
>>>>>> + }
>>>>>
>>>>> I think this change is incorrect and a bug lies in here.
>>>>>
>>>>> If VIR_STRDUP fails above, memory for less than MIN(vm->def->ndisks,
>>>>> maxerrors) will have been allocated, and then in the cleanup code
>>>>> we'll call VIR_FREE with pointers that haven't been previously
>>>>> allocated.
>>>>
>>>> That isn't a problem. User has to passed an array that we can touch. If
>>>> they store some data in it, well, their fault - how are we supposed to
>>>> return anything if we can't touch the array?
>>>
>>> I'm not sure I understand exactly what you mean.
>>>
>>> We can touch the array of course.
>>>
>>> What I'm saying is that we allocate memory with VIR_STRDUP for each
>>> errors[i].disk, but if the call fails we free this memory on our own.
>>>
>>> However how it is implemented now we might call VIR_FREE on pointers
>>> for which we have *not* allocated any memory.
>>>
>>> Because in the first loop, VIR_STRDUP might fail and send us to
>>> "cleanup". But then on cleanup we iterate over the whole errors array.
>>>
>>> Isn't this incorrect? Do I understand something wrong?
>>
>>
>> Ah, now I get it. If user passes an array that is not zeroed out then we
>> might end up passing a random pointer to free(). How about this then?
>>
>> if (ret < 0) {
>> while (i > 0)
>> VIR_FREE(errors[i--].disk);
>> }
>>
>
> Yes, this would work I think. And then the other changes in the
> cleanup etc are not needed.
>
> Ie it can be again:
>
> if (!(vm = testDomObjFromDomain(dom)))
> goto cleanup;
>
> instead of "return -1" which is more consistent with the rest of the code.
This is done in 1/2. Or what do you mean?
>
> However the code now returns errors for all disks. I thought we wanted
> to report errors only for some of them?
Doesn't matter really.
Michal
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Thu, May 16, 2019 at 9:44 AM Michal Privoznik <mprivozn@redhat.com> wrote:
>
> On 5/15/19 11:49 AM, Ilias Stamatis wrote:
> > On Wed, May 15, 2019 at 10:14 AM Michal Privoznik <mprivozn@redhat.com> wrote:
> >>
> >> On 5/14/19 5:24 PM, Ilias Stamatis wrote:
> >>> On Tue, May 14, 2019 at 5:04 PM Michal Privoznik <mprivozn@redhat.com> wrote:
> >>>>
> >>>> On 5/14/19 12:50 PM, Ilias Stamatis wrote:
> >>>>> On Tue, May 14, 2019 at 12:40 PM John Ferlan <jferlan@redhat.com> wrote:
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> On 5/13/19 9:04 AM, Ilias Stamatis wrote:
> >>>>>>> On Mon, May 13, 2019 at 2:38 PM Michal Privoznik <mprivozn@redhat.com> wrote:
> >>>>>>>>
> >>>>>>>> On 5/13/19 1:26 AM, Ilias Stamatis wrote:
> >>>>>>>>> Return the number of disks present in the configuration of the test
> >>>>>>>>> domain when called with @errors as NULL and @maxerrors as 0.
> >>>>>>>>>
> >>>>>>>>> Otherwise report an error for every second disk, assigning available
> >>>>>>>>> error codes in a cyclic order.
> >>>>>>>>>
> >>>>>>>>> Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com>
> >>>>>>>>> ---
> >>>>>>>>> src/test/test_driver.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> >>>>>>>>> 1 file changed, 42 insertions(+)
> >>>>>>>>>
> >>>>>>>>> diff --git a/src/test/test_driver.c b/src/test/test_driver.c
> >>>>>>>>> index a06d1fc402..527c2f5d3b 100644
> >>>>>>>>> --- a/src/test/test_driver.c
> >>>>>>>>> +++ b/src/test/test_driver.c
> >>>>>>>>> @@ -3046,6 +3046,47 @@ static int testDomainSetAutostart(virDomainPtr domain,
> >>>>>>>>> return 0;
> >>>>>>>>> }
> >>>>>>>>>
> >>>>>>>>> +static int testDomainGetDiskErrors(virDomainPtr dom,
> >>>>>>>>> + virDomainDiskErrorPtr errors,
> >>>>>>>>> + unsigned int maxerrors,
> >>>>>>>>> + unsigned int flags)
> >>>>>>>>> +{
> >>>>>>
> >>>>>> [...]
> >>>>>>
> >>>>>>>>> + n++;
> >>>>>>>>> + }
> >>>>>>>>> + ret = n;
> >>>>>>>>> + }
> >>>>>>>>> +
> >>>>>>>>> + cleanup:
> >>>>>>>>> + virDomainObjEndAPI(&vm);
> >>>>>>>>> + if (ret < 0) {
> >>>>>>>>> + for (i = 0; i < n; i++)
> >>>>>>>>> + VIR_FREE(errors[i].disk);
> >>>>>>>>> + }
> >>>>>>
> >>>>>> The above got changed to :
> >>>>>>
> >>>>>> + cleanup:
> >>>>>> + virDomainObjEndAPI(&vm);
> >>>>>> + if (ret < 0) {
> >>>>>> + for (i = 0; i < MIN(vm->def->ndisks, maxerrors); i++)
> >>>>>> + VIR_FREE(errors[i].disk);
> >>>>>> + }
> >>>>>
> >>>>> I think this change is incorrect and a bug lies in here.
> >>>>>
> >>>>> If VIR_STRDUP fails above, memory for less than MIN(vm->def->ndisks,
> >>>>> maxerrors) will have been allocated, and then in the cleanup code
> >>>>> we'll call VIR_FREE with pointers that haven't been previously
> >>>>> allocated.
> >>>>
> >>>> That isn't a problem. User has to passed an array that we can touch. If
> >>>> they store some data in it, well, their fault - how are we supposed to
> >>>> return anything if we can't touch the array?
> >>>
> >>> I'm not sure I understand exactly what you mean.
> >>>
> >>> We can touch the array of course.
> >>>
> >>> What I'm saying is that we allocate memory with VIR_STRDUP for each
> >>> errors[i].disk, but if the call fails we free this memory on our own.
> >>>
> >>> However how it is implemented now we might call VIR_FREE on pointers
> >>> for which we have *not* allocated any memory.
> >>>
> >>> Because in the first loop, VIR_STRDUP might fail and send us to
> >>> "cleanup". But then on cleanup we iterate over the whole errors array.
> >>>
> >>> Isn't this incorrect? Do I understand something wrong?
> >>
> >>
> >> Ah, now I get it. If user passes an array that is not zeroed out then we
> >> might end up passing a random pointer to free(). How about this then?
> >>
> >> if (ret < 0) {
> >> while (i > 0)
> >> VIR_FREE(errors[i--].disk);
> >> }
> >>
> >
> > Yes, this would work I think. And then the other changes in the
> > cleanup etc are not needed.
> >
> > Ie it can be again:
> >
> > if (!(vm = testDomObjFromDomain(dom)))
> > goto cleanup;
> >
> > instead of "return -1" which is more consistent with the rest of the code.
>
> This is done in 1/2. Or what do you mean?
I meant that the previous change of returning -1 directly instead of
doing "goto cleanup" is not needed anymore. But of course it's fine
either way. Just with the goto, there will be only a single point of
exit.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Wed, May 15, 2019 at 10:14:35 +0200, Michal Privoznik wrote: > On 5/14/19 5:24 PM, Ilias Stamatis wrote: > > On Tue, May 14, 2019 at 5:04 PM Michal Privoznik <mprivozn@redhat.com> wrote: [...] > > Because in the first loop, VIR_STRDUP might fail and send us to > > "cleanup". But then on cleanup we iterate over the whole errors array. > > > > Isn't this incorrect? Do I understand something wrong? > > > Ah, now I get it. If user passes an array that is not zeroed out then we > might end up passing a random pointer to free(). How about this then? Why don't you just sanitize the user-passed memory first then? -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2026 Red Hat, Inc.