Re: [PATCH v4 2/2] nvme: allow cmb and pmr to be enabled on same device

2020-07-07 Thread Andrzej Jakowski
On 7/6/20 12:15 AM, Klaus Jensen wrote:
> On Jul  2 16:33, Andrzej Jakowski wrote:
>> On 7/2/20 10:51 AM, Klaus Jensen wrote:
>>> On Jul  2 08:07, Andrzej Jakowski wrote:
 On 7/2/20 3:31 AM, Klaus Jensen wrote:
> Aight, an update here. This only happens when QEMU is run with a virtual
> IOMMU. Otherwise, the kernel is happy.
>
> With the vIOMMU, qemu also craps out a bit:
>
> qemu-system-x86_64: vtd_iova_to_slpte: detected slpte permission error 
> (iova=0xfd20, level=0x2, slpte=0x0, write=0)
> qemu-system-x86_64: vtd_iommu_translate: detected translation failure 
> (dev=03:00:00, iova=0xfd20)
>
> So I think we are back in QEMU land for the bug.

 Can you share command line for that?


>>>
>>> qemu-system-x86_64 \
>>>   -nodefaults \
>>>   -display none \
>>>   -device intel-iommu,pt,intremap=on,device-iotlb=on \
>>>   -machine type=q35,accel=kvm,kernel_irqchip=split \
>>>   -cpu host \
>>>   -smp 4 \
>>>   -m 8G \
>>>   -nic user,model=virtio-net-pci,hostfwd=tcp::-:22 \
>>>   -device virtio-rng-pci \
>>>   -drive 
>>> id=boot,file=/home/kbj/work/src/vmctl/state/pmr/boot.qcow2,format=qcow2,if=virtio,discard=on,detect-zeroes=unmap
>>>  \
>>>   -device pcie-root-port,id=pcie_root_port1,chassis=1,slot=0 \
>>>   -device x3130-upstream,id=pcie_upstream1,bus=pcie_root_port1 \
>>>   -device 
>>> xio3130-downstream,id=pcie_downstream1,bus=pcie_upstream1,chassis=1,slot=1 \
>>>   -drive 
>>> id=nvme0n1,file=/home/kbj/work/src/vmctl/state/pmr/nvme0n1.img,format=raw,if=none,discard=on,detect-zeroes=unmap
>>>  \
>>>   -object memory-backend-file,id=pmr,share=on,mem-path=pmr.bin,size=1M \
>>>   -device 
>>> nvme,id=nvme0,serial=deadbeef,bus=pcie_downstream1,drive=nvme0n1,msix_qsize=1,pmrdev=pmr,cmb_size_mb=2
>>>  \
>>>   -pidfile /home/kbj/work/src/vmctl/run/pmr/pidfile \
>>>   -kernel /home/kbj/work/src/kernel/linux/arch/x86_64/boot/bzImage \
>>>   -append root=/dev/vda1 console=ttyS0,115200 audit=0 nokaslr \
>>>   -virtfs 
>>> local,path=/home/kbj/work/src/kernel/linux,security_model=none,readonly,mount_tag=modules
>>>  \
>>>   -serial mon:stdio \
>>>   -trace pci_nvme*
>>>
>>>
>>
>> I focused on reproduction and it looks to me that my patch doesn't 
>> necessarily introduce regression. I run it w/ and w/o patch in both cases
>> getting error while registering. Here is kernel guest log:
>>
>> [   87.606482] nvme nvme0: pci function :00:04.0
>> [   87.635577] dev=95b0a83b bar=2 size=134217728 offset=0
>> [   87.636593] nvme nvme0: failed to register the CMB ret=-95
>> [   87.643262] nvme nvme0: 12/0/0 default/read/poll queues
>>
>> Any thoughts?
>>
> 
> Hmm, that's not what I am seeing.
> 
> With kernel v5.8-rc4, I'm not seeing any issues with CMB with and
> without IOMMU on QEMU master. With your patches, my kernel (v5.8-rc4)
> pukes both with and without iommu.
> 
> BUT! This doesn't mean that your patch is bad, it looks more like an
> issue in the kernel. I still think the BAR configuration looks sane, but
> I am not expert on this.
> 
> To satisify my curiosity I tried mending your patch to put the CMB on
> offset 0 and move the MSI-X vector table and PBA to BAR 0 (like I
> suggested back in the day). That works. With and without IOMMU. So, I
> think it is an issue with the Linux kernel not being too happy about the
> CMB being at an offset. It doesn't directly look like an issue in the
> nvme driver since the issue shows up far lower in the memory subsystem,
> but it would be nice to have the linux nvme gang at least acknowledge
> the issue.
> 

I have managed to reproduce that problem and played with patch to see
when the problem occurs vs not. 
When I put MSIX back to BAR2 (no PMR at all) and CMB left at BAR4 but 
starting at offset 0 I was still able to reproduce issue.
So then I've played with memory region API and interesting observed that
problem occurs when region overlaying is used via:

memory_region_init(>bar4, OBJECT(n), "nvme-bar4",  bar_size);$
$  
if (n->params.cmb_size_mb) {$
memory_region_init_io(>ctrl_mem, OBJECT(n), _cmb_ops, n,$
  "nvme-cmb", NVME_CMBSZ_GETSIZE(n->bar.cmbsz));$
$  
memory_region_add_subregion_overlap(>bar4, cmb_offset, >ctrl_mem, 1);$
}$

on the other hand when cmb memory region is initialized w/o region
overlaying that is:

memory_region_init_io(>ctrl_mem, OBJECT(n), _cmb_ops, n,$
  "nvme-cmb", NVME_CMBSZ_GETSIZE(n->bar.cmbsz));

I get no reproduction.

Also observed qemu complaing about failed translation:
qemu-system-x86_64: vtd_iova_to_slpte: detected slpte permission error 
(iova=0xfe40, level=0x2, slpte=0x0, write=0)
qemu-system-x86_64: vtd_iommu_translate: detected translation failure 
(dev=03:00:00, iova=0xfe40)

Not sure how we want to proceed. Any suggestions?



Re: [PATCH v12 1/8] error: New macro ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Markus Armbruster
Vladimir Sementsov-Ogievskiy  writes:

> 07.07.2020 19:50, Markus Armbruster wrote:
>> From: Vladimir Sementsov-Ogievskiy
>>
>> Introduce a new ERRP_AUTO_PROPAGATE macro, to be used at start of
>> functions with an errp OUT parameter.
>>
>> It has three goals:
>>
>> 1. Fix issue with error_fatal and error_prepend/error_append_hint: user
>> can't see this additional information, because exit() happens in
>> error_setg earlier than information is added. [Reported by Greg Kurz]
>>
>> 2. Fix issue with error_abort and error_propagate: when we wrap
>> error_abort by local_err+error_propagate, the resulting coredump will
>> refer to error_propagate and not to the place where error happened.
>> (the macro itself doesn't fix the issue, but it allows us to [3.] drop
>> the local_err+error_propagate pattern, which will definitely fix the
>> issue) [Reported by Kevin Wolf]
>>
>> 3. Drop local_err+error_propagate pattern, which is used to workaround
>> void functions with errp parameter, when caller wants to know resulting
>> status. (Note: actually these functions could be merely updated to
>> return int error code).
>>
>> To achieve these goals, later patches will add invocations
>> of this macro at the start of functions with either use
>> error_prepend/error_append_hint (solving 1) or which use
>> local_err+error_propagate to check errors, switching those
>> functions to use *errp instead (solving 2 and 3).
>>
>> Signed-off-by: Vladimir Sementsov-Ogievskiy
>> Reviewed-by: Paul Durrant
>> Reviewed-by: Greg Kurz
>> Reviewed-by: Eric Blake
>> [Comments merged properly with recent commit "error: Document Error
>> API usage rules", and edited for clarity.  Put ERRP_AUTO_PROPAGATE()
>> before its helpers, and touch up style.  Commit message tweaked.]
>> Signed-off-by: Markus Armbruster
>
> Ok, I see you have mostly rewritten the big comment

Guilty as charged...  I was happy with the contents you provided (and
grateful for it), but our parallel work caused some redundancy.  I went
beyond a minimal merge to get a something that reads as one coherent
text.

> and not only in this patch, so, I go and read the whole comment on top of 
> these series.
>
> =
>
>* Pass an existing error to the caller with the message modified:
>* error_propagate_prepend(errp, err,
>* "Could not frobnicate '%s': ", name);
>* This is more concise than
>* error_propagate(errp, err); // don't do this
>* error_prepend(errp, "Could not frobnicate '%s': ", name);
>* and works even when @errp is _fatal.
>
> - the latter doesn't consider ERRP_AUTO_PROPAGATE: as we know, that 
> ERRP_AUTO_PROPAGATE should be used when we use error_prepend, the latter 
> should look like
>
>
> ERRP_AUTO_PROPAGATE();
> ...
> error_propagate(errp, err); // don't do this
> error_prepend(errp, "Could not frobnicate '%s': ", name);
>
> - and it works even when @errp is _fatal, so the 
> error_propagate_prepend now is just a shortcut, not the only correct way.

I can duplicate the advice from the paragraph preceding it, like this:

 * This is rarely needed.  When @err is a local variable, use of
 * ERRP_GUARD() commonly results in more readable code.
 * Where it is needed, it is more concise than
 * error_propagate(errp, err); // don't do this
 * error_prepend(errp, "Could not frobnicate '%s': ", name);
 * and works even when @errp is _fatal.

> Still, the text is formally correct as is, and may be improved later.
>
> =
>
>* 2. Replace  by errp, and err by *errp.  Delete local variable
>*@err.
>
> - hmm a bit not obvious,, It can be local_err.

Yes, but I trust the reader can make that mental jump.

> It can be (in some rare cases) still needed to handle the error locally, not 
> passing to the caller..

I didn't think of this.

What about

 * To convert a function to use ERRP_GUARD(), assuming the local
 * variable it propagates to @errp is called @err:
 [...]
 * 2. Replace  by errp, and err by *errp.  Delete local variable
 *@err if it s now unused.

Nope, still no good, if we replace like that, @err *will* be unused, and
the locally handled error will leak to the caller.

No time left for wordsmithing; let's improve on top.

> may be just something like "Assume local Error *err variable is used to get 
> errors from called functions and than propagated to caller's errp" before 
> paragraph [2.] will help.
>
>
>*
>* 3. Delete error_propagate(errp, *errp), replace
>*error_propagate_prepend(errp, *errp, ...) by error_prepend(errp, ...),
>*
>* 4. Ensure @errp is valid at return: when you destroy *errp, set
>*errp = NULL.
>
> =
>
>
> May be good to add note about ERRP_AUTO_PROPAGATE() into comment above 
> error_append_hint (and error_(v)prepend)).

Good point.

> =
>
>   /*
>* Make 

Re: [PATCH 2/2] hw/sd/sdcard: Do not allow invalid SD card sizes

2020-07-07 Thread Niek Linnenbank
Hi Philippe,

Just tried out your patch on latest master, and I noticed I couldn't apply
it without getting this error:

$ git am ~/Downloads/patches/\[PATCH\ 2_2\]\ hw_sd_sdcard\:\ Do\ not\
allow\ invalid\ SD\ card\ sizes\ -\ Philippe\ Mathieu-Daudé\ \<
f4...@amsat.org\>\ -\ 2020-07-07\ 1521.eml
Applying: hw/sd/sdcard: Do not allow invalid SD card sizes
error: patch failed: hw/sd/sd.c:2130
error: hw/sd/sd.c: patch does not apply
Patch failed at 0001 hw/sd/sdcard: Do not allow invalid SD card sizes
Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

The first patch did go OK. Maybe this one just needs to be rebased, or I
made a mistake.
So I manually copy & pasted the change into hw/sd/sd.c to test it.
It looks like the check works, but my concern is that with this change, we
will be getting this error on 'off-the-shelf' images as well.
For example, the latest Raspbian image size also isn't a power of two:

$ ./arm-softmmu/qemu-system-arm -M raspi2 -sd
~/Downloads/2020-05-27-raspios-buster-lite-armhf.img -nographic
WARNING: Image format was not specified for
'/home/me/Downloads/2020-05-27-raspios-buster-lite-armhf.img' and probing
guessed raw.
 Automatically detecting the format is dangerous for raw images,
write operations on block 0 will be restricted.
 Specify the 'raw' format explicitly to remove the restrictions.
qemu-system-arm: Invalid SD card size: 1.73 GiB (expecting at least 2 GiB)

If we do decide that the change is needed, I would like to propose that we
also give the user some instructions
on how to fix it, maybe some 'dd' command? In my opinion that should also
go in some of the documentation file(s),
possibly also in the one for the OrangePi PC at
docs/system/arm/orangepi.rst (I can also provide a patch for that if you
wish).

Kind regards,

Niek


On Tue, Jul 7, 2020 at 6:11 PM Philippe Mathieu-Daudé 
wrote:

> On 7/7/20 6:06 PM, Peter Maydell wrote:
> > On Tue, 7 Jul 2020 at 17:04, Alistair Francis 
> wrote:
> >>
> >> On Tue, Jul 7, 2020 at 6:22 AM Philippe Mathieu-Daudé 
> wrote:
> >>>
> >>> QEMU allows to create SD card with unrealistic sizes. This could work,
> >>> but some guests (at least Linux) consider sizes that are not a power
> >>> of 2 as a firmware bug and fix the card size to the next power of 2.
> >>>
> >>> Before CVE-2020-13253 fix, this would allow OOB read/write accesses
> >>> past the image size end.
> >>>
> >>> CVE-2020-13253 has been fixed as:
> >>>
> >>> Read command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
> >>> occurred and no data transfer is performed.
> >>>
> >>> Write command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
> >>> occurred and no data transfer is performed.
> >>>
> >>> WP_VIOLATION errors are not modified: the error bit is set, we
> >>> stay in receive-data state, wait for a stop command. All further
> >>> data transfer is ignored. See the check on sd->card_status at the
> >>> beginning of sd_read_data() and sd_write_data().
> >>>
> >>> While this is the correct behavior, in case QEMU create smaller SD
> >>> cards, guests still try to access past the image size end, and QEMU
> >>> considers this is an invalid address, thus "all further data transfer
> >>> is ignored". This is wrong and make the guest looping until
> >>> eventually timeouts.
> >>>
> >>> Fix by not allowing invalid SD card sizes.  Suggesting the expected
> >>> size as a hint:
> >>>
> >>>   $ qemu-system-arm -M orangepi-pc -drive
> file=rootfs.ext2,if=sd,format=raw
> >>>   qemu-system-arm: Invalid SD card size: 60 MiB (expecting at least 64
> MiB)
> >>>
> >>> Signed-off-by: Philippe Mathieu-Daudé 
> >>> ---
> >>>  hw/sd/sd.c | 16 
> >>>  1 file changed, 16 insertions(+)
> >>>
> >>> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> >>> index cb81487e5c..c45106b78e 100644
> >>> --- a/hw/sd/sd.c
> >>> +++ b/hw/sd/sd.c
> >>> @@ -32,6 +32,7 @@
> >>>
> >>>  #include "qemu/osdep.h"
> >>>  #include "qemu/units.h"
> >>> +#include "qemu/cutils.h"
> >>>  #include "hw/irq.h"
> >>>  #include "hw/registerfields.h"
> >>>  #include "sysemu/block-backend.h"
> >>> @@ -2130,11 +2131,26 @@ static void sd_realize(DeviceState *dev, Error
> **errp)
> >>>  }
> >>>
> >>>  if (sd->blk) {
> >>> +int64_t blk_size;
> >>> +
> >>>  if (blk_is_read_only(sd->blk)) {
> >>>  error_setg(errp, "Cannot use read-only drive as SD card");
> >>>  return;
> >>>  }
> >>>
> >>> +blk_size = blk_getlength(sd->blk);
> >>> +if (blk_size > 0 && !is_power_of_2(blk_size)) {
> >>> +int64_t blk_size_aligned = pow2ceil(blk_size);
> >>> +char *blk_size_str = size_to_str(blk_size);
> >>> +char *blk_size_aligned_str =
> size_to_str(blk_size_aligned);
> >>> +
> >>> +   

Re: [PULL 00/31] Block patches

2020-07-07 Thread Peter Maydell
On Mon, 6 Jul 2020 at 11:04, Max Reitz  wrote:
>
> The following changes since commit eb6490f544388dd24c0d054a96dd304bc7284450:
>
>   Merge remote-tracking branch 
> 'remotes/pmaydell/tags/pull-target-arm-20200703' into staging (2020-07-04 
> 16:08:41 +0100)
>
> are available in the Git repository at:
>
>   https://github.com/XanClic/qemu.git tags/pull-block-2020-07-06
>
> for you to fetch changes up to 365fed5111b06d31c1632af63c7528dfe49d62a2:
>
>   qed: Simplify backing reads (2020-07-06 10:34:14 +0200)
>
> 
> Block patches for 5.1:
> - LUKS keyslot amendment
>   (+ patches to make the iotests pass on non-Linux systems, and to keep
>  the tests passing for qcow v1, and to skip LUKS tests (including
>  qcow2 LUKS) when the built qemu does not support it)
> - Refactoring in the block layer: Drop the basically unnecessary
>   unallocated_blocks_are_zero field from BlockDriverInfo
> - Fix qcow2 preallocation when the image size is not a multiple of the
>   cluster size
> - Fix in block-copy code
>



Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/5.1
for any user-visible changes.

-- PMM



Re: [PATCH v12 2/8] scripts: Coccinelle script to use ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Markus Armbruster
Eric Blake  writes:

> On 7/7/20 11:50 AM, Markus Armbruster wrote:
>> From: Vladimir Sementsov-Ogievskiy 
>>
>> Script adds ERRP_AUTO_PROPAGATE macro invocation where appropriate and
>> does corresponding changes in code (look for details in
>> include/qapi/error.h)
>>
>> Usage example:
>> spatch --sp-file scripts/coccinelle/auto-propagated-errp.cocci \
>>   --macro-file scripts/cocci-macro-file.h --in-place --no-show-diff \
>>   --max-width 80 FILES...
>>
>> Signed-off-by: Vladimir Sementsov-Ogievskiy 
>> Reviewed-by: Markus Armbruster 
>> Signed-off-by: Markus Armbruster 
>> ---
>>   scripts/coccinelle/auto-propagated-errp.cocci | 337 ++
>>   include/qapi/error.h  |   3 +
>>   MAINTAINERS   |   1 +
>>   3 files changed, 341 insertions(+)
>>   create mode 100644 scripts/coccinelle/auto-propagated-errp.cocci
>
> Needs a tweak if we go with ERRP_GUARD.  But that's easy.
>
>> +
>> +// Convert special case with goto separately.
>> +// I tried merging this into the following rule the obvious way, but
>> +// it made Coccinelle hang on block.c
>> +//
>> +// Note interesting thing: if we don't do it here, and try to fixup
>> +// "out: }" things later after all transformations (the rule will be
>> +// the same, just without error_propagate() call), coccinelle fails to
>> +// match this "out: }".
>
> "out: }" is not valid C; would referring to "out: ; }" fare any better?

We can try for the next batch.

>> +@ disable optional_qualifier@
>> +identifier rule1.fn, rule1.local_err, out;
>> +symbol errp;
>> +@@
>> +
>> + fn(..., Error ** , ...)
>> + {
>> + <...
>> +-goto out;
>> ++return;
>> + ...>
>> +- out:
>> +-error_propagate(errp, local_err);
>> + }
>> +
>> +// Convert most of local_err related stuff.
>> +//
>> +// Note, that we inherit rule1.fn and rule1.local_err names, not
>> +// objects themselves. We may match something not related to the
>> +// pattern matched by rule1. For example, local_err may be defined with
>> +// the same name in different blocks inside one function, and in one
>> +// block follow the propagation pattern and in other block doesn't.
>> +//
>> +// Note also that errp-cleaning functions
>> +//   error_free_errp
>> +//   error_report_errp
>> +//   error_reportf_errp
>> +//   warn_report_errp
>> +//   warn_reportf_errp
>> +// are not yet implemented. They must call corresponding Error* -
>> +// freeing function and then set *errp to NULL, to avoid further
>> +// propagation to original errp (consider ERRP_AUTO_PROPAGATE in use).
>> +// For example, error_free_errp may look like this:
>> +//
>> +//void error_free_errp(Error **errp)
>> +//{
>> +//error_free(*errp);
>> +//*errp = NULL;
>> +//}
>
> I guess we can still decide later if we want these additional
> functions, or if they will even help after the number of places we
> have already improved after applying this script as-is and with
> Markus' cleanups in place.

Yes.

> While I won't call myself a Coccinelle expert, it at least looks sane
> enough that I'm comfortable if you add:
>
> Reviewed-by: Eric Blake 

Thanks!




Re: [PATCH v12 1/8] error: New macro ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Vladimir Sementsov-Ogievskiy

07.07.2020 19:50, Markus Armbruster wrote:

From: Vladimir Sementsov-Ogievskiy

Introduce a new ERRP_AUTO_PROPAGATE macro, to be used at start of
functions with an errp OUT parameter.

It has three goals:

1. Fix issue with error_fatal and error_prepend/error_append_hint: user
can't see this additional information, because exit() happens in
error_setg earlier than information is added. [Reported by Greg Kurz]

2. Fix issue with error_abort and error_propagate: when we wrap
error_abort by local_err+error_propagate, the resulting coredump will
refer to error_propagate and not to the place where error happened.
(the macro itself doesn't fix the issue, but it allows us to [3.] drop
the local_err+error_propagate pattern, which will definitely fix the
issue) [Reported by Kevin Wolf]

3. Drop local_err+error_propagate pattern, which is used to workaround
void functions with errp parameter, when caller wants to know resulting
status. (Note: actually these functions could be merely updated to
return int error code).

To achieve these goals, later patches will add invocations
of this macro at the start of functions with either use
error_prepend/error_append_hint (solving 1) or which use
local_err+error_propagate to check errors, switching those
functions to use *errp instead (solving 2 and 3).

Signed-off-by: Vladimir Sementsov-Ogievskiy
Reviewed-by: Paul Durrant
Reviewed-by: Greg Kurz
Reviewed-by: Eric Blake
[Comments merged properly with recent commit "error: Document Error
API usage rules", and edited for clarity.  Put ERRP_AUTO_PROPAGATE()
before its helpers, and touch up style.  Commit message tweaked.]
Signed-off-by: Markus Armbruster


Ok, I see you have mostly rewritten the big comment and not only in this patch, 
so, I go and read the whole comment on top of these series.

=

   * Pass an existing error to the caller with the message modified:
   * error_propagate_prepend(errp, err,
   * "Could not frobnicate '%s': ", name);
   * This is more concise than
   * error_propagate(errp, err); // don't do this
   * error_prepend(errp, "Could not frobnicate '%s': ", name);
   * and works even when @errp is _fatal.

- the latter doesn't consider ERRP_AUTO_PROPAGATE: as we know, that 
ERRP_AUTO_PROPAGATE should be used when we use error_prepend, the latter should 
look like


ERRP_AUTO_PROPAGATE();
...
error_propagate(errp, err); // don't do this
error_prepend(errp, "Could not frobnicate '%s': ", name);

- and it works even when @errp is _fatal, so the error_propagate_prepend 
now is just a shortcut, not the only correct way.


Still, the text is formally correct as is, and may be improved later.

=

   * 2. Replace  by errp, and err by *errp.  Delete local variable
   *@err.

- hmm a bit not obvious,, It can be local_err. It can be (in some rare cases) 
still needed to handle the error locally, not passing to the caller..

may be just something like "Assume local Error *err variable is used to get errors 
from called functions and than propagated to caller's errp" before paragraph [2.] 
will help.


   *
   * 3. Delete error_propagate(errp, *errp), replace
   *error_propagate_prepend(errp, *errp, ...) by error_prepend(errp, ...),
   *
   * 4. Ensure @errp is valid at return: when you destroy *errp, set
   *errp = NULL.

=


May be good to add note about ERRP_AUTO_PROPAGATE() into comment above 
error_append_hint (and error_(v)prepend)).



=

  /*
   * Make @errp parameter easier to use regardless of argument value

may be s/argument/its/

   *
   * This macro is for use right at the beginning of a function that
   * takes an Error **errp parameter to pass errors to its caller.  The
   * parameter must be named @errp.
   *
   * It must be used when the function dereferences @errp or passes
   * @errp to error_prepend(), error_vprepend(), or error_append_hint().
   * It is safe to use even when it's not needed, but please avoid
   * cluttering the source with useless code.
   *
   * If @errp is NULL or _fatal, rewrite it to point to a local
   * Error variable, which will be automatically propagated to the
   * original @errp on function exit.
   *
   * Note: _abort is not rewritten, because that would move the
   * abort from the place where the error is created to the place where
   * it's propagated.
   */

=


All these are minor, the documentation is good as is, thank you!

--
Best regards,
Vladimir



Re: [PATCH v12 1/8] error: New macro ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Markus Armbruster
Eric Blake  writes:

> On 7/7/20 11:50 AM, Markus Armbruster wrote:
>> From: Vladimir Sementsov-Ogievskiy 
>>
>> Introduce a new ERRP_AUTO_PROPAGATE macro, to be used at start of
>> functions with an errp OUT parameter.
>>
>> It has three goals:
>>
>> 1. Fix issue with error_fatal and error_prepend/error_append_hint: user
>
> the user

Yes.

>> can't see this additional information, because exit() happens in
>> error_setg earlier than information is added. [Reported by Greg Kurz]
>>
>> 2. Fix issue with error_abort and error_propagate: when we wrap
>> error_abort by local_err+error_propagate, the resulting coredump will
>> refer to error_propagate and not to the place where error happened.
>> (the macro itself doesn't fix the issue, but it allows us to [3.] drop
>> the local_err+error_propagate pattern, which will definitely fix the
>> issue) [Reported by Kevin Wolf]
>>
>> 3. Drop local_err+error_propagate pattern, which is used to workaround
>> void functions with errp parameter, when caller wants to know resulting
>> status. (Note: actually these functions could be merely updated to
>> return int error code).
>>
>> To achieve these goals, later patches will add invocations
>> of this macro at the start of functions with either use
>> error_prepend/error_append_hint (solving 1) or which use
>> local_err+error_propagate to check errors, switching those
>> functions to use *errp instead (solving 2 and 3).
>>
>> Signed-off-by: Vladimir Sementsov-Ogievskiy 
>> Reviewed-by: Paul Durrant 
>> Reviewed-by: Greg Kurz 
>> Reviewed-by: Eric Blake 
>> [Comments merged properly with recent commit "error: Document Error
>> API usage rules", and edited for clarity.  Put ERRP_AUTO_PROPAGATE()
>> before its helpers, and touch up style.  Commit message tweaked.]
>> Signed-off-by: Markus Armbruster 
>> ---
>>   include/qapi/error.h | 160 ++-
>>   1 file changed, 141 insertions(+), 19 deletions(-)
>>
>> diff --git a/include/qapi/error.h b/include/qapi/error.h
>> index 3fed49747d..c865a7d2f1 100644
>> --- a/include/qapi/error.h
>> +++ b/include/qapi/error.h
>
>> @@ -128,18 +122,26 @@
>>* handle the error...
>>* }
>>* when it doesn't, say a void function:
>> + * ERRP_AUTO_PROPAGATE();
>> + * foo(arg, errp);
>> + * if (*errp) {
>> + * handle the error...
>> + * }
>> + * More on ERRP_AUTO_PROPAGATE() below.
>> + *
>> + * Code predating ERRP_AUTO_PROPAGATE() still exits, and looks like this:
>
> exists

Fixing...

>>* Error *err = NULL;
>>* foo(arg, );
>>* if (err) {
>>* handle the error...
>> - * error_propagate(errp, err);
>> + * error_propagate(errp, err); // deprecated
>>* }
>> - * Do *not* "optimize" this to
>> + * Avoid in new code.  Do *not* "optimize" it to
>>* foo(arg, errp);
>>* if (*errp) { // WRONG!
>>* handle the error...
>>* }
>> - * because errp may be NULL!
>> + * because errp may be NULL!  Guard with ERRP_AUTO_PROPAGATE().
>
> maybe:
>
> because errp may be NULL without the ERRP_AUTO_PROPAGATE() guard.

Sold.

>>*
>>* But when all you do with the error is pass it on, please use
>>* foo(arg, errp);
>> @@ -158,6 +160,19 @@
>>* handle the error...
>>* }
>>*
>> + * Pass an existing error to the caller:
>
>> + * = Converting to ERRP_AUTO_PROPAGATE() =
>> + *
>> + * To convert a function to use ERRP_AUTO_PROPAGATE():
>> + *
>> + * 0. If the Error ** parameter is not named @errp, rename it to
>> + *@errp.
>> + *
>> + * 1. Add an ERRP_AUTO_PROPAGATE() invocation, by convention right at
>> + *the beginning of the function.  This makes @errp safe to use.
>> + *
>> + * 2. Replace  by errp, and err by *errp.  Delete local variable
>> + *@err.
>> + *
>> + * 3. Delete error_propagate(errp, *errp), replace
>> + *error_propagate_prepend(errp, *errp, ...) by error_prepend(errp, ...),
>> + *
>
> Why a comma here?

Editing accident.

>> + * 4. Ensure @errp is valid at return: when you destroy *errp, set
>> + *errp = NULL.
>> + *
>> + * Example:
>> + *
>> + * bool fn(..., Error **errp)
>> + * {
>> + * Error *err = NULL;
>> + *
>> + * foo(arg, );
>> + * if (err) {
>> + * handle the error...
>> + * error_propagate(errp, err);
>> + * return false;
>> + * }
>> + * ...
>> + * }
>> + *
>> + * becomes
>> + *
>> + * bool fn(..., Error **errp)
>> + * {
>> + * ERRP_AUTO_PROPAGATE();
>> + *
>> + * foo(arg, errp);
>> + * if (*errp) {
>> + * handle the error...
>> + * return false;
>> + * }
>> + * ...
>> + * }
>
> Do we want the example to show the use of error_free and *errp = NULL?

Yes, but we're running out of time, so let's do it in the series that
introduces the usage to the code.

> Otherwise, this is looking good to me.  It will need a 

Re: [PATCH v6 08/10] iotests: Specify explicit backing format where sensible

2020-07-07 Thread Eric Blake

On 7/7/20 11:07 AM, Kevin Wolf wrote:

Am 06.07.2020 um 22:39 hat Eric Blake geschrieben:

There are many existing qcow2 images that specify a backing file but
no format.  This has been the source of CVEs in the past, but has
become more prominent of a problem now that libvirt has switched to
-blockdev.  With older -drive, at least the probing was always done by
qemu (so the only risk of a changed format between successive boots of
a guest was if qemu was upgraded and probed differently).  But with
newer -blockdev, libvirt must specify a format; if libvirt guesses raw
where the image was formatted, this results in data corruption visible
to the guest; conversely, if libvirt guesses qcow2 where qemu was
using raw, this can result in potential security holes, so modern
libvirt instead refuses to use images without explicit backing format.

The change in libvirt to reject images without explicit backing format
has pointed out that a number of tools have been far too reliant on
probing in the past.  It's time to set a better example in our own
iotests of properly setting this parameter.

iotest calls to create, rebase, and convert are all impacted to some
degree.  It's a bit annoying that we are inconsistent on command line
- while all of those accept -o backing_file=...,backing_fmt=..., the
shortcuts are different: create and rebase have -b and -F, while
convert has -B but no -F.  (amend has no shortcuts, but the previous
patch just deprecated the use of amend to change backing chains).

Signed-off-by: Eric Blake 


This breaks at least 024 and 043 for qed because qemu-img info can't
print the backing file format there (qed only saves a flag whether it's
raw or non-raw).


Shoot.  I tend to avoid tests of qed and qcow (because they take so 
long), so while I may have tested them around v1 or v2 of the series, 
all the rebasing has changed the results by now.  Such is life.




We can fix the output filtering during the freeze, though.


Yes indeed, and I'll post such patches soon, now that you've pointed it out.

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v4 03/45] error: Document Error API usage rules

2020-07-07 Thread Eric Blake

On 7/7/20 2:23 PM, Markus Armbruster wrote:


It helps that you have repeated the same pattern as above.  But that
means if you change the layout, both groupings should have the same
layout.  Maybe:

Intro for a task:
- when the function returns...
- when it doesn't

Also, are there functions that have a return type other than void, but
where the return value is not an indication of error?  If there are,


Yes, there are such functions.


then the "say a void function" clause makes sense (but we should
probably recommend against such functions); if there are not, then
"say a void function" reads awkwardly.  Maybe:

- when it does not, because it is a void function:


What about

   - when it does not, say because it is a void function:


Reasonable.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v4 10/45] qemu-option: Simplify around find_default_by_name()

2020-07-07 Thread Greg Kurz
On Tue,  7 Jul 2020 18:05:38 +0200
Markus Armbruster  wrote:

> Signed-off-by: Markus Armbruster 
> Reviewed-by: Eric Blake 
> Reviewed-by: Vladimir Sementsov-Ogievskiy 
> ---

Reviewed-by: Greg Kurz 

>  util/qemu-option.c | 18 +-
>  1 file changed, 5 insertions(+), 13 deletions(-)
> 
> diff --git a/util/qemu-option.c b/util/qemu-option.c
> index 14e211ddd8..e7b540a21b 100644
> --- a/util/qemu-option.c
> +++ b/util/qemu-option.c
> @@ -277,7 +277,6 @@ static void qemu_opt_del_all(QemuOpts *opts, const char 
> *name)
>  const char *qemu_opt_get(QemuOpts *opts, const char *name)
>  {
>  QemuOpt *opt;
> -const char *def_val;
>  
>  if (opts == NULL) {
>  return NULL;
> @@ -285,12 +284,10 @@ const char *qemu_opt_get(QemuOpts *opts, const char 
> *name)
>  
>  opt = qemu_opt_find(opts, name);
>  if (!opt) {
> -def_val = find_default_by_name(opts, name);
> -if (def_val) {
> -return def_val;
> -}
> +return find_default_by_name(opts, name);
>  }
> -return opt ? opt->str : NULL;
> +
> +return opt->str;
>  }
>  
>  void qemu_opt_iter_init(QemuOptsIter *iter, QemuOpts *opts, const char *name)
> @@ -319,8 +316,7 @@ const char *qemu_opt_iter_next(QemuOptsIter *iter)
>  char *qemu_opt_get_del(QemuOpts *opts, const char *name)
>  {
>  QemuOpt *opt;
> -const char *def_val;
> -char *str = NULL;
> +char *str;
>  
>  if (opts == NULL) {
>  return NULL;
> @@ -328,11 +324,7 @@ char *qemu_opt_get_del(QemuOpts *opts, const char *name)
>  
>  opt = qemu_opt_find(opts, name);
>  if (!opt) {
> -def_val = find_default_by_name(opts, name);
> -if (def_val) {
> -str = g_strdup(def_val);
> -}
> -return str;
> +return g_strdup(find_default_by_name(opts, name));
>  }
>  str = opt->str;
>  opt->str = NULL;




Re: [PATCH v12 7/8] nbd: Use ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Eric Blake

On 7/7/20 11:50 AM, Markus Armbruster wrote:

From: Vladimir Sementsov-Ogievskiy 

If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
_fatal, this means that we don't break error_abort
(we'll abort on error_set, not on error_propagate)

This commit is generated by command

 sed -n '/^Network Block Device (NBD)$/,/^$/{s/^F: //p}' \
 MAINTAINERS | \
 xargs git ls-files | grep '\.[hc]$' | \
 xargs spatch \
 --sp-file scripts/coccinelle/auto-propagated-errp.cocci \
 --macro-file scripts/cocci-macro-file.h \
 --in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Markus Armbruster 
[Commit message tweaked]
Signed-off-by: Markus Armbruster 
---


Reviewed-by: Eric Blake 

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v4 02/45] error: Improve error.h's big comment

2020-07-07 Thread Greg Kurz
On Tue,  7 Jul 2020 18:05:30 +0200
Markus Armbruster  wrote:

> Add headlines to the big comment.
> 
> Explain examples for NULL, _abort and _fatal argument
> better.
> 
> Tweak rationale for error_propagate_prepend().
> 
> Signed-off-by: Markus Armbruster 
> ---

Reviewed-by: Greg Kurz 

>  include/qapi/error.h | 51 +++-
>  1 file changed, 36 insertions(+), 15 deletions(-)
> 
> diff --git a/include/qapi/error.h b/include/qapi/error.h
> index e8960eaad5..6d079c58b7 100644
> --- a/include/qapi/error.h
> +++ b/include/qapi/error.h
> @@ -15,6 +15,8 @@
>  /*
>   * Error reporting system loosely patterned after Glib's GError.
>   *
> + * = Creating errors =
> + *
>   * Create an error:
>   * error_setg(, "situation normal, all fouled up");
>   *
> @@ -27,6 +29,8 @@
>   * error_setg(, "invalid quark\n" // WRONG!
>   *"Valid quarks are up, down, strange, charm, top, bottom.");
>   *
> + * = Reporting and destroying errors =
> + *
>   * Report an error to the current monitor if we have one, else stderr:
>   * error_report_err(err);
>   * This frees the error object.
> @@ -40,6 +44,30 @@
>   * error_free(err);
>   * Note that this loses hints added with error_append_hint().
>   *
> + * Call a function ignoring errors:
> + * foo(arg, NULL);
> + * This is more concise than
> + * Error *err = NULL;
> + * foo(arg, );
> + * error_free(err); // don't do this
> + *
> + * Call a function aborting on errors:
> + * foo(arg, _abort);
> + * This is more concise and fails more nicely than
> + * Error *err = NULL;
> + * foo(arg, );
> + * assert(!err); // don't do this
> + *
> + * Call a function treating errors as fatal:
> + * foo(arg, _fatal);
> + * This is more concise than
> + * Error *err = NULL;
> + * foo(arg, );
> + * if (err) { // don't do this
> + * error_report_err(err);
> + * exit(1);
> + * }
> + *
>   * Handle an error without reporting it (just for completeness):
>   * error_free(err);
>   *
> @@ -47,6 +75,11 @@
>   * reporting it (primarily useful in testsuites):
>   * error_free_or_abort();
>   *
> + * = Passing errors around =
> + *
> + * Errors get passed to the caller through the conventional @errp
> + * parameter.
> + *
>   * Pass an existing error to the caller:
>   * error_propagate(errp, err);
>   * where Error **errp is a parameter, by convention the last one.
> @@ -54,11 +87,10 @@
>   * Pass an existing error to the caller with the message modified:
>   * error_propagate_prepend(errp, err,
>   * "Could not frobnicate '%s': ", name);
> - *
> - * Avoid
> - * error_propagate(errp, err);
> + * This is more concise than
> + * error_propagate(errp, err); // don't do this
>   * error_prepend(errp, "Could not frobnicate '%s': ", name);
> - * because this fails to prepend when @errp is _fatal.
> + * and works even when @errp is _fatal.
>   *
>   * Create a new error and pass it to the caller:
>   * error_setg(errp, "situation normal, all fouled up");
> @@ -70,15 +102,6 @@
>   * handle the error...
>   * }
>   *
> - * Call a function ignoring errors:
> - * foo(arg, NULL);
> - *
> - * Call a function aborting on errors:
> - * foo(arg, _abort);
> - *
> - * Call a function treating errors as fatal:
> - * foo(arg, _fatal);
> - *
>   * Receive an error and pass it on to the caller:
>   * Error *err = NULL;
>   * foo(arg, );
> @@ -86,8 +109,6 @@
>   * handle the error...
>   * error_propagate(errp, err);
>   * }
> - * where Error **errp is a parameter, by convention the last one.
> - *
>   * Do *not* "optimize" this to
>   * foo(arg, errp);
>   * if (*errp) { // WRONG!




Re: [PATCH v12 2/8] scripts: Coccinelle script to use ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Eric Blake

On 7/7/20 11:50 AM, Markus Armbruster wrote:

From: Vladimir Sementsov-Ogievskiy 

Script adds ERRP_AUTO_PROPAGATE macro invocation where appropriate and
does corresponding changes in code (look for details in
include/qapi/error.h)

Usage example:
spatch --sp-file scripts/coccinelle/auto-propagated-errp.cocci \
  --macro-file scripts/cocci-macro-file.h --in-place --no-show-diff \
  --max-width 80 FILES...

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Markus Armbruster 
Signed-off-by: Markus Armbruster 
---
  scripts/coccinelle/auto-propagated-errp.cocci | 337 ++
  include/qapi/error.h  |   3 +
  MAINTAINERS   |   1 +
  3 files changed, 341 insertions(+)
  create mode 100644 scripts/coccinelle/auto-propagated-errp.cocci


Needs a tweak if we go with ERRP_GUARD.  But that's easy.


+
+// Convert special case with goto separately.
+// I tried merging this into the following rule the obvious way, but
+// it made Coccinelle hang on block.c
+//
+// Note interesting thing: if we don't do it here, and try to fixup
+// "out: }" things later after all transformations (the rule will be
+// the same, just without error_propagate() call), coccinelle fails to
+// match this "out: }".


"out: }" is not valid C; would referring to "out: ; }" fare any better?


+@ disable optional_qualifier@
+identifier rule1.fn, rule1.local_err, out;
+symbol errp;
+@@
+
+ fn(..., Error ** , ...)
+ {
+ <...
+-goto out;
++return;
+ ...>
+- out:
+-error_propagate(errp, local_err);
+ }
+
+// Convert most of local_err related stuff.
+//
+// Note, that we inherit rule1.fn and rule1.local_err names, not
+// objects themselves. We may match something not related to the
+// pattern matched by rule1. For example, local_err may be defined with
+// the same name in different blocks inside one function, and in one
+// block follow the propagation pattern and in other block doesn't.
+//
+// Note also that errp-cleaning functions
+//   error_free_errp
+//   error_report_errp
+//   error_reportf_errp
+//   warn_report_errp
+//   warn_reportf_errp
+// are not yet implemented. They must call corresponding Error* -
+// freeing function and then set *errp to NULL, to avoid further
+// propagation to original errp (consider ERRP_AUTO_PROPAGATE in use).
+// For example, error_free_errp may look like this:
+//
+//void error_free_errp(Error **errp)
+//{
+//error_free(*errp);
+//*errp = NULL;
+//}


I guess we can still decide later if we want these additional functions, 
or if they will even help after the number of places we have already 
improved after applying this script as-is and with Markus' cleanups in 
place.


While I won't call myself a Coccinelle expert, it at least looks sane 
enough that I'm comfortable if you add:


Reviewed-by: Eric Blake 

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v4 03/45] error: Document Error API usage rules

2020-07-07 Thread Markus Armbruster
Eric Blake  writes:

> On 7/7/20 11:05 AM, Markus Armbruster wrote:
>> This merely codifies existing practice, with one exception: the rule
>> advising against returning void, where existing practice is mixed.
>>
>> When the Error API was created, we adopted the (unwritten) rule to
>> return void when the function returns no useful value on success,
>> unlike GError, which recommends to return true on success and false on
>> error then.
>>
>
>> Make the rule advising against returning void official by putting it
>> in writing.  This will hopefully reduce confusion.
>>
>> Update the examples accordingly.
>>
>> The remainder of this series will update a substantial amount of code
>> to honor the rule.
>>
>> Signed-off-by: Markus Armbruster 
>> Reviewed-by: Eric Blake 
>> Reviewed-by: Vladimir Sementsov-Ogievskiy 
>> Reviewed-by: Greg Kurz 
>> ---
>
>> @@ -95,14 +122,12 @@
>>* Create a new error and pass it to the caller:
>>* error_setg(errp, "situation normal, all fouled up");
>>*
>> - * Call a function and receive an error from it:
>> - * Error *err = NULL;
>> - * foo(arg, );
>> - * if (err) {
>> + * Call a function, receive an error from it, and pass it to caller
>
> maybe s/to caller/to the caller/

Yes.

>> + * when the function returns a value that indicates failure, say false:
>> + * if (!foo(arg, errp)) {
>>* handle the error...
>>* }
>> - *
>> - * Receive an error and pass it on to the caller:
>> + * when it doesn't, say a void function:
>
> Hmm. It looks like you have a single sentence "Call a function... when
> the function returns", but this line now makes it obvious that you
> have a single prefix: "Call a function, ...and pass it to the caller:"
> with two choices "when the function returns" and "when it doesn't".
> I'm not sure if there is a nicer way to typeset it, adding yet another
> ":" at the end of the line looks odd.  The idea behind the text is
> fine, I'm just trying to paint the bikeshed to see if there is a
> better presentation.
>
>>* Error *err = NULL;
>>* foo(arg, );
>>* if (err) {
>> @@ -120,6 +145,19 @@
>>* foo(arg, errp);
>>* for readability.
>>*
>> + * Receive an error, and handle it locally
>> + * when the function returns a value that indicates failure, say false:
>> + * Error *err = NULL;
>> + * if (!foo(arg, )) {
>> + * handle the error...
>> + * }
>> + * when it doesn't, say a void function:
>
> It helps that you have repeated the same pattern as above.  But that
> means if you change the layout, both groupings should have the same
> layout.  Maybe:
>
> Intro for a task:
> - when the function returns...
> - when it doesn't
>
> Also, are there functions that have a return type other than void, but
> where the return value is not an indication of error?  If there are,

Yes, there are such functions.

> then the "say a void function" clause makes sense (but we should
> probably recommend against such functions); if there are not, then
> "say a void function" reads awkwardly.  Maybe:
>
> - when it does not, because it is a void function:

What about

  - when it does not, say because it is a void function:

>> + * Error *err = NULL;
>> + * foo(arg, );
>> + * if (err) {
>> + * handle the error...
>> + * }
>> + *
>>* Receive and accumulate multiple errors (first one wins):
>>* Error *err = NULL, *local_err = NULL;
>>* foo(arg, );
>>

Thanks!




Re: [PATCH v4 1/2] nvme: indicate CMB support through controller capabilities register

2020-07-07 Thread Klaus Jensen
On Jul  7 19:27, Maxim Levitsky wrote:
> On Wed, 2020-07-01 at 14:48 -0700, Andrzej Jakowski wrote:
> > This patch sets CMBS bit in controller capabilities register when user
> > configures NVMe driver with CMB support, so capabilites are correctly
> > reported to guest OS.
> > 
> > Signed-off-by: Andrzej Jakowski 
> > Reviewed-by: Klaus Jensen 
> > ---
> >  hw/block/nvme.c  | 2 +-
> >  include/block/nvme.h | 6 +-
> >  2 files changed, 6 insertions(+), 2 deletions(-)
> > 
> > diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> > index 1aee042d4c..9f11f3e9da 100644
> > --- a/hw/block/nvme.c
> > +++ b/hw/block/nvme.c
> > @@ -1582,6 +1582,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice 
> > *pci_dev)
> >  NVME_CAP_SET_TO(n->bar.cap, 0xf);
> >  NVME_CAP_SET_CSS(n->bar.cap, 1);
> >  NVME_CAP_SET_MPSMAX(n->bar.cap, 4);
> > +NVME_CAP_SET_CMBS(n->bar.cap, n->params.cmb_size_mb ? 1 : 0);
> >  
> >  n->bar.vs = 0x00010200;
> >  n->bar.intmc = n->bar.intms = 0;
> > @@ -1591,7 +1592,6 @@ static void nvme_realize(PCIDevice *pci_dev, Error 
> > **errp)
> >  {
> >  NvmeCtrl *n = NVME(pci_dev);
> >  Error *local_err = NULL;
> > -
> >  int i;
> >  
> >  nvme_check_constraints(n, _err);
> > diff --git a/include/block/nvme.h b/include/block/nvme.h
> > index 1720ee1d51..14cf398dfa 100644
> > --- a/include/block/nvme.h
> > +++ b/include/block/nvme.h
> > @@ -35,6 +35,7 @@ enum NvmeCapShift {
> >  CAP_MPSMIN_SHIFT   = 48,
> >  CAP_MPSMAX_SHIFT   = 52,
> >  CAP_PMR_SHIFT  = 56,
> > +CAP_CMB_SHIFT  = 57,
> >  };
> >  
> >  enum NvmeCapMask {
> > @@ -48,6 +49,7 @@ enum NvmeCapMask {
> >  CAP_MPSMIN_MASK= 0xf,
> >  CAP_MPSMAX_MASK= 0xf,
> >  CAP_PMR_MASK   = 0x1,
> > +CAP_CMB_MASK   = 0x1,
> >  };
> >  
> >  #define NVME_CAP_MQES(cap)  (((cap) >> CAP_MQES_SHIFT)   & CAP_MQES_MASK)
> > @@ -78,8 +80,10 @@ enum NvmeCapMask {
> > << 
> > CAP_MPSMIN_SHIFT)
> >  #define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & 
> > CAP_MPSMAX_MASK)\
> >  << 
> > CAP_MPSMAX_SHIFT)
> > -#define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMR_MASK)\
> > +#define NVME_CAP_SET_PMRS(cap, val)   (cap |= (uint64_t)(val & 
> > CAP_PMR_MASK)   \
> >  << 
> > CAP_PMR_SHIFT)
> > +#define NVME_CAP_SET_CMBS(cap, val)   (cap |= (uint64_t)(val & 
> > CAP_CMB_MASK)   \
> > +   << 
> > CAP_CMB_SHIFT)
> >  
> >  enum NvmeCcShift {
> >  CC_EN_SHIFT = 0,
> 
> 
> I wonder how this could have beeing forgotten. Hmm.
> I see that Linux kernel uses CMBSZ != for that.
> I guess this explains it.
> 
> Reviewed-by: Maxim Levitsky 
> 

It is a v1.4 field. The CMB support was added when NVMe was at v1.2.
And the Linux kernel is also basically adhering to v1.3 wrt. CMB
support. In v1.4 the host actually needs to specifically enable the CMB
- and that is not something the kernel does currently IIRC.



Re: [PATCH v12 1/8] error: New macro ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Eric Blake

On 7/7/20 11:50 AM, Markus Armbruster wrote:

From: Vladimir Sementsov-Ogievskiy 

Introduce a new ERRP_AUTO_PROPAGATE macro, to be used at start of
functions with an errp OUT parameter.

It has three goals:

1. Fix issue with error_fatal and error_prepend/error_append_hint: user


the user


can't see this additional information, because exit() happens in
error_setg earlier than information is added. [Reported by Greg Kurz]

2. Fix issue with error_abort and error_propagate: when we wrap
error_abort by local_err+error_propagate, the resulting coredump will
refer to error_propagate and not to the place where error happened.
(the macro itself doesn't fix the issue, but it allows us to [3.] drop
the local_err+error_propagate pattern, which will definitely fix the
issue) [Reported by Kevin Wolf]

3. Drop local_err+error_propagate pattern, which is used to workaround
void functions with errp parameter, when caller wants to know resulting
status. (Note: actually these functions could be merely updated to
return int error code).

To achieve these goals, later patches will add invocations
of this macro at the start of functions with either use
error_prepend/error_append_hint (solving 1) or which use
local_err+error_propagate to check errors, switching those
functions to use *errp instead (solving 2 and 3).

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Paul Durrant 
Reviewed-by: Greg Kurz 
Reviewed-by: Eric Blake 
[Comments merged properly with recent commit "error: Document Error
API usage rules", and edited for clarity.  Put ERRP_AUTO_PROPAGATE()
before its helpers, and touch up style.  Commit message tweaked.]
Signed-off-by: Markus Armbruster 
---
  include/qapi/error.h | 160 ++-
  1 file changed, 141 insertions(+), 19 deletions(-)

diff --git a/include/qapi/error.h b/include/qapi/error.h
index 3fed49747d..c865a7d2f1 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h



@@ -128,18 +122,26 @@
   * handle the error...
   * }
   * when it doesn't, say a void function:
+ * ERRP_AUTO_PROPAGATE();
+ * foo(arg, errp);
+ * if (*errp) {
+ * handle the error...
+ * }
+ * More on ERRP_AUTO_PROPAGATE() below.
+ *
+ * Code predating ERRP_AUTO_PROPAGATE() still exits, and looks like this:


exists


   * Error *err = NULL;
   * foo(arg, );
   * if (err) {
   * handle the error...
- * error_propagate(errp, err);
+ * error_propagate(errp, err); // deprecated
   * }
- * Do *not* "optimize" this to
+ * Avoid in new code.  Do *not* "optimize" it to
   * foo(arg, errp);
   * if (*errp) { // WRONG!
   * handle the error...
   * }
- * because errp may be NULL!
+ * because errp may be NULL!  Guard with ERRP_AUTO_PROPAGATE().


maybe:

because errp may be NULL without the ERRP_AUTO_PROPAGATE() guard.


   *
   * But when all you do with the error is pass it on, please use
   * foo(arg, errp);
@@ -158,6 +160,19 @@
   * handle the error...
   * }
   *
+ * Pass an existing error to the caller:



+ * = Converting to ERRP_AUTO_PROPAGATE() =
+ *
+ * To convert a function to use ERRP_AUTO_PROPAGATE():
+ *
+ * 0. If the Error ** parameter is not named @errp, rename it to
+ *@errp.
+ *
+ * 1. Add an ERRP_AUTO_PROPAGATE() invocation, by convention right at
+ *the beginning of the function.  This makes @errp safe to use.
+ *
+ * 2. Replace  by errp, and err by *errp.  Delete local variable
+ *@err.
+ *
+ * 3. Delete error_propagate(errp, *errp), replace
+ *error_propagate_prepend(errp, *errp, ...) by error_prepend(errp, ...),
+ *


Why a comma here?


+ * 4. Ensure @errp is valid at return: when you destroy *errp, set
+ *errp = NULL.
+ *
+ * Example:
+ *
+ * bool fn(..., Error **errp)
+ * {
+ * Error *err = NULL;
+ *
+ * foo(arg, );
+ * if (err) {
+ * handle the error...
+ * error_propagate(errp, err);
+ * return false;
+ * }
+ * ...
+ * }
+ *
+ * becomes
+ *
+ * bool fn(..., Error **errp)
+ * {
+ * ERRP_AUTO_PROPAGATE();
+ *
+ * foo(arg, errp);
+ * if (*errp) {
+ * handle the error...
+ * return false;
+ * }
+ * ...
+ * }


Do we want the example to show the use of error_free and *errp = NULL?

Otherwise, this is looking good to me.  It will need a tweak if we go 
with the shorter name ERRP_GUARD, but I like that idea.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v12 0/8] error: auto propagated local_err part I

2020-07-07 Thread Eric Blake

On 7/7/20 11:50 AM, Markus Armbruster wrote:

To speed things up, I'm taking the liberty to respin Vladimir's series
with my documentation amendments.

After my documentation work, I'm very much inclined to rename
ERRP_AUTO_PROPAGATE() to ERRP_GUARD().  The fact that it propagates
below the hood is detail.  What matters to its users is that it lets
them use @errp more freely.  Thoughts?


I like it - the shorter name is easier to type.

(The rename is a mechanical change, so if we agree to it, we should do 
it up front to minimize the churn to all the functions where we add use 
of the macro)




Based-on: Message-Id: <20200707160613.848843-1-arm...@redhat.com>

Available from my public repository https://repo.or.cz/qemu/armbru.git
on branch error-auto.

v12: (based on "[PATCH v4 00/45] Less clumsy error checking")
01: Comments merged properly with recent commit "error: Document Error
API usage rules", and edited for clarity.  Put ERRP_AUTO_PROPAGATE()
before its helpers, and touch up style.
01-08: Commit messages tweaked



--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v12 0/8] error: auto propagated local_err part I

2020-07-07 Thread Vladimir Sementsov-Ogievskiy

07.07.2020 19:50, Markus Armbruster wrote:

To speed things up, I'm taking the liberty to respin Vladimir's series
with my documentation amendments.


Thank you!



After my documentation work, I'm very much inclined to rename
ERRP_AUTO_PROPAGATE() to ERRP_GUARD().  The fact that it propagates
below the hood is detail.  What matters to its users is that it lets
them use @errp more freely.  Thoughts?


No objections, if we are making error-propagation to be internal implementation 
detail, no reason to shout about it in the macro name.


--
Best regards,
Vladimir



Re: [PATCH v4 03/45] error: Document Error API usage rules

2020-07-07 Thread Eric Blake

On 7/7/20 11:05 AM, Markus Armbruster wrote:

This merely codifies existing practice, with one exception: the rule
advising against returning void, where existing practice is mixed.

When the Error API was created, we adopted the (unwritten) rule to
return void when the function returns no useful value on success,
unlike GError, which recommends to return true on success and false on
error then.




Make the rule advising against returning void official by putting it
in writing.  This will hopefully reduce confusion.

Update the examples accordingly.

The remainder of this series will update a substantial amount of code
to honor the rule.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Greg Kurz 
---



@@ -95,14 +122,12 @@
   * Create a new error and pass it to the caller:
   * error_setg(errp, "situation normal, all fouled up");
   *
- * Call a function and receive an error from it:
- * Error *err = NULL;
- * foo(arg, );
- * if (err) {
+ * Call a function, receive an error from it, and pass it to caller


maybe s/to caller/to the caller/


+ * when the function returns a value that indicates failure, say false:
+ * if (!foo(arg, errp)) {
   * handle the error...
   * }
- *
- * Receive an error and pass it on to the caller:
+ * when it doesn't, say a void function:


Hmm. It looks like you have a single sentence "Call a function... when 
the function returns", but this line now makes it obvious that you have 
a single prefix: "Call a function, ...and pass it to the caller:"
with two choices "when the function returns" and "when it doesn't".  I'm 
not sure if there is a nicer way to typeset it, adding yet another ":" 
at the end of the line looks odd.  The idea behind the text is fine, I'm 
just trying to paint the bikeshed to see if there is a better presentation.



   * Error *err = NULL;
   * foo(arg, );
   * if (err) {
@@ -120,6 +145,19 @@
   * foo(arg, errp);
   * for readability.
   *
+ * Receive an error, and handle it locally
+ * when the function returns a value that indicates failure, say false:
+ * Error *err = NULL;
+ * if (!foo(arg, )) {
+ * handle the error...
+ * }
+ * when it doesn't, say a void function:


It helps that you have repeated the same pattern as above.  But that 
means if you change the layout, both groupings should have the same 
layout.  Maybe:


Intro for a task:
- when the function returns...
- when it doesn't

Also, are there functions that have a return type other than void, but 
where the return value is not an indication of error?  If there are, 
then the "say a void function" clause makes sense (but we should 
probably recommend against such functions); if there are not, then "say 
a void function" reads awkwardly.  Maybe:


- when it does not, because it is a void function:


+ * Error *err = NULL;
+ * foo(arg, );
+ * if (err) {
+ * handle the error...
+ * }
+ *
   * Receive and accumulate multiple errors (first one wins):
   * Error *err = NULL, *local_err = NULL;
   * foo(arg, );



--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v4 02/45] error: Improve error.h's big comment

2020-07-07 Thread Eric Blake

On 7/7/20 11:05 AM, Markus Armbruster wrote:

Add headlines to the big comment.

Explain examples for NULL, _abort and _fatal argument
better.

Tweak rationale for error_propagate_prepend().

Signed-off-by: Markus Armbruster 
---
  include/qapi/error.h | 51 +++-
  1 file changed, 36 insertions(+), 15 deletions(-)



Reviewed-by: Eric Blake 

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v4 01/45] error: Fix examples in error.h's big comment

2020-07-07 Thread Eric Blake

On 7/7/20 11:05 AM, Markus Armbruster wrote:

Mark a bad example more clearly.  Fix the error_propagate_prepend()
example.  Add a missing declaration and a second error pileup example.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Greg Kurz 
---
  include/qapi/error.h | 16 ++--
  1 file changed, 14 insertions(+), 2 deletions(-)



I know you kept my R-b because you only trimmed this in relation to v3, 
but I agree that this patch is still looking fine.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v4 00/45] Less clumsy error checking

2020-07-07 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20200707160613.848843-1-arm...@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20200707160613.848843-1-arm...@redhat.com
Subject: [PATCH v4 00/45] Less clumsy error checking

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] 
patchew/159413975752.169116.5808968580649255382.st...@bahia.lan -> 
patchew/159413975752.169116.5808968580649255382.st...@bahia.lan
 * [new tag] 
patchew/1594140062-23522-1-git-send-email-aleksandar.qemu.de...@gmail.com -> 
patchew/1594140062-23522-1-git-send-email-aleksandar.qemu.de...@gmail.com
 * [new tag] patchew/20200707163504.194740-1-kw...@redhat.com -> 
patchew/20200707163504.194740-1-kw...@redhat.com
Switched to a new branch 'test'
5dad863 hmp: Ignore Error objects where the return value suffices
99fa3f2 qdev: Ignore Error objects where the return value suffices
6ee97c0 qemu-img: Ignore Error objects where the return value suffices
677256f error: Avoid error_propagate() after migrate_add_blocker()
974c52b qapi: Purge error_propagate() from QAPI core
b664ca1 qapi: Smooth visitor error checking in generated code
58529e8 qapi: Smooth another visitor error checking pattern
8761cbd block/parallels: Simplify parallels_open() after previous commit
6821adb error: Reduce unnecessary error propagation
8ed0efc error: Eliminate error_propagate() manually
9f8cd51 error: Eliminate error_propagate() with Coccinelle, part 2
4516a2b error: Eliminate error_propagate() with Coccinelle, part 1
e776a9c error: Avoid unnecessary error_propagate() after error_setg()
97a8ae7 qdev: Use returned bool to check for failure, Coccinelle part
b489fef qdev: Make functions taking Error ** return bool, not void
c5651e9 qom: Make functions taking Error ** return bool, not 0/-1
1e9a1c3 qom: Use returned bool to check for failure, manual part
b158de6 qom: Use returned bool to check for failure, Coccinelle part
911dbb4 qom: Make functions taking Error ** return bool, not void
94c4ad1 qom: Put name parameter before value / visitor parameter
a65eadc qom: Use return values to check for error where that's simpler
aff3f41 qom: Don't handle impossible object_property_get_link() failure
f171d59 qom: Crash more nicely on object_property_get_link() failure
d1d7b14 qom: Rename qdev_get_type() to object_get_type()
54e907c qom: Use error_reportf_err() instead of g_printerr() in examples
aa402c4 s390x/pci: Fix harmless mistake in zpci's property fid's setter
e3a01f0 qapi: Use returned bool to check for failure, manual part
ee2a4a7 qapi: Use returned bool to check for failure, Coccinelle part
d78fd21 qapi: Make visitor functions taking Error ** return bool, not void
45cc0d8 hmp: Eliminate a variable in hmp_migrate_set_parameter()
18fa30f block: Avoid error accumulation in bdrv_img_create()
d5fa417 qemu-option: Use returned bool to check for failure
35a4f99 qemu-option: Make functions taking Error ** return bool, not void
9fcbf0b qemu-option: Replace opt_set() by cleaner opt_validate()
09fdc0e qemu-option: Factor out helper opt_create()
f2370fc qemu-option: Simplify around find_default_by_name()
e8d48f4 qemu-option: Factor out helper find_default_by_name()
d9cd2e4 qemu-option: Make uses of find_desc_by_name() more similar
30d78ea qemu-option: Check return value instead of @err where convenient
c670e7c virtio-crypto-pci: Tidy up virtio_crypto_pci_realize()
22252c6 macio: Tidy up error handling in macio_newworld_realize()
8c1b98a qdev: Use returned bool to check for qdev_realize() etc. failure
0ce error: Document Error API usage rules
2ae4ce8 error: Improve error.h's big comment
8d27f64 error: Fix examples in error.h's big comment

=== OUTPUT BEGIN ===
1/45 Checking commit 8d27f64734f9 (error: Fix examples in error.h's big comment)
ERROR: Error messages should not contain newlines
#25: FILE: include/qapi/error.h:27:
+ * error_setg(, "invalid quark\n" // WRONG!

total: 1 errors, 0 warnings, 40 lines checked

Patch 1/45 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

2/45 Checking commit 2ae4ce84c712 (error: Improve error.h's big comment)
3/45 Checking commit 0ce2abc0 (error: Document Error API usage rules)
4/45 Checking commit 8c1b98ac618a (qdev: Use returned bool to check for 
qdev_realize() etc. failure)
5/45 Checking commit 22252c6387fd (macio: Tidy up error handling in 
macio_newworld_realize())
6/45 Checking commit c670e7c4698a (virtio-crypto-pci: Tidy up 
virtio_crypto_pci_realize())
7/45 Checking commit 30d78eae64ac (qemu-option: Check return value 

[PATCH v12 7/8] nbd: Use ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Markus Armbruster
From: Vladimir Sementsov-Ogievskiy 

If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
   _fatal, this means that we don't break error_abort
   (we'll abort on error_set, not on error_propagate)

This commit is generated by command

sed -n '/^Network Block Device (NBD)$/,/^$/{s/^F: //p}' \
MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Markus Armbruster 
[Commit message tweaked]
Signed-off-by: Markus Armbruster 
---
 include/block/nbd.h | 1 +
 block/nbd.c | 7 +++
 nbd/client.c| 5 +
 nbd/server.c| 5 +
 4 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 20363280ae..f7d87636d3 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -361,6 +361,7 @@ void nbd_server_start_options(NbdServerOptions *arg, Error 
**errp);
 static inline int nbd_read(QIOChannel *ioc, void *buffer, size_t size,
const char *desc, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 int ret = qio_channel_read_all(ioc, buffer, size, errp) < 0 ? -EIO : 0;
 
 if (ret < 0) {
diff --git a/block/nbd.c b/block/nbd.c
index 6876da04a7..b7cea0f650 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -1408,16 +1408,15 @@ static void nbd_client_close(BlockDriverState *bs)
 static QIOChannelSocket *nbd_establish_connection(SocketAddress *saddr,
   Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 QIOChannelSocket *sioc;
-Error *local_err = NULL;
 
 sioc = qio_channel_socket_new();
 qio_channel_set_name(QIO_CHANNEL(sioc), "nbd-client");
 
-qio_channel_socket_connect_sync(sioc, saddr, _err);
-if (local_err) {
+qio_channel_socket_connect_sync(sioc, saddr, errp);
+if (*errp) {
 object_unref(OBJECT(sioc));
-error_propagate(errp, local_err);
 return NULL;
 }
 
diff --git a/nbd/client.c b/nbd/client.c
index ba173108ba..e258ef3f7e 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -68,6 +68,7 @@ static int nbd_send_option_request(QIOChannel *ioc, uint32_t 
opt,
uint32_t len, const char *data,
Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 NBDOption req;
 QEMU_BUILD_BUG_ON(sizeof(req) != 16);
 
@@ -153,6 +154,7 @@ static int nbd_receive_option_reply(QIOChannel *ioc, 
uint32_t opt,
 static int nbd_handle_reply_err(QIOChannel *ioc, NBDOptionReply *reply,
 bool strict, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 g_autofree char *msg = NULL;
 
 if (!(reply->type & (1 << 31))) {
@@ -337,6 +339,7 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, 
char **description,
 static int nbd_opt_info_or_go(QIOChannel *ioc, uint32_t opt,
   NBDExportInfo *info, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 NBDOptionReply reply;
 uint32_t len = strlen(info->name);
 uint16_t type;
@@ -882,6 +885,7 @@ static int nbd_start_negotiate(AioContext *aio_context, 
QIOChannel *ioc,
bool structured_reply, bool *zeroes,
Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 uint64_t magic;
 
 trace_nbd_start_negotiate(tlscreds, hostname ? hostname : "");
@@ -1017,6 +1021,7 @@ int nbd_receive_negotiate(AioContext *aio_context, 
QIOChannel *ioc,
   const char *hostname, QIOChannel **outioc,
   NBDExportInfo *info, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 int result;
 bool zeroes;
 bool base_allocation = info->base_allocation;
diff --git a/nbd/server.c b/nbd/server.c
index 20754e9ebc..8a12e586d7 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -211,6 +211,7 @@ static int GCC_FMT_ATTR(4, 0)
 nbd_negotiate_send_rep_verr(NBDClient *client, uint32_t type,
 Error **errp, const char *fmt, va_list va)
 {
+ERRP_AUTO_PROPAGATE();
 g_autofree char *msg = NULL;
 int ret;
 size_t len;
@@ -382,6 +383,7 @@ static int nbd_opt_read_name(NBDClient *client, char 
**name, uint32_t 

[PATCH v12 5/8] fw_cfg: Use ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Markus Armbruster
From: Vladimir Sementsov-Ogievskiy 

If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
   _fatal, this means that we don't break error_abort
   (we'll abort on error_set, not on error_propagate)

This commit is generated by command

sed -n '/^Firmware configuration (fw_cfg)$/,/^$/{s/^F: //p}' \
MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Philippe Mathieu-Daudé 
[Commit message tweaked]
Signed-off-by: Markus Armbruster 
---
 hw/nvram/fw_cfg.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 0408a31f8e..d5386c3235 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -1231,12 +1231,11 @@ static Property fw_cfg_io_properties[] = {
 
 static void fw_cfg_io_realize(DeviceState *dev, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 FWCfgIoState *s = FW_CFG_IO(dev);
-Error *local_err = NULL;
 
-fw_cfg_file_slots_allocate(FW_CFG(s), _err);
-if (local_err) {
-error_propagate(errp, local_err);
+fw_cfg_file_slots_allocate(FW_CFG(s), errp);
+if (*errp) {
 return;
 }
 
@@ -1282,14 +1281,13 @@ static Property fw_cfg_mem_properties[] = {
 
 static void fw_cfg_mem_realize(DeviceState *dev, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 FWCfgMemState *s = FW_CFG_MEM(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 const MemoryRegionOps *data_ops = _cfg_data_mem_ops;
-Error *local_err = NULL;
 
-fw_cfg_file_slots_allocate(FW_CFG(s), _err);
-if (local_err) {
-error_propagate(errp, local_err);
+fw_cfg_file_slots_allocate(FW_CFG(s), errp);
+if (*errp) {
 return;
 }
 
-- 
2.26.2




[PATCH v12 0/8] error: auto propagated local_err part I

2020-07-07 Thread Markus Armbruster
To speed things up, I'm taking the liberty to respin Vladimir's series
with my documentation amendments.

After my documentation work, I'm very much inclined to rename
ERRP_AUTO_PROPAGATE() to ERRP_GUARD().  The fact that it propagates
below the hood is detail.  What matters to its users is that it lets
them use @errp more freely.  Thoughts?

Based-on: Message-Id: <20200707160613.848843-1-arm...@redhat.com>

Available from my public repository https://repo.or.cz/qemu/armbru.git
on branch error-auto.

v12: (based on "[PATCH v4 00/45] Less clumsy error checking")
01: Comments merged properly with recent commit "error: Document Error
API usage rules", and edited for clarity.  Put ERRP_AUTO_PROPAGATE()
before its helpers, and touch up style.
01-08: Commit messages tweaked

Vladimir's cover letter for v11:

v11: (based-on "[PATCH v2 00/44] Less clumsy error checking")
01: minor rebase of documentation, keep r-bs
02: - minor comment tweaks [Markus]
- use explicit file name in MAINTAINERS instead of pattern
- add Markus's r-b
03,07,08: rabase changes, drop r-bs


v11 is available at
 https://src.openvz.org/scm/~vsementsov/qemu.git #tag 
up-auto-local-err-partI-v11
v10 is available at
 https://src.openvz.org/scm/~vsementsov/qemu.git #tag 
up-auto-local-err-partI-v10

In these series, there is no commit-per-subsystem script, each generated
commit is generated in separate.

Still, generating commands are very similar, and looks like

sed -n '/^$/,/^$/{s/^F: //p}' MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Note, that in each generated commit, generation command is the only
text, indented by 8 spaces in 'git log -1' output, so, to regenerate all
commits (for example, after rebase, or change in coccinelle script), you
may use the following command:

git rebase -x "sh -c \"git show --pretty= --name-only | xargs git checkout 
HEAD^ -- ; git reset; git log -1 | grep '^' | sh\"" HEAD~6

Which will start automated interactive rebase for generated patches,
which will stop if generated patch changed
(you may do git commit --amend to apply updated generated changes).

Note:
  git show --pretty= --name-only   - lists files, changed in HEAD
  git log -1 | grep '^' | sh   - rerun generation command of HEAD


Check for compilation of changed .c files
git rebase -x "sh -c \"git show --pretty= --name-only | sed -n 's/\.c$/.o/p' | 
xargs make -j9\"" HEAD~6

Vladimir Sementsov-Ogievskiy (8):
  error: New macro ERRP_AUTO_PROPAGATE()
  scripts: Coccinelle script to use ERRP_AUTO_PROPAGATE()
  sd: Use ERRP_AUTO_PROPAGATE()
  pflash: Use ERRP_AUTO_PROPAGATE()
  fw_cfg: Use ERRP_AUTO_PROPAGATE()
  virtio-9p: Use ERRP_AUTO_PROPAGATE()
  nbd: Use ERRP_AUTO_PROPAGATE()
  xen: Use ERRP_AUTO_PROPAGATE()

 scripts/coccinelle/auto-propagated-errp.cocci | 337 ++
 include/block/nbd.h   |   1 +
 include/qapi/error.h  | 163 -
 block/nbd.c   |   7 +-
 hw/9pfs/9p-local.c|  12 +-
 hw/9pfs/9p.c  |   1 +
 hw/block/dataplane/xen-block.c|  17 +-
 hw/block/pflash_cfi01.c   |   7 +-
 hw/block/pflash_cfi02.c   |   7 +-
 hw/block/xen-block.c  | 102 +++---
 hw/nvram/fw_cfg.c |  14 +-
 hw/pci-host/xen_igd_pt.c  |   7 +-
 hw/sd/sdhci-pci.c |   7 +-
 hw/sd/sdhci.c |  21 +-
 hw/sd/ssi-sd.c|  10 +-
 hw/xen/xen-backend.c  |   7 +-
 hw/xen/xen-bus.c  |  92 ++---
 hw/xen/xen-host-pci-device.c  |  27 +-
 hw/xen/xen_pt.c   |  25 +-
 hw/xen/xen_pt_config_init.c   |  17 +-
 nbd/client.c  |   5 +
 nbd/server.c  |   5 +
 MAINTAINERS   |   1 +
 23 files changed, 659 insertions(+), 233 deletions(-)
 create mode 100644 scripts/coccinelle/auto-propagated-errp.cocci

-- 
2.26.2




[PULL 11/12] block: Add support to warn on backing file change without format

2020-07-07 Thread Kevin Wolf
From: Eric Blake 

For now, this is a mechanical addition; all callers pass false. But
the next patch will use it to improve 'qemu-img rebase -u' when
selecting a backing file with no format.

Signed-off-by: Eric Blake 
Reviewed-by: Peter Krempa 
Reviewed-by: Ján Tomko 
Message-Id: <20200706203954.341758-10-ebl...@redhat.com>
Signed-off-by: Kevin Wolf 
---
 include/block/block.h |  4 ++--
 block.c   | 13 ++---
 block/qcow2.c |  2 +-
 block/stream.c|  2 +-
 blockdev.c|  3 ++-
 qemu-img.c|  4 ++--
 6 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/include/block/block.h b/include/block/block.h
index e8fc814996..b57a3806a5 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -410,8 +410,8 @@ void bdrv_get_geometry(BlockDriverState *bs, uint64_t 
*nb_sectors_ptr);
 void bdrv_refresh_limits(BlockDriverState *bs, Error **errp);
 int bdrv_commit(BlockDriverState *bs);
 int bdrv_make_empty(BdrvChild *c, Error **errp);
-int bdrv_change_backing_file(BlockDriverState *bs,
-const char *backing_file, const char *backing_fmt);
+int bdrv_change_backing_file(BlockDriverState *bs, const char *backing_file,
+ const char *backing_fmt, bool warn);
 void bdrv_register(BlockDriver *bdrv);
 int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
const char *backing_file_str);
diff --git a/block.c b/block.c
index 983b9bd29a..5cfd10f6b4 100644
--- a/block.c
+++ b/block.c
@@ -1206,7 +1206,8 @@ static int bdrv_backing_update_filename(BdrvChild *c, 
BlockDriverState *base,
 }
 
 ret = bdrv_change_backing_file(parent, filename,
-   base->drv ? base->drv->format_name : "");
+   base->drv ? base->drv->format_name : "",
+   false);
 if (ret < 0) {
 error_setg_errno(errp, -ret, "Could not update backing file link");
 }
@@ -4684,8 +4685,8 @@ int bdrv_check(BlockDriverState *bs,
  *image file header
  * -ENOTSUP - format driver doesn't support changing the backing file
  */
-int bdrv_change_backing_file(BlockDriverState *bs,
-const char *backing_file, const char *backing_fmt)
+int bdrv_change_backing_file(BlockDriverState *bs, const char *backing_file,
+ const char *backing_fmt, bool warn)
 {
 BlockDriver *drv = bs->drv;
 int ret;
@@ -4699,6 +4700,12 @@ int bdrv_change_backing_file(BlockDriverState *bs,
 return -EINVAL;
 }
 
+if (warn && backing_file && !backing_fmt) {
+warn_report("Deprecated use of backing file without explicit "
+"backing format, use of this image requires "
+"potentially unsafe format probing");
+}
+
 if (drv->bdrv_change_backing_file != NULL) {
 ret = drv->bdrv_change_backing_file(bs, backing_file, backing_fmt);
 } else {
diff --git a/block/qcow2.c b/block/qcow2.c
index 99aedb8eed..36793e3bb0 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3630,7 +3630,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, 
Error **errp)
 }
 
 ret = bdrv_change_backing_file(blk_bs(blk), qcow2_opts->backing_file,
-   backing_format);
+   backing_format, false);
 if (ret < 0) {
 error_setg_errno(errp, -ret, "Could not assign backing file '%s' "
  "with format '%s'", qcow2_opts->backing_file,
diff --git a/block/stream.c b/block/stream.c
index aa2e7af98e..310ccbaa4c 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -78,7 +78,7 @@ static int stream_prepare(Job *job)
 }
 }
 bdrv_set_backing_hd(bs, base, _err);
-ret = bdrv_change_backing_file(bs, base_id, base_fmt);
+ret = bdrv_change_backing_file(bs, base_id, base_fmt, false);
 if (local_err) {
 error_report_err(local_err);
 return -EPERM;
diff --git a/blockdev.c b/blockdev.c
index 31d5eaf6bf..db0fbcd214 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3429,7 +3429,8 @@ void qmp_change_backing_file(const char *device,
 }
 
 ret = bdrv_change_backing_file(image_bs, backing_file,
-   image_bs->drv ? image_bs->drv->format_name : 
"");
+   image_bs->drv ? image_bs->drv->format_name 
: "",
+   false);
 
 if (ret < 0) {
 error_setg_errno(errp, -ret, "Could not change backing file to '%s'",
diff --git a/qemu-img.c b/qemu-img.c
index b366a89ce3..440c6aef67 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3804,9 +3804,9 @@ static int img_rebase(int argc, char **argv)
  * doesn't change when we switch the backing file.
  */
 if (out_baseimg && *out_baseimg) {
-ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
+ret = 

[PULL 03/12] qemu-img: Flush stdout before before potential stderr messages

2020-07-07 Thread Kevin Wolf
From: Eric Blake 

During 'qemu-img create ... 2>&1', if --quiet is not in force, we can
end up with buffered I/O in stdout that was produced before failure,
but which appears in output after failure.  This is confusing; the fix
is to flush stdout prior to attempting anything that might produce an
error message.  Several iotests demonstrate the resulting ordering
change now that the merged outputs now reflect chronology.  (An even
better fix would be to avoid printf from within block.c altogether,
but that's much more invasive...)

Signed-off-by: Eric Blake 
Message-Id: <20200706203954.341758-2-ebl...@redhat.com>
Signed-off-by: Kevin Wolf 
---
 block.c| 1 +
 tests/qemu-iotests/049.out | 8 
 tests/qemu-iotests/054.out | 2 +-
 tests/qemu-iotests/079.out | 2 +-
 tests/qemu-iotests/112.out | 4 ++--
 tests/qemu-iotests/259.out | 2 +-
 6 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/block.c b/block.c
index 6dbcb7e083..a568196ba2 100644
--- a/block.c
+++ b/block.c
@@ -6186,6 +6186,7 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
 printf("Formatting '%s', fmt=%s ", filename, fmt);
 qemu_opts_print(opts, " ");
 puts("");
+fflush(stdout);
 }
 
 ret = bdrv_create(drv, filename, opts, _err);
diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
index c54ae21b86..22f395246b 100644
--- a/tests/qemu-iotests/049.out
+++ b/tests/qemu-iotests/049.out
@@ -167,12 +167,12 @@ qemu-img create -f qcow2 -o compat=1.1 TEST_DIR/t.qcow2 
64M
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 
cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
 
 qemu-img create -f qcow2 -o compat=0.42 TEST_DIR/t.qcow2 64M
-qemu-img: TEST_DIR/t.qcow2: Invalid parameter '0.42'
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.42 
cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
+qemu-img: TEST_DIR/t.qcow2: Invalid parameter '0.42'
 
 qemu-img create -f qcow2 -o compat=foobar TEST_DIR/t.qcow2 64M
-qemu-img: TEST_DIR/t.qcow2: Invalid parameter 'foobar'
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=foobar 
cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
+qemu-img: TEST_DIR/t.qcow2: Invalid parameter 'foobar'
 
 == Check preallocation option ==
 
@@ -183,8 +183,8 @@ qemu-img create -f qcow2 -o preallocation=metadata 
TEST_DIR/t.qcow2 64M
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 
preallocation=metadata lazy_refcounts=off refcount_bits=16 compression_type=zlib
 
 qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M
-qemu-img: TEST_DIR/t.qcow2: Invalid parameter '1234'
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 
preallocation=1234 lazy_refcounts=off refcount_bits=16 compression_type=zlib
+qemu-img: TEST_DIR/t.qcow2: Invalid parameter '1234'
 
 == Check encryption option ==
 
@@ -206,7 +206,7 @@ qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=off 
TEST_DIR/t.qcow2 64M
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 
cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
 
 qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=on TEST_DIR/t.qcow2 64M
-qemu-img: TEST_DIR/t.qcow2: Lazy refcounts only supported with compatibility 
level 1.1 and above (use version=v3 or greater)
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 
cluster_size=65536 lazy_refcounts=on refcount_bits=16 compression_type=zlib
+qemu-img: TEST_DIR/t.qcow2: Lazy refcounts only supported with compatibility 
level 1.1 and above (use version=v3 or greater)
 
 *** done
diff --git a/tests/qemu-iotests/054.out b/tests/qemu-iotests/054.out
index e6ec430edd..71f18bb987 100644
--- a/tests/qemu-iotests/054.out
+++ b/tests/qemu-iotests/054.out
@@ -1,8 +1,8 @@
 QA output created by 054
 
 creating too large image (1 EB)
-qemu-img: TEST_DIR/t.IMGFMT: The image size is too large for file format 
'IMGFMT' (try using a larger cluster size)
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1152921504606846976
+qemu-img: TEST_DIR/t.IMGFMT: The image size is too large for file format 
'IMGFMT' (try using a larger cluster size)
 
 creating too large image (1 EB) using qcow2.py
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296
diff --git a/tests/qemu-iotests/079.out b/tests/qemu-iotests/079.out
index aab922fb36..f65a9ca84f 100644
--- a/tests/qemu-iotests/079.out
+++ b/tests/qemu-iotests/079.out
@@ -9,6 +9,6 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 
preallocation=metadat
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 
preallocation=metadata
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 
preallocation=metadata
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 
preallocation=metadata
-qemu-img: TEST_DIR/t.IMGFMT: Cluster size must be a power of two between 

[PATCH v12 6/8] virtio-9p: Use ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Markus Armbruster
From: Vladimir Sementsov-Ogievskiy 

If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
   _fatal, this means that we don't break error_abort
   (we'll abort on error_set, not on error_propagate)

This commit is generated by command

sed -n '/^virtio-9p$/,/^$/{s/^F: //p}' MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Acked-by: Greg Kurz 
Reviewed-by: Christian Schoenebeck 
[Commit message tweaked]
Signed-off-by: Markus Armbruster 
---
 hw/9pfs/9p-local.c | 12 +---
 hw/9pfs/9p.c   |  1 +
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 54e012e5b4..0361e0c0b4 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -1479,10 +1479,10 @@ static void error_append_security_model_hint(Error 
*const *errp)
 
 static int local_parse_opts(QemuOpts *opts, FsDriverEntry *fse, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 const char *sec_model = qemu_opt_get(opts, "security_model");
 const char *path = qemu_opt_get(opts, "path");
 const char *multidevs = qemu_opt_get(opts, "multidevs");
-Error *local_err = NULL;
 
 if (!sec_model) {
 error_setg(errp, "security_model property not set");
@@ -1516,11 +1516,10 @@ static int local_parse_opts(QemuOpts *opts, 
FsDriverEntry *fse, Error **errp)
 fse->export_flags &= ~V9FS_FORBID_MULTIDEVS;
 fse->export_flags &= ~V9FS_REMAP_INODES;
 } else {
-error_setg(_err, "invalid multidevs property '%s'",
+error_setg(errp, "invalid multidevs property '%s'",
multidevs);
-error_append_hint(_err, "Valid options are: multidevs="
+error_append_hint(errp, "Valid options are: multidevs="
   "[remap|forbid|warn]\n");
-error_propagate(errp, local_err);
 return -1;
 }
 }
@@ -1530,9 +1529,8 @@ static int local_parse_opts(QemuOpts *opts, FsDriverEntry 
*fse, Error **errp)
 return -1;
 }
 
-if (fsdev_throttle_parse_opts(opts, >fst, _err)) {
-error_propagate_prepend(errp, local_err,
-"invalid throttle configuration: ");
+if (fsdev_throttle_parse_opts(opts, >fst, errp)) {
+error_prepend(errp, "invalid throttle configuration: ");
 return -1;
 }
 
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 9755fba9a9..bdb1360482 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -4011,6 +4011,7 @@ void pdu_submit(V9fsPDU *pdu, P9MsgHeader *hdr)
 int v9fs_device_realize_common(V9fsState *s, const V9fsTransport *t,
Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 int i, len;
 struct stat stat;
 FsDriverEntry *fse;
-- 
2.26.2




[PULL 04/12] block: Finish deprecation of 'qemu-img convert -n -o'

2020-07-07 Thread Kevin Wolf
From: Eric Blake 

It's been two releases since we started warning; time to make the
combination an error as promised.  There was no iotest coverage, so
add some.

While touching the documentation, tweak another section heading for
consistent style.

Signed-off-by: Eric Blake 
Message-Id: <20200706203954.341758-3-ebl...@redhat.com>
Signed-off-by: Kevin Wolf 
---
 docs/system/deprecated.rst | 18 --
 qemu-img.c |  4 ++--
 tests/qemu-iotests/122 |  7 +++
 tests/qemu-iotests/122.out |  4 
 4 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
index 47f84be8e0..73b9d9f378 100644
--- a/docs/system/deprecated.rst
+++ b/docs/system/deprecated.rst
@@ -418,14 +418,6 @@ kernel in 2018, and has also been dropped from glibc.
 Related binaries
 
 
-``qemu-img convert -n -o`` (since 4.2.0)
-
-
-All options specified in ``-o`` are image creation options, so
-they have no effect when used with ``-n`` to skip image creation.
-Silently ignored options can be confusing, so this combination of
-options will be made an error in future versions.
-
 Backwards compatibility
 ---
 
@@ -531,8 +523,8 @@ spec you can use the ``-cpu rv64gcsu,priv_spec=v1.10.0`` 
command line argument.
 Related binaries
 
 
-``qemu-nbd --partition`` (removed in 5.0.0)
-'''
+``qemu-nbd --partition`` (removed in 5.0)
+'
 
 The ``qemu-nbd --partition $digit`` code (also spelled ``-P``)
 could only handle MBR partitions, and never correctly handled logical
@@ -548,6 +540,12 @@ can be rewritten as::
 
   qemu-nbd -t --image-opts 
driver=raw,offset=1M,size=100M,file.driver=qcow2,file.file.driver=file,file.file.filename=file.qcow2
 
+``qemu-img convert -n -o`` (removed in 5.1)
+'''
+
+All options specified in ``-o`` are image creation options, so
+they are now rejected when used with ``-n`` to skip image creation.
+
 Command line options
 
 
diff --git a/qemu-img.c b/qemu-img.c
index 74946f81ca..b366a89ce3 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2369,8 +2369,8 @@ static int img_convert(int argc, char **argv)
 }
 
 if (skip_create && options) {
-warn_report("-o has no effect when skipping image creation");
-warn_report("This will become an error in future QEMU versions.");
+error_report("-o has no effect when skipping image creation");
+goto fail_getopt;
 }
 
 if (s.has_zero_init && !skip_create) {
diff --git a/tests/qemu-iotests/122 b/tests/qemu-iotests/122
index f7a3ae684a..2dc16b2ca4 100755
--- a/tests/qemu-iotests/122
+++ b/tests/qemu-iotests/122
@@ -290,6 +290,13 @@ TEST_IMG="$TEST_IMG".orig _make_test_img 64M
 # backing file"
 $QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base -n "$TEST_IMG" 
"$TEST_IMG".orig
 
+echo
+echo '=== -n incompatible with -o ==='
+echo
+
+$QEMU_IMG convert -O $IMGFMT -o preallocation=metadata -n \
+ "$TEST_IMG" "$TEST_IMG".orig && echo "unexpected success"
+
 # success, all done
 echo '*** done'
 rm -f $seq.full
diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out
index 1a35951a80..c2e154a1e5 100644
--- a/tests/qemu-iotests/122.out
+++ b/tests/qemu-iotests/122.out
@@ -233,4 +233,8 @@ Images are identical.
 
 Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
 Formatting 'TEST_DIR/t.IMGFMT.orig', fmt=IMGFMT size=67108864
+
+=== -n incompatible with -o ===
+
+qemu-img: -o has no effect when skipping image creation
 *** done
-- 
2.25.4




[PULL 02/12] file-posix: Mitigate file fragmentation with extent size hints

2020-07-07 Thread Kevin Wolf
Especially when O_DIRECT is used with image files so that the page cache
indirection can't cause a merge of allocating requests, the file will
fragment on the file system layer, with a potentially very small
fragment size (this depends on the requests the guest sent).

On Linux, fragmentation can be reduced by setting an extent size hint
when creating the file (at least on XFS, it can't be set any more after
the first extent has been allocated), basically giving raw files a
"cluster size" for allocation.

This adds a create option to set the extent size hint, and changes the
default from not setting a hint to setting it to 1 MB. The main reason
why qcow2 defaults to smaller cluster sizes is that COW becomes more
expensive, which is not an issue with raw files, so we can choose a
larger size. The tradeoff here is only potentially wasted disk space.

For qcow2 (or other image formats) over file-posix, the advantage should
even be greater because they grow sequentially without leaving holes, so
there won't be wasted space. Setting even larger extent size hints for
such images may make sense. This can be done with the new option, but
let's keep the default conservative for now.

The effect is very visible with a test that intentionally creates a
badly fragmented file with qemu-img bench (the time difference while
creating the file is already remarkable) and then looks at the number of
extents and the time a simple "qemu-img map" takes.

Without an extent size hint:

$ ./qemu-img create -f raw -o extent_size_hint=0 ~/tmp/test.raw 10G
Formatting '/home/kwolf/tmp/test.raw', fmt=raw size=10737418240 
extent_size_hint=0
$ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 100 -S 8192 
-o 0
Sending 100 write requests, 4096 bytes each, 64 in parallel (starting 
at offset 0, step size 8192)
Run completed in 25.848 seconds.
$ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 100 -S 8192 
-o 4096
Sending 100 write requests, 4096 bytes each, 64 in parallel (starting 
at offset 4096, step size 8192)
Run completed in 19.616 seconds.
$ filefrag ~/tmp/test.raw
/home/kwolf/tmp/test.raw: 200 extents found
$ time ./qemu-img map ~/tmp/test.raw
Offset  Length  Mapped to   File
0   0x1e848 0   /home/kwolf/tmp/test.raw

real0m1,279s
user0m0,043s
sys 0m1,226s

With the new default extent size hint of 1 MB:

$ ./qemu-img create -f raw -o extent_size_hint=1M ~/tmp/test.raw 10G
Formatting '/home/kwolf/tmp/test.raw', fmt=raw size=10737418240 
extent_size_hint=1048576
$ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 100 -S 8192 
-o 0
Sending 100 write requests, 4096 bytes each, 64 in parallel (starting 
at offset 0, step size 8192)
Run completed in 11.833 seconds.
$ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 100 -S 8192 
-o 4096
Sending 100 write requests, 4096 bytes each, 64 in parallel (starting 
at offset 4096, step size 8192)
Run completed in 10.155 seconds.
$ filefrag ~/tmp/test.raw
/home/kwolf/tmp/test.raw: 178 extents found
$ time ./qemu-img map ~/tmp/test.raw
Offset  Length  Mapped to   File
0   0x1e848 0   /home/kwolf/tmp/test.raw

real0m0,061s
user0m0,040s
sys 0m0,014s

Signed-off-by: Kevin Wolf 
Message-Id: <20200707142329.48303-1-kw...@redhat.com>
Reviewed-by: Eric Blake 
Signed-off-by: Kevin Wolf 
---
 qapi/block-core.json   | 11 ++
 include/block/block_int.h  |  1 +
 block/file-posix.c | 42 ++
 tests/qemu-iotests/082.out | 16 +++
 tests/qemu-iotests/243 |  7 ---
 tests/qemu-iotests/243.out | 16 +++
 6 files changed, 78 insertions(+), 15 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 0e1c6a59f2..ddd3737d90 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4185,14 +4185,17 @@
 # falloc (if defined CONFIG_POSIX_FALLOCATE),
 # full (if defined CONFIG_POSIX))
 # @nocow: Turn off copy-on-write (valid only on btrfs; default: off)
+# @extent-size-hint: Extent size hint to add to the image file; 0 for not
+#adding an extent size hint (default: 1 MB, since 5.1)
 #
 # Since: 2.12
 ##
 { 'struct': 'BlockdevCreateOptionsFile',
-  'data': { 'filename': 'str',
-'size': 'size',
-'*preallocation':   'PreallocMode',
-'*nocow':   'bool' } }
+  'data': { 'filename': 'str',
+'size': 'size',
+'*preallocation':   'PreallocMode',
+'*nocow':   'bool',
+'*extent-size-hint':'size'} }
 
 ##
 # @BlockdevCreateOptionsGluster:
diff --git a/include/block/block_int.h b/include/block/block_int.h

[PATCH v12 8/8] xen: Use ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Markus Armbruster
From: Vladimir Sementsov-Ogievskiy 

If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
   _fatal, this means that we don't break error_abort
   (we'll abort on error_set, not on error_propagate)

This commit is generated by command

sed -n '/^X86 Xen CPUs$/,/^$/{s/^F: //p}' MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Philippe Mathieu-Daudé 
[Commit message tweaked]
Signed-off-by: Markus Armbruster 
---
 hw/block/dataplane/xen-block.c |  17 +++---
 hw/block/xen-block.c   | 102 ++---
 hw/pci-host/xen_igd_pt.c   |   7 +--
 hw/xen/xen-backend.c   |   7 +--
 hw/xen/xen-bus.c   |  92 +
 hw/xen/xen-host-pci-device.c   |  27 +
 hw/xen/xen_pt.c|  25 
 hw/xen/xen_pt_config_init.c|  17 +++---
 8 files changed, 128 insertions(+), 166 deletions(-)

diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c
index 5f8f15778b..1a077cc05f 100644
--- a/hw/block/dataplane/xen-block.c
+++ b/hw/block/dataplane/xen-block.c
@@ -723,8 +723,8 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane,
unsigned int protocol,
Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 XenDevice *xendev = dataplane->xendev;
-Error *local_err = NULL;
 unsigned int ring_size;
 unsigned int i;
 
@@ -760,9 +760,8 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane,
 }
 
 xen_device_set_max_grant_refs(xendev, dataplane->nr_ring_ref,
-  _err);
-if (local_err) {
-error_propagate(errp, local_err);
+  errp);
+if (*errp) {
 goto stop;
 }
 
@@ -770,9 +769,8 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane,
   dataplane->ring_ref,
   dataplane->nr_ring_ref,
   PROT_READ | PROT_WRITE,
-  _err);
-if (local_err) {
-error_propagate(errp, local_err);
+  errp);
+if (*errp) {
 goto stop;
 }
 
@@ -805,9 +803,8 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane,
 dataplane->event_channel =
 xen_device_bind_event_channel(xendev, event_channel,
   xen_block_dataplane_event, dataplane,
-  _err);
-if (local_err) {
-error_propagate(errp, local_err);
+  errp);
+if (*errp) {
 goto stop;
 }
 
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index a775fba7c0..623ae5b8e0 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -195,6 +195,7 @@ static const BlockDevOps xen_block_dev_ops = {
 
 static void xen_block_realize(XenDevice *xendev, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev);
 XenBlockDeviceClass *blockdev_class =
 XEN_BLOCK_DEVICE_GET_CLASS(xendev);
@@ -202,7 +203,6 @@ static void xen_block_realize(XenDevice *xendev, Error 
**errp)
 XenBlockVdev *vdev = >props.vdev;
 BlockConf *conf = >props.conf;
 BlockBackend *blk = conf->blk;
-Error *local_err = NULL;
 
 if (vdev->type == XEN_BLOCK_VDEV_TYPE_INVALID) {
 error_setg(errp, "vdev property not set");
@@ -212,9 +212,8 @@ static void xen_block_realize(XenDevice *xendev, Error 
**errp)
 trace_xen_block_realize(type, vdev->disk, vdev->partition);
 
 if (blockdev_class->realize) {
-blockdev_class->realize(blockdev, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+blockdev_class->realize(blockdev, errp);
+if (*errp) {
 return;
 }
 }
@@ -280,8 +279,8 @@ static void xen_block_frontend_changed(XenDevice *xendev,
enum xenbus_state frontend_state,

[PULL 01/12] qemu-img map: Don't limit block status request size

2020-07-07 Thread Kevin Wolf
Limiting each loop iteration of qemu-img map to 1 GB was arbitrary from
the beginning, though it only cut the maximum in half then because the
interface was a signed 32 bit byte count. These days, bdrv_block_status
supports a 64 bit byte count, so the arbitrary limit is even worse.

On file-posix, bdrv_block_status() eventually maps to SEEK_HOLE and
SEEK_DATA, which don't support a limit, but always do all of the work
necessary to find the start of the next hole/data. Much of this work may
be repeated if we don't use this information fully, but query with an
only slightly larger offset in the next loop iteration. Therefore, if
bdrv_block_status() is called in a loop, it should always pass the
full number of bytes that the whole loop is interested in.

This removes the arbitrary limit and speeds up 'qemu-img map'
significantly on heavily fragmented images.

Signed-off-by: Kevin Wolf 
Message-Id: <20200707144629.51235-1-kw...@redhat.com>
Reviewed-by: Eric Blake 
Signed-off-by: Kevin Wolf 
---
 qemu-img.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index bdb9f6aa46..74946f81ca 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3217,12 +3217,9 @@ static int img_map(int argc, char **argv)
 curr.start = start_offset;
 while (curr.start + curr.length < length) {
 int64_t offset = curr.start + curr.length;
-int64_t n;
+int64_t n = length - offset;
 
-/* Probe up to 1 GiB at a time.  */
-n = MIN(1 * GiB, length - offset);
 ret = get_block_status(bs, offset, n, );
-
 if (ret < 0) {
 error_report("Could not read file metadata: %s", strerror(-ret));
 goto out;
-- 
2.25.4




[PATCH v12 2/8] scripts: Coccinelle script to use ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Markus Armbruster
From: Vladimir Sementsov-Ogievskiy 

Script adds ERRP_AUTO_PROPAGATE macro invocation where appropriate and
does corresponding changes in code (look for details in
include/qapi/error.h)

Usage example:
spatch --sp-file scripts/coccinelle/auto-propagated-errp.cocci \
 --macro-file scripts/cocci-macro-file.h --in-place --no-show-diff \
 --max-width 80 FILES...

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Markus Armbruster 
Signed-off-by: Markus Armbruster 
---
 scripts/coccinelle/auto-propagated-errp.cocci | 337 ++
 include/qapi/error.h  |   3 +
 MAINTAINERS   |   1 +
 3 files changed, 341 insertions(+)
 create mode 100644 scripts/coccinelle/auto-propagated-errp.cocci

diff --git a/scripts/coccinelle/auto-propagated-errp.cocci 
b/scripts/coccinelle/auto-propagated-errp.cocci
new file mode 100644
index 00..c29f695adf
--- /dev/null
+++ b/scripts/coccinelle/auto-propagated-errp.cocci
@@ -0,0 +1,337 @@
+// Use ERRP_AUTO_PROPAGATE (see include/qapi/error.h)
+//
+// Copyright (c) 2020 Virtuozzo International GmbH.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see
+// .
+//
+// Usage example:
+// spatch --sp-file scripts/coccinelle/auto-propagated-errp.cocci \
+//  --macro-file scripts/cocci-macro-file.h --in-place \
+//  --no-show-diff --max-width 80 FILES...
+//
+// Note: --max-width 80 is needed because coccinelle default is less
+// than 80, and without this parameter coccinelle may reindent some
+// lines which fit into 80 characters but not to coccinelle default,
+// which in turn produces extra patch hunks for no reason.
+
+// Switch unusual Error ** parameter names to errp
+// (this is necessary to use ERRP_AUTO_PROPAGATE).
+//
+// Disable optional_qualifier to skip functions with
+// "Error *const *errp" parameter.
+//
+// Skip functions with "assert(_errp && *_errp)" statement, because
+// that signals unusual semantics, and the parameter name may well
+// serve a purpose. (like nbd_iter_channel_error()).
+//
+// Skip util/error.c to not touch, for example, error_propagate() and
+// error_propagate_prepend().
+@ depends on !(file in "util/error.c") disable optional_qualifier@
+identifier fn;
+identifier _errp != errp;
+@@
+
+ fn(...,
+-   Error **_errp
++   Error **errp
+,...)
+ {
+(
+ ... when != assert(_errp && *_errp)
+&
+ <...
+-_errp
++errp
+ ...>
+)
+ }
+
+// Add invocation of ERRP_AUTO_PROPAGATE to errp-functions where
+// necessary
+//
+// Note, that without "when any" the final "..." does not mach
+// something matched by previous pattern, i.e. the rule will not match
+// double error_prepend in control flow like in
+// vfio_set_irq_signaling().
+//
+// Note, "exists" says that we want apply rule even if it does not
+// match on all possible control flows (otherwise, it will not match
+// standard pattern when error_propagate() call is in if branch).
+@ disable optional_qualifier exists@
+identifier fn, local_err;
+symbol errp;
+@@
+
+ fn(..., Error **errp, ...)
+ {
++   ERRP_AUTO_PROPAGATE();
+...  when != ERRP_AUTO_PROPAGATE();
+(
+(
+error_append_hint(errp, ...);
+|
+error_prepend(errp, ...);
+|
+error_vprepend(errp, ...);
+)
+... when any
+|
+Error *local_err = NULL;
+...
+(
+error_propagate_prepend(errp, local_err, ...);
+|
+error_propagate(errp, local_err);
+)
+...
+)
+ }
+
+// Warn when several Error * definitions are in the control flow.
+// This rule is not chained to rule1 and less restrictive, to cover more
+// functions to warn (even those we are not going to convert).
+//
+// Note, that even with one (or zero) Error * definition in the each
+// control flow we may have several (in total) Error * definitions in
+// the function. This case deserves attention too, but I don't see
+// simple way to match with help of coccinelle.
+@check1 disable optional_qualifier exists@
+identifier fn, _errp, local_err, local_err2;
+position p1, p2;
+@@
+
+ fn(..., Error **_errp, ...)
+ {
+ ...
+ Error *local_err = NULL;@p1
+ ... when any
+ Error *local_err2 = NULL;@p2
+ ... when any
+ }
+
+@ script:python @
+fn << check1.fn;
+p1 << check1.p1;
+p2 << check1.p2;
+@@
+
+print('Warning: function {} has several definitions of '
+  'Error * local variable: at {}:{} and then at {}:{}'.format(
+  fn, p1[0].file, p1[0].line, 

[PULL 12/12] qemu-img: Deprecate use of -b without -F

2020-07-07 Thread Kevin Wolf
From: Eric Blake 

Creating an image that requires format probing of the backing image is
potentially unsafe (we've had several CVEs over the years based on
probes leaking information to the guest on a subsequent boot, although
these days tools like libvirt are aware of the issue enough to prevent
the worst effects).  For example, if our probing algorithm ever
changes, or if other tools like libvirt determine a different probe
result than we do, then subsequent use of that backing file under a
different format will present corrupted data to the guest.
Fortunately, the worst effects occur only when the backing image is
originally raw, and we at least prevent commit into a probed raw
backing file that would change its probed type.

Still, it is worth starting a deprecation clock so that future
qemu-img can refuse to create backing chains that would rely on
probing, to encourage clients to avoid unsafe practices.  Most
warnings are intentionally emitted from bdrv_img_create() in the block
layer, but qemu-img convert uses bdrv_create() which cannot emit its
own warning without causing spurious warnings on other code paths.  In
the end, all command-line image creation or backing file rewriting now
performs a check.

Furthermore, if we probe a backing file as non-raw, then it is safe to
explicitly record that result (rather than relying on future probes);
only where we probe a raw image do we care about further warnings to
the user when using such an image (for example, commits into a
probed-raw backing file are prevented), to help them improve their
tooling.  But whether or not we make the probe results explicit, we
still warn the user to remind them to upgrade their workflow to supply
-F always.

iotest 114 specifically wants to create an unsafe image for later
amendment rather than defaulting to our new default of recording a
probed format, so it needs an update.  While touching it, expand it to
cover all of the various warnings enabled by this patch.  iotest 293
also shows a change to qcow messages.

Signed-off-by: Eric Blake 
Message-Id: <20200706203954.341758-11-ebl...@redhat.com>
Signed-off-by: Kevin Wolf 
---
 docs/system/deprecated.rst | 20 
 block.c| 27 ++-
 qemu-img.c |  9 -
 tests/qemu-iotests/114 | 12 
 tests/qemu-iotests/114.out |  9 +
 tests/qemu-iotests/293.out |  4 +++-
 6 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
index b312ad27aa..ca994e3ef5 100644
--- a/docs/system/deprecated.rst
+++ b/docs/system/deprecated.rst
@@ -430,6 +430,26 @@ image).  Rather, any changes to the backing chain should 
be performed
 with ``qemu-img rebase -u`` either before or after the remaining
 changes being performed by amend, as appropriate.
 
+qemu-img backing file without format (since 5.1)
+
+
+The use of ``qemu-img create``, ``qemu-img rebase``, or ``qemu-img
+convert`` to create or modify an image that depends on a backing file
+now recommends that an explicit backing format be provided.  This is
+for safety: if QEMU probes a different format than what you thought,
+the data presented to the guest will be corrupt; similarly, presenting
+a raw image to a guest allows a potential security exploit if a future
+probe sees a non-raw image based on guest writes.
+
+To avoid the warning message, or even future refusal to create an
+unsafe image, you must pass ``-o backing_fmt=`` (or the shorthand
+``-F`` during create) to specify the intended backing format.  You may
+use ``qemu-img rebase -u`` to retroactively add a backing format to an
+existing image.  However, be aware that there are already potential
+security risks to blindly using ``qemu-img info`` to probe the format
+of an untrusted backing image, when deciding what format to add into
+an existing image.
+
 Backwards compatibility
 ---
 
diff --git a/block.c b/block.c
index 5cfd10f6b4..aad3b3635e 100644
--- a/block.c
+++ b/block.c
@@ -6161,6 +6161,26 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
 error_append_hint(_err, "Could not open backing image.\n");
 goto out;
 } else {
+if (!backing_fmt) {
+warn_report("Deprecated use of backing file without explicit "
+"backing format (detected format of %s)",
+bs->drv->format_name);
+if (bs->drv != _raw) {
+/*
+ * A probe of raw deserves the most attention:
+ * leaving the backing format out of the image
+ * will ensure bs->probed is set (ensuring we
+ * don't accidentally commit into the backing
+ * file), and allow more spots to warn the users
+ * to fix their toolchain when 

[PATCH v12 1/8] error: New macro ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Markus Armbruster
From: Vladimir Sementsov-Ogievskiy 

Introduce a new ERRP_AUTO_PROPAGATE macro, to be used at start of
functions with an errp OUT parameter.

It has three goals:

1. Fix issue with error_fatal and error_prepend/error_append_hint: user
can't see this additional information, because exit() happens in
error_setg earlier than information is added. [Reported by Greg Kurz]

2. Fix issue with error_abort and error_propagate: when we wrap
error_abort by local_err+error_propagate, the resulting coredump will
refer to error_propagate and not to the place where error happened.
(the macro itself doesn't fix the issue, but it allows us to [3.] drop
the local_err+error_propagate pattern, which will definitely fix the
issue) [Reported by Kevin Wolf]

3. Drop local_err+error_propagate pattern, which is used to workaround
void functions with errp parameter, when caller wants to know resulting
status. (Note: actually these functions could be merely updated to
return int error code).

To achieve these goals, later patches will add invocations
of this macro at the start of functions with either use
error_prepend/error_append_hint (solving 1) or which use
local_err+error_propagate to check errors, switching those
functions to use *errp instead (solving 2 and 3).

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Paul Durrant 
Reviewed-by: Greg Kurz 
Reviewed-by: Eric Blake 
[Comments merged properly with recent commit "error: Document Error
API usage rules", and edited for clarity.  Put ERRP_AUTO_PROPAGATE()
before its helpers, and touch up style.  Commit message tweaked.]
Signed-off-by: Markus Armbruster 
---
 include/qapi/error.h | 160 ++-
 1 file changed, 141 insertions(+), 19 deletions(-)

diff --git a/include/qapi/error.h b/include/qapi/error.h
index 3fed49747d..c865a7d2f1 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -30,6 +30,10 @@
  *   job.  Since the value of @errp is about handling the error, the
  *   function should not examine it.
  *
+ * - The function may pass @errp to functions it calls to pass on
+ *   their errors to its caller.  If it dereferences @errp to check
+ *   for errors, it must use ERRP_AUTO_PROPAGATE().
+ *
  * - On success, the function should not touch *errp.  On failure, it
  *   should set a new error, e.g. with error_setg(errp, ...), or
  *   propagate an existing one, e.g. with error_propagate(errp, ...).
@@ -45,15 +49,17 @@
  * = Creating errors =
  *
  * Create an error:
- * error_setg(, "situation normal, all fouled up");
+ * error_setg(errp, "situation normal, all fouled up");
+ * where @errp points to the location to receive the error.
  *
  * Create an error and add additional explanation:
- * error_setg(, "invalid quark");
- * error_append_hint(, "Valid quarks are up, down, strange, "
+ * error_setg(errp, "invalid quark");
+ * error_append_hint(errp, "Valid quarks are up, down, strange, "
  *   "charm, top, bottom.\n");
+ * This may require use of ERRP_AUTO_PROPAGATE(); more on that below.
  *
  * Do *not* contract this to
- * error_setg(, "invalid quark\n" // WRONG!
+ * error_setg(errp, "invalid quark\n" // WRONG!
  *"Valid quarks are up, down, strange, charm, top, bottom.");
  *
  * = Reporting and destroying errors =
@@ -107,18 +113,6 @@
  * Errors get passed to the caller through the conventional @errp
  * parameter.
  *
- * Pass an existing error to the caller:
- * error_propagate(errp, err);
- * where Error **errp is a parameter, by convention the last one.
- *
- * Pass an existing error to the caller with the message modified:
- * error_propagate_prepend(errp, err,
- * "Could not frobnicate '%s': ", name);
- * This is more concise than
- * error_propagate(errp, err); // don't do this
- * error_prepend(errp, "Could not frobnicate '%s': ", name);
- * and works even when @errp is _fatal.
- *
  * Create a new error and pass it to the caller:
  * error_setg(errp, "situation normal, all fouled up");
  *
@@ -128,18 +122,26 @@
  * handle the error...
  * }
  * when it doesn't, say a void function:
+ * ERRP_AUTO_PROPAGATE();
+ * foo(arg, errp);
+ * if (*errp) {
+ * handle the error...
+ * }
+ * More on ERRP_AUTO_PROPAGATE() below.
+ *
+ * Code predating ERRP_AUTO_PROPAGATE() still exits, and looks like this:
  * Error *err = NULL;
  * foo(arg, );
  * if (err) {
  * handle the error...
- * error_propagate(errp, err);
+ * error_propagate(errp, err); // deprecated
  * }
- * Do *not* "optimize" this to
+ * Avoid in new code.  Do *not* "optimize" it to
  * foo(arg, errp);
  * if (*errp) { // WRONG!
  * handle the error...
  * }
- * because errp may be NULL!
+ * because errp may be NULL!  Guard with ERRP_AUTO_PROPAGATE().
  *
  * But when all you do with the error is pass it on, please use
  * foo(arg, errp);
@@ 

[PATCH v12 3/8] sd: Use ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Markus Armbruster
From: Vladimir Sementsov-Ogievskiy 

If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
   _fatal, this means that we don't break error_abort
   (we'll abort on error_set, not on error_propagate)

This commit is generated by command

sed -n '/^SD (Secure Card)$/,/^$/{s/^F: //p}' \
MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Philippe Mathieu-Daudé 
[Commit message tweaked]
Signed-off-by: Markus Armbruster 
---
 hw/sd/sdhci-pci.c |  7 +++
 hw/sd/sdhci.c | 21 +
 hw/sd/ssi-sd.c| 10 +-
 3 files changed, 17 insertions(+), 21 deletions(-)

diff --git a/hw/sd/sdhci-pci.c b/hw/sd/sdhci-pci.c
index 4f5977d487..38ec572fc6 100644
--- a/hw/sd/sdhci-pci.c
+++ b/hw/sd/sdhci-pci.c
@@ -29,13 +29,12 @@ static Property sdhci_pci_properties[] = {
 
 static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 SDHCIState *s = PCI_SDHCI(dev);
-Error *local_err = NULL;
 
 sdhci_initfn(s);
-sdhci_common_realize(s, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+sdhci_common_realize(s, errp);
+if (*errp) {
 return;
 }
 
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index eb2be6529e..be1928784d 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1288,7 +1288,7 @@ static const MemoryRegionOps sdhci_mmio_ops = {
 
 static void sdhci_init_readonly_registers(SDHCIState *s, Error **errp)
 {
-Error *local_err = NULL;
+ERRP_AUTO_PROPAGATE();
 
 switch (s->sd_spec_version) {
 case 2 ... 3:
@@ -1299,9 +1299,8 @@ static void sdhci_init_readonly_registers(SDHCIState *s, 
Error **errp)
 }
 s->version = (SDHC_HCVER_VENDOR << 8) | (s->sd_spec_version - 1);
 
-sdhci_check_capareg(s, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+sdhci_check_capareg(s, errp);
+if (*errp) {
 return;
 }
 }
@@ -1332,11 +1331,10 @@ void sdhci_uninitfn(SDHCIState *s)
 
 void sdhci_common_realize(SDHCIState *s, Error **errp)
 {
-Error *local_err = NULL;
+ERRP_AUTO_PROPAGATE();
 
-sdhci_init_readonly_registers(s, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+sdhci_init_readonly_registers(s, errp);
+if (*errp) {
 return;
 }
 s->buf_maxsz = sdhci_get_fifolen(s);
@@ -1456,13 +1454,12 @@ static void sdhci_sysbus_finalize(Object *obj)
 
 static void sdhci_sysbus_realize(DeviceState *dev, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 SDHCIState *s = SYSBUS_SDHCI(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-Error *local_err = NULL;
 
-sdhci_common_realize(s, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+sdhci_common_realize(s, errp);
+if (*errp) {
 return;
 }
 
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 3717b2e721..adb7fa9c24 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -241,10 +241,10 @@ static const VMStateDescription vmstate_ssi_sd = {
 
 static void ssi_sd_realize(SSISlave *d, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 ssi_sd_state *s = SSI_SD(d);
 DeviceState *carddev;
 DriveInfo *dinfo;
-Error *err = NULL;
 
 qbus_create_inplace(>sdbus, sizeof(s->sdbus), TYPE_SD_BUS,
 DEVICE(d), "sd-bus");
@@ -255,23 +255,23 @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
 carddev = qdev_new(TYPE_SD_CARD);
 if (dinfo) {
 if (!qdev_prop_set_drive_err(carddev, "drive",
- blk_by_legacy_dinfo(dinfo), )) {
+ blk_by_legacy_dinfo(dinfo), errp)) {
 goto fail;
 }
 }
 
-if (!object_property_set_bool(OBJECT(carddev), "spi", true, )) {
+if (!object_property_set_bool(OBJECT(carddev), "spi", true, errp)) {
 goto fail;
 }
 
-if (!qdev_realize_and_unref(carddev, BUS(>sdbus), )) {
+if (!qdev_realize_and_unref(carddev, BUS(>sdbus), errp)) {
 goto fail;
 }
 
 return;
 
 fail:
-error_propagate_prepend(errp, err, "failed to init SD card: ");
+error_prepend(errp, "failed to init SD 

[PATCH v12 4/8] pflash: Use ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Markus Armbruster
From: Vladimir Sementsov-Ogievskiy 

If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
   _fatal, this means that we don't break error_abort
   (we'll abort on error_set, not on error_propagate)

This commit is generated by command

sed -n '/^Parallel NOR Flash devices$/,/^$/{s/^F: //p}' \
MAINTAINERS | \
xargs git ls-files | grep '\.[hc]$' | \
xargs spatch \
--sp-file scripts/coccinelle/auto-propagated-errp.cocci \
--macro-file scripts/cocci-macro-file.h \
--in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Philippe Mathieu-Daudé 
[Commit message tweaked]
Signed-off-by: Markus Armbruster 
---
 hw/block/pflash_cfi01.c | 7 +++
 hw/block/pflash_cfi02.c | 7 +++
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index cddc3a5a0c..859cfeae14 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -696,12 +696,12 @@ static const MemoryRegionOps pflash_cfi01_ops = {
 
 static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 PFlashCFI01 *pfl = PFLASH_CFI01(dev);
 uint64_t total_len;
 int ret;
 uint64_t blocks_per_device, sector_len_per_device, device_len;
 int num_devices;
-Error *local_err = NULL;
 
 if (pfl->sector_len == 0) {
 error_setg(errp, "attribute \"sector-length\" not specified or zero.");
@@ -735,9 +735,8 @@ static void pflash_cfi01_realize(DeviceState *dev, Error 
**errp)
 >mem, OBJECT(dev),
 _cfi01_ops,
 pfl,
-pfl->name, total_len, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+pfl->name, total_len, errp);
+if (*errp) {
 return;
 }
 
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index b40ce2335a..15035ee5ef 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -724,9 +724,9 @@ static const MemoryRegionOps pflash_cfi02_ops = {
 
 static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
 {
+ERRP_AUTO_PROPAGATE();
 PFlashCFI02 *pfl = PFLASH_CFI02(dev);
 int ret;
-Error *local_err = NULL;
 
 if (pfl->uniform_sector_len == 0 && pfl->sector_len[0] == 0) {
 error_setg(errp, "attribute \"sector-length\" not specified or zero.");
@@ -792,9 +792,8 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 
 memory_region_init_rom_device(>orig_mem, OBJECT(pfl),
   _cfi02_ops, pfl, pfl->name,
-  pfl->chip_len, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+  pfl->chip_len, errp);
+if (*errp) {
 return;
 }
 
-- 
2.26.2




Re: [PATCH v4 1/2] nvme: indicate CMB support through controller capabilities register

2020-07-07 Thread Maxim Levitsky
On Wed, 2020-07-01 at 14:48 -0700, Andrzej Jakowski wrote:
> This patch sets CMBS bit in controller capabilities register when user
> configures NVMe driver with CMB support, so capabilites are correctly
> reported to guest OS.
> 
> Signed-off-by: Andrzej Jakowski 
> Reviewed-by: Klaus Jensen 
> ---
>  hw/block/nvme.c  | 2 +-
>  include/block/nvme.h | 6 +-
>  2 files changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> index 1aee042d4c..9f11f3e9da 100644
> --- a/hw/block/nvme.c
> +++ b/hw/block/nvme.c
> @@ -1582,6 +1582,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice 
> *pci_dev)
>  NVME_CAP_SET_TO(n->bar.cap, 0xf);
>  NVME_CAP_SET_CSS(n->bar.cap, 1);
>  NVME_CAP_SET_MPSMAX(n->bar.cap, 4);
> +NVME_CAP_SET_CMBS(n->bar.cap, n->params.cmb_size_mb ? 1 : 0);
>  
>  n->bar.vs = 0x00010200;
>  n->bar.intmc = n->bar.intms = 0;
> @@ -1591,7 +1592,6 @@ static void nvme_realize(PCIDevice *pci_dev, Error 
> **errp)
>  {
>  NvmeCtrl *n = NVME(pci_dev);
>  Error *local_err = NULL;
> -
>  int i;
>  
>  nvme_check_constraints(n, _err);
> diff --git a/include/block/nvme.h b/include/block/nvme.h
> index 1720ee1d51..14cf398dfa 100644
> --- a/include/block/nvme.h
> +++ b/include/block/nvme.h
> @@ -35,6 +35,7 @@ enum NvmeCapShift {
>  CAP_MPSMIN_SHIFT   = 48,
>  CAP_MPSMAX_SHIFT   = 52,
>  CAP_PMR_SHIFT  = 56,
> +CAP_CMB_SHIFT  = 57,
>  };
>  
>  enum NvmeCapMask {
> @@ -48,6 +49,7 @@ enum NvmeCapMask {
>  CAP_MPSMIN_MASK= 0xf,
>  CAP_MPSMAX_MASK= 0xf,
>  CAP_PMR_MASK   = 0x1,
> +CAP_CMB_MASK   = 0x1,
>  };
>  
>  #define NVME_CAP_MQES(cap)  (((cap) >> CAP_MQES_SHIFT)   & CAP_MQES_MASK)
> @@ -78,8 +80,10 @@ enum NvmeCapMask {
> << 
> CAP_MPSMIN_SHIFT)
>  #define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & 
> CAP_MPSMAX_MASK)\
>  << 
> CAP_MPSMAX_SHIFT)
> -#define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMR_MASK)\
> +#define NVME_CAP_SET_PMRS(cap, val)   (cap |= (uint64_t)(val & CAP_PMR_MASK) 
>   \
>  << CAP_PMR_SHIFT)
> +#define NVME_CAP_SET_CMBS(cap, val)   (cap |= (uint64_t)(val & CAP_CMB_MASK) 
>   \
> +   << CAP_CMB_SHIFT)
>  
>  enum NvmeCcShift {
>  CC_EN_SHIFT = 0,


I wonder how this could have beeing forgotten. Hmm.
I see that Linux kernel uses CMBSZ != for that.
I guess this explains it.

Reviewed-by: Maxim Levitsky 

Best regards,
Maxim Levitsky





[PULL 09/12] qcow2: Deprecate use of qemu-img amend to change backing file

2020-07-07 Thread Kevin Wolf
From: Eric Blake 

The use of 'qemu-img amend' to change qcow2 backing files is not
tested very well.  In particular, our implementation has a bug where
if a new backing file is provided without a format, then the prior
format is blindly reused, even if this results in data corruption, but
this is not caught by iotests.

There are also situations where amending other options needs access to
the original backing file (for example, on a downgrade to a v2 image,
knowing whether a v3 zero cluster must be allocated or may be left
unallocated depends on knowing whether the backing file already reads
as zero), but the command line does not have a nice way to tell us
both the backing file to use for opening the image as well as the
backing file to install after the operation is complete.

Even if we do allow changing the backing file, it is redundant with
the existing ability to change backing files via 'qemu-img rebase -u'.
It is time to deprecate this support (leaving the existing behavior
intact, even if it is buggy), and at a point in the future, require
the use of only 'qemu-img rebase' for adjusting backing chain
relations, saving 'qemu-img amend' for changes unrelated to the
backing chain.

Signed-off-by: Eric Blake 
Message-Id: <20200706203954.341758-8-ebl...@redhat.com>
Signed-off-by: Kevin Wolf 
---
 docs/system/deprecated.rst | 12 
 docs/tools/qemu-img.rst|  4 
 block/qcow2.c  |  5 +
 tests/qemu-iotests/061.out |  1 +
 tests/qemu-iotests/082.out |  2 ++
 5 files changed, 24 insertions(+)

diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
index 6fbec34b8b..b312ad27aa 100644
--- a/docs/system/deprecated.rst
+++ b/docs/system/deprecated.rst
@@ -418,6 +418,18 @@ kernel in 2018, and has also been dropped from glibc.
 Related binaries
 
 
+qemu-img amend to adjust backing file (since 5.1)
+'
+
+The use of ``qemu-img amend`` to modify the name or format of a qcow2
+backing image is deprecated; this functionality was never fully
+documented or tested, and interferes with other amend operations that
+need access to the original backing image (such as deciding whether a
+v3 zero cluster may be left unallocated when converting to a v2
+image).  Rather, any changes to the backing chain should be performed
+with ``qemu-img rebase -u`` either before or after the remaining
+changes being performed by amend, as appropriate.
+
 Backwards compatibility
 ---
 
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
index 7f0737488a..fa53e30697 100644
--- a/docs/tools/qemu-img.rst
+++ b/docs/tools/qemu-img.rst
@@ -258,6 +258,10 @@ Command description:
   Amends the image format specific *OPTIONS* for the image file
   *FILENAME*. Not all file formats support this operation.
 
+  The set of options that can be amended are dependent on the image
+  format, but note that amending the backing chain relationship should
+  instead be performed with ``qemu-img rebase``.
+
 .. option:: bench [-c COUNT] [-d DEPTH] [-f FMT] 
[--flush-interval=FLUSH_INTERVAL] [-i AIO] [-n] [--no-drain] [-o OFFSET] 
[--pattern=PATTERN] [-q] [-s BUFFER_SIZE] [-S STEP_SIZE] [-t CACHE] [-w] [-U] 
FILENAME
 
   Run a simple sequential I/O benchmark on the specified image. If ``-w`` is
diff --git a/block/qcow2.c b/block/qcow2.c
index 0cd2e6757e..99aedb8eed 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -5523,6 +5523,11 @@ static int qcow2_amend_options(BlockDriverState *bs, 
QemuOpts *opts,
 }
 
 if (backing_file || backing_format) {
+if (g_strcmp0(backing_file, s->image_backing_file) ||
+g_strcmp0(backing_format, s->image_backing_format)) {
+warn_report("Deprecated use of amend to alter the backing file; "
+"use qemu-img rebase instead");
+}
 ret = qcow2_change_backing_file(bs,
 backing_file ?: s->image_backing_file,
 backing_format ?: s->image_backing_format);
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
index 2f03cf045c..c549b139da 100644
--- a/tests/qemu-iotests/061.out
+++ b/tests/qemu-iotests/061.out
@@ -370,6 +370,7 @@ wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 read 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-img: warning: Deprecated use of amend to alter the backing file; use 
qemu-img rebase instead
 read 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 No errors were found on the image.
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
index a65e185179..e878572a0d 100644
--- a/tests/qemu-iotests/082.out
+++ b/tests/qemu-iotests/082.out
@@ -855,10 +855,12 @@ Creation options for 'qcow2':
 Note that not all of these options may be amendable.
 
 Testing: amend -f qcow2 -o 

[PULL 05/12] sheepdog: Add trivial backing_fmt support

2020-07-07 Thread Kevin Wolf
From: Eric Blake 

Sheepdog already requires that if backing_file is present, that it be
another sheepdog image (see sd_co_create).  Meanwhile, we want to move
towards always being explicit about the backing format for other
drivers where it matters.  So for convenience, make qemu-img create -F
sheepdog work, while rejecting all other explicit formats (note that
this is only for QemuOpts usage; there is no change to the QAPI to
allow a format through -blockdev).

Signed-off-by: Eric Blake 
Message-Id: <20200706203954.341758-4-ebl...@redhat.com>
Signed-off-by: Kevin Wolf 
---
 block/sheepdog.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 27a30d17f4..548ce54cbc 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -2157,13 +2157,21 @@ static int coroutine_fn sd_co_create_opts(BlockDriver 
*drv,
   Error **errp)
 {
 BlockdevCreateOptions *create_options = NULL;
-QDict *qdict, *location_qdict;
+QDict *qdict = NULL, *location_qdict;
 Visitor *v;
-char *redundancy;
+char *redundancy = NULL;
 Error *local_err = NULL;
 int ret;
+char *backing_fmt = NULL;
 
 redundancy = qemu_opt_get_del(opts, BLOCK_OPT_REDUNDANCY);
+backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
+
+if (backing_fmt && strcmp(backing_fmt, "sheepdog") != 0) {
+error_setg(errp, "backing_file must be a sheepdog image");
+ret = -EINVAL;
+goto fail;
+}
 
 qdict = qemu_opts_to_qdict(opts, NULL);
 qdict_put_str(qdict, "driver", "sheepdog");
@@ -2228,6 +2236,7 @@ fail:
 qapi_free_BlockdevCreateOptions(create_options);
 qobject_unref(qdict);
 g_free(redundancy);
+g_free(backing_fmt);
 return ret;
 }
 
@@ -3185,6 +3194,11 @@ static QemuOptsList sd_create_opts = {
 .type = QEMU_OPT_STRING,
 .help = "File name of a base image"
 },
+{
+.name = BLOCK_OPT_BACKING_FMT,
+.type = QEMU_OPT_STRING,
+.help = "Must be 'sheepdog' if present",
+},
 {
 .name = BLOCK_OPT_PREALLOC,
 .type = QEMU_OPT_STRING,
-- 
2.25.4




[PULL 07/12] qcow: Tolerate backing_fmt=

2020-07-07 Thread Kevin Wolf
From: Eric Blake 

qcow has no space in the metadata to store a backing format, and there
are existing qcow images backed both by raw or by other formats
(usually qcow) images, reliant on probing to tell the difference.  On
the bright side, because we probe every time, raw files are marked as
probed and we thus forbid a commit action into the backing file where
guest-controlled contents could change the result of the probe next
time around (the iotest added here proves that).

Still, allowing the user to specify the backing format during
creation, even if we can't record it, is a good thing.  This patch
blindly allows any value that resolves to a known driver, even if the
user's request is a mismatch from what probing finds; then the next
patch will further enhance things to verify that the user's request
matches what we actually probe.  With this and the next patch in
place, we will finally be ready to deprecate the creation of images
where a backing format was not explicitly specified by the user.

Note that this is only for QemuOpts usage; there is no change to the
QAPI to allow a format through -blockdev.

Add a new iotest 293 just for qcow, to demonstrate the latest
behavior, and to make it easier to show the improvements made in the
next patch.

Signed-off-by: Eric Blake 
Message-Id: <20200706203954.341758-6-ebl...@redhat.com>
Signed-off-by: Kevin Wolf 
---
 block/qcow.c   | 20 -
 tests/qemu-iotests/293 | 88 ++
 tests/qemu-iotests/293.out | 60 ++
 tests/qemu-iotests/group   |  1 +
 4 files changed, 168 insertions(+), 1 deletion(-)
 create mode 100755 tests/qemu-iotests/293
 create mode 100644 tests/qemu-iotests/293.out

diff --git a/block/qcow.c b/block/qcow.c
index ee5d35fe20..e91aa2d8c4 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -940,11 +940,12 @@ static int coroutine_fn qcow_co_create_opts(BlockDriver 
*drv,
 {
 BlockdevCreateOptions *create_options = NULL;
 BlockDriverState *bs = NULL;
-QDict *qdict;
+QDict *qdict = NULL;
 Visitor *v;
 const char *val;
 Error *local_err = NULL;
 int ret;
+char *backing_fmt;
 
 static const QDictRenames opt_renames[] = {
 { BLOCK_OPT_BACKING_FILE,   "backing-file" },
@@ -952,6 +953,17 @@ static int coroutine_fn qcow_co_create_opts(BlockDriver 
*drv,
 { NULL, NULL },
 };
 
+/*
+ * We can't actually store a backing format, but can check that
+ * the user's request made sense.
+ */
+backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
+if (backing_fmt && !bdrv_find_format(backing_fmt)) {
+error_setg(errp, "unrecognized backing format '%s'", backing_fmt);
+ret = -EINVAL;
+goto fail;
+}
+
 /* Parse options and convert legacy syntax */
 qdict = qemu_opts_to_qdict_filtered(opts, NULL, _create_opts, true);
 
@@ -1018,6 +1030,7 @@ static int coroutine_fn qcow_co_create_opts(BlockDriver 
*drv,
 
 ret = 0;
 fail:
+g_free(backing_fmt);
 qobject_unref(qdict);
 bdrv_unref(bs);
 qapi_free_BlockdevCreateOptions(create_options);
@@ -1152,6 +1165,11 @@ static QemuOptsList qcow_create_opts = {
 .type = QEMU_OPT_STRING,
 .help = "File name of a base image"
 },
+{
+.name = BLOCK_OPT_BACKING_FMT,
+.type = QEMU_OPT_STRING,
+.help = "Format of the backing image",
+},
 {
 .name = BLOCK_OPT_ENCRYPT,
 .type = QEMU_OPT_BOOL,
diff --git a/tests/qemu-iotests/293 b/tests/qemu-iotests/293
new file mode 100755
index 00..3823e95617
--- /dev/null
+++ b/tests/qemu-iotests/293
@@ -0,0 +1,88 @@
+#!/usr/bin/env bash
+#
+# Test qcow backing file warnings
+#
+# Copyright (C) 2020 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+status=1 # failure is the default!
+
+_cleanup()
+{
+_cleanup_test_img
+_rm_test_img "$TEST_IMG.qcow2"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow
+_supported_proto file
+_supported_os Linux
+
+size=32M
+
+echo
+echo "== qcow backed by qcow =="
+
+TEST_IMG="$TEST_IMG.base" _make_test_img $size
+_make_test_img -b "$TEST_IMG.base" $size
+_img_info

[PULL 06/12] vmdk: Add trivial backing_fmt support

2020-07-07 Thread Kevin Wolf
From: Eric Blake 

vmdk already requires that if backing_file is present, that it be
another vmdk image (see vmdk_co_do_create).  Meanwhile, we want to
move towards always being explicit about the backing format for other
drivers where it matters.  So for convenience, make qemu-img create -F
vmdk work, while rejecting all other explicit formats (note that this
is only for QemuOpts usage; there is no change to the QAPI to allow a
format through -blockdev).

Signed-off-by: Eric Blake 
Message-Id: <20200706203954.341758-5-ebl...@redhat.com>
Signed-off-by: Kevin Wolf 
---
 block/vmdk.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/block/vmdk.c b/block/vmdk.c
index 62da465126..6c58e5ec2e 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -2638,6 +2638,14 @@ static int coroutine_fn vmdk_co_create_opts(BlockDriver 
*drv,
 bool zeroed_grain;
 bool compat6;
 VMDKCreateOptsData data;
+char *backing_fmt = NULL;
+
+backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
+if (backing_fmt && strcmp(backing_fmt, "vmdk") != 0) {
+error_setg(errp, "backing_file must be a vmdk image");
+ret = -EINVAL;
+goto exit;
+}
 
 if (filename_decompose(filename, path, prefix, postfix, PATH_MAX, errp)) {
 ret = -EINVAL;
@@ -2696,6 +2704,7 @@ static int coroutine_fn vmdk_co_create_opts(BlockDriver 
*drv,
 vmdk_co_create_opts_cb, , errp);
 
 exit:
+g_free(backing_fmt);
 g_free(adapter_type);
 g_free(backing_file);
 g_free(hw_version);
@@ -3031,6 +3040,11 @@ static QemuOptsList vmdk_create_opts = {
 .type = QEMU_OPT_STRING,
 .help = "File name of a base image"
 },
+{
+.name = BLOCK_OPT_BACKING_FMT,
+.type = QEMU_OPT_STRING,
+.help = "Must be 'vmdk' if present",
+},
 {
 .name = BLOCK_OPT_COMPAT6,
 .type = QEMU_OPT_BOOL,
-- 
2.25.4




[PATCH v4 43/45] qemu-img: Ignore Error objects where the return value suffices

2020-07-07 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 qemu-img.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index fc405ee171..a6af0eaf80 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -464,22 +464,18 @@ static int add_old_style_options(const char *fmt, 
QemuOpts *opts,
  const char *base_filename,
  const char *base_fmt)
 {
-Error *err = NULL;
-
 if (base_filename) {
 if (!qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename,
-  )) {
+  NULL)) {
 error_report("Backing file not supported for file format '%s'",
  fmt);
-error_free(err);
 return -1;
 }
 }
 if (base_fmt) {
-if (!qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt, )) {
+if (!qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt, NULL)) {
 error_report("Backing file format not supported for file "
  "format '%s'", fmt);
-error_free(err);
 return -1;
 }
 }
-- 
2.26.2




[PULL 00/12] Block layer patches

2020-07-07 Thread Kevin Wolf
The following changes since commit 7623b5ba017f61de5d7c2bba12c6feb3d55091b1:

  Merge remote-tracking branch 
'remotes/vivier2/tags/linux-user-for-5.1-pull-request' into staging (2020-07-06 
11:40:10 +0100)

are available in the Git repository at:

  git://repo.or.cz/qemu/kevin.git tags/for-upstream

for you to fetch changes up to 7bf114070834e1b0c947b7c2a1c96cb734eb6b86:

  qemu-img: Deprecate use of -b without -F (2020-07-07 18:18:06 +0200)


Block layer patches:

- file-posix: Mitigate file fragmentation with extent size hints
- Tighten qemu-img rules on missing backing format
- qemu-img map: Don't limit block status request size


Eric Blake (10):
  qemu-img: Flush stdout before before potential stderr messages
  block: Finish deprecation of 'qemu-img convert -n -o'
  sheepdog: Add trivial backing_fmt support
  vmdk: Add trivial backing_fmt support
  qcow: Tolerate backing_fmt=
  block: Error if backing file fails during creation without -u
  qcow2: Deprecate use of qemu-img amend to change backing file
  iotests: Specify explicit backing format where sensible
  block: Add support to warn on backing file change without format
  qemu-img: Deprecate use of -b without -F

Kevin Wolf (2):
  qemu-img map: Don't limit block status request size
  file-posix: Mitigate file fragmentation with extent size hints

 qapi/block-core.json  | 11 --
 docs/system/deprecated.rst| 58 
 docs/tools/qemu-img.rst   |  4 ++
 include/block/block.h |  4 +-
 include/block/block_int.h |  1 +
 block.c   | 53 +++---
 block/file-posix.c| 42 +
 block/qcow.c  | 20 +-
 block/qcow2.c |  7 +++-
 block/sheepdog.c  | 18 -
 block/stream.c|  2 +-
 block/vmdk.c  | 14 +++
 blockdev.c|  3 +-
 qemu-img.c| 20 ++
 tests/qemu-iotests/017|  2 +-
 tests/qemu-iotests/017.out|  2 +-
 tests/qemu-iotests/018|  2 +-
 tests/qemu-iotests/018.out|  2 +-
 tests/qemu-iotests/019|  5 ++-
 tests/qemu-iotests/019.out|  2 +-
 tests/qemu-iotests/020|  4 +-
 tests/qemu-iotests/020.out|  4 +-
 tests/qemu-iotests/024|  8 ++--
 tests/qemu-iotests/024.out|  5 ++-
 tests/qemu-iotests/028|  4 +-
 tests/qemu-iotests/028.out|  2 +-
 tests/qemu-iotests/030| 26 +
 tests/qemu-iotests/034|  2 +-
 tests/qemu-iotests/034.out|  2 +-
 tests/qemu-iotests/037|  2 +-
 tests/qemu-iotests/037.out|  2 +-
 tests/qemu-iotests/038|  2 +-
 tests/qemu-iotests/038.out|  2 +-
 tests/qemu-iotests/039|  3 +-
 tests/qemu-iotests/039.out|  2 +-
 tests/qemu-iotests/040| 47 ---
 tests/qemu-iotests/041| 37 --
 tests/qemu-iotests/042|  4 +-
 tests/qemu-iotests/043| 18 -
 tests/qemu-iotests/043.out| 16 +---
 tests/qemu-iotests/046|  2 +-
 tests/qemu-iotests/046.out|  2 +-
 tests/qemu-iotests/049.out|  8 ++--
 tests/qemu-iotests/050|  4 +-
 tests/qemu-iotests/050.out|  2 +-
 tests/qemu-iotests/051|  2 +-
 tests/qemu-iotests/051.out|  2 +-
 tests/qemu-iotests/051.pc.out |  2 +-
 tests/qemu-iotests/054.out|  2 +-
 tests/qemu-iotests/056|  3 +-
 tests/qemu-iotests/060|  2 +-
 tests/qemu-iotests/060.out|  2 +-
 tests/qemu-iotests/061| 10 ++---
 tests/qemu-iotests/061.out| 11 +++---
 tests/qemu-iotests/069|  2 +-
 tests/qemu-iotests/069.out|  2 +-
 tests/qemu-iotests/073|  2 +-
 tests/qemu-iotests/073.out|  2 +-
 tests/qemu-iotests/079.out|  2 +-
 tests/qemu-iotests/082| 10 +++--
 tests/qemu-iotests/082.out| 30 ---
 tests/qemu-iotests/085|  4 +-
 tests/qemu-iotests/085.out|  6 +--
 tests/qemu-iotests/089|  2 +-
 tests/qemu-iotests/089.out|  2 +-
 tests/qemu-iotests/095|  4 +-
 tests/qemu-iotests/095.out|  4 +-
 tests/qemu-iotests/097|  4 +-
 tests/qemu-iotests/097.out| 16 
 tests/qemu-iotests/098|  2 +-
 tests/qemu-iotests/098.out|  8 ++--
 tests/qemu-iotests/110|  4 +-
 tests/qemu-iotests/110.out|  4 +-
 tests/qemu-iotests/111.out|  2 +-
 tests/qemu-iotests/112.out|  4 +-
 tests/qemu-iotests/114| 12 ++
 tests/qemu-iotests/114.out|  9 +
 tests/qemu-iotests/122| 34 +++--
 tests/qemu-iotests/122.out| 12 --
 tests/qemu-iotests/126|  4 +-
 tests/qemu-iotests/126.out|  4 +-
 tests/qemu-iotests/127|  4 +-
 tests/qemu-iotests/127.out|  4 +-
 tests/qemu-iotests/129

[PATCH v4 25/45] qom: Use return values to check for error where that's simpler

2020-07-07 Thread Markus Armbruster
When using the Error object to check for error, we need to receive it
into a local variable, then propagate() it to @errp.

Using the return value permits allows receiving it straight to @errp.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 qom/object.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/qom/object.c b/qom/object.c
index 0808da2767..3a7c062f8e 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -549,8 +549,7 @@ void object_initialize_child_with_propsv(Object *parentobj,
 object_initialize(childobj, size, type);
 obj = OBJECT(childobj);
 
-object_set_propv(obj, _err, vargs);
-if (local_err) {
+if (object_set_propv(obj, errp, vargs) < 0) {
 goto out;
 }
 
@@ -743,7 +742,7 @@ Object *object_new_with_propv(const char *typename,
 }
 obj = object_new_with_type(klass->type);
 
-if (object_set_propv(obj, _err, vargs) < 0) {
+if (object_set_propv(obj, errp, vargs) < 0) {
 goto error;
 }
 
@@ -1763,20 +1762,24 @@ static void object_set_link_property(Object *obj, 
Visitor *v,
 LinkProperty *prop = opaque;
 Object **targetp = object_link_get_targetp(obj, prop);
 Object *old_target = *targetp;
-Object *new_target = NULL;
+Object *new_target;
 char *path = NULL;
 
-visit_type_str(v, name, , _err);
+if (!visit_type_str(v, name, , errp)) {
+return;
+}
 
-if (!local_err && strcmp(path, "") != 0) {
-new_target = object_resolve_link(obj, name, path, _err);
+if (*path) {
+new_target = object_resolve_link(obj, name, path, errp);
+if (!new_target) {
+g_free(path);
+return;
+}
+} else {
+new_target = NULL;
 }
 
 g_free(path);
-if (local_err) {
-error_propagate(errp, local_err);
-return;
-}
 
 prop->check(obj, name, new_target, _err);
 if (local_err) {
-- 
2.26.2




Re: [PATCH 1/2] tests/acceptance/boot_linux: Truncate SD card image to power of 2

2020-07-07 Thread Philippe Mathieu-Daudé
On 7/7/20 5:53 PM, Alistair Francis wrote:
> n Tue, Jul 7, 2020 at 6:21 AM Philippe Mathieu-Daudé  wrote:
>>
>> In the next commit we won't allow SD card images with invalid
>> size (not aligned to a power of 2). Prepare the tests: add the
>> pow2ceil() and image_pow2ceil_truncate() methods and truncate
>> the images of the tests using SD cards.
>>
>> Signed-off-by: Philippe Mathieu-Daudé 
>> ---
>>  tests/acceptance/boot_linux_console.py | 15 +++
>>  1 file changed, 15 insertions(+)
>>
>> diff --git a/tests/acceptance/boot_linux_console.py 
>> b/tests/acceptance/boot_linux_console.py
>> index 3d02519660..f4d4e3635f 100644
>> --- a/tests/acceptance/boot_linux_console.py
>> +++ b/tests/acceptance/boot_linux_console.py
>> @@ -28,6 +28,18 @@
>>  except CmdNotFoundError:
>>  P7ZIP_AVAILABLE = False
>>
>> +# round up to next power of 2
>> +def pow2ceil(x):
>> +return 1 if x == 0 else 2**(x - 1).bit_length()
>> +
>> +# truncate file size to next power of 2
>> +def image_pow2ceil_truncate(path):
>> +size = os.path.getsize(path)
>> +size_aligned = pow2ceil(size)
>> +if size != size_aligned:
>> +with open(path, 'ab+') as fd:
>> +fd.truncate(size_aligned)
> 
> Why truncate the image, can't we expand it instead?

pow2ceil() round UP to the next power of 2. I think this
Python truncate() is a simple wrapper around the ftruncate()
syscall. IOW we only "expand the image". Note, these are
test images copied in tmpdir and discarded after the tests
ran. I'll improve the description.

> 
> Alistair
> 
>> +
>>  class LinuxKernelTest(Test):
>>  KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
>>
>> @@ -635,6 +647,7 @@ def test_arm_orangepi_sd(self):
>>  rootfs_path_xz = self.fetch_asset(rootfs_url, 
>> asset_hash=rootfs_hash)
>>  rootfs_path = os.path.join(self.workdir, 'rootfs.cpio')
>>  archive.lzma_uncompress(rootfs_path_xz, rootfs_path)
>> +image_pow2ceil_truncate(rootfs_path)
>>
>>  self.vm.set_console()
>>  kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
>> @@ -679,6 +692,7 @@ def test_arm_orangepi_bionic(self):
>>  image_name = 'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.img'
>>  image_path = os.path.join(self.workdir, image_name)
>>  process.run("7z e -o%s %s" % (self.workdir, image_path_7z))
>> +image_pow2ceil_truncate(image_path)
>>
>>  self.vm.set_console()
>>  self.vm.add_args('-drive', 'file=' + image_path + 
>> ',if=sd,format=raw',
>> @@ -728,6 +742,7 @@ def test_arm_orangepi_uboot_netbsd9(self):
>>  image_hash = '2babb29d36d8360adcb39c09e31060945259917a'
>>  image_path_gz = self.fetch_asset(image_url, asset_hash=image_hash)
>>  image_path = os.path.join(self.workdir, 'armv7.img')
>> +image_pow2ceil_truncate(image_path)
>>  image_drive_args = 'if=sd,format=raw,snapshot=on,file=' + image_path
>>  archive.gzip_uncompress(image_path_gz, image_path)
>>
>> --
>> 2.21.3
>>
>>
> 



Re: [PATCH 2/5] block/io: introduce bdrv_co_range_try_lock

2020-07-07 Thread Stefan Hajnoczi
On Sat, Jun 20, 2020 at 05:36:46PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> @@ -83,6 +84,12 @@ typedef struct BdrvTrackedRequest {
>  CoQueue wait_queue; /* coroutines blocked on this request */
>  
>  struct BdrvTrackedRequest *waiting_for;
> +
> +/*
> + * If non-zero, the request is under lock, so it's allowed to intersect
> + * (actully it must be inside) the @lock request.

s/actully/actually/

> @@ -745,15 +747,26 @@ static bool coroutine_fn 
> wait_or_find_conflicts(BdrvTrackedRequest *self,
>  if (tracked_request_overlaps(req, self->overlap_offset,
>   self->overlap_bytes))
>  {
> -/* Hitting this means there was a reentrant request, for
> - * example, a block driver issuing nested requests.  This 
> must
> - * never happen since it means deadlock.
> +if (self->lock == req) {
> +/* This is atomic request under range_lock */
> +assert(req->type == BDRV_TRACKED_LOCK);
> +assert(self->offset >= req->offset);
> +assert(self->bytes <= req->bytes);

These assertions do not catch requests that start within the locked
region but span beyond the end of the region. How about:

  assert(self->offset + self->bytes - req->offset >= req->bytes);

> +int coroutine_fn bdrv_co_pwrite_zeroes_locked(BdrvChild *child, int64_t 
> offset,
> +  int bytes, BdrvRequestFlags 
> flags,
> +  BdrvTrackedRequest *lock)

The name is confusing because _locked() normally means that a mutex
should be held. Functions using that naming convention already exist in
block/io.c. It would be nice to distinguish between functions that need
BdrvTrackedRequest and functions that must be called with a mutex held.

How about bdrv_co_pwrite_zeroes_with_lock()?


signature.asc
Description: PGP signature


[PATCH v4 02/45] error: Improve error.h's big comment

2020-07-07 Thread Markus Armbruster
Add headlines to the big comment.

Explain examples for NULL, _abort and _fatal argument
better.

Tweak rationale for error_propagate_prepend().

Signed-off-by: Markus Armbruster 
---
 include/qapi/error.h | 51 +++-
 1 file changed, 36 insertions(+), 15 deletions(-)

diff --git a/include/qapi/error.h b/include/qapi/error.h
index e8960eaad5..6d079c58b7 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -15,6 +15,8 @@
 /*
  * Error reporting system loosely patterned after Glib's GError.
  *
+ * = Creating errors =
+ *
  * Create an error:
  * error_setg(, "situation normal, all fouled up");
  *
@@ -27,6 +29,8 @@
  * error_setg(, "invalid quark\n" // WRONG!
  *"Valid quarks are up, down, strange, charm, top, bottom.");
  *
+ * = Reporting and destroying errors =
+ *
  * Report an error to the current monitor if we have one, else stderr:
  * error_report_err(err);
  * This frees the error object.
@@ -40,6 +44,30 @@
  * error_free(err);
  * Note that this loses hints added with error_append_hint().
  *
+ * Call a function ignoring errors:
+ * foo(arg, NULL);
+ * This is more concise than
+ * Error *err = NULL;
+ * foo(arg, );
+ * error_free(err); // don't do this
+ *
+ * Call a function aborting on errors:
+ * foo(arg, _abort);
+ * This is more concise and fails more nicely than
+ * Error *err = NULL;
+ * foo(arg, );
+ * assert(!err); // don't do this
+ *
+ * Call a function treating errors as fatal:
+ * foo(arg, _fatal);
+ * This is more concise than
+ * Error *err = NULL;
+ * foo(arg, );
+ * if (err) { // don't do this
+ * error_report_err(err);
+ * exit(1);
+ * }
+ *
  * Handle an error without reporting it (just for completeness):
  * error_free(err);
  *
@@ -47,6 +75,11 @@
  * reporting it (primarily useful in testsuites):
  * error_free_or_abort();
  *
+ * = Passing errors around =
+ *
+ * Errors get passed to the caller through the conventional @errp
+ * parameter.
+ *
  * Pass an existing error to the caller:
  * error_propagate(errp, err);
  * where Error **errp is a parameter, by convention the last one.
@@ -54,11 +87,10 @@
  * Pass an existing error to the caller with the message modified:
  * error_propagate_prepend(errp, err,
  * "Could not frobnicate '%s': ", name);
- *
- * Avoid
- * error_propagate(errp, err);
+ * This is more concise than
+ * error_propagate(errp, err); // don't do this
  * error_prepend(errp, "Could not frobnicate '%s': ", name);
- * because this fails to prepend when @errp is _fatal.
+ * and works even when @errp is _fatal.
  *
  * Create a new error and pass it to the caller:
  * error_setg(errp, "situation normal, all fouled up");
@@ -70,15 +102,6 @@
  * handle the error...
  * }
  *
- * Call a function ignoring errors:
- * foo(arg, NULL);
- *
- * Call a function aborting on errors:
- * foo(arg, _abort);
- *
- * Call a function treating errors as fatal:
- * foo(arg, _fatal);
- *
  * Receive an error and pass it on to the caller:
  * Error *err = NULL;
  * foo(arg, );
@@ -86,8 +109,6 @@
  * handle the error...
  * error_propagate(errp, err);
  * }
- * where Error **errp is a parameter, by convention the last one.
- *
  * Do *not* "optimize" this to
  * foo(arg, errp);
  * if (*errp) { // WRONG!
-- 
2.26.2




[PULL 08/12] block: Error if backing file fails during creation without -u

2020-07-07 Thread Kevin Wolf
From: Eric Blake 

Back in commit 6e6e55f5 (Jul 2017, v2.10), we tweaked the code to warn
if the backing file could not be opened but the user gave a size,
unless the user also passes the -u option to bypass the open of the
backing file.  As one common reason for failure to open the backing
file is when there is mismatch in the requested backing format in
relation to what the backing file actually contains, we actually want
to open the backing file and ensure that it has the right format in as
many cases as possible.  iotest 293 for qcow demonstrates how
detecting explicit format mismatch is useful to prevent the creation
of an image that would probe differently than the user requested.  Now
is the time to finally turn the warning an error, as promised.

Note that the original warning was added prior to our documentation of
an official deprecation policy (eb22aeca, also Jul 2017), and because
the warning didn't mention the word "deprecated", we never actually
remembered to document it as such.  But the warning has been around
long enough that I don't see prolonging it another two releases.

Signed-off-by: Eric Blake 
Message-Id: <20200706203954.341758-7-ebl...@redhat.com>
Signed-off-by: Kevin Wolf 
---
 docs/system/deprecated.rst | 12 
 block.c| 12 ++--
 tests/qemu-iotests/111.out |  2 +-
 tests/qemu-iotests/293.out | 13 +
 4 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
index 73b9d9f378..6fbec34b8b 100644
--- a/docs/system/deprecated.rst
+++ b/docs/system/deprecated.rst
@@ -546,6 +546,18 @@ can be rewritten as::
 All options specified in ``-o`` are image creation options, so
 they are now rejected when used with ``-n`` to skip image creation.
 
+
+``qemu-img create -b bad file $size`` (removed in 5.1)
+''
+
+When creating an image with a backing file that could not be opened,
+``qemu-img create`` used to issue a warning about the failure but
+proceed with the image creation if an explicit size was provided.
+However, as the ``-u`` option exists for this purpose, it is safer to
+enforce that any failure to open the backing image (including if the
+backing file is missing or an incorrect format was specified) is an
+error when ``-u`` is not used.
+
 Command line options
 
 
diff --git a/block.c b/block.c
index a568196ba2..983b9bd29a 100644
--- a/block.c
+++ b/block.c
@@ -6150,16 +6150,8 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
 bs = bdrv_open(full_backing, NULL, backing_options, back_flags,
_err);
 g_free(full_backing);
-if (!bs && size != -1) {
-/* Couldn't open BS, but we have a size, so it's nonfatal */
-warn_reportf_err(local_err,
-"Could not verify backing image. "
-"This may become an error in future versions.\n");
-local_err = NULL;
-} else if (!bs) {
-/* Couldn't open bs, do not have size */
-error_append_hint(_err,
-  "Could not open backing image to determine 
size.\n");
+if (!bs) {
+error_append_hint(_err, "Could not open backing image.\n");
 goto out;
 } else {
 if (size == -1) {
diff --git a/tests/qemu-iotests/111.out b/tests/qemu-iotests/111.out
index 5279c462fc..ba034e5c58 100644
--- a/tests/qemu-iotests/111.out
+++ b/tests/qemu-iotests/111.out
@@ -1,4 +1,4 @@
 QA output created by 111
 qemu-img: TEST_DIR/t.IMGFMT: Could not open 'TEST_DIR/t.IMGFMT.inexistent': No 
such file or directory
-Could not open backing image to determine size.
+Could not open backing image.
 *** done
diff --git a/tests/qemu-iotests/293.out b/tests/qemu-iotests/293.out
index d07918b6d7..3c612903f8 100644
--- a/tests/qemu-iotests/293.out
+++ b/tests/qemu-iotests/293.out
@@ -17,18 +17,15 @@ backing file: TEST_DIR/t.IMGFMT.base
 
 == mismatched command line detection ==
 qemu-img: TEST_DIR/t.IMGFMT: invalid VMDK image descriptor
-Could not open backing image to determine size.
-qemu-img: warning: Could not verify backing image. This may become an error in 
future versions.
-invalid VMDK image descriptor
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 
backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=vmdk
+Could not open backing image.
+qemu-img: TEST_DIR/t.IMGFMT: invalid VMDK image descriptor
+Could not open backing image.
 
 qemu-img: TEST_DIR/t.IMGFMT: Image creation needs a size parameter
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 
backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=vmdk
 
-qemu-img: warning: Could not verify backing image. This may become an error in 
future versions.
-Unknown driver 'garbage'
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 
backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=garbage

Re: [PATCH v6 08/10] iotests: Specify explicit backing format where sensible

2020-07-07 Thread Kevin Wolf
Am 06.07.2020 um 22:39 hat Eric Blake geschrieben:
> There are many existing qcow2 images that specify a backing file but
> no format.  This has been the source of CVEs in the past, but has
> become more prominent of a problem now that libvirt has switched to
> -blockdev.  With older -drive, at least the probing was always done by
> qemu (so the only risk of a changed format between successive boots of
> a guest was if qemu was upgraded and probed differently).  But with
> newer -blockdev, libvirt must specify a format; if libvirt guesses raw
> where the image was formatted, this results in data corruption visible
> to the guest; conversely, if libvirt guesses qcow2 where qemu was
> using raw, this can result in potential security holes, so modern
> libvirt instead refuses to use images without explicit backing format.
> 
> The change in libvirt to reject images without explicit backing format
> has pointed out that a number of tools have been far too reliant on
> probing in the past.  It's time to set a better example in our own
> iotests of properly setting this parameter.
> 
> iotest calls to create, rebase, and convert are all impacted to some
> degree.  It's a bit annoying that we are inconsistent on command line
> - while all of those accept -o backing_file=...,backing_fmt=..., the
> shortcuts are different: create and rebase have -b and -F, while
> convert has -B but no -F.  (amend has no shortcuts, but the previous
> patch just deprecated the use of amend to change backing chains).
> 
> Signed-off-by: Eric Blake 

This breaks at least 024 and 043 for qed because qemu-img info can't
print the backing file format there (qed only saves a flag whether it's
raw or non-raw).

We can fix the output filtering during the freeze, though.

Kevin




Re: [PATCH 2/2] hw/sd/sdcard: Do not allow invalid SD card sizes

2020-07-07 Thread Philippe Mathieu-Daudé
On 7/7/20 6:06 PM, Peter Maydell wrote:
> On Tue, 7 Jul 2020 at 17:04, Alistair Francis  wrote:
>>
>> On Tue, Jul 7, 2020 at 6:22 AM Philippe Mathieu-Daudé  
>> wrote:
>>>
>>> QEMU allows to create SD card with unrealistic sizes. This could work,
>>> but some guests (at least Linux) consider sizes that are not a power
>>> of 2 as a firmware bug and fix the card size to the next power of 2.
>>>
>>> Before CVE-2020-13253 fix, this would allow OOB read/write accesses
>>> past the image size end.
>>>
>>> CVE-2020-13253 has been fixed as:
>>>
>>> Read command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
>>> occurred and no data transfer is performed.
>>>
>>> Write command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
>>> occurred and no data transfer is performed.
>>>
>>> WP_VIOLATION errors are not modified: the error bit is set, we
>>> stay in receive-data state, wait for a stop command. All further
>>> data transfer is ignored. See the check on sd->card_status at the
>>> beginning of sd_read_data() and sd_write_data().
>>>
>>> While this is the correct behavior, in case QEMU create smaller SD
>>> cards, guests still try to access past the image size end, and QEMU
>>> considers this is an invalid address, thus "all further data transfer
>>> is ignored". This is wrong and make the guest looping until
>>> eventually timeouts.
>>>
>>> Fix by not allowing invalid SD card sizes.  Suggesting the expected
>>> size as a hint:
>>>
>>>   $ qemu-system-arm -M orangepi-pc -drive file=rootfs.ext2,if=sd,format=raw
>>>   qemu-system-arm: Invalid SD card size: 60 MiB (expecting at least 64 MiB)
>>>
>>> Signed-off-by: Philippe Mathieu-Daudé 
>>> ---
>>>  hw/sd/sd.c | 16 
>>>  1 file changed, 16 insertions(+)
>>>
>>> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
>>> index cb81487e5c..c45106b78e 100644
>>> --- a/hw/sd/sd.c
>>> +++ b/hw/sd/sd.c
>>> @@ -32,6 +32,7 @@
>>>
>>>  #include "qemu/osdep.h"
>>>  #include "qemu/units.h"
>>> +#include "qemu/cutils.h"
>>>  #include "hw/irq.h"
>>>  #include "hw/registerfields.h"
>>>  #include "sysemu/block-backend.h"
>>> @@ -2130,11 +2131,26 @@ static void sd_realize(DeviceState *dev, Error 
>>> **errp)
>>>  }
>>>
>>>  if (sd->blk) {
>>> +int64_t blk_size;
>>> +
>>>  if (blk_is_read_only(sd->blk)) {
>>>  error_setg(errp, "Cannot use read-only drive as SD card");
>>>  return;
>>>  }
>>>
>>> +blk_size = blk_getlength(sd->blk);
>>> +if (blk_size > 0 && !is_power_of_2(blk_size)) {
>>> +int64_t blk_size_aligned = pow2ceil(blk_size);
>>> +char *blk_size_str = size_to_str(blk_size);
>>> +char *blk_size_aligned_str = size_to_str(blk_size_aligned);
>>> +
>>> +error_setg(errp, "Invalid SD card size: %s (expecting at least 
>>> %s)",
>>> +   blk_size_str, blk_size_aligned_str);
>>
>> Should we print that we expect a power of 2? This isn't always obvious
>> from the message.
> 
> Mmm, I was thinking that. Perhaps
>  "expecting a power of 2, e.g. %s"
> ?

OK, thanks guys!

> 
> thanks
> -- PMM
> 



[PATCH v4 22/45] qom: Rename qdev_get_type() to object_get_type()

2020-07-07 Thread Markus Armbruster
Commit 2f262e06f0 lifted qdev_get_type() from qdev to object without
renaming it accordingly.  Do that now.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 qom/object.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/qom/object.c b/qom/object.c
index 87ee0b5a81..0808da2767 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -2365,7 +2365,7 @@ object_class_property_add_tm(ObjectClass *klass, const 
char *name,
  NULL, NULL, prop);
 }
 
-static char *qdev_get_type(Object *obj, Error **errp)
+static char *object_get_type(Object *obj, Error **errp)
 {
 return g_strdup(object_get_typename(obj));
 }
@@ -2716,7 +2716,7 @@ void object_class_property_set_description(ObjectClass 
*klass,
 
 static void object_class_init(ObjectClass *klass, void *data)
 {
-object_class_property_add_str(klass, "type", qdev_get_type,
+object_class_property_add_str(klass, "type", object_get_type,
   NULL);
 }
 
-- 
2.26.2




[PATCH v4 44/45] qdev: Ignore Error objects where the return value suffices

2020-07-07 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 hw/core/qdev-properties.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 2bec8a80b8..098298c78e 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -742,7 +742,6 @@ static void set_pci_devfn(Object *obj, Visitor *v, const 
char *name,
 Property *prop = opaque;
 int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
 unsigned int slot, fn, n;
-Error *local_err = NULL;
 char *str;
 
 if (dev->realized) {
@@ -750,9 +749,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, const 
char *name,
 return;
 }
 
-if (!visit_type_str(v, name, , _err)) {
-error_free(local_err);
-local_err = NULL;
+if (!visit_type_str(v, name, , NULL)) {
 if (!visit_type_int32(v, name, , errp)) {
 return;
 }
-- 
2.26.2




Re: [PATCH v4 00/45] Less clumsy error checking

2020-07-07 Thread Markus Armbruster
Neglected to mention: code changes are limited to resolving rebase
conflicts in PATCH 26.  v4 is about comments, mostly to reduce churn
when combined with Vladimir's auto propagation work.




Re: [PATCH v6 00/10] Tighten qemu-img rules on missing backing format

2020-07-07 Thread Kevin Wolf
Am 06.07.2020 um 22:39 hat Eric Blake geschrieben:
> v5 was here:
> https://lists.gnu.org/archive/html/qemu-devel/2020-04/msg00679.html
> In v6:
> - add a few more patches
> - change qcow semantics based on several iterations of mailing list
> debates on what behavior is easiest to support
> - add iotesting that a probed raw file cannot be committed into
> - instead of recording an implicit probed raw file, instead we record
> only a non-raw file
> - rebase to a few more affected iotests, plus s/5.0/5.1/
> 
> Yes, I know this is really short notice to make it in before feature
> freeze for 5.1 (removal in 6.0), so it may end up slipping into 5.2
> (removal in 6.1); but we'll see how things go.

Thanks, applied to the block branch.

Kevin




[PATCH v4 41/45] qapi: Purge error_propagate() from QAPI core

2020-07-07 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 qapi/qapi-visit-core.c | 40 +++-
 1 file changed, 19 insertions(+), 21 deletions(-)

diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 5a9c47aabf..7e5f40e7f0 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -39,19 +39,18 @@ void visit_free(Visitor *v)
 bool visit_start_struct(Visitor *v, const char *name, void **obj,
 size_t size, Error **errp)
 {
-Error *err = NULL;
+bool ok;
 
 trace_visit_start_struct(v, name, obj, size);
 if (obj) {
 assert(size);
 assert(!(v->type & VISITOR_OUTPUT) || *obj);
 }
-v->start_struct(v, name, obj, size, );
+ok = v->start_struct(v, name, obj, size, errp);
 if (obj && (v->type & VISITOR_INPUT)) {
-assert(!err != !*obj);
+assert(ok != !*obj);
 }
-error_propagate(errp, err);
-return !err;
+return ok;
 }
 
 bool visit_check_struct(Visitor *v, Error **errp)
@@ -69,16 +68,15 @@ void visit_end_struct(Visitor *v, void **obj)
 bool visit_start_list(Visitor *v, const char *name, GenericList **list,
   size_t size, Error **errp)
 {
-Error *err = NULL;
+bool ok;
 
 assert(!list || size >= sizeof(GenericList));
 trace_visit_start_list(v, name, list, size);
-v->start_list(v, name, list, size, );
+ok = v->start_list(v, name, list, size, errp);
 if (list && (v->type & VISITOR_INPUT)) {
-assert(!(err && *list));
+assert(ok || !*list);
 }
-error_propagate(errp, err);
-return !err;
+return ok;
 }
 
 GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size)
@@ -104,19 +102,20 @@ bool visit_start_alternate(Visitor *v, const char *name,
GenericAlternate **obj, size_t size,
Error **errp)
 {
-Error *err = NULL;
+bool ok;
 
 assert(obj && size >= sizeof(GenericAlternate));
 assert(!(v->type & VISITOR_OUTPUT) || *obj);
 trace_visit_start_alternate(v, name, obj, size);
-if (v->start_alternate) {
-v->start_alternate(v, name, obj, size, );
+if (!v->start_alternate) {
+assert(!(v->type & VISITOR_INPUT));
+return true;
 }
+ok = v->start_alternate(v, name, obj, size, errp);
 if (v->type & VISITOR_INPUT) {
-assert(v->start_alternate && !err != !*obj);
+assert(ok != !*obj);
 }
-error_propagate(errp, err);
-return !err;
+return ok;
 }
 
 void visit_end_alternate(Visitor *v, void **obj)
@@ -309,7 +308,7 @@ bool visit_type_bool(Visitor *v, const char *name, bool 
*obj, Error **errp)
 
 bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp)
 {
-Error *err = NULL;
+bool ok;
 
 assert(obj);
 /* TODO: Fix callers to not pass NULL when they mean "", so that we
@@ -317,12 +316,11 @@ bool visit_type_str(Visitor *v, const char *name, char 
**obj, Error **errp)
 assert(!(v->type & VISITOR_OUTPUT) || *obj);
  */
 trace_visit_type_str(v, name, obj);
-v->type_str(v, name, obj, );
+ok = v->type_str(v, name, obj, errp);
 if (v->type & VISITOR_INPUT) {
-assert(!err != !*obj);
+assert(ok != !*obj);
 }
-error_propagate(errp, err);
-return !err;
+return ok;
 }
 
 bool visit_type_number(Visitor *v, const char *name, double *obj,
-- 
2.26.2




[PATCH v4 17/45] qapi: Make visitor functions taking Error ** return bool, not void

2020-07-07 Thread Markus Armbruster
See recent commit "error: Document Error API usage rules" for
rationale.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 docs/devel/qapi-code-gen.txt  |  51 +--
 include/qapi/clone-visitor.h  |   8 +-
 include/qapi/visitor-impl.h   |  26 +++---
 include/qapi/visitor.h| 102 -
 audio/audio_legacy.c  |  15 ++--
 qapi/opts-visitor.c   |  66 --
 qapi/qapi-clone-visitor.c |  69 +++---
 qapi/qapi-dealloc-visitor.c   |  27 --
 qapi/qapi-visit-core.c| 165 ++
 qapi/qobject-input-visitor.c  | 109 +-
 qapi/qobject-output-visitor.c |  27 --
 qapi/string-input-visitor.c   |  62 +++--
 qapi/string-output-visitor.c  |  32 ---
 scripts/qapi/visit.py |  58 +---
 14 files changed, 456 insertions(+), 361 deletions(-)

diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
index a7794ef658..9bfc57063c 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -1408,42 +1408,38 @@ Example:
 #include "example-qapi-types.h"
 
 
-void visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error 
**errp);
-void visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, 
Error **errp);
-void visit_type_UserDefOneList(Visitor *v, const char *name, 
UserDefOneList **obj, Error **errp);
+bool visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error 
**errp);
+bool visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, 
Error **errp);
+bool visit_type_UserDefOneList(Visitor *v, const char *name, 
UserDefOneList **obj, Error **errp);
 
-void visit_type_q_obj_my_command_arg_members(Visitor *v, 
q_obj_my_command_arg *obj, Error **errp);
+bool visit_type_q_obj_my_command_arg_members(Visitor *v, 
q_obj_my_command_arg *obj, Error **errp);
 
 #endif /* EXAMPLE_QAPI_VISIT_H */
 $ cat qapi-generated/example-qapi-visit.c
 [Uninteresting stuff omitted...]
 
-void visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error 
**errp)
+bool visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error 
**errp)
 {
 Error *err = NULL;
 
-visit_type_int(v, "integer", >integer, );
-if (err) {
-goto out;
+if (!visit_type_int(v, "integer", >integer, errp)) {
+return false;
 }
 if (visit_optional(v, "string", >has_string)) {
-visit_type_str(v, "string", >string, );
-if (err) {
-goto out;
+if (!visit_type_str(v, "string", >string, errp)) {
+return false;
 }
 }
-
-out:
 error_propagate(errp, err);
+return !err;
 }
 
-void visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, 
Error **errp)
+bool visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, 
Error **errp)
 {
 Error *err = NULL;
 
-visit_start_struct(v, name, (void **)obj, sizeof(UserDefOne), );
-if (err) {
-goto out;
+if (!visit_start_struct(v, name, (void **)obj, sizeof(UserDefOne), 
errp)) {
+return false;
 }
 if (!*obj) {
 /* incomplete */
@@ -1461,19 +1457,18 @@ Example:
 qapi_free_UserDefOne(*obj);
 *obj = NULL;
 }
-out:
 error_propagate(errp, err);
+return !err;
 }
 
-void visit_type_UserDefOneList(Visitor *v, const char *name, 
UserDefOneList **obj, Error **errp)
+bool visit_type_UserDefOneList(Visitor *v, const char *name, 
UserDefOneList **obj, Error **errp)
 {
 Error *err = NULL;
 UserDefOneList *tail;
 size_t size = sizeof(**obj);
 
-visit_start_list(v, name, (GenericList **)obj, size, );
-if (err) {
-goto out;
+if (!visit_start_list(v, name, (GenericList **)obj, size, errp)) {
+return false;
 }
 
 for (tail = *obj; tail;
@@ -1492,21 +1487,19 @@ Example:
 qapi_free_UserDefOneList(*obj);
 *obj = NULL;
 }
-out:
 error_propagate(errp, err);
+return !err;
 }
 
-void visit_type_q_obj_my_command_arg_members(Visitor *v, 
q_obj_my_command_arg *obj, Error **errp)
+bool visit_type_q_obj_my_command_arg_members(Visitor *v, 
q_obj_my_command_arg *obj, Error **errp)
 {
 Error *err = NULL;
 
-visit_type_UserDefOneList(v, "arg1", >arg1, );
-if (err) {
-goto out;
+if (!visit_type_UserDefOneList(v, "arg1", >arg1, errp)) {
+return false;
 }
-
-out:
 error_propagate(errp, err);
+return !err;
 }
 
 [Uninteresting stuff omitted...]
diff --git a/include/qapi/clone-visitor.h b/include/qapi/clone-visitor.h
index 5b665ee38c..adf9a788e2 

Re: [PATCH for-5.1] file-posix: Mitigate file fragmentation with extent size hints

2020-07-07 Thread Kevin Wolf
Am 07.07.2020 um 16:23 hat Kevin Wolf geschrieben:
> Espeically when O_DIRECT is used with image files so that the page cache
> indirection can't cause a merge of allocating requests, the file will
> fragment on the file system layer, with a potentially very small
> fragment size (this depends on the requests the guest sent).
> 
> On Linux, fragmentation can be reduced by setting an extent size hint
> when creating the file (at least on XFS, it can't be set any more after
> the first extent has been allocated), basically giving raw files a
> "cluster size" for allocation.
> 
> This adds an create option to set the extent size hint, and changes the
> default from not setting a hint to setting it to 1 MB. The main reason
> why qcow2 defaults to smaller cluster sizes is that COW becomes more
> expensive, which is not an issue with raw files, so we can choose a
> larger file. The tradeoff here is only potentially wasted disk space.
> 
> For qcow2 (or other image formats) over file-posix, the advantage should
> even be greater because they grow sequentially without leaving holes, so
> there won't be wasted space. Setting even larger extent size hints for
> such images may make sense. This can be done with the new option, but
> let's keep the default conservative for now.
> 
> The effect is very visible with a test that intentionally creates a
> badly fragmented file with qemu-img bench (the time difference while
> creating the file is already remarkable) and then looks at the number of
> extents and the take a simple "qemu-img map" takes.
> 
> Without an extent size hint:
> 
> $ ./qemu-img create -f raw -o extent_size_hint=0 ~/tmp/test.raw 10G
> Formatting '/home/kwolf/tmp/test.raw', fmt=raw size=10737418240 
> extent_size_hint=0
> $ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 100 -S 8192 
> -o 0
> Sending 100 write requests, 4096 bytes each, 64 in parallel (starting 
> at offset 0, step size 8192)
> Run completed in 25.848 seconds.
> $ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 100 -S 8192 
> -o 4096
> Sending 100 write requests, 4096 bytes each, 64 in parallel (starting 
> at offset 4096, step size 8192)
> Run completed in 19.616 seconds.
> $ filefrag ~/tmp/test.raw
> /home/kwolf/tmp/test.raw: 200 extents found
> $ time ./qemu-img map ~/tmp/test.raw
> Offset  Length  Mapped to   File
> 0   0x1e848 0   /home/kwolf/tmp/test.raw
> 
> real0m1,279s
> user0m0,043s
> sys 0m1,226s
> 
> With the new default extent size hint of 1 MB:
> 
> $ ./qemu-img create -f raw -o extent_size_hint=1M ~/tmp/test.raw 10G
> Formatting '/home/kwolf/tmp/test.raw', fmt=raw size=10737418240 
> extent_size_hint=1048576
> $ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 100 -S 8192 
> -o 0
> Sending 100 write requests, 4096 bytes each, 64 in parallel (starting 
> at offset 0, step size 8192)
> Run completed in 11.833 seconds.
> $ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 100 -S 8192 
> -o 4096
> Sending 100 write requests, 4096 bytes each, 64 in parallel (starting 
> at offset 4096, step size 8192)
> Run completed in 10.155 seconds.
> $ filefrag ~/tmp/test.raw
> /home/kwolf/tmp/test.raw: 178 extents found
> $ time ./qemu-img map ~/tmp/test.raw
> Offset  Length  Mapped to   File
> 0   0x1e848 0   /home/kwolf/tmp/test.raw
> 
> real0m0,061s
> user0m0,040s
> sys 0m0,014s
> 
> Signed-off-by: Kevin Wolf 

I also need to squash in a few trivial qemu-iotests updates, for which I
won't send a v2:

diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
index 1b0a75c8f9..0d7c5e8342 100644
--- a/tests/qemu-iotests/082.out
+++ b/tests/qemu-iotests/082.out
@@ -62,6 +62,7 @@ Supported options:
   encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm
   encrypt.key-secret= - ID of secret providing qcow AES key or LUKS 
passphrase
   encryption= - Encrypt the image with format 'aes'. 
(Deprecated in favor of encrypt.format=aes)
+  extent_size_hint= - Extent size hint for the image file, 0 to disable
   lazy_refcounts= - Postpone refcount updates
   nocow=  - Turn off copy-on-write (valid only on btrfs)
   preallocation=- Preallocation mode (allowed values: off, metadata, 
falloc, full)
@@ -86,6 +87,7 @@ Supported options:
   encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm
   encrypt.key-secret= - ID of secret providing qcow AES key or LUKS 
passphrase
   encryption= - Encrypt the image with format 'aes'. 
(Deprecated in favor of encrypt.format=aes)
+  extent_size_hint= - Extent size hint for the image file, 0 to disable
   lazy_refcounts= - Postpone refcount updates
   nocow=  - Turn off copy-on-write (valid only on btrfs)
   preallocation=- Preallocation mode (allowed values: 

[PATCH v4 40/45] qapi: Smooth visitor error checking in generated code

2020-07-07 Thread Markus Armbruster
Use visitor functions' return values to check for failure.  Eliminate
error_propagate() that are now unnecessary.  Delete @err that are now
unused.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 docs/devel/qapi-code-gen.txt | 60 ++--
 scripts/qapi/commands.py | 22 ++---
 scripts/qapi/visit.py| 57 ++
 3 files changed, 55 insertions(+), 84 deletions(-)

diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
index 9bfc57063c..69eede6c28 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -1420,8 +1420,6 @@ Example:
 
 bool visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error 
**errp)
 {
-Error *err = NULL;
-
 if (!visit_type_int(v, "integer", >integer, errp)) {
 return false;
 }
@@ -1430,13 +1428,12 @@ Example:
 return false;
 }
 }
-error_propagate(errp, err);
-return !err;
+return true;
 }
 
 bool visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, 
Error **errp)
 {
-Error *err = NULL;
+bool ok = false;
 
 if (!visit_start_struct(v, name, (void **)obj, sizeof(UserDefOne), 
errp)) {
 return false;
@@ -1446,24 +1443,22 @@ Example:
 assert(visit_is_dealloc(v));
 goto out_obj;
 }
-visit_type_UserDefOne_members(v, *obj, );
-if (err) {
+if (!visit_type_UserDefOne_members(v, *obj, errp)) {
 goto out_obj;
 }
-visit_check_struct(v, );
+ok = visit_check_struct(v, errp);
 out_obj:
 visit_end_struct(v, (void **)obj);
-if (err && visit_is_input(v)) {
+if (!ok && visit_is_input(v)) {
 qapi_free_UserDefOne(*obj);
 *obj = NULL;
 }
-error_propagate(errp, err);
-return !err;
+return ok;
 }
 
 bool visit_type_UserDefOneList(Visitor *v, const char *name, 
UserDefOneList **obj, Error **errp)
 {
-Error *err = NULL;
+bool ok = false;
 UserDefOneList *tail;
 size_t size = sizeof(**obj);
 
@@ -1473,33 +1468,27 @@ Example:
 
 for (tail = *obj; tail;
  tail = (UserDefOneList *)visit_next_list(v, (GenericList *)tail, 
size)) {
-visit_type_UserDefOne(v, NULL, >value, );
-if (err) {
-break;
+if (!visit_type_UserDefOne(v, NULL, >value, errp)) {
+goto out_obj;
 }
 }
 
-if (!err) {
-visit_check_list(v, );
-}
+ok = visit_check_list(v, errp);
+out_obj:
 visit_end_list(v, (void **)obj);
-if (err && visit_is_input(v)) {
+if (!ok && visit_is_input(v)) {
 qapi_free_UserDefOneList(*obj);
 *obj = NULL;
 }
-error_propagate(errp, err);
-return !err;
+return ok;
 }
 
 bool visit_type_q_obj_my_command_arg_members(Visitor *v, 
q_obj_my_command_arg *obj, Error **errp)
 {
-Error *err = NULL;
-
 if (!visit_type_UserDefOneList(v, "arg1", >arg1, errp)) {
 return false;
 }
-error_propagate(errp, err);
-return !err;
+return true;
 }
 
 [Uninteresting stuff omitted...]
@@ -1554,15 +1543,12 @@ Example:
 
 static void qmp_marshal_output_UserDefOne(UserDefOne *ret_in, QObject 
**ret_out, Error **errp)
 {
-Error *err = NULL;
 Visitor *v;
 
 v = qobject_output_visitor_new(ret_out);
-visit_type_UserDefOne(v, "unused", _in, );
-if (!err) {
+if (visit_type_UserDefOne(v, "unused", _in, errp)) {
 visit_complete(v, ret_out);
 }
-error_propagate(errp, err);
 visit_free(v);
 v = qapi_dealloc_visitor_new();
 visit_type_UserDefOne(v, "unused", _in, NULL);
@@ -1572,33 +1558,32 @@ Example:
 void qmp_marshal_my_command(QDict *args, QObject **ret, Error **errp)
 {
 Error *err = NULL;
+bool ok = false;
 Visitor *v;
 UserDefOne *retval;
 q_obj_my_command_arg arg = {0};
 
 v = qobject_input_visitor_new(QOBJECT(args));
-visit_start_struct(v, NULL, NULL, 0, );
-if (err) {
+if (!visit_start_struct(v, NULL, NULL, 0, errp)) {
 goto out;
 }
-visit_type_q_obj_my_command_arg_members(v, , );
-if (!err) {
-visit_check_struct(v, );
+if (visit_type_q_obj_my_command_arg_members(v, , errp)) {
+ok = visit_check_struct(v, errp);
 }
 visit_end_struct(v, NULL);
-if (err) {
+if (!ok) {
 goto out;
 }
 
 retval = qmp_my_command(arg.arg1, );
+error_propagate(errp, err);
 if (err) {
 goto out;
 }
 
-

[PATCH v4 00/45] Less clumsy error checking

2020-07-07 Thread Markus Armbruster
When the Error API was created, we adopted the (unwritten) rule to
return void when the function returns no useful value on success,
unlike GError, which recommends to return true on success and false on
error then.

When a function returns a distinct error value, say false, a checked
call that passes the error up looks like

if (!frobnicate(..., errp)) {
handle the error...
}

When it returns void, we need

Error *err = NULL;

frobnicate(..., );
if (err) {
handle the error...
error_propagate(errp, err);
}

Not only is this more verbose, it also creates an Error object even
when @errp is null, _abort or _fatal.

People got tired of the additional boilerplate, and started to ignore
the unwritten rule.  The result is confusion among developers about
the preferred usage.

This series adopts the GError rule (in writing), and updates a
substantial amount of code to honor the rule.  Cuts the number of
error_propagate() calls nearly by half.  The diffstat speaks for
itself.

Also available from my public repository
https://repo.or.cz/qemu/armbru.git on branch error-smooth.

v4:
* Rebased
* PATCH 01: Don't show errp instead of , it's premature; leave
  it to Vladimir's series.  Fix the error_propagate_prepend() pileup
  example.  Update commit message accordingly.  R-bys kept, hope
  that's not too bold.
* PATCH 02: New.
* PATCH 03: Structure the big comment with headlines.  Explain the
  @errp usage restrictions more clearly.  Update examples to
  prefer checking the return value over checking @err.  Update commit
  message accordingly.  R-bys kept, hope that's not too bold.
* PATCH 07: Tweak commit message [Greg]
* Left for later: followup to fix nearby typos and such [Eric]

v3:
* Rebased
* Fix patch ordering: old PATCH 19 becomes PATCH 37
* PATCH 03+13+25+27: Avoid long lines in Coccinelle script [Eric]
* PATCH 14: Fix commit message typo [Eric]
* PATCH 16: Unbreak opts_start_list(), qapi_clone_start_list(),
  qapi_clone_start_alternate() [Vladimir]
* PATCH 24: Unbreak object_set_link_property() [Vladimir]
* PATCH 25+33+35: Move unrelated hunks from 25 to 33 and 35
  [Vladimir], tweak line breaks
* PATCH 32: Have commit message point out the unnecessary
  error_propagate() will be eliminated shortly [Eric]
* PATCH 33: Fix commit message typo [Eric]
* PATCH 35: Delete comment along with the assertion [Eric]
* Left for later: followup to fix nearby typos and such [Eric]

v2:
* Rebased
* Coccinelle scripts reworked, patches sliced and diced for
  reviewability:
  Old PATCH 03+17+23-24+35+38-39+42 split into "Use returned bool to
  check for failure" parts [PATCH 03+13+17-18+25+28-29+42], and
  "Eliminate error_propagate()" parts.  The latter combined with old
  PATCH 06-07+18-19+29+43 are now [PATCH 33-37].  The end result is
  almost identical.  Some R-bys dropped; sorry!
* Drop variables as they become unused [Vladimir]
* PATCH 01: Comment typos fixed [Greg]
* PATCH 09: Simplify further by cutting out variables [Eric]
* PATCH 11: opt_set() renamed to opt_validate(), redundant parameter
  dropped [Vladimir], R-by kept
* PATCH 16: Comment typos fixed, indentation tidied up [Eric]
* PATCH 23: Assertion dropped [Eric], incorrect hunk backed out
* PATCH 26: Regenerated after rebase; note additional Coccinelle
  hiccup in the commit message
* PATCH 27: Indentation tiedied up [Eric]
* Left for later: followup to fix nearby typos and such [Eric]

Markus Armbruster (45):
  error: Fix examples in error.h's big comment
  error: Improve error.h's big comment
  error: Document Error API usage rules
  qdev: Use returned bool to check for qdev_realize() etc. failure
  macio: Tidy up error handling in macio_newworld_realize()
  virtio-crypto-pci: Tidy up virtio_crypto_pci_realize()
  qemu-option: Check return value instead of @err where convenient
  qemu-option: Make uses of find_desc_by_name() more similar
  qemu-option: Factor out helper find_default_by_name()
  qemu-option: Simplify around find_default_by_name()
  qemu-option: Factor out helper opt_create()
  qemu-option: Replace opt_set() by cleaner opt_validate()
  qemu-option: Make functions taking Error ** return bool, not void
  qemu-option: Use returned bool to check for failure
  block: Avoid error accumulation in bdrv_img_create()
  hmp: Eliminate a variable in hmp_migrate_set_parameter()
  qapi: Make visitor functions taking Error ** return bool, not void
  qapi: Use returned bool to check for failure, Coccinelle part
  qapi: Use returned bool to check for failure, manual part
  s390x/pci: Fix harmless mistake in zpci's property fid's setter
  qom: Use error_reportf_err() instead of g_printerr() in examples
  qom: Rename qdev_get_type() to object_get_type()
  qom: Crash more nicely on object_property_get_link() failure
  qom: Don't handle impossible object_property_get_link() failure
  qom: Use return values to check for error where that's simpler
  qom: Put name parameter before value / visitor parameter
  qom: Make 

[PATCH v4 21/45] qom: Use error_reportf_err() instead of g_printerr() in examples

2020-07-07 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 include/qom/object.h | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 94a61ccc3f..b70edd8cd9 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -671,8 +671,7 @@ Object *object_new(const char *typename);
  *   NULL);
  *
  *   if (!obj) {
- * g_printerr("Cannot create memory backend: %s\n",
- *error_get_pretty(err));
+ * error_reportf_err(err, "Cannot create memory backend: ");
  *   }
  *   
  * 
@@ -739,8 +738,7 @@ void object_apply_compat_props(Object *obj);
  *  NULL);
  *
  *   if (!obj) {
- * g_printerr("Cannot set properties: %s\n",
- *error_get_pretty(err));
+ * error_reportf_err(err, "Cannot set properties: ");
  *   }
  *   
  * 
-- 
2.26.2




Re: [PATCH 2/2] hw/sd/sdcard: Do not allow invalid SD card sizes

2020-07-07 Thread Peter Maydell
On Tue, 7 Jul 2020 at 17:04, Alistair Francis  wrote:
>
> On Tue, Jul 7, 2020 at 6:22 AM Philippe Mathieu-Daudé  wrote:
> >
> > QEMU allows to create SD card with unrealistic sizes. This could work,
> > but some guests (at least Linux) consider sizes that are not a power
> > of 2 as a firmware bug and fix the card size to the next power of 2.
> >
> > Before CVE-2020-13253 fix, this would allow OOB read/write accesses
> > past the image size end.
> >
> > CVE-2020-13253 has been fixed as:
> >
> > Read command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
> > occurred and no data transfer is performed.
> >
> > Write command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
> > occurred and no data transfer is performed.
> >
> > WP_VIOLATION errors are not modified: the error bit is set, we
> > stay in receive-data state, wait for a stop command. All further
> > data transfer is ignored. See the check on sd->card_status at the
> > beginning of sd_read_data() and sd_write_data().
> >
> > While this is the correct behavior, in case QEMU create smaller SD
> > cards, guests still try to access past the image size end, and QEMU
> > considers this is an invalid address, thus "all further data transfer
> > is ignored". This is wrong and make the guest looping until
> > eventually timeouts.
> >
> > Fix by not allowing invalid SD card sizes.  Suggesting the expected
> > size as a hint:
> >
> >   $ qemu-system-arm -M orangepi-pc -drive file=rootfs.ext2,if=sd,format=raw
> >   qemu-system-arm: Invalid SD card size: 60 MiB (expecting at least 64 MiB)
> >
> > Signed-off-by: Philippe Mathieu-Daudé 
> > ---
> >  hw/sd/sd.c | 16 
> >  1 file changed, 16 insertions(+)
> >
> > diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> > index cb81487e5c..c45106b78e 100644
> > --- a/hw/sd/sd.c
> > +++ b/hw/sd/sd.c
> > @@ -32,6 +32,7 @@
> >
> >  #include "qemu/osdep.h"
> >  #include "qemu/units.h"
> > +#include "qemu/cutils.h"
> >  #include "hw/irq.h"
> >  #include "hw/registerfields.h"
> >  #include "sysemu/block-backend.h"
> > @@ -2130,11 +2131,26 @@ static void sd_realize(DeviceState *dev, Error 
> > **errp)
> >  }
> >
> >  if (sd->blk) {
> > +int64_t blk_size;
> > +
> >  if (blk_is_read_only(sd->blk)) {
> >  error_setg(errp, "Cannot use read-only drive as SD card");
> >  return;
> >  }
> >
> > +blk_size = blk_getlength(sd->blk);
> > +if (blk_size > 0 && !is_power_of_2(blk_size)) {
> > +int64_t blk_size_aligned = pow2ceil(blk_size);
> > +char *blk_size_str = size_to_str(blk_size);
> > +char *blk_size_aligned_str = size_to_str(blk_size_aligned);
> > +
> > +error_setg(errp, "Invalid SD card size: %s (expecting at least 
> > %s)",
> > +   blk_size_str, blk_size_aligned_str);
>
> Should we print that we expect a power of 2? This isn't always obvious
> from the message.

Mmm, I was thinking that. Perhaps
 "expecting a power of 2, e.g. %s"
?

thanks
-- PMM



[PATCH v4 37/45] error: Reduce unnecessary error propagation

2020-07-07 Thread Markus Armbruster
When all we do with an Error we receive into a local variable is
propagating to somewhere else, we can just as well receive it there
right away, even when we need to keep error_propagate() for other
error paths.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 block.c | 2 +-
 block/gluster.c | 8 
 block/parallels.c   | 2 +-
 block/quorum.c  | 2 +-
 block/replication.c | 3 +--
 block/vxhs.c| 4 ++--
 hw/core/qdev.c  | 2 +-
 hw/net/virtio-net.c | 4 ++--
 8 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/block.c b/block.c
index 60d2945c2c..2dcf9afd61 100644
--- a/block.c
+++ b/block.c
@@ -6073,7 +6073,7 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
 
 /* Parse -o options */
 if (options) {
-if (!qemu_opts_do_parse(opts, options, NULL, _err)) {
+if (!qemu_opts_do_parse(opts, options, NULL, errp)) {
 goto out;
 }
 }
diff --git a/block/gluster.c b/block/gluster.c
index c620880f27..4f1448e2bc 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -523,7 +523,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster 
*gconf,
 
 /* create opts info from runtime_json_opts list */
 opts = qemu_opts_create(_json_opts, NULL, 0, _abort);
-if (!qemu_opts_absorb_qdict(opts, options, _err)) {
+if (!qemu_opts_absorb_qdict(opts, options, errp)) {
 goto out;
 }
 
@@ -554,7 +554,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster 
*gconf,
 
 /* create opts info from runtime_type_opts list */
 opts = qemu_opts_create(_type_opts, NULL, 0, _abort);
-if (!qemu_opts_absorb_qdict(opts, backing_options, _err)) {
+if (!qemu_opts_absorb_qdict(opts, backing_options, errp)) {
 goto out;
 }
 
@@ -584,7 +584,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster 
*gconf,
 if (gsconf->type == SOCKET_ADDRESS_TYPE_INET) {
 /* create opts info from runtime_inet_opts list */
 opts = qemu_opts_create(_inet_opts, NULL, 0, _abort);
-if (!qemu_opts_absorb_qdict(opts, backing_options, _err)) {
+if (!qemu_opts_absorb_qdict(opts, backing_options, errp)) {
 goto out;
 }
 
@@ -632,7 +632,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster 
*gconf,
 } else {
 /* create opts info from runtime_unix_opts list */
 opts = qemu_opts_create(_unix_opts, NULL, 0, _abort);
-if (!qemu_opts_absorb_qdict(opts, backing_options, _err)) {
+if (!qemu_opts_absorb_qdict(opts, backing_options, errp)) {
 goto out;
 }
 
diff --git a/block/parallels.c b/block/parallels.c
index ff27a85c01..180dd41e2b 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -828,7 +828,7 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 goto fail_options;
 }
 
-if (!qemu_opts_absorb_qdict(opts, options, _err)) {
+if (!qemu_opts_absorb_qdict(opts, options, errp)) {
 goto fail_options;
 }
 
diff --git a/block/quorum.c b/block/quorum.c
index 5d52e605db..6df9449fc2 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -921,7 +921,7 @@ static int quorum_open(BlockDriverState *bs, QDict 
*options, int flags,
 }
 
 opts = qemu_opts_create(_runtime_opts, NULL, 0, _abort);
-if (!qemu_opts_absorb_qdict(opts, options, _err)) {
+if (!qemu_opts_absorb_qdict(opts, options, errp)) {
 ret = -EINVAL;
 goto exit;
 }
diff --git a/block/replication.c b/block/replication.c
index dcd430624e..0c70215784 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -85,7 +85,6 @@ static int replication_open(BlockDriverState *bs, QDict 
*options,
 {
 int ret;
 BDRVReplicationState *s = bs->opaque;
-Error *local_err = NULL;
 QemuOpts *opts = NULL;
 const char *mode;
 const char *top_id;
@@ -99,7 +98,7 @@ static int replication_open(BlockDriverState *bs, QDict 
*options,
 
 ret = -EINVAL;
 opts = qemu_opts_create(_runtime_opts, NULL, 0, _abort);
-if (!qemu_opts_absorb_qdict(opts, options, _err)) {
+if (!qemu_opts_absorb_qdict(opts, options, errp)) {
 goto fail;
 }
 
diff --git a/block/vxhs.c b/block/vxhs.c
index fecaeb82c9..dc0e254730 100644
--- a/block/vxhs.c
+++ b/block/vxhs.c
@@ -318,7 +318,7 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
 opts = qemu_opts_create(_opts, NULL, 0, _abort);
 tcp_opts = qemu_opts_create(_tcp_opts, NULL, 0, _abort);
 
-if (!qemu_opts_absorb_qdict(opts, options, _err)) {
+if (!qemu_opts_absorb_qdict(opts, options, errp)) {
 ret = -EINVAL;
 goto out;
 }
@@ -345,7 +345,7 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
 /* get the 'server.' arguments */
 qdict_extract_subqdict(options, _options, VXHS_OPT_SERVER".");
 
-if (!qemu_opts_absorb_qdict(tcp_opts, 

[PATCH v4 29/45] qom: Use returned bool to check for failure, manual part

2020-07-07 Thread Markus Armbruster
The previous commit used Coccinelle to convert from checking the Error
object to checking the return value.  Convert a few more manually.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 hw/core/bus.c  |  6 +-
 hw/core/qdev.c |  7 +--
 hw/s390x/s390-virtio-ccw.c | 13 +++--
 3 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/hw/core/bus.c b/hw/core/bus.c
index 00d1d31762..6b987b6946 100644
--- a/hw/core/bus.c
+++ b/hw/core/bus.c
@@ -166,11 +166,7 @@ BusState *qbus_create(const char *typename, DeviceState 
*parent, const char *nam
 
 bool qbus_realize(BusState *bus, Error **errp)
 {
-Error *err = NULL;
-
-object_property_set_bool(OBJECT(bus), "realized", true, );
-error_propagate(errp, err);
-return !err;
+return object_property_set_bool(OBJECT(bus), "realized", true, errp);
 }
 
 void qbus_unrealize(BusState *bus)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index d6416fb894..17bd8fc2ec 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -386,8 +386,6 @@ void qdev_simple_device_unplug_cb(HotplugHandler 
*hotplug_dev,
  */
 bool qdev_realize(DeviceState *dev, BusState *bus, Error **errp)
 {
-Error *err = NULL;
-
 assert(!dev->realized && !dev->parent_bus);
 
 if (bus) {
@@ -396,10 +394,7 @@ bool qdev_realize(DeviceState *dev, BusState *bus, Error 
**errp)
 assert(!DEVICE_GET_CLASS(dev)->bus_type);
 }
 
-if (!object_property_set_bool(OBJECT(dev), "realized", true, )) {
-error_propagate(errp, err);
-}
-return !err;
+return object_property_set_bool(OBJECT(dev), "realized", true, errp);
 }
 
 /*
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 62af349c31..f7a68343ef 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -70,19 +70,20 @@ static S390CPU *s390x_new_cpu(const char *typename, 
uint32_t core_id,
 {
 S390CPU *cpu = S390_CPU(object_new(typename));
 Error *err = NULL;
+S390CPU *ret = NULL;
 
 if (!object_property_set_int(OBJECT(cpu), "core-id", core_id, )) {
 goto out;
 }
-qdev_realize(DEVICE(cpu), NULL, );
+if (!qdev_realize(DEVICE(cpu), NULL, )) {
+goto out;
+}
+ret = cpu;
 
 out:
 object_unref(OBJECT(cpu));
-if (err) {
-error_propagate(errp, err);
-cpu = NULL;
-}
-return cpu;
+error_propagate(errp, err);
+return ret;
 }
 
 static void s390_init_cpus(MachineState *machine)
-- 
2.26.2




[PATCH v4 19/45] qapi: Use returned bool to check for failure, manual part

2020-07-07 Thread Markus Armbruster
The previous commit used Coccinelle to convert from checking the Error
object to checking the return value.  Convert a few more manually.
Also tweak control flow in places to conform to the conventional "if
error bail out" pattern.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 accel/kvm/kvm-all.c   | 50 ++-
 block/throttle-groups.c   |  5 ++--
 bootdevice.c  |  4 ++--
 hw/core/qdev-properties.c | 12 +-
 hw/ide/qdev.c |  4 ++--
 hw/mem/nvdimm.c   |  9 +++
 hw/net/ne2000-isa.c   |  4 ++--
 hw/usb/dev-storage.c  |  4 ++--
 net/net.c |  8 ++-
 9 files changed, 44 insertions(+), 56 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 397669231d..83f03b2018 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -3128,37 +3128,33 @@ static void kvm_set_kernel_irqchip(Object *obj, Visitor 
*v,
const char *name, void *opaque,
Error **errp)
 {
-Error *err = NULL;
 KVMState *s = KVM_STATE(obj);
 OnOffSplit mode;
 
-visit_type_OnOffSplit(v, name, , );
-if (err) {
-error_propagate(errp, err);
+if (!visit_type_OnOffSplit(v, name, , errp)) {
 return;
-} else {
-switch (mode) {
-case ON_OFF_SPLIT_ON:
-s->kernel_irqchip_allowed = true;
-s->kernel_irqchip_required = true;
-s->kernel_irqchip_split = ON_OFF_AUTO_OFF;
-break;
-case ON_OFF_SPLIT_OFF:
-s->kernel_irqchip_allowed = false;
-s->kernel_irqchip_required = false;
-s->kernel_irqchip_split = ON_OFF_AUTO_OFF;
-break;
-case ON_OFF_SPLIT_SPLIT:
-s->kernel_irqchip_allowed = true;
-s->kernel_irqchip_required = true;
-s->kernel_irqchip_split = ON_OFF_AUTO_ON;
-break;
-default:
-/* The value was checked in visit_type_OnOffSplit() above. If
- * we get here, then something is wrong in QEMU.
- */
-abort();
-}
+}
+switch (mode) {
+case ON_OFF_SPLIT_ON:
+s->kernel_irqchip_allowed = true;
+s->kernel_irqchip_required = true;
+s->kernel_irqchip_split = ON_OFF_AUTO_OFF;
+break;
+case ON_OFF_SPLIT_OFF:
+s->kernel_irqchip_allowed = false;
+s->kernel_irqchip_required = false;
+s->kernel_irqchip_split = ON_OFF_AUTO_OFF;
+break;
+case ON_OFF_SPLIT_SPLIT:
+s->kernel_irqchip_allowed = true;
+s->kernel_irqchip_required = true;
+s->kernel_irqchip_split = ON_OFF_AUTO_ON;
+break;
+default:
+/* The value was checked in visit_type_OnOffSplit() above. If
+ * we get here, then something is wrong in QEMU.
+ */
+abort();
 }
 }
 
diff --git a/block/throttle-groups.c b/block/throttle-groups.c
index bb242fde1a..e411051160 100644
--- a/block/throttle-groups.c
+++ b/block/throttle-groups.c
@@ -895,8 +895,8 @@ static void throttle_group_set_limits(Object *obj, Visitor 
*v,
 ThrottleLimits *argp;
 Error *local_err = NULL;
 
-if (!visit_type_ThrottleLimits(v, name, , _err)) {
-goto ret;
+if (!visit_type_ThrottleLimits(v, name, , errp)) {
+return;
 }
 qemu_mutex_lock(>lock);
 throttle_get_config(>ts, );
@@ -908,7 +908,6 @@ static void throttle_group_set_limits(Object *obj, Visitor 
*v,
 
 unlock:
 qemu_mutex_unlock(>lock);
-ret:
 qapi_free_ThrottleLimits(argp);
 error_propagate(errp, local_err);
 return;
diff --git a/bootdevice.c b/bootdevice.c
index fb09d3c668..769f40c77d 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -297,8 +297,8 @@ static void device_set_bootindex(Object *obj, Visitor *v, 
const char *name,
 int32_t boot_index;
 Error *local_err = NULL;
 
-if (!visit_type_int32(v, name, _index, _err)) {
-goto out;
+if (!visit_type_int32(v, name, _index, errp)) {
+return;
 }
 /* check whether bootindex is present in fw_boot_order list  */
 check_boot_index(boot_index, _err);
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 3cb6faa12b..4c7a8a05a5 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -761,15 +761,15 @@ static void set_pci_devfn(Object *obj, Visitor *v, const 
char *name,
 if (!visit_type_str(v, name, , _err)) {
 error_free(local_err);
 local_err = NULL;
-visit_type_int32(v, name, , _err);
-if (local_err) {
-error_propagate(errp, local_err);
-} else if (value < -1 || value > 255) {
+if (!visit_type_int32(v, name, , errp)) {
+return;
+}
+if (value < -1 || value > 255) {
 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
name 

[PATCH v4 39/45] qapi: Smooth another visitor error checking pattern

2020-07-07 Thread Markus Armbruster
Convert

visit_type_FOO(v, ..., , );
...
if (err) {
...
}

to

visit_type_FOO(v, ..., , errp);
...
if (!ptr) {
...
}

for functions that set @ptr to non-null / null on success / error.

Eliminate error_propagate() that are now unnecessary.  Delete @err
that are now unused.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 block/nfs.c  |  7 ++-
 block/parallels.c|  7 ++-
 block/qcow.c |  7 ++-
 block/qcow2.c|  7 ++-
 block/qed.c  |  7 ++-
 block/rbd.c  |  7 ++-
 block/sheepdog.c |  6 ++
 block/ssh.c  |  7 ++-
 block/vdi.c  |  7 ++-
 block/vhdx.c |  7 ++-
 block/vpc.c  |  7 ++-
 hw/acpi/core.c   |  5 ++---
 hw/block/xen-block.c |  6 ++
 hw/core/numa.c   |  7 +++
 monitor/monitor.c| 21 +++--
 15 files changed, 36 insertions(+), 79 deletions(-)

diff --git a/block/nfs.c b/block/nfs.c
index b1718d125a..61a249a9fc 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -563,18 +563,15 @@ static BlockdevOptionsNfs 
*nfs_options_qdict_to_qapi(QDict *options,
 BlockdevOptionsNfs *opts = NULL;
 Visitor *v;
 const QDictEntry *e;
-Error *local_err = NULL;
 
 v = qobject_input_visitor_new_flat_confused(options, errp);
 if (!v) {
 return NULL;
 }
 
-visit_type_BlockdevOptionsNfs(v, NULL, , _err);
+visit_type_BlockdevOptionsNfs(v, NULL, , errp);
 visit_free(v);
-
-if (local_err) {
-error_propagate(errp, local_err);
+if (!opts) {
 return NULL;
 }
 
diff --git a/block/parallels.c b/block/parallels.c
index cb5259ac44..f489c0d4ba 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -625,7 +625,6 @@ static int coroutine_fn 
parallels_co_create_opts(BlockDriver *drv,
  Error **errp)
 {
 BlockdevCreateOptions *create_options = NULL;
-Error *local_err = NULL;
 BlockDriverState *bs = NULL;
 QDict *qdict;
 Visitor *v;
@@ -668,11 +667,9 @@ static int coroutine_fn 
parallels_co_create_opts(BlockDriver *drv,
 goto done;
 }
 
-visit_type_BlockdevCreateOptions(v, NULL, _options, _err);
+visit_type_BlockdevCreateOptions(v, NULL, _options, errp);
 visit_free(v);
-
-if (local_err) {
-error_propagate(errp, local_err);
+if (!create_options) {
 ret = -EINVAL;
 goto done;
 }
diff --git a/block/qcow.c b/block/qcow.c
index dca2a1fe7d..c22d1bf6b8 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -943,7 +943,6 @@ static int coroutine_fn qcow_co_create_opts(BlockDriver 
*drv,
 QDict *qdict;
 Visitor *v;
 const char *val;
-Error *local_err = NULL;
 int ret;
 
 static const QDictRenames opt_renames[] = {
@@ -995,11 +994,9 @@ static int coroutine_fn qcow_co_create_opts(BlockDriver 
*drv,
 goto fail;
 }
 
-visit_type_BlockdevCreateOptions(v, NULL, _options, _err);
+visit_type_BlockdevCreateOptions(v, NULL, _options, errp);
 visit_free(v);
-
-if (local_err) {
-error_propagate(errp, local_err);
+if (!create_options) {
 ret = -EINVAL;
 goto fail;
 }
diff --git a/block/qcow2.c b/block/qcow2.c
index a9137a535b..9ed2396c88 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3683,7 +3683,6 @@ static int coroutine_fn qcow2_co_create_opts(BlockDriver 
*drv,
 Visitor *v;
 BlockDriverState *bs = NULL;
 BlockDriverState *data_bs = NULL;
-Error *local_err = NULL;
 const char *val;
 int ret;
 
@@ -3779,11 +3778,9 @@ static int coroutine_fn qcow2_co_create_opts(BlockDriver 
*drv,
 goto finish;
 }
 
-visit_type_BlockdevCreateOptions(v, NULL, _options, _err);
+visit_type_BlockdevCreateOptions(v, NULL, _options, errp);
 visit_free(v);
-
-if (local_err) {
-error_propagate(errp, local_err);
+if (!create_options) {
 ret = -EINVAL;
 goto finish;
 }
diff --git a/block/qed.c b/block/qed.c
index e369fd360a..7fa7f880f6 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -729,7 +729,6 @@ static int coroutine_fn bdrv_qed_co_create_opts(BlockDriver 
*drv,
 QDict *qdict;
 Visitor *v;
 BlockDriverState *bs = NULL;
-Error *local_err = NULL;
 int ret;
 
 static const QDictRenames opt_renames[] = {
@@ -771,11 +770,9 @@ static int coroutine_fn 
bdrv_qed_co_create_opts(BlockDriver *drv,
 goto fail;
 }
 
-visit_type_BlockdevCreateOptions(v, NULL, _options, _err);
+visit_type_BlockdevCreateOptions(v, NULL, _options, errp);
 visit_free(v);
-
-if (local_err) {
-error_propagate(errp, local_err);
+if (!create_options) {
 ret = -EINVAL;
 goto fail;
 }
diff --git a/block/rbd.c b/block/rbd.c
index 617553b022..688074c64b 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -681,7 +681,6 @@ static int qemu_rbd_convert_options(QDict *options, 

[PATCH v4 45/45] hmp: Ignore Error objects where the return value suffices

2020-07-07 Thread Markus Armbruster
qdev_print_props() receives and throws away Error objects just to
check for object_property_get_str() and object_property_print()
failure.  Unnecessary, both return suitable values, so use those
instead.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 qdev-monitor.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/qdev-monitor.c b/qdev-monitor.c
index 96e52a9e81..31cc1f6564 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -694,22 +694,22 @@ static void qdev_print_props(Monitor *mon, DeviceState 
*dev, Property *props,
 if (!props)
 return;
 for (; props->name; props++) {
-Error *err = NULL;
 char *value;
 char *legacy_name = g_strdup_printf("legacy-%s", props->name);
+
 if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
-value = object_property_get_str(OBJECT(dev), legacy_name, );
+value = object_property_get_str(OBJECT(dev), legacy_name, NULL);
 } else {
-value = object_property_print(OBJECT(dev), props->name, true, 
);
+value = object_property_print(OBJECT(dev), props->name, true,
+  NULL);
 }
 g_free(legacy_name);
 
-if (err) {
-error_free(err);
+if (!value) {
 continue;
 }
 qdev_printf("%s = %s\n", props->name,
-value && *value ? value : "");
+*value ? value : "");
 g_free(value);
 }
 }
-- 
2.26.2




[PATCH v4 18/45] qapi: Use returned bool to check for failure, Coccinelle part

2020-07-07 Thread Markus Armbruster
The previous commit enables conversion of

visit_foo(..., );
if (err) {
...
}

to

if (!visit_foo(..., errp)) {
...
}

for visitor functions that now return true / false on success / error.
Coccinelle script:

@@
identifier fun =~ 
"check_list|input_type_enum|lv_start_struct|lv_type_bool|lv_type_int64|lv_type_str|lv_type_uint64|output_type_enum|parse_type_bool|parse_type_int64|parse_type_null|parse_type_number|parse_type_size|parse_type_str|parse_type_uint64|print_type_bool|print_type_int64|print_type_null|print_type_number|print_type_size|print_type_str|print_type_uint64|qapi_clone_start_alternate|qapi_clone_start_list|qapi_clone_start_struct|qapi_clone_type_bool|qapi_clone_type_int64|qapi_clone_type_null|qapi_clone_type_number|qapi_clone_type_str|qapi_clone_type_uint64|qapi_dealloc_start_list|qapi_dealloc_start_struct|qapi_dealloc_type_anything|qapi_dealloc_type_bool|qapi_dealloc_type_int64|qapi_dealloc_type_null|qapi_dealloc_type_number|qapi_dealloc_type_str|qapi_dealloc_type_uint64|qobject_input_check_list|qobject_input_check_struct|qobject_input_start_alternate|qobject_input_start_list|qobject_input_start_struct|qobject_input_type_any|qobject_input_type_bool|qobject_input_type_bool_keyval|qobject_input_type_int64|qobject_input_type_int64_keyval|qobject_input_type_null|qobject_input_type_number|qobject_input_type_number_keyval|qobject_input_type_size_keyval|qobject_input_type_str|qobject_input_type_str_keyval|qobject_input_type_uint64|qobject_input_type_uint64_keyval|qobject_output_start_list|qobject_output_start_struct|qobject_output_type_any|qobject_output_type_bool|qobject_output_type_int64|qobject_output_type_null|qobject_output_type_number|qobject_output_type_str|qobject_output_type_uint64|start_list|visit_check_list|visit_check_struct|visit_start_alternate|visit_start_list|visit_start_struct|visit_type_.*";
expression list args;
typedef Error;
Error *err;
@@
-fun(args, );
-if (err)
+if (!fun(args, ))
 {
 ...
 }

A few line breaks tidied up manually.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 accel/kvm/kvm-all.c  |  3 +--
 accel/tcg/tcg-all.c  |  3 +--
 backends/cryptodev.c |  3 +--
 backends/hostmem-file.c  |  3 +--
 backends/hostmem-memfd.c |  3 +--
 backends/hostmem.c   |  6 ++---
 backends/tpm/tpm_util.c  |  3 +--
 block/blkdebug.c |  3 +--
 block/nbd.c  |  3 +--
 block/sheepdog.c |  3 +--
 block/throttle-groups.c  |  6 ++---
 bootdevice.c |  3 +--
 hw/block/xen-block.c |  3 +--
 hw/core/machine.c|  3 +--
 hw/core/qdev-properties-system.c | 12 +++--
 hw/core/qdev-properties.c| 38 +++--
 hw/cpu/core.c|  6 ++---
 hw/gpio/aspeed_gpio.c|  3 +--
 hw/i386/pc.c |  3 +--
 hw/ide/qdev.c|  3 +--
 hw/intc/apic_common.c|  3 +--
 hw/mem/nvdimm.c  |  6 ++---
 hw/misc/aspeed_sdmc.c|  3 +--
 hw/misc/pca9552.c|  3 +--
 hw/misc/tmp105.c |  3 +--
 hw/misc/tmp421.c |  3 +--
 hw/net/ne2000-isa.c  |  3 +--
 hw/ppc/spapr_caps.c  |  9 +++
 hw/ppc/spapr_drc.c   | 10 +++-
 hw/s390x/css.c   |  3 +--
 hw/usb/dev-storage.c |  3 +--
 hw/vfio/pci-quirks.c |  3 +--
 hw/virtio/virtio-balloon.c   | 15 
 iothread.c   |  3 +--
 monitor/hmp-cmds.c   |  3 +--
 net/colo-compare.c   |  6 ++---
 net/dump.c   |  3 +--
 net/filter-buffer.c  |  3 +--
 qom/object.c | 42 +++-
 qom/object_interfaces.c  |  3 +--
 target/arm/cpu64.c   |  9 +++
 target/arm/monitor.c |  3 +--
 target/i386/cpu.c| 15 
 target/ppc/compat.c  |  3 +--
 target/s390x/cpu_models.c|  9 +++
 target/sparc/cpu.c   |  3 +--
 46 files changed, 97 insertions(+), 188 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index d54a8701d8..397669231d 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -3116,8 +3116,7 @@ static void kvm_set_kvm_shadow_mem(Object *obj, Visitor 
*v,
 Error *error = NULL;
 int64_t value;
 
-visit_type_int(v, name, , );
-if (error) {
+if (!visit_type_int(v, name, , )) {
 error_propagate(errp, error);
 return;
 }
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 3b4fda5640..d6b3d7fc07 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -185,8 +185,7 @@ static void tcg_set_tb_size(Object *obj, Visitor *v,
 

[PATCH v4 38/45] block/parallels: Simplify parallels_open() after previous commit

2020-07-07 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 block/parallels.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 180dd41e2b..cb5259ac44 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -842,6 +842,7 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
_err);
 g_free(buf);
 if (local_err != NULL) {
+error_propagate(errp, local_err);
 goto fail_options;
 }
 
@@ -872,15 +873,11 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 
 fail_format:
 error_setg(errp, "Image not in Parallels format");
+fail_options:
 ret = -EINVAL;
 fail:
 qemu_vfree(s->header);
 return ret;
-
-fail_options:
-error_propagate(errp, local_err);
-ret = -EINVAL;
-goto fail;
 }
 
 
-- 
2.26.2




[PATCH v4 31/45] qdev: Make functions taking Error ** return bool, not void

2020-07-07 Thread Markus Armbruster
See recent commit "error: Document Error API usage rules" for
rationale.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 include/hw/qdev-properties.h | 4 ++--
 hw/core/qdev-properties-system.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 944e3f2e0c..587e5b7d31 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -239,8 +239,8 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
 /*
  * Set properties between creation and realization.
  */
-void qdev_prop_set_drive_err(DeviceState *dev, const char *name,
- BlockBackend *value, Error **errp);
+bool qdev_prop_set_drive_err(DeviceState *dev, const char *name,
+ BlockBackend *value, Error **errp);
 
 /*
  * Set properties between creation and realization.
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 810831b1df..7d2387f22c 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -421,7 +421,7 @@ const PropertyInfo qdev_prop_audiodev = {
 .set = set_audiodev,
 };
 
-void qdev_prop_set_drive_err(DeviceState *dev, const char *name,
+bool qdev_prop_set_drive_err(DeviceState *dev, const char *name,
  BlockBackend *value, Error **errp)
 {
 const char *ref = "";
@@ -436,7 +436,7 @@ void qdev_prop_set_drive_err(DeviceState *dev, const char 
*name,
 }
 }
 
-object_property_set_str(OBJECT(dev), name, ref, errp);
+return object_property_set_str(OBJECT(dev), name, ref, errp);
 }
 
 void qdev_prop_set_drive(DeviceState *dev, const char *name,
-- 
2.26.2




[PATCH v4 16/45] hmp: Eliminate a variable in hmp_migrate_set_parameter()

2020-07-07 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 monitor/hmp-cmds.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 2b0b58a336..d7810cb564 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -1247,7 +1247,6 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict 
*qdict)
 MigrateSetParameters *p = g_new0(MigrateSetParameters, 1);
 uint64_t valuebw = 0;
 uint64_t cache_size;
-MultiFDCompression compress_type;
 Error *err = NULL;
 int val, ret;
 
@@ -1343,11 +1342,8 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict 
*qdict)
 break;
 case MIGRATION_PARAMETER_MULTIFD_COMPRESSION:
 p->has_multifd_compression = true;
-visit_type_MultiFDCompression(v, param, _type, );
-if (err) {
-break;
-}
-p->multifd_compression = compress_type;
+visit_type_MultiFDCompression(v, param, >multifd_compression,
+  );
 break;
 case MIGRATION_PARAMETER_MULTIFD_ZLIB_LEVEL:
 p->has_multifd_zlib_level = true;
-- 
2.26.2




[PATCH v4 36/45] error: Eliminate error_propagate() manually

2020-07-07 Thread Markus Armbruster
When all we do with an Error we receive into a local variable is
propagating to somewhere else, we can just as well receive it there
right away.  The previous two commits did that for sufficiently simple
cases with Coccinelle.  Do it for several more manually.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 block/replication.c|  4 +---
 blockdev.c | 16 --
 bootdevice.c   |  6 ++
 dump/dump.c|  7 ++
 hw/block/fdc.c |  8 +++
 hw/core/numa.c | 44 --
 hw/i386/x86.c  |  6 ++
 hw/intc/xive.c | 12 +++
 hw/ppc/spapr_cpu_core.c| 14 
 hw/s390x/s390-pci-bus.c|  4 +---
 hw/s390x/s390-virtio-ccw.c |  6 ++
 hw/s390x/sclp.c| 12 ---
 hw/usb/bus.c   |  4 +---
 qdev-monitor.c | 12 ---
 qga/commands-posix.c   |  4 +---
 qom/object.c   | 33 +++-
 qom/qom-qobject.c  |  5 +
 target/i386/cpu.c  | 19 +---
 18 files changed, 67 insertions(+), 149 deletions(-)

diff --git a/block/replication.c b/block/replication.c
index b844a09eb1..dcd430624e 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -367,7 +367,6 @@ static void reopen_backing_file(BlockDriverState *bs, bool 
writable,
 {
 BDRVReplicationState *s = bs->opaque;
 BlockReopenQueue *reopen_queue = NULL;
-Error *local_err = NULL;
 
 if (writable) {
 s->orig_hidden_read_only = bdrv_is_read_only(s->hidden_disk->bs);
@@ -392,8 +391,7 @@ static void reopen_backing_file(BlockDriverState *bs, bool 
writable,
 }
 
 if (reopen_queue) {
-bdrv_reopen_multiple(reopen_queue, _err);
-error_propagate(errp, local_err);
+bdrv_reopen_multiple(reopen_queue, errp);
 }
 
 bdrv_subtree_drained_end(s->hidden_disk->bs);
diff --git a/blockdev.c b/blockdev.c
index 1f254e7110..59b0b8ffaf 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -793,7 +793,6 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType 
block_default_type,
 bool read_only = false;
 bool copy_on_read;
 const char *filename;
-Error *local_err = NULL;
 int i;
 
 /* Change legacy command line options into QMP ones */
@@ -1003,13 +1002,10 @@ DriveInfo *drive_new(QemuOpts *all_opts, 
BlockInterfaceType block_default_type,
 }
 
 /* Actual block device init: Functionality shared with blockdev-add */
-blk = blockdev_init(filename, bs_opts, _err);
+blk = blockdev_init(filename, bs_opts, errp);
 bs_opts = NULL;
 if (!blk) {
-error_propagate(errp, local_err);
 goto fail;
-} else {
-assert(!local_err);
 }
 
 /* Create legacy DriveInfo */
@@ -3141,9 +3137,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
arg->has_copy_mode, arg->copy_mode,
arg->has_auto_finalize, arg->auto_finalize,
arg->has_auto_dismiss, arg->auto_dismiss,
-   _err);
+   errp);
 bdrv_unref(target_bs);
-error_propagate(errp, local_err);
 out:
 aio_context_release(aio_context);
 }
@@ -3171,7 +3166,6 @@ void qmp_blockdev_mirror(bool has_job_id, const char 
*job_id,
 AioContext *aio_context;
 AioContext *old_context;
 BlockMirrorBackingMode backing_mode = MIRROR_LEAVE_BACKING_CHAIN;
-Error *local_err = NULL;
 bool zero_target;
 int ret;
 
@@ -3213,8 +3207,7 @@ void qmp_blockdev_mirror(bool has_job_id, const char 
*job_id,
has_copy_mode, copy_mode,
has_auto_finalize, auto_finalize,
has_auto_dismiss, auto_dismiss,
-   _err);
-error_propagate(errp, local_err);
+   errp);
 out:
 aio_context_release(aio_context);
 }
@@ -3433,8 +3426,7 @@ void qmp_change_backing_file(const char *device,
 }
 
 if (ro) {
-bdrv_reopen_set_read_only(image_bs, true, _err);
-error_propagate(errp, local_err);
+bdrv_reopen_set_read_only(image_bs, true, errp);
 }
 
 out:
diff --git a/bootdevice.c b/bootdevice.c
index 8185402a5a..add4e3d2d1 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -303,15 +303,13 @@ static void device_set_bootindex(Object *obj, Visitor *v, 
const char *name,
 /* check whether bootindex is present in fw_boot_order list  */
 check_boot_index(boot_index, _err);
 if (local_err) {
-goto out;
+error_propagate(errp, local_err);
+return;
 }
 /* change bootindex to a new one */
 *prop->bootindex = boot_index;
 
 add_boot_device_path(*prop->bootindex, prop->dev, prop->suffix);
-
-out:
-error_propagate(errp, local_err);
 }
 
 static void property_release_bootindex(Object *obj, const char *name,
diff --git 

[PATCH v4 33/45] error: Avoid unnecessary error_propagate() after error_setg()

2020-07-07 Thread Markus Armbruster
Replace

error_setg(, ...);
error_propagate(errp, err);

by

error_setg(errp, ...);

Related pattern:

if (...) {
error_setg(, ...);
goto out;
}
...
 out:
error_propagate(errp, err);
return;

When all paths to label out are that way, replace by

if (...) {
error_setg(errp, ...);
return;
}

and delete the label along with the error_propagate().

When we have at most one other path that actually needs to propagate,
and maybe one at the end that where propagation is unnecessary, e.g.

foo(..., );
if (err) {
goto out;
}
...
bar(..., );
 out:
error_propagate(errp, err);
return;

move the error_propagate() to where it's needed, like

if (...) {
foo(..., );
error_propagate(errp, err);
return;
}
...
bar(..., errp);
return;

and transform the error_setg() as above.

In some places, the transformation results in obviously unnecessary
error_propagate().  The next few commits will eliminate them.

Bonus: the elimination of gotos will make later patches in this series
easier to review.

Candidates for conversion tracked down with this Coccinelle script:

@@
identifier err, errp;
expression list args;
@@
-error_setg(, args);
+error_setg(errp, args);
 ... when != err
 error_propagate(errp, err);

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 backends/cryptodev.c| 11 +++---
 backends/hostmem-file.c | 19 +++---
 backends/hostmem-memfd.c| 15 
 backends/hostmem.c  | 27 ++
 block/quorum.c  | 16 
 block/replication.c | 11 +++---
 block/throttle-groups.c | 22 +--
 block/vxhs.c|  9 ++---
 hw/acpi/core.c  | 14 +++
 hw/hyperv/vmbus.c   |  5 +--
 hw/i386/pc.c| 35 ++
 hw/mem/nvdimm.c | 17 -
 hw/mem/pc-dimm.c| 14 +++
 hw/misc/aspeed_sdmc.c   |  3 +-
 hw/ppc/rs6000_mc.c  |  9 ++---
 hw/ppc/spapr.c  | 73 -
 hw/ppc/spapr_pci.c  | 14 +++
 hw/s390x/ipl.c  | 23 +---
 hw/xen/xen_pt_config_init.c |  3 +-
 iothread.c  | 12 +++---
 net/colo-compare.c  | 20 --
 net/dump.c  | 10 ++---
 net/filter-buffer.c | 10 ++---
 qga/commands-win32.c| 19 +++---
 24 files changed, 169 insertions(+), 242 deletions(-)

diff --git a/backends/cryptodev.c b/backends/cryptodev.c
index 72b7077475..4de378532b 100644
--- a/backends/cryptodev.c
+++ b/backends/cryptodev.c
@@ -158,16 +158,15 @@ cryptodev_backend_set_queues(Object *obj, Visitor *v, 
const char *name,
 uint32_t value;
 
 if (!visit_type_uint32(v, name, , _err)) {
-goto out;
+error_propagate(errp, local_err);
+return;
 }
 if (!value) {
-error_setg(_err, "Property '%s.%s' doesn't take value '%"
-   PRIu32 "'", object_get_typename(obj), name, value);
-goto out;
+error_setg(errp, "Property '%s.%s' doesn't take value '%" PRIu32 "'",
+   object_get_typename(obj), name, value);
+return;
 }
 backend->conf.peers.queues = value;
-out:
-error_propagate(errp, local_err);
 }
 
 static void
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 320dffbaa9..a44f5a61ac 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -114,18 +114,16 @@ static void file_memory_backend_set_align(Object *o, 
Visitor *v,
 uint64_t val;
 
 if (host_memory_backend_mr_inited(backend)) {
-error_setg(_err, "cannot change property '%s' of %s",
-   name, object_get_typename(o));
-goto out;
+error_setg(errp, "cannot change property '%s' of %s", name,
+   object_get_typename(o));
+return;
 }
 
 if (!visit_type_size(v, name, , _err)) {
-goto out;
+error_propagate(errp, local_err);
+return;
 }
 fb->align = val;
-
- out:
-error_propagate(errp, local_err);
 }
 
 static bool file_memory_backend_get_pmem(Object *o, Error **errp)
@@ -139,7 +137,6 @@ static void file_memory_backend_set_pmem(Object *o, bool 
value, Error **errp)
 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
 
 if (host_memory_backend_mr_inited(backend)) {
-
 error_setg(errp, "cannot change property 'pmem' of %s.",
object_get_typename(o));
 return;
@@ -147,13 +144,9 @@ static void file_memory_backend_set_pmem(Object *o, bool 
value, Error **errp)
 
 #ifndef CONFIG_LIBPMEM
 if (value) {
-Error *local_err = NULL;
-
-error_setg(_err,
-   "Lack of libpmem support while setting the 'pmem=on'"
+error_setg(errp, "Lack of libpmem support while setting the 'pmem=on'"
  

[PATCH v4 27/45] qom: Make functions taking Error ** return bool, not void

2020-07-07 Thread Markus Armbruster
See recent commit "error: Document Error API usage rules" for
rationale.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 include/qom/object.h| 42 ++
 include/qom/object_interfaces.h | 12 +++-
 include/qom/qom-qobject.h   |  4 +-
 qom/object.c| 99 +
 qom/object_interfaces.c | 21 ---
 qom/qom-qobject.c   |  6 +-
 6 files changed, 122 insertions(+), 62 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index e60aa8dd5c..189f8ecbf6 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -703,7 +703,7 @@ Object *object_new_with_propv(const char *typename,
   Error **errp,
   va_list vargs);
 
-void object_apply_global_props(Object *obj, const GPtrArray *props,
+bool object_apply_global_props(Object *obj, const GPtrArray *props,
Error **errp);
 void object_set_machine_compat_props(GPtrArray *compat_props);
 void object_set_accelerator_compat_props(GPtrArray *compat_props);
@@ -798,8 +798,10 @@ void object_initialize(void *obj, size_t size, const char 
*typename);
  * strings. The propname of %NULL indicates the end of the property list.
  * If the object implements the user creatable interface, the object will
  * be marked complete once all the properties have been processed.
+ *
+ * Returns: %true on success, %false on failure.
  */
-void object_initialize_child_with_props(Object *parentobj,
+bool object_initialize_child_with_props(Object *parentobj,
  const char *propname,
  void *childobj, size_t size, const char *type,
  Error **errp, ...) QEMU_SENTINEL;
@@ -815,8 +817,10 @@ void object_initialize_child_with_props(Object *parentobj,
  * @vargs: list of property names and values
  *
  * See object_initialize_child() for documentation.
+ *
+ * Returns: %true on success, %false on failure.
  */
-void object_initialize_child_with_propsv(Object *parentobj,
+bool object_initialize_child_with_propsv(Object *parentobj,
   const char *propname,
   void *childobj, size_t size, const char *type,
   Error **errp, va_list vargs);
@@ -1197,8 +1201,10 @@ void object_unparent(Object *obj);
  * @errp: returns an error if this function fails
  *
  * Reads a property from a object.
+ *
+ * Returns: %true on success, %false on failure.
  */
-void object_property_get(Object *obj, const char *name, Visitor *v,
+bool object_property_get(Object *obj, const char *name, Visitor *v,
  Error **errp);
 
 /**
@@ -1208,8 +1214,10 @@ void object_property_get(Object *obj, const char *name, 
Visitor *v,
  * @errp: returns an error if this function fails
  *
  * Writes a string value to a property.
+ *
+ * Returns: %true on success, %false on failure.
  */
-void object_property_set_str(Object *obj, const char *name,
+bool object_property_set_str(Object *obj, const char *name,
  const char *value, Error **errp);
 
 /**
@@ -1237,8 +1245,9 @@ char *object_property_get_str(Object *obj, const char 
*name,
  * OBJ_PROP_LINK_STRONG bit, the old target object is
  * unreferenced, and a reference is added to the new target object.
  *
+ * Returns: %true on success, %false on failure.
  */
-void object_property_set_link(Object *obj, const char *name,
+bool object_property_set_link(Object *obj, const char *name,
   Object *value, Error **errp);
 
 /**
@@ -1261,8 +1270,10 @@ Object *object_property_get_link(Object *obj, const char 
*name,
  * @errp: returns an error if this function fails
  *
  * Writes a bool value to a property.
+ *
+ * Returns: %true on success, %false on failure.
  */
-void object_property_set_bool(Object *obj, const char *name,
+bool object_property_set_bool(Object *obj, const char *name,
   bool value, Error **errp);
 
 /**
@@ -1284,8 +1295,10 @@ bool object_property_get_bool(Object *obj, const char 
*name,
  * @errp: returns an error if this function fails
  *
  * Writes an integer value to a property.
+ *
+ * Returns: %true on success, %false on failure.
  */
-void object_property_set_int(Object *obj, const char *name,
+bool object_property_set_int(Object *obj, const char *name,
  int64_t value, Error **errp);
 
 /**
@@ -1307,8 +1320,10 @@ int64_t object_property_get_int(Object *obj, const char 
*name,
  * @errp: returns an error if this function fails
  *
  * Writes an unsigned integer value to a property.
+ *
+ * Returns: %true on success, %false on failure.
  */
-void object_property_set_uint(Object *obj, const char *name,
+bool object_property_set_uint(Object *obj, const char *name,
   uint64_t value, Error **errp);
 
 /**

[PATCH v4 42/45] error: Avoid error_propagate() after migrate_add_blocker()

2020-07-07 Thread Markus Armbruster
When migrate_add_blocker(blocker, ) is followed by
error_propagate(errp, err), we can often just as well do
migrate_add_blocker(..., errp).

Do that with this Coccinelle script:

@@
expression blocker, err, errp;
expression ret;
@@
-ret = migrate_add_blocker(blocker, );
-if (err) {
+ret = migrate_add_blocker(blocker, errp);
+if (ret < 0) {
 ... when != err;
-error_propagate(errp, err);
 ...
 }

@@
expression blocker, err, errp;
@@
-migrate_add_blocker(blocker, );
-if (err) {
+if (migrate_add_blocker(blocker, errp) < 0) {
 ... when != err;
-error_propagate(errp, err);
 ...
 }

Double-check @err is not used afterwards.  Dereferencing it would be
use after free, but checking whether it's null would be legitimate.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 block/parallels.c| 5 ++---
 block/qcow.c | 6 ++
 block/vdi.c  | 6 ++
 block/vhdx.c | 5 ++---
 block/vmdk.c | 6 ++
 block/vpc.c  | 5 ++---
 block/vvfat.c| 6 ++
 hw/display/virtio-gpu-base.c | 5 +
 hw/intc/arm_gic_kvm.c| 4 +---
 hw/intc/arm_gicv3_its_kvm.c  | 5 +
 hw/intc/arm_gicv3_kvm.c  | 4 +---
 hw/misc/ivshmem.c| 4 +---
 hw/scsi/vhost-scsi.c | 4 +---
 13 files changed, 20 insertions(+), 45 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index f489c0d4ba..3c22dfdc9d 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -859,9 +859,8 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 error_setg(>migration_blocker, "The Parallels format used by node '%s' "
"does not support live migration",
bdrv_get_device_or_node_name(bs));
-ret = migrate_add_blocker(s->migration_blocker, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+ret = migrate_add_blocker(s->migration_blocker, errp);
+if (ret < 0) {
 error_free(s->migration_blocker);
 goto fail;
 }
diff --git a/block/qcow.c b/block/qcow.c
index c22d1bf6b8..1e134f3445 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -121,7 +121,6 @@ static int qcow_open(BlockDriverState *bs, QDict *options, 
int flags,
 unsigned int len, i, shift;
 int ret;
 QCowHeader header;
-Error *local_err = NULL;
 QCryptoBlockOpenOptions *crypto_opts = NULL;
 unsigned int cflags = 0;
 QDict *encryptopts = NULL;
@@ -314,9 +313,8 @@ static int qcow_open(BlockDriverState *bs, QDict *options, 
int flags,
 error_setg(>migration_blocker, "The qcow format used by node '%s' "
"does not support live migration",
bdrv_get_device_or_node_name(bs));
-ret = migrate_add_blocker(s->migration_blocker, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+ret = migrate_add_blocker(s->migration_blocker, errp);
+if (ret < 0) {
 error_free(s->migration_blocker);
 goto fail;
 }
diff --git a/block/vdi.c b/block/vdi.c
index 0a60be773e..3a3df45f84 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -375,7 +375,6 @@ static int vdi_open(BlockDriverState *bs, QDict *options, 
int flags,
 VdiHeader header;
 size_t bmap_size;
 int ret;
-Error *local_err = NULL;
 QemuUUID uuid_link, uuid_parent;
 
 bs->file = bdrv_open_child(NULL, options, "file", bs, _of_bds,
@@ -496,9 +495,8 @@ static int vdi_open(BlockDriverState *bs, QDict *options, 
int flags,
 error_setg(>migration_blocker, "The vdi format used by node '%s' "
"does not support live migration",
bdrv_get_device_or_node_name(bs));
-ret = migrate_add_blocker(s->migration_blocker, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+ret = migrate_add_blocker(s->migration_blocker, errp);
+if (ret < 0) {
 error_free(s->migration_blocker);
 goto fail_free_bmap;
 }
diff --git a/block/vhdx.c b/block/vhdx.c
index eed9c3b860..1f9fca837d 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -1089,9 +1089,8 @@ static int vhdx_open(BlockDriverState *bs, QDict 
*options, int flags,
 error_setg(>migration_blocker, "The vhdx format used by node '%s' "
"does not support live migration",
bdrv_get_device_or_node_name(bs));
-ret = migrate_add_blocker(s->migration_blocker, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+ret = migrate_add_blocker(s->migration_blocker, errp);
+if (ret < 0) {
 error_free(s->migration_blocker);
 goto fail;
 }
diff --git a/block/vmdk.c b/block/vmdk.c
index 9a09193f3b..28cec50f38 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1263,7 +1263,6 @@ static int 

[PATCH v4 09/45] qemu-option: Factor out helper find_default_by_name()

2020-07-07 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Greg Kurz 
---
 util/qemu-option.c | 47 ++
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/util/qemu-option.c b/util/qemu-option.c
index 1df55bc881..14e211ddd8 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -142,6 +142,13 @@ static const QemuOptDesc *find_desc_by_name(const 
QemuOptDesc *desc,
 return NULL;
 }
 
+static const char *find_default_by_name(QemuOpts *opts, const char *name)
+{
+const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
+
+return desc ? desc->def_value_str : NULL;
+}
+
 void parse_option_size(const char *name, const char *value,
uint64_t *ret, Error **errp)
 {
@@ -270,7 +277,7 @@ static void qemu_opt_del_all(QemuOpts *opts, const char 
*name)
 const char *qemu_opt_get(QemuOpts *opts, const char *name)
 {
 QemuOpt *opt;
-const QemuOptDesc *desc;
+const char *def_val;
 
 if (opts == NULL) {
 return NULL;
@@ -278,9 +285,9 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name)
 
 opt = qemu_opt_find(opts, name);
 if (!opt) {
-desc = find_desc_by_name(opts->list->desc, name);
-if (desc && desc->def_value_str) {
-return desc->def_value_str;
+def_val = find_default_by_name(opts, name);
+if (def_val) {
+return def_val;
 }
 }
 return opt ? opt->str : NULL;
@@ -312,7 +319,7 @@ const char *qemu_opt_iter_next(QemuOptsIter *iter)
 char *qemu_opt_get_del(QemuOpts *opts, const char *name)
 {
 QemuOpt *opt;
-const QemuOptDesc *desc;
+const char *def_val;
 char *str = NULL;
 
 if (opts == NULL) {
@@ -321,9 +328,9 @@ char *qemu_opt_get_del(QemuOpts *opts, const char *name)
 
 opt = qemu_opt_find(opts, name);
 if (!opt) {
-desc = find_desc_by_name(opts->list->desc, name);
-if (desc && desc->def_value_str) {
-str = g_strdup(desc->def_value_str);
+def_val = find_default_by_name(opts, name);
+if (def_val) {
+str = g_strdup(def_val);
 }
 return str;
 }
@@ -349,7 +356,7 @@ static bool qemu_opt_get_bool_helper(QemuOpts *opts, const 
char *name,
  bool defval, bool del)
 {
 QemuOpt *opt;
-const QemuOptDesc *desc;
+const char *def_val;
 bool ret = defval;
 
 if (opts == NULL) {
@@ -358,9 +365,9 @@ static bool qemu_opt_get_bool_helper(QemuOpts *opts, const 
char *name,
 
 opt = qemu_opt_find(opts, name);
 if (opt == NULL) {
-desc = find_desc_by_name(opts->list->desc, name);
-if (desc && desc->def_value_str) {
-parse_option_bool(name, desc->def_value_str, , _abort);
+def_val = find_default_by_name(opts, name);
+if (def_val) {
+parse_option_bool(name, def_val, , _abort);
 }
 return ret;
 }
@@ -386,7 +393,7 @@ static uint64_t qemu_opt_get_number_helper(QemuOpts *opts, 
const char *name,
uint64_t defval, bool del)
 {
 QemuOpt *opt;
-const QemuOptDesc *desc;
+const char *def_val;
 uint64_t ret = defval;
 
 if (opts == NULL) {
@@ -395,9 +402,9 @@ static uint64_t qemu_opt_get_number_helper(QemuOpts *opts, 
const char *name,
 
 opt = qemu_opt_find(opts, name);
 if (opt == NULL) {
-desc = find_desc_by_name(opts->list->desc, name);
-if (desc && desc->def_value_str) {
-parse_option_number(name, desc->def_value_str, , _abort);
+def_val = find_default_by_name(opts, name);
+if (def_val) {
+parse_option_number(name, def_val, , _abort);
 }
 return ret;
 }
@@ -424,7 +431,7 @@ static uint64_t qemu_opt_get_size_helper(QemuOpts *opts, 
const char *name,
  uint64_t defval, bool del)
 {
 QemuOpt *opt;
-const QemuOptDesc *desc;
+const char *def_val;
 uint64_t ret = defval;
 
 if (opts == NULL) {
@@ -433,9 +440,9 @@ static uint64_t qemu_opt_get_size_helper(QemuOpts *opts, 
const char *name,
 
 opt = qemu_opt_find(opts, name);
 if (opt == NULL) {
-desc = find_desc_by_name(opts->list->desc, name);
-if (desc && desc->def_value_str) {
-parse_option_size(name, desc->def_value_str, , _abort);
+def_val = find_default_by_name(opts, name);
+if (def_val) {
+parse_option_size(name, def_val, , _abort);
 }
 return ret;
 }
-- 
2.26.2




[PATCH v4 35/45] error: Eliminate error_propagate() with Coccinelle, part 2

2020-07-07 Thread Markus Armbruster
When all we do with an Error we receive into a local variable is
propagating to somewhere else, we can just as well receive it there
right away.  The previous commit did that with a Coccinelle script I
consider fairly trustworthy.  This commit uses the same script with
the matching of return taken out, i.e. we convert

if (!foo(..., )) {
...
error_propagate(errp, err);
...
}

to

if (!foo(..., errp)) {
...
...
}

This is unsound: @err could still be read between afterwards.  I don't
know how to express "no read of @err without an intervening write" in
Coccinelle.  Instead, I manually double-checked for uses of @err.

Suboptimal line breaks tweaked manually.  qdev_realize() simplified
further to placate scripts/checkpatch.pl.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 block.c  |  6 ++
 block/blkdebug.c |  7 ++-
 block/blklogwrites.c |  3 +--
 block/blkverify.c|  3 +--
 block/crypto.c   |  4 +---
 block/file-posix.c   |  6 ++
 block/file-win32.c   |  6 ++
 block/gluster.c  |  4 +---
 block/iscsi.c|  3 +--
 block/nbd.c  |  8 ++--
 block/qcow2.c| 13 -
 block/raw-format.c   |  4 +---
 block/sheepdog.c |  8 ++--
 block/ssh.c  |  3 +--
 block/throttle.c |  4 +---
 block/vmdk.c |  4 +---
 block/vpc.c  |  3 +--
 block/vvfat.c|  3 +--
 blockdev.c   |  3 +--
 hw/intc/xics.c   |  4 +---
 hw/vfio/pci.c|  3 +--
 net/tap.c|  3 +--
 qom/object.c |  4 +---
 23 files changed, 32 insertions(+), 77 deletions(-)

diff --git a/block.c b/block.c
index 7f3091da63..60d2945c2c 100644
--- a/block.c
+++ b/block.c
@@ -1629,8 +1629,7 @@ static int bdrv_open_common(BlockDriverState *bs, 
BlockBackend *file,
 assert(options != NULL && bs->options != options);
 
 opts = qemu_opts_create(_runtime_opts, NULL, 0, _abort);
-if (!qemu_opts_absorb_qdict(opts, options, _err)) {
-error_propagate(errp, local_err);
+if (!qemu_opts_absorb_qdict(opts, options, errp)) {
 ret = -EINVAL;
 goto fail_opts;
 }
@@ -4090,8 +4089,7 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, 
BlockReopenQueue *queue,
 
 /* Process generic block layer options */
 opts = qemu_opts_create(_runtime_opts, NULL, 0, _abort);
-if (!qemu_opts_absorb_qdict(opts, reopen_state->options, _err)) {
-error_propagate(errp, local_err);
+if (!qemu_opts_absorb_qdict(opts, reopen_state->options, errp)) {
 ret = -EINVAL;
 goto error;
 }
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 3c0a9d45cc..9c08d8a005 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -359,7 +359,6 @@ static int blkdebug_parse_perm_list(uint64_t *dest, QDict 
*options,
 QObject *crumpled_subqdict = NULL;
 Visitor *v = NULL;
 BlockPermissionList *perm_list = NULL, *element;
-Error *local_err = NULL;
 
 *dest = 0;
 
@@ -375,8 +374,7 @@ static int blkdebug_parse_perm_list(uint64_t *dest, QDict 
*options,
 }
 
 v = qobject_input_visitor_new(crumpled_subqdict);
-if (!visit_type_BlockPermissionList(v, NULL, _list, _err)) {
-error_propagate(errp, local_err);
+if (!visit_type_BlockPermissionList(v, NULL, _list, errp)) {
 ret = -EINVAL;
 goto out;
 }
@@ -471,8 +469,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict 
*options, int flags,
 uint64_t align;
 
 opts = qemu_opts_create(_opts, NULL, 0, _abort);
-if (!qemu_opts_absorb_qdict(opts, options, _err)) {
-error_propagate(errp, local_err);
+if (!qemu_opts_absorb_qdict(opts, options, errp)) {
 ret = -EINVAL;
 goto out;
 }
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
index 0c93e926b1..57315f56b4 100644
--- a/block/blklogwrites.c
+++ b/block/blklogwrites.c
@@ -149,9 +149,8 @@ static int blk_log_writes_open(BlockDriverState *bs, QDict 
*options, int flags,
 bool log_append;
 
 opts = qemu_opts_create(_opts, NULL, 0, _abort);
-if (!qemu_opts_absorb_qdict(opts, options, _err)) {
+if (!qemu_opts_absorb_qdict(opts, options, errp)) {
 ret = -EINVAL;
-error_propagate(errp, local_err);
 goto fail;
 }
 
diff --git a/block/blkverify.c b/block/blkverify.c
index 666d626c57..4aed53ab59 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -116,8 +116,7 @@ static int blkverify_open(BlockDriverState *bs, QDict 
*options, int flags,
 int ret;
 
 opts = qemu_opts_create(_opts, NULL, 0, _abort);
-if (!qemu_opts_absorb_qdict(opts, options, _err)) {
-error_propagate(errp, local_err);
+if (!qemu_opts_absorb_qdict(opts, options, errp)) {
 ret = -EINVAL;
 goto fail;
 }
diff --git a/block/crypto.c b/block/crypto.c
index 301fa4da8e..5b2b97ea2f 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -212,7 +212,6 @@ static int 

[PATCH v4 28/45] qom: Use returned bool to check for failure, Coccinelle part

2020-07-07 Thread Markus Armbruster
The previous commit enables conversion of

foo(..., );
if (err) {
...
}

to

if (!foo(..., errp)) {
...
}

for QOM functions that now return true / false on success / error.
Coccinelle script:

@@
identifier fun = {
object_apply_global_props, object_initialize_child_with_props,
object_initialize_child_with_propsv, object_property_get,
object_property_get_bool, object_property_parse, object_property_set,
object_property_set_bool, object_property_set_int,
object_property_set_link, object_property_set_qobject,
object_property_set_str, object_property_set_uint, object_set_props,
object_set_propv, user_creatable_add_dict,
user_creatable_complete, user_creatable_del
};
expression list args, args2;
typedef Error;
Error *err;
@@
-fun(args, , args2);
-if (err)
+if (!fun(args, , args2))
 {
 ...
 }

Fails to convert hw/arm/armsse.c, because Coccinelle gets confused by
ARMSSE being used both as typedef and function-like macro there.
Convert manually.

Line breaks tidied up manually.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 hw/arm/armsse.c  | 52 +++-
 hw/arm/armv7m.c  | 20 ++
 hw/arm/aspeed_ast2600.c  |  5 ++--
 hw/arm/aspeed_soc.c  |  5 ++--
 hw/arm/bcm2835_peripherals.c |  5 ++--
 hw/arm/bcm2836.c | 12 -
 hw/arm/cubieboard.c  | 11 
 hw/arm/digic.c   |  4 +--
 hw/arm/nrf51_soc.c   |  8 +++---
 hw/arm/stm32f405_soc.c   |  7 +++--
 hw/arm/xlnx-zynqmp.c | 14 +-
 hw/block/xen-block.c | 15 +--
 hw/core/qdev.c   |  3 +--
 hw/i386/x86.c|  3 +--
 hw/ppc/pnv_psi.c |  4 +--
 hw/s390x/s390-pci-bus.c  |  3 +--
 hw/s390x/s390-virtio-ccw.c   |  3 +--
 hw/scsi/scsi-bus.c   |  3 +--
 hw/sd/aspeed_sdhci.c |  8 +++---
 hw/sd/ssi-sd.c   |  3 +--
 hw/virtio/virtio-rng.c   |  5 ++--
 qdev-monitor.c   |  3 +--
 qom/object.c | 15 ---
 qom/object_interfaces.c  |  6 ++---
 softmmu/vl.c |  4 +--
 target/arm/monitor.c |  3 +--
 target/i386/cpu.c| 11 +++-
 target/s390x/cpu_models.c|  3 +--
 28 files changed, 96 insertions(+), 142 deletions(-)

diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 1f8ce94ecc..c8604926a3 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -534,22 +534,20 @@ static void armsse_realize(DeviceState *dev, Error **errp)
  * later if necessary.
  */
 if (extract32(info->cpuwait_rst, i, 1)) {
-object_property_set_bool(cpuobj, "start-powered-off", true, );
-if (err) {
+if (!object_property_set_bool(cpuobj, "start-powered-off", true,
+  )) {
 error_propagate(errp, err);
 return;
 }
 }
 if (!s->cpu_fpu[i]) {
-object_property_set_bool(cpuobj, "vfp", false, );
-if (err) {
+if (!object_property_set_bool(cpuobj, "vfp", false, )) {
 error_propagate(errp, err);
 return;
 }
 }
 if (!s->cpu_dsp[i]) {
-object_property_set_bool(cpuobj, "dsp", false, );
-if (err) {
+if (!object_property_set_bool(cpuobj, "dsp", false, )) {
 error_propagate(errp, err);
 return;
 }
@@ -604,9 +602,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
 DeviceState *devs = DEVICE(splitter);
 int cpunum;
 
-object_property_set_int(splitter, "num-lines", info->num_cpus,
-);
-if (err) {
+if (!object_property_set_int(splitter, "num-lines",
+ info->num_cpus, )) {
 error_propagate(errp, err);
 return;
 }
@@ -658,9 +655,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
  * multiple lines, one for each of the PPCs within the ARMSSE and one
  * that will be an output from the ARMSSE to the system.
  */
-object_property_set_int(OBJECT(>sec_resp_splitter), "num-lines", 3,
-);
-if (err) {
+if (!object_property_set_int(OBJECT(>sec_resp_splitter),
+ "num-lines", 3, )) {
 error_propagate(errp, err);
 return;
 }
@@ -702,9 +698,9 @@ static void armsse_realize(DeviceState *dev, Error **errp)
 }
 
 /* We must OR together lines from the MPC splitters to go to the NVIC */
-object_property_set_int(OBJECT(>mpc_irq_orgate), 

[PATCH v4 30/45] qom: Make functions taking Error ** return bool, not 0/-1

2020-07-07 Thread Markus Armbruster
Just for consistency.  Also fix the example in object_set_props()'s
documentation.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 include/qom/object.h | 28 +++-
 qom/object.c | 14 +++---
 2 files changed, 18 insertions(+), 24 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 189f8ecbf6..04271ea5de 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -729,15 +729,13 @@ void object_apply_compat_props(Object *obj);
  *   Error *err = NULL;
  *   Object *obj = ...get / create object...;
  *
- *   obj = object_set_props(obj,
- *  ,
- *  "share", "yes",
- *  "mem-path", "/dev/shm/somefile",
- *  "prealloc", "yes",
- *  "size", "1048576",
- *  NULL);
- *
- *   if (!obj) {
+ *   if (!object_set_props(obj,
+ * ,
+ * "share", "yes",
+ * "mem-path", "/dev/shm/somefile",
+ * "prealloc", "yes",
+ * "size", "1048576",
+ * NULL)) {
  * error_reportf_err(err, "Cannot set properties: ");
  *   }
  *   
@@ -746,11 +744,9 @@ void object_apply_compat_props(Object *obj);
  * The returned object will have one stable reference maintained
  * for as long as it is present in the object hierarchy.
  *
- * Returns: -1 on error, 0 on success
+ * Returns: %true on success, %false on error.
  */
-int object_set_props(Object *obj,
- Error **errp,
- ...) QEMU_SENTINEL;
+bool object_set_props(Object *obj, Error **errp, ...) QEMU_SENTINEL;
 
 /**
  * object_set_propv:
@@ -760,11 +756,9 @@ int object_set_props(Object *obj,
  *
  * See object_set_props() for documentation.
  *
- * Returns: -1 on error, 0 on success
+ * Returns: %true on success, %false on error.
  */
-int object_set_propv(Object *obj,
- Error **errp,
- va_list vargs);
+bool object_set_propv(Object *obj, Error **errp, va_list vargs);
 
 /**
  * object_initialize:
diff --git a/qom/object.c b/qom/object.c
index 25c5ddb78f..97c4e0af07 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -557,7 +557,7 @@ bool object_initialize_child_with_propsv(Object *parentobj,
 object_initialize(childobj, size, type);
 obj = OBJECT(childobj);
 
-if (object_set_propv(obj, errp, vargs) < 0) {
+if (!object_set_propv(obj, errp, vargs)) {
 goto out;
 }
 
@@ -752,7 +752,7 @@ Object *object_new_with_propv(const char *typename,
 }
 obj = object_new_with_type(klass->type);
 
-if (object_set_propv(obj, errp, vargs) < 0) {
+if (!object_set_propv(obj, errp, vargs)) {
 goto error;
 }
 
@@ -780,12 +780,12 @@ Object *object_new_with_propv(const char *typename,
 }
 
 
-int object_set_props(Object *obj,
+bool object_set_props(Object *obj,
  Error **errp,
  ...)
 {
 va_list vargs;
-int ret;
+bool ret;
 
 va_start(vargs, errp);
 ret = object_set_propv(obj, errp, vargs);
@@ -795,7 +795,7 @@ int object_set_props(Object *obj,
 }
 
 
-int object_set_propv(Object *obj,
+bool object_set_propv(Object *obj,
  Error **errp,
  va_list vargs)
 {
@@ -809,12 +809,12 @@ int object_set_propv(Object *obj,
 g_assert(value != NULL);
 if (!object_property_parse(obj, propname, value, _err)) {
 error_propagate(errp, local_err);
-return -1;
+return false;
 }
 propname = va_arg(vargs, char *);
 }
 
-return 0;
+return true;
 }
 
 
-- 
2.26.2




[PATCH v4 04/45] qdev: Use returned bool to check for qdev_realize() etc. failure

2020-07-07 Thread Markus Armbruster
Convert

foo(..., );
if (err) {
...
}

to

if (!foo(..., )) {
...
}

for qdev_realize(), qdev_realize_and_unref(), qbus_realize() and their
wrappers isa_realize_and_unref(), pci_realize_and_unref(),
sysbus_realize(), sysbus_realize_and_unref(), usb_realize_and_unref().
Coccinelle script:

@@
identifier fun = {
isa_realize_and_unref, pci_realize_and_unref, qbus_realize,
qdev_realize, qdev_realize_and_unref, sysbus_realize,
sysbus_realize_and_unref, usb_realize_and_unref
};
expression list args, args2;
typedef Error;
Error *err;
@@
-fun(args, , args2);
-if (err)
+if (!fun(args, , args2))
 {
 ...
 }

Chokes on hw/arm/musicpal.c's lcd_refresh() with the unhelpful error
message "no position information".  Nothing to convert there; skipped.

Fails to convert hw/arm/armsse.c, because Coccinelle gets confused by
ARMSSE being used both as typedef and function-like macro there.
Converted manually.

A few line breaks tidied up manually.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Greg Kurz 
---
 hw/arm/allwinner-a10.c  | 15 +++
 hw/arm/armsse.c | 78 +++--
 hw/arm/armv7m.c |  9 ++--
 hw/arm/aspeed_ast2600.c | 51 +++--
 hw/arm/aspeed_soc.c | 45 +++
 hw/arm/bcm2835_peripherals.c| 45 +++
 hw/arm/bcm2836.c|  9 ++--
 hw/arm/cubieboard.c |  3 +-
 hw/arm/digic.c  |  9 ++--
 hw/arm/digic_boards.c   |  3 +-
 hw/arm/fsl-imx25.c  | 33 +-
 hw/arm/fsl-imx31.c  | 24 --
 hw/arm/fsl-imx6.c   | 36 +--
 hw/arm/msf2-soc.c   | 15 +++
 hw/arm/nrf51_soc.c  | 18 +++-
 hw/arm/stm32f205_soc.c  | 21 +++--
 hw/arm/stm32f405_soc.c  | 24 --
 hw/arm/xlnx-zynqmp.c| 45 +++
 hw/block/fdc.c  |  3 +-
 hw/block/xen-block.c|  3 +-
 hw/char/serial-pci-multi.c  |  3 +-
 hw/char/serial-pci.c|  3 +-
 hw/char/serial.c|  6 +--
 hw/core/cpu.c   |  3 +-
 hw/cpu/a15mpcore.c  |  3 +-
 hw/cpu/a9mpcore.c   | 15 +++
 hw/cpu/arm11mpcore.c| 12 ++---
 hw/cpu/realview_mpcore.c|  6 +--
 hw/display/virtio-gpu-pci.c |  4 +-
 hw/display/virtio-vga.c |  3 +-
 hw/intc/armv7m_nvic.c   |  6 +--
 hw/intc/pnv_xive.c  |  6 +--
 hw/intc/realview_gic.c  |  3 +-
 hw/intc/spapr_xive.c|  6 +--
 hw/intc/xics.c  |  3 +-
 hw/intc/xive.c  |  3 +-
 hw/isa/piix4.c  |  3 +-
 hw/microblaze/xlnx-zynqmp-pmu.c |  6 +--
 hw/mips/cps.c   | 12 ++---
 hw/misc/macio/cuda.c|  3 +-
 hw/misc/macio/macio.c   | 18 +++-
 hw/misc/macio/pmu.c |  3 +-
 hw/pci-host/pnv_phb3.c  |  9 ++--
 hw/pci-host/pnv_phb4.c  |  3 +-
 hw/pci-host/pnv_phb4_pec.c  |  3 +-
 hw/ppc/e500.c   |  3 +-
 hw/ppc/pnv.c| 39 ++---
 hw/ppc/pnv_core.c   |  3 +-
 hw/ppc/pnv_psi.c|  6 +--
 hw/ppc/spapr_cpu_core.c |  3 +-
 hw/ppc/spapr_irq.c  |  3 +-
 hw/riscv/opentitan.c|  6 +--
 hw/riscv/sifive_e.c |  3 +-
 hw/riscv/sifive_u.c |  3 +-
 hw/s390x/event-facility.c   | 10 ++---
 hw/s390x/s390-pci-bus.c |  3 +-
 hw/s390x/sclp.c |  3 +-
 hw/s390x/virtio-ccw-crypto.c|  3 +-
 hw/s390x/virtio-ccw-rng.c   |  3 +-
 hw/scsi/scsi-bus.c  |  3 +-
 hw/sd/aspeed_sdhci.c|  3 +-
 hw/sd/ssi-sd.c  |  3 +-
 hw/usb/bus.c|  3 +-
 hw/virtio/virtio-rng-pci.c  |  3 +-
 qdev-monitor.c  |  3 +-
 65 files changed, 248 insertions(+), 495 deletions(-)

diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index 52e0d83760..e1acffe5f6 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -74,14 +74,12 @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
 SysBusDevice *sysbusdev;
 Error *err = NULL;
 
-qdev_realize(DEVICE(>cpu), NULL, );
-if (err != NULL) {
+if (!qdev_realize(DEVICE(>cpu), NULL, )) {
 error_propagate(errp, err);
 return;
 }
 
-sysbus_realize(SYS_BUS_DEVICE(>intc), );
-if (err != NULL) {
+if (!sysbus_realize(SYS_BUS_DEVICE(>intc), )) {
 error_propagate(errp, err);
 return;
 }
@@ -93,8 +91,7 @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in(DEVICE(>cpu), ARM_CPU_FIQ));
 qdev_pass_gpios(DEVICE(>intc), dev, NULL);
 
-   

[PATCH v4 32/45] qdev: Use returned bool to check for failure, Coccinelle part

2020-07-07 Thread Markus Armbruster
The previous commit enables conversion of

qdev_prop_set_drive_err(..., );
if (err) {
...
}

to

if (!qdev_prop_set_drive_err(..., errp)) {
...
}

Coccinelle script:

@@
identifier fun = qdev_prop_set_drive_err;
expression list args;
typedef Error;
Error *err;
@@
-fun(args, );
-if (err)
+if (!fun(args, ))
 {
 ...
 }

One line break tidied up manually.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 hw/scsi/scsi-bus.c | 3 +--
 hw/sd/sd.c | 3 +--
 hw/sd/ssi-sd.c | 5 ++---
 3 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index a83939f7d0..38b66a2f45 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -277,8 +277,7 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, 
BlockBackend *blk,
 if (serial && object_property_find(OBJECT(dev), "serial", NULL)) {
 qdev_prop_set_string(dev, "serial", serial);
 }
-qdev_prop_set_drive_err(dev, "drive", blk, );
-if (err) {
+if (!qdev_prop_set_drive_err(dev, "drive", blk, )) {
 error_propagate(errp, err);
 object_unparent(OBJECT(dev));
 return NULL;
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 97a9d32964..5137168d66 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -706,8 +706,7 @@ SDState *sd_init(BlockBackend *blk, bool is_spi)
 
 obj = object_new(TYPE_SD_CARD);
 dev = DEVICE(obj);
-qdev_prop_set_drive_err(dev, "drive", blk, );
-if (err) {
+if (!qdev_prop_set_drive_err(dev, "drive", blk, )) {
 error_reportf_err(err, "sd_init failed: ");
 return NULL;
 }
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index ad825220e2..3717b2e721 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -254,9 +254,8 @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
 dinfo = drive_get_next(IF_SD);
 carddev = qdev_new(TYPE_SD_CARD);
 if (dinfo) {
-qdev_prop_set_drive_err(carddev, "drive", blk_by_legacy_dinfo(dinfo),
-);
-if (err) {
+if (!qdev_prop_set_drive_err(carddev, "drive",
+ blk_by_legacy_dinfo(dinfo), )) {
 goto fail;
 }
 }
-- 
2.26.2




[PATCH v4 07/45] qemu-option: Check return value instead of @err where convenient

2020-07-07 Thread Markus Armbruster
Convert uses like

opts = qemu_opts_create(..., );
if (err) {
...
}

to

opts = qemu_opts_create(..., errp);
if (!opts) {
...
}

Eliminate error_propagate() that are now unnecessary.  Delete @err
that are now unused.

Note that we can't drop parallels_open()'s error_propagate() here.  We
continue to execute it even in the converted case.  It's a no-op then:
local_err is null.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Greg Kurz 
---
 block/parallels.c  |  4 ++--
 blockdev.c |  5 ++---
 qdev-monitor.c |  5 ++---
 util/qemu-config.c | 10 --
 util/qemu-option.c | 12 
 5 files changed, 14 insertions(+), 22 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 63a1cde8af..f26f03c926 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -824,8 +824,8 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 }
 }
 
-opts = qemu_opts_create(_runtime_opts, NULL, 0, _err);
-if (local_err != NULL) {
+opts = qemu_opts_create(_runtime_opts, NULL, 0, errp);
+if (!opts) {
 goto fail_options;
 }
 
diff --git a/blockdev.c b/blockdev.c
index 31d5eaf6bf..b52ed9de86 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -504,9 +504,8 @@ static BlockBackend *blockdev_init(const char *file, QDict 
*bs_opts,
 /* Check common options by copying from bs_opts to opts, all other options
  * stay in bs_opts for processing by bdrv_open(). */
 id = qdict_get_try_str(bs_opts, "id");
-opts = qemu_opts_create(_common_drive_opts, id, 1, );
-if (error) {
-error_propagate(errp, error);
+opts = qemu_opts_create(_common_drive_opts, id, 1, errp);
+if (!opts) {
 goto err_no_opts;
 }
 
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 13a13a811a..079cb6001e 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -799,9 +799,8 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error 
**errp)
 QemuOpts *opts;
 DeviceState *dev;
 
-opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, errp);
+if (!opts) {
 return;
 }
 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
diff --git a/util/qemu-config.c b/util/qemu-config.c
index 772f5a219e..c0d0e9b8ef 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -493,9 +493,8 @@ static void config_parse_qdict_section(QDict *options, 
QemuOptsList *opts,
 goto out;
 }
 
-subopts = qemu_opts_create(opts, NULL, 0, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+subopts = qemu_opts_create(opts, NULL, 0, errp);
+if (!subopts) {
 goto out;
 }
 
@@ -538,10 +537,9 @@ static void config_parse_qdict_section(QDict *options, 
QemuOptsList *opts,
 }
 
 opt_name = g_strdup_printf("%s.%u", opts->name, i++);
-subopts = qemu_opts_create(opts, opt_name, 1, _err);
+subopts = qemu_opts_create(opts, opt_name, 1, errp);
 g_free(opt_name);
-if (local_err) {
-error_propagate(errp, local_err);
+if (!subopts) {
 goto out;
 }
 
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 0ebfd97a98..fd1fd23521 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -670,11 +670,9 @@ void qemu_opts_set(QemuOptsList *list, const char *id,
const char *name, const char *value, Error **errp)
 {
 QemuOpts *opts;
-Error *local_err = NULL;
 
-opts = qemu_opts_create(list, id, 1, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+opts = qemu_opts_create(list, id, 1, errp);
+if (!opts) {
 return;
 }
 qemu_opt_set(opts, name, value, errp);
@@ -1012,10 +1010,8 @@ QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const 
QDict *qdict,
 QemuOpts *opts;
 const QDictEntry *entry;
 
-opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1,
-_err);
-if (local_err) {
-error_propagate(errp, local_err);
+opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1, errp);
+if (!opts) {
 return NULL;
 }
 
-- 
2.26.2




[PATCH v4 13/45] qemu-option: Make functions taking Error ** return bool, not void

2020-07-07 Thread Markus Armbruster
See recent commit "error: Document Error API usage rules" for
rationale.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 include/qemu/option.h | 16 
 blockdev.c|  5 ++-
 util/qemu-option.c| 92 +--
 3 files changed, 64 insertions(+), 49 deletions(-)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index eb4097889d..2d77b10f90 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -30,7 +30,7 @@
 
 const char *get_opt_value(const char *p, char **value);
 
-void parse_option_size(const char *name, const char *value,
+bool parse_option_size(const char *name, const char *value,
uint64_t *ret, Error **errp);
 bool has_help_option(const char *param);
 
@@ -80,11 +80,11 @@ uint64_t qemu_opt_get_number_del(QemuOpts *opts, const char 
*name,
 uint64_t qemu_opt_get_size_del(QemuOpts *opts, const char *name,
uint64_t defval);
 int qemu_opt_unset(QemuOpts *opts, const char *name);
-void qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
+bool qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
   Error **errp);
-void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
+bool qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
Error **errp);
-void qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val,
+bool qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val,
  Error **errp);
 typedef int (*qemu_opt_loopfunc)(void *opaque,
  const char *name, const char *value,
@@ -106,13 +106,13 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char 
*id,
int fail_if_exists, Error **errp);
 void qemu_opts_reset(QemuOptsList *list);
 void qemu_opts_loc_restore(QemuOpts *opts);
-void qemu_opts_set(QemuOptsList *list, const char *id,
+bool qemu_opts_set(QemuOptsList *list, const char *id,
const char *name, const char *value, Error **errp);
 const char *qemu_opts_id(QemuOpts *opts);
 void qemu_opts_set_id(QemuOpts *opts, char *id);
 void qemu_opts_del(QemuOpts *opts);
-void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp);
-void qemu_opts_do_parse(QemuOpts *opts, const char *params,
+bool qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp);
+bool qemu_opts_do_parse(QemuOpts *opts, const char *params,
 const char *firstname, Error **errp);
 QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
   bool permit_abbrev);
@@ -125,7 +125,7 @@ QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const 
QDict *qdict,
 QDict *qemu_opts_to_qdict_filtered(QemuOpts *opts, QDict *qdict,
QemuOptsList *list, bool del);
 QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
-void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp);
+bool qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp);
 
 typedef int (*qemu_opts_loopfunc)(void *opaque, QemuOpts *opts, Error **errp);
 int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func,
diff --git a/blockdev.c b/blockdev.c
index b52ed9de86..39e12a62b3 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -705,7 +705,7 @@ BlockDriverState *bdrv_next_monitor_owned(BlockDriverState 
*bs)
   : QTAILQ_FIRST(_bdrv_states);
 }
 
-static void qemu_opt_rename(QemuOpts *opts, const char *from, const char *to,
+static bool qemu_opt_rename(QemuOpts *opts, const char *from, const char *to,
 Error **errp)
 {
 const char *value;
@@ -715,7 +715,7 @@ static void qemu_opt_rename(QemuOpts *opts, const char 
*from, const char *to,
 if (qemu_opt_find(opts, to)) {
 error_setg(errp, "'%s' and its alias '%s' can't be used at the "
"same time", to, from);
-return;
+return false;
 }
 }
 
@@ -724,6 +724,7 @@ static void qemu_opt_rename(QemuOpts *opts, const char 
*from, const char *to,
 qemu_opt_set(opts, to, value, _abort);
 qemu_opt_unset(opts, from);
 }
+return true;
 }
 
 QemuOptsList qemu_legacy_drive_opts = {
diff --git a/util/qemu-option.c b/util/qemu-option.c
index d8233b3b35..2f4fb62120 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -96,7 +96,7 @@ const char *get_opt_value(const char *p, char **value)
 return offset;
 }
 
-static void parse_option_bool(const char *name, const char *value, bool *ret,
+static bool parse_option_bool(const char *name, const char *value, bool *ret,
   Error **errp)
 {
 if (!strcmp(value, "on")) {
@@ -106,10 +106,12 @@ static void parse_option_bool(const char *name, const 
char *value, bool *ret,
 } else 

[PATCH v4 24/45] qom: Don't handle impossible object_property_get_link() failure

2020-07-07 Thread Markus Armbruster
Don't handle object_property_get_link() failure that can't happen
unless the programmer screwed up, pass _abort.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/arm/bcm2835_peripherals.c |  7 +--
 hw/arm/bcm2836.c |  7 +--
 hw/display/bcm2835_fb.c  |  8 +---
 hw/dma/bcm2835_dma.c |  9 +
 hw/gpio/bcm2835_gpio.c   | 15 ++-
 hw/intc/nios2_iic.c  |  8 +---
 hw/misc/bcm2835_mbox.c   |  9 +
 hw/misc/bcm2835_property.c   | 17 ++---
 hw/usb/hcd-dwc2.c|  9 +
 9 files changed, 11 insertions(+), 78 deletions(-)

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index 2df81168e4..beade39e41 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -134,12 +134,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, 
Error **errp)
 uint64_t ram_size, vcram_size;
 int n;
 
-obj = object_property_get_link(OBJECT(dev), "ram", );
-if (obj == NULL) {
-error_setg(errp, "%s: required ram link not found: %s",
-   __func__, error_get_pretty(err));
-return;
-}
+obj = object_property_get_link(OBJECT(dev), "ram", _abort);
 
 ram = MEMORY_REGION(obj);
 ram_size = memory_region_size(ram);
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
index 1a7560ef30..70ca2f0d9a 100644
--- a/hw/arm/bcm2836.c
+++ b/hw/arm/bcm2836.c
@@ -77,12 +77,7 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
 
 /* common peripherals from bcm2835 */
 
-obj = object_property_get_link(OBJECT(dev), "ram", );
-if (obj == NULL) {
-error_setg(errp, "%s: required ram link not found: %s",
-   __func__, error_get_pretty(err));
-return;
-}
+obj = object_property_get_link(OBJECT(dev), "ram", _abort);
 
 object_property_add_const_link(OBJECT(>peripherals), "ram", obj);
 
diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c
index 7c0e5eef2d..986c994522 100644
--- a/hw/display/bcm2835_fb.c
+++ b/hw/display/bcm2835_fb.c
@@ -405,7 +405,6 @@ static void bcm2835_fb_reset(DeviceState *dev)
 static void bcm2835_fb_realize(DeviceState *dev, Error **errp)
 {
 BCM2835FBState *s = BCM2835_FB(dev);
-Error *err = NULL;
 Object *obj;
 
 if (s->vcram_base == 0) {
@@ -413,12 +412,7 @@ static void bcm2835_fb_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-obj = object_property_get_link(OBJECT(dev), "dma-mr", );
-if (obj == NULL) {
-error_setg(errp, "%s: required dma-mr link not found: %s",
-   __func__, error_get_pretty(err));
-return;
-}
+obj = object_property_get_link(OBJECT(dev), "dma-mr", _abort);
 
 /* Fill in the parts of initial_config that are not set by QOM properties 
*/
 s->initial_config.xres_virtual = s->initial_config.xres;
diff --git a/hw/dma/bcm2835_dma.c b/hw/dma/bcm2835_dma.c
index 4cd9dab745..eb0002a2b9 100644
--- a/hw/dma/bcm2835_dma.c
+++ b/hw/dma/bcm2835_dma.c
@@ -376,16 +376,9 @@ static void bcm2835_dma_reset(DeviceState *dev)
 static void bcm2835_dma_realize(DeviceState *dev, Error **errp)
 {
 BCM2835DMAState *s = BCM2835_DMA(dev);
-Error *err = NULL;
 Object *obj;
 
-obj = object_property_get_link(OBJECT(dev), "dma-mr", );
-if (obj == NULL) {
-error_setg(errp, "%s: required dma-mr link not found: %s",
-   __func__, error_get_pretty(err));
-return;
-}
-
+obj = object_property_get_link(OBJECT(dev), "dma-mr", _abort);
 s->dma_mr = MEMORY_REGION(obj);
 address_space_init(>dma_as, s->dma_mr, TYPE_BCM2835_DMA "-memory");
 
diff --git a/hw/gpio/bcm2835_gpio.c b/hw/gpio/bcm2835_gpio.c
index 91ce3d10cc..abdddbc67c 100644
--- a/hw/gpio/bcm2835_gpio.c
+++ b/hw/gpio/bcm2835_gpio.c
@@ -312,22 +312,11 @@ static void bcm2835_gpio_realize(DeviceState *dev, Error 
**errp)
 {
 BCM2835GpioState *s = BCM2835_GPIO(dev);
 Object *obj;
-Error *err = NULL;
 
-obj = object_property_get_link(OBJECT(dev), "sdbus-sdhci", );
-if (obj == NULL) {
-error_setg(errp, "%s: required sdhci link not found: %s",
-__func__, error_get_pretty(err));
-return;
-}
+obj = object_property_get_link(OBJECT(dev), "sdbus-sdhci", _abort);
 s->sdbus_sdhci = SD_BUS(obj);
 
-obj = object_property_get_link(OBJECT(dev), "sdbus-sdhost", );
-if (obj == NULL) {
-error_setg(errp, "%s: required sdhost link not found: %s",
-__func__, error_get_pretty(err));
-return;
-}
+obj = object_property_get_link(OBJECT(dev), "sdbus-sdhost", _abort);
 s->sdbus_sdhost = SD_BUS(obj);
 }
 
diff --git a/hw/intc/nios2_iic.c b/hw/intc/nios2_iic.c
index 3a5d86c2a4..1a5df8c89a 100644
--- a/hw/intc/nios2_iic.c
+++ b/hw/intc/nios2_iic.c
@@ -66,14 +66,8 @@ static void altera_iic_init(Object *obj)
 static void 

[PATCH v4 06/45] virtio-crypto-pci: Tidy up virtio_crypto_pci_realize()

2020-07-07 Thread Markus Armbruster
virtio_crypto_pci_realize() continues after realization of its
"virtio-crypto-device" fails.  Only an object_property_set_link()
follows; looks harmless to me.  Tidy up anyway: return after failure,
just like virtio_rng_pci_realize() does.

Cc: "Gonglei (Arei)" 
Cc: Michael S. Tsirkin 
Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Gonglei < arei.gong...@huawei.com>
---
 hw/virtio/virtio-crypto-pci.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-crypto-pci.c b/hw/virtio/virtio-crypto-pci.c
index 72be531c95..0755722288 100644
--- a/hw/virtio/virtio-crypto-pci.c
+++ b/hw/virtio/virtio-crypto-pci.c
@@ -54,7 +54,9 @@ static void virtio_crypto_pci_realize(VirtIOPCIProxy 
*vpci_dev, Error **errp)
 }
 
 virtio_pci_force_virtio_1(vpci_dev);
-qdev_realize(vdev, BUS(_dev->bus), errp);
+if (!qdev_realize(vdev, BUS(_dev->bus), errp)) {
+return;
+}
 object_property_set_link(OBJECT(vcrypto),
  OBJECT(vcrypto->vdev.conf.cryptodev), "cryptodev",
  NULL);
-- 
2.26.2




[PATCH v4 12/45] qemu-option: Replace opt_set() by cleaner opt_validate()

2020-07-07 Thread Markus Armbruster
opt_set() frees its argument @value on failure.  Slightly unclean;
functions ideally do nothing on failure.

To tidy this up, move opt_create() from opt_set() into its callers,
along with the cleanup.  Rename opt_set() to opt_validate(), noting
its similarity to qemu_opts_validate().  Drop redundant parameter
@opts; use opt->opts instead.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 util/qemu-option.c | 35 +++
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/util/qemu-option.c b/util/qemu-option.c
index 1023fe7527..d8233b3b35 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -516,36 +516,39 @@ static QemuOpt *opt_create(QemuOpts *opts, const char 
*name, char *value,
 return opt;
 }
 
-static void opt_set(QemuOpts *opts, const char *name, char *value,
-bool prepend, bool *help_wanted, Error **errp)
+static bool opt_validate(QemuOpt *opt, bool *help_wanted,
+ Error **errp)
 {
-QemuOpt *opt;
 const QemuOptDesc *desc;
 Error *local_err = NULL;
 
-desc = find_desc_by_name(opts->list->desc, name);
-if (!desc && !opts_accepts_any(opts)) {
-g_free(value);
-error_setg(errp, QERR_INVALID_PARAMETER, name);
-if (help_wanted && is_help_option(name)) {
+desc = find_desc_by_name(opt->opts->list->desc, opt->name);
+if (!desc && !opts_accepts_any(opt->opts)) {
+error_setg(errp, QERR_INVALID_PARAMETER, opt->name);
+if (help_wanted && is_help_option(opt->name)) {
 *help_wanted = true;
 }
-return;
+return false;
 }
 
-opt = opt_create(opts, name, value, prepend);
 opt->desc = desc;
 qemu_opt_parse(opt, _err);
 if (local_err) {
 error_propagate(errp, local_err);
-qemu_opt_del(opt);
+return false;
 }
+
+return true;
 }
 
 void qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
   Error **errp)
 {
-opt_set(opts, name, g_strdup(value), false, NULL, errp);
+QemuOpt *opt = opt_create(opts, name, g_strdup(value), false);
+
+if (!opt_validate(opt, NULL, errp)) {
+qemu_opt_del(opt);
+}
 }
 
 void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
@@ -817,9 +820,9 @@ static void opts_do_parse(QemuOpts *opts, const char 
*params,
   const char *firstname, bool prepend,
   bool *help_wanted, Error **errp)
 {
-Error *local_err = NULL;
 char *option, *value;
 const char *p;
+QemuOpt *opt;
 
 for (p = params; *p;) {
 p = get_opt_name_value(p, firstname, , );
@@ -831,10 +834,10 @@ static void opts_do_parse(QemuOpts *opts, const char 
*params,
 continue;
 }
 
-opt_set(opts, option, value, prepend, help_wanted, _err);
+opt = opt_create(opts, option, value, prepend);
 g_free(option);
-if (local_err) {
-error_propagate(errp, local_err);
+if (!opt_validate(opt, help_wanted, errp)) {
+qemu_opt_del(opt);
 return;
 }
 }
-- 
2.26.2




[PATCH v4 14/45] qemu-option: Use returned bool to check for failure

2020-07-07 Thread Markus Armbruster
The previous commit enables conversion of

foo(..., );
if (err) {
...
}

to

if (!foo(..., )) {
...
}

for QemuOpts functions that now return true / false on success /
error.  Coccinelle script:

@@
identifier fun = {
opts_do_parse, parse_option_bool, parse_option_number,
parse_option_size, qemu_opt_parse, qemu_opt_rename, qemu_opt_set,
qemu_opt_set_bool, qemu_opt_set_number, qemu_opts_absorb_qdict,
qemu_opts_do_parse, qemu_opts_from_qdict_entry, qemu_opts_set,
qemu_opts_validate
};
expression list args, args2;
typedef Error;
Error *err;
@@
-fun(args, , args2);
-if (err)
+if (!fun(args, , args2))
 {
 ...
 }

A few line breaks tidied up manually.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 block.c   | 16 ++--
 block/blkdebug.c  |  3 +--
 block/blklogwrites.c  |  3 +--
 block/blkverify.c |  3 +--
 block/crypto.c|  3 +--
 block/curl.c  |  3 +--
 block/file-posix.c|  6 ++
 block/file-win32.c|  6 ++
 block/gluster.c   | 15 +--
 block/iscsi.c |  3 +--
 block/nbd.c   |  3 +--
 block/parallels.c |  3 +--
 block/qcow2.c |  3 +--
 block/quorum.c|  3 +--
 block/raw-format.c|  3 +--
 block/replication.c   |  3 +--
 block/sheepdog.c  |  3 +--
 block/ssh.c   |  3 +--
 block/throttle.c  |  3 +--
 block/vpc.c   |  3 +--
 block/vvfat.c |  3 +--
 block/vxhs.c  |  6 ++
 blockdev.c| 11 ---
 chardev/char.c|  6 ++
 contrib/ivshmem-server/main.c |  4 ++--
 hw/net/virtio-net.c   |  5 ++---
 hw/smbios/smbios.c| 24 
 qapi/string-input-visitor.c   |  3 +--
 qemu-img.c| 19 +++
 tpm.c |  3 +--
 util/qemu-config.c| 12 
 util/qemu-option.c| 16 ++--
 32 files changed, 71 insertions(+), 132 deletions(-)

diff --git a/block.c b/block.c
index 6dbcb7e083..8d478bdc51 100644
--- a/block.c
+++ b/block.c
@@ -1629,8 +1629,7 @@ static int bdrv_open_common(BlockDriverState *bs, 
BlockBackend *file,
 assert(options != NULL && bs->options != options);
 
 opts = qemu_opts_create(_runtime_opts, NULL, 0, _abort);
-qemu_opts_absorb_qdict(opts, options, _err);
-if (local_err) {
+if (!qemu_opts_absorb_qdict(opts, options, _err)) {
 error_propagate(errp, local_err);
 ret = -EINVAL;
 goto fail_opts;
@@ -4091,8 +4090,7 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, 
BlockReopenQueue *queue,
 
 /* Process generic block layer options */
 opts = qemu_opts_create(_runtime_opts, NULL, 0, _abort);
-qemu_opts_absorb_qdict(opts, reopen_state->options, _err);
-if (local_err) {
+if (!qemu_opts_absorb_qdict(opts, reopen_state->options, _err)) {
 error_propagate(errp, local_err);
 ret = -EINVAL;
 goto error;
@@ -6078,8 +6076,7 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
 
 /* Parse -o options */
 if (options) {
-qemu_opts_do_parse(opts, options, NULL, _err);
-if (local_err) {
+if (!qemu_opts_do_parse(opts, options, NULL, _err)) {
 goto out;
 }
 }
@@ -6092,8 +6089,8 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
 }
 
 if (base_filename) {
-qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename, _err);
-if (local_err) {
+if (!qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename,
+  _err)) {
 error_setg(errp, "Backing file not supported for file format '%s'",
fmt);
 goto out;
@@ -6101,8 +6098,7 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
 }
 
 if (base_fmt) {
-qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt, _err);
-if (local_err) {
+if (!qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt, _err)) {
 error_setg(errp, "Backing file format not supported for file "
  "format '%s'", fmt);
 goto out;
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 7194bc7f06..d473dcf8c7 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -472,8 +472,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict 
*options, int flags,
 uint64_t align;
 
 opts = qemu_opts_create(_opts, NULL, 0, _abort);
-qemu_opts_absorb_qdict(opts, options, _err);
-if (local_err) {
+if (!qemu_opts_absorb_qdict(opts, options, _err)) {
 

[PATCH v4 08/45] qemu-option: Make uses of find_desc_by_name() more similar

2020-07-07 Thread Markus Armbruster
This is to make the next commit easier to review.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Greg Kurz 
---
 util/qemu-option.c | 32 ++--
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/util/qemu-option.c b/util/qemu-option.c
index fd1fd23521..1df55bc881 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -270,6 +270,7 @@ static void qemu_opt_del_all(QemuOpts *opts, const char 
*name)
 const char *qemu_opt_get(QemuOpts *opts, const char *name)
 {
 QemuOpt *opt;
+const QemuOptDesc *desc;
 
 if (opts == NULL) {
 return NULL;
@@ -277,7 +278,7 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name)
 
 opt = qemu_opt_find(opts, name);
 if (!opt) {
-const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
+desc = find_desc_by_name(opts->list->desc, name);
 if (desc && desc->def_value_str) {
 return desc->def_value_str;
 }
@@ -348,6 +349,7 @@ static bool qemu_opt_get_bool_helper(QemuOpts *opts, const 
char *name,
  bool defval, bool del)
 {
 QemuOpt *opt;
+const QemuOptDesc *desc;
 bool ret = defval;
 
 if (opts == NULL) {
@@ -356,7 +358,7 @@ static bool qemu_opt_get_bool_helper(QemuOpts *opts, const 
char *name,
 
 opt = qemu_opt_find(opts, name);
 if (opt == NULL) {
-const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
+desc = find_desc_by_name(opts->list->desc, name);
 if (desc && desc->def_value_str) {
 parse_option_bool(name, desc->def_value_str, , _abort);
 }
@@ -384,6 +386,7 @@ static uint64_t qemu_opt_get_number_helper(QemuOpts *opts, 
const char *name,
uint64_t defval, bool del)
 {
 QemuOpt *opt;
+const QemuOptDesc *desc;
 uint64_t ret = defval;
 
 if (opts == NULL) {
@@ -392,7 +395,7 @@ static uint64_t qemu_opt_get_number_helper(QemuOpts *opts, 
const char *name,
 
 opt = qemu_opt_find(opts, name);
 if (opt == NULL) {
-const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
+desc = find_desc_by_name(opts->list->desc, name);
 if (desc && desc->def_value_str) {
 parse_option_number(name, desc->def_value_str, , _abort);
 }
@@ -421,6 +424,7 @@ static uint64_t qemu_opt_get_size_helper(QemuOpts *opts, 
const char *name,
  uint64_t defval, bool del)
 {
 QemuOpt *opt;
+const QemuOptDesc *desc;
 uint64_t ret = defval;
 
 if (opts == NULL) {
@@ -429,7 +433,7 @@ static uint64_t qemu_opt_get_size_helper(QemuOpts *opts, 
const char *name,
 
 opt = qemu_opt_find(opts, name);
 if (opt == NULL) {
-const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
+desc = find_desc_by_name(opts->list->desc, name);
 if (desc && desc->def_value_str) {
 parse_option_size(name, desc->def_value_str, , _abort);
 }
@@ -540,18 +544,18 @@ void qemu_opt_set_bool(QemuOpts *opts, const char *name, 
bool val,
Error **errp)
 {
 QemuOpt *opt;
-const QemuOptDesc *desc = opts->list->desc;
+const QemuOptDesc *desc;
 
-opt = g_malloc0(sizeof(*opt));
-opt->desc = find_desc_by_name(desc, name);
-if (!opt->desc && !opts_accepts_any(opts)) {
+desc = find_desc_by_name(opts->list->desc, name);
+if (!desc && !opts_accepts_any(opts)) {
 error_setg(errp, QERR_INVALID_PARAMETER, name);
-g_free(opt);
 return;
 }
 
+opt = g_malloc0(sizeof(*opt));
 opt->name = g_strdup(name);
 opt->opts = opts;
+opt->desc = desc;
 opt->value.boolean = !!val;
 opt->str = g_strdup(val ? "on" : "off");
 QTAILQ_INSERT_TAIL(>head, opt, next);
@@ -561,18 +565,18 @@ void qemu_opt_set_number(QemuOpts *opts, const char 
*name, int64_t val,
  Error **errp)
 {
 QemuOpt *opt;
-const QemuOptDesc *desc = opts->list->desc;
+const QemuOptDesc *desc;
 
-opt = g_malloc0(sizeof(*opt));
-opt->desc = find_desc_by_name(desc, name);
-if (!opt->desc && !opts_accepts_any(opts)) {
+desc = find_desc_by_name(opts->list->desc, name);
+if (!desc && !opts_accepts_any(opts)) {
 error_setg(errp, QERR_INVALID_PARAMETER, name);
-g_free(opt);
 return;
 }
 
+opt = g_malloc0(sizeof(*opt));
 opt->name = g_strdup(name);
 opt->opts = opts;
+opt->desc = desc;
 opt->value.uint = val;
 opt->str = g_strdup_printf("%" PRId64, val);
 QTAILQ_INSERT_TAIL(>head, opt, next);
-- 
2.26.2




[PATCH v4 10/45] qemu-option: Simplify around find_default_by_name()

2020-07-07 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 util/qemu-option.c | 18 +-
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/util/qemu-option.c b/util/qemu-option.c
index 14e211ddd8..e7b540a21b 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -277,7 +277,6 @@ static void qemu_opt_del_all(QemuOpts *opts, const char 
*name)
 const char *qemu_opt_get(QemuOpts *opts, const char *name)
 {
 QemuOpt *opt;
-const char *def_val;
 
 if (opts == NULL) {
 return NULL;
@@ -285,12 +284,10 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name)
 
 opt = qemu_opt_find(opts, name);
 if (!opt) {
-def_val = find_default_by_name(opts, name);
-if (def_val) {
-return def_val;
-}
+return find_default_by_name(opts, name);
 }
-return opt ? opt->str : NULL;
+
+return opt->str;
 }
 
 void qemu_opt_iter_init(QemuOptsIter *iter, QemuOpts *opts, const char *name)
@@ -319,8 +316,7 @@ const char *qemu_opt_iter_next(QemuOptsIter *iter)
 char *qemu_opt_get_del(QemuOpts *opts, const char *name)
 {
 QemuOpt *opt;
-const char *def_val;
-char *str = NULL;
+char *str;
 
 if (opts == NULL) {
 return NULL;
@@ -328,11 +324,7 @@ char *qemu_opt_get_del(QemuOpts *opts, const char *name)
 
 opt = qemu_opt_find(opts, name);
 if (!opt) {
-def_val = find_default_by_name(opts, name);
-if (def_val) {
-str = g_strdup(def_val);
-}
-return str;
+return g_strdup(find_default_by_name(opts, name));
 }
 str = opt->str;
 opt->str = NULL;
-- 
2.26.2




[PATCH v4 20/45] s390x/pci: Fix harmless mistake in zpci's property fid's setter

2020-07-07 Thread Markus Armbruster
s390_pci_set_fid() sets zpci->fid_defined to true even when
visit_type_uint32() failed.  Reproducer: "-device zpci,fid=junk".
Harmless in practice, because qdev_device_add() then fails, throwing
away @zpci.  Fix it anyway.

Cc: Matthew Rosato 
Cc: Cornelia Huck 
Signed-off-by: Markus Armbruster 
Reviewed-by: Matthew Rosato 
Reviewed-by: Cornelia Huck 
---
 hw/s390x/s390-pci-bus.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 9e6b170fa8..1e4537f0e3 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -1269,7 +1269,9 @@ static void s390_pci_set_fid(Object *obj, Visitor *v, 
const char *name,
 return;
 }
 
-visit_type_uint32(v, name, ptr, errp);
+if (!visit_type_uint32(v, name, ptr, errp)) {
+return;
+}
 zpci->fid_defined = true;
 }
 
-- 
2.26.2




[PATCH v4 15/45] block: Avoid error accumulation in bdrv_img_create()

2020-07-07 Thread Markus Armbruster
When creating an image fails because the format doesn't support option
"backing_file" or "backing_fmt", bdrv_img_create() first has
qemu_opt_set() put a generic error into @local_err, then puts the real
error into @errp with error_setg(), and then propagates the former to
the latter, which throws away the generic error.  A bit complicated,
but works.

Now that qemu_opt_set() returns a useful value, we can simply ignore
the generic error instead.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 block.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/block.c b/block.c
index 8d478bdc51..b396f32a51 100644
--- a/block.c
+++ b/block.c
@@ -6090,7 +6090,7 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
 
 if (base_filename) {
 if (!qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename,
-  _err)) {
+  NULL)) {
 error_setg(errp, "Backing file not supported for file format '%s'",
fmt);
 goto out;
@@ -6098,7 +6098,7 @@ void bdrv_img_create(const char *filename, const char 
*fmt,
 }
 
 if (base_fmt) {
-if (!qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt, _err)) {
+if (!qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt, NULL)) {
 error_setg(errp, "Backing file format not supported for file "
  "format '%s'", fmt);
 goto out;
-- 
2.26.2




[PATCH v4 11/45] qemu-option: Factor out helper opt_create()

2020-07-07 Thread Markus Armbruster
There is just one use so far.  The next commit will add more.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 util/qemu-option.c | 27 ++-
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/util/qemu-option.c b/util/qemu-option.c
index e7b540a21b..1023fe7527 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -499,6 +499,23 @@ int qemu_opt_unset(QemuOpts *opts, const char *name)
 }
 }
 
+static QemuOpt *opt_create(QemuOpts *opts, const char *name, char *value,
+   bool prepend)
+{
+QemuOpt *opt = g_malloc0(sizeof(*opt));
+
+opt->name = g_strdup(name);
+opt->str = value;
+opt->opts = opts;
+if (prepend) {
+QTAILQ_INSERT_HEAD(>head, opt, next);
+} else {
+QTAILQ_INSERT_TAIL(>head, opt, next);
+}
+
+return opt;
+}
+
 static void opt_set(QemuOpts *opts, const char *name, char *value,
 bool prepend, bool *help_wanted, Error **errp)
 {
@@ -516,16 +533,8 @@ static void opt_set(QemuOpts *opts, const char *name, char 
*value,
 return;
 }
 
-opt = g_malloc0(sizeof(*opt));
-opt->name = g_strdup(name);
-opt->opts = opts;
-if (prepend) {
-QTAILQ_INSERT_HEAD(>head, opt, next);
-} else {
-QTAILQ_INSERT_TAIL(>head, opt, next);
-}
+opt = opt_create(opts, name, value, prepend);
 opt->desc = desc;
-opt->str = value;
 qemu_opt_parse(opt, _err);
 if (local_err) {
 error_propagate(errp, local_err);
-- 
2.26.2




[PATCH v4 23/45] qom: Crash more nicely on object_property_get_link() failure

2020-07-07 Thread Markus Armbruster
Pass _abort instead of NULL where the returned value is
dereferenced or asserted to be non-null.  Drop a now redundant
assertion.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 hw/core/platform-bus.c | 6 +++---
 hw/ppc/spapr_drc.c | 3 ++-
 hw/ppc/spapr_hcall.c   | 3 ++-
 hw/ppc/spapr_pci_nvlink2.c | 3 ++-
 ui/vnc.c   | 2 +-
 5 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/hw/core/platform-bus.c b/hw/core/platform-bus.c
index d494e5cec1..5037ca265e 100644
--- a/hw/core/platform-bus.c
+++ b/hw/core/platform-bus.c
@@ -22,6 +22,7 @@
 #include "qemu/osdep.h"
 #include "hw/platform-bus.h"
 #include "hw/qdev-properties.h"
+#include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "qemu/module.h"
 
@@ -63,9 +64,8 @@ hwaddr platform_bus_get_mmio_addr(PlatformBusDevice *pbus, 
SysBusDevice *sbdev,
 return -1;
 }
 
-parent_mr = object_property_get_link(OBJECT(sbdev_mr), "container", NULL);
-
-assert(parent_mr);
+parent_mr = object_property_get_link(OBJECT(sbdev_mr), "container",
+ _abort);
 if (parent_mr != pbus_mr_obj) {
 /* MMIO region is not mapped on platform bus */
 return -1;
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index d10193f39e..1f18b79348 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -870,7 +870,8 @@ int spapr_dt_drc(void *fdt, int offset, Object *owner, 
uint32_t drc_type_mask)
 continue;
 }
 
-obj = object_property_get_link(root_container, prop->name, NULL);
+obj = object_property_get_link(root_container, prop->name,
+   _abort);
 drc = SPAPR_DR_CONNECTOR(obj);
 drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
 
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 0f54988f2e..c1d01228c6 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1655,7 +1655,8 @@ static void 
spapr_handle_transient_dev_before_cas(SpaprMachineState *spapr)
 continue;
 }
 drc = SPAPR_DR_CONNECTOR(object_property_get_link(drc_container,
-  prop->name, NULL));
+  prop->name,
+  _abort));
 
 if (spapr_drc_transient(drc)) {
 spapr_drc_reset(drc);
diff --git a/hw/ppc/spapr_pci_nvlink2.c b/hw/ppc/spapr_pci_nvlink2.c
index 8332d5694e..dd8cd6db96 100644
--- a/hw/ppc/spapr_pci_nvlink2.c
+++ b/hw/ppc/spapr_pci_nvlink2.c
@@ -358,7 +358,8 @@ void spapr_phb_nvgpu_ram_populate_dt(SpaprPhbState *sphb, 
void *fdt)
 for (i = 0; i < sphb->nvgpus->num; ++i) {
 SpaprPhbPciNvGpuSlot *nvslot = >nvgpus->slots[i];
 Object *nv_mrobj = object_property_get_link(OBJECT(nvslot->gpdev),
-"nvlink2-mr[0]", NULL);
+"nvlink2-mr[0]",
+_abort);
 uint32_t associativity[] = {
 cpu_to_be32(0x4),
 SPAPR_GPU_NUMA_ID,
diff --git a/ui/vnc.c b/ui/vnc.c
index 527ad25124..f006aa1afd 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -568,7 +568,7 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp)
>vencrypt, >has_vencrypt);
 if (vd->dcl.con) {
 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
-  "device", NULL));
+  "device", _abort));
 info->has_display = true;
 info->display = g_strdup(dev->id);
 }
-- 
2.26.2




[PATCH v4 03/45] error: Document Error API usage rules

2020-07-07 Thread Markus Armbruster
This merely codifies existing practice, with one exception: the rule
advising against returning void, where existing practice is mixed.

When the Error API was created, we adopted the (unwritten) rule to
return void when the function returns no useful value on success,
unlike GError, which recommends to return true on success and false on
error then.

When a function returns a distinct error value, say false, a checked
call that passes the error up looks like

if (!frobnicate(..., errp)) {
handle the error...
}

When it returns void, we need

Error *err = NULL;

frobnicate(..., );
if (err) {
handle the error...
error_propagate(errp, err);
}

Not only is this more verbose, it also creates an Error object even
when @errp is null, _abort or _fatal.

People got tired of the additional boilerplate, and started to ignore
the unwritten rule.  The result is confusion among developers about
the preferred usage.

Make the rule advising against returning void official by putting it
in writing.  This will hopefully reduce confusion.

Update the examples accordingly.

The remainder of this series will update a substantial amount of code
to honor the rule.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Greg Kurz 
---
 include/qapi/error.h | 50 ++--
 1 file changed, 44 insertions(+), 6 deletions(-)

diff --git a/include/qapi/error.h b/include/qapi/error.h
index 6d079c58b7..3fed49747d 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -15,6 +15,33 @@
 /*
  * Error reporting system loosely patterned after Glib's GError.
  *
+ * = Rules =
+ *
+ * - Functions that use Error to report errors have an Error **errp
+ *   parameter.  It should be the last parameter, except for functions
+ *   taking variable arguments.
+ *
+ * - You may pass NULL to not receive the error, _abort to abort
+ *   on error, _fatal to exit(1) on error, or a pointer to a
+ *   variable containing NULL to receive the error.
+ *
+ * - Separation of concerns: the function is responsible for detecting
+ *   errors and failing cleanly; handling the error is its caller's
+ *   job.  Since the value of @errp is about handling the error, the
+ *   function should not examine it.
+ *
+ * - On success, the function should not touch *errp.  On failure, it
+ *   should set a new error, e.g. with error_setg(errp, ...), or
+ *   propagate an existing one, e.g. with error_propagate(errp, ...).
+ *
+ * - Whenever practical, also return a value that indicates success /
+ *   failure.  This can make the error checking more concise, and can
+ *   avoid useless error object creation and destruction.  Note that
+ *   we still have many functions returning void.  We recommend
+ *   • bool-valued functions return true on success / false on failure,
+ *   • pointer-valued functions return non-null / null pointer, and
+ *   • integer-valued functions return non-negative / negative.
+ *
  * = Creating errors =
  *
  * Create an error:
@@ -95,14 +122,12 @@
  * Create a new error and pass it to the caller:
  * error_setg(errp, "situation normal, all fouled up");
  *
- * Call a function and receive an error from it:
- * Error *err = NULL;
- * foo(arg, );
- * if (err) {
+ * Call a function, receive an error from it, and pass it to caller
+ * when the function returns a value that indicates failure, say false:
+ * if (!foo(arg, errp)) {
  * handle the error...
  * }
- *
- * Receive an error and pass it on to the caller:
+ * when it doesn't, say a void function:
  * Error *err = NULL;
  * foo(arg, );
  * if (err) {
@@ -120,6 +145,19 @@
  * foo(arg, errp);
  * for readability.
  *
+ * Receive an error, and handle it locally
+ * when the function returns a value that indicates failure, say false:
+ * Error *err = NULL;
+ * if (!foo(arg, )) {
+ * handle the error...
+ * }
+ * when it doesn't, say a void function:
+ * Error *err = NULL;
+ * foo(arg, );
+ * if (err) {
+ * handle the error...
+ * }
+ *
  * Receive and accumulate multiple errors (first one wins):
  * Error *err = NULL, *local_err = NULL;
  * foo(arg, );
-- 
2.26.2




[PATCH v4 01/45] error: Fix examples in error.h's big comment

2020-07-07 Thread Markus Armbruster
Mark a bad example more clearly.  Fix the error_propagate_prepend()
example.  Add a missing declaration and a second error pileup example.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Greg Kurz 
---
 include/qapi/error.h | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/include/qapi/error.h b/include/qapi/error.h
index ad5b6e896d..e8960eaad5 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -24,7 +24,7 @@
  *   "charm, top, bottom.\n");
  *
  * Do *not* contract this to
- * error_setg(, "invalid quark\n"
+ * error_setg(, "invalid quark\n" // WRONG!
  *"Valid quarks are up, down, strange, charm, top, bottom.");
  *
  * Report an error to the current monitor if we have one, else stderr:
@@ -52,7 +52,8 @@
  * where Error **errp is a parameter, by convention the last one.
  *
  * Pass an existing error to the caller with the message modified:
- * error_propagate_prepend(errp, err);
+ * error_propagate_prepend(errp, err,
+ * "Could not frobnicate '%s': ", name);
  *
  * Avoid
  * error_propagate(errp, err);
@@ -108,12 +109,23 @@
  * }
  *
  * Do *not* "optimize" this to
+ * Error *err = NULL;
  * foo(arg, );
  * bar(arg, ); // WRONG!
  * if (err) {
  * handle the error...
  * }
  * because this may pass a non-null err to bar().
+ *
+ * Likewise, do *not*
+ * Error *err = NULL;
+ * if (cond1) {
+ * error_setg(, ...);
+ * }
+ * if (cond2) {
+ * error_setg(, ...); // WRONG!
+ * }
+ * because this may pass a non-null err to error_setg().
  */
 
 #ifndef ERROR_H
-- 
2.26.2




Re: [PATCH 2/2] hw/sd/sdcard: Do not allow invalid SD card sizes

2020-07-07 Thread Alistair Francis
On Tue, Jul 7, 2020 at 6:22 AM Philippe Mathieu-Daudé  wrote:
>
> QEMU allows to create SD card with unrealistic sizes. This could work,
> but some guests (at least Linux) consider sizes that are not a power
> of 2 as a firmware bug and fix the card size to the next power of 2.
>
> Before CVE-2020-13253 fix, this would allow OOB read/write accesses
> past the image size end.
>
> CVE-2020-13253 has been fixed as:
>
> Read command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
> occurred and no data transfer is performed.
>
> Write command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
> occurred and no data transfer is performed.
>
> WP_VIOLATION errors are not modified: the error bit is set, we
> stay in receive-data state, wait for a stop command. All further
> data transfer is ignored. See the check on sd->card_status at the
> beginning of sd_read_data() and sd_write_data().
>
> While this is the correct behavior, in case QEMU create smaller SD
> cards, guests still try to access past the image size end, and QEMU
> considers this is an invalid address, thus "all further data transfer
> is ignored". This is wrong and make the guest looping until
> eventually timeouts.
>
> Fix by not allowing invalid SD card sizes.  Suggesting the expected
> size as a hint:
>
>   $ qemu-system-arm -M orangepi-pc -drive file=rootfs.ext2,if=sd,format=raw
>   qemu-system-arm: Invalid SD card size: 60 MiB (expecting at least 64 MiB)
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/sd/sd.c | 16 
>  1 file changed, 16 insertions(+)
>
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index cb81487e5c..c45106b78e 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -32,6 +32,7 @@
>
>  #include "qemu/osdep.h"
>  #include "qemu/units.h"
> +#include "qemu/cutils.h"
>  #include "hw/irq.h"
>  #include "hw/registerfields.h"
>  #include "sysemu/block-backend.h"
> @@ -2130,11 +2131,26 @@ static void sd_realize(DeviceState *dev, Error **errp)
>  }
>
>  if (sd->blk) {
> +int64_t blk_size;
> +
>  if (blk_is_read_only(sd->blk)) {
>  error_setg(errp, "Cannot use read-only drive as SD card");
>  return;
>  }
>
> +blk_size = blk_getlength(sd->blk);
> +if (blk_size > 0 && !is_power_of_2(blk_size)) {
> +int64_t blk_size_aligned = pow2ceil(blk_size);
> +char *blk_size_str = size_to_str(blk_size);
> +char *blk_size_aligned_str = size_to_str(blk_size_aligned);
> +
> +error_setg(errp, "Invalid SD card size: %s (expecting at least 
> %s)",
> +   blk_size_str, blk_size_aligned_str);

Should we print that we expect a power of 2? This isn't always obvious
from the message.

Alistair

> +g_free(blk_size_str);
> +g_free(blk_size_aligned_str);
> +return;
> +}
> +
>  ret = blk_set_perm(sd->blk, BLK_PERM_CONSISTENT_READ | 
> BLK_PERM_WRITE,
> BLK_PERM_ALL, errp);
>  if (ret < 0) {
> --
> 2.21.3
>
>



[PATCH v4 05/45] macio: Tidy up error handling in macio_newworld_realize()

2020-07-07 Thread Markus Armbruster
macio_newworld_realize() effectively ignores ns->gpio realization
errors, leaking the Error object.  Fortunately, macio_gpio_realize()
can't actually fail.  Tidy up.

Cc: Mark Cave-Ayland 
Cc: David Gibson 
Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Acked-by: David Gibson 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Greg Kurz 
---
 hw/misc/macio/macio.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index 42414797e2..be66bb7758 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -334,7 +334,9 @@ static void macio_newworld_realize(PCIDevice *d, Error 
**errp)
  _abort);
 memory_region_add_subregion(>bar, 0x50,
 sysbus_mmio_get_region(sysbus_dev, 0));
-qdev_realize(DEVICE(>gpio), BUS(>macio_bus), );
+if (!qdev_realize(DEVICE(>gpio), BUS(>macio_bus), errp)) {
+return;
+}
 
 /* PMU */
 object_initialize_child(OBJECT(s), "pmu", >pmu, TYPE_VIA_PMU);
-- 
2.26.2




Re: [PATCH 1/2] tests/acceptance/boot_linux: Truncate SD card image to power of 2

2020-07-07 Thread Alistair Francis
n Tue, Jul 7, 2020 at 6:21 AM Philippe Mathieu-Daudé  wrote:
>
> In the next commit we won't allow SD card images with invalid
> size (not aligned to a power of 2). Prepare the tests: add the
> pow2ceil() and image_pow2ceil_truncate() methods and truncate
> the images of the tests using SD cards.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  tests/acceptance/boot_linux_console.py | 15 +++
>  1 file changed, 15 insertions(+)
>
> diff --git a/tests/acceptance/boot_linux_console.py 
> b/tests/acceptance/boot_linux_console.py
> index 3d02519660..f4d4e3635f 100644
> --- a/tests/acceptance/boot_linux_console.py
> +++ b/tests/acceptance/boot_linux_console.py
> @@ -28,6 +28,18 @@
>  except CmdNotFoundError:
>  P7ZIP_AVAILABLE = False
>
> +# round up to next power of 2
> +def pow2ceil(x):
> +return 1 if x == 0 else 2**(x - 1).bit_length()
> +
> +# truncate file size to next power of 2
> +def image_pow2ceil_truncate(path):
> +size = os.path.getsize(path)
> +size_aligned = pow2ceil(size)
> +if size != size_aligned:
> +with open(path, 'ab+') as fd:
> +fd.truncate(size_aligned)

Why truncate the image, can't we expand it instead?

Alistair

> +
>  class LinuxKernelTest(Test):
>  KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
>
> @@ -635,6 +647,7 @@ def test_arm_orangepi_sd(self):
>  rootfs_path_xz = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash)
>  rootfs_path = os.path.join(self.workdir, 'rootfs.cpio')
>  archive.lzma_uncompress(rootfs_path_xz, rootfs_path)
> +image_pow2ceil_truncate(rootfs_path)
>
>  self.vm.set_console()
>  kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
> @@ -679,6 +692,7 @@ def test_arm_orangepi_bionic(self):
>  image_name = 'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.img'
>  image_path = os.path.join(self.workdir, image_name)
>  process.run("7z e -o%s %s" % (self.workdir, image_path_7z))
> +image_pow2ceil_truncate(image_path)
>
>  self.vm.set_console()
>  self.vm.add_args('-drive', 'file=' + image_path + 
> ',if=sd,format=raw',
> @@ -728,6 +742,7 @@ def test_arm_orangepi_uboot_netbsd9(self):
>  image_hash = '2babb29d36d8360adcb39c09e31060945259917a'
>  image_path_gz = self.fetch_asset(image_url, asset_hash=image_hash)
>  image_path = os.path.join(self.workdir, 'armv7.img')
> +image_pow2ceil_truncate(image_path)
>  image_drive_args = 'if=sd,format=raw,snapshot=on,file=' + image_path
>  archive.gzip_uncompress(image_path_gz, image_path)
>
> --
> 2.21.3
>
>



Re: [PATCH 1/5] block/io: introduce bdrv_try_mark_request_serialising

2020-07-07 Thread Stefan Hajnoczi
On Sat, Jun 20, 2020 at 05:36:45PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> Introduce a function to mark the request serialising only if there are
> no conflicting request to wait for.
> 
> The function is static, so mark it unused. The attribute is to be
> dropped in the next commit.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>  block/io.c | 58 +++---
>  1 file changed, 51 insertions(+), 7 deletions(-)

I found this patch difficult to understand because there are multiple
levels of functions passing flags to ultimiately do different things in
a common function.

Here are some ideas if you have time to rework this patch:

1. Introduce a bdrv_find_overlapping_request() function that does most
   of bdrv_wait_serialising_requests_locked() but does not wait. Then
   bdrv_wait_serialising_requests_locked() can call that function in a
   loop and wait if an overlapping request is found.

2. Pass overlap_offset/overlap_bytes arguments to
   bdrv_find_overlapping_request() instead of changing and restoring the
   value in bdrv_do_mark_request_serialising().

3. Use consistent names for flags: wait/blocking, found/success

I'm not sure if all these ideas will work, but I get the feeling this
code can be refactored to make it easier to understand. Since I don't
have a concrete suggestion and the code looks correct:

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


Re: [PATCH v5 1/5] virtio-pci: add virtio_pci_optimal_num_queues() helper

2020-07-07 Thread Cornelia Huck
On Mon,  6 Jul 2020 14:56:46 +0100
Stefan Hajnoczi  wrote:

> Multi-queue devices achieve the best performance when each vCPU has a
> dedicated queue. This ensures that virtqueue used notifications are
> handled on the same vCPU that submitted virtqueue buffers.  When another
> vCPU handles the the notification an IPI will be necessary to wake the
> submission vCPU and this incurs a performance overhead.
> 
> Provide a helper function that virtio-pci devices will use in later
> patches to automatically select the optimal number of queues.
> 
> The function handles guests with large numbers of CPUs by limiting the
> number of queues to fit within the following constraints:
> 1. The maximum number of MSI-X vectors.
> 2. The maximum number of virtqueues.
> 
> Signed-off-by: Stefan Hajnoczi 
> ---
>  hw/virtio/virtio-pci.h |  9 +
>  hw/virtio/virtio-pci.c | 32 
>  2 files changed, 41 insertions(+)

I guess this should honour all relevant limits now.

Reviewed-by: Cornelia Huck 




  1   2   >