Add a flag (modifies_fd) to the call structure in generator/API.ml
which is set to true if the handle call may do something with the
file descriptor. That is, it is true for all calls which are or may
call aio_notify_*, including all synchronous commands like
nbd_connect or nbd_opt_go.

The motivation for this is that the asynchronous handle in the Rust
bindings uses its own loop for polling, modifying the file descriptor
outside of this loop may cause unexpected behaviour. Including that the
handle may hang. All commands which set this flag to true will be
excluded from that handle. The asynchronous (aio_*) functions will be
used instead.
---
 generator/API.ml  | 32 ++++++++++++++++++++++++++++++++
 generator/API.mli |  7 +++++++
 2 files changed, 39 insertions(+)

diff --git a/generator/API.ml b/generator/API.ml
index 99fcb82..b0f5e2a 100644
--- a/generator/API.ml
+++ b/generator/API.ml
@@ -33,6 +33,7 @@ type call = {
   is_locked : bool;
   may_set_error : bool;
   async_kind : async_kind option;
+  modifies_fd: bool;
   mutable first_version : int * int;
 }
 and arg =
@@ -255,6 +256,7 @@ let default_call = { args = []; optargs = []; ret = RErr;
                      permitted_states = [];
                      is_locked = true; may_set_error = true;
                      async_kind = None;
+                     modifies_fd = false;
                      first_version = (0, 0) }
 
 (* Calls.
@@ -1162,6 +1164,7 @@ Return true if option negotiation mode was enabled on 
this handle.";
     default_call with
     args = []; ret = RErr;
     permitted_states = [ Negotiating ];
+    modifies_fd = true;
     shortdesc = "end negotiation and move on to using an export";
     longdesc = "\
 Request that the server finish negotiation and move on to serving the
@@ -1189,6 +1192,7 @@ although older servers will instead have killed the 
connection.";
     default_call with
     args = []; ret = RErr;
     permitted_states = [ Negotiating ];
+    modifies_fd = true;
     shortdesc = "end negotiation and close the connection";
     longdesc = "\
 Request that the server finish negotiation, gracefully if possible, then
@@ -1202,6 +1206,7 @@ enabled option mode.";
     default_call with
     args = []; ret = RBool;
     permitted_states = [ Negotiating ];
+    modifies_fd = true;
     shortdesc = "request the server to initiate TLS";
     longdesc = "\
 Request that the server initiate a secure TLS connection, by
@@ -1240,6 +1245,7 @@ established, as reported by 
L<nbd_get_tls_negotiated(3)>.";
     default_call with
     args = []; ret = RBool;
     permitted_states = [ Negotiating ];
+    modifies_fd = true;
     shortdesc = "request the server to enable structured replies";
     longdesc = "\
 Request that the server use structured replies, by sending
@@ -1266,6 +1272,7 @@ later calls to this function return false.";
     default_call with
     args = [ Closure list_closure ]; ret = RInt;
     permitted_states = [ Negotiating ];
+    modifies_fd = true;
     shortdesc = "request the server to list all exports during negotiation";
     longdesc = "\
 Request that the server list all exports that it supports.  This can
@@ -1307,6 +1314,7 @@ description is set with I<-D>.";
     default_call with
     args = []; ret = RErr;
     permitted_states = [ Negotiating ];
+    modifies_fd = true;
     shortdesc = "request the server for information about an export";
     longdesc = "\
 Request that the server supply information about the export name
@@ -1338,6 +1346,7 @@ corresponding L<nbd_opt_go(3)> would succeed.";
     default_call with
     args = [ Closure context_closure ]; ret = RInt;
     permitted_states = [ Negotiating ];
+    modifies_fd = true;
     shortdesc = "list available meta contexts, using implicit query list";
     longdesc = "\
 Request that the server list available meta contexts associated with
@@ -1393,6 +1402,7 @@ a server may send a lengthy list.";
     default_call with
     args = [ StringList "queries"; Closure context_closure ]; ret = RInt;
     permitted_states = [ Negotiating ];
+    modifies_fd = true;
     shortdesc = "list available meta contexts, using explicit query list";
     longdesc = "\
 Request that the server list available meta contexts associated with
@@ -1443,6 +1453,7 @@ a server may send a lengthy list.";
     default_call with
     args = [ Closure context_closure ]; ret = RInt;
     permitted_states = [ Negotiating ];
+    modifies_fd = true;
     shortdesc = "select specific meta contexts, using implicit query list";
     longdesc = "\
 Request that the server supply all recognized meta contexts
@@ -1502,6 +1513,7 @@ no contexts are reported, or may fail but have a 
non-empty list.";
     default_call with
     args = [ StringList "queries"; Closure context_closure ]; ret = RInt;
     permitted_states = [ Negotiating ];
+    modifies_fd = true;
     shortdesc = "select specific meta contexts, using explicit query list";
     longdesc = "\
 Request that the server supply all recognized meta contexts
@@ -1731,6 +1743,7 @@ parameter in NBD URIs is allowed.";
     default_call with
     args = [ String "uri" ]; ret = RErr;
     permitted_states = [ Created ];
+    modifies_fd = true;
     shortdesc = "connect to NBD URI";
     longdesc = "\
 Connect (synchronously) to an NBD server and export by specifying
@@ -1909,6 +1922,7 @@ See L<nbd_get_uri(3)>.";
     default_call with
     args = [ Path "unixsocket" ]; ret = RErr;
     permitted_states = [ Created ];
+    modifies_fd = true;
     shortdesc = "connect to NBD server over a Unix domain socket";
     longdesc = "\
 Connect (synchronously) over the named Unix domain socket (C<unixsocket>)
@@ -1922,6 +1936,7 @@ to an NBD server running on the same machine.
     default_call with
     args = [ UInt32 "cid"; UInt32 "port" ]; ret = RErr;
     permitted_states = [ Created ];
+    modifies_fd = true;
     shortdesc = "connect to NBD server over AF_VSOCK protocol";
     longdesc = "\
 Connect (synchronously) over the C<AF_VSOCK> protocol from a
@@ -1942,6 +1957,7 @@ built on a system with vsock support, see 
L<nbd_supports_vsock(3)>.
     default_call with
     args = [ String "hostname"; String "port" ]; ret = RErr;
     permitted_states = [ Created ];
+    modifies_fd = true;
     shortdesc = "connect to NBD server over a TCP port";
     longdesc = "\
 Connect (synchronously) to the NBD server listening on
@@ -1956,6 +1972,7 @@ such as C<\"10809\">.
     default_call with
     args = [ Fd "sock" ]; ret = RErr;
     permitted_states = [ Created ];
+    modifies_fd = true;
     shortdesc = "connect directly to a connected socket";
     longdesc = "\
 Pass a connected socket C<sock> through which libnbd will talk
@@ -1977,6 +1994,7 @@ handle is closed.  The caller must not use the socket in 
any way.
     default_call with
     args = [ StringList "argv" ]; ret = RErr;
     permitted_states = [ Created ];
+    modifies_fd = true;
     shortdesc = "connect to NBD server command";
     longdesc = "\
 Run the command as a subprocess and connect to it over
@@ -2012,6 +2030,7 @@ is killed.
     default_call with
     args = [ StringList "argv" ]; ret = RErr;
     permitted_states = [ Created ];
+    modifies_fd = true;
     shortdesc = "connect using systemd socket activation";
     longdesc = "\
 Run the command as a subprocess and connect to it using
@@ -2385,6 +2404,7 @@ requests sizes.
     optargs = [ OFlags ("flags", cmd_flags, Some []) ];
     ret = RErr;
     permitted_states = [ Connected ];
+    modifies_fd = true;
     shortdesc = "read from the NBD server";
     longdesc = "\
 Issue a read command to the NBD server for the range starting
@@ -2424,6 +2444,7 @@ on failure."
     optargs = [ OFlags ("flags", cmd_flags, Some ["DF"]) ];
     ret = RErr;
     permitted_states = [ Connected ];
+    modifies_fd = true;
     shortdesc = "read from the NBD server";
     longdesc = "\
 Issue a read command to the NBD server for the range starting
@@ -2516,6 +2537,7 @@ on failure."
     optargs = [ OFlags ("flags", cmd_flags, Some ["FUA"; "PAYLOAD_LEN"]) ];
     ret = RErr;
     permitted_states = [ Connected ];
+    modifies_fd = true;
     shortdesc = "write to the NBD server";
     longdesc = "\
 Issue a write command to the NBD server, writing the data in
@@ -2552,6 +2574,7 @@ extended headers were negotiated."
     args = []; optargs = [ OFlags ("flags", shutdown_flags, None) ];
     ret = RErr;
     permitted_states = [ Connected ];
+    modifies_fd = true;
     shortdesc = "disconnect from the NBD server";
     longdesc = "\
 Issue the disconnect command to the NBD server.  This is
@@ -2589,6 +2612,7 @@ A future version of the library may add new flags.";
     default_call with
     args = []; optargs = [ OFlags ("flags", cmd_flags, Some []) ]; ret = RErr;
     permitted_states = [ Connected ];
+    modifies_fd = true;
     shortdesc = "send flush command to the NBD server";
     longdesc = "\
 Issue the flush command to the NBD server.  The function should
@@ -2609,6 +2633,7 @@ protocol extensions)."
     optargs = [ OFlags ("flags", cmd_flags, Some ["FUA"]) ];
     ret = RErr;
     permitted_states = [ Connected ];
+    modifies_fd = true;
     shortdesc = "send trim command to the NBD server";
     longdesc = "\
 Issue a trim command to the NBD server, which if supported
@@ -2640,6 +2665,7 @@ L<nbd_can_fua(3)>)."
     optargs = [ OFlags ("flags", cmd_flags, Some []) ];
     ret = RErr;
     permitted_states = [ Connected ];
+    modifies_fd = true;
     shortdesc = "send cache (prefetch) command to the NBD server";
     longdesc = "\
 Issue the cache (prefetch) command to the NBD server, which
@@ -2669,6 +2695,7 @@ protocol extensions)."
                         Some ["FUA"; "NO_HOLE"; "FAST_ZERO"]) ];
     ret = RErr;
     permitted_states = [ Connected ];
+    modifies_fd = true;
     shortdesc = "send write zeroes command to the NBD server";
     longdesc = "\
 Issue a write zeroes command to the NBD server, which if supported
@@ -2707,6 +2734,7 @@ cannot do this, see L<nbd_can_fast_zero(3)>)."
     optargs = [ OFlags ("flags", cmd_flags, Some ["REQ_ONE"]) ];
     ret = RErr;
     permitted_states = [ Connected ];
+    modifies_fd = true;
     shortdesc = "send block status command to the NBD server";
     longdesc = "\
 Issue the block status command to the NBD server.  If
@@ -2773,6 +2801,7 @@ validate that the server obeyed the flag."
   "poll", {
     default_call with
     args = [ Int "timeout" ]; ret = RInt;
+    modifies_fd = true;
     shortdesc = "poll the handle once";
     longdesc = "\
 This is a simple implementation of L<poll(2)> which is used
@@ -2794,6 +2823,7 @@ intended as something you would use.";
   "poll2", {
     default_call with
     args = [Fd "fd"; Int "timeout" ]; ret = RInt;
+    modifies_fd = true;
     shortdesc = "poll the handle once, with fd";
     longdesc = "\
 This is the same as L<nbd_poll(3)>, but an additional
@@ -3477,6 +3507,7 @@ and invalidate the need to write more commands.
   "aio_notify_read", {
     default_call with
     args = []; ret = RErr;
+    modifies_fd = true;
     shortdesc = "notify that the connection is readable";
     longdesc = "\
 Send notification to the state machine that the connection
@@ -3488,6 +3519,7 @@ connection is readable.";
   "aio_notify_write", {
     default_call with
     args = []; ret = RErr;
+    modifies_fd = true;
     shortdesc = "notify that the connection is writable";
     longdesc = "\
 Send notification to the state machine that the connection
diff --git a/generator/API.mli b/generator/API.mli
index 361132d..351170e 100644
--- a/generator/API.mli
+++ b/generator/API.mli
@@ -41,6 +41,13 @@ type call = {
       if the function is asynchronous and in that case how one can check if
       it has completed. *)
   async_kind : async_kind option;
+  (** A flag telling if the call may do something with the file descriptor.
+      Some bindings needs exclusive access to the file descriptor and can not
+      allow the user to call [aio_notify_read] or [aio_notify_write], neither
+      directly nor indirectly from another call. So all calls that might 
trigger
+      any of these functions to be called, including all synchronous commands
+      like [pread] or [connect], should set this to [true]. *)
+  modifies_fd : bool;
   (** The first stable version that the symbol appeared in, for
       example (1, 2) if the symbol was added in development cycle
       1.1.x and thus the first stable version was 1.2.  This is
-- 
2.41.0

_______________________________________________
Libguestfs mailing list
Libguestfs@redhat.com
https://listman.redhat.com/mailman/listinfo/libguestfs

Reply via email to