Skip to content
This repository was archived by the owner on Nov 6, 2024. It is now read-only.

RFC: enhance kvm-binding to optionally support serde #7

Closed
wants to merge 4 commits into from

Conversation

jiangliu
Copy link
Member

This PR implements serde for kvm-binding based on the proposed vmm-serde crate (rust-vmm/community#76).
It's based on the @aghecenco work (#4), but optionally implementing de/serialization by using rust proc macro.
It implements the Serialize/Deserialize trait by:

  1. post-process source files generated by the bindgen, adding `#[derive(SerializeFfi, DeserializeFfi/DeserializeFfiFam)]' to suitable structs.
  2. the vmm_serde crate implements proc_macro_derive(SerializeFfi, DeseriailizeFfi, DeserializeFfiFam) by using the serde_bytes crate.
  3. Implement trait SizeofFamStruct to support data structures with flexible array member.

The first patch remvoes Cargo.lock from the crate, the second patch imports add_serde.py from @aghecenco previous work with modification, the third patch builds the infrastructure to serde, and the last patch commits code generated by add_serde.py.

jiangliu and others added 4 commits September 18, 2019 15:54
The kvm-binding is a library crate, so remove the Cargo.lock file to
avoid unnecessary changes.

Signed-off-by: Liu Jiang <[email protected]>
Import the vmm-serde crate and implement trait SizeofFamStruct for
KVM structs with flexible array member.

Signed-off-by: Liu Jiang <[email protected]>
Import add_serde.py from
https://github.com/aghecenco/kvm-bindings/tree/serde_old
with modifications to integrate with the vmm_serde crate.

Rules for preprocess the bindgen generated sources files:
For each `struct` with attribute `#[derive(xxx)]`
- skip if it already implements the Serialize trait.
- skip if it's in the black list.
- add `#[derive(SerializeFfi, DeserializeFfiFam)]` if it's a struct with
  a flexible array as the last field.
- otherwise add `#[derive(SerializeFfi, DeserializeFfi)]`.

Signed-off-by: Xingjun Liu <[email protected]>
Signed-off-by: Alexandra Iordache <[email protected]>
Add #[derive(SerializeFfi, DeserializeFfi) to KVM structs using the
script tool/add_derive.py.

Signed-off-by: Liu Jiang <[email protected]>
@jiangliu jiangliu force-pushed the serde branch 2 times, most recently from 4923b87 to fe9b240 Compare September 19, 2019 02:09
Copy link

@yisun-git yisun-git left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can serde.rs be common, i.e. work for arm too?

@jiangliu
Copy link
Member Author

Can serde.rs be common, i.e. work for arm too?
serde is platform independent, but I have no ARM env available so only enabled it fort x86.

@yisun-git
Copy link

yisun-git commented Sep 26, 2019 via email

@bjzhjing
Copy link

bjzhjing commented Nov 15, 2019

@jiangliu For kvm_nested_state, is it sensible to have serde_ffi_fam_impl implemented on it? The structure does not meet the condition to work with SizeofFamStruct trait. Cargo test --all-features has associated failures. Please help confirm this.

bjzhjing added a commit to bjzhjing/cloud-hypervisor that referenced this pull request Dec 12, 2019
To apply the serde functions provided by the following links for kvm-bindings
serialize/deserialize, switch both kvm-bindings and kvm-ioctls urls to internal
branch links.

rust-vmm/kvm-bindings#7

Signed-off-by: Cathy Zhang <[email protected]>
bjzhjing added a commit to bjzhjing/cloud-hypervisor that referenced this pull request Dec 13, 2019
To apply the serde functions provided by the following links for kvm-bindings
serialize/deserialize, switch both kvm-bindings and kvm-ioctls urls to internal
branch links.

rust-vmm/kvm-bindings#7

Signed-off-by: Cathy Zhang <[email protected]>
@alxiord
Copy link
Member

alxiord commented Dec 19, 2019

Hey @jiangliu, I've been giving this extensive thought and come to the following conclusions:

  • I no longer agree with the FFI byte-dump serialization approach. It's unsafe, it's nearly impossible to debug, and very tricky to work around in case of a corrupt snapshot. I much rather prefer the initial solution: let serde do its thing and serialize structs as structs, giving the crate consumer the highest granularity of the data and the possibility to dump it in a (machine and) human readable format like JSON.
  • I also no longer agree with autogenerating serialization support. Snapshot deserialization essentially introduces a new attack surface, so I advocate for paying close attention to everything that's read from a file into process memory. That means manual inspection of every serializable item, and careful considering whether serialization is absolutely necessary for a binding / field. (For instance, padding should alway be skipped.)

I initially formulated these points in #11 but that didn't exactly generate traction so would you take a peek at #14 instead?

@jiangliu
Copy link
Member Author

Hey @jiangliu, I've been giving this extensive thought and come to the following conclusions:

  • I no longer agree with the FFI byte-dump serialization approach. It's unsafe, it's nearly impossible to debug, and very tricky to work around in case of a corrupt snapshot. I much rather prefer the initial solution: let serde do its thing and serialize structs as structs, giving the crate consumer the highest granularity of the data and the possibility to dump it in a (machine and) human readable format like JSON.
  • I also no longer agree with autogenerating serialization support. Snapshot deserialization essentially introduces a new attack surface, so I advocate for paying close attention to everything that's read from a file into process memory. That means manual inspection of every serializable item, and careful considering whether serialization is absolutely necessary for a binding / field. (For instance, padding should alway be skipped.)

I initially formulated these points in #11 but that didn't exactly generate traction so would you take a peek at #14 instead?

Hi Alexandra,
Thanks for the great work. I'm work with hand-writing serde implementations for kvm-bindings, and it's step forward towards hand-writing kvm-binding itself:)
Apparently, snapshot has more strict requirements on kvm-binding serde implementation than live-upgrading. So it should ok ok for us to migrate to the new implementation.
Thanks for your great work again:)

@sboeuf
Copy link

sboeuf commented Sep 3, 2020

Trying to revive this thread! I'd really like to see every project rely on the same kvm-bindings crate, hence I'd like to propose that we all decide to move to versionize crate. Cloud-Hypervisor does not rely on it yet, but I'd be totally fine making the change since I can see how versionize can help everybody handle versioning in the future.

This means we'd need to send a PR with this patch firecracker-microvm@b581698 to derive all KVM structures with Versionize. That would give us a kvm-bindings crate usable both from Firecracker and Cloud-Hypervisor (after we'd do the necessary changes).

That being said, if we agree on this move, I think it'd be important to move versionize to rust-vmm as it's kinda weird having a rust-vmm crate relying on a Firecracker crate :) (should be the other way around).

@sameo @rbradford @aghecenco @andreeaflorescu @jiangliu

@jiangliu
Copy link
Member Author

jiangliu commented Sep 3, 2020

Trying to revive this thread! I'd really like to see every project rely on the same kvm-bindings crate, hence I'd like to propose that we all decide to move to versionize crate. Cloud-Hypervisor does not rely on it yet, but I'd be totally fine making the change since I can see how versionize can help everybody handle versioning in the future.

This means we'd need to send a PR with this patch firecracker-microvm@b581698 to derive all KVM structures with Versionize. That would give us a kvm-bindings crate usable both from Firecracker and Cloud-Hypervisor (after we'd do the necessary changes).

That being said, if we agree on this move, I think it'd be important to move versionize to rust-vmm as it's kinda weird having a rust-vmm crate relying on a Firecracker crate :) (should be the other way around).

@sameo @rbradford @aghecenco @andreeaflorescu @jiangliu

I'm OK to migrate to versionize crate once it's moved to rust-vmm, so we could have common code base.
We can migrate our vmm-serde based implementation to versionize crate.

@andreeaflorescu
Copy link
Member

We were also looking at using a proxy crate for the state instead of adding the serialization macros in the kvm-bindings structure directly. I find adding either serde or versionize macros directly in kvm-bindings as a bit too intrusive because there is not getting away from it :))

I believe @alexandruag is working on a prototype, and can probably give you some more details.

Are we actually okay with closing this PR or do we want to keep it open for the discussions?

@jiangliu
Copy link
Member Author

jiangliu commented Sep 3, 2020

It's OK to close this PR and open another issue for discussion.

@sboeuf
Copy link

sboeuf commented Sep 3, 2020

We were also looking at using a proxy crate for the state instead of adding the serialization macros in the kvm-bindings structure directly. I find adding either serde or versionize macros directly in kvm-bindings as a bit too intrusive because there is not getting away from it :))

But if we add one more layer between versionize and kvm-bindings, this will introduce lots of duplication and maintenance, won't it? As long as we agree that versionize can live on rust-vmm, we can simply decide that deriving kvm-bindings structures with Versionize is acceptable.

I believe @alexandruag is working on a prototype, and can probably give you some more details.

Cool!

Are we actually okay with closing this PR or do we want to keep it open for the discussions?

Let's keep it open for the discussion.

@andreeaflorescu
Copy link
Member

But if we add one more layer between versionize and kvm-bindings, this will introduce lots of duplication and maintenance, won't it?

@sboeuf I don't think that the cost is so high TBH, but then it's probably better to discuss it on the actual proposal :)) I have a few concerns with adding serialize support directly on the bindings. Over time it can add a non-negligible size overhead. Then the second thing is that bindings in their current form (with the padding definition and FAM structs) is not exactly the "KVM state" in a sens.

@sboeuf
Copy link

sboeuf commented Sep 3, 2020

Closing to continue the discussion on #24

@sboeuf sboeuf closed this Sep 3, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants