marcandre.lur...@redhat.com writes: > From: Marc-André Lureau <marcandre.lur...@redhat.com> > > Hi, > > Among the QEMU developers, there is a desire to use Rust. (see previous > thread from Stefan "Why QEMU should move from C to Rust", the rust-vmm > related projects and other experiments). > > Thanks to our QAPI type system and the associate code generator, it is > relatively straightforward to create Rust bindings for the generated C > types (also called sys/ffi binding) and functions. (rust-bindgen could > probably do a similar job, but it would probably bring other issues). > This provides an important internal API already. > > Slightly more complicated is to expose a Rust API for those, and provide > convenient conversions C<->Rust. Taking inspiration from glib-rs > binding, I implemented a simplified version of the FromGlib/ToGlib > traits, with simpler ownership model, sufficient for QAPI needs. > > The usage is relatively simple: > > - from_qemu_none(ptr: *const sys::P) -> T > Return a Rust type T for a const ffi pointer P. > > - from_qemu_full(ptr: *mut sys::P) -> T > Return a Rust type T for a ffi pointer P, taking ownership. > > - T::to_qemu_none() -> Stash<P> > Returns a borrowed ffi pointer P (using a Stash to destroy "glue" > storage data, if any). > > - T::to_qemu_full() -> P > Returns a ffi pointer P. (P resources are leaked/passed to C/ffi) > > With those traits, it's relatively easy to implement the QMP callbacks. > With enough interest, we could eventually start rewriting QGA in > Rust, as it is a simple service. See qga/qmp.rs for some examples. > We could also try to tackle qemu itself.
Up to here, you're talking about *internal* interfaces. Correct? Your motivation is enabling use of Rust in QEMU. Correct? > Finally, given that the QAPI types are easy to serialize, it was simple > to use "serde" on them, and provide a D-Bus interface for QMP with zbus. > (a similar approach could probably be taken for other protocols, that > could be dynamically loaded... anyone like protobuf better?) QMP is an *external* interface. It supports compatible evolution: we can make certain kinds of changes without affecting clients. These include: * Adding optional arguments * Adding results * Adding values to an enumeration type, branches to a union or alternate * Reordering members of enumerations, structs, unions * Turning an argument type into an alternate with the old type as branch We've made use of this extensively. See also docs/devel/qapi-code-gen.txt section "Compatibility considerations." How do such changes affect clients of the proposed D-Bus interface? > This PoC modifies qemu-ga to provide the interface on the session bus: > $ qga/qemu-ga -m unix-listen -p /tmp/qga.sock -t /tmp -v > $ busctl --user introspect org.qemu.qga /org/qemu/qga org.qemu.QgaQapi > ... > $ busctl --user call org.qemu.qga /org/qemu/qga org.qemu.QgaQapi > GuestSetVcpus aa\{sv\} 1 2 logical-id x 0 online b 1 > ... > > Note: the generated code doesn't work with the qemu schema, there is a > couple of fixme/todo left. > > Shameful pain point: meson & cargo don't play nicely together. > > Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com>