Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-23 Thread Claudio Fontana
On 9/23/22 18:29, Kevin Wolf wrote:
> Am 23.09.2022 um 16:46 hat Claudio Fontana geschrieben:
>> On 9/23/22 16:42, Kevin Wolf wrote:
>>> Am 23.09.2022 um 16:10 hat Claudio Fontana geschrieben:
 On 9/21/22 13:56, Kevin Wolf wrote:
> Am 21.09.2022 um 09:50 hat Claudio Fontana geschrieben:
>> On 9/20/22 18:50, Kevin Wolf wrote:
>>> Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
 On 9/8/22 19:10, Claudio Fontana wrote:
> On 9/8/22 18:03, Richard Henderson wrote:
>> On 9/8/22 15:53, Claudio Fontana wrote:
>>> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, 
>>> QDict *options, int flags,
>>>   return -EINVAL;
>>>   }
>>>   
>>> -block_module_load_one("dmg-bz2");
>>> -block_module_load_one("dmg-lzfse");
>>> +if (!block_module_load_one("dmg-bz2", _err) && 
>>> local_err) {
>>> +error_report_err(local_err);
>>> +}
>>> +local_err = NULL;
>>> +if (!block_module_load_one("dmg-lzfse", _err) && 
>>> local_err) {
>>> +error_report_err(local_err);
>>> +}
>>>   
>>>   s->n_chunks = 0;
>>>   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
>>
>> I wonder if these shouldn't fail hard if the modules don't exist?
>> Or at least pass back the error.
>>
>> Kevin?

 is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
 image is not compressed, "dmg" can function even if the extra dmg-bz
 module is not loaded right?
>>>
>>> Indeed. The code seems to consider that the modules may not be present.
>>> The behaviour in these cases is questionable (it seems to silently leave
>>> the buffers as they are and return success)
>
> I think I misunderstood the code here actually. dmg_read_mish_block()
> skips chunks of unknown type, so later trying to find them fails and
> dmg_co_preadv() returns -EIO. Which is a reasonable return value for
> this.
>
>>> , but the modules are clearly
>>> optional.
>>>
 I'd suspect we should then do:

 if (!block_module_load_one("dmg-bz2", _err)) {
   if (local_err) {
  error_report_err(local_err);
  return -EINVAL;
   }
   warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed 
 chunks */
 }

 and same for dmg-lzfse...?
>>>
>>> Actually, I think during initialisation, we should just pass NULL as
>>> errp and ignore any errors.
>>
>> Hmm really? I'd think that if there is an actual error loading the
>> module (module is installed, but the loading itself fails due to
>> broken module, wrong permissions, I/O errors etc) we would want to
>> report that fact as it happens?
>
> Can we distinguish the two error cases?
>
> Oooh... Reading the code again carefully, are you returning false
> without setting errp if the module just couldn't be found? This is a
> surprising interface.
>
> Yes, I guess then your proposed code is fine (modulo moving
> warn_report() somewhere else so that it doesn't complain when the image
> doesn't even contain compressed chunks).
>
>>> When a request would access a block that can't be uncompressed because
>>> of the missing module, that's where we can have a warn_report_once() and
>>> arguably should fail the I/O request.
>>>
>>> Kevin
>>>
>>
>> That would mean, moving the
>>
>> warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed 
>> chunks")
>>
>> to the uncompression code and change it to a warn_report_once() right?
>
> Yeah, though I think this doesn't actually work because we never even
> stored the metadata for chunks of unknown type (see above), so we never
> reach the uncompression code.
>
> What misled me initially is this code in dmg_read_chunk():
>
> case UDBZ: /* bzip2 compressed */
> if (!dmg_uncompress_bz2) {
> break;
> }
>
> I believe this is dead code, it could actually be an assertion. So
> if I'm not missing anything, adding the warning there would be useless.
>
> The other option is moving it into dmg_is_known_block_type() or its
> caller dmg_read_mish_block(), then we would detect it during open, which
> is probably nicer anyway.
>
> Kevin
>
>

 Hi Kevin, I got a bit lost on whether we have some agreement on where
 if anywhere to move the check/warning about missing decompression
 submodules.

 If that's ok I'd post a V5, and we can rediscuss from the new starting
 point?
>>>
>>> Sure, feel free, though I don't think the code will 

Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-23 Thread Kevin Wolf
Am 23.09.2022 um 16:46 hat Claudio Fontana geschrieben:
> On 9/23/22 16:42, Kevin Wolf wrote:
> > Am 23.09.2022 um 16:10 hat Claudio Fontana geschrieben:
> >> On 9/21/22 13:56, Kevin Wolf wrote:
> >>> Am 21.09.2022 um 09:50 hat Claudio Fontana geschrieben:
>  On 9/20/22 18:50, Kevin Wolf wrote:
> > Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
> >> On 9/8/22 19:10, Claudio Fontana wrote:
> >>> On 9/8/22 18:03, Richard Henderson wrote:
>  On 9/8/22 15:53, Claudio Fontana wrote:
> > @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, 
> > QDict *options, int flags,
> >   return -EINVAL;
> >   }
> >   
> > -block_module_load_one("dmg-bz2");
> > -block_module_load_one("dmg-lzfse");
> > +if (!block_module_load_one("dmg-bz2", _err) && 
> > local_err) {
> > +error_report_err(local_err);
> > +}
> > +local_err = NULL;
> > +if (!block_module_load_one("dmg-lzfse", _err) && 
> > local_err) {
> > +error_report_err(local_err);
> > +}
> >   
> >   s->n_chunks = 0;
> >   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
> 
>  I wonder if these shouldn't fail hard if the modules don't exist?
>  Or at least pass back the error.
> 
>  Kevin?
> >>
> >> is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
> >> image is not compressed, "dmg" can function even if the extra dmg-bz
> >> module is not loaded right?
> >
> > Indeed. The code seems to consider that the modules may not be present.
> > The behaviour in these cases is questionable (it seems to silently leave
> > the buffers as they are and return success)
> >>>
> >>> I think I misunderstood the code here actually. dmg_read_mish_block()
> >>> skips chunks of unknown type, so later trying to find them fails and
> >>> dmg_co_preadv() returns -EIO. Which is a reasonable return value for
> >>> this.
> >>>
> > , but the modules are clearly
> > optional.
> >
> >> I'd suspect we should then do:
> >>
> >> if (!block_module_load_one("dmg-bz2", _err)) {
> >>   if (local_err) {
> >>  error_report_err(local_err);
> >>  return -EINVAL;
> >>   }
> >>   warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed 
> >> chunks */
> >> }
> >>
> >> and same for dmg-lzfse...?
> >
> > Actually, I think during initialisation, we should just pass NULL as
> > errp and ignore any errors.
> 
>  Hmm really? I'd think that if there is an actual error loading the
>  module (module is installed, but the loading itself fails due to
>  broken module, wrong permissions, I/O errors etc) we would want to
>  report that fact as it happens?
> >>>
> >>> Can we distinguish the two error cases?
> >>>
> >>> Oooh... Reading the code again carefully, are you returning false
> >>> without setting errp if the module just couldn't be found? This is a
> >>> surprising interface.
> >>>
> >>> Yes, I guess then your proposed code is fine (modulo moving
> >>> warn_report() somewhere else so that it doesn't complain when the image
> >>> doesn't even contain compressed chunks).
> >>>
> > When a request would access a block that can't be uncompressed because
> > of the missing module, that's where we can have a warn_report_once() and
> > arguably should fail the I/O request.
> >
> > Kevin
> >
> 
>  That would mean, moving the
> 
>  warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed 
>  chunks")
> 
>  to the uncompression code and change it to a warn_report_once() right?
> >>>
> >>> Yeah, though I think this doesn't actually work because we never even
> >>> stored the metadata for chunks of unknown type (see above), so we never
> >>> reach the uncompression code.
> >>>
> >>> What misled me initially is this code in dmg_read_chunk():
> >>>
> >>> case UDBZ: /* bzip2 compressed */
> >>> if (!dmg_uncompress_bz2) {
> >>> break;
> >>> }
> >>>
> >>> I believe this is dead code, it could actually be an assertion. So
> >>> if I'm not missing anything, adding the warning there would be useless.
> >>>
> >>> The other option is moving it into dmg_is_known_block_type() or its
> >>> caller dmg_read_mish_block(), then we would detect it during open, which
> >>> is probably nicer anyway.
> >>>
> >>> Kevin
> >>>
> >>>
> >>
> >> Hi Kevin, I got a bit lost on whether we have some agreement on where
> >> if anywhere to move the check/warning about missing decompression
> >> submodules.
> >>
> >> If that's ok I'd post a V5, and we can rediscuss from the new starting
> >> point?
> > 
> > Sure, feel free, though I don't think the code will otherwise change for
> > dmg, so we 

Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-23 Thread Claudio Fontana
On 9/23/22 16:42, Kevin Wolf wrote:
> Am 23.09.2022 um 16:10 hat Claudio Fontana geschrieben:
>> On 9/21/22 13:56, Kevin Wolf wrote:
>>> Am 21.09.2022 um 09:50 hat Claudio Fontana geschrieben:
 On 9/20/22 18:50, Kevin Wolf wrote:
> Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
>> On 9/8/22 19:10, Claudio Fontana wrote:
>>> On 9/8/22 18:03, Richard Henderson wrote:
 On 9/8/22 15:53, Claudio Fontana wrote:
> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
> *options, int flags,
>   return -EINVAL;
>   }
>   
> -block_module_load_one("dmg-bz2");
> -block_module_load_one("dmg-lzfse");
> +if (!block_module_load_one("dmg-bz2", _err) && local_err) {
> +error_report_err(local_err);
> +}
> +local_err = NULL;
> +if (!block_module_load_one("dmg-lzfse", _err) && 
> local_err) {
> +error_report_err(local_err);
> +}
>   
>   s->n_chunks = 0;
>   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;

 I wonder if these shouldn't fail hard if the modules don't exist?
 Or at least pass back the error.

 Kevin?
>>
>> is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
>> image is not compressed, "dmg" can function even if the extra dmg-bz
>> module is not loaded right?
>
> Indeed. The code seems to consider that the modules may not be present.
> The behaviour in these cases is questionable (it seems to silently leave
> the buffers as they are and return success)
>>>
>>> I think I misunderstood the code here actually. dmg_read_mish_block()
>>> skips chunks of unknown type, so later trying to find them fails and
>>> dmg_co_preadv() returns -EIO. Which is a reasonable return value for
>>> this.
>>>
> , but the modules are clearly
> optional.
>
>> I'd suspect we should then do:
>>
>> if (!block_module_load_one("dmg-bz2", _err)) {
>>   if (local_err) {
>>  error_report_err(local_err);
>>  return -EINVAL;
>>   }
>>   warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed 
>> chunks */
>> }
>>
>> and same for dmg-lzfse...?
>
> Actually, I think during initialisation, we should just pass NULL as
> errp and ignore any errors.

 Hmm really? I'd think that if there is an actual error loading the
 module (module is installed, but the loading itself fails due to
 broken module, wrong permissions, I/O errors etc) we would want to
 report that fact as it happens?
>>>
>>> Can we distinguish the two error cases?
>>>
>>> Oooh... Reading the code again carefully, are you returning false
>>> without setting errp if the module just couldn't be found? This is a
>>> surprising interface.
>>>
>>> Yes, I guess then your proposed code is fine (modulo moving
>>> warn_report() somewhere else so that it doesn't complain when the image
>>> doesn't even contain compressed chunks).
>>>
> When a request would access a block that can't be uncompressed because
> of the missing module, that's where we can have a warn_report_once() and
> arguably should fail the I/O request.
>
> Kevin
>

 That would mean, moving the

 warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks")

 to the uncompression code and change it to a warn_report_once() right?
>>>
>>> Yeah, though I think this doesn't actually work because we never even
>>> stored the metadata for chunks of unknown type (see above), so we never
>>> reach the uncompression code.
>>>
>>> What misled me initially is this code in dmg_read_chunk():
>>>
>>> case UDBZ: /* bzip2 compressed */
>>> if (!dmg_uncompress_bz2) {
>>> break;
>>> }
>>>
>>> I believe this is dead code, it could actually be an assertion. So
>>> if I'm not missing anything, adding the warning there would be useless.
>>>
>>> The other option is moving it into dmg_is_known_block_type() or its
>>> caller dmg_read_mish_block(), then we would detect it during open, which
>>> is probably nicer anyway.
>>>
>>> Kevin
>>>
>>>
>>
>> Hi Kevin, I got a bit lost on whether we have some agreement on where
>> if anywhere to move the check/warning about missing decompression
>> submodules.
>>
>> If that's ok I'd post a V5, and we can rediscuss from the new starting
>> point?
> 
> Sure, feel free, though I don't think the code will otherwise change for
> dmg, so we could as well continue here.
> 
> My conclusion was that only dmg_read_mish_block() or something called by
> it can know whether compressed blocks exist in the image when the
> modules aren't present. So if we want to make the warning conditional on
> that (and my understanding is correct), this is where a
> warn_report_once() 

Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-23 Thread Kevin Wolf
Am 23.09.2022 um 16:10 hat Claudio Fontana geschrieben:
> On 9/21/22 13:56, Kevin Wolf wrote:
> > Am 21.09.2022 um 09:50 hat Claudio Fontana geschrieben:
> >> On 9/20/22 18:50, Kevin Wolf wrote:
> >>> Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
>  On 9/8/22 19:10, Claudio Fontana wrote:
> > On 9/8/22 18:03, Richard Henderson wrote:
> >> On 9/8/22 15:53, Claudio Fontana wrote:
> >>> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
> >>> *options, int flags,
> >>>   return -EINVAL;
> >>>   }
> >>>   
> >>> -block_module_load_one("dmg-bz2");
> >>> -block_module_load_one("dmg-lzfse");
> >>> +if (!block_module_load_one("dmg-bz2", _err) && local_err) {
> >>> +error_report_err(local_err);
> >>> +}
> >>> +local_err = NULL;
> >>> +if (!block_module_load_one("dmg-lzfse", _err) && 
> >>> local_err) {
> >>> +error_report_err(local_err);
> >>> +}
> >>>   
> >>>   s->n_chunks = 0;
> >>>   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
> >>
> >> I wonder if these shouldn't fail hard if the modules don't exist?
> >> Or at least pass back the error.
> >>
> >> Kevin?
> 
>  is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
>  image is not compressed, "dmg" can function even if the extra dmg-bz
>  module is not loaded right?
> >>>
> >>> Indeed. The code seems to consider that the modules may not be present.
> >>> The behaviour in these cases is questionable (it seems to silently leave
> >>> the buffers as they are and return success)
> > 
> > I think I misunderstood the code here actually. dmg_read_mish_block()
> > skips chunks of unknown type, so later trying to find them fails and
> > dmg_co_preadv() returns -EIO. Which is a reasonable return value for
> > this.
> > 
> >>> , but the modules are clearly
> >>> optional.
> >>>
>  I'd suspect we should then do:
> 
>  if (!block_module_load_one("dmg-bz2", _err)) {
>    if (local_err) {
>   error_report_err(local_err);
>   return -EINVAL;
>    }
>    warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed 
>  chunks */
>  }
> 
>  and same for dmg-lzfse...?
> >>>
> >>> Actually, I think during initialisation, we should just pass NULL as
> >>> errp and ignore any errors.
> >>
> >> Hmm really? I'd think that if there is an actual error loading the
> >> module (module is installed, but the loading itself fails due to
> >> broken module, wrong permissions, I/O errors etc) we would want to
> >> report that fact as it happens?
> > 
> > Can we distinguish the two error cases?
> > 
> > Oooh... Reading the code again carefully, are you returning false
> > without setting errp if the module just couldn't be found? This is a
> > surprising interface.
> > 
> > Yes, I guess then your proposed code is fine (modulo moving
> > warn_report() somewhere else so that it doesn't complain when the image
> > doesn't even contain compressed chunks).
> > 
> >>> When a request would access a block that can't be uncompressed because
> >>> of the missing module, that's where we can have a warn_report_once() and
> >>> arguably should fail the I/O request.
> >>>
> >>> Kevin
> >>>
> >>
> >> That would mean, moving the
> >>
> >> warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks")
> >>
> >> to the uncompression code and change it to a warn_report_once() right?
> > 
> > Yeah, though I think this doesn't actually work because we never even
> > stored the metadata for chunks of unknown type (see above), so we never
> > reach the uncompression code.
> > 
> > What misled me initially is this code in dmg_read_chunk():
> > 
> > case UDBZ: /* bzip2 compressed */
> > if (!dmg_uncompress_bz2) {
> > break;
> > }
> > 
> > I believe this is dead code, it could actually be an assertion. So
> > if I'm not missing anything, adding the warning there would be useless.
> > 
> > The other option is moving it into dmg_is_known_block_type() or its
> > caller dmg_read_mish_block(), then we would detect it during open, which
> > is probably nicer anyway.
> > 
> > Kevin
> > 
> > 
> 
> Hi Kevin, I got a bit lost on whether we have some agreement on where
> if anywhere to move the check/warning about missing decompression
> submodules.
> 
> If that's ok I'd post a V5, and we can rediscuss from the new starting
> point?

Sure, feel free, though I don't think the code will otherwise change for
dmg, so we could as well continue here.

My conclusion was that only dmg_read_mish_block() or something called by
it can know whether compressed blocks exist in the image when the
modules aren't present. So if we want to make the warning conditional on
that (and my understanding is correct), this is where a
warn_report_once() would have to live.

Kevin




Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-23 Thread Claudio Fontana
On 9/21/22 13:56, Kevin Wolf wrote:
> Am 21.09.2022 um 09:50 hat Claudio Fontana geschrieben:
>> On 9/20/22 18:50, Kevin Wolf wrote:
>>> Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
 On 9/8/22 19:10, Claudio Fontana wrote:
> On 9/8/22 18:03, Richard Henderson wrote:
>> On 9/8/22 15:53, Claudio Fontana wrote:
>>> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
>>> *options, int flags,
>>>   return -EINVAL;
>>>   }
>>>   
>>> -block_module_load_one("dmg-bz2");
>>> -block_module_load_one("dmg-lzfse");
>>> +if (!block_module_load_one("dmg-bz2", _err) && local_err) {
>>> +error_report_err(local_err);
>>> +}
>>> +local_err = NULL;
>>> +if (!block_module_load_one("dmg-lzfse", _err) && local_err) {
>>> +error_report_err(local_err);
>>> +}
>>>   
>>>   s->n_chunks = 0;
>>>   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
>>
>> I wonder if these shouldn't fail hard if the modules don't exist?
>> Or at least pass back the error.
>>
>> Kevin?

 is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
 image is not compressed, "dmg" can function even if the extra dmg-bz
 module is not loaded right?
>>>
>>> Indeed. The code seems to consider that the modules may not be present.
>>> The behaviour in these cases is questionable (it seems to silently leave
>>> the buffers as they are and return success)
> 
> I think I misunderstood the code here actually. dmg_read_mish_block()
> skips chunks of unknown type, so later trying to find them fails and
> dmg_co_preadv() returns -EIO. Which is a reasonable return value for
> this.
> 
>>> , but the modules are clearly
>>> optional.
>>>
 I'd suspect we should then do:

 if (!block_module_load_one("dmg-bz2", _err)) {
   if (local_err) {
  error_report_err(local_err);
  return -EINVAL;
   }
   warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks 
 */
 }

 and same for dmg-lzfse...?
>>>
>>> Actually, I think during initialisation, we should just pass NULL as
>>> errp and ignore any errors.
>>
>> Hmm really? I'd think that if there is an actual error loading the
>> module (module is installed, but the loading itself fails due to
>> broken module, wrong permissions, I/O errors etc) we would want to
>> report that fact as it happens?
> 
> Can we distinguish the two error cases?
> 
> Oooh... Reading the code again carefully, are you returning false
> without setting errp if the module just couldn't be found? This is a
> surprising interface.
> 
> Yes, I guess then your proposed code is fine (modulo moving
> warn_report() somewhere else so that it doesn't complain when the image
> doesn't even contain compressed chunks).
> 
>>> When a request would access a block that can't be uncompressed because
>>> of the missing module, that's where we can have a warn_report_once() and
>>> arguably should fail the I/O request.
>>>
>>> Kevin
>>>
>>
>> That would mean, moving the
>>
>> warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks")
>>
>> to the uncompression code and change it to a warn_report_once() right?
> 
> Yeah, though I think this doesn't actually work because we never even
> stored the metadata for chunks of unknown type (see above), so we never
> reach the uncompression code.
> 
> What misled me initially is this code in dmg_read_chunk():
> 
> case UDBZ: /* bzip2 compressed */
> if (!dmg_uncompress_bz2) {
> break;
> }
> 
> I believe this is dead code, it could actually be an assertion. So
> if I'm not missing anything, adding the warning there would be useless.
> 
> The other option is moving it into dmg_is_known_block_type() or its
> caller dmg_read_mish_block(), then we would detect it during open, which
> is probably nicer anyway.
> 
> Kevin
> 
> 

Hi Kevin, I got a bit lost on whether we have some agreement on where if 
anywhere to move the check/warning about missing decompression submodules.

If that's ok I'd post a V5, and we can rediscuss from the new starting point?

Thanks,

Claudio



Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-22 Thread Markus Armbruster
Kevin Wolf  writes:

> Am 21.09.2022 um 14:08 hat Markus Armbruster geschrieben:
>> Kevin Wolf  writes:
>> 
>> > Am 21.09.2022 um 06:45 hat Markus Armbruster geschrieben:
>> >> Can we detect presence of compressed blocks on open?
>> >
>> > We seem to read in the full metadata of the image in dmg_open(). So I
>> > think it would be possible to detect it there.
>> >
>> > dmg_read_mish_block() is what fills in s->types. However, it never fills
>> > in types that it doesn't know (and it pretends it doesn't know the types
>> > of compressed blocks whose module is not loaded). So instead of checking
>> > it in dmg_open() after dmg_read_mish_block() has completed, you would
>> > have to catch the situation already in dmg_read_mish_block() while
>> > parsing the image file, which should be entirely doable if you want.
>> 
>> In most cases, "open fails because some blocks are known to be
>> unreadable" is much better UX than "everything goes swimmingly until you
>> try to read one of the known-unreadable blocks".
>> 
>> Even when your software manages not to eat your data, surprise bad
>> blocks are still likely to result in a bad day.
>
> That's fair. On the other hand, not allowing the user to read the part
> of data that is perfectly readable would be bad, too.
>
> Maybe the right solution would be to have a driver option like
> "unknown-block-types=io-error|fail-open" (probably with better names),
> and then having "fail-open" as the new default would be reasonable
> enough.

Makes sense.




Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-22 Thread Kevin Wolf
Am 21.09.2022 um 14:08 hat Markus Armbruster geschrieben:
> Kevin Wolf  writes:
> 
> > Am 21.09.2022 um 06:45 hat Markus Armbruster geschrieben:
> >> Can we detect presence of compressed blocks on open?
> >
> > We seem to read in the full metadata of the image in dmg_open(). So I
> > think it would be possible to detect it there.
> >
> > dmg_read_mish_block() is what fills in s->types. However, it never fills
> > in types that it doesn't know (and it pretends it doesn't know the types
> > of compressed blocks whose module is not loaded). So instead of checking
> > it in dmg_open() after dmg_read_mish_block() has completed, you would
> > have to catch the situation already in dmg_read_mish_block() while
> > parsing the image file, which should be entirely doable if you want.
> 
> In most cases, "open fails because some blocks are known to be
> unreadable" is much better UX than "everything goes swimmingly until you
> try to read one of the known-unreadable blocks".
> 
> Even when your software manages not to eat your data, surprise bad
> blocks are still likely to result in a bad day.

That's fair. On the other hand, not allowing the user to read the part
of data that is perfectly readable would be bad, too.

Maybe the right solution would be to have a driver option like
"unknown-block-types=io-error|fail-open" (probably with better names),
and then having "fail-open" as the new default would be reasonable
enough.

Kevin




Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-21 Thread Kevin Wolf
Am 21.09.2022 um 09:50 hat Claudio Fontana geschrieben:
> On 9/20/22 18:50, Kevin Wolf wrote:
> > Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
> >> On 9/8/22 19:10, Claudio Fontana wrote:
> >>> On 9/8/22 18:03, Richard Henderson wrote:
>  On 9/8/22 15:53, Claudio Fontana wrote:
> > @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
> > *options, int flags,
> >   return -EINVAL;
> >   }
> >   
> > -block_module_load_one("dmg-bz2");
> > -block_module_load_one("dmg-lzfse");
> > +if (!block_module_load_one("dmg-bz2", _err) && local_err) {
> > +error_report_err(local_err);
> > +}
> > +local_err = NULL;
> > +if (!block_module_load_one("dmg-lzfse", _err) && local_err) {
> > +error_report_err(local_err);
> > +}
> >   
> >   s->n_chunks = 0;
> >   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
> 
>  I wonder if these shouldn't fail hard if the modules don't exist?
>  Or at least pass back the error.
> 
>  Kevin?
> >>
> >> is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
> >> image is not compressed, "dmg" can function even if the extra dmg-bz
> >> module is not loaded right?
> > 
> > Indeed. The code seems to consider that the modules may not be present.
> > The behaviour in these cases is questionable (it seems to silently leave
> > the buffers as they are and return success)

I think I misunderstood the code here actually. dmg_read_mish_block()
skips chunks of unknown type, so later trying to find them fails and
dmg_co_preadv() returns -EIO. Which is a reasonable return value for
this.

> > , but the modules are clearly
> > optional.
> > 
> >> I'd suspect we should then do:
> >>
> >> if (!block_module_load_one("dmg-bz2", _err)) {
> >>   if (local_err) {
> >>  error_report_err(local_err);
> >>  return -EINVAL;
> >>   }
> >>   warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks 
> >> */
> >> }
> >>
> >> and same for dmg-lzfse...?
> > 
> > Actually, I think during initialisation, we should just pass NULL as
> > errp and ignore any errors.
> 
> Hmm really? I'd think that if there is an actual error loading the
> module (module is installed, but the loading itself fails due to
> broken module, wrong permissions, I/O errors etc) we would want to
> report that fact as it happens?

Can we distinguish the two error cases?

Oooh... Reading the code again carefully, are you returning false
without setting errp if the module just couldn't be found? This is a
surprising interface.

Yes, I guess then your proposed code is fine (modulo moving
warn_report() somewhere else so that it doesn't complain when the image
doesn't even contain compressed chunks).

> > When a request would access a block that can't be uncompressed because
> > of the missing module, that's where we can have a warn_report_once() and
> > arguably should fail the I/O request.
> > 
> > Kevin
> > 
> 
> That would mean, moving the
> 
> warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks")
> 
> to the uncompression code and change it to a warn_report_once() right?

Yeah, though I think this doesn't actually work because we never even
stored the metadata for chunks of unknown type (see above), so we never
reach the uncompression code.

What misled me initially is this code in dmg_read_chunk():

case UDBZ: /* bzip2 compressed */
if (!dmg_uncompress_bz2) {
break;
}

I believe this is dead code, it could actually be an assertion. So
if I'm not missing anything, adding the warning there would be useless.

The other option is moving it into dmg_is_known_block_type() or its
caller dmg_read_mish_block(), then we would detect it during open, which
is probably nicer anyway.

Kevin




Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-21 Thread Markus Armbruster
Kevin Wolf  writes:

> Am 21.09.2022 um 06:45 hat Markus Armbruster geschrieben:
>> Kevin Wolf  writes:
>> 
>> > Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
>> >> On 9/8/22 19:10, Claudio Fontana wrote:
>> >> > On 9/8/22 18:03, Richard Henderson wrote:
>> >> >> On 9/8/22 15:53, Claudio Fontana wrote:
>> >> >>> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
>> >> >>> *options, int flags,
>> >> >>>   return -EINVAL;
>> >> >>>   }
>> >> >>>   
>> >> >>> -block_module_load_one("dmg-bz2");
>> >> >>> -block_module_load_one("dmg-lzfse");
>> >> >>> +if (!block_module_load_one("dmg-bz2", _err) && local_err) {
>> >> >>> +error_report_err(local_err);
>> >> >>> +}
>> >> >>> +local_err = NULL;
>> >> >>> +if (!block_module_load_one("dmg-lzfse", _err) && 
>> >> >>> local_err) {
>> >> >>> +error_report_err(local_err);
>> >> >>> +}
>> >> >>>   
>> >> >>>   s->n_chunks = 0;
>> >> >>>   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
>> >> >>
>> >> >> I wonder if these shouldn't fail hard if the modules don't exist?
>> >> >> Or at least pass back the error.
>> >> >>
>> >> >> Kevin?
>> >> 
>> >> is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
>> >> image is not compressed, "dmg" can function even if the extra dmg-bz
>> >> module is not loaded right?
>> >
>> > Indeed. The code seems to consider that the modules may not be present.
>> > The behaviour in these cases is questionable (it seems to silently leave
>> > the buffers as they are and return success), but the modules are clearly
>> > optional.
>> >
>> >> I'd suspect we should then do:
>> >> 
>> >> if (!block_module_load_one("dmg-bz2", _err)) {
>> >>   if (local_err) {
>> >>  error_report_err(local_err);
>> >>  return -EINVAL;
>> >>   }
>> >>   warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed 
>> >> chunks */
>> >> }
>> >> 
>> >> and same for dmg-lzfse...?
>> >
>> > Actually, I think during initialisation, we should just pass NULL as
>> > errp and ignore any errors.
>> >
>> > When a request would access a block that can't be uncompressed because
>> > of the missing module, that's where we can have a warn_report_once() and
>> > arguably should fail the I/O request.
>> 
>> Seems like asking for data corruption.  To avoid it, the complete stack
>> needs to handle I/O errors correctly.
>
> If you have any component that doesn't handle I/O errors correctly, keep
> it far away from your data because it _will_ cause corruption eventually.
> The earlier it fails, the better for you.

True for immortals.  Since we're not, it actually depends on
probabilities.

> I don't think we should put great effort into making fundamentally
> broken software a little bit less broken in the corner case that you're
> least likely to hit.

Fair point.

>> Can we detect presence of compressed blocks on open?
>
> We seem to read in the full metadata of the image in dmg_open(). So I
> think it would be possible to detect it there.
>
> dmg_read_mish_block() is what fills in s->types. However, it never fills
> in types that it doesn't know (and it pretends it doesn't know the types
> of compressed blocks whose module is not loaded). So instead of checking
> it in dmg_open() after dmg_read_mish_block() has completed, you would
> have to catch the situation already in dmg_read_mish_block() while
> parsing the image file, which should be entirely doable if you want.

In most cases, "open fails because some blocks are known to be
unreadable" is much better UX than "everything goes swimmingly until you
try to read one of the known-unreadable blocks".

Even when your software manages not to eat your data, surprise bad
blocks are still likely to result in a bad day.

> This is a change in dmg's behaviour, though, which is not the goal of
> the proposed patch. So if we want to do that, it should be a separate
> patch.

Makes sense.




Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-21 Thread Kevin Wolf
Am 21.09.2022 um 06:45 hat Markus Armbruster geschrieben:
> Kevin Wolf  writes:
> 
> > Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
> >> On 9/8/22 19:10, Claudio Fontana wrote:
> >> > On 9/8/22 18:03, Richard Henderson wrote:
> >> >> On 9/8/22 15:53, Claudio Fontana wrote:
> >> >>> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
> >> >>> *options, int flags,
> >> >>>   return -EINVAL;
> >> >>>   }
> >> >>>   
> >> >>> -block_module_load_one("dmg-bz2");
> >> >>> -block_module_load_one("dmg-lzfse");
> >> >>> +if (!block_module_load_one("dmg-bz2", _err) && local_err) {
> >> >>> +error_report_err(local_err);
> >> >>> +}
> >> >>> +local_err = NULL;
> >> >>> +if (!block_module_load_one("dmg-lzfse", _err) && local_err) 
> >> >>> {
> >> >>> +error_report_err(local_err);
> >> >>> +}
> >> >>>   
> >> >>>   s->n_chunks = 0;
> >> >>>   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
> >> >>
> >> >> I wonder if these shouldn't fail hard if the modules don't exist?
> >> >> Or at least pass back the error.
> >> >>
> >> >> Kevin?
> >> 
> >> is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
> >> image is not compressed, "dmg" can function even if the extra dmg-bz
> >> module is not loaded right?
> >
> > Indeed. The code seems to consider that the modules may not be present.
> > The behaviour in these cases is questionable (it seems to silently leave
> > the buffers as they are and return success), but the modules are clearly
> > optional.
> >
> >> I'd suspect we should then do:
> >> 
> >> if (!block_module_load_one("dmg-bz2", _err)) {
> >>   if (local_err) {
> >>  error_report_err(local_err);
> >>  return -EINVAL;
> >>   }
> >>   warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks 
> >> */
> >> }
> >> 
> >> and same for dmg-lzfse...?
> >
> > Actually, I think during initialisation, we should just pass NULL as
> > errp and ignore any errors.
> >
> > When a request would access a block that can't be uncompressed because
> > of the missing module, that's where we can have a warn_report_once() and
> > arguably should fail the I/O request.
> 
> Seems like asking for data corruption.  To avoid it, the complete stack
> needs to handle I/O errors correctly.

If you have any component that doesn't handle I/O errors correctly, keep
it far away from your data because it _will_ cause corruption eventually.
The earlier it fails, the better for you.

I don't think we should put great effort into making fundamentally
broken software a little bit less broken in the corner case that you're
least likely to hit.

> Can we detect presence of compressed blocks on open?

We seem to read in the full metadata of the image in dmg_open(). So I
think it would be possible to detect it there.

dmg_read_mish_block() is what fills in s->types. However, it never fills
in types that it doesn't know (and it pretends it doesn't know the types
of compressed blocks whose module is not loaded). So instead of checking
it in dmg_open() after dmg_read_mish_block() has completed, you would
have to catch the situation already in dmg_read_mish_block() while
parsing the image file, which should be entirely doable if you want.

This is a change in dmg's behaviour, though, which is not the goal of
the proposed patch. So if we want to do that, it should be a separate
patch.

Kevin




Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-21 Thread Claudio Fontana
On 9/20/22 18:50, Kevin Wolf wrote:
> Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
>> On 9/8/22 19:10, Claudio Fontana wrote:
>>> On 9/8/22 18:03, Richard Henderson wrote:
 On 9/8/22 15:53, Claudio Fontana wrote:
> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
> *options, int flags,
>   return -EINVAL;
>   }
>   
> -block_module_load_one("dmg-bz2");
> -block_module_load_one("dmg-lzfse");
> +if (!block_module_load_one("dmg-bz2", _err) && local_err) {
> +error_report_err(local_err);
> +}
> +local_err = NULL;
> +if (!block_module_load_one("dmg-lzfse", _err) && local_err) {
> +error_report_err(local_err);
> +}
>   
>   s->n_chunks = 0;
>   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;

 I wonder if these shouldn't fail hard if the modules don't exist?
 Or at least pass back the error.

 Kevin?
>>
>> is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
>> image is not compressed, "dmg" can function even if the extra dmg-bz
>> module is not loaded right?
> 
> Indeed. The code seems to consider that the modules may not be present.
> The behaviour in these cases is questionable (it seems to silently leave
> the buffers as they are and return success), but the modules are clearly
> optional.
> 
>> I'd suspect we should then do:
>>
>> if (!block_module_load_one("dmg-bz2", _err)) {
>>   if (local_err) {
>>  error_report_err(local_err);
>>  return -EINVAL;
>>   }
>>   warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks */
>> }
>>
>> and same for dmg-lzfse...?
> 
> Actually, I think during initialisation, we should just pass NULL as
> errp and ignore any errors.

Hmm really? I'd think that if there is an actual error loading the module 
(module is installed, but the loading itself fails due to broken module, wrong 
permissions, I/O errors etc)
we would want to report that fact as it happens?

> 
> When a request would access a block that can't be uncompressed because
> of the missing module, that's where we can have a warn_report_once() and
> arguably should fail the I/O request.
> 
> Kevin
> 

That would mean, moving the

warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks")

to the uncompression code and change it to a warn_report_once() right?

Thanks,

Claudio



Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-20 Thread Markus Armbruster
Kevin Wolf  writes:

> Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
>> On 9/8/22 19:10, Claudio Fontana wrote:
>> > On 9/8/22 18:03, Richard Henderson wrote:
>> >> On 9/8/22 15:53, Claudio Fontana wrote:
>> >>> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
>> >>> *options, int flags,
>> >>>   return -EINVAL;
>> >>>   }
>> >>>   
>> >>> -block_module_load_one("dmg-bz2");
>> >>> -block_module_load_one("dmg-lzfse");
>> >>> +if (!block_module_load_one("dmg-bz2", _err) && local_err) {
>> >>> +error_report_err(local_err);
>> >>> +}
>> >>> +local_err = NULL;
>> >>> +if (!block_module_load_one("dmg-lzfse", _err) && local_err) {
>> >>> +error_report_err(local_err);
>> >>> +}
>> >>>   
>> >>>   s->n_chunks = 0;
>> >>>   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
>> >>
>> >> I wonder if these shouldn't fail hard if the modules don't exist?
>> >> Or at least pass back the error.
>> >>
>> >> Kevin?
>> 
>> is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
>> image is not compressed, "dmg" can function even if the extra dmg-bz
>> module is not loaded right?
>
> Indeed. The code seems to consider that the modules may not be present.
> The behaviour in these cases is questionable (it seems to silently leave
> the buffers as they are and return success), but the modules are clearly
> optional.
>
>> I'd suspect we should then do:
>> 
>> if (!block_module_load_one("dmg-bz2", _err)) {
>>   if (local_err) {
>>  error_report_err(local_err);
>>  return -EINVAL;
>>   }
>>   warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks */
>> }
>> 
>> and same for dmg-lzfse...?
>
> Actually, I think during initialisation, we should just pass NULL as
> errp and ignore any errors.
>
> When a request would access a block that can't be uncompressed because
> of the missing module, that's where we can have a warn_report_once() and
> arguably should fail the I/O request.

Seems like asking for data corruption.  To avoid it, the complete stack
needs to handle I/O errors correctly.

Can we detect presence of compressed blocks on open?




Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-20 Thread Kevin Wolf
Am 08.09.2022 um 19:36 hat Claudio Fontana geschrieben:
> On 9/8/22 19:10, Claudio Fontana wrote:
> > On 9/8/22 18:03, Richard Henderson wrote:
> >> On 9/8/22 15:53, Claudio Fontana wrote:
> >>> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
> >>> *options, int flags,
> >>>   return -EINVAL;
> >>>   }
> >>>   
> >>> -block_module_load_one("dmg-bz2");
> >>> -block_module_load_one("dmg-lzfse");
> >>> +if (!block_module_load_one("dmg-bz2", _err) && local_err) {
> >>> +error_report_err(local_err);
> >>> +}
> >>> +local_err = NULL;
> >>> +if (!block_module_load_one("dmg-lzfse", _err) && local_err) {
> >>> +error_report_err(local_err);
> >>> +}
> >>>   
> >>>   s->n_chunks = 0;
> >>>   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
> >>
> >> I wonder if these shouldn't fail hard if the modules don't exist?
> >> Or at least pass back the error.
> >>
> >> Kevin?
> 
> is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg
> image is not compressed, "dmg" can function even if the extra dmg-bz
> module is not loaded right?

Indeed. The code seems to consider that the modules may not be present.
The behaviour in these cases is questionable (it seems to silently leave
the buffers as they are and return success), but the modules are clearly
optional.

> I'd suspect we should then do:
> 
> if (!block_module_load_one("dmg-bz2", _err)) {
>   if (local_err) {
>  error_report_err(local_err);
>  return -EINVAL;
>   }
>   warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks */
> }
> 
> and same for dmg-lzfse...?

Actually, I think during initialisation, we should just pass NULL as
errp and ignore any errors.

When a request would access a block that can't be uncompressed because
of the missing module, that's where we can have a warn_report_once() and
arguably should fail the I/O request.

Kevin




Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-08 Thread Claudio Fontana
On 9/8/22 19:10, Claudio Fontana wrote:
> On 9/8/22 18:03, Richard Henderson wrote:
>> On 9/8/22 15:53, Claudio Fontana wrote:
>>> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
>>> *options, int flags,
>>>   return -EINVAL;
>>>   }
>>>   
>>> -block_module_load_one("dmg-bz2");
>>> -block_module_load_one("dmg-lzfse");
>>> +if (!block_module_load_one("dmg-bz2", _err) && local_err) {
>>> +error_report_err(local_err);
>>> +}
>>> +local_err = NULL;
>>> +if (!block_module_load_one("dmg-lzfse", _err) && local_err) {
>>> +error_report_err(local_err);
>>> +}
>>>   
>>>   s->n_chunks = 0;
>>>   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
>>
>> I wonder if these shouldn't fail hard if the modules don't exist?
>> Or at least pass back the error.
>>
>> Kevin?

is "dmg-bz" _required_ for dmg open to work? I suspect if the dmg image is not 
compressed,
"dmg" can function even if the extra dmg-bz module is not loaded right?

I'd suspect we should then do:

if (!block_module_load_one("dmg-bz2", _err)) {
  if (local_err) {
 error_report_err(local_err);
 return -EINVAL;
  }
  warn_report("dmg-bz2 is not present, dmg will skip bz2-compressed chunks */
}

and same for dmg-lzfse...?

Ciao,

C
 
>>> +error_report_err(local_err);
>>> +}
>>
>>> @@ -1033,7 +1039,10 @@ ObjectClass *module_object_class_by_name(const char 
>>> *typename)
>>>   oc = object_class_by_name(typename);
>>>   #ifdef CONFIG_MODULES
>>>   if (!oc) {
>>> -module_load_qom_one(typename);
>>> +Error *local_err = NULL;
>>> +if (!module_load_qom_one(typename, _err) && local_err) {
>>> +error_report_err(local_err);
>>> +}
>>
>> You can return NULL from this path, we know it failed.
> 
> 
> I am tempted then to change also other similar instances in the code.
> 
>>
>>> @@ -172,46 +170,38 @@ static int module_load_file(const char *fname, bool 
>>> export_symbols)
>>>   }
>>>   g_module = g_module_open(fname, flags);
>>>   if (!g_module) {
>>> -fprintf(stderr, "Failed to open module: %s\n",
>>> -g_module_error());
>>> -ret = -EINVAL;
>>> -goto out;
>>> +error_setg(errp, "failed to open module: %s", g_module_error());
>>> +return false;
>>>   }
>>>   if (!g_module_symbol(g_module, DSO_STAMP_FUN_STR, (gpointer *))) {
>>> -fprintf(stderr, "Failed to initialize module: %s\n",
>>> -fname);
>>> -/* Print some info if this is a QEMU module (but from different 
>>> build),
>>> - * this will make debugging user problems easier. */
>>> +error_setg(errp, "failed to initialize module: %s", fname);
>>> +/*
>>> + * Print some info if this is a QEMU module (but from different 
>>> build),
>>> + * this will make debugging user problems easier.
>>> + */
>>>   if (g_module_symbol(g_module, "qemu_module_dummy", (gpointer 
>>> *))) {
>>> -fprintf(stderr,
>>> -"Note: only modules from the same build can be 
>>> loaded.\n");
>>> +error_append_hint(errp,
>>> +  "Only modules from the same build can be 
>>> loaded");
>>
>> With error_append_hint, you add the newline.
>>
>> The rest of the util/module.c reorg looks good.
>>
>>
>> r~
> 




Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-08 Thread Claudio Fontana
On 9/8/22 18:03, Richard Henderson wrote:
> On 9/8/22 15:53, Claudio Fontana wrote:
>> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
>> *options, int flags,
>>   return -EINVAL;
>>   }
>>   
>> -block_module_load_one("dmg-bz2");
>> -block_module_load_one("dmg-lzfse");
>> +if (!block_module_load_one("dmg-bz2", _err) && local_err) {
>> +error_report_err(local_err);
>> +}
>> +local_err = NULL;
>> +if (!block_module_load_one("dmg-lzfse", _err) && local_err) {
>> +error_report_err(local_err);
>> +}
>>   
>>   s->n_chunks = 0;
>>   s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
> 
> I wonder if these shouldn't fail hard if the modules don't exist?
> Or at least pass back the error.
> 
> Kevin?
> 
>> @@ -1033,7 +1039,10 @@ ObjectClass *module_object_class_by_name(const char 
>> *typename)
>>   oc = object_class_by_name(typename);
>>   #ifdef CONFIG_MODULES
>>   if (!oc) {
>> -module_load_qom_one(typename);
>> +Error *local_err = NULL;
>> +if (!module_load_qom_one(typename, _err) && local_err) {
>> +error_report_err(local_err);
>> +}
> 
> You can return NULL from this path, we know it failed.


I am tempted then to change also other similar instances in the code.

> 
>> @@ -172,46 +170,38 @@ static int module_load_file(const char *fname, bool 
>> export_symbols)
>>   }
>>   g_module = g_module_open(fname, flags);
>>   if (!g_module) {
>> -fprintf(stderr, "Failed to open module: %s\n",
>> -g_module_error());
>> -ret = -EINVAL;
>> -goto out;
>> +error_setg(errp, "failed to open module: %s", g_module_error());
>> +return false;
>>   }
>>   if (!g_module_symbol(g_module, DSO_STAMP_FUN_STR, (gpointer *))) {
>> -fprintf(stderr, "Failed to initialize module: %s\n",
>> -fname);
>> -/* Print some info if this is a QEMU module (but from different 
>> build),
>> - * this will make debugging user problems easier. */
>> +error_setg(errp, "failed to initialize module: %s", fname);
>> +/*
>> + * Print some info if this is a QEMU module (but from different 
>> build),
>> + * this will make debugging user problems easier.
>> + */
>>   if (g_module_symbol(g_module, "qemu_module_dummy", (gpointer 
>> *))) {
>> -fprintf(stderr,
>> -"Note: only modules from the same build can be 
>> loaded.\n");
>> +error_append_hint(errp,
>> +  "Only modules from the same build can be 
>> loaded");
> 
> With error_append_hint, you add the newline.
> 
> The rest of the util/module.c reorg looks good.
> 
> 
> r~




Re: [PATCH v3 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-08 Thread Richard Henderson

On 9/8/22 15:53, Claudio Fontana wrote:

@@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict *options, 
int flags,
  return -EINVAL;
  }
  
-block_module_load_one("dmg-bz2");

-block_module_load_one("dmg-lzfse");
+if (!block_module_load_one("dmg-bz2", _err) && local_err) {
+error_report_err(local_err);
+}
+local_err = NULL;
+if (!block_module_load_one("dmg-lzfse", _err) && local_err) {
+error_report_err(local_err);
+}
  
  s->n_chunks = 0;

  s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;


I wonder if these shouldn't fail hard if the modules don't exist?
Or at least pass back the error.

Kevin?


@@ -1033,7 +1039,10 @@ ObjectClass *module_object_class_by_name(const char 
*typename)
  oc = object_class_by_name(typename);
  #ifdef CONFIG_MODULES
  if (!oc) {
-module_load_qom_one(typename);
+Error *local_err = NULL;
+if (!module_load_qom_one(typename, _err) && local_err) {
+error_report_err(local_err);
+}


You can return NULL from this path, we know it failed.


@@ -172,46 +170,38 @@ static int module_load_file(const char *fname, bool 
export_symbols)
  }
  g_module = g_module_open(fname, flags);
  if (!g_module) {
-fprintf(stderr, "Failed to open module: %s\n",
-g_module_error());
-ret = -EINVAL;
-goto out;
+error_setg(errp, "failed to open module: %s", g_module_error());
+return false;
  }
  if (!g_module_symbol(g_module, DSO_STAMP_FUN_STR, (gpointer *))) {
-fprintf(stderr, "Failed to initialize module: %s\n",
-fname);
-/* Print some info if this is a QEMU module (but from different build),
- * this will make debugging user problems easier. */
+error_setg(errp, "failed to initialize module: %s", fname);
+/*
+ * Print some info if this is a QEMU module (but from different build),
+ * this will make debugging user problems easier.
+ */
  if (g_module_symbol(g_module, "qemu_module_dummy", (gpointer *))) 
{
-fprintf(stderr,
-"Note: only modules from the same build can be loaded.\n");
+error_append_hint(errp,
+  "Only modules from the same build can be 
loaded");


With error_append_hint, you add the newline.

The rest of the util/module.c reorg looks good.


r~