From 95e4b3413aca7d8c8c8cdec5a83b76214d0d1a64 Mon Sep 17 00:00:00 2001 From: Eduard Shishkin Date: Fri, 16 May 2025 14:24:24 +0200 Subject: [PATCH] zipl/src: Prepare for global sync(2) removal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Stefan Haberland Signed-off-by: Jan Höppner --- zipl/include/misc.h | 1 + zipl/src/bootmap.c | 31 +++++++++++++++++++++++++++---- zipl/src/install.c | 4 +++- zipl/src/misc.c | 10 ++++++++++ 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/zipl/include/misc.h b/zipl/include/misc.h index 01f3a323..4b29adff 100644 --- a/zipl/include/misc.h +++ b/zipl/include/misc.h @@ -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); diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c index ed3834b7..9b9136c6 100644 --- a/zipl/src/bootmap.c +++ b/zipl/src/bootmap.c @@ -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); } } diff --git a/zipl/src/install.c b/zipl/src/install.c index 31e9c486..137793af 100644 --- a/zipl/src/install.c +++ b/zipl/src/install.c @@ -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); } diff --git a/zipl/src/misc.c b/zipl/src/misc.c index b2d7fa29..f0a83dec 100644 --- a/zipl/src/misc.c +++ b/zipl/src/misc.c @@ -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. */