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); |