Skip to content
Snippets Groups Projects
  1. Dec 19, 2020
    • Markus Armbruster's avatar
      qobject: Change qobject_to_json()'s value to GString · eab3a467
      Markus Armbruster authored
      
      qobject_to_json() and qobject_to_json_pretty() build a GString, then
      covert it to QString.  Just one of the callers actually needs a
      QString: qemu_rbd_parse_filename().  A few others need a string they
      can modify: qmp_send_response(), qga's send_response(), to_json_str(),
      and qmp_fd_vsend_fds().  The remainder just need a string.
      
      Change qobject_to_json() and qobject_to_json_pretty() to return the
      GString.
      
      qemu_rbd_parse_filename() now has to convert to QString.  All others
      save a QString temporary.  to_json_str() actually becomes a bit
      simpler, because GString provides more convenient modification
      functions.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20201211171152.146877-6-armbru@redhat.com>
      eab3a467
  2. Oct 15, 2020
  3. Jul 10, 2020
    • Eric Auger's avatar
      qom: Introduce object_property_try_add_child() · db57fef1
      Eric Auger authored
      
      object_property_add() does not allow object_property_try_add()
      to gracefully fail as &error_abort is passed as an error handle.
      
      However such failure can easily be triggered from the QMP shell when,
      for instance, one attempts to create an object with an id that already
      exists. This is achieved from the following call path:
      
      qmp_object_add -> user_creatable_add_dict -> user_creatable_add_type ->
      object_property_add_child -> object_property_add
      
      For instance, from the qmp-shell, call twice:
      object-add qom-type=memory-backend-ram id=mem1 props.size=1073741824
      and QEMU aborts.
      
      This behavior is undesired as a user/management application mistake
      in reusing a property ID shouldn't result in loss of the VM and live
      data within.
      
      This patch introduces a new function, object_property_try_add_child()
      which takes an error handle and turn object_property_try_add() into
      a non-static one.
      
      Now the call path becomes:
      
      user_creatable_add_type -> object_property_try_add_child ->
      object_property_try_add
      
      and the error is returned gracefully to the QMP client.
      
      (QEMU) object-add qom-type=memory-backend-ram id=mem2  props.size=4294967296
      {"return": {}}
      (QEMU) object-add qom-type=memory-backend-ram id=mem2  props.size=4294967296
      {"error": {"class": "GenericError", "desc": "attempt to add duplicate property
      'mem2' to object (type 'container')"}}
      
      Signed-off-by: default avatarEric Auger <eric.auger@redhat.com>
      Fixes: d2623129 ("qom: Drop parameter @errp of object_property_add() & friends")
      Reviewed-by: default avatarMarkus Armbruster <armbru@redhat.com>
      
      Reviewed-by: default avatarGreg Kurz <groug@kaod.org>
      Tested-by: default avatarGreg Kurz <groug@kaod.org>
      Message-Id: <20200629193424.30280-2-eric.auger@redhat.com>
      Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      db57fef1
    • Markus Armbruster's avatar
      qom: Use returned bool to check for failure, Coccinelle part · 778a2dc5
      Markus Armbruster authored
      
      The previous commit enables conversion of
      
          foo(..., &err);
          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, &err, args2);
          -    if (err)
          +    if (!fun(args, &err, 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: 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-29-armbru@redhat.com>
      778a2dc5
    • Markus Armbruster's avatar
      qom: Make functions taking Error ** return bool, not void · 6fd5bef1
      Markus Armbruster authored
      
      See recent commit "error: Document Error API usage rules" for
      rationale.
      
      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-28-armbru@redhat.com>
      6fd5bef1
    • Markus Armbruster's avatar
      qom: Put name parameter before value / visitor parameter · 5325cc34
      Markus Armbruster authored
      
      The object_property_set_FOO() setters take property name and value in
      an unusual order:
      
          void object_property_set_FOO(Object *obj, FOO_TYPE value,
                                       const char *name, Error **errp)
      
      Having to pass value before name feels grating.  Swap them.
      
      Same for object_property_set(), object_property_get(), and
      object_property_parse().
      
      Convert callers with this Coccinelle script:
      
          @@
          identifier fun = {
              object_property_get, object_property_parse, object_property_set_str,
              object_property_set_link, object_property_set_bool,
              object_property_set_int, object_property_set_uint, object_property_set,
              object_property_set_qobject
          };
          expression obj, v, name, errp;
          @@
          -    fun(obj, v, name, errp)
          +    fun(obj, name, v, errp)
      
      Chokes on hw/arm/musicpal.c's lcd_refresh() with the unhelpful error
      message "no position information".  Convert that one manually.
      
      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.
      
      Fails to convert hw/rx/rx-gdbsim.c, because Coccinelle gets confused
      by RXCPU being used both as typedef and function-like macro there.
      Convert manually.  The other files using RXCPU that way don't need
      conversion.
      
      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-27-armbru@redhat.com>
      [Straightforwad conflict with commit 2336172d "audio: set default
      value for pcspk.iobase property" resolved]
      5325cc34
    • Markus Armbruster's avatar
      qapi: Use returned bool to check for failure, Coccinelle part · 62a35aaa
      Markus Armbruster authored
      
      The previous commit enables conversion of
      
          visit_foo(..., &err);
          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, &err);
          -    if (err)
          +    if (!fun(args, &err))
               {
                   ...
               }
      
      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-19-armbru@redhat.com>
      62a35aaa
  4. May 15, 2020
    • Markus Armbruster's avatar
      qom: Drop @errp parameter of object_property_del() · df4fe0b2
      Markus Armbruster authored
      
      Same story as for object_property_add(): the only way
      object_property_del() can fail is when the property with this name
      does not exist.  Since our property names are all hardcoded, failure
      is a programming error, and the appropriate way to handle it is
      passing &error_abort.  Most callers do that, the commit before
      previous fixed one that didn't (and got the error handling wrong), and
      the two remaining exceptions ignore errors.
      
      Drop the @errp parameter.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      Message-Id: <20200505152926.18877-19-armbru@redhat.com>
      Reviewed-by: default avatarPhilippe Mathieu-Daudé <philmd@redhat.com>
      df4fe0b2
    • Markus Armbruster's avatar
      qom: Drop parameter @errp of object_property_add() & friends · d2623129
      Markus Armbruster authored
      
      The only way object_property_add() can fail is when a property with
      the same name already exists.  Since our property names are all
      hardcoded, failure is a programming error, and the appropriate way to
      handle it is passing &error_abort.
      
      Same for its variants, except for object_property_add_child(), which
      additionally fails when the child already has a parent.  Parentage is
      also under program control, so this is a programming error, too.
      
      We have a bit over 500 callers.  Almost half of them pass
      &error_abort, slightly fewer ignore errors, one test case handles
      errors, and the remaining few callers pass them to their own callers.
      
      The previous few commits demonstrated once again that ignoring
      programming errors is a bad idea.
      
      Of the few ones that pass on errors, several violate the Error API.
      The Error ** argument must be NULL, &error_abort, &error_fatal, or a
      pointer to a variable containing NULL.  Passing an argument of the
      latter kind twice without clearing it in between is wrong: if the
      first call sets an error, it no longer points to NULL for the second
      call.  ich9_pm_add_properties(), sparc32_ledma_realize(),
      sparc32_dma_realize(), xilinx_axidma_realize(), xilinx_enet_realize()
      are wrong that way.
      
      When the one appropriate choice of argument is &error_abort, letting
      users pick the argument is a bad idea.
      
      Drop parameter @errp and assert the preconditions instead.
      
      There's one exception to "duplicate property name is a programming
      error": the way object_property_add() implements the magic (and
      undocumented) "automatic arrayification".  Don't drop @errp there.
      Instead, rename object_property_add() to object_property_try_add(),
      and add the obvious wrapper object_property_add().
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      Message-Id: <20200505152926.18877-15-armbru@redhat.com>
      [Two semantic rebase conflicts resolved]
      d2623129
  5. Apr 30, 2020
    • Kevin Wolf's avatar
      qemu-storage-daemon: Fix non-string --object properties · eaae29ef
      Kevin Wolf authored
      
      After processing the option string with the keyval parser, we get a
      QDict that contains only strings. This QDict must be fed to a keyval
      visitor which converts the strings into the right data types.
      
      qmp_object_add(), however, uses the normal QObject input visitor, which
      expects a QDict where all properties already have the QType that matches
      the data type required by the QOM object type.
      
      Change the --object implementation in qemu-storage-daemon so that it
      doesn't call qmp_object_add(), but calls user_creatable_add_dict()
      directly instead and pass it a new keyval boolean that decides which
      visitor must be used.
      
      Reported-by: default avatarCoiby Xu <coiby.xu@gmail.com>
      Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
      eaae29ef
    • Kevin Wolf's avatar
      qom: Factor out user_creatable_add_dict() · d6a5beeb
      Kevin Wolf authored
      
      The QMP handler qmp_object_add() and the implementation of --object in
      qemu-storage-daemon can share most of the code. Currently,
      qemu-storage-daemon calls qmp_object_add(), but this is not correct
      because different visitors need to be used.
      
      As a first step towards a fix, make qmp_object_add() a wrapper around a
      new function user_creatable_add_dict() that can get an additional
      parameter. The handling of "props" is only required for compatibility
      and not required for the qemu-storage-daemon command line, so it stays
      in qmp_object_add().
      
      Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
      d6a5beeb
  6. Jan 24, 2020
  7. Oct 14, 2019
  8. Feb 26, 2019
  9. Dec 11, 2018
  10. Oct 19, 2018
  11. Oct 05, 2018
    • Marc-André Lureau's avatar
      vl: list user creatable properties when 'help' is argument · 1195fa2b
      Marc-André Lureau authored
      
      Iterate over the writable class properties, sort and print them out
      with the description if available.
      
      Ex: qemu -object memory-backend-file,help
      memory-backend-file.align=int
      memory-backend-file.discard-data=bool
      memory-backend-file.dump=bool - Set to 'off' to exclude from core dump
      memory-backend-file.host-nodes=int - Binds memory to the list of NUMA host nodes
      memory-backend-file.mem-path=string
      memory-backend-file.merge=bool - Mark memory as mergeable
      memory-backend-file.pmem=bool
      memory-backend-file.policy=HostMemPolicy - Set the NUMA policy
      memory-backend-file.prealloc=bool - Preallocate memory
      memory-backend-file.share=bool - Mark the memory as private to QEMU or shared
      memory-backend-file.size=int - Size of the memory region (ex: 500M)
      
      Signed-off-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      1195fa2b
  12. May 08, 2018
  13. May 04, 2018
  14. Mar 02, 2018
  15. Feb 09, 2018
  16. Sep 19, 2017
  17. Sep 01, 2017
  18. Jun 06, 2017
    • Michael Roth's avatar
      monitor: fix object_del for command-line-created objects · c645d5ac
      Michael Roth authored
      
      Currently objects specified on the command-line are only partially
      cleaned up when 'object_del' is issued in either HMP or QMP: the
      object itself is fully finalized, but the QemuOpts are not removed.
      This results in the following behavior:
      
        x86_64-softmmu/qemu-system-x86_64 -monitor stdio \
          -object memory-backend-ram,id=ram1,size=256M
      
        QEMU 2.7.91 monitor - type 'help' for more information
        (qemu) object_del ram1
        (qemu) object_del ram1
        object 'ram1' not found
        (qemu) object_add memory-backend-ram,id=ram1,size=256M
        Duplicate ID 'ram1' for object
        Try "help object_add" for more information
      
      which can be an issue for use-cases like memory hotplug.
      
      This happens on the HMP side because hmp_object_add() attempts to
      create a temporary QemuOpts entry with ID 'ram1', which ends up
      conflicting with the command-line-created entry, since it was never
      cleaned up during the previous hmp_object_del() call.
      
      We address this by adding a check in user_creatable_del(), which
      is called by both qmp_object_del() and hmp_object_del() to handle
      the actual object cleanup, to determine whether an option group entry
      matching the object's ID is present and removing it if it is.
      
      Note that qmp_object_add() never attempts to create a temporary
      QemuOpts entry, so it does not encounter the duplicate ID error,
      which is why this isn't generally visible in libvirt.
      
      Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
      Cc: Markus Armbruster <armbru@redhat.com>
      Cc: Eric Blake <eblake@redhat.com>
      Cc: Daniel Berrange <berrange@redhat.com>
      Cc: qemu-stable@nongnu.org
      Signed-off-by: default avatarMichael Roth <mdroth@linux.vnet.ibm.com>
      Reviewed-by: default avatarDaniel P. Berrange <berrange@redhat.com>
      Reviewed-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <1496531612-22166-3-git-send-email-mdroth@linux.vnet.ibm.com>
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      c645d5ac
  19. Mar 23, 2017
  20. Mar 22, 2017
    • Eric Blake's avatar
      qom: Avoid unvisited 'id'/'qom-type' in user_creatable_add_opts · 9a6d1acb
      Eric Blake authored
      
      A regression in commit 15c2f669 caused us to silently ignore
      excess input to the QemuOpts visitor.  Later, commit ea4641
      accidentally abused that situation, by removing "qom-type" and
      "id" from the corresponding QDict but leaving them defined in
      the QemuOpts, when using the pair of containers to create a
      user-defined object. Note that since we are already traversing
      two separate items (a QDict and a QemuOpts), we are already
      able to flag bogus arguments, as in:
      
      $ ./x86_64-softmmu/qemu-system-x86_64 -nodefaults -nographic -qmp stdio -object memory-backend-ram,id=mem1,size=4k,bogus=huh
      qemu-system-x86_64: -object memory-backend-ram,id=mem1,size=4k,bogus=huh: Property '.bogus' not found
      
      So the only real concern is that when we re-enable strict checking
      in the QemuOpts visitor, we do not want to start flagging the two
      leftover keys as unvisited.  Rearrange the code to clean out the
      QemuOpts listing in advance, rather than removing items from the
      QDict.  Since "qom-type" is usually an automatic implicit default,
      we don't have to restore it (this does mean that once instantiated,
      QemuOpts is not necessarily an accurate representation of the
      original command line - but this is not the first place to do that);
      however "id" has to be put back (requiring us to cast away a const).
      
      [As a side note, hmp_object_add() turns a QDict into a QemuOpts,
      then calls user_creatable_add_opts() which converts QemuOpts into
      a new QDict. There are probably a lot of wasteful conversions like
      this, but cleaning them up is a much bigger task than the immediate
      regression fix.]
      
      CC: qemu-stable@nongnu.org
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20170322144525.18964-3-eblake@redhat.com>
      Tested-by: default avatarLaurent Vivier <lvivier@redhat.com>
      Reviewed-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      9a6d1acb
  21. Jan 12, 2017
  22. Oct 25, 2016
  23. Jul 06, 2016
    • Eric Blake's avatar
      opts-visitor: Favor new visit_free() function · 09204eac
      Eric Blake authored
      
      Now that we have a polymorphic visit_free(), we no longer need
      opts_visitor_cleanup(); which in turn means we no longer need
      to return a subtype from opts_visitor_new() nor a public upcast
      function.
      
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <1465490926-28625-6-git-send-email-eblake@redhat.com>
      Reviewed-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      09204eac
    • Eric Blake's avatar
      qapi: Add parameter to visit_end_* · 1158bb2a
      Eric Blake authored
      
      Rather than making the dealloc visitor track of stack of pointers
      remembered during visit_start_* in order to free them during
      visit_end_*, it's a lot easier to just make all callers pass the
      same pointer to visit_end_*.  The generated code has access to the
      same pointer, while all other users are doing virtual walks and
      can pass NULL.  The dealloc visitor is then greatly simplified.
      
      All three visit_end_*() functions intentionally take a void**,
      even though the visit_start_*() functions differ between void**,
      GenericList**, and GenericAlternate**.  This is done for several
      reasons: when doing a virtual walk, passing NULL doesn't care
      what the type is, but when doing a generated walk, we already
      have to cast the caller's specific FOO* to call visit_start,
      while using void** lets us use visit_end without a cast. Also,
      an upcoming patch will add a clone visitor that wants to use
      the same implementation for all three visit_end callbacks,
      which is made easier if all three share the same signature.
      
      For visitors with already track per-object state (the QMP visitors
      via a stack, and the string visitors which do not allow nesting),
      add an assertion that the caller is indeed passing the same
      pointer to paired calls.
      
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <1465490926-28625-4-git-send-email-eblake@redhat.com>
      Reviewed-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      1158bb2a
  24. May 12, 2016
    • Eric Blake's avatar
      qapi: Split visit_end_struct() into pieces · 15c2f669
      Eric Blake authored
      
      As mentioned in previous patches, we want to call visit_end_struct()
      functions unconditionally, so that visitors can release resources
      tied up since the matching visit_start_struct() without also having
      to worry about error priority if more than one error occurs.
      
      Even though error_propagate() can be safely used to ignore a second
      error during cleanup caused by a first error, it is simpler if the
      cleanup cannot set an error.  So, split out the error checking
      portion (basically, input visitors checking for unvisited keys) into
      a new function visit_check_struct(), which can be safely skipped if
      any earlier errors are encountered, and leave the cleanup portion
      (which never fails, but must be called unconditionally if
      visit_start_struct() succeeded) in visit_end_struct().
      
      Generated code in qapi-visit.c has diffs resembling:
      
      |@@ -59,10 +59,12 @@ void visit_type_ACPIOSTInfo(Visitor *v,
      |         goto out_obj;
      |     }
      |     visit_type_ACPIOSTInfo_members(v, obj, &err);
      |-    error_propagate(errp, err);
      |-    err = NULL;
      |+    if (err) {
      |+        goto out_obj;
      |+    }
      |+    visit_check_struct(v, &err);
      | out_obj:
      |-    visit_end_struct(v, &err);
      |+    visit_end_struct(v);
      | out:
      
      and in qapi-event.c:
      
      @@ -47,7 +47,10 @@ void qapi_event_send_acpi_device_ost(ACP
      |         goto out;
      |     }
      |     visit_type_q_obj_ACPI_DEVICE_OST_arg_members(v, &param, &err);
      |-    visit_end_struct(v, err ? NULL : &err);
      |+    if (!err) {
      |+        visit_check_struct(v, &err);
      |+    }
      |+    visit_end_struct(v);
      |     if (err) {
      |         goto out;
      
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <1461879932-9020-20-git-send-email-eblake@redhat.com>
      [Conflict with a doc fixup resolved]
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      15c2f669
    • Eric Blake's avatar
      qom: Wrap prop visit in visit_start_struct · ad739706
      Eric Blake authored
      
      The qmp-input visitor was allowing callers to play rather fast
      and loose: when visiting a QDict, you could grab members of the
      root dictionary without first pushing into the dict; the final
      such culprit was the QOM code for converting to and from object
      properties.  But we are about to tighten the input visitor, at
      which point user_creatable_add_type() as called with a QMP input
      visitor via qmp_object_add() MUST follow the same paradigms as
      everyone else, of pushing into the struct before grabbing its
      keys.
      
      The use of 'err ? NULL : &err' is temporary; a later patch will
      clean that up when it splits visit_end_struct().
      
      Furthermore, note that both callers always pass qdict, so we can
      convert the conditional into an assert and reduce indentation.
      
      The change has no impact to the testsuite now, but is required to
      avoid a failure in tests/test-netfilter once qmp-input is made
      stricter to detect inconsistent 'name' arguments on the root visit.
      
      Since user_creatable_add_type() is also called with OptsVisitor
      through user_creatable_add_opts(), we must also check that there
      is no negative impact there; both pre- and post-patch, we see:
      
      $ ./x86_64-softmmu/qemu-system-x86_64 -nographic -nodefaults -qmp stdio -object secret,id=sec0,data=letmein,format=raw,foo=bar
      qemu-system-x86_64: -object secret,id=sec0,data=letmein,format=raw,foo=bar: Property '.foo' not found
      
      That is, the only new checking that the new visit_end_struct() can
      perform is for excess input, but we already catch excess input
      earlier in object_property_set().
      
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <1461879932-9020-10-git-send-email-eblake@redhat.com>
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      ad739706
  25. Apr 28, 2016
    • Markus Armbruster's avatar
      qom: -object error messages lost location, restore it · 51b9b478
      Markus Armbruster authored
      
      qemu_opts_foreach() runs its callback with the error location set to
      the option's location.  Any errors the callback reports use the
      option's location automatically.
      
      Commit 90998d58 moved the actual error reporting from "inside"
      qemu_opts_foreach() to after it.  Here's a typical hunk:
      
      	 if (qemu_opts_foreach(qemu_find_opts("object"),
          -                          object_create,
          -                          object_create_initial, NULL)) {
          +                          user_creatable_add_opts_foreach,
          +                          object_create_initial, &err)) {
          +        error_report_err(err);
      	     exit(1);
      	 }
      
      Before, object_create() reports from within qemu_opts_foreach(), using
      the option's location.  Afterwards, we do it after
      qemu_opts_foreach(), using whatever location happens to be current
      there.  Commonly a "none" location.
      
      This is because Error objects don't have location information.
      Problematic.
      
      Reproducer:
      
          $ qemu-system-x86_64 -nodefaults -display none -object secret,id=foo,foo=bar
          qemu-system-x86_64: Property '.foo' not found
      
      Note no location.  This commit restores it:
      
          qemu-system-x86_64: -object secret,id=foo,foo=bar: Property '.foo' not found
      
      Note that the qemu_opts_foreach() bug just fixed could mask the bug
      here: if the location it leaves dangling hasn't been clobbered, yet,
      it's the correct one.
      
      Reported-by: default avatarEric Blake <eblake@redhat.com>
      Cc: Daniel P. Berrange <berrange@redhat.com>
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <1461767349-15329-4-git-send-email-armbru@redhat.com>
      Reviewed-by: default avatarDaniel P. Berrange <berrange@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      [Paragraph on Error added to commit message]
      51b9b478
  26. Mar 22, 2016
    • Markus Armbruster's avatar
      include/qemu/osdep.h: Don't include qapi/error.h · da34e65c
      Markus Armbruster authored
      
      Commit 57cb38b3 included qapi/error.h into qemu/osdep.h to get the
      Error typedef.  Since then, we've moved to include qemu/osdep.h
      everywhere.  Its file comment explains: "To avoid getting into
      possible circular include dependencies, this file should not include
      any other QEMU headers, with the exceptions of config-host.h,
      compiler.h, os-posix.h and os-win32.h, all of which are doing a
      similar job to this file and are under similar constraints."
      qapi/error.h doesn't do a similar job, and it doesn't adhere to
      similar constraints: it includes qapi-types.h.  That's in excess of
      100KiB of crap most .c files don't actually need.
      
      Add the typedef to qemu/typedefs.h, and include that instead of
      qapi/error.h.  Include qapi/error.h in .c files that need it and don't
      get it now.  Include qapi-types.h in qom/object.h for uint16List.
      
      Update scripts/clean-includes accordingly.  Update it further to match
      reality: replace config.h by config-target.h, add sysemu/os-posix.h,
      sysemu/os-win32.h.  Update the list of includes in the qemu/osdep.h
      comment quoted above similarly.
      
      This reduces the number of objects depending on qapi/error.h from "all
      of them" to less than a third.  Unfortunately, the number depending on
      qapi-types.h shrinks only a little.  More work is needed for that one.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      [Fix compilation without the spice devel packages. - Paolo]
      Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      da34e65c
Loading