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