diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 455de4b529..64380ff8d3 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -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);