Revision 1d45f8b5 block/nbd.c
b/block/nbd.c | ||
---|---|---|
33 | 33 |
#include <sys/types.h> |
34 | 34 |
#include <unistd.h> |
35 | 35 |
|
36 |
#define EN_OPTSTR ":exportname=" |
|
37 |
|
|
36 | 38 |
typedef struct BDRVNBDState { |
37 | 39 |
int sock; |
38 | 40 |
off_t size; |
... | ... | |
42 | 44 |
static int nbd_open(BlockDriverState *bs, const char* filename, int flags) |
43 | 45 |
{ |
44 | 46 |
BDRVNBDState *s = bs->opaque; |
47 |
uint32_t nbdflags; |
|
48 |
|
|
49 |
char *file; |
|
50 |
char *name; |
|
45 | 51 |
const char *host; |
46 | 52 |
const char *unixpath; |
47 | 53 |
int sock; |
48 | 54 |
off_t size; |
49 | 55 |
size_t blocksize; |
50 | 56 |
int ret; |
57 |
int err = -EINVAL; |
|
58 |
|
|
59 |
file = qemu_strdup(filename); |
|
51 | 60 |
|
52 |
if (!strstart(filename, "nbd:", &host)) |
|
53 |
return -EINVAL; |
|
61 |
name = strstr(file, EN_OPTSTR); |
|
62 |
if (name) { |
|
63 |
if (name[strlen(EN_OPTSTR)] == 0) { |
|
64 |
goto out; |
|
65 |
} |
|
66 |
name[0] = 0; |
|
67 |
name += strlen(EN_OPTSTR); |
|
68 |
} |
|
69 |
|
|
70 |
if (!strstart(file, "nbd:", &host)) { |
|
71 |
goto out; |
|
72 |
} |
|
54 | 73 |
|
55 | 74 |
if (strstart(host, "unix:", &unixpath)) { |
56 | 75 |
|
57 |
if (unixpath[0] != '/') |
|
58 |
return -EINVAL; |
|
76 |
if (unixpath[0] != '/') { |
|
77 |
goto out; |
|
78 |
} |
|
59 | 79 |
|
60 | 80 |
sock = unix_socket_outgoing(unixpath); |
61 | 81 |
|
62 | 82 |
} else { |
63 |
uint16_t port; |
|
83 |
uint16_t port = NBD_DEFAULT_PORT;
|
|
64 | 84 |
char *p, *r; |
65 | 85 |
char hostname[128]; |
66 | 86 |
|
67 | 87 |
pstrcpy(hostname, 128, host); |
68 | 88 |
|
69 | 89 |
p = strchr(hostname, ':'); |
70 |
if (p == NULL) |
|
71 |
return -EINVAL; |
|
90 |
if (p != NULL) { |
|
91 |
*p = '\0'; |
|
92 |
p++; |
|
93 |
|
|
94 |
port = strtol(p, &r, 0); |
|
95 |
if (r == p) { |
|
96 |
goto out; |
|
97 |
} |
|
98 |
} else if (name == NULL) { |
|
99 |
goto out; |
|
100 |
} |
|
72 | 101 |
|
73 |
*p = '\0'; |
|
74 |
p++; |
|
75 |
|
|
76 |
port = strtol(p, &r, 0); |
|
77 |
if (r == p) |
|
78 |
return -EINVAL; |
|
79 | 102 |
sock = tcp_socket_outgoing(hostname, port); |
80 | 103 |
} |
81 | 104 |
|
82 |
if (sock == -1) |
|
83 |
return -errno; |
|
105 |
if (sock == -1) { |
|
106 |
err = -errno; |
|
107 |
goto out; |
|
108 |
} |
|
84 | 109 |
|
85 |
ret = nbd_receive_negotiate(sock, &size, &blocksize); |
|
86 |
if (ret == -1) |
|
87 |
return -errno; |
|
110 |
ret = nbd_receive_negotiate(sock, name, &nbdflags, &size, &blocksize); |
|
111 |
if (ret == -1) { |
|
112 |
err = -errno; |
|
113 |
goto out; |
|
114 |
} |
|
88 | 115 |
|
89 | 116 |
s->sock = sock; |
90 | 117 |
s->size = size; |
91 | 118 |
s->blocksize = blocksize; |
119 |
err = 0; |
|
92 | 120 |
|
93 |
return 0; |
|
121 |
out: |
|
122 |
qemu_free(file); |
|
123 |
return err; |
|
94 | 124 |
} |
95 | 125 |
|
96 | 126 |
static int nbd_read(BlockDriverState *bs, int64_t sector_num, |
Also available in: Unified diff