#include <libgen.h>
#include <string.h>
#define SOURCES_CONF_FILE "usr/share/installer/sources.conf"
#ifdef ENABLE_NLS
#include <libintl.h>
#define _(String) gettext (String)
#else
#define _(String) (String)
#endif
#include "libaura/mem.h"
#include "libaura/buffer.h"
#include "libaura/fspred.h"
#include "libdfui/dfui.h"
#include "libdfui/system.h"
#include "libinstaller/commands.h"
#include "libinstaller/confed.h"
#include "libinstaller/diskutil.h"
#include "libinstaller/functions.h"
#include "libinstaller/uiutil.h"
#include "flow.h"
#include "pathnames.h"
#include "fn.h"
static const char *nullfs_mountpt[] = {
"/usr/obj", "/var/crash", "/var/cache",
"/var/spool", "/var/log", "/var/tmp",
NULL };
static const char *nullfs_mountname[] = {
"/build/usr.obj", "/build/var.crash", "/build/var.cache",
"/build/var.spool", "/build/var.log", "/build/var.tmp",
NULL };
static void
handle_altfs(struct i_fn_args *a, struct commands *cmds)
{
int i;
for (i = 0; nullfs_mountpt[i]; ++i) {
if (subpartition_find(storage_get_selected_slice(a->s), "%s", nullfs_mountpt[i]) != NULL)
continue;
command_add(cmds, "%s%s -p %smnt%s",
a->os_root, cmd_name(a, "MKDIR"),
a->os_root, nullfs_mountname[i]);
command_add(cmds, "%s%s -p %smnt%s",
a->os_root, cmd_name(a, "MKDIR"),
a->os_root, nullfs_mountpt[i]);
command_add(cmds, "%s%s %smnt%s %smnt%s",
a->os_root, cmd_name(a, "MOUNT_NULL"),
a->os_root, nullfs_mountname[i],
a->os_root, nullfs_mountpt[i]);
}
if (subpartition_find(storage_get_selected_slice(a->s), "%s", "/tmp") == NULL) {
command_add(cmds, "%s%s -p %smnt/tmp",
a->os_root, cmd_name(a, "MKDIR"), a->os_root);
command_add(cmds, "%s%s 1777 %smnt/tmp",
a->os_root, cmd_name(a, "CHMOD"), a->os_root);
command_add(cmds, "%s%s dummy %smnt/tmp",
a->os_root, cmd_name(a, "MOUNT_TMPFS"), a->os_root);
}
}
static void
unmount_altfs(struct i_fn_args *a __unused, struct commands *cmds __unused)
{
return;
#if 0
int i;
i = sizeof(nullfs_mountpt) / sizeof(nullfs_mountpt[0]) - 1;
while (i >= 0) {
if (subpartition_find(storage_get_selected_slice(a->s), "%s", nullfs_mountpt[i]) != NULL)
continue;
command_add(cmds, "%s%s %smnt%s",
a->os_root, cmd_name(a, "UMOUNT"),
a->os_root, nullfs_mountpt[i]);
--i;
}
if (subpartition_find(storage_get_selected_slice(a->s), "%s", "/tmp") == NULL) {
command_add(cmds, "%s%s -p %smnt%s",
a->os_root, cmd_name(a, "UMOUNT"),
a->os_root, "/tmp");
}
#endif
}
void
fn_install_os(struct i_fn_args *a)
{
struct subpartition *sp, *spnext;
struct commands *cmds;
struct command *cmd;
int i, seen_it, prefix, j, needcrypt;
FILE *sources_conf;
char line[256];
char cp_src[64][256];
char file_path[256];
char *string;
int lines = 0;
int nfsidx;
snprintf(file_path, 256, "%s%s", a->os_root, SOURCES_CONF_FILE);
sources_conf = fopen(file_path, "r");
i_log(a, "Reading %s", file_path);
while(fgets(line, 256, sources_conf) != NULL && lines < 63) {
if(strlen(line)>0)
line[strlen(line)-1] = '\0';
strlcpy(cp_src[lines], line, 256);
i_log(a,"Adding %s to copy source table.", cp_src[lines]);
lines++;
}
i_log(a,"Added %i total items to copy source table.", lines);
strcpy(cp_src[lines], "");
fclose(sources_conf);
cmds = commands_new();
if (measure_activated_swap(a) == 0) {
for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
sp != NULL; sp = subpartition_next(sp)) {
if (!subpartition_is_swap(sp))
continue;
command_add(cmds, "%s%s /dev/%s",
a->os_root,
cmd_name(a, "SWAPON"),
subpartition_is_encrypted(sp) ?
"mapper/swap" : subpartition_get_device_name(sp));
}
}
unmount_altfs(a, cmds);
unmount_all_under(a, cmds, "%smnt", a->os_root);
needcrypt = 0;
for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
sp != NULL; sp = subpartition_next(sp)) {
if (subpartition_is_encrypted(sp)) {
needcrypt = 1;
break;
}
}
for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
sp != NULL; sp = subpartition_next(sp)) {
if (strcmp(subpartition_get_mountpoint(sp), "/") == 0 ||
strcmp(subpartition_get_mountpoint(sp), "/build") == 0) {
command_add(cmds, "%s%s -p %smnt%s",
a->os_root, cmd_name(a, "MKDIR"),
a->os_root,
subpartition_get_mountpoint(sp));
switch(use_hammer) {
case 1:
command_add(cmds, "%s%s /dev/%s %smnt%s",
a->os_root, cmd_name(a, "MOUNT_HAMMER"),
(subpartition_is_encrypted(sp) ?
subpartition_get_mapper_name(sp, 0) :
subpartition_get_device_name(sp)),
a->os_root,
subpartition_get_mountpoint(sp));
break;
case 2:
command_add(cmds, "%s%s /dev/%s %smnt%s",
a->os_root, cmd_name(a, "MOUNT_HAMMER2"),
(subpartition_is_encrypted(sp) ?
subpartition_get_mapper_name(sp, 0) :
subpartition_get_device_name(sp)),
a->os_root,
subpartition_get_mountpoint(sp));
break;
case 0:
default:
command_add(cmds, "%s%s /dev/%s %smnt%s",
a->os_root, cmd_name(a, "MOUNT"),
(subpartition_is_encrypted(sp) ?
subpartition_get_mapper_name(sp, 0) :
subpartition_get_device_name(sp)),
a->os_root,
subpartition_get_mountpoint(sp));
break;
}
}
}
for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
sp != NULL; sp = subpartition_next(sp)) {
if (subpartition_is_swap(sp)) {
command_add(cmds, "%s%s off",
a->os_root, cmd_name(a, "DUMPON"));
command_add(cmds, "%s%s -v /dev/%s",
a->os_root, cmd_name(a, "DUMPON"),
subpartition_is_encrypted(sp) ?
"mapper/swap" : subpartition_get_device_name(sp));
asprintf(&string, "/dev/%s",
subpartition_is_encrypted(sp) ?
"mapper/swap" : subpartition_get_device_name(sp));
config_var_set(rc_conf, "dumpdev", string);
free(string);
continue;
}
if (strcmp(subpartition_get_mountpoint(sp), "/") != 0 &&
strcmp(subpartition_get_mountpoint(sp), "/build") != 0) {
command_add(cmds, "%s%s -p %smnt%s",
a->os_root, cmd_name(a, "MKDIR"),
a->os_root,
subpartition_get_mountpoint(sp));
if (subpartition_is_tmpfsbacked(sp))
continue;
command_add(cmds, "%s%s /dev/%s %smnt%s",
a->os_root, cmd_name(a, "MOUNT"),
(subpartition_is_encrypted(sp) ?
subpartition_get_mapper_name(sp, 0) :
subpartition_get_device_name(sp)),
a->os_root,
subpartition_get_mountpoint(sp));
}
}
handle_altfs(a, cmds);
for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) {
char *src, *dest, *dn, *tmp_dest;
dest = cp_src[i];
sp = subpartition_of(storage_get_selected_slice(a->s),
"%s%s", a->os_root, &dest[1]);
if (sp != NULL && subpartition_is_tmpfsbacked(sp)) {
continue;
}
tmp_dest = aura_strdup(dest);
dn = dirname(tmp_dest);
if (is_dir("%s%s", a->os_root, &dn[1]) &&
!is_dir("%smnt%s", a->os_root, dn)) {
command_add(cmds, "%s%s -p %smnt%s",
a->os_root, cmd_name(a, "MKDIR"),
a->os_root, dn);
}
aura_free(tmp_dest, "directory name");
if (is_dir("%s%s.hdd", a->os_root, &dest[1]))
asprintf(&src, "%s.hdd", &dest[1]);
else
asprintf(&src, "%s", &dest[1]);
if (is_dir("%s%s", a->os_root, src) ||
is_file("%s%s", a->os_root, src)) {
cmd = command_add(cmds, "%s%s %s%s %smnt%s",
a->os_root, cmd_name(a, "CPDUP"),
a->os_root, src,
a->os_root, dest);
command_set_log_mode(cmd, COMMAND_LOG_QUIET);
}
}
nfsidx = 0;
sp = NULL;
spnext = slice_subpartition_first(storage_get_selected_slice(a->s));
for (;;) {
const char *mountpt;
if (nullfs_mountpt[nfsidx]) {
mountpt = nullfs_mountpt[nfsidx];
++nfsidx;
} else {
sp = spnext;
if (sp == NULL)
break;
spnext = subpartition_next(sp);
mountpt = subpartition_get_mountpoint(sp);
}
if (sp) {
if (subpartition_is_swap(sp) ||
subpartition_is_tmpfsbacked(sp)) {
continue;
}
}
if (!is_dir("%s%s", a->os_root, mountpt + 1))
continue;
seen_it = 0;
prefix = 0;
for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) {
if (strncmp(mountpt, cp_src[i],
strlen(mountpt)) == 0) {
seen_it = 1;
break;
}
if (strncmp(cp_src[i], mountpt, strlen(cp_src[i])) == 0) {
prefix = 1;
}
}
if (seen_it || !prefix)
continue;
cmd = command_add(cmds, "%s%s %s%s %smnt%s",
a->os_root, cmd_name(a, "CPDUP"),
a->os_root, mountpt + 1,
a->os_root, mountpt);
command_set_log_mode(cmd, COMMAND_LOG_QUIET);
}
command_add(cmds, "%s%s -deiU -f %setc/mtree/BSD.var.dist -p %smnt/var",
a->os_root, cmd_name(a, "MTREE"), a->os_root, a->os_root);
command_add(cmds, "%s%s -s usr/src/sys %smnt/sys",
a->os_root, cmd_name(a, "LN"), a->os_root);
command_add(cmds, "%s%s -p %smnt/home",
a->os_root, cmd_name(a, "MKDIR"), a->os_root);
command_add(cmds, "%s%s -f %smnt/boot/loader.conf",
a->os_root, cmd_name(a, "RM"), a->os_root);
command_add(cmds, "%s%s -f %smnt/tmp/install.log",
a->os_root, cmd_name(a, "RM"), a->os_root);
command_add(cmds, "%s%s -f %smnt/tmp/t[12]",
a->os_root, cmd_name(a, "RM"), a->os_root);
command_add(cmds, "%s%s -f %smnt/tmp/test_in",
a->os_root, cmd_name(a, "RM"), a->os_root);
command_add(cmds, "%s%s -f %smnt/tmp/test_out",
a->os_root, cmd_name(a, "RM"), a->os_root);
for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) {
char *src, *dest, *dn, *tmp_dest;
src = cp_src[i];
dest = cp_src[i];
tmp_dest = aura_strdup(dest);
dn = dirname(tmp_dest);
if (!is_dir("%s%s%s", a->os_root, PRISTINE_DIR, dn)) {
aura_free(tmp_dest, _("directory name"));
continue;
}
if (!is_dir("%smnt%s", a->os_root, dn)) {
command_add(cmds, "%s%s -p %smnt%s",
a->os_root, cmd_name(a, "MKDIR"),
a->os_root, dn);
}
aura_free(tmp_dest, "directory name");
cmd = command_add(cmds, "%s%s %s%s %smnt%s",
a->os_root, cmd_name(a, "CPDUP"),
a->os_root, src,
a->os_root, dest);
cmd = command_add(cmds,
"%s%s %s%s%s %smnt%s",
a->os_root, cmd_name(a, "CPDUP"),
a->os_root, PRISTINE_DIR, src,
a->os_root, dest);
command_set_log_mode(cmd, COMMAND_LOG_QUIET);
}
command_add(cmds, "%s%s -p -d %smnt/etc %smnt/etc/master.passwd",
a->os_root, cmd_name(a, "PWD_MKDB"), a->os_root, a->os_root);
command_add(cmds, "%s%s %smnt/proc",
a->os_root, cmd_name(a, "MKDIR"), a->os_root);
command_add(cmds, "%s%s %smnt/dev",
a->os_root, cmd_name(a, "MKDIR"), a->os_root);
command_add(cmds, "%s%s %smnt/mnt",
a->os_root, cmd_name(a, "MKDIR"), a->os_root);
command_add(cmds, "%s%s '%s' >%smnt/etc/fstab",
a->os_root, cmd_name(a, "ECHO"),
"# Device\t\tMountpoint\tFStype\tOptions\t\tDump\tPass#",
a->os_root);
for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
sp != NULL; sp = subpartition_next(sp)) {
if (strcmp(subpartition_get_mountpoint(sp), "swap") == 0) {
command_add(cmds, "%s%s '/dev/%s\t\tnone\t\tswap\tsw\t\t0\t0' >>%smnt/etc/fstab",
a->os_root, cmd_name(a, "ECHO"),
subpartition_is_encrypted(sp) ?
"mapper/swap" : subpartition_get_device_name(sp),
a->os_root);
if (subpartition_is_encrypted(sp)) {
command_add(cmds,
"%s%s 'swap\t/dev/%s\tnone\tnone' >>%smnt/etc/crypttab",
a->os_root, cmd_name(a, "ECHO"),
subpartition_get_device_name(sp),
a->os_root);
}
} else {
const char *fsname;
int order;
if (strcmp(subpartition_get_mountpoint(sp), "/boot") == 0)
fsname = "ufs";
else if (use_hammer == 2)
fsname = "hammer2";
else if (use_hammer)
fsname = "hammer";
else
fsname = "ufs";
if (strcmp(subpartition_get_mountpoint(sp), "/") == 0)
order = 1;
else
order = 2;
if (strcmp(subpartition_get_mountpoint(sp), "/") == 0) {
if (subpartition_is_encrypted(sp)) {
command_add(cmds,
"%s%s 'vfs.root.mountfrom=\"ufs:md0s0\"' >>%smnt/boot/loader.conf",
a->os_root, cmd_name(a, "ECHO"),
a->os_root);
command_add(cmds,
"%s%s 'vfs.root.realroot=\"crypt:%s:%s:%s\"' >>%smnt/boot/loader.conf",
a->os_root, cmd_name(a, "ECHO"),
fsname,
subpartition_get_device_name(sp),
subpartition_get_mapper_name(sp, -1),
a->os_root);
} else {
command_add(cmds,
"%s%s 'vfs.root.mountfrom=\"%s:%s\"' >>%smnt/boot/loader.conf",
a->os_root, cmd_name(a, "ECHO"),
fsname,
subpartition_get_device_name(sp),
a->os_root);
}
}
if (subpartition_is_tmpfsbacked(sp)) {
command_add(cmds, "%s%s 'tmpfs\t\t\t%s\t\ttmpfs\trw,-s%luM\t1\t1' >>%smnt/etc/fstab",
a->os_root, cmd_name(a, "ECHO"),
subpartition_get_mountpoint(sp),
subpartition_get_capacity(sp),
a->os_root);
} else if (subpartition_is_encrypted(sp)) {
if (strcmp(subpartition_get_mapper_name(sp, -1), "root") != 0) {
command_add(cmds, "%s%s '%s\t/dev/%s\tnone\tnone' >>%smnt/etc/crypttab",
a->os_root, cmd_name(a, "ECHO"),
subpartition_get_mapper_name(sp, -1),
subpartition_get_device_name(sp),
a->os_root);
}
command_add(cmds, "%s%s '/dev/%s\t\t%s\t\t%s\trw\t\t2\t2' >>%smnt/etc/fstab",
a->os_root, cmd_name(a, "ECHO"),
subpartition_get_mapper_name(sp, 0),
subpartition_get_mountpoint(sp),
fsname,
a->os_root);
} else {
command_add(cmds, "%s%s '/dev/%s\t\t%s\t\t%s\trw\t\t%d\t%d' >>%smnt/etc/fstab",
a->os_root, cmd_name(a, "ECHO"),
subpartition_get_device_name(sp),
subpartition_get_mountpoint(sp),
fsname,
order, order,
a->os_root);
}
}
}
for (j = 0; nullfs_mountpt[j] != NULL; j++) {
if (subpartition_find(storage_get_selected_slice(a->s),
"%s", nullfs_mountpt[j]) != NULL) {
continue;
}
command_add(cmds,
"%s%s '%s\t%s\t\tnull\trw\t\t0\t0' >>%smnt/etc/fstab",
a->os_root, cmd_name(a, "ECHO"),
nullfs_mountname[j],
nullfs_mountpt[j],
a->os_root);
}
if (subpartition_find(storage_get_selected_slice(a->s), "/tmp") == NULL) {
command_add(cmds,
"%s%s 'tmpfs\t/tmp\t\ttmpfs\trw\t\t0\t0' >>%smnt/etc/fstab",
a->os_root, cmd_name(a, "ECHO"), a->os_root);
}
command_add(cmds, "%s%s '%s' >>%smnt/etc/fstab",
a->os_root, cmd_name(a, "ECHO"),
"proc\t\t\t/proc\t\tprocfs\trw\t\t0\t0",
a->os_root);
command_add(cmds, "%s%s %s > %smnt/etc/disklabel.%s",
a->os_root, cmd_name(a, "DISKLABEL64"),
slice_get_device_name(storage_get_selected_slice(a->s)),
a->os_root,
slice_get_device_name(storage_get_selected_slice(a->s)));
#if 0
for (j = 0; pfs_mountpt[j] != NULL; j++)
if (pfs_nohistory[j] == 1)
command_add(cmds, "%s%s -R nohistory %smnt%s",
a->os_root, cmd_name(a, "CHFLAGS"),
a->os_root, pfs_mountpt[j]);
#endif
if (needcrypt) {
command_add(cmds,
"%s%s 'dm_load=\"yes\"' >>%smnt/boot/loader.conf",
a->os_root, cmd_name(a, "ECHO"),
a->os_root);
command_add(cmds,
"%s%s 'dm_target_crypt_load=\"yes\"' >>%smnt/boot/loader.conf",
a->os_root, cmd_name(a, "ECHO"),
a->os_root);
command_add(cmds,
"%s%s 'initrd.img_load=\"YES\"' >>%smnt/boot/loader.conf",
a->os_root, cmd_name(a, "ECHO"),
a->os_root);
command_add(cmds,
"%s%s 'initrd.img_type=\"md_image\"' >>%smnt/boot/loader.conf",
a->os_root, cmd_name(a, "ECHO"),
a->os_root);
}
if(is_file("%susr/local/bin/after_installation_routines.sh", a->os_root)) {
command_add(cmds, "%susr/local/bin/after_installation_routines.sh",
a->os_root);
}
command_add(cmds, "%s%s %sinstall.log %smnt/var/log/install.log",
a->os_root, cmd_name(a, "CP"),
a->tmp, a->os_root);
command_add(cmds, "%s%s 600 %smnt/var/log/install.log",
a->os_root, cmd_name(a, "CHMOD"), a->os_root);
if (!commands_execute(a, cmds)) {
inform(a->c, _("%s was not fully installed."), OPERATING_SYSTEM_NAME);
a->result = 0;
} else {
a->result = 1;
}
commands_free(cmds);
cmds = commands_new();
if (a->result) {
config_vars_write(rc_conf, CONFIG_TYPE_SH,
"%smnt/etc/rc.conf", a->os_root);
config_vars_write(resolv_conf, CONFIG_TYPE_RESOLV,
"%smnt/etc/resolv.conf", a->os_root);
config_vars_free(rc_conf);
config_vars_free(resolv_conf);
rc_conf = config_vars_new();
resolv_conf = config_vars_new();
}
unmount_altfs(a, cmds);
unmount_all_under(a, cmds, "%smnt", a->os_root);
if (a->result)
command_add(cmds, "%s%s -B %s",
a->os_root, cmd_name(a, "DISKLABEL64"),
slice_get_device_name(storage_get_selected_slice(a->s)));
if (!commands_execute(a, cmds))
inform(a->c, _("Warning: subpartitions were not correctly unmounted."));
commands_free(cmds);
if (swapoff_all(a) == NULL)
inform(a->c, _("Warning: swap could not be turned off."));
if (remove_all_mappings(a) == NULL)
inform(a->c, _("Warning: mappings could not be removed."));
}