nbd.c (f53a1febcd9d887149ac1429880a3f2fdb2c117f) nbd.c (6963a30d82413bea36c7545137b090b284cc2b18)
1/*
2 * QEMU Block driver for NBD
3 *
4 * Copyright (C) 2008 Bull S.A.S.
5 * Author: Laurent Vivier <Laurent.Vivier@bull.net>
6 *
7 * Some parts:
8 * Copyright (C) 2007 Anthony Liguori <anthony@codemonkey.ws>

--- 129 unchanged lines hidden (view full) ---

138out:
139 if (qp) {
140 query_params_free(qp);
141 }
142 uri_free(uri);
143 return ret;
144}
145
1/*
2 * QEMU Block driver for NBD
3 *
4 * Copyright (C) 2008 Bull S.A.S.
5 * Author: Laurent Vivier <Laurent.Vivier@bull.net>
6 *
7 * Some parts:
8 * Copyright (C) 2007 Anthony Liguori <anthony@codemonkey.ws>

--- 129 unchanged lines hidden (view full) ---

138out:
139 if (qp) {
140 query_params_free(qp);
141 }
142 uri_free(uri);
143 return ret;
144}
145
146static int nbd_parse_filename(const char *filename, QDict *options)
146static void nbd_parse_filename(const char *filename, QDict *options,
147 Error **errp)
147{
148 char *file;
149 char *export_name;
150 const char *host_spec;
151 const char *unixpath;
148{
149 char *file;
150 char *export_name;
151 const char *host_spec;
152 const char *unixpath;
152 int ret = -EINVAL;
153 Error *local_err = NULL;
154
155 if (strstr(filename, "://")) {
153
154 if (strstr(filename, "://")) {
156 return nbd_parse_uri(filename, options);
155 int ret = nbd_parse_uri(filename, options);
156 if (ret < 0) {
157 error_setg(errp, "No valid URL specified");
158 }
159 return;
157 }
158
159 file = g_strdup(filename);
160
161 export_name = strstr(file, EN_OPTSTR);
162 if (export_name) {
163 if (export_name[strlen(EN_OPTSTR)] == 0) {
164 goto out;
165 }
166 export_name[0] = 0; /* truncate 'file' */
167 export_name += strlen(EN_OPTSTR);
168
169 qdict_put(options, "export", qstring_from_str(export_name));
170 }
171
172 /* extract the host_spec - fail if it's not nbd:... */
173 if (!strstart(file, "nbd:", &host_spec)) {
160 }
161
162 file = g_strdup(filename);
163
164 export_name = strstr(file, EN_OPTSTR);
165 if (export_name) {
166 if (export_name[strlen(EN_OPTSTR)] == 0) {
167 goto out;
168 }
169 export_name[0] = 0; /* truncate 'file' */
170 export_name += strlen(EN_OPTSTR);
171
172 qdict_put(options, "export", qstring_from_str(export_name));
173 }
174
175 /* extract the host_spec - fail if it's not nbd:... */
176 if (!strstart(file, "nbd:", &host_spec)) {
177 error_setg(errp, "File name string for NBD must start with 'nbd:'");
174 goto out;
175 }
176
177 if (!*host_spec) {
178 goto out;
179 }
180
181 if (!*host_spec) {
178 ret = 1;
179 goto out;
180 }
181
182 /* are we a UNIX or TCP socket? */
183 if (strstart(host_spec, "unix:", &unixpath)) {
184 qdict_put(options, "path", qstring_from_str(unixpath));
185 } else {
186 InetSocketAddress *addr = NULL;
187
182 goto out;
183 }
184
185 /* are we a UNIX or TCP socket? */
186 if (strstart(host_spec, "unix:", &unixpath)) {
187 qdict_put(options, "path", qstring_from_str(unixpath));
188 } else {
189 InetSocketAddress *addr = NULL;
190
188 addr = inet_parse(host_spec, &local_err);
189 if (local_err != NULL) {
190 qerror_report_err(local_err);
191 error_free(local_err);
191 addr = inet_parse(host_spec, errp);
192 if (error_is_set(errp)) {
192 goto out;
193 }
194
195 qdict_put(options, "host", qstring_from_str(addr->host));
196 qdict_put(options, "port", qstring_from_str(addr->port));
197 qapi_free_InetSocketAddress(addr);
198 }
199
193 goto out;
194 }
195
196 qdict_put(options, "host", qstring_from_str(addr->host));
197 qdict_put(options, "port", qstring_from_str(addr->port));
198 qapi_free_InetSocketAddress(addr);
199 }
200
200 ret = 1;
201out:
202 g_free(file);
201out:
202 g_free(file);
203 return ret;
204}
205
206static int nbd_config(BDRVNBDState *s, QDict *options)
207{
208 Error *local_err = NULL;
209
210 if (qdict_haskey(options, "path")) {
211 s->is_unix = true;

--- 220 unchanged lines hidden (view full) ---

432{
433 BDRVNBDState *s = bs->opaque;
434 int result;
435
436 qemu_co_mutex_init(&s->send_mutex);
437 qemu_co_mutex_init(&s->free_sema);
438
439 /* Pop the config into our state object. Exit if invalid. */
203}
204
205static int nbd_config(BDRVNBDState *s, QDict *options)
206{
207 Error *local_err = NULL;
208
209 if (qdict_haskey(options, "path")) {
210 s->is_unix = true;

--- 220 unchanged lines hidden (view full) ---

431{
432 BDRVNBDState *s = bs->opaque;
433 int result;
434
435 qemu_co_mutex_init(&s->send_mutex);
436 qemu_co_mutex_init(&s->free_sema);
437
438 /* Pop the config into our state object. Exit if invalid. */
440 result = nbd_parse_filename(filename, options);
441 if (result < 0) {
442 return result;
443 }
444
445 result = nbd_config(s, options);
446 if (result != 0) {
447 return result;
448 }
449
450 /* establish TCP connection, return error if it fails
451 * TODO: Configurable retry-until-timeout behaviour.
452 */

--- 164 unchanged lines hidden (view full) ---

617
618 return s->size;
619}
620
621static BlockDriver bdrv_nbd = {
622 .format_name = "nbd",
623 .protocol_name = "nbd",
624 .instance_size = sizeof(BDRVNBDState),
439 result = nbd_config(s, options);
440 if (result != 0) {
441 return result;
442 }
443
444 /* establish TCP connection, return error if it fails
445 * TODO: Configurable retry-until-timeout behaviour.
446 */

--- 164 unchanged lines hidden (view full) ---

611
612 return s->size;
613}
614
615static BlockDriver bdrv_nbd = {
616 .format_name = "nbd",
617 .protocol_name = "nbd",
618 .instance_size = sizeof(BDRVNBDState),
619 .bdrv_parse_filename = nbd_parse_filename,
625 .bdrv_file_open = nbd_open,
626 .bdrv_co_readv = nbd_co_readv,
627 .bdrv_co_writev = nbd_co_writev,
628 .bdrv_close = nbd_close,
629 .bdrv_co_flush_to_os = nbd_co_flush,
630 .bdrv_co_discard = nbd_co_discard,
631 .bdrv_getlength = nbd_getlength,
632};
633
634static BlockDriver bdrv_nbd_tcp = {
635 .format_name = "nbd",
636 .protocol_name = "nbd+tcp",
637 .instance_size = sizeof(BDRVNBDState),
620 .bdrv_file_open = nbd_open,
621 .bdrv_co_readv = nbd_co_readv,
622 .bdrv_co_writev = nbd_co_writev,
623 .bdrv_close = nbd_close,
624 .bdrv_co_flush_to_os = nbd_co_flush,
625 .bdrv_co_discard = nbd_co_discard,
626 .bdrv_getlength = nbd_getlength,
627};
628
629static BlockDriver bdrv_nbd_tcp = {
630 .format_name = "nbd",
631 .protocol_name = "nbd+tcp",
632 .instance_size = sizeof(BDRVNBDState),
633 .bdrv_parse_filename = nbd_parse_filename,
638 .bdrv_file_open = nbd_open,
639 .bdrv_co_readv = nbd_co_readv,
640 .bdrv_co_writev = nbd_co_writev,
641 .bdrv_close = nbd_close,
642 .bdrv_co_flush_to_os = nbd_co_flush,
643 .bdrv_co_discard = nbd_co_discard,
644 .bdrv_getlength = nbd_getlength,
645};
646
647static BlockDriver bdrv_nbd_unix = {
648 .format_name = "nbd",
649 .protocol_name = "nbd+unix",
650 .instance_size = sizeof(BDRVNBDState),
634 .bdrv_file_open = nbd_open,
635 .bdrv_co_readv = nbd_co_readv,
636 .bdrv_co_writev = nbd_co_writev,
637 .bdrv_close = nbd_close,
638 .bdrv_co_flush_to_os = nbd_co_flush,
639 .bdrv_co_discard = nbd_co_discard,
640 .bdrv_getlength = nbd_getlength,
641};
642
643static BlockDriver bdrv_nbd_unix = {
644 .format_name = "nbd",
645 .protocol_name = "nbd+unix",
646 .instance_size = sizeof(BDRVNBDState),
647 .bdrv_parse_filename = nbd_parse_filename,
651 .bdrv_file_open = nbd_open,
652 .bdrv_co_readv = nbd_co_readv,
653 .bdrv_co_writev = nbd_co_writev,
654 .bdrv_close = nbd_close,
655 .bdrv_co_flush_to_os = nbd_co_flush,
656 .bdrv_co_discard = nbd_co_discard,
657 .bdrv_getlength = nbd_getlength,
658};
659
660static void bdrv_nbd_init(void)
661{
662 bdrv_register(&bdrv_nbd);
663 bdrv_register(&bdrv_nbd_tcp);
664 bdrv_register(&bdrv_nbd_unix);
665}
666
667block_init(bdrv_nbd_init);
648 .bdrv_file_open = nbd_open,
649 .bdrv_co_readv = nbd_co_readv,
650 .bdrv_co_writev = nbd_co_writev,
651 .bdrv_close = nbd_close,
652 .bdrv_co_flush_to_os = nbd_co_flush,
653 .bdrv_co_discard = nbd_co_discard,
654 .bdrv_getlength = nbd_getlength,
655};
656
657static void bdrv_nbd_init(void)
658{
659 bdrv_register(&bdrv_nbd);
660 bdrv_register(&bdrv_nbd_tcp);
661 bdrv_register(&bdrv_nbd_unix);
662}
663
664block_init(bdrv_nbd_init);