1 1.25 martin /* $NetBSD: install.c,v 1.25 2023/01/06 18:13:40 martin Exp $ */ 2 1.1 dholland 3 1.1 dholland /* 4 1.1 dholland * Copyright 1997 Piermont Information Systems Inc. 5 1.1 dholland * All rights reserved. 6 1.1 dholland * 7 1.1 dholland * Written by Philip A. Nelson for Piermont Information Systems Inc. 8 1.1 dholland * 9 1.1 dholland * Redistribution and use in source and binary forms, with or without 10 1.1 dholland * modification, are permitted provided that the following conditions 11 1.1 dholland * are met: 12 1.1 dholland * 1. Redistributions of source code must retain the above copyright 13 1.1 dholland * notice, this list of conditions and the following disclaimer. 14 1.1 dholland * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 dholland * notice, this list of conditions and the following disclaimer in the 16 1.1 dholland * documentation and/or other materials provided with the distribution. 17 1.1 dholland * 3. The name of Piermont Information Systems Inc. may not be used to endorse 18 1.1 dholland * or promote products derived from this software without specific prior 19 1.1 dholland * written permission. 20 1.1 dholland * 21 1.1 dholland * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS'' 22 1.1 dholland * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 1.1 dholland * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 1.1 dholland * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE 25 1.1 dholland * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 1.1 dholland * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 1.1 dholland * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 1.1 dholland * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 1.1 dholland * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 1.1 dholland * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 1.1 dholland * THE POSSIBILITY OF SUCH DAMAGE. 32 1.1 dholland * 33 1.1 dholland */ 34 1.1 dholland 35 1.1 dholland /* install.c -- system installation. */ 36 1.1 dholland 37 1.12 martin #include <sys/param.h> 38 1.1 dholland #include <stdio.h> 39 1.1 dholland #include <curses.h> 40 1.1 dholland #include "defs.h" 41 1.1 dholland #include "msg_defs.h" 42 1.1 dholland #include "menu_defs.h" 43 1.1 dholland 44 1.6 martin /* 45 1.6 martin * helper function: call the md pre/post disklabel callback for all involved 46 1.6 martin * inner partitions and write them back. 47 1.6 martin * return net result 48 1.6 martin */ 49 1.6 martin static bool 50 1.6 martin write_all_parts(struct install_partition_desc *install) 51 1.6 martin { 52 1.6 martin struct disk_partitions **allparts, *parts; 53 1.13 martin #ifndef NO_CLONES 54 1.12 martin struct selected_partition *src; 55 1.13 martin #endif 56 1.6 martin size_t num_parts, i, j; 57 1.6 martin bool found, res; 58 1.6 martin 59 1.6 martin /* pessimistic assumption: all partitions on different devices */ 60 1.17 martin allparts = calloc(install->num + install->num_write_back, 61 1.17 martin sizeof(*allparts)); 62 1.6 martin if (allparts == NULL) 63 1.6 martin return false; 64 1.6 martin 65 1.6 martin /* collect all different partition sets */ 66 1.6 martin num_parts = 0; 67 1.17 martin for (i = 0; i < install->num_write_back; i++) { 68 1.17 martin parts = install->write_back[i]; 69 1.17 martin if (parts == NULL) 70 1.17 martin continue; 71 1.17 martin found = false; 72 1.17 martin for (j = 0; j < num_parts; j++) { 73 1.17 martin if (allparts[j] == parts) { 74 1.17 martin found = true; 75 1.17 martin break; 76 1.17 martin } 77 1.17 martin } 78 1.17 martin if (found) 79 1.17 martin continue; 80 1.17 martin allparts[num_parts++] = parts; 81 1.17 martin } 82 1.6 martin for (i = 0; i < install->num; i++) { 83 1.6 martin parts = install->infos[i].parts; 84 1.6 martin if (parts == NULL) 85 1.6 martin continue; 86 1.6 martin found = false; 87 1.6 martin for (j = 0; j < num_parts; j++) { 88 1.6 martin if (allparts[j] == parts) { 89 1.6 martin found = true; 90 1.6 martin break; 91 1.6 martin } 92 1.6 martin } 93 1.6 martin if (found) 94 1.6 martin continue; 95 1.6 martin allparts[num_parts++] = parts; 96 1.6 martin } 97 1.6 martin 98 1.12 martin /* do multiple phases, abort anytime and go out, returning res */ 99 1.6 martin 100 1.6 martin res = true; 101 1.6 martin 102 1.6 martin /* phase 1: pre disklabel - used to write MBR and similar */ 103 1.6 martin for (i = 0; i < num_parts; i++) { 104 1.6 martin if (!md_pre_disklabel(install, allparts[i])) { 105 1.6 martin res = false; 106 1.6 martin goto out; 107 1.6 martin } 108 1.6 martin } 109 1.6 martin 110 1.6 martin /* phase 2: write our partitions (used to be: disklabel) */ 111 1.6 martin for (i = 0; i < num_parts; i++) { 112 1.6 martin if (!allparts[i]->pscheme->write_to_disk(allparts[i])) { 113 1.6 martin res = false; 114 1.6 martin goto out; 115 1.6 martin } 116 1.6 martin } 117 1.6 martin 118 1.6 martin /* phase 3: now we may have a first chance to enable swap space */ 119 1.6 martin set_swap_if_low_ram(install); 120 1.6 martin 121 1.13 martin #ifndef NO_CLONES 122 1.12 martin /* phase 4: copy any cloned partitions data (if requested) */ 123 1.12 martin for (i = 0; i < install->num; i++) { 124 1.12 martin if ((install->infos[i].flags & PUIFLG_CLONE_PARTS) == 0 125 1.12 martin || install->infos[i].clone_src == NULL 126 1.12 martin || !install->infos[i].clone_src->with_data) 127 1.12 martin continue; 128 1.12 martin src = &install->infos[i].clone_src 129 1.12 martin ->selection[install->infos[i].clone_ndx]; 130 1.12 martin clone_partition_data(install->infos[i].parts, 131 1.12 martin install->infos[i].cur_part_id, 132 1.12 martin src->parts, src->id); 133 1.12 martin } 134 1.13 martin #endif 135 1.12 martin 136 1.12 martin /* phase 5: post disklabel (used for updating boot loaders) */ 137 1.6 martin for (i = 0; i < num_parts; i++) { 138 1.6 martin if (!md_post_disklabel(install, allparts[i])) { 139 1.6 martin res = false; 140 1.6 martin goto out; 141 1.6 martin } 142 1.6 martin } 143 1.6 martin 144 1.6 martin out: 145 1.6 martin free(allparts); 146 1.6 martin 147 1.6 martin return res; 148 1.6 martin } 149 1.6 martin 150 1.1 dholland /* Do the system install. */ 151 1.1 dholland 152 1.1 dholland void 153 1.1 dholland do_install(void) 154 1.1 dholland { 155 1.2 martin int find_disks_ret; 156 1.18 martin int retcode = 0, res; 157 1.9 martin struct install_partition_desc install = {}; 158 1.6 martin 159 1.5 rin #ifndef NO_PARTMAN 160 1.2 martin partman_go = -1; 161 1.5 rin #else 162 1.5 rin partman_go = 0; 163 1.5 rin #endif 164 1.1 dholland 165 1.2 martin #ifndef DEBUG 166 1.1 dholland msg_display(MSG_installusure); 167 1.4 martin if (!ask_noyes(NULL)) 168 1.1 dholland return; 169 1.2 martin #endif 170 1.1 dholland 171 1.6 martin memset(&install, 0, sizeof install); 172 1.6 martin 173 1.2 martin /* Create and mount partitions */ 174 1.9 martin find_disks_ret = find_disks(msg_string(MSG_install), false); 175 1.2 martin if (partman_go == 1) { 176 1.24 martin if (partman(&install) < 0) { 177 1.6 martin hit_enter_to_continue(MSG_abort_part, NULL); 178 1.2 martin return; 179 1.2 martin } 180 1.2 martin } else if (find_disks_ret < 0) 181 1.1 dholland return; 182 1.2 martin else { 183 1.2 martin /* Classical partitioning wizard */ 184 1.2 martin partman_go = 0; 185 1.2 martin clear(); 186 1.2 martin refresh(); 187 1.1 dholland 188 1.2 martin if (check_swap(pm->diskdev, 0) > 0) { 189 1.6 martin hit_enter_to_continue(MSG_swapactive, NULL); 190 1.2 martin if (check_swap(pm->diskdev, 1) < 0) { 191 1.6 martin hit_enter_to_continue(MSG_swapdelfailed, NULL); 192 1.2 martin if (!debug) 193 1.2 martin return; 194 1.2 martin } 195 1.1 dholland } 196 1.1 dholland 197 1.18 martin for (;;) { 198 1.18 martin if (md_get_info(&install)) { 199 1.18 martin res = md_make_bsd_partitions(&install); 200 1.18 martin if (res == -1) { 201 1.18 martin pm->parts = NULL; 202 1.18 martin continue; 203 1.18 martin } else if (res == 1) { 204 1.18 martin break; 205 1.18 martin } 206 1.18 martin } 207 1.6 martin hit_enter_to_continue(MSG_abort_inst, NULL); 208 1.10 martin goto error; 209 1.2 martin } 210 1.1 dholland 211 1.2 martin /* Last chance ... do you really want to do this? */ 212 1.2 martin clear(); 213 1.2 martin refresh(); 214 1.8 christos msg_fmt_display(MSG_lastchance, "%s", pm->diskdev); 215 1.4 martin if (!ask_noyes(NULL)) 216 1.10 martin goto error; 217 1.2 martin 218 1.6 martin if ((!pm->no_part && !write_all_parts(&install)) || 219 1.6 martin make_filesystems(&install) || 220 1.6 martin make_fstab(&install) != 0 || 221 1.6 martin md_post_newfs(&install) != 0) 222 1.25 martin goto error; 223 1.1 dholland } 224 1.1 dholland 225 1.2 martin /* Unpack the distribution. */ 226 1.2 martin process_menu(MENU_distset, &retcode); 227 1.2 martin if (retcode == 0) 228 1.10 martin goto error; 229 1.1 dholland if (get_and_unpack_sets(0, MSG_disksetupdone, 230 1.1 dholland MSG_extractcomplete, MSG_abortinst) != 0) 231 1.10 martin goto error; 232 1.1 dholland 233 1.22 martin if (md_post_extract(&install, false) != 0) 234 1.10 martin goto error; 235 1.1 dholland 236 1.23 martin root_pw_setup(); 237 1.23 martin #if CHECK_ENTROPY 238 1.23 martin do_add_entropy(); 239 1.23 martin #endif 240 1.6 martin do_configmenu(&install); 241 1.1 dholland 242 1.1 dholland sanity_check(); 243 1.1 dholland 244 1.6 martin md_cleanup_install(&install); 245 1.6 martin 246 1.6 martin hit_enter_to_continue(MSG_instcomplete, NULL); 247 1.10 martin 248 1.10 martin error: 249 1.12 martin free_install_desc(&install); 250 1.1 dholland } 251