提交 1b8bbb46 编写于 作者: M MORITA Kazutaka 提交者: Stefan Hajnoczi

sheepdog: add support for connecting to unix domain socket

This patch adds support for a unix domain socket for a connection
between qemu and local sheepdog server.  You can use the unix domain
socket with the following syntax:

 $ qemu sheepdog+unix:///<vdiname>?socket=<socket path>[#snapid]
Signed-off-by: NMORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: NStefan Hajnoczi <stefanha@redhat.com>
上级 25af257d
...@@ -299,6 +299,7 @@ typedef struct BDRVSheepdogState { ...@@ -299,6 +299,7 @@ typedef struct BDRVSheepdogState {
uint32_t cache_flags; uint32_t cache_flags;
char *host_spec; char *host_spec;
bool is_unix;
int fd; int fd;
CoMutex lock; CoMutex lock;
...@@ -451,7 +452,18 @@ static int connect_to_sdog(BDRVSheepdogState *s) ...@@ -451,7 +452,18 @@ static int connect_to_sdog(BDRVSheepdogState *s)
int fd; int fd;
Error *err = NULL; Error *err = NULL;
fd = inet_connect(s->host_spec, &err); if (s->is_unix) {
fd = unix_connect(s->host_spec, &err);
} else {
fd = inet_connect(s->host_spec, &err);
if (err == NULL) {
int ret = socket_set_nodelay(fd);
if (ret < 0) {
error_report("%s", strerror(errno));
}
}
}
if (err != NULL) { if (err != NULL) {
qerror_report_err(err); qerror_report_err(err);
...@@ -757,7 +769,7 @@ static int aio_flush_request(void *opaque) ...@@ -757,7 +769,7 @@ static int aio_flush_request(void *opaque)
*/ */
static int get_sheep_fd(BDRVSheepdogState *s) static int get_sheep_fd(BDRVSheepdogState *s)
{ {
int ret, fd; int fd;
fd = connect_to_sdog(s); fd = connect_to_sdog(s);
if (fd < 0) { if (fd < 0) {
...@@ -766,13 +778,6 @@ static int get_sheep_fd(BDRVSheepdogState *s) ...@@ -766,13 +778,6 @@ static int get_sheep_fd(BDRVSheepdogState *s)
socket_set_nonblock(fd); socket_set_nonblock(fd);
ret = socket_set_nodelay(fd);
if (ret) {
error_report("%s", strerror(errno));
closesocket(fd);
return -errno;
}
qemu_aio_set_fd_handler(fd, co_read_response, NULL, aio_flush_request, s); qemu_aio_set_fd_handler(fd, co_read_response, NULL, aio_flush_request, s);
return fd; return fd;
} }
...@@ -789,15 +794,42 @@ static int sd_parse_uri(BDRVSheepdogState *s, const char *filename, ...@@ -789,15 +794,42 @@ static int sd_parse_uri(BDRVSheepdogState *s, const char *filename,
return -EINVAL; return -EINVAL;
} }
/* transport */
if (!strcmp(uri->scheme, "sheepdog")) {
s->is_unix = false;
} else if (!strcmp(uri->scheme, "sheepdog+tcp")) {
s->is_unix = false;
} else if (!strcmp(uri->scheme, "sheepdog+unix")) {
s->is_unix = true;
} else {
ret = -EINVAL;
goto out;
}
if (uri->path == NULL || !strcmp(uri->path, "/")) { if (uri->path == NULL || !strcmp(uri->path, "/")) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
pstrcpy(vdi, SD_MAX_VDI_LEN, uri->path + 1); pstrcpy(vdi, SD_MAX_VDI_LEN, uri->path + 1);
/* sheepdog[+tcp]://[host:port]/vdiname */ qp = query_params_parse(uri->query);
s->host_spec = g_strdup_printf("%s:%d", uri->server ?: SD_DEFAULT_ADDR, if (qp->n > 1 || (s->is_unix && !qp->n) || (!s->is_unix && qp->n)) {
uri->port ?: SD_DEFAULT_PORT); ret = -EINVAL;
goto out;
}
if (s->is_unix) {
/* sheepdog+unix:///vdiname?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 {
/* sheepdog[+tcp]://[host:port]/vdiname */
s->host_spec = g_strdup_printf("%s:%d", uri->server ?: SD_DEFAULT_ADDR,
uri->port ?: SD_DEFAULT_PORT);
}
/* snapshot tag */ /* snapshot tag */
if (uri->fragment) { if (uri->fragment) {
...@@ -2098,9 +2130,35 @@ static BlockDriver bdrv_sheepdog_tcp = { ...@@ -2098,9 +2130,35 @@ static BlockDriver bdrv_sheepdog_tcp = {
.create_options = sd_create_options, .create_options = sd_create_options,
}; };
static BlockDriver bdrv_sheepdog_unix = {
.format_name = "sheepdog",
.protocol_name = "sheepdog+unix",
.instance_size = sizeof(BDRVSheepdogState),
.bdrv_file_open = sd_open,
.bdrv_close = sd_close,
.bdrv_create = sd_create,
.bdrv_getlength = sd_getlength,
.bdrv_truncate = sd_truncate,
.bdrv_co_readv = sd_co_readv,
.bdrv_co_writev = sd_co_writev,
.bdrv_co_flush_to_disk = sd_co_flush_to_disk,
.bdrv_snapshot_create = sd_snapshot_create,
.bdrv_snapshot_goto = sd_snapshot_goto,
.bdrv_snapshot_delete = sd_snapshot_delete,
.bdrv_snapshot_list = sd_snapshot_list,
.bdrv_save_vmstate = sd_save_vmstate,
.bdrv_load_vmstate = sd_load_vmstate,
.create_options = sd_create_options,
};
static void bdrv_sheepdog_init(void) static void bdrv_sheepdog_init(void)
{ {
bdrv_register(&bdrv_sheepdog); bdrv_register(&bdrv_sheepdog);
bdrv_register(&bdrv_sheepdog_tcp); bdrv_register(&bdrv_sheepdog_tcp);
bdrv_register(&bdrv_sheepdog_unix);
} }
block_init(bdrv_sheepdog_init); block_init(bdrv_sheepdog_init);
...@@ -865,6 +865,12 @@ qemu-img create -b sheepdog:///@var{base}#@var{tag} sheepdog:///@var{image} ...@@ -865,6 +865,12 @@ qemu-img create -b sheepdog:///@var{base}#@var{tag} sheepdog:///@var{image}
where @var{base} is a image name of the source snapshot and @var{tag} where @var{base} is a image name of the source snapshot and @var{tag}
is its tag name. is its tag name.
You can use an unix socket instead of an inet socket:
@example
qemu-system-i386 sheepdog+unix:///@var{image}?socket=@var{path}
@end example
If the Sheepdog daemon doesn't run on the local host, you need to If the Sheepdog daemon doesn't run on the local host, you need to
specify one of the Sheepdog servers to connect to. specify one of the Sheepdog servers to connect to.
@example @example
......
...@@ -2100,7 +2100,7 @@ devices. ...@@ -2100,7 +2100,7 @@ devices.
Syntax for specifying a sheepdog device Syntax for specifying a sheepdog device
@example @example
sheepdog[+tcp]://[host:port]/vdiname[#snapid|#tag] sheepdog[+tcp|+unix]://[host:port]/vdiname[?socket=path][#snapid|#tag]
@end example @end example
Example Example
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册