struct i_fn_args * i_fn_args_new(const char *os_root, const char *def_tmp_dir, const char *def_cmds_file, int transport, const char *rendezvous) { struct i_fn_args *a; char *filename; AURA_MALLOC(a, i_fn_args); a->c = NULL; a->os_root = aura_strdup(os_root); a->cfg_root = ""; a->name = ""; a->short_desc = ""; a->long_desc = ""; a->result = 0; a->log = NULL; a->s = NULL; a->tmp = NULL; a->temp_files = NULL; a->cmd_names = NULL; asprintf(&filename, "%sinstall.log", def_tmp_dir); a->log = fopen(filename, "w"); free(filename); if (a->log == NULL) { i_fn_args_free(a); return(NULL); } i_log(a, "Installer started"); i_log(a, "-----------------"); i_log(a, "+ Creating DFUI connection on ``%s''\n", rendezvous); if ((a->c = dfui_connection_new(transport, rendezvous)) == NULL) { i_log(a, "! ERROR: Couldn't create connection on ``%s''\n", rendezvous); i_fn_args_free(a); return(NULL); } i_log(a, "+ Connecting on ``%s''\n", rendezvous); if (!dfui_be_start(a->c)) { i_log(a, "! ERROR: Couldn't connect to frontend on ``%s''\n", rendezvous); i_fn_args_free(a); return(NULL); } if ((a->s = storage_new()) == NULL) { i_log(a, "! ERROR: Couldn't create storage descriptor"); i_fn_args_free(a); return(NULL); } a->tmp = def_tmp_dir; /* XXX temporarily set to this */ a->temp_files = aura_dict_new(23, AURA_DICT_HASH); a->cmd_names = config_vars_new(); if (!config_vars_read(a, a->cmd_names, CONFIG_TYPE_SH, "%s", def_cmds_file)) { i_log(a, "! ERROR: Couldn't read cmdnames config file"); i_fn_args_free(a); return(NULL); } a->tmp = cmd_name(a, "INSTALLER_TEMP"); i_log(a, "+ Starting installer state machine"); return(a); }
/* * Read from the pipe that was opened to the executing commands * and update the progress bar as data comes and (and/or as the * read from the pipe times out.) */ static int pipe_loop(struct i_fn_args *a, struct dfui_progress *pr, struct command *cmd, int *cancelled) { FILE *cmdout = NULL; struct timeval tv = { 1, 0 }; char cline[256]; char *command; pid_t pid; fd_set r; int n; asprintf(&command, "(%s) 2>&1 </dev/null", cmd->cmdline); fflush(stdout); cmdout = aura_popen(command, "r"); free(command); if (cmdout == NULL) { i_log(a, "! could not aura_popen() command"); return(COMMAND_RESULT_POPEN_ERR); } pid = aura_pgetpid(cmdout); #ifdef DEBUG fprintf(stderr, "+ pid = %d\n", pid); #endif /* * Loop, selecting on the command and a timeout. */ for (;;) { if (*cancelled) break; FD_ZERO(&r); FD_SET(fileno(cmdout), &r); n = select(fileno(cmdout) + 1, &r, NULL, NULL, &tv); #ifdef DEBUG fprintf(stderr, "+ select() = %d\n", n); #endif if (n < 0) { /* Error */ i_log(a, "! select() failed\n"); aura_pclose(cmdout); return(COMMAND_RESULT_SELECT_ERR); } else if (n == 0) { /* Timeout */ if (!dfui_be_progress_update(a->c, pr, cancelled)) abort_backend(); #ifdef DEBUG fprintf(stderr, "+ cancelled = %d\n", *cancelled); #endif } else { /* Data came in */ fgets(cline, 255, cmdout); while (strlen(cline) > 0 && cline[strlen(cline) - 1] == '\n') cline[strlen(cline) - 1] = '\0'; if (feof(cmdout)) break; if (!dfui_be_progress_update(a->c, pr, cancelled)) abort_backend(); if (cmd->log_mode == COMMAND_LOG_VERBOSE) { i_log(a, "| %s", cline); } else if (cmd->log_mode != COMMAND_LOG_SILENT) { fprintf(stderr, "| %s\n", cline); } } } if (*cancelled) { #ifdef DEBUG fprintf(stderr, "+ killing %d\n", pid); #endif n = kill(pid, SIGTERM); #ifdef DEBUG fprintf(stderr, "+ kill() = %d\n", n); #endif } #ifdef DEBUG fprintf(stderr, "+ pclosing %d\n", fileno(cmdout)); #endif n = aura_pclose(cmdout) / 256; #ifdef DEBUG fprintf(stderr, "+ pclose() = %d\n", n); #endif return(n); }
/* * Execute a single command. * Return value is a COMMAND_RESULT_* constant, or * a value from 0 to 255 to indicate the exit code * from the utility. */ static int command_execute(struct i_fn_args *a, struct dfui_progress *pr, struct command *cmd) { FILE *log = NULL; char *filename; int cancelled = 0, done = 0, report_done = 0; if (cmd->desc != NULL) dfui_info_set_short_desc(dfui_progress_get_info(pr), cmd->desc); else dfui_info_set_short_desc(dfui_progress_get_info(pr), cmd->cmdline); if (!dfui_be_progress_update(a->c, pr, &cancelled)) abort_backend(); while (!done) { asprintf(&filename, "%sinstall.log", a->tmp); log = fopen(filename, "a"); free(filename); if (cmd->log_mode != COMMAND_LOG_SILENT) i_log(a, ",-<<< Executing `%s'", cmd->cmdline); cmd->result = pipe_loop(a, pr, cmd, &cancelled); if (cmd->log_mode != COMMAND_LOG_SILENT) i_log(a, "`->>> Exit status: %d\n", cmd->result); if (log != NULL) fclose(log); if (cancelled) { if (!dfui_be_progress_end(a->c)) abort_backend(); report_done = 0; while (!report_done) { switch (dfui_be_present_dialog(a->c, "Cancelled", "View Log|Retry|Cancel|Skip", "Execution of the command\n\n%s\n\n" "was cancelled.", cmd->cmdline)) { case 1: /* View Log */ view_command_log(a); break; case 2: /* Retry */ cancelled = 0; report_done = 1; break; case 3: /* Cancel */ cmd->result = COMMAND_RESULT_CANCELLED; report_done = 1; done = 1; break; case 4: /* Skip */ cmd->result = COMMAND_RESULT_SKIPPED; report_done = 1; done = 1; break; } } if (!dfui_be_progress_begin(a->c, pr)) abort_backend(); } else if (cmd->failure_mode == COMMAND_FAILURE_IGNORE) { cmd->result = 0; done = 1; } else if (cmd->result != 0 && cmd->failure_mode != COMMAND_FAILURE_WARN) { if (!dfui_be_progress_end(a->c)) abort_backend(); report_done = 0; while (!report_done) { switch (dfui_be_present_dialog(a->c, "Command Failed!", "View Log|Retry|Cancel|Skip", "Execution of the command\n\n%s\n\n" "FAILED with a return code of %d.", cmd->cmdline, cmd->result)) { case 1: /* View Log */ view_command_log(a); break; case 2: /* Retry */ report_done = 1; break; case 3: /* Cancel */ /* XXX need a better way to retain actual result */ cmd->result = COMMAND_RESULT_CANCELLED; report_done = 1; done = 1; break; case 4: /* Skip */ /* XXX need a better way to retain actual result */ cmd->result = COMMAND_RESULT_SKIPPED; report_done = 1; done = 1; break; } } if (!dfui_be_progress_begin(a->c, pr)) abort_backend(); } else { done = 1; } } return(cmd->result); }
/* * fn_install_os: actually put DragonFly on a disk. */ void fn_install_os(struct i_fn_args *a) { struct subpartition *sp; 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; /* * Read SOURCES_CONF_FILE and populate our copy sources. */ 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 swap isn't mounted yet, mount it. */ 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 %sdev/%s", a->os_root, cmd_name(a, "SWAPON"), a->os_root, subpartition_is_encrypted(sp) ? "mapper/swap" : subpartition_get_device_name(sp)); } } /* * Unmount anything already mounted on /mnt. */ unmount_all_under(a, cmds, "%smnt", a->os_root); /* Check if crypto support is needed */ 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) { if (use_hammer == 1) { command_add(cmds, "%s%s %sdev/%s %smnt%s", a->os_root, cmd_name(a, "MOUNT_HAMMER"), a->os_root, subpartition_is_encrypted(sp) ? "mapper/root" : subpartition_get_device_name(sp), a->os_root, subpartition_get_mountpoint(sp)); } else { command_add(cmds, "%s%s %sdev/%s %smnt%s", a->os_root, cmd_name(a, "MOUNT"), a->os_root, subpartition_get_device_name(sp), a->os_root, subpartition_get_mountpoint(sp)); } } } /* * Create mount points and mount subpartitions on them. */ for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); sp != NULL; sp = subpartition_next(sp)) { if (subpartition_is_swap(sp)) { /* * Set this subpartition as the dump device. */ if (subpartition_get_capacity(sp) < storage_get_memsize(a->s)) continue; command_add(cmds, "%s%s -v %sdev/%s", a->os_root, cmd_name(a, "DUMPON"), a->os_root, 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 (use_hammer == 0) { /* / is already mounted */ if (strcmp(subpartition_get_mountpoint(sp), "/") != 0) { command_add(cmds, "%s%s -p %smnt%s", a->os_root, cmd_name(a, "MKDIR"), a->os_root, subpartition_get_mountpoint(sp)); /* Don't mount it if it's TMPFS-backed. */ if (subpartition_is_tmpfsbacked(sp)) continue; if (subpartition_is_encrypted(sp)) { command_add(cmds, "%s%s %sdev/mapper/%s %smnt%s", a->os_root, cmd_name(a, "MOUNT"), a->os_root, subpartition_get_mountpoint(sp) + 1, a->os_root, subpartition_get_mountpoint(sp)); } else { command_add(cmds, "%s%s %sdev/%s %smnt%s", a->os_root, cmd_name(a, "MOUNT"), a->os_root, subpartition_get_device_name(sp), a->os_root, subpartition_get_mountpoint(sp)); } } } else if (strcmp(subpartition_get_mountpoint(sp), "/boot") == 0) { command_add(cmds, "%s%s -p %smnt%s", a->os_root, cmd_name(a, "MKDIR"), a->os_root, subpartition_get_mountpoint(sp)); command_add(cmds, "%s%s %sdev/%s %smnt%s", a->os_root, cmd_name(a, "MOUNT"), a->os_root, subpartition_get_device_name(sp), a->os_root, subpartition_get_mountpoint(sp)); } } /* * Take care of HAMMER PFS. */ if (use_hammer == 1) handle_pfs(a, cmds); /* * Actually copy files now. */ for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) { char *src, *dest, *dn, *tmp_dest; dest = cp_src[i]; /* * If dest would be on an TMPFS-backed * mountpoint, don't bother copying it. */ sp = subpartition_of(storage_get_selected_slice(a->s), "%s%s", a->os_root, &dest[1]); if (sp != NULL && subpartition_is_tmpfsbacked(sp)) { continue; } /* * Create intermediate directories, if needed. */ 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 a directory by the same name but with the suffix * ".hdd" exists on the installation media, cpdup that * instead. This is particularly useful with /etc, which * may have significantly different behaviour on the * live CD compared to a standard HDD boot. */ 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)) { /* * Cpdup the chosen file or directory onto the HDD. * if it exists on the source. */ 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); } } /* * Now, because cpdup does not cross mount points, * we must copy anything that the user might've made a * seperate mount point for (e.g. /usr/libdata/lint.) */ for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); sp != NULL; sp = subpartition_next(sp)) { /* * If the subpartition is a swap subpartition or an * TMPFS-backed mountpoint, don't try to copy anything * into it. */ if (subpartition_is_swap(sp) || subpartition_is_tmpfsbacked(sp)) continue; /* * If the mountpoint doesn't even exist on the installation * medium, don't try to copy anything from it! We assume * it's an empty subpartition for the user's needs. */ if (!is_dir("%s%s", a->os_root, &subpartition_get_mountpoint(sp)[1])) continue; /* * Don't bother copying the mountpoint IF: * - we've already said to copy it, or something besides it * (it's a prefix of something in cp_src); or * - we haven't said to copy it * (nothing in cp_src is a prefix of it.) */ seen_it = 0; prefix = 0; for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) { if (strncmp(subpartition_get_mountpoint(sp), cp_src[i], strlen(subpartition_get_mountpoint(sp))) == 0) { seen_it = 1; break; } if (strncmp(cp_src[i], subpartition_get_mountpoint(sp), strlen(cp_src[i])) == 0) { prefix = 1; } } if (seen_it || !prefix) continue; /* * Otherwise, cpdup the subpartition. * * XXX check for .hdd-extended source dirs here, too, * eventually - but for now, /etc.hdd will never be * the kind of tricky sub-mount-within-a-mount-point * that this part of the code is meant to handle. */ cmd = command_add(cmds, "%s%s %s%s %smnt%s", a->os_root, cmd_name(a, "CPDUP"), a->os_root, &subpartition_get_mountpoint(sp)[1], a->os_root, subpartition_get_mountpoint(sp)); command_set_log_mode(cmd, COMMAND_LOG_QUIET); } /* * Create symlinks. */ /* Take care of /sys. */ command_add(cmds, "%s%s -s usr/src/sys %smnt/sys", a->os_root, cmd_name(a, "LN"), a->os_root); /* * If the user has both /var and /tmp subpartitions, * symlink /var/tmp to /tmp. */ if (subpartition_find(storage_get_selected_slice(a->s), "/tmp") != NULL && subpartition_find(storage_get_selected_slice(a->s), "/var") != NULL) { command_add(cmds, "%s%s 1777 %smnt/tmp", a->os_root, cmd_name(a, "CHMOD"), a->os_root); command_add(cmds, "%s%s -rf %smnt/var/tmp", a->os_root, cmd_name(a, "RM"), a->os_root); command_add(cmds, "%s%s -s /tmp %smnt/var/tmp", a->os_root, cmd_name(a, "LN"), a->os_root); } /* * If the user has /var, but no /tmp, * symlink /tmp to /var/tmp. */ if (subpartition_find(storage_get_selected_slice(a->s), "/tmp") == NULL && subpartition_find(storage_get_selected_slice(a->s), "/var") != NULL) { command_add(cmds, "%s%s -rf %smnt/tmp", a->os_root, cmd_name(a, "RM"), a->os_root); command_add(cmds, "%s%s -s /var/tmp %smnt/tmp", a->os_root, cmd_name(a, "LN"), a->os_root); } /* * If the user has /usr, but no /home, * symlink /home to /usr/home. */ if (subpartition_find(storage_get_selected_slice(a->s), "/home") == NULL && subpartition_find(storage_get_selected_slice(a->s), "/usr") != NULL) { command_add(cmds, "%s%s -rf %smnt/home", a->os_root, cmd_name(a, "RM"), a->os_root); command_add(cmds, "%s%s %smnt/usr/home", a->os_root, cmd_name(a, "MKDIR"), a->os_root); command_add(cmds, "%s%s -s /usr/home %smnt/home", a->os_root, cmd_name(a, "LN"), a->os_root); } /* * XXX check for other possible combinations too? */ /* * Clean up. In case some file didn't make it, use rm -f */ 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); /* * Copy pristine versions over any files we might have installed. * This allows the resulting file tree to be customized. */ 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]; /* * Get the directory that the desired thing to * copy resides in. */ tmp_dest = aura_strdup(dest); dn = dirname(tmp_dest); /* * If this dir doesn't exist in PRISTINE_DIR * on the install media, just skip it. */ if (!is_dir("%s%s%s", a->os_root, PRISTINE_DIR, dn)) { aura_free(tmp_dest, _("directory name")); continue; } /* * Create intermediate directories, if needed. */ 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"); /* * Cpdup the chosen file or directory onto the HDD. */ 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); } /* * Rebuild the user database, to get rid of any extra users * from the LiveCD that aren't supposed to be installed * (copying a pristine master.passwd isn't enough.) */ 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); /* Create missing directories. */ command_add(cmds, "%s%s %smnt/proc", 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); /* Write new fstab. */ 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 if (use_hammer == 0) { if (strcmp(subpartition_get_mountpoint(sp), "/") == 0) { command_add(cmds, "%s%s '/dev/%s\t\t%s\t\tufs\trw\t\t1\t1' >>%smnt/etc/fstab", a->os_root, cmd_name(a, "ECHO"), subpartition_get_device_name(sp), subpartition_get_mountpoint(sp), a->os_root); } else 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)) { command_add(cmds, "%s%s '%s\t/dev/%s\tnone\tnone' >>%smnt/etc/crypttab", a->os_root, cmd_name(a, "ECHO"), subpartition_get_mountpoint(sp) + 1, subpartition_get_device_name(sp), a->os_root); command_add(cmds, "%s%s '/dev/mapper/%s\t\t%s\t\tufs\trw\t\t2\t2' >>%smnt/etc/fstab", a->os_root, cmd_name(a, "ECHO"), subpartition_get_mountpoint(sp) + 1, subpartition_get_mountpoint(sp), a->os_root); } else { command_add(cmds, "%s%s '/dev/%s\t\t%s\t\tufs\trw\t\t2\t2' >>%smnt/etc/fstab", a->os_root, cmd_name(a, "ECHO"), subpartition_get_device_name(sp), subpartition_get_mountpoint(sp), a->os_root); } } else { if (strcmp(subpartition_get_mountpoint(sp), "/") == 0) { command_add(cmds, "%s%s '/dev/%s\t\t%s\t\thammer\trw\t\t1\t1' >>%smnt/etc/fstab", a->os_root, cmd_name(a, "ECHO"), subpartition_get_device_name(sp), subpartition_get_mountpoint(sp), a->os_root); 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:hammer:%s:root\"' >>%smnt/boot/loader.conf", a->os_root, cmd_name(a, "ECHO"), subpartition_get_device_name(sp), a->os_root); } else { command_add(cmds, "%s%s 'vfs.root.mountfrom=\"hammer:%s\"' >>%smnt/boot/loader.conf", a->os_root, cmd_name(a, "ECHO"), subpartition_get_device_name(sp), a->os_root); } } else if (strcmp(subpartition_get_mountpoint(sp), "/boot") == 0) { command_add(cmds, "%s%s '/dev/%s\t\t%s\t\tufs\trw\t\t1\t1' >>%smnt/etc/fstab", a->os_root, cmd_name(a, "ECHO"), subpartition_get_device_name(sp), subpartition_get_mountpoint(sp), a->os_root); } } } /* * Take care of HAMMER PFS null mounts. */ if (use_hammer == 1) { for (j = 0; pfs_mountpt[j] != NULL; j++) { if (rindex(pfs_mountpt[j]+1, '/') != NULL) command_add(cmds, "%s%s '/pfs%s.%s\t%s\t\tnull\trw\t\t0\t0' >>%smnt/etc/fstab", a->os_root, cmd_name(a, "ECHO"), dirname(pfs_mountpt[j]), basename(pfs_mountpt[j]), pfs_mountpt[j], a->os_root); else command_add(cmds, "%s%s '/pfs%s\t\t%s\t\tnull\trw\t\t0\t0' >>%smnt/etc/fstab", a->os_root, cmd_name(a, "ECHO"), pfs_mountpt[j], pfs_mountpt[j], 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); /* Backup the disklabel and the log. */ 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))); /* 'chflags nohistory' as needed */ 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]); 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); /* Do some preparation if encrypted partitions were configured */ 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); if (use_hammer) { command_add(cmds, "%s%s -b %smnt/boot -t %smnt/tmp", a->os_root, cmd_name(a, "MKINITRD"), a->os_root, a->os_root); command_add(cmds, "%s%s -rf %smnt/tmp/initrd", a->os_root, cmd_name(a, "RM"), 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); } } /* Customize stuff here */ 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); } /* * Do it! */ /* commands_preview(a->c, cmds); */ 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_free(rc_conf); rc_conf = config_vars_new(); } /* * Unmount everything we mounted on /mnt. This is done in a seperate * command chain, so that partitions are unmounted, even if an error * occurs in one of the preceding commands, or it is cancelled. */ unmount_all_under(a, cmds, "%smnt", a->os_root); /* * Once everything is unmounted, if the install went successfully, * make sure once and for all that the disklabel is bootable. */ 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); /* * Finally, remove all swap and any mappings. */ 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.")); }