Am 05.06.2012 03:00, schrieb Michael Roth:
This is an import of Anthony's qidl compiler, with some changes squashed
in to add support for doing the visitor generation via QEMU's qapi code
generators rather than directly.
Documentation has been imported as well, as is also viewable at:
https://github.com/aliguori/qidl/blob/master/qc.md
This will be used to add annotations to device structs to aid in
generating visitors that can be used to serialize/unserialize them.
Signed-off-by: Michael Roth<address@hidden>
---
scripts/qc.md | 331 ++++++++++++++++++++++++++++++++++++++
scripts/qc.py | 494 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 825 insertions(+), 0 deletions(-)
create mode 100644 scripts/qc.md
create mode 100755 scripts/qc.py
diff --git a/scripts/qc.md b/scripts/qc.md
new file mode 100644
index 0000000..4cf4b21
--- /dev/null
+++ b/scripts/qc.md
I think docs/ would be a better place than scripts/
+Getting Started
+---------------
+
+The first step is to move your device struct definition to a header file. This
+header file should only contain the struct definition and any preprocessor
+declarations you need to define the structure. This header file will act as
+the source for the QC IDL compiler.
+
+Do not include any function declarations in this header file as QC does not
+understand function declarations.
Couldn't we use a header file (or even source file) that has some magic
markers for the IDL compiler? Like:
... random stuff ...
/* QIDL START */
struct Foo {
...
};
/* QIDL END */
... random stuff ...
Adding a new header file for each device really doesn't look like a
desirable thing, and this way it could be avoided.
+Determining What State Gets Saved
+---------------------------------
+
+By default, QC saves every field in a structure it sees. This provides maximum
+correctness by default. However, device structures generally contain state
+that reflects state that is in someway duplicated or not guest visible. This
+more often that not reflects design implementation details.
+
+Since design implementation details change over time, saving this state makes
+compatibility hard to maintain since it would effectively lock down a device's
+implementation.
+
+QC allows a device author to suppress certain fields from being saved although
+there are very strict rules about when this is allowed and what needs to be
done
+to ensure that this does not impact correctness.
+
+There are three cases where state can be suppressed: when it is **immutable**,
+**derived**, or **broken**. In addition, QC can decide at run time whether to
+suppress a field by assigning it a **default** value.
What about fields that have a known state or whose state doesn't matter?
For example, when migrating a disk, we know that no I/O requests are in
flight because they are flushed before sending the device state.
The fields describing the in-flight request are not immutable, because
the do change a lot during runtime. They are not really derived either
because they don't depend on other fields and they don't need a
post-load function. Broken implies that there is a bug, but there isn't.
It's just that their value after migration simply doesn't matter.
+It can be subtle whether a field is truly immutable. A good example is a
+*QEMUTimer*. Timer's will usually have their timeout modified with a call to
+*qemu_mod_timer()* even though they are only assigned in the device
+initialization function.
+
+If the timer is always modified with a fixed value that is not dependent on
+guest state, then the timer is immutable since it's unaffected by the state of
+the guest.
+
+On the other hand, if the timer is modified based on guest state (such as a
+guest programmed time out), then the timer carries state. It may be necessary
+to save/restore the timer or mark it as **_derived** and work with it
+accordingly.
Another instance of the above problem: What if a timer value is changed
dynamically for example as an optimisation, but for correctness it's not
really important what it is?
And even with a fixed timeout, as long as it's guest visible, can you
avoid transferring it, strictly speaking? It carries information about
when the next timeout occurs.
+### Default Values
+
+In many cases, a field that gets marked broken was not originally saved because
+in the vast majority of the time, the field does not contain a meaningful
value.
+
+In the case of our *thr* example, the field usually does not have a meaningful
+value.
+
+Instead of always saving the field, QC has another mechanism that allows the
+field to be saved only when it has a meaningful value. This is done using the
+**_default()** marker. The default marker tells QC that if the field currently
+has a specific value, do not save the value as part of serialization.
+
+When loading a field, QC will assign the default value to the field before it
+tries to load the field. If the field cannot be loaded, QC will ignore the
+error and rely on the default value.
+
+Using default values, we can fix broken fields while also minimizing the cases
+where we break live migration compatibility. The **_default()** marker can be
+used in conjunction with the **_broken** marker. We can extend our example as
+follows:
+
+ typedef struct SerialDevice {
+ SysBusDevice parent;
+
+
+ uint8_t thr _default(0); // transmit holding register
+ uint8_t lsr; // line status register
+ uint8_t ier; // interrupt enable register
+
+ int _derived int_pending; // whether we have a pending queued interrupt
+ CharDriverState _immutable *chr;
+ } SerialDevice;
+
+The following guidelines should be followed when using a default marker:
+
+ 1. Is the field set to the default value both during device initialization and
+ whenever the field is no longer in use?
+
+ 2. If the non-default value is expected to occur often, then consider using
the
+ **_broken** marker along with the default marker and using a flag day to
+ remove the **_broken** marker.
+
+ 3. In general, setting default values as the value during device
initialization
+ is a good idea even if the field was never broken. This gives us maximum
+ flexibility in the long term.
+
+ 4. Never change a default value without renaming a field. The default value
is
+ part of the device's ABI.
+
+The first guideline is particularly important. In the case of QEMU's real
+*SerialDevice*, it would be necessary to add code to set the *thr* register to
+zero after the byte has been successfully transmitted. Otherwise, it is
+unlikely that it would ever contain the default value.
Does this use subsections internally? How would we convert existing
subsections that have a specific name and may contain more than one
field? We also have is_needed functions that are more complex than just
comparing to a default value.
So I guess my real question is what the concept for maintaining
migration compatibility is.