2 * Copyright (C) 2013-2020 Red Hat Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 #undef NDEBUG /* Keep test strong even for nbdkit built without assertions */
45 #include <sys/types.h>
46 #include <sys/socket.h>
51 #define SOCKET "pause.sock"
53 static bool command1_completed
= false;
54 static bool command2_completed
= false;
57 callback (void *vp
, int *err
)
65 main (int argc
, char *argv
[])
67 struct nbd_handle
*nbd
;
69 struct sockaddr_un addr
;
77 fprintf (stderr
, "%s\n", nbd_get_error ());
81 if (nbd_connect_command (nbd
,
83 "nbdkit", "-s", "--exit-with-parent",
85 "example1", "pause-control=" SOCKET
,
87 fprintf (stderr
, "%s\n", nbd_get_error ());
91 /* Connect separately to the pause control socket. */
92 ctrlsock
= socket (AF_UNIX
, SOCK_STREAM
, 0);
97 addr
.sun_family
= AF_UNIX
;
98 strcpy (addr
.sun_path
, SOCKET
);
100 if (connect (ctrlsock
, (struct sockaddr
*) &addr
, sizeof addr
) == -1) {
105 /* To start with, we should be able to read synchronously normally. */
106 if (nbd_pread (nbd
, buf
, sizeof buf
, 0, 0) == -1) {
107 fprintf (stderr
, "%s\n", nbd_get_error ());
111 /* Pause the connection. */
112 fprintf (stderr
, "pausing the connection\n");
114 if (write (ctrlsock
, &c
, 1) != 1) {
115 perror ("write: ctrlsock: pause");
118 if (read (ctrlsock
, &c
, 1) != 1) {
119 perror ("read: ctrlsock: response to pause");
124 /* Issue some asynchronous commands. These should hang. */
125 cookie
= nbd_aio_pread (nbd
, buf
, sizeof buf
, 0,
126 (nbd_completion_callback
) {
127 .callback
= callback
,
128 .user_data
= &command1_completed
,
131 fprintf (stderr
, "%s\n", nbd_get_error ());
134 cookie
= nbd_aio_pread (nbd
, buf
, sizeof buf
, 0,
135 (nbd_completion_callback
) {
136 .callback
= callback
,
137 .user_data
= &command2_completed
,
140 fprintf (stderr
, "%s\n", nbd_get_error ());
144 /* Wait a bit to check they don't complete. */
146 while (time (&t
) <= start_t
+ 5)
147 nbd_poll (nbd
, 1000);
148 assert (!command1_completed
);
149 assert (!command2_completed
);
151 /* Resume the connection. */
152 fprintf (stderr
, "resuming the connection\n");
154 if (write (ctrlsock
, &c
, 1) != 1) {
155 perror ("write: ctrlsock: resume");
158 if (read (ctrlsock
, &c
, 1) != 1) {
159 perror ("read: ctrlsock: response to resume");
164 /* Now at least one of the commands should complete. */
166 while (!command1_completed
&& !command2_completed
&&
167 time (&t
) <= start_t
+ 60)
168 nbd_poll (nbd
, 1000);
169 assert (command1_completed
|| command2_completed
);
172 nbd_shutdown (nbd
, 0);