Historically libvirt has connected stdout & stderr from QEMU directly to a plain file (/var/log/libvirt/qemu/$GUESTNAME.log). This has worked well enough in general, but is susceptible to a guest denial of service if the guest can cause QEMU to spew messages to stderr. There are enough places in QEMU and SPICE that still print to stderr that this isn't very hard to achieve. So In libvirt 1.3.0 we introduce a new daemon 'virtlogd' which is used for handling log file writing. When this is used, QEMU's stdout/stderr will be connected to an anonymous pipe file descriptor, the other end of which is held by the virtlogd daemon. The virtlogd daemon will only permit a fixed file size to be created before rotating the log file, so we no longer have the possibility of unbounded disk usage, which is nice. I'm now looking to extend the use of 'virtlogd' to also handle character devices. OpenStack has historically configured the primary serial port to log to a file in order to capture kernel boot up messages and later report them to the user via its API. This serial port file backend is of course susceptible to the same disk space denial of service. We don't really want to push file rotation logic into QEMU because that would involve giving QEMU permission to create / rename files, which is undesirable from a security POV. We also prefer a solution that ideally works with existing QEMU builds. So for this my plan is to stop using the QEMU 'file' backend for char devs and instead pass across a pre-opened file descriptor, connected to virtlogd. There is no "officially documented" way to pass in a file descriptor to QEMU chardevs, but since QEMU uses qemu_open(), we can make use of the fdset feature to achieve this. eg eg, consider fd 33 is the write end of a pipe file descriptor I can (in theory) do -add-fd set=2,fd=33 -chardev file,id=charserial0,path=/dev/fdset/2 Now in practice this doesn't work, because qmp_chardev_open_file() passes the O_CREAT|O_TRUNC flags in, which means the qemu_open() call will fail when using the pipe FD pased in via fdsets. After more investigation I found it *is* possible to use a socketpair and a pipe backend though... -add-fd set=2,fd=33 -chardev pipe,id=charserial0,path=/dev/fdset/2 ..because for reasons I don't understand, if QEMU can't open $PATH.in and $PATH.out, it'll fallback to just opening $PATH in read-write mode even. AFAICT, this is pretty useless with pipes since they are unidirectional, but, it works nicely with socketpairs, where virtlogd has one of the socketpairs and QEMU gets passed the other via fdset. I can easily check this works for historical QEMU versions back to when fdsets support was added to chardevs, but I'm working if the QEMU maintainers consider this usage acceptable over the long term, and if so, should we explicitly document it as supported ? If not, should we introduce a more explicit syntax for passing in a pre-opened FD for chardevs ? eg -add-fd set=2,fd=33 -chardev fd,id=charserial0,path=/dev/fdset/2 Or just make -chardev file,id=charserial0,path=/dev/fdset/2 actually work ? Or something else ? OpenStack has a further requirement to allow use of the serial port as an interactive console, at the same time that it is logging to a file which is something QEMU can't support at all currently. This essentially means being able to have multiple chardev backends all connected to the same serial frontend - specifically we would need a TCP backend and a file backend concurrently. Again this could be implemented in QEMU, but we'd prefer something that works with existing QEMU. This is not too difficult to achieve with virtlogd really. Instead of using the QEMU 'tcp' or 'unix' chardev protocol, we'd just always pass QEMU a pre-opened socketpair, and then leave the TCP/UNIX socket listening to the virtlogd daemon. This is portable with existing QEMU versions, but the obvious downside with this is extra copies in the interactive console path. So might it be worth exploring the posibility of a chardev multiplexor in QEMU. We would still pass in a pre-opened socketpair to QEMU for the logging side of things, but would leave the TCP/UNIX socket listening upto QEMU still. eg should we make something like this work: -add-fd set=2,fd=33 -chardev pipe,id=charserial0file,path=/dev/fdset/2 -chardev socket,id=charserial0tcp,host=127.0.0.1,port=9999,telnet,server,nowait -chardev multiplex,id=charserial0,muxA=charserial0file,muxB=charserial1 -serial isa-serial,chardev=charserial0,id=serial0 Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list