From 5f84c38bc888a10adcba458f36fa5a36b9fd4c91 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sun, 27 Dec 2020 22:32:04 +0100 Subject: [PATCH] Fix sysinstall hook markers not being installed and prefix logic. Document the compatibility hooks behavior while here. --- share/man/man5/upgrade.conf.5 | 2 ++ share/man/man7/following-development.7 | 3 ++ share/man/man7/upgrade.7 | 3 ++ sysinstall/Makefile | 3 ++ sysinstall/hooks.c | 38 ++++++++++++++++---------- sysinstall/hooks.h | 4 +-- sysinstall/sysmerge.8 | 12 +++++--- sysinstall/sysmerge.c | 12 +++----- sysinstall/sysupgrade.c | 6 ++-- 9 files changed, 51 insertions(+), 32 deletions(-) diff --git a/share/man/man5/upgrade.conf.5 b/share/man/man5/upgrade.conf.5 index 451f43b2..07d47958 100644 --- a/share/man/man5/upgrade.conf.5 +++ b/share/man/man5/upgrade.conf.5 @@ -80,6 +80,8 @@ into .Pa /oldsrc . .It Sy system Ns "=" Ns Oo Sy no "|" yes Oc (default Sy yes ) . Install the new system. +The upgrade hooks are run if needed as described in +.Xr following-development 7 . This will run .Xr update-initrd 8 and if diff --git a/share/man/man7/following-development.7 b/share/man/man7/following-development.7 index f94b42a4..1532fe12 100644 --- a/share/man/man7/following-development.7 +++ b/share/man/man7/following-development.7 @@ -28,6 +28,9 @@ and .Xr sysupgrade 8 programs automatically handle compatibility issues when upgrading an existing system to a new build. +This is done using upgrade hooks built into the programs that are run if the +installation does not have the appropriate files in +.Pa /share/sysinstall/hooks . They can handle incompatible ABI changes and automatically fix configuration files and other issues. .Pp diff --git a/share/man/man7/upgrade.7 b/share/man/man7/upgrade.7 index ab17698c..b3b3e6b3 100644 --- a/share/man/man7/upgrade.7 +++ b/share/man/man7/upgrade.7 @@ -117,6 +117,9 @@ The upgrader will take the appropriate actions: .Pp .Bl -bullet -compact .It +Running any upgrade hooks needed to migrate the installation across incompatible +changes. +.It Updating the system. .It Updating the ports. diff --git a/sysinstall/Makefile b/sysinstall/Makefile index f74c9a45..f091da87 100644 --- a/sysinstall/Makefile +++ b/sysinstall/Makefile @@ -48,6 +48,9 @@ install: all cp sysinstall.8 $(DESTDIR)$(MANDIR)/man8/sysinstall.8 cp sysmerge.8 $(DESTDIR)$(MANDIR)/man8/sysmerge.8 cp sysupgrade.8 $(DESTDIR)$(MANDIR)/man8/sysupgrade.8 + mkdir -p $(DESTDIR)$(DATADIR)/sysinstall/hooks + # TODO: After releasing Sortix 1.1, remove this compatibility. + touch $(DESTDIR)$(DATADIR)/sysinstall/hooks/sortix-1.1-random-seed sysinstall: $(SYSINSTALL_OBJS) $(CC) $(SYSINSTALL_OBJS) -o $@ -lmount diff --git a/sysinstall/hooks.c b/sysinstall/hooks.c index 8de00b75..5847df4d 100644 --- a/sysinstall/hooks.c +++ b/sysinstall/hooks.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, 2018 Jonas 'Sortie' Termansen. + * Copyright (c) 2016, 2017, 2018, 2020, 2021 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * hooks.c - * Upgrade compatibility hooks. + * Upgrade hooks. */ #include @@ -33,7 +33,7 @@ // incompatible operating system change is made that needs additional actions. // These files are part of the system manifest and their lack can be tested // in upgrade_prepare, but not in upgrade_finalize (as they would have been -// installed there). If a file is lacking, then a hook should be run taking +// installed by then). If a file is lacking, then a hook should be run taking // the needed action. For instance, if /etc/foo becomes the different /etc/bar, // then /share/sysinstall/hooks/osname-x.y-bar would be made, and if it is // absent then upgrade_prepare converts /etc/foo to /etc/bar. The file is then @@ -41,22 +41,29 @@ // // Hooks are meant to run once. However, they must handle if the upgrade fails // between the hook running and the hook file being installed when the system -// manifest is installed. +// manifest is installed. I.e. they need to be reentrant and idempotent. // // If this system is used, follow the instructions in following-development(7) // and add an entry in that manual page about the change. __attribute__((used)) -static bool hook_needs_to_be_run(const char* target_prefix, const char* hook) +static bool hook_needs_to_be_run(const char* source_prefix, + const char* target_prefix, + const char* hook) { - char* path; - if ( asprintf(&path, "%sshare/sysinstall/hooks/%s", + char* source_path; + char* target_path; + if ( asprintf(&source_path, "%s/share/sysinstall/hooks/%s", + source_prefix, hook) < 0 || + asprintf(&target_path, "%s/share/sysinstall/hooks/%s", target_prefix, hook) < 0 ) { - warn("asprintf"); + warn("malloc"); _exit(2); } - bool result = access_or_die(path, F_OK) < 0; - free(path); + bool result = access_or_die(source_path, F_OK) == 0 && + access_or_die(target_path, F_OK) < 0; + free(source_path); + free(target_path); return result; } @@ -71,13 +78,14 @@ void upgrade_prepare(const struct release* old_release, (void) target_prefix; // TODO: After releasing Sortix 1.1, remove this compatibility. - if ( hook_needs_to_be_run(target_prefix, "sortix-1.1-random-seed") ) + if ( hook_needs_to_be_run(source_prefix, target_prefix, + "sortix-1.1-random-seed") ) { - char* random_seed_path; - if ( asprintf(&random_seed_path, "%sboot/random.seed", target_prefix) < 0 ) + char* random_seed_path = join_paths(target_prefix, "/boot/random.seed"); + if ( !random_seed_path ) { - warn("asprintf"); - _exit(1); + warn("malloc"); + _exit(2); } if ( access_or_die(random_seed_path, F_OK) < 0 ) { diff --git a/sysinstall/hooks.h b/sysinstall/hooks.h index 8b501781..3cd5be03 100644 --- a/sysinstall/hooks.h +++ b/sysinstall/hooks.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Jonas 'Sortie' Termansen. + * Copyright (c) 2016, 2020 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * hooks.h - * Upgrade compatibility hooks. + * Upgrade hooks. */ #ifndef HOOKS_H diff --git a/sysinstall/sysmerge.8 b/sysinstall/sysmerge.8 index 59028016..cb31a8f3 100644 --- a/sysinstall/sysmerge.8 +++ b/sysinstall/sysmerge.8 @@ -27,6 +27,9 @@ installs the manifest from the tix repository in the .Ar source directory, as well as all the ports found. +Upgrade hooks will be run if further actions are needed to migrate the system to +the new version as described in +.Xr following-development 7 . The .Xr initrd 7 is regenerated using @@ -41,8 +44,7 @@ It is meant to be used as part of the development process to upgrade to locally built versions. The .Xr sysupgrade 8 -program is by contrast an interactive program, meant to help upgrading across -much larger development distances. +program is by contrast an interactive program. .Pp The options are as follows: .Bl -tag -width "12345678" @@ -67,14 +69,14 @@ directory and restore the old and .Xr initrd 7 . .It Fl \-hook-finalize -Run the pre-installation compatibility hooks. +Run the post-upgrade hooks. This is meant to be used by the old .Nm when it invokes the new .Nm during a non-waiting upgrade. .It Fl \-hook-prepare -Run the post-prepare compatibility hooks. +Run the pre-upgrade hooks. This is meant to be used by the old .Nm when it invokes the new @@ -124,6 +126,8 @@ the current system release .It Pa /etc/upgrade.conf controls the bootloader upgrade behavior (see .Xr upgrade.conf 5 ) +.It Pa /share/sysinstall/hooks +A file per upgrade hook indicating that it doesn't need to be run. .It Pa /sysmerge pending upgrade is stored here .El diff --git a/sysinstall/sysmerge.c b/sysinstall/sysmerge.c index e8a7db6e..7409d70f 100644 --- a/sysinstall/sysmerge.c +++ b/sysinstall/sysmerge.c @@ -278,13 +278,11 @@ int main(int argc, char* argv[]) new_release.pretty_name, source); } - // Compatibility hooks that runs before the old system is replaced. + // Upgrade hooks that runs before the old system is replaced. if ( run_prepare ) { if ( my_prepare ) - { - upgrade_prepare(&old_release, &new_release, source, "/"); - } + upgrade_prepare(&old_release, &new_release, source, ""); else { char* new_sysmerge = join_paths(source, "sbin/sysmerge"); @@ -331,13 +329,11 @@ int main(int argc, char* argv[]) return 0; } - // Compatibility hooks that run after the new system is installed. + // Upgrade hooks that run after the new system is installed. if ( run_finalize ) { if ( my_finalize ) - { - upgrade_finalize(&old_release, &new_release, source, "/"); - } + upgrade_finalize(&old_release, &new_release, source, ""); else { char* new_sysmerge = join_paths(source, "sbin/sysmerge"); diff --git a/sysinstall/sysupgrade.c b/sysinstall/sysupgrade.c index 799235f7..0e37784d 100644 --- a/sysinstall/sysupgrade.c +++ b/sysinstall/sysupgrade.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, 2021 Jonas 'Sortie' Termansen. + * Copyright (c) 2015, 2016, 2020, 2021 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -807,7 +807,7 @@ int main(void) // untracked or moved from one manifest to another. if ( conf.system ) { - upgrade_prepare(target_release, &new_release, "/", ""); + upgrade_prepare(target_release, &new_release, "", "."); install_manifest("system", "", "."); } if ( has_manifest("src") ) @@ -848,7 +848,7 @@ int main(void) if ( conf.ports ) install_ports("", "."); if ( conf.system ) - upgrade_finalize(target_release, &new_release, "/", ""); + upgrade_finalize(target_release, &new_release, "", "."); if ( conf.system ) { printf(" - Creating initrd...\n");