Loading block/nbd.c +97 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include "qemu-common.h" #include "nbd.h" #include "uri.h" #include "block_int.h" #include "module.h" #include "qemu_socket.h" Loading Loading @@ -69,6 +70,69 @@ typedef struct BDRVNBDState { char *export_name; /* An NBD server may export several devices */ } BDRVNBDState; static int nbd_parse_uri(BDRVNBDState *s, const char *filename) { URI *uri; const char *p; QueryParams *qp = NULL; int ret = 0; uri = uri_parse(filename); if (!uri) { return -EINVAL; } /* transport */ if (!strcmp(uri->scheme, "nbd")) { s->is_unix = false; } else if (!strcmp(uri->scheme, "nbd+tcp")) { s->is_unix = false; } else if (!strcmp(uri->scheme, "nbd+unix")) { s->is_unix = true; } else { ret = -EINVAL; goto out; } p = uri->path ? uri->path : "/"; p += strspn(p, "/"); if (p[0]) { s->export_name = g_strdup(p); } qp = query_params_parse(uri->query); if (qp->n > 1 || (s->is_unix && !qp->n) || (!s->is_unix && qp->n)) { ret = -EINVAL; goto out; } if (s->is_unix) { /* nbd+unix:///export?socket=path */ if (uri->server || uri->port || strcmp(qp->p[0].name, "socket")) { ret = -EINVAL; goto out; } s->host_spec = g_strdup(qp->p[0].value); } else { /* nbd[+tcp]://host:port/export */ if (!uri->server) { ret = -EINVAL; goto out; } if (!uri->port) { uri->port = NBD_DEFAULT_PORT; } s->host_spec = g_strdup_printf("%s:%d", uri->server, uri->port); } out: if (qp) { query_params_free(qp); } uri_free(uri); return ret; } static int nbd_config(BDRVNBDState *s, const char *filename) { char *file; Loading @@ -77,6 +141,10 @@ static int nbd_config(BDRVNBDState *s, const char *filename) const char *unixpath; int err = -EINVAL; if (strstr(filename, "://")) { return nbd_parse_uri(s, filename); } file = g_strdup(filename); export_name = strstr(file, EN_OPTSTR); Loading Loading @@ -495,6 +563,33 @@ static int64_t nbd_getlength(BlockDriverState *bs) static BlockDriver bdrv_nbd = { .format_name = "nbd", .protocol_name = "nbd", .instance_size = sizeof(BDRVNBDState), .bdrv_file_open = nbd_open, .bdrv_co_readv = nbd_co_readv, .bdrv_co_writev = nbd_co_writev, .bdrv_close = nbd_close, .bdrv_co_flush_to_os = nbd_co_flush, .bdrv_co_discard = nbd_co_discard, .bdrv_getlength = nbd_getlength, }; static BlockDriver bdrv_nbd_tcp = { .format_name = "nbd", .protocol_name = "nbd+tcp", .instance_size = sizeof(BDRVNBDState), .bdrv_file_open = nbd_open, .bdrv_co_readv = nbd_co_readv, .bdrv_co_writev = nbd_co_writev, .bdrv_close = nbd_close, .bdrv_co_flush_to_os = nbd_co_flush, .bdrv_co_discard = nbd_co_discard, .bdrv_getlength = nbd_getlength, }; static BlockDriver bdrv_nbd_unix = { .format_name = "nbd", .protocol_name = "nbd+unix", .instance_size = sizeof(BDRVNBDState), .bdrv_file_open = nbd_open, .bdrv_co_readv = nbd_co_readv, Loading @@ -503,12 +598,13 @@ static BlockDriver bdrv_nbd = { .bdrv_co_flush_to_os = nbd_co_flush, .bdrv_co_discard = nbd_co_discard, .bdrv_getlength = nbd_getlength, .protocol_name = "nbd", }; static void bdrv_nbd_init(void) { bdrv_register(&bdrv_nbd); bdrv_register(&bdrv_nbd_tcp); bdrv_register(&bdrv_nbd_unix); } block_init(bdrv_nbd_init); qemu-doc.texi +17 −8 Original line number Diff line number Diff line Loading @@ -610,14 +610,14 @@ QEMU can access directly to block device exported using the Network Block Device protocol. @example qemu-system-i386 linux.img -hdb nbd:my_nbd_server.mydomain.org:1024 qemu-system-i386 linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/ @end example If the NBD server is located on the same host, you can use an unix socket instead of an inet socket: @example qemu-system-i386 linux.img -hdb nbd:unix:/tmp/my_socket qemu-system-i386 linux.img -hdb nbd+unix://?socket=/tmp/my_socket @end example In this case, the block device must be exported using qemu-nbd: Loading @@ -631,17 +631,26 @@ The use of qemu-nbd allows to share a disk between several guests: qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2 @end example @noindent and then you can use it with two guests: @example qemu-system-i386 linux1.img -hdb nbd:unix:/tmp/my_socket qemu-system-i386 linux2.img -hdb nbd:unix:/tmp/my_socket qemu-system-i386 linux1.img -hdb nbd+unix://?socket=/tmp/my_socket qemu-system-i386 linux2.img -hdb nbd+unix://?socket=/tmp/my_socket @end example If the nbd-server uses named exports (since NBD 2.9.18), you must use the "exportname" option: If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's own embedded NBD server), you must specify an export name in the URI: @example qemu-system-i386 -cdrom nbd:localhost:exportname=debian-500-ppc-netinst qemu-system-i386 -cdrom nbd:localhost:exportname=openSUSE-11.1-ppc-netinst qemu-system-i386 -cdrom nbd://localhost/debian-500-ppc-netinst qemu-system-i386 -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst @end example The URI syntax for NBD is supported since QEMU 1.3. An alternative syntax is also available. Here are some example of the older syntax: @example qemu-system-i386 linux.img -hdb nbd:my_nbd_server.mydomain.org:1024 qemu-system-i386 linux2.img -hdb nbd:unix:/tmp/my_socket qemu-system-i386 -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst @end example @node disk_images_sheepdog Loading Loading
block/nbd.c +97 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include "qemu-common.h" #include "nbd.h" #include "uri.h" #include "block_int.h" #include "module.h" #include "qemu_socket.h" Loading Loading @@ -69,6 +70,69 @@ typedef struct BDRVNBDState { char *export_name; /* An NBD server may export several devices */ } BDRVNBDState; static int nbd_parse_uri(BDRVNBDState *s, const char *filename) { URI *uri; const char *p; QueryParams *qp = NULL; int ret = 0; uri = uri_parse(filename); if (!uri) { return -EINVAL; } /* transport */ if (!strcmp(uri->scheme, "nbd")) { s->is_unix = false; } else if (!strcmp(uri->scheme, "nbd+tcp")) { s->is_unix = false; } else if (!strcmp(uri->scheme, "nbd+unix")) { s->is_unix = true; } else { ret = -EINVAL; goto out; } p = uri->path ? uri->path : "/"; p += strspn(p, "/"); if (p[0]) { s->export_name = g_strdup(p); } qp = query_params_parse(uri->query); if (qp->n > 1 || (s->is_unix && !qp->n) || (!s->is_unix && qp->n)) { ret = -EINVAL; goto out; } if (s->is_unix) { /* nbd+unix:///export?socket=path */ if (uri->server || uri->port || strcmp(qp->p[0].name, "socket")) { ret = -EINVAL; goto out; } s->host_spec = g_strdup(qp->p[0].value); } else { /* nbd[+tcp]://host:port/export */ if (!uri->server) { ret = -EINVAL; goto out; } if (!uri->port) { uri->port = NBD_DEFAULT_PORT; } s->host_spec = g_strdup_printf("%s:%d", uri->server, uri->port); } out: if (qp) { query_params_free(qp); } uri_free(uri); return ret; } static int nbd_config(BDRVNBDState *s, const char *filename) { char *file; Loading @@ -77,6 +141,10 @@ static int nbd_config(BDRVNBDState *s, const char *filename) const char *unixpath; int err = -EINVAL; if (strstr(filename, "://")) { return nbd_parse_uri(s, filename); } file = g_strdup(filename); export_name = strstr(file, EN_OPTSTR); Loading Loading @@ -495,6 +563,33 @@ static int64_t nbd_getlength(BlockDriverState *bs) static BlockDriver bdrv_nbd = { .format_name = "nbd", .protocol_name = "nbd", .instance_size = sizeof(BDRVNBDState), .bdrv_file_open = nbd_open, .bdrv_co_readv = nbd_co_readv, .bdrv_co_writev = nbd_co_writev, .bdrv_close = nbd_close, .bdrv_co_flush_to_os = nbd_co_flush, .bdrv_co_discard = nbd_co_discard, .bdrv_getlength = nbd_getlength, }; static BlockDriver bdrv_nbd_tcp = { .format_name = "nbd", .protocol_name = "nbd+tcp", .instance_size = sizeof(BDRVNBDState), .bdrv_file_open = nbd_open, .bdrv_co_readv = nbd_co_readv, .bdrv_co_writev = nbd_co_writev, .bdrv_close = nbd_close, .bdrv_co_flush_to_os = nbd_co_flush, .bdrv_co_discard = nbd_co_discard, .bdrv_getlength = nbd_getlength, }; static BlockDriver bdrv_nbd_unix = { .format_name = "nbd", .protocol_name = "nbd+unix", .instance_size = sizeof(BDRVNBDState), .bdrv_file_open = nbd_open, .bdrv_co_readv = nbd_co_readv, Loading @@ -503,12 +598,13 @@ static BlockDriver bdrv_nbd = { .bdrv_co_flush_to_os = nbd_co_flush, .bdrv_co_discard = nbd_co_discard, .bdrv_getlength = nbd_getlength, .protocol_name = "nbd", }; static void bdrv_nbd_init(void) { bdrv_register(&bdrv_nbd); bdrv_register(&bdrv_nbd_tcp); bdrv_register(&bdrv_nbd_unix); } block_init(bdrv_nbd_init);
qemu-doc.texi +17 −8 Original line number Diff line number Diff line Loading @@ -610,14 +610,14 @@ QEMU can access directly to block device exported using the Network Block Device protocol. @example qemu-system-i386 linux.img -hdb nbd:my_nbd_server.mydomain.org:1024 qemu-system-i386 linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/ @end example If the NBD server is located on the same host, you can use an unix socket instead of an inet socket: @example qemu-system-i386 linux.img -hdb nbd:unix:/tmp/my_socket qemu-system-i386 linux.img -hdb nbd+unix://?socket=/tmp/my_socket @end example In this case, the block device must be exported using qemu-nbd: Loading @@ -631,17 +631,26 @@ The use of qemu-nbd allows to share a disk between several guests: qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2 @end example @noindent and then you can use it with two guests: @example qemu-system-i386 linux1.img -hdb nbd:unix:/tmp/my_socket qemu-system-i386 linux2.img -hdb nbd:unix:/tmp/my_socket qemu-system-i386 linux1.img -hdb nbd+unix://?socket=/tmp/my_socket qemu-system-i386 linux2.img -hdb nbd+unix://?socket=/tmp/my_socket @end example If the nbd-server uses named exports (since NBD 2.9.18), you must use the "exportname" option: If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's own embedded NBD server), you must specify an export name in the URI: @example qemu-system-i386 -cdrom nbd:localhost:exportname=debian-500-ppc-netinst qemu-system-i386 -cdrom nbd:localhost:exportname=openSUSE-11.1-ppc-netinst qemu-system-i386 -cdrom nbd://localhost/debian-500-ppc-netinst qemu-system-i386 -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst @end example The URI syntax for NBD is supported since QEMU 1.3. An alternative syntax is also available. Here are some example of the older syntax: @example qemu-system-i386 linux.img -hdb nbd:my_nbd_server.mydomain.org:1024 qemu-system-i386 linux2.img -hdb nbd:unix:/tmp/my_socket qemu-system-i386 -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst @end example @node disk_images_sheepdog Loading