Revision b90fb4b8 nbd.c
b/nbd.c | ||
---|---|---|
30 | 30 |
#include <ctype.h> |
31 | 31 |
#include <inttypes.h> |
32 | 32 |
|
33 |
#ifdef __linux__ |
|
34 |
#include <linux/fs.h> |
|
35 |
#endif |
|
36 |
|
|
33 | 37 |
#include "qemu_socket.h" |
34 | 38 |
|
35 | 39 |
//#define DEBUG_NBD |
... | ... | |
172 | 176 |
Request (type == 2) |
173 | 177 |
*/ |
174 | 178 |
|
175 |
int nbd_negotiate(int csock, off_t size) |
|
179 |
int nbd_negotiate(int csock, off_t size, uint32_t flags)
|
|
176 | 180 |
{ |
177 | 181 |
char buf[8 + 8 + 8 + 128]; |
178 | 182 |
|
... | ... | |
180 | 184 |
[ 0 .. 7] passwd ("NBDMAGIC") |
181 | 185 |
[ 8 .. 15] magic (0x00420281861253) |
182 | 186 |
[16 .. 23] size |
183 |
[24 .. 151] reserved (0) |
|
187 |
[24 .. 27] flags |
|
188 |
[28 .. 151] reserved (0) |
|
184 | 189 |
*/ |
185 | 190 |
|
186 | 191 |
TRACE("Beginning negotiation."); |
187 | 192 |
memcpy(buf, "NBDMAGIC", 8); |
188 | 193 |
cpu_to_be64w((uint64_t*)(buf + 8), 0x00420281861253LL); |
189 | 194 |
cpu_to_be64w((uint64_t*)(buf + 16), size); |
190 |
memset(buf + 24, 0, 128); |
|
195 |
cpu_to_be32w((uint32_t*)(buf + 24), flags | NBD_FLAG_HAS_FLAGS); |
|
196 |
memset(buf + 28, 0, 124); |
|
191 | 197 |
|
192 | 198 |
if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) { |
193 | 199 |
LOG("write failed"); |
... | ... | |
337 | 343 |
return 0; |
338 | 344 |
} |
339 | 345 |
|
340 |
#ifndef _WIN32
|
|
341 |
int nbd_init(int fd, int csock, off_t size, size_t blocksize) |
|
346 |
#ifdef __linux__
|
|
347 |
int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize)
|
|
342 | 348 |
{ |
343 | 349 |
TRACE("Setting block size to %lu", (unsigned long)blocksize); |
344 | 350 |
|
... | ... | |
358 | 364 |
return -1; |
359 | 365 |
} |
360 | 366 |
|
367 |
if (flags & NBD_FLAG_READ_ONLY) { |
|
368 |
int read_only = 1; |
|
369 |
TRACE("Setting readonly attribute"); |
|
370 |
|
|
371 |
if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) { |
|
372 |
int serrno = errno; |
|
373 |
LOG("Failed setting read-only attribute"); |
|
374 |
errno = serrno; |
|
375 |
return -1; |
|
376 |
} |
|
377 |
} |
|
378 |
|
|
361 | 379 |
TRACE("Clearing NBD socket"); |
362 | 380 |
|
363 | 381 |
if (ioctl(fd, NBD_CLEAR_SOCK) == -1) { |
... | ... | |
548 | 566 |
} |
549 | 567 |
|
550 | 568 |
int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, |
551 |
off_t *offset, bool readonly, uint8_t *data, int data_size)
|
|
569 |
off_t *offset, uint32_t nbdflags, uint8_t *data, int data_size)
|
|
552 | 570 |
{ |
553 | 571 |
struct nbd_request request; |
554 | 572 |
struct nbd_reply reply; |
... | ... | |
632 | 650 |
return -1; |
633 | 651 |
} |
634 | 652 |
|
635 |
if (readonly) {
|
|
653 |
if (nbdflags & NBD_FLAG_READ_ONLY) {
|
|
636 | 654 |
TRACE("Server is read-only, return error"); |
637 | 655 |
reply.error = 1; |
638 | 656 |
} else { |
Also available in: Unified diff