-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plugin Callback Issues in Rust Library #21
Comments
Note the actual repo is https://gitlab.com/nbdkit/nbdkit This is a mirror. And out of date because I notice the mirroring stopped working ... @asomers ^ |
|
Yes, I think both of those features could be added. Would you care to submit a PR? |
A posted a simple implementation of |
|
For the other change see https://gitlab.com/nbdkit/nbdkit/-/merge_requests/23 |
See: libguestfs#21 Tested by applying the following patch to the example plugin and running it with verbose enabled: --- a/plugins/rust/examples/ramdisk.rs +++ b/plugins/rust/examples/ramdisk.rs @@ -43,6 +43,12 @@ struct RamDisk { } impl Server for RamDisk { + fn after_fork() -> Result<()> { + // A place to start background threads. + eprintln!("forked"); + Ok(()) + } + fn get_size(&self) -> Result<i64> { Ok(DISK.lock().unwrap().len() as i64) } @@ -76,4 +82,4 @@ impl Server for RamDisk { } } -plugin!(RamDisk {thread_model, write_at}); +plugin!(RamDisk {thread_model, write_at, after_fork});
The underlying plugin API allows the open method to return an error (by returning NULL). However this was not mirrored in the rust bindings because you could only return a boxed object (equivalent to returning a non-NULL object in C). Modify the rust API so Result<> is required. The API changes as follows, requiring all plugins to change: - fn open(readonly: bool) -> Box<dyn Server> where Self: Sized; + fn open(readonly: bool) -> Result<Box<dyn Server>> where Self: Sized; Trivially this can be done by surrounding the return value of the existing open method with Ok(...) Tested by applying the following patch to example.rs: --- a/plugins/rust/examples/ramdisk.rs +++ b/plugins/rust/examples/ramdisk.rs @@ -52,7 +52,8 @@ impl Server for RamDisk { } fn open(_readonly: bool) -> Result<Box<dyn Server>> { - Ok(Box::<RamDisk>::default()) + // Ok(Box::<RamDisk>::default()) + Err(Error::new(libc::EINVAL, "oops")) } fn read_at(&self, buf: &mut [u8], offset: u64) -> Result<()> { and observing the behaviour when connecting to the plugin: nbdkit: ramdisk[1]: debug: ramdisk: open readonly=0 exportname="" tls=0 nbdkit: ramdisk[1]: debug: ramdisk: default_export readonly=0 tls=0 nbdkit: ramdisk[1]: error: oops See: libguestfs#21
For reference using
nbdkit = "0.2.0"
(appears to be latest version on crates.io)Noticed a couple gaps in the rust library for writing plugins:
open() does not return
Result<Box<dyn Server>>
, instead it simply returnsBox<dyn Server>
there is no after_fork() callback. I ran into some bugs where a lazy_static tokio runtime was being accessed (and therefor initialized) too early (before fork). this resulted in failures when the runtime was used after fork() (presumably due to the loss of the runtime's internal threads). it would be nice to have after_fork() to verify at startup time that the runtime is in a good state (and panic accordingly if not). in general, it appears inconvenient to spin up background threads for Rust plugins. right now these checks can only be done retrospectively when a connection is opened, which is undesirable (server should fail to start up rather than mislead user into thinking it is good-to-go until an actual connections happens.)
The text was updated successfully, but these errors were encountered: