[Libvir] PATCH: Create a logfile for each QEMU vm

Daniel P. Berrange berrange at redhat.com
Tue May 15 17:37:40 UTC 2007


On Tue, May 15, 2007 at 05:15:04PM +0100, Daniel P. Berrange wrote:
> On Tue, May 15, 2007 at 05:09:56PM +0100, Mark McLoughlin wrote:
> > On Tue, 2007-05-15 at 17:04 +0100, Daniel P. Berrange wrote:
> > 
> > > For every VM we start it will create a logfile
> > > 
> > >   /etc/libvirt/qemu/logs/[vmname].log
> > 
> > 	Why not /var/log? /etc/ isn't the place for this kind of stuff, surely.
> 
> True - though we'd have to code different behaviour when running as an
> unprivileged user. Shouldn't complicate things too much i guess.

Attached a new version which does this. If using qemu:///system they get
put into /var/log/libvirt/qemu, while if using qemu://session they go into
$HOME/.libvirt/qemu/log

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 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,</name>,</name>\n  <uuid>$(UUID)</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;


More information about the libvir-list mailing list