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 -=|
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;