zipl/src: Prepare for global sync(2) removal

zipl tool calls sync(2) before exit, which may hang on attempts to
flush not relevant problematic mounts (e.g. nfs) [1].

Complete any modification performed by zipl(8) tool with calling
fsync(2), or syncfs(2). This allows to get rid of the mentioned
sync(2) call.

[1] https://github.com/openshift/os/issues/1720
Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/186
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Eduard Shishkin
2025-05-16 14:24:24 +02:00
committed by Jan Höppner
parent 06e0d569f1
commit 95e4b3413a
4 changed files with 41 additions and 5 deletions

View File

@@ -34,6 +34,7 @@ int misc_asprintf(char **out, const char *fmt, ...);
void* misc_calloc(size_t n, size_t size);
char* misc_strdup(const char* s);
int misc_open_device(const char *filename, struct misc_fd *mfd, int simulate);
int misc_fsync(struct misc_fd *mfd, const char *filename);
int misc_read(int fd, void* buffer, size_t count);
int misc_read_file(const char* filename, char** buffer, size_t* size,
int nil_terminate);

View File

@@ -1617,6 +1617,11 @@ static int finalize_create_file(struct job_data *job, struct install_set *bis)
{
char *final_name;
/*
* Sync the file before rename
*/
if (misc_fsync(&bis->mfd, bis->filename))
return -1;
final_name = misc_make_path(job->target.bootmap_dir, BOOTMAP_FILENAME);
if (!final_name)
return -1;
@@ -1632,6 +1637,18 @@ static int finalize_create_file(struct job_data *job, struct install_set *bis)
* from the semantic volume
*/
bis->tmp_filename_created = 0;
/*
* Sync meta-data and the parent directory of the new object.
* For this, sync the whole file system, using the descriptor
* obtained for the file with the old name.
*/
if (syncfs(bis->mfd.fd)) {
error_reason(strerror(errno));
error_text("Could not sync fs containing '%s'",
final_name);
free(final_name);
return -1;
}
free(final_name);
return 0;
}
@@ -1698,7 +1715,11 @@ static int ngdump_create_meta(const char *path)
rc = fclose(fp);
if (rc < 0)
return -1;
/*
* In case of dry-run the meta-file will be removed.
* Otherwise it will be written to disk when unmounting
* the ngdump.
*/
return 0;
}
@@ -1861,13 +1882,15 @@ int prepare_bootloader(struct job_data *job, struct install_set *bis)
*/
int post_install_bootloader(struct job_data *job, struct install_set *bis)
{
if (dry_run)
return 0;
if (job->id == job_dump_partition) {
if (job_dump_is_ngdump(job))
return dry_run ? 0 : finalize_create_file(job, bis);
return finalize_create_file(job, bis);
else
return 0;
return misc_fsync(&bis->mfd, bis->filename);
} else {
return dry_run ? 0 : finalize_create_file(job, bis);
return finalize_create_file(job, bis);
}
}

View File

@@ -784,6 +784,8 @@ install_tapeloader(const char* device, const char* image, const char* parmline,
error_text("Could not rewind tape device '%s' to tape", device);
rc = -1;
}
if (!dry_run && fsync(fd))
error_text("Could not sync device file '%s'", device);
close(fd);
return rc;
}
@@ -1139,7 +1141,7 @@ install_dump(const char *device, struct job_target_data *target, uint64_t mem,
error_text("Could not install dump record on tape "
"device '%s'", device);
} else {
if (verbose) {
if (!misc_fsync(&mfd, device) && verbose) {
printf("Dump record successfully installed on "
"tape device '%s'.\n", device);
}

View File

@@ -131,6 +131,16 @@ int misc_open_device(const char *filename, struct misc_fd *mfd, int simulate)
return mfd->fd;
}
int misc_fsync(struct misc_fd *mfd, const char *filename)
{
if (fsync(mfd->fd)) {
error_reason(strerror(errno));
error_text("Could not sync file '%s'", filename);
return -1;
}
return 0;
}
/* Read COUNT bytes of data from file identified by file descriptor FD to
* memory at location BUFFER. Return 0 when all bytes were successfully read,
* non-zero otherwise. */