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