xref: /dflybsd-src/usr.sbin/installer/dfuibe_installer/fn_install.c (revision 9758d73afa45aa6436355bee66f24d490ea5b84a)
121c1c48aSSascha Wildner /*
2f9602a12SMatthew Dillon  * Copyright (c)2004,2015 The DragonFly Project.  All rights reserved.
321c1c48aSSascha Wildner  *
421c1c48aSSascha Wildner  * Redistribution and use in source and binary forms, with or without
521c1c48aSSascha Wildner  * modification, are permitted provided that the following conditions
621c1c48aSSascha Wildner  * are met:
721c1c48aSSascha Wildner  *
821c1c48aSSascha Wildner  *   Redistributions of source code must retain the above copyright
921c1c48aSSascha Wildner  *   notice, this list of conditions and the following disclaimer.
1021c1c48aSSascha Wildner  *
1121c1c48aSSascha Wildner  *   Redistributions in binary form must reproduce the above copyright
1221c1c48aSSascha Wildner  *   notice, this list of conditions and the following disclaimer in
1321c1c48aSSascha Wildner  *   the documentation and/or other materials provided with the
1421c1c48aSSascha Wildner  *   distribution.
1521c1c48aSSascha Wildner  *
1621c1c48aSSascha Wildner  *   Neither the name of the DragonFly Project nor the names of its
1721c1c48aSSascha Wildner  *   contributors may be used to endorse or promote products derived
1821c1c48aSSascha Wildner  *   from this software without specific prior written permission.
1921c1c48aSSascha Wildner  *
2021c1c48aSSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2121c1c48aSSascha Wildner  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2221c1c48aSSascha Wildner  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
2321c1c48aSSascha Wildner  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
2421c1c48aSSascha Wildner  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2521c1c48aSSascha Wildner  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2621c1c48aSSascha Wildner  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2721c1c48aSSascha Wildner  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2821c1c48aSSascha Wildner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2921c1c48aSSascha Wildner  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3021c1c48aSSascha Wildner  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
3121c1c48aSSascha Wildner  * OF THE POSSIBILITY OF SUCH DAMAGE.
3221c1c48aSSascha Wildner  */
3321c1c48aSSascha Wildner 
3421c1c48aSSascha Wildner /*
3521c1c48aSSascha Wildner  * fn_install.c
3621c1c48aSSascha Wildner  * Installer Function : Install OS Files.
3721c1c48aSSascha Wildner  * $Id: fn_install.c,v 1.74 2006/04/18 19:43:48 joerg Exp $
3821c1c48aSSascha Wildner  */
3921c1c48aSSascha Wildner 
4021c1c48aSSascha Wildner #include <libgen.h>
4121c1c48aSSascha Wildner #include <string.h>
4221c1c48aSSascha Wildner 
43ed643d92SSascha Wildner #define SOURCES_CONF_FILE "usr/share/installer/sources.conf"
4421c1c48aSSascha Wildner 
4521c1c48aSSascha Wildner #ifdef ENABLE_NLS
4621c1c48aSSascha Wildner #include <libintl.h>
4721c1c48aSSascha Wildner #define _(String) gettext (String)
4821c1c48aSSascha Wildner #else
4921c1c48aSSascha Wildner #define _(String) (String)
5021c1c48aSSascha Wildner #endif
5121c1c48aSSascha Wildner 
5221c1c48aSSascha Wildner #include "libaura/mem.h"
5321c1c48aSSascha Wildner #include "libaura/buffer.h"
5421c1c48aSSascha Wildner #include "libaura/fspred.h"
5521c1c48aSSascha Wildner 
5621c1c48aSSascha Wildner #include "libdfui/dfui.h"
5721c1c48aSSascha Wildner #include "libdfui/system.h"
5821c1c48aSSascha Wildner 
5921c1c48aSSascha Wildner #include "libinstaller/commands.h"
6021c1c48aSSascha Wildner #include "libinstaller/confed.h"
6121c1c48aSSascha Wildner #include "libinstaller/diskutil.h"
6221c1c48aSSascha Wildner #include "libinstaller/functions.h"
6321c1c48aSSascha Wildner #include "libinstaller/uiutil.h"
6421c1c48aSSascha Wildner 
6521c1c48aSSascha Wildner #include "flow.h"
6621c1c48aSSascha Wildner #include "pathnames.h"
6721c1c48aSSascha Wildner #include "fn.h"
6821c1c48aSSascha Wildner 
69f9602a12SMatthew Dillon /*
70f9602a12SMatthew Dillon  * NOTE: Even though /var/run doesn't need to be backed up, nearly all
71f9602a12SMatthew Dillon  *	 services depend on it so it is best to leave it on the root.
72f9602a12SMatthew Dillon  */
73f9602a12SMatthew Dillon static const char *nullfs_mountpt[] = {
74f9602a12SMatthew Dillon 	"/usr/obj", "/var/crash", "/var/cache",
75f9602a12SMatthew Dillon 	"/var/spool", "/var/log", "/var/tmp",
76f9602a12SMatthew Dillon 	NULL };
77f9602a12SMatthew Dillon static const char *nullfs_mountname[] = {
78f9602a12SMatthew Dillon 	"/build/usr.obj", "/build/var.crash", "/build/var.cache",
79f9602a12SMatthew Dillon 	"/build/var.spool", "/build/var.log", "/build/var.tmp",
80f9602a12SMatthew Dillon 	NULL };
8121c1c48aSSascha Wildner 
8221c1c48aSSascha Wildner static void
handle_altfs(struct i_fn_args * a,struct commands * cmds)83f9602a12SMatthew Dillon handle_altfs(struct i_fn_args *a, struct commands *cmds)
8421c1c48aSSascha Wildner {
85f9602a12SMatthew Dillon 	int i;
8621c1c48aSSascha Wildner 
8721c1c48aSSascha Wildner 	/*
88f9602a12SMatthew Dillon 	 * Create directories for null mounts if not specified as a partition.
89f9602a12SMatthew Dillon 	 * (null mounts are from /build)
9021c1c48aSSascha Wildner 	 */
91f9602a12SMatthew Dillon 	for (i = 0; nullfs_mountpt[i]; ++i) {
92f9602a12SMatthew Dillon 		if (subpartition_find(storage_get_selected_slice(a->s), "%s", nullfs_mountpt[i]) != NULL)
93f9602a12SMatthew Dillon 			continue;
9421c1c48aSSascha Wildner 
9521c1c48aSSascha Wildner 		/*
96f9602a12SMatthew Dillon 		 * Create directory infrastructure for null-mount if
97f9602a12SMatthew Dillon 		 * necessary, then issue the null mount(s).
9821c1c48aSSascha Wildner 		 */
9921c1c48aSSascha Wildner 		command_add(cmds, "%s%s -p %smnt%s",
10021c1c48aSSascha Wildner 			    a->os_root, cmd_name(a, "MKDIR"),
101f9602a12SMatthew Dillon 			    a->os_root, nullfs_mountname[i]);
10221c1c48aSSascha Wildner 		command_add(cmds, "%s%s -p %smnt%s",
10321c1c48aSSascha Wildner 			    a->os_root, cmd_name(a, "MKDIR"),
104f9602a12SMatthew Dillon 			    a->os_root, nullfs_mountpt[i]);
105f9602a12SMatthew Dillon 		command_add(cmds, "%s%s %smnt%s %smnt%s",
10621c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "MOUNT_NULL"),
107f9602a12SMatthew Dillon 		    a->os_root, nullfs_mountname[i],
108f9602a12SMatthew Dillon 		    a->os_root, nullfs_mountpt[i]);
109f9602a12SMatthew Dillon 	}
110f9602a12SMatthew Dillon 
111f9602a12SMatthew Dillon 	/*
112f9602a12SMatthew Dillon 	 * Create directory for /tmp and tmpfs mount if not specified as
113f9602a12SMatthew Dillon 	 * a partition.
114f9602a12SMatthew Dillon 	 */
115f9602a12SMatthew Dillon 	if (subpartition_find(storage_get_selected_slice(a->s), "%s", "/tmp") == NULL) {
116f9602a12SMatthew Dillon 		command_add(cmds, "%s%s -p %smnt/tmp",
117f9602a12SMatthew Dillon 			    a->os_root, cmd_name(a, "MKDIR"), a->os_root);
118f9602a12SMatthew Dillon 		command_add(cmds, "%s%s 1777 %smnt/tmp",
119f9602a12SMatthew Dillon 			    a->os_root, cmd_name(a, "CHMOD"), a->os_root);
120f9602a12SMatthew Dillon 		command_add(cmds, "%s%s dummy %smnt/tmp",
121f9602a12SMatthew Dillon 			    a->os_root, cmd_name(a, "MOUNT_TMPFS"), a->os_root);
12221c1c48aSSascha Wildner 	}
12321c1c48aSSascha Wildner }
124f9602a12SMatthew Dillon 
125f9602a12SMatthew Dillon static void
unmount_altfs(struct i_fn_args * a __unused,struct commands * cmds __unused)126f9602a12SMatthew Dillon unmount_altfs(struct i_fn_args *a __unused, struct commands *cmds __unused)
127f9602a12SMatthew Dillon {
128f9602a12SMatthew Dillon 	return;
129f9602a12SMatthew Dillon #if 0
130f9602a12SMatthew Dillon 	int i;
131f9602a12SMatthew Dillon 
132f9602a12SMatthew Dillon 	/*
133f9602a12SMatthew Dillon 	 * Unmount null mounts
134f9602a12SMatthew Dillon 	 */
135f9602a12SMatthew Dillon 	i = sizeof(nullfs_mountpt) / sizeof(nullfs_mountpt[0]) - 1;
136f9602a12SMatthew Dillon 	while (i >= 0) {
137f9602a12SMatthew Dillon 		if (subpartition_find(storage_get_selected_slice(a->s), "%s", nullfs_mountpt[i]) != NULL)
138f9602a12SMatthew Dillon 			continue;
139f9602a12SMatthew Dillon 
140f9602a12SMatthew Dillon 		/*
141f9602a12SMatthew Dillon 		 * Create directory infrastructure for null-mount if
142f9602a12SMatthew Dillon 		 * necessary, then issue the null mount(s).
143f9602a12SMatthew Dillon 		 */
144f9602a12SMatthew Dillon 		command_add(cmds, "%s%s %smnt%s",
145f9602a12SMatthew Dillon 			    a->os_root, cmd_name(a, "UMOUNT"),
146f9602a12SMatthew Dillon 			    a->os_root, nullfs_mountpt[i]);
147f9602a12SMatthew Dillon 		--i;
148f9602a12SMatthew Dillon 	}
149f9602a12SMatthew Dillon 
150f9602a12SMatthew Dillon 	/*
151f9602a12SMatthew Dillon 	 * Unmount tmpfs mounts
152f9602a12SMatthew Dillon 	 */
153f9602a12SMatthew Dillon 	if (subpartition_find(storage_get_selected_slice(a->s), "%s", "/tmp") == NULL) {
154f9602a12SMatthew Dillon 		command_add(cmds, "%s%s -p %smnt%s",
155f9602a12SMatthew Dillon 			    a->os_root, cmd_name(a, "UMOUNT"),
156f9602a12SMatthew Dillon 			    a->os_root, "/tmp");
157f9602a12SMatthew Dillon 	}
158f9602a12SMatthew Dillon #endif
15921c1c48aSSascha Wildner }
16021c1c48aSSascha Wildner 
16121c1c48aSSascha Wildner /*
16221c1c48aSSascha Wildner  * fn_install_os: actually put DragonFly on a disk.
16321c1c48aSSascha Wildner  */
16421c1c48aSSascha Wildner void
fn_install_os(struct i_fn_args * a)16521c1c48aSSascha Wildner fn_install_os(struct i_fn_args *a)
16621c1c48aSSascha Wildner {
167f9602a12SMatthew Dillon 	struct subpartition *sp, *spnext;
16821c1c48aSSascha Wildner 	struct commands *cmds;
16921c1c48aSSascha Wildner 	struct command *cmd;
17088cfb1f7SSascha Wildner 	int i, seen_it, prefix, j, needcrypt;
17121c1c48aSSascha Wildner 	FILE *sources_conf;
17221c1c48aSSascha Wildner 	char line[256];
17321c1c48aSSascha Wildner 	char cp_src[64][256];
17421c1c48aSSascha Wildner 	char file_path[256];
1751c142c35SSascha Wildner 	char *string;
17621c1c48aSSascha Wildner 	int lines = 0;
177f9602a12SMatthew Dillon 	int nfsidx;
17821c1c48aSSascha Wildner 
179fbe689f9SSascha Wildner 	/*
180fbe689f9SSascha Wildner 	 * Read SOURCES_CONF_FILE and populate our copy sources.
181fbe689f9SSascha Wildner 	 */
18221c1c48aSSascha Wildner 	snprintf(file_path, 256, "%s%s", a->os_root, SOURCES_CONF_FILE);
18321c1c48aSSascha Wildner 	sources_conf = fopen(file_path, "r");
184ed643d92SSascha Wildner 	i_log(a, "Reading %s", file_path);
18521c1c48aSSascha Wildner 	while(fgets(line, 256, sources_conf) != NULL && lines < 63) {
18621c1c48aSSascha Wildner 		if(strlen(line)>0)
18721c1c48aSSascha Wildner 			line[strlen(line)-1] = '\0';
18821c1c48aSSascha Wildner 		strlcpy(cp_src[lines], line, 256);
18921c1c48aSSascha Wildner 		i_log(a,"Adding %s to copy source table.", cp_src[lines]);
19021c1c48aSSascha Wildner 		lines++;
19121c1c48aSSascha Wildner 	}
19221c1c48aSSascha Wildner 	i_log(a,"Added %i total items to copy source table.", lines);
19321c1c48aSSascha Wildner 	strcpy(cp_src[lines], "");
19421c1c48aSSascha Wildner 	fclose(sources_conf);
19521c1c48aSSascha Wildner 
19621c1c48aSSascha Wildner 	cmds = commands_new();
19721c1c48aSSascha Wildner 
19821c1c48aSSascha Wildner 	/*
19921c1c48aSSascha Wildner 	 * If swap isn't mounted yet, mount it.
20021c1c48aSSascha Wildner 	 */
20121c1c48aSSascha Wildner 	if (measure_activated_swap(a) == 0) {
20221c1c48aSSascha Wildner 		for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
20321c1c48aSSascha Wildner 		    sp != NULL; sp = subpartition_next(sp)) {
20421c1c48aSSascha Wildner 			if (!subpartition_is_swap(sp))
20521c1c48aSSascha Wildner 				continue;
20651871435SSascha Wildner 			command_add(cmds, "%s%s /dev/%s",
20721c1c48aSSascha Wildner 			    a->os_root,
20821c1c48aSSascha Wildner 			    cmd_name(a, "SWAPON"),
20988cfb1f7SSascha Wildner 			    subpartition_is_encrypted(sp) ?
21088cfb1f7SSascha Wildner 			    "mapper/swap" : subpartition_get_device_name(sp));
21121c1c48aSSascha Wildner 		}
21221c1c48aSSascha Wildner 	}
21321c1c48aSSascha Wildner 
21421c1c48aSSascha Wildner 	/*
21521c1c48aSSascha Wildner 	 * Unmount anything already mounted on /mnt.
21621c1c48aSSascha Wildner 	 */
217f9602a12SMatthew Dillon 	unmount_altfs(a, cmds);
21821c1c48aSSascha Wildner 	unmount_all_under(a, cmds, "%smnt", a->os_root);
21921c1c48aSSascha Wildner 
22088cfb1f7SSascha Wildner 	/* Check if crypto support is needed */
22188cfb1f7SSascha Wildner 	needcrypt = 0;
22288cfb1f7SSascha Wildner 	for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
22388cfb1f7SSascha Wildner 	     sp != NULL; sp = subpartition_next(sp)) {
22488cfb1f7SSascha Wildner 		if (subpartition_is_encrypted(sp)) {
22588cfb1f7SSascha Wildner 			needcrypt = 1;
22688cfb1f7SSascha Wildner 			break;
22788cfb1f7SSascha Wildner 		}
22888cfb1f7SSascha Wildner 	}
22988cfb1f7SSascha Wildner 
23021c1c48aSSascha Wildner 	for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
23121c1c48aSSascha Wildner 	     sp != NULL; sp = subpartition_next(sp)) {
232f9602a12SMatthew Dillon 		if (strcmp(subpartition_get_mountpoint(sp), "/") == 0 ||
233f9602a12SMatthew Dillon 		    strcmp(subpartition_get_mountpoint(sp), "/build") == 0) {
234f9602a12SMatthew Dillon 			/* make sure mountpoint directory exists */
235f9602a12SMatthew Dillon 			command_add(cmds, "%s%s -p %smnt%s",
236f9602a12SMatthew Dillon 				    a->os_root, cmd_name(a, "MKDIR"),
237f9602a12SMatthew Dillon 				    a->os_root,
238f9602a12SMatthew Dillon 				    subpartition_get_mountpoint(sp));
239e90c1ebbSMatthew Dillon 			switch(use_hammer) {
240e90c1ebbSMatthew Dillon 			case 1:
24151871435SSascha Wildner 				command_add(cmds, "%s%s /dev/%s %smnt%s",
24221c1c48aSSascha Wildner 				    a->os_root, cmd_name(a, "MOUNT_HAMMER"),
243f9602a12SMatthew Dillon 				    (subpartition_is_encrypted(sp) ?
2440c941bc8SSascha Wildner 					subpartition_get_mapper_name(sp, 0) :
2450c941bc8SSascha Wildner 					subpartition_get_device_name(sp)),
24621c1c48aSSascha Wildner 				    a->os_root,
24721c1c48aSSascha Wildner 				    subpartition_get_mountpoint(sp));
248e90c1ebbSMatthew Dillon 				break;
249e90c1ebbSMatthew Dillon 			case 2:
250e90c1ebbSMatthew Dillon 				command_add(cmds, "%s%s /dev/%s %smnt%s",
251e90c1ebbSMatthew Dillon 				    a->os_root, cmd_name(a, "MOUNT_HAMMER2"),
252e90c1ebbSMatthew Dillon 				    (subpartition_is_encrypted(sp) ?
253e90c1ebbSMatthew Dillon 					subpartition_get_mapper_name(sp, 0) :
254e90c1ebbSMatthew Dillon 					subpartition_get_device_name(sp)),
255e90c1ebbSMatthew Dillon 				    a->os_root,
256e90c1ebbSMatthew Dillon 				    subpartition_get_mountpoint(sp));
257e90c1ebbSMatthew Dillon 				break;
258e90c1ebbSMatthew Dillon 			case 0:
259e90c1ebbSMatthew Dillon 			default:
26051871435SSascha Wildner 				command_add(cmds, "%s%s /dev/%s %smnt%s",
26121c1c48aSSascha Wildner 				    a->os_root, cmd_name(a, "MOUNT"),
2620c941bc8SSascha Wildner 				    (subpartition_is_encrypted(sp) ?
2630c941bc8SSascha Wildner 					subpartition_get_mapper_name(sp, 0) :
2640c941bc8SSascha Wildner 					subpartition_get_device_name(sp)),
26521c1c48aSSascha Wildner 				    a->os_root,
26621c1c48aSSascha Wildner 				    subpartition_get_mountpoint(sp));
267e90c1ebbSMatthew Dillon 				break;
26821c1c48aSSascha Wildner 			}
26921c1c48aSSascha Wildner 		}
27021c1c48aSSascha Wildner 	}
27121c1c48aSSascha Wildner 
27221c1c48aSSascha Wildner 	/*
27321c1c48aSSascha Wildner 	 * Create mount points and mount subpartitions on them.
27421c1c48aSSascha Wildner 	 */
27521c1c48aSSascha Wildner 	for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
27621c1c48aSSascha Wildner 	     sp != NULL; sp = subpartition_next(sp)) {
27721c1c48aSSascha Wildner 		if (subpartition_is_swap(sp)) {
27821c1c48aSSascha Wildner 			/*
27921c1c48aSSascha Wildner 			 * Set this subpartition as the dump device.
28021c1c48aSSascha Wildner 			 */
281e90c1ebbSMatthew Dillon 			command_add(cmds, "%s%s off",
282e90c1ebbSMatthew Dillon 			    a->os_root, cmd_name(a, "DUMPON"));
28351871435SSascha Wildner 			command_add(cmds, "%s%s -v /dev/%s",
28421c1c48aSSascha Wildner 			    a->os_root, cmd_name(a, "DUMPON"),
28588cfb1f7SSascha Wildner 			    subpartition_is_encrypted(sp) ?
28688cfb1f7SSascha Wildner 			    "mapper/swap" : subpartition_get_device_name(sp));
28721c1c48aSSascha Wildner 
28821c1c48aSSascha Wildner 			asprintf(&string, "/dev/%s",
28988cfb1f7SSascha Wildner 			    subpartition_is_encrypted(sp) ?
29088cfb1f7SSascha Wildner 			    "mapper/swap" : subpartition_get_device_name(sp));
29121c1c48aSSascha Wildner 			config_var_set(rc_conf, "dumpdev", string);
29221c1c48aSSascha Wildner 			free(string);
29321c1c48aSSascha Wildner 			continue;
29421c1c48aSSascha Wildner 		}
29521c1c48aSSascha Wildner 
296f9602a12SMatthew Dillon 		/*
297f9602a12SMatthew Dillon 		 * mount everything except / and /build (which have already
298f9602a12SMatthew Dillon 		 * been mounted).  This should also get /boot.
299f9602a12SMatthew Dillon 		 */
300f9602a12SMatthew Dillon 		if (strcmp(subpartition_get_mountpoint(sp), "/") != 0 &&
301f9602a12SMatthew Dillon 		    strcmp(subpartition_get_mountpoint(sp), "/build") != 0) {
302f9602a12SMatthew Dillon 			/* make sure mountpoint directory exists */
30321c1c48aSSascha Wildner 			command_add(cmds, "%s%s -p %smnt%s",
30421c1c48aSSascha Wildner 			    a->os_root, cmd_name(a, "MKDIR"),
30521c1c48aSSascha Wildner 			    a->os_root,
30621c1c48aSSascha Wildner 			    subpartition_get_mountpoint(sp));
307761cad2fSSascha Wildner 			/* Don't mount it if it's TMPFS-backed. */
308761cad2fSSascha Wildner 			if (subpartition_is_tmpfsbacked(sp))
30921c1c48aSSascha Wildner 				continue;
310f9602a12SMatthew Dillon 			command_add(cmds, "%s%s /dev/%s %smnt%s",
31188cfb1f7SSascha Wildner 			    a->os_root, cmd_name(a, "MOUNT"),
3120c941bc8SSascha Wildner 			    (subpartition_is_encrypted(sp) ?
3130c941bc8SSascha Wildner 				subpartition_get_mapper_name(sp, 0) :
3140c941bc8SSascha Wildner 				subpartition_get_device_name(sp)),
31588cfb1f7SSascha Wildner 			    a->os_root,
31688cfb1f7SSascha Wildner 			    subpartition_get_mountpoint(sp));
31788cfb1f7SSascha Wildner 		}
31821c1c48aSSascha Wildner 	}
31921c1c48aSSascha Wildner 
32021c1c48aSSascha Wildner 	/*
321f9602a12SMatthew Dillon 	 * Take care of tmpfs and null-mounts from /build
32221c1c48aSSascha Wildner 	 */
323f9602a12SMatthew Dillon 	handle_altfs(a, cmds);
32421c1c48aSSascha Wildner 
32521c1c48aSSascha Wildner 	/*
32621c1c48aSSascha Wildner 	 * Actually copy files now.
32721c1c48aSSascha Wildner 	 */
32821c1c48aSSascha Wildner 	for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) {
32921c1c48aSSascha Wildner 		char *src, *dest, *dn, *tmp_dest;
33021c1c48aSSascha Wildner 
33121c1c48aSSascha Wildner 		dest = cp_src[i];
33221c1c48aSSascha Wildner 
33321c1c48aSSascha Wildner 		/*
334761cad2fSSascha Wildner 		 * If dest would be on an TMPFS-backed
33521c1c48aSSascha Wildner 		 * mountpoint, don't bother copying it.
33621c1c48aSSascha Wildner 		 */
33721c1c48aSSascha Wildner 		sp = subpartition_of(storage_get_selected_slice(a->s),
33821c1c48aSSascha Wildner 				     "%s%s", a->os_root, &dest[1]);
339761cad2fSSascha Wildner 		if (sp != NULL && subpartition_is_tmpfsbacked(sp)) {
34021c1c48aSSascha Wildner 			continue;
34121c1c48aSSascha Wildner 		}
34221c1c48aSSascha Wildner 
34321c1c48aSSascha Wildner 		/*
34421c1c48aSSascha Wildner 		 * Create intermediate directories, if needed.
34521c1c48aSSascha Wildner 		 */
34621c1c48aSSascha Wildner 		tmp_dest = aura_strdup(dest);
34721c1c48aSSascha Wildner 		dn = dirname(tmp_dest);
34821c1c48aSSascha Wildner 		if (is_dir("%s%s", a->os_root, &dn[1]) &&
34921c1c48aSSascha Wildner 		    !is_dir("%smnt%s", a->os_root, dn)) {
35021c1c48aSSascha Wildner 			command_add(cmds, "%s%s -p %smnt%s",
35121c1c48aSSascha Wildner 			    a->os_root, cmd_name(a, "MKDIR"),
35221c1c48aSSascha Wildner 			    a->os_root, dn);
35321c1c48aSSascha Wildner 		}
35421c1c48aSSascha Wildner 		aura_free(tmp_dest, "directory name");
35521c1c48aSSascha Wildner 
35621c1c48aSSascha Wildner 		/*
35721c1c48aSSascha Wildner 		 * If a directory by the same name but with the suffix
35821c1c48aSSascha Wildner 		 * ".hdd" exists on the installation media, cpdup that
35921c1c48aSSascha Wildner 		 * instead.  This is particularly useful with /etc, which
36021c1c48aSSascha Wildner 		 * may have significantly different behaviour on the
36121c1c48aSSascha Wildner 		 * live CD compared to a standard HDD boot.
36221c1c48aSSascha Wildner 		 */
36321c1c48aSSascha Wildner 		if (is_dir("%s%s.hdd", a->os_root, &dest[1]))
36421c1c48aSSascha Wildner 			asprintf(&src, "%s.hdd", &dest[1]);
36521c1c48aSSascha Wildner 		else
36621c1c48aSSascha Wildner 			asprintf(&src, "%s", &dest[1]);
36721c1c48aSSascha Wildner 
36821c1c48aSSascha Wildner 		/*
36921c1c48aSSascha Wildner 		 * Cpdup the chosen file or directory onto the HDD.
37021c1c48aSSascha Wildner 		 * if it exists on the source.
37121c1c48aSSascha Wildner 		 */
372f9602a12SMatthew Dillon 		if (is_dir("%s%s", a->os_root, src) ||
373f9602a12SMatthew Dillon 		    is_file("%s%s", a->os_root, src)) {
37421c1c48aSSascha Wildner 			cmd = command_add(cmds, "%s%s %s%s %smnt%s",
37521c1c48aSSascha Wildner 			    a->os_root, cmd_name(a, "CPDUP"),
37621c1c48aSSascha Wildner 			    a->os_root, src,
37721c1c48aSSascha Wildner 			    a->os_root, dest);
37821c1c48aSSascha Wildner 			command_set_log_mode(cmd, COMMAND_LOG_QUIET);
37921c1c48aSSascha Wildner 		}
38021c1c48aSSascha Wildner 	}
38121c1c48aSSascha Wildner 
38221c1c48aSSascha Wildner 	/*
38321c1c48aSSascha Wildner 	 * Now, because cpdup does not cross mount points,
38421c1c48aSSascha Wildner 	 * we must copy anything that the user might've made a
38521c1c48aSSascha Wildner 	 * seperate mount point for (e.g. /usr/libdata/lint.)
38621c1c48aSSascha Wildner 	 */
387f9602a12SMatthew Dillon 	nfsidx = 0;
388f9602a12SMatthew Dillon 	sp = NULL;
389f9602a12SMatthew Dillon 	spnext = slice_subpartition_first(storage_get_selected_slice(a->s));
390f9602a12SMatthew Dillon 
391f9602a12SMatthew Dillon 	for (;;) {
392f9602a12SMatthew Dillon 		const char *mountpt;
393f9602a12SMatthew Dillon 
394f9602a12SMatthew Dillon 		/*
395f9602a12SMatthew Dillon 		 * Iterate nullfs mounts and then partitions
396f9602a12SMatthew Dillon 		 */
397f9602a12SMatthew Dillon 		if (nullfs_mountpt[nfsidx]) {
398f9602a12SMatthew Dillon 			mountpt = nullfs_mountpt[nfsidx];
399f9602a12SMatthew Dillon 			++nfsidx;
400f9602a12SMatthew Dillon 		} else {
401f9602a12SMatthew Dillon 			sp = spnext;
402f9602a12SMatthew Dillon 			if (sp == NULL)
403f9602a12SMatthew Dillon 				break;
404f9602a12SMatthew Dillon 			spnext = subpartition_next(sp);
405f9602a12SMatthew Dillon 			mountpt = subpartition_get_mountpoint(sp);
406f9602a12SMatthew Dillon 		}
407f9602a12SMatthew Dillon 
40821c1c48aSSascha Wildner 		/*
40921c1c48aSSascha Wildner 		 * If the subpartition is a swap subpartition or an
410761cad2fSSascha Wildner 		 * TMPFS-backed mountpoint, don't try to copy anything
41121c1c48aSSascha Wildner 		 * into it.
41221c1c48aSSascha Wildner 		 */
413f9602a12SMatthew Dillon 		if (sp) {
414f9602a12SMatthew Dillon 			if (subpartition_is_swap(sp) ||
415f9602a12SMatthew Dillon 			    subpartition_is_tmpfsbacked(sp)) {
41621c1c48aSSascha Wildner 				continue;
417f9602a12SMatthew Dillon 			}
418f9602a12SMatthew Dillon 		}
41921c1c48aSSascha Wildner 
42021c1c48aSSascha Wildner 		/*
42121c1c48aSSascha Wildner 		 * If the mountpoint doesn't even exist on the installation
42221c1c48aSSascha Wildner 		 * medium, don't try to copy anything from it!  We assume
42321c1c48aSSascha Wildner 		 * it's an empty subpartition for the user's needs.
42421c1c48aSSascha Wildner 		 */
425f9602a12SMatthew Dillon 		if (!is_dir("%s%s", a->os_root, mountpt + 1))
42621c1c48aSSascha Wildner 			continue;
42721c1c48aSSascha Wildner 
42821c1c48aSSascha Wildner 		/*
42921c1c48aSSascha Wildner 		 * Don't bother copying the mountpoint IF:
43021c1c48aSSascha Wildner 		 * - we've already said to copy it, or something besides it
43121c1c48aSSascha Wildner 		 *   (it's a prefix of something in cp_src); or
43221c1c48aSSascha Wildner 		 * - we haven't said to copy it
43321c1c48aSSascha Wildner 		 *   (nothing in cp_src is a prefix of it.)
43421c1c48aSSascha Wildner 		 */
43521c1c48aSSascha Wildner 		seen_it = 0;
43621c1c48aSSascha Wildner 		prefix = 0;
43721c1c48aSSascha Wildner 		for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) {
438f9602a12SMatthew Dillon 			if (strncmp(mountpt, cp_src[i],
439f9602a12SMatthew Dillon 			    strlen(mountpt)) == 0) {
44021c1c48aSSascha Wildner 				seen_it = 1;
44121c1c48aSSascha Wildner 				break;
44221c1c48aSSascha Wildner 			}
443f9602a12SMatthew Dillon 			if (strncmp(cp_src[i], mountpt, strlen(cp_src[i])) == 0) {
44421c1c48aSSascha Wildner 				prefix = 1;
44521c1c48aSSascha Wildner 			}
44621c1c48aSSascha Wildner 		}
44721c1c48aSSascha Wildner 		if (seen_it || !prefix)
44821c1c48aSSascha Wildner 			continue;
44921c1c48aSSascha Wildner 
45021c1c48aSSascha Wildner 		/*
45121c1c48aSSascha Wildner 		 * Otherwise, cpdup the subpartition.
45221c1c48aSSascha Wildner 		 *
45321c1c48aSSascha Wildner 		 * XXX check for .hdd-extended source dirs here, too,
45421c1c48aSSascha Wildner 		 * eventually - but for now, /etc.hdd will never be
45521c1c48aSSascha Wildner 		 * the kind of tricky sub-mount-within-a-mount-point
45621c1c48aSSascha Wildner 		 * that this part of the code is meant to handle.
45721c1c48aSSascha Wildner 		 */
45821c1c48aSSascha Wildner 		cmd = command_add(cmds, "%s%s %s%s %smnt%s",
45921c1c48aSSascha Wildner 			a->os_root, cmd_name(a, "CPDUP"),
460f9602a12SMatthew Dillon 			a->os_root, mountpt + 1,
461f9602a12SMatthew Dillon 			a->os_root, mountpt);
46221c1c48aSSascha Wildner 		command_set_log_mode(cmd, COMMAND_LOG_QUIET);
46321c1c48aSSascha Wildner 	}
46421c1c48aSSascha Wildner 
46521c1c48aSSascha Wildner 	/*
466*9758d73aSSascha Wildner 	 * XXX This should not be needed. It was added to fix /var/run/sem
467*9758d73aSSascha Wildner 	 *     issues, see d4c25c30fc5f9ffeb258150a9590ef56954435bb.
468*9758d73aSSascha Wildner 	 *
469d4c25c30SSascha Wildner 	 * Ensure /var has all directories it needs.
470d4c25c30SSascha Wildner 	 */
471*9758d73aSSascha Wildner 	command_add(cmds, "%s%s -deiU -f %setc/mtree/BSD.var.dist -p %smnt/var",
472d4c25c30SSascha Wildner 	    a->os_root, cmd_name(a, "MTREE"), a->os_root, a->os_root);
473d4c25c30SSascha Wildner 
474d4c25c30SSascha Wildner 	/*
47521c1c48aSSascha Wildner 	 * Create symlinks.
47621c1c48aSSascha Wildner 	 */
47721c1c48aSSascha Wildner 
4783ab4451fSSascha Wildner 	/* Take care of /sys. */
4793ab4451fSSascha Wildner 	command_add(cmds, "%s%s -s usr/src/sys %smnt/sys",
4803ab4451fSSascha Wildner 	    a->os_root, cmd_name(a, "LN"), a->os_root);
4813ab4451fSSascha Wildner 
48221c1c48aSSascha Wildner 	/*
483f9602a12SMatthew Dillon 	 * Make sure /home exists (goes on root mount otherwise).
48421c1c48aSSascha Wildner 	 */
485f9602a12SMatthew Dillon 	command_add(cmds, "%s%s -p %smnt/home",
48621c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "MKDIR"), a->os_root);
48721c1c48aSSascha Wildner 
48821c1c48aSSascha Wildner 	/*
48921c1c48aSSascha Wildner 	 * XXX check for other possible combinations too?
49021c1c48aSSascha Wildner 	 */
49121c1c48aSSascha Wildner 
49221c1c48aSSascha Wildner 	/*
49321c1c48aSSascha Wildner 	 * Clean up.  In case some file didn't make it, use rm -f
49421c1c48aSSascha Wildner 	 */
49521c1c48aSSascha Wildner 	command_add(cmds, "%s%s -f %smnt/boot/loader.conf",
49621c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "RM"), a->os_root);
49721c1c48aSSascha Wildner 	command_add(cmds, "%s%s -f %smnt/tmp/install.log",
49821c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "RM"), a->os_root);
49988cfb1f7SSascha Wildner 	command_add(cmds, "%s%s -f %smnt/tmp/t[12]",
50088cfb1f7SSascha Wildner 	    a->os_root, cmd_name(a, "RM"), a->os_root);
50188cfb1f7SSascha Wildner 	command_add(cmds, "%s%s -f %smnt/tmp/test_in",
50288cfb1f7SSascha Wildner 	    a->os_root, cmd_name(a, "RM"), a->os_root);
50388cfb1f7SSascha Wildner 	command_add(cmds, "%s%s -f %smnt/tmp/test_out",
50488cfb1f7SSascha Wildner 	    a->os_root, cmd_name(a, "RM"), a->os_root);
50521c1c48aSSascha Wildner 
50621c1c48aSSascha Wildner 	/*
50721c1c48aSSascha Wildner 	 * Copy pristine versions over any files we might have installed.
50821c1c48aSSascha Wildner 	 * This allows the resulting file tree to be customized.
50921c1c48aSSascha Wildner 	 */
51021c1c48aSSascha Wildner 	for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) {
51121c1c48aSSascha Wildner 		char *src, *dest, *dn, *tmp_dest;
51221c1c48aSSascha Wildner 
51321c1c48aSSascha Wildner 		src = cp_src[i];
51421c1c48aSSascha Wildner 		dest = cp_src[i];
51521c1c48aSSascha Wildner 
51621c1c48aSSascha Wildner 		/*
51721c1c48aSSascha Wildner 		 * Get the directory that the desired thing to
51821c1c48aSSascha Wildner 		 * copy resides in.
51921c1c48aSSascha Wildner 		 */
52021c1c48aSSascha Wildner 		tmp_dest = aura_strdup(dest);
52121c1c48aSSascha Wildner 		dn = dirname(tmp_dest);
52221c1c48aSSascha Wildner 
52321c1c48aSSascha Wildner 		/*
52421c1c48aSSascha Wildner 		 * If this dir doesn't exist in PRISTINE_DIR
52521c1c48aSSascha Wildner 		 * on the install media, just skip it.
52621c1c48aSSascha Wildner 		 */
52721c1c48aSSascha Wildner 		if (!is_dir("%s%s%s", a->os_root, PRISTINE_DIR, dn)) {
52821c1c48aSSascha Wildner 			aura_free(tmp_dest, _("directory name"));
52921c1c48aSSascha Wildner 			continue;
53021c1c48aSSascha Wildner 		}
53121c1c48aSSascha Wildner 
53221c1c48aSSascha Wildner 		/*
53321c1c48aSSascha Wildner 		 * Create intermediate directories, if needed.
53421c1c48aSSascha Wildner 		 */
53521c1c48aSSascha Wildner 		if (!is_dir("%smnt%s", a->os_root, dn)) {
53621c1c48aSSascha Wildner 			command_add(cmds, "%s%s -p %smnt%s",
53721c1c48aSSascha Wildner 			    a->os_root, cmd_name(a, "MKDIR"),
53821c1c48aSSascha Wildner 			    a->os_root, dn);
53921c1c48aSSascha Wildner 		}
54021c1c48aSSascha Wildner 		aura_free(tmp_dest, "directory name");
54121c1c48aSSascha Wildner 
54221c1c48aSSascha Wildner 		/*
54321c1c48aSSascha Wildner 		 * Cpdup the chosen file or directory onto the HDD.
54421c1c48aSSascha Wildner 		 */
54521c1c48aSSascha Wildner 		cmd = command_add(cmds, "%s%s %s%s %smnt%s",
54621c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "CPDUP"),
54721c1c48aSSascha Wildner 		    a->os_root, src,
54821c1c48aSSascha Wildner 		    a->os_root, dest);
54921c1c48aSSascha Wildner 
55021c1c48aSSascha Wildner 		cmd = command_add(cmds,
55121c1c48aSSascha Wildner 		    "%s%s %s%s%s %smnt%s",
55221c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "CPDUP"),
55321c1c48aSSascha Wildner 		    a->os_root, PRISTINE_DIR, src,
55421c1c48aSSascha Wildner 		    a->os_root, dest);
55521c1c48aSSascha Wildner 		command_set_log_mode(cmd, COMMAND_LOG_QUIET);
55621c1c48aSSascha Wildner 	}
55721c1c48aSSascha Wildner 
55821c1c48aSSascha Wildner 	/*
55921c1c48aSSascha Wildner 	 * Rebuild the user database, to get rid of any extra users
56021c1c48aSSascha Wildner 	 * from the LiveCD that aren't supposed to be installed
56121c1c48aSSascha Wildner 	 * (copying a pristine master.passwd isn't enough.)
56221c1c48aSSascha Wildner 	 */
56321c1c48aSSascha Wildner 	command_add(cmds, "%s%s -p -d %smnt/etc %smnt/etc/master.passwd",
56421c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "PWD_MKDB"), a->os_root, a->os_root);
56521c1c48aSSascha Wildner 
56673be8a18SMatthew Dillon 	/*
56773be8a18SMatthew Dillon 	 * Create missing directories for special mounts.
56873be8a18SMatthew Dillon 	 */
56921c1c48aSSascha Wildner 	command_add(cmds, "%s%s %smnt/proc",
57021c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "MKDIR"), a->os_root);
57173be8a18SMatthew Dillon 	command_add(cmds, "%s%s %smnt/dev",
57273be8a18SMatthew Dillon 	    a->os_root, cmd_name(a, "MKDIR"), a->os_root);
57321c1c48aSSascha Wildner 	command_add(cmds, "%s%s %smnt/mnt",
57421c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "MKDIR"), a->os_root);
57521c1c48aSSascha Wildner 
576f59b7dfaSSascha Wildner 	/* Write new fstab. */
57721c1c48aSSascha Wildner 	command_add(cmds, "%s%s '%s' >%smnt/etc/fstab",
57821c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "ECHO"),
57921c1c48aSSascha Wildner 	    "# Device\t\tMountpoint\tFStype\tOptions\t\tDump\tPass#",
58021c1c48aSSascha Wildner 	    a->os_root);
58121c1c48aSSascha Wildner 
58221c1c48aSSascha Wildner 	for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
58321c1c48aSSascha Wildner 	     sp != NULL; sp = subpartition_next(sp)) {
58421c1c48aSSascha Wildner 		if (strcmp(subpartition_get_mountpoint(sp), "swap") == 0) {
5854bcdd60eSSascha Wildner 			command_add(cmds, "%s%s '/dev/%s\t\tnone\t\tswap\tsw\t\t0\t0' >>%smnt/etc/fstab",
58621c1c48aSSascha Wildner 			    a->os_root, cmd_name(a, "ECHO"),
58788cfb1f7SSascha Wildner 			    subpartition_is_encrypted(sp) ?
58888cfb1f7SSascha Wildner 			    "mapper/swap" : subpartition_get_device_name(sp),
58988cfb1f7SSascha Wildner 			    a->os_root);
590e2ce1af2SSascha Wildner 			if (subpartition_is_encrypted(sp)) {
591e2ce1af2SSascha Wildner 				command_add(cmds,
592e2ce1af2SSascha Wildner 				    "%s%s 'swap\t/dev/%s\tnone\tnone' >>%smnt/etc/crypttab",
59388cfb1f7SSascha Wildner 				    a->os_root, cmd_name(a, "ECHO"),
5944bcdd60eSSascha Wildner 				    subpartition_get_device_name(sp),
59521c1c48aSSascha Wildner 				    a->os_root);
596e2ce1af2SSascha Wildner 			}
59721c1c48aSSascha Wildner 		} else {
598f9602a12SMatthew Dillon 			const char *fsname;
599f9602a12SMatthew Dillon 			int order;
600f9602a12SMatthew Dillon 
601f9602a12SMatthew Dillon 			/*
602f9602a12SMatthew Dillon 			 * fs type (/boot is always ufs)
603f9602a12SMatthew Dillon 			 */
604f9602a12SMatthew Dillon 			if (strcmp(subpartition_get_mountpoint(sp), "/boot") == 0)
605f9602a12SMatthew Dillon 				fsname = "ufs";
606e90c1ebbSMatthew Dillon 			else if (use_hammer == 2)
607e90c1ebbSMatthew Dillon 				fsname = "hammer2";
608f9602a12SMatthew Dillon 			else if (use_hammer)
609f9602a12SMatthew Dillon 				fsname = "hammer";
610f9602a12SMatthew Dillon 			else
611f9602a12SMatthew Dillon 				fsname = "ufs";
612f9602a12SMatthew Dillon 
613f9602a12SMatthew Dillon 			if (strcmp(subpartition_get_mountpoint(sp), "/") == 0)
614f9602a12SMatthew Dillon 				order = 1;
615f9602a12SMatthew Dillon 			else
616f9602a12SMatthew Dillon 				order = 2;
617f9602a12SMatthew Dillon 
618f9602a12SMatthew Dillon 			/*
619f9602a12SMatthew Dillon 			 * Adjust loader.conf for root partition
620f9602a12SMatthew Dillon 			 */
62121c1c48aSSascha Wildner 			if (strcmp(subpartition_get_mountpoint(sp), "/") == 0) {
62288cfb1f7SSascha Wildner 				if (subpartition_is_encrypted(sp)) {
62388cfb1f7SSascha Wildner 					command_add(cmds,
62488cfb1f7SSascha Wildner 					    "%s%s 'vfs.root.mountfrom=\"ufs:md0s0\"' >>%smnt/boot/loader.conf",
62588cfb1f7SSascha Wildner 					    a->os_root, cmd_name(a, "ECHO"),
62688cfb1f7SSascha Wildner 					    a->os_root);
62788cfb1f7SSascha Wildner 					command_add(cmds,
628f9602a12SMatthew Dillon 					    "%s%s 'vfs.root.realroot=\"crypt:%s:%s:%s\"' >>%smnt/boot/loader.conf",
629e6847d54SSascha Wildner 					    a->os_root, cmd_name(a, "ECHO"),
630f9602a12SMatthew Dillon 					    fsname,
631e6847d54SSascha Wildner 					    subpartition_get_device_name(sp),
6320c941bc8SSascha Wildner 					    subpartition_get_mapper_name(sp, -1),
633e6847d54SSascha Wildner 					    a->os_root);
63488cfb1f7SSascha Wildner 				} else {
63588cfb1f7SSascha Wildner 					command_add(cmds,
636f9602a12SMatthew Dillon 					    "%s%s 'vfs.root.mountfrom=\"%s:%s\"' >>%smnt/boot/loader.conf",
63788cfb1f7SSascha Wildner 					    a->os_root, cmd_name(a, "ECHO"),
638f9602a12SMatthew Dillon 					    fsname,
63988cfb1f7SSascha Wildner 					    subpartition_get_device_name(sp),
64088cfb1f7SSascha Wildner 					    a->os_root);
64188cfb1f7SSascha Wildner 				}
642f9602a12SMatthew Dillon 			}
643f9602a12SMatthew Dillon 			if (subpartition_is_tmpfsbacked(sp)) {
644f9602a12SMatthew Dillon 				command_add(cmds, "%s%s 'tmpfs\t\t\t%s\t\ttmpfs\trw,-s%luM\t1\t1' >>%smnt/etc/fstab",
645f9602a12SMatthew Dillon 				    a->os_root, cmd_name(a, "ECHO"),
646f9602a12SMatthew Dillon 				    subpartition_get_mountpoint(sp),
647f9602a12SMatthew Dillon 				    subpartition_get_capacity(sp),
648f9602a12SMatthew Dillon 				    a->os_root);
649f9602a12SMatthew Dillon 			} else if (subpartition_is_encrypted(sp)) {
6500c941bc8SSascha Wildner 				if (strcmp(subpartition_get_mapper_name(sp, -1), "root") != 0) {
651f9602a12SMatthew Dillon 					command_add(cmds, "%s%s '%s\t/dev/%s\tnone\tnone' >>%smnt/etc/crypttab",
652f9602a12SMatthew Dillon 					    a->os_root, cmd_name(a, "ECHO"),
6530c941bc8SSascha Wildner 					    subpartition_get_mapper_name(sp, -1),
654f9602a12SMatthew Dillon 					    subpartition_get_device_name(sp),
655f9602a12SMatthew Dillon 					    a->os_root);
65675132aa2SSascha Wildner 				}
657f9602a12SMatthew Dillon 				command_add(cmds, "%s%s '/dev/%s\t\t%s\t\t%s\trw\t\t2\t2' >>%smnt/etc/fstab",
658f9602a12SMatthew Dillon 				    a->os_root, cmd_name(a, "ECHO"),
6590c941bc8SSascha Wildner 				    subpartition_get_mapper_name(sp, 0),
660f9602a12SMatthew Dillon 				    subpartition_get_mountpoint(sp),
661f9602a12SMatthew Dillon 				    fsname,
662f9602a12SMatthew Dillon 				    a->os_root);
663f9602a12SMatthew Dillon 			} else {
664f9602a12SMatthew Dillon 				command_add(cmds, "%s%s '/dev/%s\t\t%s\t\t%s\trw\t\t%d\t%d' >>%smnt/etc/fstab",
66521c1c48aSSascha Wildner 				    a->os_root, cmd_name(a, "ECHO"),
6664bcdd60eSSascha Wildner 				    subpartition_get_device_name(sp),
66721c1c48aSSascha Wildner 				    subpartition_get_mountpoint(sp),
668f9602a12SMatthew Dillon 				    fsname,
669f9602a12SMatthew Dillon 				    order, order,
67021c1c48aSSascha Wildner 				    a->os_root);
67121c1c48aSSascha Wildner 			}
67221c1c48aSSascha Wildner 		}
67321c1c48aSSascha Wildner 	}
67421c1c48aSSascha Wildner 
67521c1c48aSSascha Wildner 	/*
676f9602a12SMatthew Dillon 	 * Take care of NULL mounts from /build for things like /var/crash
677f9602a12SMatthew Dillon 	 * and /usr/obj if not specified as a discrete partition.
67821c1c48aSSascha Wildner 	 */
679f9602a12SMatthew Dillon 	for (j = 0; nullfs_mountpt[j] != NULL; j++) {
680f9602a12SMatthew Dillon 		if (subpartition_find(storage_get_selected_slice(a->s),
68102f3d2d0Szrj 				      "%s", nullfs_mountpt[j]) != NULL) {
682f9602a12SMatthew Dillon 			continue;
68321c1c48aSSascha Wildner 		}
684f9602a12SMatthew Dillon 		command_add(cmds,
685f9602a12SMatthew Dillon 		    "%s%s '%s\t%s\t\tnull\trw\t\t0\t0' >>%smnt/etc/fstab",
686f9602a12SMatthew Dillon 		    a->os_root, cmd_name(a, "ECHO"),
687f9602a12SMatthew Dillon 		    nullfs_mountname[j],
688f9602a12SMatthew Dillon 		    nullfs_mountpt[j],
689f9602a12SMatthew Dillon 		    a->os_root);
69021c1c48aSSascha Wildner 	}
69121c1c48aSSascha Wildner 
692f9602a12SMatthew Dillon 	/*
693f9602a12SMatthew Dillon 	 * Take care of /tmp as a tmpfs filesystem
694f9602a12SMatthew Dillon 	 */
695f9602a12SMatthew Dillon 	if (subpartition_find(storage_get_selected_slice(a->s), "/tmp") == NULL) {
696f9602a12SMatthew Dillon 		command_add(cmds,
697f9602a12SMatthew Dillon 		    "%s%s 'tmpfs\t/tmp\t\ttmpfs\trw\t\t0\t0' >>%smnt/etc/fstab",
698f9602a12SMatthew Dillon 		    a->os_root, cmd_name(a, "ECHO"), a->os_root);
699f9602a12SMatthew Dillon 	}
700f9602a12SMatthew Dillon 
701f9602a12SMatthew Dillon 	/*
702f9602a12SMatthew Dillon 	 * Take care of /proc
703f9602a12SMatthew Dillon 	 */
70421c1c48aSSascha Wildner 	command_add(cmds, "%s%s '%s' >>%smnt/etc/fstab",
70521c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "ECHO"),
70621c1c48aSSascha Wildner 	    "proc\t\t\t/proc\t\tprocfs\trw\t\t0\t0",
70721c1c48aSSascha Wildner 	    a->os_root);
70821c1c48aSSascha Wildner 
70921c1c48aSSascha Wildner 	/* Backup the disklabel and the log. */
71021c1c48aSSascha Wildner 	command_add(cmds, "%s%s %s > %smnt/etc/disklabel.%s",
71121c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "DISKLABEL64"),
71221c1c48aSSascha Wildner 	    slice_get_device_name(storage_get_selected_slice(a->s)),
71321c1c48aSSascha Wildner 	    a->os_root,
71421c1c48aSSascha Wildner 	    slice_get_device_name(storage_get_selected_slice(a->s)));
71521c1c48aSSascha Wildner 
716f9602a12SMatthew Dillon #if 0
7176b8a26e2SSascha Wildner 	/* 'chflags nohistory' as needed */
7186b8a26e2SSascha Wildner 	for (j = 0; pfs_mountpt[j] != NULL; j++)
7196b8a26e2SSascha Wildner 		if (pfs_nohistory[j] == 1)
7206b8a26e2SSascha Wildner 			command_add(cmds, "%s%s -R nohistory %smnt%s",
7216b8a26e2SSascha Wildner 			    a->os_root, cmd_name(a, "CHFLAGS"),
7226b8a26e2SSascha Wildner 			    a->os_root, pfs_mountpt[j]);
723f9602a12SMatthew Dillon #endif
7246b8a26e2SSascha Wildner 
72588cfb1f7SSascha Wildner 	/* Do some preparation if encrypted partitions were configured */
72688cfb1f7SSascha Wildner 	if (needcrypt) {
72788cfb1f7SSascha Wildner 		command_add(cmds,
72888cfb1f7SSascha Wildner 		    "%s%s 'dm_load=\"yes\"' >>%smnt/boot/loader.conf",
72988cfb1f7SSascha Wildner 		    a->os_root, cmd_name(a, "ECHO"),
73088cfb1f7SSascha Wildner 		    a->os_root);
731bff42f93SAlex Hornung 		command_add(cmds,
732bff42f93SAlex Hornung 		    "%s%s 'dm_target_crypt_load=\"yes\"' >>%smnt/boot/loader.conf",
733bff42f93SAlex Hornung 		    a->os_root, cmd_name(a, "ECHO"),
734bff42f93SAlex Hornung 		    a->os_root);
73588cfb1f7SSascha Wildner 		command_add(cmds,
73688cfb1f7SSascha Wildner 		    "%s%s 'initrd.img_load=\"YES\"' >>%smnt/boot/loader.conf",
73788cfb1f7SSascha Wildner 		    a->os_root, cmd_name(a, "ECHO"),
73888cfb1f7SSascha Wildner 		    a->os_root);
73988cfb1f7SSascha Wildner 		command_add(cmds,
74088cfb1f7SSascha Wildner 		    "%s%s 'initrd.img_type=\"md_image\"' >>%smnt/boot/loader.conf",
74188cfb1f7SSascha Wildner 		    a->os_root, cmd_name(a, "ECHO"),
74288cfb1f7SSascha Wildner 		    a->os_root);
74388cfb1f7SSascha Wildner 	}
74488cfb1f7SSascha Wildner 
74521c1c48aSSascha Wildner 	/* Customize stuff here */
74659b733d3SSascha Wildner 	if(is_file("%susr/local/bin/after_installation_routines.sh", a->os_root)) {
74721c1c48aSSascha Wildner 		command_add(cmds, "%susr/local/bin/after_installation_routines.sh",
74859b733d3SSascha Wildner 		    a->os_root);
74921c1c48aSSascha Wildner 	}
75021c1c48aSSascha Wildner 
75161f1dc6aSSascha Wildner 	/* Save the installation log. */
75261f1dc6aSSascha Wildner 	command_add(cmds, "%s%s %sinstall.log %smnt/var/log/install.log",
75361f1dc6aSSascha Wildner 	    a->os_root, cmd_name(a, "CP"),
75461f1dc6aSSascha Wildner 	    a->tmp, a->os_root);
75561f1dc6aSSascha Wildner 	command_add(cmds, "%s%s 600 %smnt/var/log/install.log",
75661f1dc6aSSascha Wildner 	    a->os_root, cmd_name(a, "CHMOD"), a->os_root);
75761f1dc6aSSascha Wildner 
75821c1c48aSSascha Wildner 	/*
75921c1c48aSSascha Wildner 	 * Do it!
76021c1c48aSSascha Wildner 	 */
7618c0b6c44SSascha Wildner 	/* commands_preview(a->c, cmds); */
76221c1c48aSSascha Wildner 	if (!commands_execute(a, cmds)) {
76321c1c48aSSascha Wildner 		inform(a->c, _("%s was not fully installed."), OPERATING_SYSTEM_NAME);
76421c1c48aSSascha Wildner 		a->result = 0;
76521c1c48aSSascha Wildner 	} else {
76621c1c48aSSascha Wildner 		a->result = 1;
76721c1c48aSSascha Wildner 	}
76821c1c48aSSascha Wildner 	commands_free(cmds);
7691c142c35SSascha Wildner 	cmds = commands_new();
7701c142c35SSascha Wildner 
7711c142c35SSascha Wildner 	if (a->result) {
7721c142c35SSascha Wildner 		config_vars_write(rc_conf, CONFIG_TYPE_SH, "%smnt/etc/rc.conf",
7731c142c35SSascha Wildner 		    a->os_root);
7741c142c35SSascha Wildner 		config_vars_free(rc_conf);
7751c142c35SSascha Wildner 		rc_conf = config_vars_new();
7761c142c35SSascha Wildner 	}
77721c1c48aSSascha Wildner 
77821c1c48aSSascha Wildner 	/*
77921c1c48aSSascha Wildner 	 * Unmount everything we mounted on /mnt.  This is done in a seperate
78021c1c48aSSascha Wildner 	 * command chain, so that partitions are unmounted, even if an error
78121c1c48aSSascha Wildner 	 * occurs in one of the preceding commands, or it is cancelled.
78221c1c48aSSascha Wildner 	 */
783f9602a12SMatthew Dillon 	unmount_altfs(a, cmds);
78421c1c48aSSascha Wildner 	unmount_all_under(a, cmds, "%smnt", a->os_root);
78521c1c48aSSascha Wildner 
78621c1c48aSSascha Wildner 	/*
78721c1c48aSSascha Wildner 	 * Once everything is unmounted, if the install went successfully,
78821c1c48aSSascha Wildner 	 * make sure once and for all that the disklabel is bootable.
78921c1c48aSSascha Wildner 	 */
790b5cb2d94SSascha Wildner 	if (a->result)
79121c1c48aSSascha Wildner 		command_add(cmds, "%s%s -B %s",
79221c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "DISKLABEL64"),
79321c1c48aSSascha Wildner 		    slice_get_device_name(storage_get_selected_slice(a->s)));
79421c1c48aSSascha Wildner 
79521c1c48aSSascha Wildner 	if (!commands_execute(a, cmds))
79621c1c48aSSascha Wildner 		inform(a->c, _("Warning: subpartitions were not correctly unmounted."));
79721c1c48aSSascha Wildner 
79821c1c48aSSascha Wildner 	commands_free(cmds);
7999687cd27SSascha Wildner 
8009687cd27SSascha Wildner 	/*
801fa419eaeSSascha Wildner 	 * Finally, remove all swap and any mappings.
8029687cd27SSascha Wildner 	 */
8039687cd27SSascha Wildner 	if (swapoff_all(a) == NULL)
8049687cd27SSascha Wildner 		inform(a->c, _("Warning: swap could not be turned off."));
805fa419eaeSSascha Wildner 	if (remove_all_mappings(a) == NULL)
806fa419eaeSSascha Wildner 		inform(a->c, _("Warning: mappings could not be removed."));
80721c1c48aSSascha Wildner }
808