1 /* $NetBSD: install.c,v 1.11 2019/08/17 18:08:06 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 <stdio.h> 38 #include <curses.h> 39 #include "defs.h" 40 #include "msg_defs.h" 41 #include "menu_defs.h" 42 43 /* 44 * helper function: call the md pre/post disklabel callback for all involved 45 * inner partitions and write them back. 46 * return net result 47 */ 48 static bool 49 write_all_parts(struct install_partition_desc *install) 50 { 51 struct disk_partitions **allparts, *parts; 52 size_t num_parts, i, j; 53 bool found, res; 54 55 /* pessimistic assumption: all partitions on different devices */ 56 allparts = calloc(install->num, sizeof(*allparts)); 57 if (allparts == NULL) 58 return false; 59 60 /* collect all different partition sets */ 61 num_parts = 0; 62 for (i = 0; i < install->num; i++) { 63 parts = install->infos[i].parts; 64 if (parts == NULL) 65 continue; 66 found = false; 67 for (j = 0; j < num_parts; j++) { 68 if (allparts[j] == parts) { 69 found = true; 70 break; 71 } 72 } 73 if (found) 74 continue; 75 allparts[num_parts++] = parts; 76 } 77 78 /* do four phases, abort anytime and go out, returning res */ 79 80 res = true; 81 82 /* phase 1: pre disklabel - used to write MBR and similar */ 83 for (i = 0; i < num_parts; i++) { 84 if (!md_pre_disklabel(install, allparts[i])) { 85 res = false; 86 goto out; 87 } 88 } 89 90 /* phase 2: write our partitions (used to be: disklabel) */ 91 for (i = 0; i < num_parts; i++) { 92 if (!allparts[i]->pscheme->write_to_disk(allparts[i])) { 93 res = false; 94 goto out; 95 } 96 } 97 98 /* phase 3: now we may have a first chance to enable swap space */ 99 set_swap_if_low_ram(install); 100 101 /* phase 4: post disklabel (used for updating boot loaders) */ 102 for (i = 0; i < num_parts; i++) { 103 if (!md_post_disklabel(install, allparts[i])) { 104 res = false; 105 goto out; 106 } 107 } 108 109 out: 110 free(allparts); 111 112 return res; 113 } 114 115 /* Do the system install. */ 116 117 void 118 do_install(void) 119 { 120 int find_disks_ret; 121 int retcode = 0; 122 struct install_partition_desc install = {}; 123 struct disk_partitions *parts; 124 125 #ifndef NO_PARTMAN 126 partman_go = -1; 127 #else 128 partman_go = 0; 129 #endif 130 131 #ifndef DEBUG 132 msg_display(MSG_installusure); 133 if (!ask_noyes(NULL)) 134 return; 135 #endif 136 137 memset(&install, 0, sizeof install); 138 139 get_ramsize(); 140 141 /* Create and mount partitions */ 142 find_disks_ret = find_disks(msg_string(MSG_install), false); 143 if (partman_go == 1) { 144 if (partman() < 0) { 145 hit_enter_to_continue(MSG_abort_part, NULL); 146 return; 147 } 148 } else if (find_disks_ret < 0) 149 return; 150 else { 151 /* Classical partitioning wizard */ 152 partman_go = 0; 153 clear(); 154 refresh(); 155 156 if (check_swap(pm->diskdev, 0) > 0) { 157 hit_enter_to_continue(MSG_swapactive, NULL); 158 if (check_swap(pm->diskdev, 1) < 0) { 159 hit_enter_to_continue(MSG_swapdelfailed, NULL); 160 if (!debug) 161 return; 162 } 163 } 164 165 if (!md_get_info(&install) || 166 !md_make_bsd_partitions(&install)) { 167 hit_enter_to_continue(MSG_abort_inst, NULL); 168 goto error; 169 } 170 171 /* Last chance ... do you really want to do this? */ 172 clear(); 173 refresh(); 174 msg_fmt_display(MSG_lastchance, "%s", pm->diskdev); 175 if (!ask_noyes(NULL)) 176 goto error; 177 178 /* 179 * Check if we have a secondary partitioning and 180 * use that if available. The MD code will typically 181 * have written the outer partitioning in md_pre_disklabel. 182 */ 183 parts = pm->parts; 184 if (!pm->no_part && parts != NULL) { 185 if (parts->pscheme->secondary_scheme != NULL && 186 parts->pscheme->secondary_partitions != NULL) { 187 parts = parts->pscheme->secondary_partitions( 188 parts, pm->ptstart, false); 189 if (parts == NULL) 190 parts = pm->parts; 191 } 192 } 193 if ((!pm->no_part && !write_all_parts(&install)) || 194 make_filesystems(&install) || 195 make_fstab(&install) != 0 || 196 md_post_newfs(&install) != 0) 197 goto error; 198 } 199 200 /* Unpack the distribution. */ 201 process_menu(MENU_distset, &retcode); 202 if (retcode == 0) 203 goto error; 204 if (get_and_unpack_sets(0, MSG_disksetupdone, 205 MSG_extractcomplete, MSG_abortinst) != 0) 206 goto error; 207 208 if (md_post_extract(&install) != 0) 209 goto error; 210 211 do_configmenu(&install); 212 213 sanity_check(); 214 215 md_cleanup_install(&install); 216 217 hit_enter_to_continue(MSG_instcomplete, NULL); 218 219 error: 220 free(install.infos); 221 } 222