[Libvir] PATCH: Create a logfile for each QEMU vm
Daniel P. Berrange
berrange at redhat.com
Tue May 15 16:04:25 UTC 2007
Most of the error reporting the QEMU daemon is focused on sending errors
wrt to RPC ops to the client. There is no provision currently for getting
info about the QEMU vm itself when problems occur. The most common problem
is some mis-configurable in the XML causes qemu to fail to start up. This
results in the completely accurate & completely useless (mea-culpa) error
message
libvirt.libvirtError: virDomainCreateLinux() failed internal error
End-of-file while reading PTY startup output'
What this means is that qemu crashed/exited at startup. Now this patch
does not (yet) directly address that stupid error message, but what it
does do is provide a way to diagnose the real problem.
For every VM we start it will create a logfile
/etc/libvirt/qemu/logs/[vmname].log
Or
$HOME/.libvirt/qemu/logs/[vmname].log
And all output from QEMU's stderr/stdout will get written to this file.
So
# virsh --connect qemu:///system start wizz
libvir: QEMU error : internal error End-of-file while reading PTY startup output
error: Failed to start domain wizz
# cat /etc/libvirt/qemu/logs/wizz.log
qemu: could not open hard disk image '/home/berrange/src/xen/virtinst--devel/demo'
Next up I'm going to work on
a) Improving the error message
b) Adding validation that disk images actually exist before
launching QEMU since that's the most common error we're seeing
Regards,
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
-------------- next part --------------
diff -rup libvirt-0.2.2.orig/libvirt.spec.in libvirt-0.2.2.new/libvirt.spec.in
--- libvirt-0.2.2.orig/libvirt.spec.in 2007-04-17 05:33:16.000000000 -0400
+++ libvirt-0.2.2.new/libvirt.spec.in 2007-05-15 11:53:00.000000000 -0400
@@ -125,6 +125,7 @@ fi
%{_libdir}/lib*.so.*
%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/
%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/
+%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/logs
%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/networks/
%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/networks/autostart
%{_sysconfdir}/rc.d/init.d/libvirtd
diff -rup libvirt-0.2.2.orig/qemud/internal.h libvirt-0.2.2.new/qemud/internal.h
--- libvirt-0.2.2.orig/qemud/internal.h 2007-05-15 10:52:00.000000000 -0400
+++ libvirt-0.2.2.new/qemud/internal.h 2007-05-15 10:55:08.000000000 -0400
@@ -63,7 +63,7 @@ typedef enum {
QEMUD_DIR_AUTOSTART,
QEMUD_DIR_NETWORK_CONFIG,
QEMUD_DIR_NETWORK_AUTOSTART,
-
+ QEMUD_DIR_LOGS,
QEMUD_N_CONFIG_DIRS
} qemudConfigDirType;
@@ -213,6 +213,7 @@ struct qemud_vm {
int stdout;
int stderr;
int monitor;
+ int logfile;
int pid;
int id;
int state;
diff -rup libvirt-0.2.2.orig/qemud/Makefile.am libvirt-0.2.2.new/qemud/Makefile.am
--- libvirt-0.2.2.orig/qemud/Makefile.am 2007-04-06 07:12:29.000000000 -0400
+++ libvirt-0.2.2.new/qemud/Makefile.am 2007-05-15 11:52:46.000000000 -0400
@@ -24,6 +24,7 @@ libvirt_qemud_DEPENDENCIES =
libvirt_qemud_LDADD =
install-data-local:
+ mkdir -p $(DESTDIR)$(sysconfdir)/libvirt/qemu/logs
mkdir -p $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart
$(INSTALL_DATA) $(srcdir)/default-network.xml $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/default.xml
sed -i -e "s,</name>,</name>\n <uuid>$(UUID)</uuid>," $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/default.xml
@@ -36,6 +37,7 @@ uninstall-local:
rm -f $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml
rm -f $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/default.xml
rmdir $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart || :
+ rmdir $(DESTDIR)$(sysconfdir)/libvirt/qemu/logs || :
rmdir $(DESTDIR)$(localstatedir)/run/libvirt || :
rmdir $(DESTDIR)$(localstatedir)/lib/libvirt || :
diff -rup libvirt-0.2.2.orig/qemud/qemud.c libvirt-0.2.2.new/qemud/qemud.c
--- libvirt-0.2.2.orig/qemud/qemud.c 2007-05-15 10:52:00.000000000 -0400
+++ libvirt-0.2.2.new/qemud/qemud.c 2007-05-15 11:46:02.000000000 -0400
@@ -415,6 +415,7 @@ static int qemudInitPaths(struct qemud_s
"libvirt/qemu/autostart", /* QEMUD_DIR_AUTO_DOMAINS */
"libvirt/qemu/networks", /* QEMUD_DIR_NETWORKS */
"libvirt/qemu/networks/autostart", /* QEMUD_DIR_AUTO_NETWORKS */
+ "libvirt/qemu/logs", /* QEMUD_DIR_LOGS */
};
uid_t uid;
@@ -785,6 +786,16 @@ qemudOpenMonitorPath(struct qemud_server
int fd ATTRIBUTE_UNUSED)
{
char monitor[PATH_MAX];
+ int len = strlen(output);
+
+ retry:
+ if (write(vm->logfile, output, len) < 0) {
+ /* Log, but ignore failures to write logfile for VM */
+ if (errno == EINTR)
+ goto retry;
+ qemudLog(QEMUD_WARN, "Unable to log VM console data: %s",
+ strerror(errno));
+ }
if (qemudExtractMonitorPath(output, monitor, sizeof(monitor)) < 0)
return 1; /* keep reading */
@@ -841,6 +852,7 @@ int qemudStartVMDaemon(struct qemud_serv
struct qemud_vm *vm) {
char **argv = NULL;
int i, ret = -1;
+ char logfile[PATH_MAX];
if (qemudIsActiveVM(vm)) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
@@ -859,6 +871,37 @@ int qemudStartVMDaemon(struct qemud_serv
} else
vm->def->vncActivePort = vm->def->vncPort;
+ if ((strlen(server->configDirs[QEMUD_DIR_LOGS]) + /* path */
+ 1 + /* Separator */
+ strlen(vm->def->name) + /* basename */
+ 4 + /* suffix .log */
+ 1 /* NULL */) > PATH_MAX) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "config file path too long: %s/%s.log",
+ server->configDirs[QEMUD_DIR_LOGS],
+ vm->def->name);
+ return -1;
+ }
+ strcpy(logfile, server->configDirs[QEMUD_DIR_LOGS]);
+ strcat(logfile, "/");
+ strcat(logfile, vm->def->name);
+ strcat(logfile, ".log");
+
+ if (qemudEnsureDir(server->configDirs[QEMUD_DIR_LOGS]) < 0) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "cannot create log directory %s: %s",
+ server->configDirs[QEMUD_DIR_LOGS], strerror(err));
+ return -1;
+ }
+
+ if ((vm->logfile = open(logfile, O_CREAT | O_TRUNC | O_WRONLY,
+ S_IRUSR | S_IWUSR)) < 0) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "failed to create logfile %s: %s",
+ logfile, strerror(errno));
+ return -1;
+ }
+
if (qemudBuildCommandLine(server, vm, &argv) < 0)
return -1;
@@ -1038,7 +1081,14 @@ static int qemudVMData(struct qemud_serv
}
buf[ret] = '\0';
- qemudDebug("[%s]", buf);
+ retry:
+ if (write(vm->logfile, buf, ret) < 0) {
+ /* Log, but ignore failures to write logfile for VM */
+ if (errno == EINTR)
+ goto retry;
+ qemudLog(QEMUD_WARN, "Unable to log VM console data: %s",
+ strerror(errno));
+ }
}
}
@@ -1053,10 +1103,12 @@ int qemudShutdownVMDaemon(struct qemud_s
qemudVMData(server, vm, vm->stdout);
qemudVMData(server, vm, vm->stderr);
+ close(vm->logfile);
close(vm->stdout);
close(vm->stderr);
if (vm->monitor != -1)
close(vm->monitor);
+ vm->logfile = -1;
vm->stdout = -1;
vm->stderr = -1;
vm->monitor = -1;
More information about the libvir-list
mailing list