mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
Added per-VM logging
This commit is contained in:
parent
ef38afcfd4
commit
85e9f9fb47
@ -1,3 +1,9 @@
|
|||||||
|
Fri May 18 14:36:00 EST 2007 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
* qemud/conf.c, qemud/internal.h, qemud/qemud.c: Save VM output
|
||||||
|
in a logfile
|
||||||
|
* libvirt.spec.in: added /var/log/libvirt/qemud directory
|
||||||
|
|
||||||
Mon May 14 11:00:00 EST 2007 Daniel P. Berrange <berrange@redhat.com>
|
Mon May 14 11:00:00 EST 2007 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
* qemud/conf.c: Fix initialization of var to prevent stack
|
* qemud/conf.c: Fix initialization of var to prevent stack
|
||||||
|
@ -138,6 +138,7 @@ fi
|
|||||||
%{_datadir}/libvirt/networks/default.xml
|
%{_datadir}/libvirt/networks/default.xml
|
||||||
%dir %{_localstatedir}/run/libvirt/
|
%dir %{_localstatedir}/run/libvirt/
|
||||||
%dir %{_localstatedir}/lib/libvirt/
|
%dir %{_localstatedir}/lib/libvirt/
|
||||||
|
%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/qemu/
|
||||||
%attr(4755, root, root) %{_libexecdir}/libvirt_proxy
|
%attr(4755, root, root) %{_libexecdir}/libvirt_proxy
|
||||||
%attr(0755, root, root) %{_sbindir}/libvirt_qemud
|
%attr(0755, root, root) %{_sbindir}/libvirt_qemud
|
||||||
%doc docs/libvirt.rng
|
%doc docs/libvirt.rng
|
||||||
|
@ -29,6 +29,7 @@ install-data-local:
|
|||||||
sed -i -e "s,</name>,</name>\n <uuid>$(UUID)</uuid>," $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/default.xml
|
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 || \
|
test -e $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml || \
|
||||||
ln -s ../default.xml $(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)/run/libvirt
|
||||||
mkdir -p $(DESTDIR)$(localstatedir)/lib/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/autostart/default.xml
|
||||||
rm -f $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/default.xml
|
rm -f $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/default.xml
|
||||||
rmdir $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart || :
|
rmdir $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart || :
|
||||||
|
rmdir $(DESTDIR)$(localstatedir)/log/libvirt/qemu || :
|
||||||
rmdir $(DESTDIR)$(localstatedir)/run/libvirt || :
|
rmdir $(DESTDIR)$(localstatedir)/run/libvirt || :
|
||||||
rmdir $(DESTDIR)$(localstatedir)/lib/libvirt || :
|
rmdir $(DESTDIR)$(localstatedir)/lib/libvirt || :
|
||||||
|
|
||||||
|
@ -1212,12 +1212,12 @@ int qemudBuildCommandLine(struct qemud_server *server,
|
|||||||
|
|
||||||
uname(&ut);
|
uname(&ut);
|
||||||
|
|
||||||
/* Nasty hack make i?86 look like i386 to simplify next comparison */
|
/* Nasty hack make i?86 look like i686 to simplify next comparison */
|
||||||
if (ut.machine[0] == 'i' &&
|
if (ut.machine[0] == 'i' &&
|
||||||
ut.machine[2] == '8' &&
|
ut.machine[2] == '8' &&
|
||||||
ut.machine[3] == '6' &&
|
ut.machine[3] == '6' &&
|
||||||
!ut.machine[4])
|
!ut.machine[4])
|
||||||
ut.machine[1] = '3';
|
ut.machine[1] = '6';
|
||||||
|
|
||||||
/* Need to explicitly disable KQEMU if
|
/* Need to explicitly disable KQEMU if
|
||||||
* 1. Arch matches host arch
|
* 1. Arch matches host arch
|
||||||
|
@ -213,6 +213,7 @@ struct qemud_vm {
|
|||||||
int stdout;
|
int stdout;
|
||||||
int stderr;
|
int stderr;
|
||||||
int monitor;
|
int monitor;
|
||||||
|
int logfile;
|
||||||
int pid;
|
int pid;
|
||||||
int id;
|
int id;
|
||||||
int state;
|
int state;
|
||||||
@ -319,6 +320,7 @@ struct qemud_server {
|
|||||||
char *autostartDir;
|
char *autostartDir;
|
||||||
char *networkConfigDir;
|
char *networkConfigDir;
|
||||||
char *networkAutostartDir;
|
char *networkAutostartDir;
|
||||||
|
char logDir[PATH_MAX];
|
||||||
char errorMessage[QEMUD_MAX_ERROR_LEN];
|
char errorMessage[QEMUD_MAX_ERROR_LEN];
|
||||||
int errorCode;
|
int errorCode;
|
||||||
unsigned int shutdown : 1;
|
unsigned int shutdown : 1;
|
||||||
|
103
qemud/qemud.c
103
qemud/qemud.c
@ -439,6 +439,9 @@ static int qemudInitPaths(struct qemud_server *server,
|
|||||||
goto snprintf_error;
|
goto snprintf_error;
|
||||||
|
|
||||||
unlink(roSockname);
|
unlink(roSockname);
|
||||||
|
|
||||||
|
if (snprintf(server->logDir, PATH_MAX, "%s/log/libvirt/qemu", LOCAL_STATE_DIR) >= PATH_MAX)
|
||||||
|
goto snprintf_error;
|
||||||
} else {
|
} else {
|
||||||
if (!(pw = getpwuid(uid))) {
|
if (!(pw = getpwuid(uid))) {
|
||||||
qemudLog(QEMUD_ERR, "Failed to find user record for uid '%d': %s",
|
qemudLog(QEMUD_ERR, "Failed to find user record for uid '%d': %s",
|
||||||
@ -451,6 +454,9 @@ static int qemudInitPaths(struct qemud_server *server,
|
|||||||
|
|
||||||
if (snprintf(base, PATH_MAX, "%s/.", pw->pw_dir) >= PATH_MAX)
|
if (snprintf(base, PATH_MAX, "%s/.", pw->pw_dir) >= PATH_MAX)
|
||||||
goto snprintf_error;
|
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++)
|
for (i = 0; i < QEMUD_N_CONFIG_DIRS; i++)
|
||||||
@ -647,6 +653,7 @@ qemudReadMonitorOutput(struct qemud_server *server,
|
|||||||
#define MONITOR_TIMEOUT 3000
|
#define MONITOR_TIMEOUT 3000
|
||||||
|
|
||||||
int got = 0;
|
int got = 0;
|
||||||
|
buffer[0] = '\0';
|
||||||
|
|
||||||
/* Consume & discard the initial greeting */
|
/* Consume & discard the initial greeting */
|
||||||
while (got < (buflen-1)) {
|
while (got < (buflen-1)) {
|
||||||
@ -655,13 +662,15 @@ qemudReadMonitorOutput(struct qemud_server *server,
|
|||||||
ret = read(fd, buffer+got, buflen-got-1);
|
ret = read(fd, buffer+got, buflen-got-1);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
||||||
"End-of-file while reading %s startup output", what);
|
"QEMU quit during %s startup\n%s", what, buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
struct pollfd pfd = { .fd = fd, .events = POLLIN };
|
struct pollfd pfd = { .fd = fd, .events = POLLIN };
|
||||||
if (errno != EAGAIN &&
|
if (errno == EINTR)
|
||||||
errno != EINTR) {
|
continue;
|
||||||
|
|
||||||
|
if (errno != EAGAIN) {
|
||||||
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
||||||
"Failure while reading %s startup output: %s",
|
"Failure while reading %s startup output: %s",
|
||||||
what, strerror(errno));
|
what, strerror(errno));
|
||||||
@ -680,11 +689,12 @@ qemudReadMonitorOutput(struct qemud_server *server,
|
|||||||
what, strerror(errno));
|
what, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (pfd.revents & POLLHUP) {
|
} else {
|
||||||
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
/* Make sure we continue loop & read any further data
|
||||||
"End-of-file while reading %s startup output", what);
|
available before dealing with EOF */
|
||||||
return -1;
|
if (pfd.revents & (POLLIN | POLLHUP))
|
||||||
} else if (pfd.revents != POLLIN) {
|
continue;
|
||||||
|
|
||||||
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
||||||
"Failure while reading %s startup output", what);
|
"Failure while reading %s startup output", what);
|
||||||
return -1;
|
return -1;
|
||||||
@ -794,11 +804,22 @@ qemudOpenMonitorPath(struct qemud_server *server,
|
|||||||
|
|
||||||
static int qemudWaitForMonitor(struct qemud_server *server, struct qemud_vm *vm) {
|
static int qemudWaitForMonitor(struct qemud_server *server, struct qemud_vm *vm) {
|
||||||
char buffer[1024]; /* Plenty of space to get startup greeting */
|
char buffer[1024]; /* Plenty of space to get startup greeting */
|
||||||
|
int ret = qemudReadMonitorOutput(server, vm, vm->stderr,
|
||||||
|
buffer, sizeof(buffer),
|
||||||
|
qemudOpenMonitorPath,
|
||||||
|
"console");
|
||||||
|
|
||||||
return qemudReadMonitorOutput(server, vm, vm->stderr,
|
buffer[sizeof(buffer)-1] = '\0';
|
||||||
buffer, sizeof(buffer),
|
retry:
|
||||||
qemudOpenMonitorPath,
|
if (write(vm->logfile, buffer, strlen(buffer)) < 0) {
|
||||||
"PTY");
|
/* 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qemudNextFreeVNCPort(struct qemud_server *server ATTRIBUTE_UNUSED) {
|
static int qemudNextFreeVNCPort(struct qemud_server *server ATTRIBUTE_UNUSED) {
|
||||||
@ -839,8 +860,9 @@ static int qemudNextFreeVNCPort(struct qemud_server *server ATTRIBUTE_UNUSED) {
|
|||||||
|
|
||||||
int qemudStartVMDaemon(struct qemud_server *server,
|
int qemudStartVMDaemon(struct qemud_server *server,
|
||||||
struct qemud_vm *vm) {
|
struct qemud_vm *vm) {
|
||||||
char **argv = NULL;
|
char **argv = NULL, **tmp;
|
||||||
int i, ret = -1;
|
int i, ret = -1;
|
||||||
|
char logfile[PATH_MAX];
|
||||||
|
|
||||||
if (qemudIsActiveVM(vm)) {
|
if (qemudIsActiveVM(vm)) {
|
||||||
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
||||||
@ -859,8 +881,49 @@ int qemudStartVMDaemon(struct qemud_server *server,
|
|||||||
} else
|
} else
|
||||||
vm->def->vncActivePort = vm->def->vncPort;
|
vm->def->vncActivePort = vm->def->vncPort;
|
||||||
|
|
||||||
if (qemudBuildCommandLine(server, vm, &argv) < 0)
|
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;
|
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) {
|
||||||
|
close(vm->logfile);
|
||||||
|
vm->logfile = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = argv;
|
||||||
|
while (*tmp) {
|
||||||
|
write(vm->logfile, *tmp, strlen(*tmp));
|
||||||
|
write(vm->logfile, " ", 1);
|
||||||
|
tmp++;
|
||||||
|
}
|
||||||
|
write(vm->logfile, "\n", 1);
|
||||||
|
|
||||||
if (qemudExec(server, argv, &vm->pid, &vm->stdout, &vm->stderr) == 0) {
|
if (qemudExec(server, argv, &vm->pid, &vm->stdout, &vm->stderr) == 0) {
|
||||||
vm->id = server->nextvmid++;
|
vm->id = server->nextvmid++;
|
||||||
@ -1038,7 +1101,14 @@ static int qemudVMData(struct qemud_server *server ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
buf[ret] = '\0';
|
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 +1123,13 @@ int qemudShutdownVMDaemon(struct qemud_server *server, struct qemud_vm *vm) {
|
|||||||
|
|
||||||
qemudVMData(server, vm, vm->stdout);
|
qemudVMData(server, vm, vm->stdout);
|
||||||
qemudVMData(server, vm, vm->stderr);
|
qemudVMData(server, vm, vm->stderr);
|
||||||
|
if (close(vm->logfile) < 0)
|
||||||
|
qemudLog(QEMUD_WARN, "Unable to close logfile %d: %s", errno, strerror(errno));
|
||||||
close(vm->stdout);
|
close(vm->stdout);
|
||||||
close(vm->stderr);
|
close(vm->stderr);
|
||||||
if (vm->monitor != -1)
|
if (vm->monitor != -1)
|
||||||
close(vm->monitor);
|
close(vm->monitor);
|
||||||
|
vm->logfile = -1;
|
||||||
vm->stdout = -1;
|
vm->stdout = -1;
|
||||||
vm->stderr = -1;
|
vm->stderr = -1;
|
||||||
vm->monitor = -1;
|
vm->monitor = -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user