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 13:11:28.000000000 -0400 @@ -137,6 +137,7 @@ fi %{_datadir}/libvirt/networks/default.xml %dir %{_localstatedir}/run/libvirt/ %dir %{_localstatedir}/lib/libvirt/ +%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/qemu/ %attr(4755, root, root) %{_libexecdir}/libvirt_proxy %attr(0755, root, root) %{_sbindir}/libvirt_qemud %doc docs/libvirt.rng 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 13:02:08.000000000 -0400 @@ -63,7 +63,6 @@ typedef enum { QEMUD_DIR_AUTOSTART, QEMUD_DIR_NETWORK_CONFIG, QEMUD_DIR_NETWORK_AUTOSTART, - QEMUD_N_CONFIG_DIRS } qemudConfigDirType; @@ -213,6 +212,7 @@ struct qemud_vm { int stdout; int stderr; int monitor; + int logfile; int pid; int id; int state; @@ -319,6 +319,7 @@ struct qemud_server { char *autostartDir; char *networkConfigDir; char *networkAutostartDir; + char logDir[PATH_MAX]; char errorMessage[QEMUD_MAX_ERROR_LEN]; int errorCode; unsigned int shutdown : 1; 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 13:15:52.000000000 -0400 @@ -29,6 +29,7 @@ install-data-local: sed -i -e "s,,\n $(UUID)," $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/default.xml test -e $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml || \ ln -s ../default.xml $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml + mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/qemu mkdir -p $(DESTDIR)$(localstatedir)/run/libvirt mkdir -p $(DESTDIR)$(localstatedir)/lib/libvirt @@ -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)$(localstatedir)/log/libvirt/qemu || : 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 13:26:42.000000000 -0400 @@ -439,6 +439,9 @@ static int qemudInitPaths(struct qemud_s goto snprintf_error; unlink(roSockname); + + if (snprintf(server->logDir, PATH_MAX, "%s/log/libvirt/qemu", LOCAL_STATE_DIR) >= PATH_MAX) + goto snprintf_error; } else { if (!(pw = getpwuid(uid))) { qemudLog(QEMUD_ERR, "Failed to find user record for uid '%d': %s", @@ -451,12 +454,16 @@ static int qemudInitPaths(struct qemud_s if (snprintf(base, PATH_MAX, "%s/.", pw->pw_dir) >= PATH_MAX) goto snprintf_error; + + if (snprintf(server->logDir, PATH_MAX, "%s/.libvirt/qemu/log", pw->pw_dir) >= PATH_MAX) + goto snprintf_error; } for (i = 0; i < QEMUD_N_CONFIG_DIRS; i++) if (snprintf(server->configDirs[i], PATH_MAX, "%s%s", base, paths[i]) >= PATH_MAX) goto snprintf_error; + return 0; snprintf_error: @@ -785,6 +792,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 +858,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 +877,36 @@ int qemudStartVMDaemon(struct qemud_serv } else vm->def->vncActivePort = vm->def->vncPort; + if ((strlen(server->logDir) + /* 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->logDir, vm->def->name); + return -1; + } + strcpy(logfile, server->logDir); + strcat(logfile, "/"); + strcat(logfile, vm->def->name); + strcat(logfile, ".log"); + + if (qemudEnsureDir(server->logDir) < 0) { + qemudReportError(server, VIR_ERR_INTERNAL_ERROR, + "cannot create log directory %s: %s", + server->logDir, strerror(errno)); + 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 +1086,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 +1108,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;