@@ -182,6 +182,9 @@ static QemuOptsList qemu_chardev_opts = {
.name = "ipv6",
.type = QEMU_OPT_BOOL,
},{
+ .name = "abstract",
+ .type = QEMU_OPT_BOOL,
+ },{
.name = "wait",
.type = QEMU_OPT_BOOL,
},{
@@ -56,6 +56,9 @@ static QemuOptsList dummy_opts = {
},{
.name = "ipv6",
.type = QEMU_OPT_BOOL,
+ },{
+ .name = "abstract",
+ .type = QEMU_OPT_BOOL,
},
{ /* end if list */ }
},
@@ -667,7 +670,9 @@ int unix_listen_opts(QemuOpts *opts, Error **errp)
{
struct sockaddr_un un;
const char *path = qemu_opt_get(opts, "path");
+ bool abstract = qemu_opt_get_bool(opts, "abstract", false);
int sock, fd;
+ socklen_t addrlen = sizeof(un);
sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
@@ -678,7 +683,15 @@ int unix_listen_opts(QemuOpts *opts, Error **errp)
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
if (path && strlen(path)) {
- snprintf(un.sun_path, sizeof(un.sun_path), "%s", path);
+ if (!abstract) {
+ snprintf(un.sun_path, sizeof(un.sun_path), "%s", path);
+ } else {
+ int printed_chars;
+ printed_chars = snprintf(un.sun_path + 1, sizeof(un.sun_path) - 1,
+ "%s", path);
+ addrlen =
+ offsetof(struct sockaddr_un, sun_path) + 1 + printed_chars;
+ }
} else {
char *tmpdir = getenv("TMPDIR");
snprintf(un.sun_path, sizeof(un.sun_path), "%s/qemu-socket-XXXXXX",
@@ -694,8 +707,10 @@ int unix_listen_opts(QemuOpts *opts, Error **errp)
qemu_opt_set(opts, "path", un.sun_path);
}
- unlink(un.sun_path);
- if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) {
+ if (!abstract) {
+ unlink(un.sun_path);
+ }
+ if (bind(sock, (struct sockaddr *) &un, addrlen) < 0) {
error_set_errno(errp, errno, QERR_SOCKET_BIND_FAILED);
goto err;
}
@@ -716,8 +731,10 @@ int unix_connect_opts(QemuOpts *opts, Error **errp,
{
struct sockaddr_un un;
const char *path = qemu_opt_get(opts, "path");
+ bool abstract = qemu_opt_get_bool(opts, "abstract", false);
ConnectState *connect_state = NULL;
int sock, rc;
+ socklen_t addrlen = sizeof(un);
if (NULL == path) {
error_setg(errp, "unix connect: no path specified\n");
@@ -738,12 +755,20 @@ int unix_connect_opts(QemuOpts *opts, Error **errp,
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
- snprintf(un.sun_path, sizeof(un.sun_path), "%s", path);
+ if (!abstract) {
+ snprintf(un.sun_path, sizeof(un.sun_path), "%s", path);
+ } else {
+ int printed_chars;
+ printed_chars = snprintf(un.sun_path + 1, sizeof(un.sun_path) - 1,
+ "%s", path);
+ addrlen =
+ offsetof(struct sockaddr_un, sun_path) + 1 + printed_chars;
+ }
/* connect to peer */
do {
rc = 0;
- if (connect(sock, (struct sockaddr *) &un, sizeof(un)) < 0) {
+ if (connect(sock, (struct sockaddr *) &un, addrlen) < 0) {
rc = -socket_error();
}
} while (rc == -EINTR);
The abstract socket namespace is a nonportable Linux extension. The sockets' names in this namespace have no connection with file system pathnames. To specify a named AF_UNIX socket in the abstract socket namespace, pass true for the boolean flag "abstract", e.g.: qemu -chardev socket,path=NAME_OF_THE_SOCKET,abstract=on Signed-off-by: Alexander Barabash <alexander_barabash@mentor.com> --- qemu-config.c | 3 +++ qemu-sockets.c | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 5 deletions(-)