1 /* $NetBSD: install.c,v 1.14 2020/01/16 13:56:24 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, sizeof(*allparts)); 61 if (allparts == NULL) 62 return false; 63 64 /* collect all different partition sets */ 65 num_parts = 0; 66 for (i = 0; i < install->num; i++) { 67 parts = install->infos[i].parts; 68 if (parts == NULL) 69 continue; 70 found = false; 71 for (j = 0; j < num_parts; j++) { 72 if (allparts[j] == parts) { 73 found = true; 74 break; 75 } 76 } 77 if (found) 78 continue; 79 allparts[num_parts++] = parts; 80 } 81 82 /* do multiple phases, abort anytime and go out, returning res */ 83 84 res = true; 85 86 /* phase 1: pre disklabel - used to write MBR and similar */ 87 for (i = 0; i < num_parts; i++) { 88 if (!md_pre_disklabel(install, allparts[i])) { 89 res = false; 90 goto out; 91 } 92 } 93 94 /* phase 2: write our partitions (used to be: disklabel) */ 95 for (i = 0; i < num_parts; i++) { 96 if (!allparts[i]->pscheme->write_to_disk(allparts[i])) { 97 res = false; 98 goto out; 99 } 100 } 101 102 /* phase 3: now we may have a first chance to enable swap space */ 103 set_swap_if_low_ram(install); 104 105 #ifndef NO_CLONES 106 /* phase 4: copy any cloned partitions data (if requested) */ 107 for (i = 0; i < install->num; i++) { 108 if ((install->infos[i].flags & PUIFLG_CLONE_PARTS) == 0 109 || install->infos[i].clone_src == NULL 110 || !install->infos[i].clone_src->with_data) 111 continue; 112 src = &install->infos[i].clone_src 113 ->selection[install->infos[i].clone_ndx]; 114 clone_partition_data(install->infos[i].parts, 115 install->infos[i].cur_part_id, 116 src->parts, src->id); 117 } 118 #endif 119 120 /* phase 5: post disklabel (used for updating boot loaders) */ 121 for (i = 0; i < num_parts; i++) { 122 if (!md_post_disklabel(install, allparts[i])) { 123 res = false; 124 goto out; 125 } 126 } 127 128 out: 129 free(allparts); 130 131 return res; 132 } 133 134 /* Do the system install. */ 135 136 void 137 do_install(void) 138 { 139 int find_disks_ret; 140 int retcode = 0; 141 struct install_partition_desc install = {}; 142 struct disk_partitions *parts; 143 144 #ifndef NO_PARTMAN 145 partman_go = -1; 146 #else 147 partman_go = 0; 148 #endif 149 150 #ifndef DEBUG 151 msg_display(MSG_installusure); 152 if (!ask_noyes(NULL)) 153 return; 154 #endif 155 156 memset(&install, 0, sizeof install); 157 158 /* Create and mount partitions */ 159 find_disks_ret = find_disks(msg_string(MSG_install), false); 160 if (partman_go == 1) { 161 if (partman() < 0) { 162 hit_enter_to_continue(MSG_abort_part, NULL); 163 return; 164 } 165 } else if (find_disks_ret < 0) 166 return; 167 else { 168 /* Classical partitioning wizard */ 169 partman_go = 0; 170 clear(); 171 refresh(); 172 173 if (check_swap(pm->diskdev, 0) > 0) { 174 hit_enter_to_continue(MSG_swapactive, NULL); 175 if (check_swap(pm->diskdev, 1) < 0) { 176 hit_enter_to_continue(MSG_swapdelfailed, NULL); 177 if (!debug) 178 return; 179 } 180 } 181 182 if (!md_get_info(&install) || 183 !md_make_bsd_partitions(&install)) { 184 hit_enter_to_continue(MSG_abort_inst, NULL); 185 goto error; 186 } 187 188 /* Last chance ... do you really want to do this? */ 189 clear(); 190 refresh(); 191 msg_fmt_display(MSG_lastchance, "%s", pm->diskdev); 192 if (!ask_noyes(NULL)) 193 goto error; 194 195 /* 196 * Check if we have a secondary partitioning and 197 * use that if available. The MD code will typically 198 * have written the outer partitioning in md_pre_disklabel. 199 */ 200 parts = pm->parts; 201 if (!pm->no_part && parts != NULL) { 202 if (parts->pscheme->secondary_scheme != NULL && 203 parts->pscheme->secondary_partitions != NULL) { 204 parts = parts->pscheme->secondary_partitions( 205 parts, pm->ptstart, false); 206 if (parts == NULL) 207 parts = pm->parts; 208 } 209 } 210 if ((!pm->no_part && !write_all_parts(&install)) || 211 make_filesystems(&install) || 212 make_fstab(&install) != 0 || 213 md_post_newfs(&install) != 0) 214 goto error; 215 } 216 217 /* Unpack the distribution. */ 218 process_menu(MENU_distset, &retcode); 219 if (retcode == 0) 220 goto error; 221 if (get_and_unpack_sets(0, MSG_disksetupdone, 222 MSG_extractcomplete, MSG_abortinst) != 0) 223 goto error; 224 225 if (md_post_extract(&install) != 0) 226 goto error; 227 228 do_configmenu(&install); 229 230 sanity_check(); 231 232 md_cleanup_install(&install); 233 234 hit_enter_to_continue(MSG_instcomplete, NULL); 235 236 error: 237 free_install_desc(&install); 238 } 239