To use virtio-serial device, unix socket created for chardev with
default umask(022) has insufficient permissions.
e.g. start kvm guest with:
-device virtio-serial \
-chardev socket,path=/tmp/foo,server,nowait,id=foo \
-device virtserialport,chardev=foo,name=org.fedoraproject.port.0
Check permissions for the socket file that has been created in the host
to enable communication through virtual serial ports in the guest:
#ls -l /tmp/somefile.sock
srwxr-xr-x 1 qemu qemu 0 21. Jul 14:19 /tmp/somefile.sock
Other users in the qemu group (like real user, test engines, etc) cannot
write to this socket.
Problem reported here:
https://sourceware.org/bugzilla/show_bug.cgi?id=13078#c11
https://bugzilla.novell.com/show_bug.cgi?id=888166
This patch tries to add a 'umask' option to 'chardev', so that user
can have chance to indicate a umask overwritting the default one (default
is 022), then create unix sockets with expected permissions.
Signed-off-by: Chunyan Liu <cyliu(a)suse.com>
---
This is patch for qemu.
qemu-char.c | 3 +++
qemu-options.hx | 9 +++++++--
util/qemu-sockets.c | 12 +++++++++++-
3 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index d4f327a..a39a5e4 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3856,6 +3856,9 @@ QemuOptsList qemu_chardev_opts = {
},{
.name = "chardev",
.type = QEMU_OPT_STRING,
+ },{
+ .name = "umask",
+ .type = QEMU_OPT_NUMBER,
},
{ /* end of list */ }
},
diff --git a/qemu-options.hx b/qemu-options.hx
index ecd0e34..078e9db 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1929,7 +1929,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
"-chardev null,id=id[,mux=on|off]\n"
"-chardev
socket,id=id[,host=host],port=port[,to=to][,ipv4][,ipv6][,nodelay]\n"
" [,server][,nowait][,telnet][,mux=on|off] (tcp)\n"
- "-chardev socket,id=id,path=path[,server][,nowait][,telnet],[mux=on|off]
(unix)\n"
+ "-chardev socket,id=id,path=path[,umask][,server][,nowait][,telnet],[mux=on|off]
(unix)\n"
"-chardev udp,id=id[,host=host],port=port[,localaddr=localaddr]\n"
" [,localport=localport][,ipv4][,ipv6][,mux=on|off]\n"
"-chardev msmouse,id=id[,mux=on|off]\n"
@@ -2001,12 +2001,17 @@ Options to each backend are described below.
A void device. This device will not emit any data, and will drop any data it
receives. The null backend does not take any options.
-@item -chardev socket ,id=@var{id} [@var{TCP options} or @var{unix options}] [,server]
[,nowait] [,telnet]
+@item -chardev socket ,id=@var{id} [@var{TCP options} or @var{unix options}]
[,umask][,server] [,nowait] [,telnet]
Create a two-way stream socket, which can be either a TCP or a unix socket. A
unix socket will be created if @option{path} is specified. Behaviour is
undefined if TCP options are specified for a unix socket.
+@option{umask} specifies the umask used for creating a unix socket. Without
+this option, default umask(022) will be used, permission is not sufficient
+for virtio-serial device. One can indicate umask=0x002 for virtio-serial
+device for correct usage.
+
@option{server} specifies that the socket shall be a listening socket.
@option{nowait} specifies that QEMU should not block waiting for a client to
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 5d38395..facf2c6 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -680,7 +680,8 @@ int unix_listen_opts(QemuOpts *opts, Error **errp)
{
struct sockaddr_un un;
const char *path = qemu_opt_get(opts, "path");
- int sock, fd;
+ int newmask = qemu_opt_get_number(opts, "umask", 0);
+ int sock, fd, oldmask;
sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
@@ -708,10 +709,19 @@ int unix_listen_opts(QemuOpts *opts, Error **errp)
}
unlink(un.sun_path);
+ if (newmask) {
+ oldmask = umask(newmask);
+ }
if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) {
+ if (newmask) {
+ umask(oldmask);
+ }
error_set_errno(errp, errno, QERR_SOCKET_BIND_FAILED);
goto err;
}
+ if (newmask) {
+ umask(oldmask);
+ }
if (listen(sock, 1) < 0) {
error_set_errno(errp, errno, QERR_SOCKET_LISTEN_FAILED);
goto err;
--
1.8.5.2