1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
|
=head1 NAME
nbd_shutdown - disconnect from the NBD server
=head1 SYNOPSIS
#include <libnbd.h>
int nbd_shutdown (
struct nbd_handle *h, uint32_t flags
);
=head1 DESCRIPTION
Issue the disconnect command to the NBD server. This is
a nice way to tell the server we are going away, but from the
client's point of view has no advantage over abruptly closing
the connection (see L<nbd_close(3)>).
This function works whether or not the handle is ready for
transmission of commands. If more fine-grained control is
needed, see L<nbd_aio_opt_abort(3)> and L<nbd_aio_disconnect(3)>.
The C<flags> argument is a bitmask, including zero or more of the
following shutdown flags:
=over 4
=item C<LIBNBD_SHUTDOWN_ABANDON_PENDING> = 0x10000
If there are any pending requests which have not yet been sent to
the server (see L<nbd_aio_in_flight(3)>), abandon them without
sending them to the server, rather than the usual practice of
issuing those commands before informing the server of the intent
to disconnect.
=back
For convenience, the constant C<LIBNBD_SHUTDOWN_MASK> is available
to describe all shutdown flags recognized by this build of libnbd.
A future version of the library may add new flags.
=head1 RETURN VALUE
If the call is successful the function returns C<0>.
=head1 ERRORS
On error C<-1> is returned.
Refer to L<libnbd(3)/ERROR HANDLING>
for how to get further details of the error.
The following parameters must not be NULL: C<h>.
For more information see L<libnbd(3)/Non-NULL parameters>.
=head1 HANDLE STATE
nbd_shutdown
can be called when the handle is in the following states:
┌─────────────────────────────────────┬─────────────────────────┐
│ Handle created, before connecting │ ❌ error │
│ Connecting │ ❌ error │
│ Connecting & handshaking (opt_mode) │ ✅ allowed │
│ Connected to the server │ ✅ allowed │
│ Connection shut down │ ❌ error │
│ Handle dead │ ❌ error │
└─────────────────────────────────────┴─────────────────────────┘
=head1 VERSION
This function first appeared in libnbd 1.0.
If you need to test if this function is available at compile time
check if the following macro is defined:
#define LIBNBD_HAVE_NBD_SHUTDOWN 1
=head1 EXAMPLE
This example is also available as F<examples/reads-and-writes.c>
in the libnbd source code.
/* This example shows how to do synchronous reads
* and writes randomly over the first megabyte of an
* NBD server. Note this will destroy any existing
* content on the NBD server.
*
* To test it with nbdkit and a RAM disk:
*
* nbdkit -U - memory 1M \
* --run './simple-reads-and-writes $unixsocket'
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <assert.h>
#include <time.h>
#include <libnbd.h>
int
main (int argc, char *argv[])
{
struct nbd_handle *nbd;
char buf[512];
size_t i;
int64_t exportsize;
uint64_t offset;
srand (time (NULL));
if (argc != 2) {
fprintf (stderr, "%s socket\n", argv[0]);
exit (EXIT_FAILURE);
}
/* Create the libnbd handle. */
nbd = nbd_create ();
if (nbd == NULL) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
/* Connect to the NBD server over a
* Unix domain socket.
*/
if (nbd_connect_unix (nbd, argv[1]) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
/* Get the size of the disk and check
* it's large enough.
*/
exportsize = nbd_get_size (nbd);
if (exportsize == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
assert (exportsize >= sizeof buf);
/* Check that the server is writable. */
if (nbd_is_read_only (nbd) == 1) {
fprintf (stderr, "%s: "
"error: this NBD export is read-only\n",
argv[0]);
exit (EXIT_FAILURE);
}
for (i = 0; i < sizeof buf; ++i)
buf[i] = rand ();
/* 1000 writes. */
for (i = 0; i < 1000; ++i) {
offset = rand () % (exportsize - sizeof buf);
if (nbd_pwrite (nbd, buf, sizeof buf,
offset, 0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
}
/* 1000 reads and writes. */
for (i = 0; i < 1000; ++i) {
offset = rand () % (exportsize - sizeof buf);
if (nbd_pread (nbd, buf, sizeof buf,
offset, 0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
offset = rand () % (exportsize - sizeof buf);
if (nbd_pwrite (nbd, buf, sizeof buf,
offset, 0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
}
/* Sends a graceful shutdown to the server. */
if (nbd_shutdown (nbd, 0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
nbd_close (nbd);
exit (EXIT_SUCCESS);
}
=head1 SEE ALSO
L<nbd_aio_disconnect(3)>,
L<nbd_aio_in_flight(3)>,
L<nbd_aio_opt_abort(3)>,
L<nbd_close(3)>,
L<nbd_create(3)>,
L<libnbd(3)>.
=head1 AUTHORS
Eric Blake
Richard W.M. Jones
=head1 COPYRIGHT
Copyright Red Hat
|