Revision 1d7d2a9d
b/block/nbd.c | ||
---|---|---|
28 | 28 |
|
29 | 29 |
#include "qemu-common.h" |
30 | 30 |
#include "nbd.h" |
31 |
#include "uri.h" |
|
31 | 32 |
#include "block_int.h" |
32 | 33 |
#include "module.h" |
33 | 34 |
#include "qemu_socket.h" |
... | ... | |
69 | 70 |
char *export_name; /* An NBD server may export several devices */ |
70 | 71 |
} BDRVNBDState; |
71 | 72 |
|
73 |
static int nbd_parse_uri(BDRVNBDState *s, const char *filename) |
|
74 |
{ |
|
75 |
URI *uri; |
|
76 |
const char *p; |
|
77 |
QueryParams *qp = NULL; |
|
78 |
int ret = 0; |
|
79 |
|
|
80 |
uri = uri_parse(filename); |
|
81 |
if (!uri) { |
|
82 |
return -EINVAL; |
|
83 |
} |
|
84 |
|
|
85 |
/* transport */ |
|
86 |
if (!strcmp(uri->scheme, "nbd")) { |
|
87 |
s->is_unix = false; |
|
88 |
} else if (!strcmp(uri->scheme, "nbd+tcp")) { |
|
89 |
s->is_unix = false; |
|
90 |
} else if (!strcmp(uri->scheme, "nbd+unix")) { |
|
91 |
s->is_unix = true; |
|
92 |
} else { |
|
93 |
ret = -EINVAL; |
|
94 |
goto out; |
|
95 |
} |
|
96 |
|
|
97 |
p = uri->path ? uri->path : "/"; |
|
98 |
p += strspn(p, "/"); |
|
99 |
if (p[0]) { |
|
100 |
s->export_name = g_strdup(p); |
|
101 |
} |
|
102 |
|
|
103 |
qp = query_params_parse(uri->query); |
|
104 |
if (qp->n > 1 || (s->is_unix && !qp->n) || (!s->is_unix && qp->n)) { |
|
105 |
ret = -EINVAL; |
|
106 |
goto out; |
|
107 |
} |
|
108 |
|
|
109 |
if (s->is_unix) { |
|
110 |
/* nbd+unix:///export?socket=path */ |
|
111 |
if (uri->server || uri->port || strcmp(qp->p[0].name, "socket")) { |
|
112 |
ret = -EINVAL; |
|
113 |
goto out; |
|
114 |
} |
|
115 |
s->host_spec = g_strdup(qp->p[0].value); |
|
116 |
} else { |
|
117 |
/* nbd[+tcp]://host:port/export */ |
|
118 |
if (!uri->server) { |
|
119 |
ret = -EINVAL; |
|
120 |
goto out; |
|
121 |
} |
|
122 |
if (!uri->port) { |
|
123 |
uri->port = NBD_DEFAULT_PORT; |
|
124 |
} |
|
125 |
s->host_spec = g_strdup_printf("%s:%d", uri->server, uri->port); |
|
126 |
} |
|
127 |
|
|
128 |
out: |
|
129 |
if (qp) { |
|
130 |
query_params_free(qp); |
|
131 |
} |
|
132 |
uri_free(uri); |
|
133 |
return ret; |
|
134 |
} |
|
135 |
|
|
72 | 136 |
static int nbd_config(BDRVNBDState *s, const char *filename) |
73 | 137 |
{ |
74 | 138 |
char *file; |
... | ... | |
77 | 141 |
const char *unixpath; |
78 | 142 |
int err = -EINVAL; |
79 | 143 |
|
144 |
if (strstr(filename, "://")) { |
|
145 |
return nbd_parse_uri(s, filename); |
|
146 |
} |
|
147 |
|
|
80 | 148 |
file = g_strdup(filename); |
81 | 149 |
|
82 | 150 |
export_name = strstr(file, EN_OPTSTR); |
... | ... | |
495 | 563 |
|
496 | 564 |
static BlockDriver bdrv_nbd = { |
497 | 565 |
.format_name = "nbd", |
566 |
.protocol_name = "nbd", |
|
567 |
.instance_size = sizeof(BDRVNBDState), |
|
568 |
.bdrv_file_open = nbd_open, |
|
569 |
.bdrv_co_readv = nbd_co_readv, |
|
570 |
.bdrv_co_writev = nbd_co_writev, |
|
571 |
.bdrv_close = nbd_close, |
|
572 |
.bdrv_co_flush_to_os = nbd_co_flush, |
|
573 |
.bdrv_co_discard = nbd_co_discard, |
|
574 |
.bdrv_getlength = nbd_getlength, |
|
575 |
}; |
|
576 |
|
|
577 |
static BlockDriver bdrv_nbd_tcp = { |
|
578 |
.format_name = "nbd", |
|
579 |
.protocol_name = "nbd+tcp", |
|
580 |
.instance_size = sizeof(BDRVNBDState), |
|
581 |
.bdrv_file_open = nbd_open, |
|
582 |
.bdrv_co_readv = nbd_co_readv, |
|
583 |
.bdrv_co_writev = nbd_co_writev, |
|
584 |
.bdrv_close = nbd_close, |
|
585 |
.bdrv_co_flush_to_os = nbd_co_flush, |
|
586 |
.bdrv_co_discard = nbd_co_discard, |
|
587 |
.bdrv_getlength = nbd_getlength, |
|
588 |
}; |
|
589 |
|
|
590 |
static BlockDriver bdrv_nbd_unix = { |
|
591 |
.format_name = "nbd", |
|
592 |
.protocol_name = "nbd+unix", |
|
498 | 593 |
.instance_size = sizeof(BDRVNBDState), |
499 | 594 |
.bdrv_file_open = nbd_open, |
500 | 595 |
.bdrv_co_readv = nbd_co_readv, |
... | ... | |
503 | 598 |
.bdrv_co_flush_to_os = nbd_co_flush, |
504 | 599 |
.bdrv_co_discard = nbd_co_discard, |
505 | 600 |
.bdrv_getlength = nbd_getlength, |
506 |
.protocol_name = "nbd", |
|
507 | 601 |
}; |
508 | 602 |
|
509 | 603 |
static void bdrv_nbd_init(void) |
510 | 604 |
{ |
511 | 605 |
bdrv_register(&bdrv_nbd); |
606 |
bdrv_register(&bdrv_nbd_tcp); |
|
607 |
bdrv_register(&bdrv_nbd_unix); |
|
512 | 608 |
} |
513 | 609 |
|
514 | 610 |
block_init(bdrv_nbd_init); |
b/qemu-doc.texi | ||
---|---|---|
610 | 610 |
protocol. |
611 | 611 |
|
612 | 612 |
@example |
613 |
qemu-system-i386 linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
|
|
613 |
qemu-system-i386 linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/
|
|
614 | 614 |
@end example |
615 | 615 |
|
616 | 616 |
If the NBD server is located on the same host, you can use an unix socket instead |
617 | 617 |
of an inet socket: |
618 | 618 |
|
619 | 619 |
@example |
620 |
qemu-system-i386 linux.img -hdb nbd:unix:/tmp/my_socket
|
|
620 |
qemu-system-i386 linux.img -hdb nbd+unix://?socket=/tmp/my_socket
|
|
621 | 621 |
@end example |
622 | 622 |
|
623 | 623 |
In this case, the block device must be exported using qemu-nbd: |
... | ... | |
631 | 631 |
qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2 |
632 | 632 |
@end example |
633 | 633 |
|
634 |
@noindent |
|
634 | 635 |
and then you can use it with two guests: |
635 | 636 |
@example |
636 |
qemu-system-i386 linux1.img -hdb nbd:unix:/tmp/my_socket
|
|
637 |
qemu-system-i386 linux2.img -hdb nbd:unix:/tmp/my_socket
|
|
637 |
qemu-system-i386 linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
|
|
638 |
qemu-system-i386 linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
|
|
638 | 639 |
@end example |
639 | 640 |
|
640 |
If the nbd-server uses named exports (since NBD 2.9.18), you must use the
|
|
641 |
"exportname" option:
|
|
641 |
If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's
|
|
642 |
own embedded NBD server), you must specify an export name in the URI:
|
|
642 | 643 |
@example |
643 |
qemu-system-i386 -cdrom nbd:localhost:exportname=debian-500-ppc-netinst |
|
644 |
qemu-system-i386 -cdrom nbd:localhost:exportname=openSUSE-11.1-ppc-netinst |
|
644 |
qemu-system-i386 -cdrom nbd://localhost/debian-500-ppc-netinst |
|
645 |
qemu-system-i386 -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst |
|
646 |
@end example |
|
647 |
|
|
648 |
The URI syntax for NBD is supported since QEMU 1.3. An alternative syntax is |
|
649 |
also available. Here are some example of the older syntax: |
|
650 |
@example |
|
651 |
qemu-system-i386 linux.img -hdb nbd:my_nbd_server.mydomain.org:1024 |
|
652 |
qemu-system-i386 linux2.img -hdb nbd:unix:/tmp/my_socket |
|
653 |
qemu-system-i386 -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst |
|
645 | 654 |
@end example |
646 | 655 |
|
647 | 656 |
@node disk_images_sheepdog |
Also available in: Unified diff