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 #include "byte-swapping.h"
44 #include "nbd-protocol.h"
53 r
= protocol_handshake_oldstyle ();
55 r
= protocol_handshake_newstyle ();
61 /* Common code used by oldstyle and newstyle protocols to:
63 * - call the backend .open method
65 * - get the export size
67 * - compute the eflags (same between oldstyle and newstyle
70 * The protocols must defer this as late as possible so that
71 * unauthorized clients can't cause unnecessary work in .open by
72 * simply opening a TCP connection.
75 protocol_common_open (uint64_t *exportsize
, uint16_t *flags
,
76 const char *exportname
)
80 uint16_t eflags
= NBD_FLAG_HAS_FLAGS
;
83 conn
->top_context
= backend_open (top
, read_only
, exportname
, false);
84 if (conn
->top_context
== NULL
)
87 /* Prepare (for filters), called just after open. */
88 if (backend_prepare (conn
->top_context
) == -1)
91 size
= backend_get_size (conn
->top_context
);
95 nbdkit_error (".get_size function returned invalid value "
96 "(%" PRIi64
")", size
);
100 /* Check all flags even if they won't be advertised, to prime the
101 * cache and make later request validation easier.
103 fl
= backend_can_write (conn
->top_context
);
107 eflags
|= NBD_FLAG_READ_ONLY
;
109 fl
= backend_can_zero (conn
->top_context
);
113 eflags
|= NBD_FLAG_SEND_WRITE_ZEROES
;
115 fl
= backend_can_fast_zero (conn
->top_context
);
119 eflags
|= NBD_FLAG_SEND_FAST_ZERO
;
121 fl
= backend_can_trim (conn
->top_context
);
125 eflags
|= NBD_FLAG_SEND_TRIM
;
127 fl
= backend_can_fua (conn
->top_context
);
131 eflags
|= NBD_FLAG_SEND_FUA
;
133 fl
= backend_can_flush (conn
->top_context
);
137 eflags
|= NBD_FLAG_SEND_FLUSH
;
139 fl
= backend_is_rotational (conn
->top_context
);
143 eflags
|= NBD_FLAG_ROTATIONAL
;
145 /* multi-conn is useless if parallel connections are not allowed. */
146 fl
= backend_can_multi_conn (conn
->top_context
);
149 if (fl
&& (thread_model
> NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS
))
150 eflags
|= NBD_FLAG_CAN_MULTI_CONN
;
152 fl
= backend_can_cache (conn
->top_context
);
156 eflags
|= NBD_FLAG_SEND_CACHE
;
158 /* The result of this is not directly advertised as part of the
159 * handshake, but priming the cache here makes BLOCK_STATUS handling
160 * not have to worry about errors, and makes test-layers easier to
163 fl
= backend_can_extents (conn
->top_context
);
167 if (conn
->structured_replies
)
168 eflags
|= NBD_FLAG_SEND_DF
;