xref: /netbsd-src/usr.sbin/sysinst/install.c (revision 76c7fc5f6b13ed0b1508e6b313e88e59977ed78e)
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