From 95cf3fba984f4487782edee8753d2669204186b7 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sun, 3 Sep 2023 17:24:48 +0200 Subject: [PATCH] Save kernel options upon installation. --- kernel/kernel.cpp | 1 + share/man/man5/autoinstall.conf.5 | 9 +++ share/man/man7/installation.7 | 65 ++++-------------- sysinstall/fileops.c | 20 ++++++ sysinstall/fileops.h | 1 + sysinstall/sysinstall.c | 109 ++++++++++++++++++++++++++++++ 6 files changed, 154 insertions(+), 51 deletions(-) diff --git a/kernel/kernel.cpp b/kernel/kernel.cpp index 8eaa7d98..c7e7f829 100644 --- a/kernel/kernel.cpp +++ b/kernel/kernel.cpp @@ -255,6 +255,7 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo_p) } argv[argc] = NULL; + // Add new once-only options to sysinstall's normalize_kernel_options. bool no_random_seed = false; for ( int i = 0; i < argc; i++ ) { diff --git a/share/man/man5/autoinstall.conf.5 b/share/man/man5/autoinstall.conf.5 index 1fa0ca50..e2f88c67 100644 --- a/share/man/man5/autoinstall.conf.5 +++ b/share/man/man5/autoinstall.conf.5 @@ -154,6 +154,15 @@ question could be answered with to dynamically hash the bootloader password. .It Sy grub_password_empty Ns "=" Ns Oo Sy no "|" Sy yes Oc ( default Sy no ) Allow an insecure empty bootloader password typed interactively? +.It Sy kernel_options Ns "=" Ns Ar options +What +.Xr kernel 7 +options should be set in +.Xr grub 5 +with +.Sy GRUB_CMDLINE_SORTIX ? +This question is asked only the GRUB port is installed, if the kernel was booted +with explicit options or this question is set. .It Sy disked Ns "=" Ns Ar commands Commands to create partitions and filesystems with .Xr disked 8 ? diff --git a/share/man/man7/installation.7 b/share/man/man7/installation.7 index 2d0f008d..f7a0b69e 100644 --- a/share/man/man7/installation.7 +++ b/share/man/man7/installation.7 @@ -170,8 +170,8 @@ selecting .Sy Disable network drivers . It can be useful to disable the network drivers if it's undesirable to put the system on the network for security reasons. -You can disable network drivers by default by editing the bootloader -configuration as described below after completing the installation. +You will be asked later if you'd like to save this choice in the kernel +options. .Pp By default .Xr dhclient 8 @@ -271,6 +271,18 @@ The password will be hashed and stored in and is inserted into the GRUB configuration when .Xr update-grub 8 is run. +.Pp +If the +.Xr kernel 7 +was booted with explicit options via the advanced bootloader menu, then you +will be asked if you'd like to make these changes permanent via the +.Sy GRUB_CMDLINE_SORTIX +variable in the +.Pa /etc/grub +configuration file. +Run +.Xr update-grub 8 +to apply the changes if you edit this file. .Ss Partitioning You will now need to set up a partition for the root filesystem and other filesystems you wish to use. @@ -495,55 +507,6 @@ The manual page is a basic overview of the system for new users. .Pp Congratulations on your new Sortix system. -.Ss Disabling Networking by Default -To disable networking drivers by default, edit the bootloader configuration to -pass the -.Fl \-disable-network-drivers -option by default on the -.Xr kernel 7 -command line. -.Pp -If you are at the final stage of installation, you can answer -.Sy '!' -to get a shell in the live environment and then run -.Sy "chroot -d ." -to enter a shell inside the new installation. -.Pp -For instance, if GRUB is used the bootloader, networking can be disabled by -default by done by editing -.Pa /etc/grub.d/10_sortix -of the new installation. -.Xr editor 1 -or any editor can be used to edit the file. -Change the line from -.Bd -literal - multiboot $BOOT_REL/sortix.bin -.Ed -.Pp -to instead be -.Bd -literal - multiboot $BOOT_REL/sortix.bin --disable-network-drivers -.Ed -.Pp -If the included GRUB bootloader is used, after making the above edit, run -.Xr update-grub 8 -within the new installation to regenerate the bootloader configuration. -Note that -.Pa /etc/default/grub.d/10_sortix -is part of the GRUB package and local changes will be undone when the GRUB -package is updated or reinstalled, in which case you must make this change again -and run -.Xr update-grub 8 -again. -.Pp -If the included GRUB bootloader is not used, but instead the -.Pa /etc/default/grub.d/10_sortix.cache -fragment is spliced into another GRUB installation, make the above change and -then run the -.Pa /etc/default/grub.d/10_sortix -command and use the freshly regenerated -.Pa /etc/default/grub.d/10_sortix.cache -fragment instead. .Sh SEE ALSO .Xr chkblayout 1 , .Xr chvideomode 1 , diff --git a/sysinstall/fileops.c b/sysinstall/fileops.c index 718b057e..cf1487ce 100644 --- a/sysinstall/fileops.c +++ b/sysinstall/fileops.c @@ -17,6 +17,7 @@ * File operation utility functions. */ +#include #include #include @@ -221,3 +222,22 @@ char** read_lines_file(const char* path, size_t* out_count) *out_count = count; return lines; } + +char* akernelinfo(const char* request) +{ + char* buffer = NULL; + size_t size = 0; + while ( true ) + { + errno = 0; + ssize_t needed = kernelinfo(request, buffer, size); + if ( needed < 0 ) + return free(buffer), NULL; + if ( errno != ERANGE ) + return buffer; + size = (size_t) needed + 1; + free(buffer); + if ( !(buffer = malloc(size)) ) + return NULL; + } +} diff --git a/sysinstall/fileops.h b/sysinstall/fileops.h index 15d00e7a..3c8bbbfd 100644 --- a/sysinstall/fileops.h +++ b/sysinstall/fileops.h @@ -27,5 +27,6 @@ void mkdir_or_chmod_or_die(const char* path, mode_t mode); void write_random_seed(const char* path); char* read_string_file(const char* path); char** read_lines_file(const char* path, size_t* out_count); +char* akernelinfo(const char* request); #endif diff --git a/sysinstall/sysinstall.c b/sysinstall/sysinstall.c index b87eec42..4972005e 100644 --- a/sysinstall/sysinstall.c +++ b/sysinstall/sysinstall.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -341,6 +342,84 @@ static void grub_hash_password(char* buffer, size_t buffer_size, const char* pw) errx(2, "grub password hash failed"); } + +static const char* const ignore_kernel_options[] = +{ + "--no-random-seed", + "--random-seed", + NULL, +}; + +static char* normalize_kernel_options(void) +{ + char* options = akernelinfo("options"); + if ( !options ) + { + warn("kernelinfo: options"); + return NULL; + } + size_t i = 0, o = 0; + while ( options[i] ) + { + if ( isspace((unsigned char) options[i]) ) + { + i++; + continue; + } + if ( options[i] != '-' ) // Imperfect since quoting options is allowed. + break; + if ( !strncmp(options + i, "--", 2) && + (!options[i + 2] || isspace((unsigned char) options[i + 2])) ) + break; + bool ignored = false; + for ( size_t n = 0; ignore_kernel_options[n]; n++ ) + { + const char* opt = ignore_kernel_options[n]; + size_t len = strlen(opt); + if ( !strncmp(options + i, opt, len) && + (!options[i + len] || + isspace((unsigned char) options[i + len])) ) + { + i += len; + ignored = true; + break; + } + } + if ( ignored ) + continue; + bool singly = false; + bool doubly = false; + bool escaped = false; + for ( ; options[i]; i++ ) + { + char c = options[i]; + options[o++] = c; + if ( !escaped && !singly && !doubly && isspace((unsigned char) c) ) + break; + if ( !escaped && !doubly && c == '\'' ) + { + singly = !singly; + continue; + } + if ( !escaped && !singly && c == '"' ) + { + doubly = !doubly; + continue; + } + if ( !singly && !escaped && c == '\\' ) + { + escaped = true; + continue; + } + escaped = false; + } + } + while ( o && isspace((unsigned char) options[o - 1]) ) + o--; + options[o] = '\0'; + return options; +} + static pid_t main_pid; static struct mountpoint* mountpoints; static size_t mountpoints_used; @@ -748,6 +827,36 @@ int main(void) text("\n"); } + char* kernel_options = normalize_kernel_options(); + if ( (autoconf_has("kernel_options") || + (kernel_options && kernel_options[0])) && + !access_or_die("/tix/tixinfo/grub", F_OK) ) + { + text("The operating system was booted with explicit kernel(7) options. " + "Would you like set them permanently in /etc/grub?\n\n"); + + while ( true ) + { + char options[1024]; + prompt(options, sizeof(options), "kernel_options", + "Kernel options? (OPTIONS/no)", kernel_options); + if ( !strcasecmp(options, "no") ) + { + kernel_options = NULL; + break; + } + if ( options[0] ) + { + install_configurationf("grub", "w", + "GRUB_CMDLINE_SORTIX='%s'\n", options); + textf("/etc/grub will be made with the kernel options.\n"); + } + break; + } + text("\n"); + } + free(kernel_options); + // TODO: Offer the user an automatic layout of partitions if the disk is // empty.