Skip to content
Snippets Groups Projects
  1. Sep 29, 2021
    • Vladimir Sementsov-Ogievskiy's avatar
      block: use int64_t instead of uint64_t in driver read handlers · f7ef38dd
      Vladimir Sementsov-Ogievskiy authored
      
      We are generally moving to int64_t for both offset and bytes parameters
      on all io paths.
      
      Main motivation is realization of 64-bit write_zeroes operation for
      fast zeroing large disk chunks, up to the whole disk.
      
      We chose signed type, to be consistent with off_t (which is signed) and
      with possibility for signed return type (where negative value means
      error).
      
      So, convert driver read handlers parameters which are already 64bit to
      signed type.
      
      While being here, convert also flags parameter to be BdrvRequestFlags.
      
      Now let's consider all callers. Simple
      
        git grep '\->bdrv_\(aio\|co\)_preadv\(_part\)\?'
      
      shows that's there three callers of driver function:
      
       bdrv_driver_preadv() in block/io.c, passes int64_t, checked by
         bdrv_check_qiov_request() to be non-negative.
      
       qcow2_load_vmstate() does bdrv_check_qiov_request().
      
       do_perform_cow_read() has uint64_t argument. And a lot of things in
       qcow2 driver are uint64_t, so converting it is big job. But we must
       not work with requests that don't satisfy bdrv_check_qiov_request(),
       so let's just assert it here.
      
      Still, the functions may be called directly, not only by drv->...
      Let's check:
      
      git grep '\.bdrv_\(aio\|co\)_preadv\(_part\)\?\s*=' | \
      awk '{print $4}' | sed 's/,//' | sed 's/&//' | sort | uniq | \
      while read func; do git grep "$func(" | \
      grep -v "$func(BlockDriverState"; done
      
      The only one such caller:
      
          QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, &data, 1);
          ...
          ret = bdrv_replace_test_co_preadv(bs, 0, 1, &qiov, 0);
      
      in tests/unit/test-bdrv-drain.c, and it's OK obviously.
      
      Signed-off-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      Message-Id: <20210903102807.27127-4-vsementsov@virtuozzo.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      [eblake: fix typos]
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      f7ef38dd
  2. Mar 19, 2021
    • Hanna Reitz's avatar
      curl: Disconnect sockets from CURLState · 0f418a20
      Hanna Reitz authored
      When a curl transfer is finished, that does not mean that CURL lets go
      of all the sockets it used for it.  We therefore must not free a
      CURLSocket object before CURL has invoked curl_sock_cb() to tell us to
      remove it.  Otherwise, we may get a use-after-free, as described in this
      bug report: https://bugs.launchpad.net/qemu/+bug/1916501
      
      (Reproducer from that report:
        $ qemu-img convert -f qcow2 -O raw \
        https://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img \
        out.img
      )
      
      (Alternatively, it might seem logical to force-drop all sockets that
      have been used for a state when the respective transfer is done, kind of
      like it is done now, but including unsetting the AIO handlers.
      Unfortunately, doing so makes the driver just hang instead of crashing,
      which seems to evidence that CURL still uses those sockets.)
      
      Make the CURLSocket object independent of "its" CURLState by putting all
      sockets into a hash table belonging to the BDRVCURLState instead of a
      list that belongs to a CURLState.  Do not touch any sockets in
      curl_clean_state().
      
      Testing, it seems like all sockets are indeed gone by the time the curl
      BDS is closed, so it seems like there really was no point in freeing any
      socket just because a transfer is done.  libcurl does invoke
      curl_sock_cb() with CURL_POLL_REMOVE for every socket it has.
      
      Buglink: https://bugs.launchpad.net/qemu/+bug/1916501
      
      
      Signed-off-by: default avatarMax Reitz <mreitz@redhat.com>
      Message-Id: <20210309130541.37540-3-mreitz@redhat.com>
      Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
      0f418a20
    • Hanna Reitz's avatar
      curl: Store BDRVCURLState pointer in CURLSocket · 3663dca4
      Hanna Reitz authored
      
      A socket does not really belong to any specific state.  We do not need
      to store a pointer to "its" state in it, a pointer to the common
      BDRVCURLState is sufficient.
      
      Signed-off-by: default avatarMax Reitz <mreitz@redhat.com>
      Message-Id: <20210309130541.37540-2-mreitz@redhat.com>
      Reviewed-by: default avatarPhilippe Mathieu-Daudé <philmd@redhat.com>
      Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
      3663dca4
  3. Jan 02, 2021
  4. Dec 11, 2020
  5. Jul 10, 2020
    • Markus Armbruster's avatar
      error: Eliminate error_propagate() with Coccinelle, part 1 · 668f62ec
      Markus Armbruster authored
      
      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.  Convert
      
          if (!foo(..., &err)) {
              ...
              error_propagate(errp, err);
              ...
              return ...
          }
      
      to
      
          if (!foo(..., errp)) {
              ...
              ...
              return ...
          }
      
      where nothing else needs @err.  Coccinelle script:
      
          @rule1 forall@
          identifier fun, err, errp, lbl;
          expression list args, args2;
          binary operator op;
          constant c1, c2;
          symbol false;
          @@
               if (
          (
          -        fun(args, &err, args2)
          +        fun(args, errp, args2)
          |
          -        !fun(args, &err, args2)
          +        !fun(args, errp, args2)
          |
          -        fun(args, &err, args2) op c1
          +        fun(args, errp, args2) op c1
          )
                  )
               {
                   ... when != err
                       when != lbl:
                       when strict
          -        error_propagate(errp, err);
                   ... when != err
          (
                   return;
          |
                   return c2;
          |
                   return false;
          )
               }
      
          @rule2 forall@
          identifier fun, err, errp, lbl;
          expression list args, args2;
          expression var;
          binary operator op;
          constant c1, c2;
          symbol false;
          @@
          -    var = fun(args, &err, args2);
          +    var = fun(args, errp, args2);
               ... when != err
               if (
          (
                   var
          |
                   !var
          |
                   var op c1
          )
                  )
               {
                   ... when != err
                       when != lbl:
                       when strict
          -        error_propagate(errp, err);
                   ... when != err
          (
                   return;
          |
                   return c2;
          |
                   return false;
          |
                   return var;
          )
               }
      
          @depends on rule1 || rule2@
          identifier err;
          @@
          -    Error *err = NULL;
               ... when != err
      
      Not exactly elegant, I'm afraid.
      
      The "when != lbl:" is necessary to avoid transforming
      
               if (fun(args, &err)) {
                   goto out
               }
               ...
           out:
               error_propagate(errp, err);
      
      even though other paths to label out still need the error_propagate().
      For an actual example, see sclp_realize().
      
      Without the "when strict", Coccinelle transforms vfio_msix_setup(),
      incorrectly.  I don't know what exactly "when strict" does, only that
      it helps here.
      
      The match of return is narrower than what I want, but I can't figure
      out how to express "return where the operand doesn't use @err".  For
      an example where it's too narrow, see vfio_intx_enable().
      
      Silently 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.
      
      Line breaks tidied up manually.  One nested declaration of @local_err
      deleted manually.  Preexisting unwanted blank line dropped in
      hw/riscv/sifive_e.c.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20200707160613.848843-35-armbru@redhat.com>
      668f62ec
    • Markus Armbruster's avatar
      qemu-option: Use returned bool to check for failure · 235e59cf
      Markus Armbruster authored
      
      The previous commit enables conversion of
      
          foo(..., &err);
          if (err) {
              ...
          }
      
      to
      
          if (!foo(..., &err)) {
              ...
          }
      
      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, &err, args2);
          -    if (err)
          +    if (!fun(args, &err, args2))
               {
                   ...
               }
      
      A few line breaks tidied up manually.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Reviewed-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      Message-Id: <20200707160613.848843-15-armbru@redhat.com>
      [Conflict with commit 0b6786a9 "block/amend: refactor qcow2 amend
      options" resolved by rerunning Coccinelle on master's version]
      235e59cf
  6. Mar 11, 2020
  7. Sep 16, 2019
  8. Jun 12, 2019
  9. Feb 25, 2019
  10. Jan 30, 2019
  11. Nov 05, 2018
  12. Sep 25, 2018
    • Richard W.M. Jones's avatar
      curl: Make sslverify=off disable host as well as peer verification. · 637fa44a
      Richard W.M. Jones authored
      The sslverify setting is supposed to turn off all TLS certificate
      checks in libcurl.  However because of the way we use it, it only
      turns off peer certificate authenticity checks
      (CURLOPT_SSL_VERIFYPEER).  This patch makes it also turn off the check
      that the server name in the certificate is the same as the server
      you're connecting to (CURLOPT_SSL_VERIFYHOST).
      
      We can use Google's server at 8.8.8.8 which happens to have a bad TLS
      certificate to demonstrate this:
      
      $ ./qemu-img create -q -f qcow2 -b 'json: { "file.sslverify": "off", "file.driver": "https", "file.url": "https://8.8.8.8/foo" }' /var/tmp/file.qcow2
      qemu-img: /var/tmp/file.qcow2: CURL: Error opening file: SSL: no alternative certificate subject name matches target host name '8.8.8.8'
      Could not open backing image to determine size.
      
      With this patch applied, qemu-img connects to the server regardless of
      the bad certificate:
      
      $ ./qemu-img create -q -f qcow2 -b 'json: { "file.sslverify": "off", "file.driver": "https", "file.url": "https://8.8.8.8/foo" }' /var/tmp/file.qcow2
      qemu-img: /var/tmp/file.qcow2: CURL: Error opening file: The requested URL returned error: 404 Not Found
      
      (The 404 error is expected because 8.8.8.8 is not actually serving a
      file called "/foo".)
      
      Of course the default (without sslverify=off) remains to always check
      the certificate:
      
      $ ./qemu-img create -q -f qcow2 -b 'json: { "file.driver": "https", "file.url": "https://8.8.8.8/foo" }' /var/tmp/file.qcow2
      qemu-img: /var/tmp/file.qcow2: CURL: Error opening file: SSL: no alternative certificate subject name matches target host name '8.8.8.8'
      Could not open backing image to determine size.
      
      Further information about the two settings is available here:
      
      https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html
      https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html
      
      
      
      Signed-off-by: default avatarRichard W.M. Jones <rjones@redhat.com>
      Message-id: 20180914095622.19698-1-rjones@redhat.com
      Signed-off-by: default avatarJeff Cody <jcody@redhat.com>
      637fa44a
  13. Jul 23, 2018
  14. Feb 09, 2018
  15. Feb 08, 2018
  16. Dec 18, 2017
  17. May 16, 2017
  18. May 09, 2017
  19. Mar 31, 2017
Loading