mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 20:45:18 +00:00
qemu: do crash safe creation of NVRAM file
If we crash part way through writing the NVRAM file we end up with an unusable NVRAM on file. To avoid this we need to write to a temporary file and fsync(2) at the end, then rename to the real NVRAM file path. Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
2df9031a0e
commit
5e3498744e
@ -4433,6 +4433,7 @@ qemuPrepareNVRAM(virQEMUDriver *driver,
|
||||
bool created = false;
|
||||
const char *master_nvram_path;
|
||||
ssize_t r;
|
||||
g_autofree char *tmp_dst_path = NULL;
|
||||
|
||||
if (!loader || !loader->nvram || virFileExists(loader->nvram))
|
||||
return 0;
|
||||
@ -4463,14 +4464,15 @@ qemuPrepareNVRAM(virQEMUDriver *driver,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((dstFD = virFileOpenAs(loader->nvram,
|
||||
tmp_dst_path = g_strdup_printf("%s.tmp", loader->nvram);
|
||||
if ((dstFD = virFileOpenAs(tmp_dst_path,
|
||||
O_WRONLY | O_CREAT | O_EXCL,
|
||||
S_IRUSR | S_IWUSR,
|
||||
cfg->user, cfg->group,
|
||||
VIR_FILE_OPEN_FORCE_OWNER)) < 0) {
|
||||
virReportSystemError(-dstFD,
|
||||
_("Failed to create file '%s'"),
|
||||
loader->nvram);
|
||||
tmp_dst_path);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@ -4489,7 +4491,7 @@ qemuPrepareNVRAM(virQEMUDriver *driver,
|
||||
if (safewrite(dstFD, buf, r) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Unable to write to file '%s'"),
|
||||
loader->nvram);
|
||||
tmp_dst_path);
|
||||
goto cleanup;
|
||||
}
|
||||
} while (r);
|
||||
@ -4500,9 +4502,23 @@ qemuPrepareNVRAM(virQEMUDriver *driver,
|
||||
master_nvram_path);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (g_fsync(dstFD) < 0) {
|
||||
virReportSystemError(errno, _("cannot sync file '%s'"),
|
||||
tmp_dst_path);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (VIR_CLOSE(dstFD) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Unable to close file '%s'"),
|
||||
tmp_dst_path);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (rename(tmp_dst_path, loader->nvram) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Unable to replace '%s'"),
|
||||
loader->nvram);
|
||||
goto cleanup;
|
||||
}
|
||||
@ -4513,7 +4529,7 @@ qemuPrepareNVRAM(virQEMUDriver *driver,
|
||||
* copy the file content. Roll back. */
|
||||
if (ret < 0) {
|
||||
if (created)
|
||||
unlink(loader->nvram);
|
||||
unlink(tmp_dst_path);
|
||||
}
|
||||
|
||||
VIR_FORCE_CLOSE(srcFD);
|
||||
|
Loading…
x
Reference in New Issue
Block a user