ToDo/CodeTransitions: Difference between revisions

From QEMU
Line 18: Line 18:


Ideally all device models should be QOM objects (usually deriving from DeviceState or one of its subclasses). However we still have a fairly large number of devices which are coded in an ad-hoc way. These should all be converted to QOM but it is a big job. See [[QOMConventions]] for the latest guidance on how to structure a QOM device.
Ideally all device models should be QOM objects (usually deriving from DeviceState or one of its subclasses). However we still have a fairly large number of devices which are coded in an ad-hoc way. These should all be converted to QOM but it is a big job. See [[QOMConventions]] for the latest guidance on how to structure a QOM device.
* The QEMUMachine is being replaced with a QOM hierarchy, details on Features/QOM/Machine.
* The QEMUMachine is being replaced with a QOM hierarchy, details on [[Features/QOM/Machine]].


=== Use DeviceClass::realize rather than SysBusDeviceClass::init ===
=== Use DeviceClass::realize rather than SysBusDeviceClass::init ===

Revision as of 09:24, 13 May 2014

Code Transitions

This page exists to keep a record of API and style transitions in the QEMU codebase. It's quite common for us to introduce a new API or design guideline, but not be able to convert the whole of QEMU's existing code over to it at once. So at any point in time some of QEMU will still be using the old deprecated approaches.

The aim of this page is twofold:

  • as a quick reference for less frequent contributors, to give an idea of things to avoid copying from old code
  • to embarrass ourselves into maybe finishing off some of these transitions

If you add a new transition to this page, please also briefly mention it in the DeveloperNews page with a link to here.

Ongoing transitions

Making all devices QOM objects

Ideally all device models should be QOM objects (usually deriving from DeviceState or one of its subclasses). However we still have a fairly large number of devices which are coded in an ad-hoc way. These should all be converted to QOM but it is a big job. See QOMConventions for the latest guidance on how to structure a QOM device.

Use DeviceClass::realize rather than SysBusDeviceClass::init

All new devices derived from SysBusDevice should use QOM realize (DeviceClass::realize) rather than SysBusDeviceClass::init. Work is under way to convert existing devices. It is permissable to implement neither realize nor init.

(QOM realize was first presented by Anthony on the 2012-01-31 KVM call and after much debate of scope minimally implemented for DeviceState by Andreas for v1.4. Some extensions by Paolo (recursive realization) are still pending device preparations.)

MemoryRegionOps old_mmio

The MemoryRegionOps struct has an old_mmio field which was added to make it simpler to convert devices to the MemoryRegion API (it allows use of separate byte, halfword and word read and write functions, rather than combined read and write functions which take the access size as a parameter). This is still being used by about 40 devices -- it would be nice to convert those to the new style and remove old_mmio entirely.

Using VMStateDescription rather than load and save functions

The preferred way to implement state save/load for migration is to describe the device state using a VMStateDescription struct. Some devices are still using the old vmstate_register() API, however; these all need converting. (This is often going to involve also converting the device to use QOM.)

Coding whitespace and brace style

New QEMU code should follow the style guidelines in CODING_STYLE, and in particular this means 4-space indent, no hardcoded tab, braces on all if() statements. However much of the codebase is old and doesn't follow this. Changes to areas of existing code should generally update the lines of code they're touching anyway, but we prefer to avoid wholesale "fix coding style" patches because they obscure the change history for tools like "git blame".

Error reporting

Several transitions are in flight here:

  • Avoid ErrorClass values other than ERROR_CLASS_GENERIC_ERROR unless you have a specific reason. Prefer error_setg() & friends over error_set() & friends.
  • The QError macros QERR_ are a hack to help with the transition to the current error.h API (human-readable message rather than JSON argument, see commit df1e608). Avoid them in new code, use simple message strings instead.
  • qerror_report() is a transitional interface to help with converting existing HMP commands to QMP. It should not be used elsewhere. Use Error objects instead with error_propagate() and error_setg() instead.
  • Use error_report() & friends instead of fprintf(stderr, ...). Unlike fprintf(), it does the right thing in human monitor context. It also adds program name and error location when appropriate, and supports timestamps (-msg timestamp=on).
  • Avoid error_is_set(errp); it is simpler to just test for non-NULL *errp in the first place.

QMP legacy interface to the QAPI

There are only a few QMP commands missing to be converted from the QMP legacy interface to the QAPI. The most important of them are do_device_add() and do_qmp_capabilities() (which may or may not need session support to be converted). You can find more details in the QMP TODO page.

Makefile

Although object specific options are traditionally implemented with Target-specific Variable Values, such as

   $(obj)/arm-a64.o: QEMU_CFLAGS += -I$(libvixldir)

, currently the cflags and libs should be specified as per-object variable in Makefile.objs and friends, which will be automatically expanded into the compiling and the linking commands. E.g. in block/Makefile.objs:

   ...
   iscsi.o-cflags     := $(LIBISCSI_CFLAGS)
   iscsi.o-libs       := $(LIBISCSI_LIBS)
   curl.o-cflags      := $(CURL_CFLAGS)
   curl.o-libs        := $(CURL_LIBS)
   ...

where $(obj)/ is not needed compared to the old way.

.gitignore

While CVS required an ignore file per directory, git allows for a single ignore file at the top of the tree to describe the entire project. We have an unfortunate mix of using the top file to ignore files in subdirectories, while using nested files to ignore other files. Ideally, there should be only a single top-level gitignore that covers everything for the project.

Modern shell scripting

Various shell files contain a mix between obsolete `` and modern $(); use of `` is only required when using /bin/sh on Solaris. It would be nice to convert to using $() everywhere, or at least in all bash scripts, as well as in all scripts that are known to not be run on Solaris. While at it, there are some other places we can simplify to rely on POSIX shell semantics, such as using $PWD instead of $(pwd).

Completed transitions

  • Everything is using the MemoryRegion API now!
  • Users of old_portio have all been updated and the support removed