1 /* $NetBSD: install.c,v 1.20 2020/11/04 14:29: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 */ 49 static bool 50 write_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 144 out: 145 free(allparts); 146 147 return res; 148 } 149 150 /* Do the system install. */ 151 152 void 153 do_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 #ifdef CHECK_ENTROPY 172 if (!do_check_entropy()) { 173 hit_enter_to_continue(MSG_abort_installation, NULL); 174 return; 175 } 176 #endif 177 178 memset(&install, 0, sizeof install); 179 180 /* Create and mount partitions */ 181 find_disks_ret = find_disks(msg_string(MSG_install), false); 182 if (partman_go == 1) { 183 if (partman() < 0) { 184 hit_enter_to_continue(MSG_abort_part, NULL); 185 return; 186 } 187 } else if (find_disks_ret < 0) 188 return; 189 else { 190 /* Classical partitioning wizard */ 191 partman_go = 0; 192 clear(); 193 refresh(); 194 195 if (check_swap(pm->diskdev, 0) > 0) { 196 hit_enter_to_continue(MSG_swapactive, NULL); 197 if (check_swap(pm->diskdev, 1) < 0) { 198 hit_enter_to_continue(MSG_swapdelfailed, NULL); 199 if (!debug) 200 return; 201 } 202 } 203 204 for (;;) { 205 if (md_get_info(&install)) { 206 res = md_make_bsd_partitions(&install); 207 if (res == -1) { 208 pm->parts = NULL; 209 continue; 210 } else if (res == 1) { 211 break; 212 } 213 } 214 hit_enter_to_continue(MSG_abort_inst, NULL); 215 goto error; 216 } 217 218 /* Last chance ... do you really want to do this? */ 219 clear(); 220 refresh(); 221 msg_fmt_display(MSG_lastchance, "%s", pm->diskdev); 222 if (!ask_noyes(NULL)) 223 goto error; 224 225 if ((!pm->no_part && !write_all_parts(&install)) || 226 make_filesystems(&install) || 227 make_fstab(&install) != 0 || 228 md_post_newfs(&install) != 0) 229 goto error; 230 } 231 232 /* Unpack the distribution. */ 233 process_menu(MENU_distset, &retcode); 234 if (retcode == 0) 235 goto error; 236 if (get_and_unpack_sets(0, MSG_disksetupdone, 237 MSG_extractcomplete, MSG_abortinst) != 0) 238 goto error; 239 240 if (md_post_extract(&install) != 0) 241 goto error; 242 243 do_configmenu(&install); 244 245 sanity_check(); 246 247 md_cleanup_install(&install); 248 249 hit_enter_to_continue(MSG_instcomplete, NULL); 250 251 error: 252 free_install_desc(&install); 253 } 254