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_barab...@mentor.com> --- qemu-config.c | 3 +++ qemu-sockets.c | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/qemu-config.c b/qemu-config.c index 2188c3e..5b0f71e 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -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, },{ diff --git a/qemu-sockets.c b/qemu-sockets.c index 3537bf3..b1c3a79 100644 --- a/qemu-sockets.c +++ b/qemu-sockets.c @@ -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); -- 1.7.9.5