mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
qemu: support VIR_DOMAIN_DESTROY_REMOVE_LOGS flag
Note that we attempt to remove logs only if virtlogd is in use. Otherwise we do not know the pattern for rotated files. For example for VM named "foo" we can not use "foo.log*" pattern to remove rotated logs as we can have VM named "foo.log" with log "foo.log.log". We can add extra check that filename does not end with ".log" but for VM "foo.log" we can have rotated log "foo.log.log.1". Ok let's check we don't have "log" in filename part corresponging to * but what if someone will use logrotate with "%Y.log-%m-%d" 'dateformat' option. In this case the check will exclude proper rotated files. Yes, the last example if quite artificial but it shows it is difficult to find out correctly rotated files when rotated files pattern is not known. Thus the above decision only to support case with virtlogd when we know the pattern. Another reason for not removing log files when logrotate is present is that due to races some files can escape deletion. For example foo.log.3 will be rotated to foo.log.4 after removing function will read directory files and thus foo.log.4 will not be deleted. Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
ce3f707af5
commit
a414cb76e3
@ -11820,3 +11820,44 @@ qemuDomainDeviceBackendChardevForeach(virDomainDef *def,
|
||||
DOMAIN_DEVICE_ITERATE_MISSING_INFO,
|
||||
&data);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
qemuDomainRemoveLogs(virQEMUDriver *driver,
|
||||
const char *name)
|
||||
{
|
||||
g_autoptr(virQEMUDriverConfig) cfg = NULL;
|
||||
g_autofree char *format = NULL;
|
||||
g_autofree char *main = NULL;
|
||||
g_autoptr(DIR) dir = NULL;
|
||||
struct dirent *entry;
|
||||
int rc;
|
||||
|
||||
cfg = virQEMUDriverGetConfig(driver);
|
||||
if (!cfg->stdioLogD)
|
||||
return 0;
|
||||
|
||||
if (virDirOpen(&dir, cfg->logDir) < 0)
|
||||
return -1;
|
||||
|
||||
main = g_strdup_printf("%s.log", name);
|
||||
format = g_strdup_printf("%s.log.%%u", name);
|
||||
|
||||
while ((rc = virDirRead(dir, &entry, cfg->logDir)) > 0) {
|
||||
unsigned int u;
|
||||
|
||||
if (STREQ(entry->d_name, main) ||
|
||||
sscanf(entry->d_name, format, &u) == 1) {
|
||||
g_autofree char *path = NULL;
|
||||
|
||||
path = g_strdup_printf("%s/%s", cfg->logDir, entry->d_name);
|
||||
if (unlink(path) && errno != ENOENT)
|
||||
VIR_WARN("unlink(%s) error: %s", path, g_strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1084,3 +1084,7 @@ int
|
||||
qemuDomainDeviceBackendChardevForeach(virDomainDef *def,
|
||||
qemuDomainDeviceBackendChardevForeachCallback cb,
|
||||
void *opaque);
|
||||
|
||||
int
|
||||
qemuDomainRemoveLogs(virQEMUDriver *driver,
|
||||
const char *name);
|
||||
|
@ -2072,7 +2072,8 @@ qemuDomainDestroyFlags(virDomainPtr dom,
|
||||
int reason;
|
||||
bool starting;
|
||||
|
||||
virCheckFlags(VIR_DOMAIN_DESTROY_GRACEFUL, -1);
|
||||
virCheckFlags(VIR_DOMAIN_DESTROY_GRACEFUL |
|
||||
VIR_DOMAIN_DESTROY_REMOVE_LOGS, -1);
|
||||
|
||||
if (!(vm = qemuDomainObjFromDomain(dom)))
|
||||
return -1;
|
||||
@ -2112,6 +2113,11 @@ qemuDomainDestroyFlags(virDomainPtr dom,
|
||||
|
||||
qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED,
|
||||
VIR_ASYNC_JOB_NONE, stopFlags);
|
||||
|
||||
if ((flags & VIR_DOMAIN_DESTROY_REMOVE_LOGS) &&
|
||||
qemuDomainRemoveLogs(driver, vm->def->name) < 0)
|
||||
VIR_WARN("Failed to remove logs for VM '%s'", vm->def->name);
|
||||
|
||||
event = virDomainEventLifecycleNewFromObj(vm,
|
||||
VIR_DOMAIN_EVENT_STOPPED,
|
||||
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
|
||||
|
Loading…
Reference in New Issue
Block a user