summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2022-09-02 11:14:22 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2022-09-02 11:14:22 -0400
commit9fd704da6809f3e01d0283f0d6d619022d481fb9 (patch)
tree73204f61edde82762db2e0df14283a3abe1997c0
parentc125b5520712badab15b90034a808a809288b477 (diff)
parent0f957c53c84d655f2e99677d407cf2bbe1832de4 (diff)
downloadfocaccia-qemu-9fd704da6809f3e01d0283f0d6d619022d481fb9.tar.gz
focaccia-qemu-9fd704da6809f3e01d0283f0d6d619022d481fb9.zip
Merge tag 'char-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging
chardev patches & small audio fix

# -----BEGIN PGP SIGNATURE-----
#
# iQJQBAABCAA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmMSAXYcHG1hcmNhbmRy
# ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5YvaD/9VUIy96LZUGIexEhLj
# IT804yjCtSl9iV7/V7oivIPr9IpTKnUQS/yqbX8B8Afc6uQHDQRrhoNmuDRb3gCo
# V4XhZxZTzUvwJ/FUp35tgsEvqTMsK9taVrPtwVB9VJ3c7OkjvJGn1Q9+Di7WbsuZ
# +rZVR7+1IxkFpIqxBiSqdjHCkqSsAYtaL7wqSnpwiz3jw1nbL25iheo3gylNJbg5
# tfxLLJDFUs9Qqf04iVFtMv9vKoXZDBlCLEiCaCHbpzMXylP6t82oRoj3j2XioqvS
# 9dc3NNcWqTg5Srx1HJ95V8jPnUqLXD91fw9EqD+v0Va1l1JZ+2lGvqnTWDRZfBl3
# 2WZ23oHgwPSgFUyArmrSMX6qRG+f29NHA+r6F5ebVm8AzCP/QkhIqY/EJx8te77C
# 6cN8xS8LDkiL6fsJ5r5ZXViaCgvC33oLSmBQ/wVAJtNChYykmFUBw66Wc+ySSM/L
# HqNNflM1vWHnAc4/EqQT9PYV7cl5Ooss7i1lDIXu5tEpWtBFzV5OFtGE+njfQJ4B
# gpe0zhwXM/+fRyGvDnCkwINTQMgoKku12nTTE9NBpMWxlhW9BtCpY92Ht5BJmNVj
# b+ylbZaTiGBjHfshx0UlZ4vsDDy5gA28gJa7S6cs/Ak7TMLjwqj0Av+upUYt3PBW
# 8A1IB2wL91sFESh5RrMJCg4Bbg==
# =jtDp
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 02 Sep 2022 09:13:26 EDT
# gpg:                using RSA key 87A9BD933F87C606D276F62DDAE8E10975969CE5
# gpg:                issuer "marcandre.lureau@redhat.com"
# gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>" [full]
# gpg:                 aka "Marc-André Lureau <marcandre.lureau@gmail.com>" [full]
# Primary key fingerprint: 87A9 BD93 3F87 C606 D276  F62D DAE8 E109 7596 9CE5

* tag 'char-pull-request' of https://gitlab.com/marcandre.lureau/qemu:
  audio: exit(1) if audio backend failed to be found or initialized
  tests/unit: Update test-io-channel-socket.c for Windows
  chardev/char-socket: Update AF_UNIX for Windows
  util/qemu-sockets: Enable unix socket support on Windows

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r--audio/audio.c14
-rw-r--r--audio/audio.h2
-rw-r--r--chardev/char-socket.c4
-rw-r--r--include/sysemu/os-win32.h17
-rw-r--r--meson.build3
-rw-r--r--softmmu/vl.c4
-rw-r--r--tests/unit/socket-helpers.c16
-rw-r--r--tests/unit/socket-helpers.h9
-rw-r--r--tests/unit/test-io-channel-socket.c37
-rw-r--r--util/qemu-sockets.c25
10 files changed, 85 insertions, 46 deletions
diff --git a/audio/audio.c b/audio/audio.c
index a02f3ce5c6..76b8735b44 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1743,7 +1743,6 @@ static AudioState *audio_init(Audiodev *dev, const char *name)
         atexit(audio_cleanup);
         atexit_registered = true;
     }
-    QTAILQ_INSERT_TAIL(&audio_states, s, list);
 
     s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s);
 
@@ -1769,6 +1768,10 @@ static AudioState *audio_init(Audiodev *dev, const char *name)
         } else {
             dolog ("Unknown audio driver `%s'\n", drvname);
         }
+        if (!done) {
+            free_audio_state(s);
+            return NULL;
+        }
     } else {
         for (i = 0; audio_prio_list[i]; i++) {
             AudiodevListEntry *e = audiodev_find(&head, audio_prio_list[i]);
@@ -1806,6 +1809,7 @@ static AudioState *audio_init(Audiodev *dev, const char *name)
                "(Audio can continue looping even after stopping the VM)\n");
     }
 
+    QTAILQ_INSERT_TAIL(&audio_states, s, list);
     QLIST_INIT (&s->card_head);
     vmstate_register (NULL, 0, &vmstate_audio, s);
     return s;
@@ -2119,13 +2123,17 @@ void audio_define(Audiodev *dev)
     QSIMPLEQ_INSERT_TAIL(&audiodevs, e, next);
 }
 
-void audio_init_audiodevs(void)
+bool audio_init_audiodevs(void)
 {
     AudiodevListEntry *e;
 
     QSIMPLEQ_FOREACH(e, &audiodevs, next) {
-        audio_init(e->dev, NULL);
+        if (!audio_init(e->dev, NULL)) {
+            return false;
+        }
     }
+
+    return true;
 }
 
 audsettings audiodev_to_audsettings(AudiodevPerDirectionOptions *pdo)
diff --git a/audio/audio.h b/audio/audio.h
index b5e17cd218..27e67079a0 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -170,7 +170,7 @@ void audio_sample_from_uint64(void *samples, int pos,
 
 void audio_define(Audiodev *audio);
 void audio_parse_option(const char *opt);
-void audio_init_audiodevs(void);
+bool audio_init_audiodevs(void);
 void audio_legacy_help(void);
 
 AudioState *audio_state_by_name(const char *name);
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index dc4e218eeb..879564aa8a 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -557,12 +557,10 @@ static char *qemu_chr_compute_filename(SocketChardev *s)
     const char *left = "", *right = "";
 
     switch (ss->ss_family) {
-#ifndef _WIN32
     case AF_UNIX:
         return g_strdup_printf("unix:%s%s",
                                ((struct sockaddr_un *)(ss))->sun_path,
                                s->is_listen ? ",server=on" : "");
-#endif
     case AF_INET6:
         left  = "[";
         right = "]";
@@ -1372,10 +1370,12 @@ static void qmp_chardev_open_socket(Chardev *chr,
     }
 
     qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
+#ifndef _WIN32
     /* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */
     if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) {
         qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
     }
+#endif
 
     /*
      * In the chardev-change special-case, we shouldn't register a new yank
diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
index edc3b38a57..5b38c7bd04 100644
--- a/include/sysemu/os-win32.h
+++ b/include/sysemu/os-win32.h
@@ -30,6 +30,23 @@
 #include <windows.h>
 #include <ws2tcpip.h>
 
+#ifdef HAVE_AFUNIX_H
+#include <afunix.h>
+#else
+/*
+ * Fallback definitions of things we need in afunix.h, if not available from
+ * the used Windows SDK or MinGW headers.
+ */
+#define UNIX_PATH_MAX 108
+
+typedef struct sockaddr_un {
+    ADDRESS_FAMILY sun_family;
+    char sun_path[UNIX_PATH_MAX];
+} SOCKADDR_UN, *PSOCKADDR_UN;
+
+#define SIO_AF_UNIX_GETPEERPID _WSAIOR(IOC_VENDOR, 256)
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/meson.build b/meson.build
index 20fddbd707..169b18a279 100644
--- a/meson.build
+++ b/meson.build
@@ -1890,6 +1890,9 @@ config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
+if targetos == 'windows'
+  config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
+endif
 
 # has_function
 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 706bd7cff7..dea4005e47 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -1885,7 +1885,9 @@ static void qemu_create_early_backends(void)
      * setting machine properties, so they can be referred to.
      */
     configure_blockdev(&bdo_queue, machine_class, snapshot);
-    audio_init_audiodevs();
+    if (!audio_init_audiodevs()) {
+        exit(1);
+    }
 }
 
 
diff --git a/tests/unit/socket-helpers.c b/tests/unit/socket-helpers.c
index 5af4de513b..eecadf3a3c 100644
--- a/tests/unit/socket-helpers.c
+++ b/tests/unit/socket-helpers.c
@@ -154,3 +154,19 @@ int socket_check_protocol_support(bool *has_ipv4, bool *has_ipv6)
 
     return 0;
 }
+
+void socket_check_afunix_support(bool *has_afunix)
+{
+    int fd;
+
+    fd = socket(PF_UNIX, SOCK_STREAM, 0);
+    closesocket(fd);
+
+#ifdef _WIN32
+    *has_afunix = (fd != (int)INVALID_SOCKET);
+#else
+    *has_afunix = (fd >= 0);
+#endif
+
+    return;
+}
diff --git a/tests/unit/socket-helpers.h b/tests/unit/socket-helpers.h
index 512a004811..ed8477ceb3 100644
--- a/tests/unit/socket-helpers.h
+++ b/tests/unit/socket-helpers.h
@@ -32,4 +32,13 @@
  */
 int socket_check_protocol_support(bool *has_ipv4, bool *has_ipv6);
 
+/*
+ * @has_afunix: set to true on return if unix socket support is available
+ *
+ * Check whether unix domain socket support is available for use.
+ * On success, @has_afunix will be set to indicate whether AF_UNIX protocol
+ * is available.
+ */
+void socket_check_afunix_support(bool *has_afunix);
+
 #endif
diff --git a/tests/unit/test-io-channel-socket.c b/tests/unit/test-io-channel-socket.c
index 6713886d02..b36a5d972a 100644
--- a/tests/unit/test-io-channel-socket.c
+++ b/tests/unit/test-io-channel-socket.c
@@ -179,10 +179,12 @@ static void test_io_channel(bool async,
         test_io_channel_setup_async(listen_addr, connect_addr,
                                     &srv, &src, &dst);
 
+#ifndef _WIN32
         g_assert(!passFD ||
                  qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
         g_assert(!passFD ||
                  qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
+#endif
         g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
         g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
 
@@ -206,10 +208,12 @@ static void test_io_channel(bool async,
         test_io_channel_setup_async(listen_addr, connect_addr,
                                     &srv, &src, &dst);
 
+#ifndef _WIN32
         g_assert(!passFD ||
                  qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
         g_assert(!passFD ||
                  qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
+#endif
         g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
         g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
 
@@ -236,10 +240,12 @@ static void test_io_channel(bool async,
         test_io_channel_setup_sync(listen_addr, connect_addr,
                                    &srv, &src, &dst);
 
+#ifndef _WIN32
         g_assert(!passFD ||
                  qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
         g_assert(!passFD ||
                  qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
+#endif
         g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
         g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
 
@@ -263,10 +269,12 @@ static void test_io_channel(bool async,
         test_io_channel_setup_sync(listen_addr, connect_addr,
                                    &srv, &src, &dst);
 
+#ifndef _WIN32
         g_assert(!passFD ||
                  qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
         g_assert(!passFD ||
                  qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
+#endif
         g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
         g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
 
@@ -367,7 +375,6 @@ static void test_io_channel_ipv6_async(void)
 }
 
 
-#ifndef _WIN32
 static void test_io_channel_unix(bool async)
 {
     SocketAddress *listen_addr = g_new0(SocketAddress, 1);
@@ -398,6 +405,7 @@ static void test_io_channel_unix_async(void)
     return test_io_channel_unix(true);
 }
 
+#ifndef _WIN32
 static void test_io_channel_unix_fd_pass(void)
 {
     SocketAddress *listen_addr = g_new0(SocketAddress, 1);
@@ -491,6 +499,7 @@ static void test_io_channel_unix_fd_pass(void)
     }
     g_free(fdrecv);
 }
+#endif /* _WIN32 */
 
 static void test_io_channel_unix_listen_cleanup(void)
 {
@@ -522,9 +531,6 @@ static void test_io_channel_unix_listen_cleanup(void)
     unlink(TEST_SOCKET);
 }
 
-#endif /* _WIN32 */
-
-
 static void test_io_channel_ipv4_fd(void)
 {
     QIOChannel *ioc;
@@ -555,7 +561,7 @@ static void test_io_channel_ipv4_fd(void)
 
 int main(int argc, char **argv)
 {
-    bool has_ipv4, has_ipv6;
+    bool has_ipv4, has_ipv6, has_afunix;
 
     module_call_init(MODULE_INIT_QOM);
     qemu_init_main_loop(&error_abort);
@@ -588,16 +594,19 @@ int main(int argc, char **argv)
                         test_io_channel_ipv6_async);
     }
 
+    socket_check_afunix_support(&has_afunix);
+    if (has_afunix) {
+        g_test_add_func("/io/channel/socket/unix-sync",
+                        test_io_channel_unix_sync);
+        g_test_add_func("/io/channel/socket/unix-async",
+                        test_io_channel_unix_async);
 #ifndef _WIN32
-    g_test_add_func("/io/channel/socket/unix-sync",
-                    test_io_channel_unix_sync);
-    g_test_add_func("/io/channel/socket/unix-async",
-                    test_io_channel_unix_async);
-    g_test_add_func("/io/channel/socket/unix-fd-pass",
-                    test_io_channel_unix_fd_pass);
-    g_test_add_func("/io/channel/socket/unix-listen-cleanup",
-                    test_io_channel_unix_listen_cleanup);
-#endif /* _WIN32 */
+        g_test_add_func("/io/channel/socket/unix-fd-pass",
+                        test_io_channel_unix_fd_pass);
+#endif
+        g_test_add_func("/io/channel/socket/unix-listen-cleanup",
+                        test_io_channel_unix_listen_cleanup);
+    }
 
 end:
     return g_test_run();
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 0e2298278f..83f4bd6fd2 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -880,8 +880,6 @@ static int vsock_parse(VsockSocketAddress *addr, const char *str,
 }
 #endif /* CONFIG_AF_VSOCK */
 
-#ifndef _WIN32
-
 static bool saddr_is_abstract(UnixSocketAddress *saddr)
 {
 #ifdef CONFIG_LINUX
@@ -1054,25 +1052,6 @@ static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp)
     return -1;
 }
 
-#else
-
-static int unix_listen_saddr(UnixSocketAddress *saddr,
-                             int num,
-                             Error **errp)
-{
-    error_setg(errp, "unix sockets are not available on windows");
-    errno = ENOTSUP;
-    return -1;
-}
-
-static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp)
-{
-    error_setg(errp, "unix sockets are not available on windows");
-    errno = ENOTSUP;
-    return -1;
-}
-#endif
-
 /* compatibility wrapper */
 int unix_listen(const char *str, Error **errp)
 {
@@ -1335,7 +1314,6 @@ socket_sockaddr_to_address_inet(struct sockaddr_storage *sa,
 }
 
 
-#ifndef WIN32
 static SocketAddress *
 socket_sockaddr_to_address_unix(struct sockaddr_storage *sa,
                                 socklen_t salen,
@@ -1362,7 +1340,6 @@ socket_sockaddr_to_address_unix(struct sockaddr_storage *sa,
     addr->u.q_unix.path = g_strndup(su->sun_path, salen);
     return addr;
 }
-#endif /* WIN32 */
 
 #ifdef CONFIG_AF_VSOCK
 static SocketAddress *
@@ -1394,10 +1371,8 @@ socket_sockaddr_to_address(struct sockaddr_storage *sa,
     case AF_INET6:
         return socket_sockaddr_to_address_inet(sa, salen, errp);
 
-#ifndef WIN32
     case AF_UNIX:
         return socket_sockaddr_to_address_unix(sa, salen, errp);
-#endif /* WIN32 */
 
 #ifdef CONFIG_AF_VSOCK
     case AF_VSOCK: