@@ -30,8 +30,8 @@ use thiserror::Error;
3030use vmbus_async:: async_dgram:: AsyncRecvExt ;
3131use vmbus_channel:: bus:: OfferParams ;
3232use vmbus_channel:: gpadl_ring:: GpadlRingMem ;
33+ use vmbus_channel:: simple:: SaveRestoreSimpleVmbusDevice ;
3334use vmbus_channel:: simple:: SimpleVmbusDevice ;
34- use vmcore:: save_restore:: SavedStateNotSupported ;
3535use zerocopy:: FromBytes ;
3636use zerocopy:: IntoBytes ;
3737
@@ -51,7 +51,7 @@ impl VmbfsDevice {
5151
5252#[ async_trait]
5353impl SimpleVmbusDevice for VmbfsDevice {
54- type SavedState = SavedStateNotSupported ;
54+ type SavedState = save_restore :: state :: SavedState ;
5555 type Runner = VmbfsChannel ;
5656
5757 fn offer ( & self ) -> OfferParams {
@@ -93,12 +93,9 @@ impl SimpleVmbusDevice for VmbfsDevice {
9393 fn supports_save_restore (
9494 & mut self ,
9595 ) -> Option <
96- & mut dyn vmbus_channel:: simple:: SaveRestoreSimpleVmbusDevice <
97- SavedState = Self :: SavedState ,
98- Runner = Self :: Runner ,
99- > ,
96+ & mut dyn SaveRestoreSimpleVmbusDevice < SavedState = Self :: SavedState , Runner = Self :: Runner > ,
10097 > {
101- None
98+ Some ( self )
10299 }
103100}
104101
@@ -108,6 +105,8 @@ pub struct VmbfsChannel {
108105 state : State ,
109106 #[ inspect( mut ) ]
110107 pipe : vmbus_async:: pipe:: MessagePipe < GpadlRingMem > ,
108+ // A scratch buffer for reading messages. This is allocated once and reused for each message.
109+ // It does not hold any meaningful state.
111110 buf : Vec < u8 > ,
112111}
113112
@@ -327,3 +326,60 @@ enum DeviceError {
327326 #[ error( "read too large" ) ]
328327 ReadTooLarge ,
329328}
329+
330+ mod save_restore {
331+ use super :: * ;
332+
333+ pub mod state {
334+ use mesh:: payload:: Protobuf ;
335+ use vmcore:: save_restore:: SavedStateRoot ;
336+
337+ #[ derive( Copy , Clone , Protobuf ) ]
338+ #[ mesh( package = "vmbfs" ) ]
339+ pub enum State {
340+ #[ mesh( 1 ) ]
341+ VersionRequest ,
342+ #[ mesh( 2 ) ]
343+ Ready ,
344+ }
345+
346+ #[ derive( Protobuf , SavedStateRoot ) ]
347+ #[ mesh( package = "vmbfs" ) ]
348+ pub struct SavedState {
349+ #[ mesh( 1 ) ]
350+ pub state : State ,
351+ }
352+ }
353+
354+ impl SaveRestoreSimpleVmbusDevice for VmbfsDevice {
355+ fn save_open ( & mut self , runner : & Self :: Runner ) -> state:: SavedState {
356+ let Self :: Runner {
357+ state,
358+ pipe : _,
359+ buf : _,
360+ } = runner;
361+ state:: SavedState {
362+ state : match state {
363+ State :: VersionRequest => state:: State :: VersionRequest ,
364+ State :: Ready => state:: State :: Ready ,
365+ } ,
366+ }
367+ }
368+
369+ fn restore_open (
370+ & mut self ,
371+ saved_state : Self :: SavedState ,
372+ channel : vmbus_channel:: RawAsyncChannel < GpadlRingMem > ,
373+ ) -> Result < Self :: Runner , vmbus_channel:: channel:: ChannelOpenError > {
374+ let Self :: SavedState { state } = saved_state;
375+ Ok ( VmbfsChannel {
376+ state : match state {
377+ state:: State :: VersionRequest => State :: VersionRequest ,
378+ state:: State :: Ready => State :: Ready ,
379+ } ,
380+ pipe : vmbus_async:: pipe:: MessagePipe :: new ( channel) ?,
381+ buf : vec ! [ 0 ; protocol:: MAX_MESSAGE_SIZE ] ,
382+ } )
383+ }
384+ }
385+ }
0 commit comments