1 /* 2 * Copyright (c)2004 The DragonFly Project. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * Neither the name of the DragonFly Project nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31 * OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * fn_install.c 36 * Installer Function : Install OS Files. 37 * $Id: fn_install.c,v 1.74 2006/04/18 19:43:48 joerg Exp $ 38 */ 39 40 #include <libgen.h> 41 #include <string.h> 42 43 #define SOURCES_CONF_FILE "usr/share/installer/sources.conf" 44 45 #ifdef ENABLE_NLS 46 #include <libintl.h> 47 #define _(String) gettext (String) 48 #else 49 #define _(String) (String) 50 #endif 51 52 #include "libaura/mem.h" 53 #include "libaura/buffer.h" 54 #include "libaura/fspred.h" 55 56 #include "libdfui/dfui.h" 57 #include "libdfui/system.h" 58 59 #include "libinstaller/commands.h" 60 #include "libinstaller/confed.h" 61 #include "libinstaller/diskutil.h" 62 #include "libinstaller/functions.h" 63 #include "libinstaller/uiutil.h" 64 65 #include "flow.h" 66 #include "pathnames.h" 67 #include "fn.h" 68 69 static const char *pfs_mountpt[8] = {"/var", "/tmp", "/usr", "/home", 70 "/usr/obj", "/var/crash", "/var/tmp", NULL}; 71 72 static const int pfs_nohistory[8] = {0, 1, 0, 0, 1, 1, 1}; 73 74 static void 75 handle_pfs(struct i_fn_args *a, struct commands *cmds) 76 { 77 int j; 78 79 /* 80 * Create PFS root directory. 81 */ 82 command_add(cmds, "%s%s -p %smnt/pfs", 83 a->os_root, cmd_name(a, "MKDIR"), 84 a->os_root); 85 86 for (j = 0; pfs_mountpt[j] != NULL; j++) { 87 /* 88 * We have a PFS for a subdirectory, e.g. /var/crash, so we 89 * need to create /pfs/var.crash 90 */ 91 if (rindex(pfs_mountpt[j]+1, '/') != NULL) { 92 command_add(cmds, "%s%s pfs-master %smnt/pfs%s.%s", 93 a->os_root, cmd_name(a, "HAMMER"), 94 a->os_root, dirname(pfs_mountpt[j]), 95 basename(pfs_mountpt[j])); 96 command_add(cmds, "%s%s -p %smnt%s", 97 a->os_root, cmd_name(a, "MKDIR"), 98 a->os_root, pfs_mountpt[j]); 99 command_add(cmds, "%s%s %smnt/pfs%s.%s %smnt%s", 100 a->os_root, cmd_name(a, "MOUNT_NULL"), 101 a->os_root, dirname(pfs_mountpt[j]), 102 basename(pfs_mountpt[j]), 103 a->os_root, pfs_mountpt[j]); 104 } else { 105 command_add(cmds, "%s%s pfs-master %smnt/pfs%s", 106 a->os_root, cmd_name(a, "HAMMER"), 107 a->os_root, pfs_mountpt[j]); 108 command_add(cmds, "%s%s -p %smnt%s", 109 a->os_root, cmd_name(a, "MKDIR"), 110 a->os_root, pfs_mountpt[j]); 111 command_add(cmds, "%s%s %smnt/pfs%s %smnt%s", 112 a->os_root, cmd_name(a, "MOUNT_NULL"), 113 a->os_root, pfs_mountpt[j], 114 a->os_root, pfs_mountpt[j]); 115 } 116 } 117 } 118 119 /* 120 * fn_install_os: actually put DragonFly on a disk. 121 */ 122 void 123 fn_install_os(struct i_fn_args *a) 124 { 125 struct subpartition *sp; 126 struct commands *cmds; 127 struct command *cmd; 128 int i, seen_it, prefix, j, needcrypt; 129 FILE *sources_conf; 130 char line[256]; 131 char cp_src[64][256]; 132 char file_path[256]; 133 char *string; 134 int lines = 0; 135 136 /* 137 * Read SOURCES_CONF_FILE and populate our copy sources. 138 */ 139 snprintf(file_path, 256, "%s%s", a->os_root, SOURCES_CONF_FILE); 140 sources_conf = fopen(file_path, "r"); 141 i_log(a, "Reading %s", file_path); 142 while(fgets(line, 256, sources_conf) != NULL && lines < 63) { 143 if(strlen(line)>0) 144 line[strlen(line)-1] = '\0'; 145 strlcpy(cp_src[lines], line, 256); 146 i_log(a,"Adding %s to copy source table.", cp_src[lines]); 147 lines++; 148 } 149 i_log(a,"Added %i total items to copy source table.", lines); 150 strcpy(cp_src[lines], ""); 151 fclose(sources_conf); 152 153 cmds = commands_new(); 154 155 /* 156 * If swap isn't mounted yet, mount it. 157 */ 158 if (measure_activated_swap(a) == 0) { 159 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 160 sp != NULL; sp = subpartition_next(sp)) { 161 if (!subpartition_is_swap(sp)) 162 continue; 163 command_add(cmds, "%s%s /dev/%s", 164 a->os_root, 165 cmd_name(a, "SWAPON"), 166 subpartition_is_encrypted(sp) ? 167 "mapper/swap" : subpartition_get_device_name(sp)); 168 } 169 } 170 171 /* 172 * Unmount anything already mounted on /mnt. 173 */ 174 unmount_all_under(a, cmds, "%smnt", a->os_root); 175 176 /* Check if crypto support is needed */ 177 needcrypt = 0; 178 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 179 sp != NULL; sp = subpartition_next(sp)) { 180 if (subpartition_is_encrypted(sp)) { 181 needcrypt = 1; 182 break; 183 } 184 } 185 186 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 187 sp != NULL; sp = subpartition_next(sp)) { 188 if (strcmp(subpartition_get_mountpoint(sp), "/") == 0) { 189 if (use_hammer == 1) { 190 command_add(cmds, "%s%s /dev/%s %smnt%s", 191 a->os_root, cmd_name(a, "MOUNT_HAMMER"), 192 subpartition_is_encrypted(sp) ? 193 "mapper/root" : subpartition_get_device_name(sp), 194 a->os_root, 195 subpartition_get_mountpoint(sp)); 196 } else { 197 command_add(cmds, "%s%s /dev/%s %smnt%s", 198 a->os_root, cmd_name(a, "MOUNT"), 199 subpartition_get_device_name(sp), 200 a->os_root, 201 subpartition_get_mountpoint(sp)); 202 } 203 } 204 } 205 206 /* 207 * Create mount points and mount subpartitions on them. 208 */ 209 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 210 sp != NULL; sp = subpartition_next(sp)) { 211 if (subpartition_is_swap(sp)) { 212 /* 213 * Set this subpartition as the dump device. 214 */ 215 command_add(cmds, "%s%s -v /dev/%s", 216 a->os_root, cmd_name(a, "DUMPON"), 217 subpartition_is_encrypted(sp) ? 218 "mapper/swap" : subpartition_get_device_name(sp)); 219 220 asprintf(&string, "/dev/%s", 221 subpartition_is_encrypted(sp) ? 222 "mapper/swap" : subpartition_get_device_name(sp)); 223 config_var_set(rc_conf, "dumpdev", string); 224 free(string); 225 continue; 226 } 227 228 if (use_hammer == 0) { 229 /* / is already mounted */ 230 if (strcmp(subpartition_get_mountpoint(sp), "/") != 0) { 231 command_add(cmds, "%s%s -p %smnt%s", 232 a->os_root, cmd_name(a, "MKDIR"), 233 a->os_root, 234 subpartition_get_mountpoint(sp)); 235 /* Don't mount it if it's TMPFS-backed. */ 236 if (subpartition_is_tmpfsbacked(sp)) 237 continue; 238 if (subpartition_is_encrypted(sp)) { 239 command_add(cmds, "%s%s /dev/mapper/%s %smnt%s", 240 a->os_root, cmd_name(a, "MOUNT"), 241 subpartition_get_mountpoint(sp) + 1, 242 a->os_root, 243 subpartition_get_mountpoint(sp)); 244 } else { 245 command_add(cmds, "%s%s /dev/%s %smnt%s", 246 a->os_root, cmd_name(a, "MOUNT"), 247 subpartition_get_device_name(sp), 248 a->os_root, 249 subpartition_get_mountpoint(sp)); 250 } 251 } 252 } else if (strcmp(subpartition_get_mountpoint(sp), "/boot") == 0) { 253 command_add(cmds, "%s%s -p %smnt%s", 254 a->os_root, cmd_name(a, "MKDIR"), 255 a->os_root, 256 subpartition_get_mountpoint(sp)); 257 command_add(cmds, "%s%s /dev/%s %smnt%s", 258 a->os_root, cmd_name(a, "MOUNT"), 259 subpartition_get_device_name(sp), 260 a->os_root, 261 subpartition_get_mountpoint(sp)); 262 } 263 } 264 265 /* 266 * Take care of HAMMER PFS. 267 */ 268 if (use_hammer == 1) 269 handle_pfs(a, cmds); 270 271 /* 272 * Actually copy files now. 273 */ 274 275 for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) { 276 char *src, *dest, *dn, *tmp_dest; 277 278 dest = cp_src[i]; 279 280 /* 281 * If dest would be on an TMPFS-backed 282 * mountpoint, don't bother copying it. 283 */ 284 sp = subpartition_of(storage_get_selected_slice(a->s), 285 "%s%s", a->os_root, &dest[1]); 286 if (sp != NULL && subpartition_is_tmpfsbacked(sp)) { 287 continue; 288 } 289 290 /* 291 * Create intermediate directories, if needed. 292 */ 293 tmp_dest = aura_strdup(dest); 294 dn = dirname(tmp_dest); 295 if (is_dir("%s%s", a->os_root, &dn[1]) && 296 !is_dir("%smnt%s", a->os_root, dn)) { 297 command_add(cmds, "%s%s -p %smnt%s", 298 a->os_root, cmd_name(a, "MKDIR"), 299 a->os_root, dn); 300 } 301 aura_free(tmp_dest, "directory name"); 302 303 /* 304 * If a directory by the same name but with the suffix 305 * ".hdd" exists on the installation media, cpdup that 306 * instead. This is particularly useful with /etc, which 307 * may have significantly different behaviour on the 308 * live CD compared to a standard HDD boot. 309 */ 310 if (is_dir("%s%s.hdd", a->os_root, &dest[1])) 311 asprintf(&src, "%s.hdd", &dest[1]); 312 else 313 asprintf(&src, "%s", &dest[1]); 314 315 if (is_dir("%s%s", a->os_root, src) || is_file("%s%s", a->os_root, src)) { 316 /* 317 * Cpdup the chosen file or directory onto the HDD. 318 * if it exists on the source. 319 */ 320 cmd = command_add(cmds, "%s%s %s%s %smnt%s", 321 a->os_root, cmd_name(a, "CPDUP"), 322 a->os_root, src, 323 a->os_root, dest); 324 command_set_log_mode(cmd, COMMAND_LOG_QUIET); 325 } 326 } 327 328 /* 329 * Now, because cpdup does not cross mount points, 330 * we must copy anything that the user might've made a 331 * seperate mount point for (e.g. /usr/libdata/lint.) 332 */ 333 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 334 sp != NULL; sp = subpartition_next(sp)) { 335 /* 336 * If the subpartition is a swap subpartition or an 337 * TMPFS-backed mountpoint, don't try to copy anything 338 * into it. 339 */ 340 if (subpartition_is_swap(sp) || subpartition_is_tmpfsbacked(sp)) 341 continue; 342 343 /* 344 * If the mountpoint doesn't even exist on the installation 345 * medium, don't try to copy anything from it! We assume 346 * it's an empty subpartition for the user's needs. 347 */ 348 if (!is_dir("%s%s", a->os_root, &subpartition_get_mountpoint(sp)[1])) 349 continue; 350 351 /* 352 * Don't bother copying the mountpoint IF: 353 * - we've already said to copy it, or something besides it 354 * (it's a prefix of something in cp_src); or 355 * - we haven't said to copy it 356 * (nothing in cp_src is a prefix of it.) 357 */ 358 seen_it = 0; 359 prefix = 0; 360 for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) { 361 if (strncmp(subpartition_get_mountpoint(sp), cp_src[i], 362 strlen(subpartition_get_mountpoint(sp))) == 0) { 363 seen_it = 1; 364 break; 365 } 366 if (strncmp(cp_src[i], subpartition_get_mountpoint(sp), 367 strlen(cp_src[i])) == 0) { 368 prefix = 1; 369 } 370 } 371 if (seen_it || !prefix) 372 continue; 373 374 /* 375 * Otherwise, cpdup the subpartition. 376 * 377 * XXX check for .hdd-extended source dirs here, too, 378 * eventually - but for now, /etc.hdd will never be 379 * the kind of tricky sub-mount-within-a-mount-point 380 * that this part of the code is meant to handle. 381 */ 382 cmd = command_add(cmds, "%s%s %s%s %smnt%s", 383 a->os_root, cmd_name(a, "CPDUP"), 384 a->os_root, &subpartition_get_mountpoint(sp)[1], 385 a->os_root, subpartition_get_mountpoint(sp)); 386 command_set_log_mode(cmd, COMMAND_LOG_QUIET); 387 } 388 389 /* 390 * Create symlinks. 391 */ 392 393 /* Take care of /sys. */ 394 command_add(cmds, "%s%s -s usr/src/sys %smnt/sys", 395 a->os_root, cmd_name(a, "LN"), a->os_root); 396 397 /* 398 * If the user has both /var and /tmp subpartitions, 399 * symlink /var/tmp to /tmp. 400 */ 401 if (subpartition_find(storage_get_selected_slice(a->s), "/tmp") != NULL && 402 subpartition_find(storage_get_selected_slice(a->s), "/var") != NULL) { 403 command_add(cmds, "%s%s 1777 %smnt/tmp", 404 a->os_root, cmd_name(a, "CHMOD"), a->os_root); 405 command_add(cmds, "%s%s -rf %smnt/var/tmp", 406 a->os_root, cmd_name(a, "RM"), a->os_root); 407 command_add(cmds, "%s%s -s /tmp %smnt/var/tmp", 408 a->os_root, cmd_name(a, "LN"), a->os_root); 409 } 410 411 /* 412 * If the user has /var, but no /tmp, 413 * symlink /tmp to /var/tmp. 414 */ 415 if (subpartition_find(storage_get_selected_slice(a->s), "/tmp") == NULL && 416 subpartition_find(storage_get_selected_slice(a->s), "/var") != NULL) { 417 command_add(cmds, "%s%s -rf %smnt/tmp", 418 a->os_root, cmd_name(a, "RM"), a->os_root); 419 command_add(cmds, "%s%s -s /var/tmp %smnt/tmp", 420 a->os_root, cmd_name(a, "LN"), a->os_root); 421 } 422 423 /* 424 * If the user has /usr, but no /home, 425 * symlink /home to /usr/home. 426 */ 427 if (subpartition_find(storage_get_selected_slice(a->s), "/home") == NULL && 428 subpartition_find(storage_get_selected_slice(a->s), "/usr") != NULL) { 429 command_add(cmds, "%s%s -rf %smnt/home", 430 a->os_root, cmd_name(a, "RM"), a->os_root); 431 command_add(cmds, "%s%s %smnt/usr/home", 432 a->os_root, cmd_name(a, "MKDIR"), a->os_root); 433 command_add(cmds, "%s%s -s /usr/home %smnt/home", 434 a->os_root, cmd_name(a, "LN"), a->os_root); 435 } 436 437 /* 438 * XXX check for other possible combinations too? 439 */ 440 441 /* 442 * Clean up. In case some file didn't make it, use rm -f 443 */ 444 command_add(cmds, "%s%s -f %smnt/boot/loader.conf", 445 a->os_root, cmd_name(a, "RM"), a->os_root); 446 command_add(cmds, "%s%s -f %smnt/tmp/install.log", 447 a->os_root, cmd_name(a, "RM"), a->os_root); 448 command_add(cmds, "%s%s -f %smnt/tmp/t[12]", 449 a->os_root, cmd_name(a, "RM"), a->os_root); 450 command_add(cmds, "%s%s -f %smnt/tmp/test_in", 451 a->os_root, cmd_name(a, "RM"), a->os_root); 452 command_add(cmds, "%s%s -f %smnt/tmp/test_out", 453 a->os_root, cmd_name(a, "RM"), a->os_root); 454 455 /* 456 * Copy pristine versions over any files we might have installed. 457 * This allows the resulting file tree to be customized. 458 */ 459 for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) { 460 char *src, *dest, *dn, *tmp_dest; 461 462 src = cp_src[i]; 463 dest = cp_src[i]; 464 465 /* 466 * Get the directory that the desired thing to 467 * copy resides in. 468 */ 469 tmp_dest = aura_strdup(dest); 470 dn = dirname(tmp_dest); 471 472 /* 473 * If this dir doesn't exist in PRISTINE_DIR 474 * on the install media, just skip it. 475 */ 476 if (!is_dir("%s%s%s", a->os_root, PRISTINE_DIR, dn)) { 477 aura_free(tmp_dest, _("directory name")); 478 continue; 479 } 480 481 /* 482 * Create intermediate directories, if needed. 483 */ 484 if (!is_dir("%smnt%s", a->os_root, dn)) { 485 command_add(cmds, "%s%s -p %smnt%s", 486 a->os_root, cmd_name(a, "MKDIR"), 487 a->os_root, dn); 488 } 489 aura_free(tmp_dest, "directory name"); 490 491 /* 492 * Cpdup the chosen file or directory onto the HDD. 493 */ 494 cmd = command_add(cmds, "%s%s %s%s %smnt%s", 495 a->os_root, cmd_name(a, "CPDUP"), 496 a->os_root, src, 497 a->os_root, dest); 498 499 cmd = command_add(cmds, 500 "%s%s %s%s%s %smnt%s", 501 a->os_root, cmd_name(a, "CPDUP"), 502 a->os_root, PRISTINE_DIR, src, 503 a->os_root, dest); 504 command_set_log_mode(cmd, COMMAND_LOG_QUIET); 505 } 506 507 /* 508 * Rebuild the user database, to get rid of any extra users 509 * from the LiveCD that aren't supposed to be installed 510 * (copying a pristine master.passwd isn't enough.) 511 */ 512 command_add(cmds, "%s%s -p -d %smnt/etc %smnt/etc/master.passwd", 513 a->os_root, cmd_name(a, "PWD_MKDB"), a->os_root, a->os_root); 514 515 /* Create missing directories. */ 516 command_add(cmds, "%s%s %smnt/proc", 517 a->os_root, cmd_name(a, "MKDIR"), a->os_root); 518 command_add(cmds, "%s%s %smnt/mnt", 519 a->os_root, cmd_name(a, "MKDIR"), a->os_root); 520 521 /* Write new fstab. */ 522 command_add(cmds, "%s%s '%s' >%smnt/etc/fstab", 523 a->os_root, cmd_name(a, "ECHO"), 524 "# Device\t\tMountpoint\tFStype\tOptions\t\tDump\tPass#", 525 a->os_root); 526 527 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 528 sp != NULL; sp = subpartition_next(sp)) { 529 if (strcmp(subpartition_get_mountpoint(sp), "swap") == 0) { 530 command_add(cmds, "%s%s '/dev/%s\t\tnone\t\tswap\tsw\t\t0\t0' >>%smnt/etc/fstab", 531 a->os_root, cmd_name(a, "ECHO"), 532 subpartition_is_encrypted(sp) ? 533 "mapper/swap" : subpartition_get_device_name(sp), 534 a->os_root); 535 if (subpartition_is_encrypted(sp)) { 536 command_add(cmds, 537 "%s%s 'swap\t/dev/%s\tnone\tnone' >>%smnt/etc/crypttab", 538 a->os_root, cmd_name(a, "ECHO"), 539 subpartition_get_device_name(sp), 540 a->os_root); 541 } 542 } else if (use_hammer == 0) { 543 if (strcmp(subpartition_get_mountpoint(sp), "/") == 0) { 544 command_add(cmds, "%s%s '/dev/%s\t\t%s\t\tufs\trw\t\t1\t1' >>%smnt/etc/fstab", 545 a->os_root, cmd_name(a, "ECHO"), 546 subpartition_get_device_name(sp), 547 subpartition_get_mountpoint(sp), 548 a->os_root); 549 } else if (subpartition_is_tmpfsbacked(sp)) { 550 command_add(cmds, "%s%s 'tmpfs\t\t\t%s\t\ttmpfs\trw,-s%luM\t1\t1' >>%smnt/etc/fstab", 551 a->os_root, cmd_name(a, "ECHO"), 552 subpartition_get_mountpoint(sp), 553 subpartition_get_capacity(sp), 554 a->os_root); 555 } else if (subpartition_is_encrypted(sp)) { 556 command_add(cmds, "%s%s '%s\t/dev/%s\tnone\tnone' >>%smnt/etc/crypttab", 557 a->os_root, cmd_name(a, "ECHO"), 558 subpartition_get_mountpoint(sp) + 1, 559 subpartition_get_device_name(sp), 560 a->os_root); 561 command_add(cmds, "%s%s '/dev/mapper/%s\t\t%s\t\tufs\trw\t\t2\t2' >>%smnt/etc/fstab", 562 a->os_root, cmd_name(a, "ECHO"), 563 subpartition_get_mountpoint(sp) + 1, 564 subpartition_get_mountpoint(sp), 565 a->os_root); 566 } else { 567 command_add(cmds, "%s%s '/dev/%s\t\t%s\t\tufs\trw\t\t2\t2' >>%smnt/etc/fstab", 568 a->os_root, cmd_name(a, "ECHO"), 569 subpartition_get_device_name(sp), 570 subpartition_get_mountpoint(sp), 571 a->os_root); 572 } 573 } else { 574 if (strcmp(subpartition_get_mountpoint(sp), "/") == 0) { 575 command_add(cmds, "%s%s '/dev/%s\t\t%s\t\thammer\trw\t\t1\t1' >>%smnt/etc/fstab", 576 a->os_root, cmd_name(a, "ECHO"), 577 subpartition_get_device_name(sp), 578 subpartition_get_mountpoint(sp), 579 a->os_root); 580 if (subpartition_is_encrypted(sp)) { 581 command_add(cmds, 582 "%s%s 'vfs.root.mountfrom=\"ufs:md0s0\"' >>%smnt/boot/loader.conf", 583 a->os_root, cmd_name(a, "ECHO"), 584 a->os_root); 585 command_add(cmds, 586 "%s%s 'vfs.root.realroot=\"crypt:hammer:%s:root\"' >>%smnt/boot/loader.conf", 587 a->os_root, cmd_name(a, "ECHO"), 588 subpartition_get_device_name(sp), 589 a->os_root); 590 } else { 591 command_add(cmds, 592 "%s%s 'vfs.root.mountfrom=\"hammer:%s\"' >>%smnt/boot/loader.conf", 593 a->os_root, cmd_name(a, "ECHO"), 594 subpartition_get_device_name(sp), 595 a->os_root); 596 } 597 } else if (strcmp(subpartition_get_mountpoint(sp), "/boot") == 0) { 598 command_add(cmds, "%s%s '/dev/%s\t\t%s\t\tufs\trw\t\t1\t1' >>%smnt/etc/fstab", 599 a->os_root, cmd_name(a, "ECHO"), 600 subpartition_get_device_name(sp), 601 subpartition_get_mountpoint(sp), 602 a->os_root); 603 } 604 } 605 } 606 607 /* 608 * Take care of HAMMER PFS null mounts. 609 */ 610 if (use_hammer == 1) { 611 for (j = 0; pfs_mountpt[j] != NULL; j++) { 612 if (rindex(pfs_mountpt[j]+1, '/') != NULL) 613 command_add(cmds, "%s%s '/pfs%s.%s\t%s\t\tnull\trw\t\t0\t0' >>%smnt/etc/fstab", 614 a->os_root, cmd_name(a, "ECHO"), 615 dirname(pfs_mountpt[j]), 616 basename(pfs_mountpt[j]), 617 pfs_mountpt[j], 618 a->os_root); 619 else 620 command_add(cmds, "%s%s '/pfs%s\t\t%s\t\tnull\trw\t\t0\t0' >>%smnt/etc/fstab", 621 a->os_root, cmd_name(a, "ECHO"), 622 pfs_mountpt[j], 623 pfs_mountpt[j], 624 a->os_root); 625 } 626 } 627 628 command_add(cmds, "%s%s '%s' >>%smnt/etc/fstab", 629 a->os_root, cmd_name(a, "ECHO"), 630 "proc\t\t\t/proc\t\tprocfs\trw\t\t0\t0", 631 a->os_root); 632 633 /* Backup the disklabel and the log. */ 634 command_add(cmds, "%s%s %s > %smnt/etc/disklabel.%s", 635 a->os_root, cmd_name(a, "DISKLABEL64"), 636 slice_get_device_name(storage_get_selected_slice(a->s)), 637 a->os_root, 638 slice_get_device_name(storage_get_selected_slice(a->s))); 639 640 /* 'chflags nohistory' as needed */ 641 for (j = 0; pfs_mountpt[j] != NULL; j++) 642 if (pfs_nohistory[j] == 1) 643 command_add(cmds, "%s%s -R nohistory %smnt%s", 644 a->os_root, cmd_name(a, "CHFLAGS"), 645 a->os_root, pfs_mountpt[j]); 646 647 /* Create the rescue image. */ 648 command_add(cmds, "%s%s -b %smnt/boot -t %smnt/tmp", 649 a->os_root, cmd_name(a, "MKINITRD"), 650 a->os_root, a->os_root); 651 command_add(cmds, "%s%s -rf %smnt/tmp/initrd", 652 a->os_root, cmd_name(a, "RM"), a->os_root); 653 654 /* Do some preparation if encrypted partitions were configured */ 655 if (needcrypt) { 656 command_add(cmds, 657 "%s%s 'dm_load=\"yes\"' >>%smnt/boot/loader.conf", 658 a->os_root, cmd_name(a, "ECHO"), 659 a->os_root); 660 command_add(cmds, 661 "%s%s 'dm_target_crypt_load=\"yes\"' >>%smnt/boot/loader.conf", 662 a->os_root, cmd_name(a, "ECHO"), 663 a->os_root); 664 if (use_hammer) { 665 command_add(cmds, 666 "%s%s 'initrd.img_load=\"YES\"' >>%smnt/boot/loader.conf", 667 a->os_root, cmd_name(a, "ECHO"), 668 a->os_root); 669 command_add(cmds, 670 "%s%s 'initrd.img_type=\"md_image\"' >>%smnt/boot/loader.conf", 671 a->os_root, cmd_name(a, "ECHO"), 672 a->os_root); 673 } 674 } 675 676 /* Customize stuff here */ 677 if(is_file("%susr/local/bin/after_installation_routines.sh", a->os_root)) { 678 command_add(cmds, "%susr/local/bin/after_installation_routines.sh", 679 a->os_root); 680 } 681 682 /* Save the installation log. */ 683 command_add(cmds, "%s%s %sinstall.log %smnt/var/log/install.log", 684 a->os_root, cmd_name(a, "CP"), 685 a->tmp, a->os_root); 686 command_add(cmds, "%s%s 600 %smnt/var/log/install.log", 687 a->os_root, cmd_name(a, "CHMOD"), a->os_root); 688 689 /* 690 * Do it! 691 */ 692 /* commands_preview(a->c, cmds); */ 693 if (!commands_execute(a, cmds)) { 694 inform(a->c, _("%s was not fully installed."), OPERATING_SYSTEM_NAME); 695 a->result = 0; 696 } else { 697 a->result = 1; 698 } 699 commands_free(cmds); 700 cmds = commands_new(); 701 702 if (a->result) { 703 config_vars_write(rc_conf, CONFIG_TYPE_SH, "%smnt/etc/rc.conf", 704 a->os_root); 705 config_vars_free(rc_conf); 706 rc_conf = config_vars_new(); 707 } 708 709 /* 710 * Unmount everything we mounted on /mnt. This is done in a seperate 711 * command chain, so that partitions are unmounted, even if an error 712 * occurs in one of the preceding commands, or it is cancelled. 713 */ 714 unmount_all_under(a, cmds, "%smnt", a->os_root); 715 716 /* 717 * Once everything is unmounted, if the install went successfully, 718 * make sure once and for all that the disklabel is bootable. 719 */ 720 if (a->result) 721 command_add(cmds, "%s%s -B %s", 722 a->os_root, cmd_name(a, "DISKLABEL64"), 723 slice_get_device_name(storage_get_selected_slice(a->s))); 724 725 if (!commands_execute(a, cmds)) 726 inform(a->c, _("Warning: subpartitions were not correctly unmounted.")); 727 728 commands_free(cmds); 729 730 /* 731 * Finally, remove all swap and any mappings. 732 */ 733 if (swapoff_all(a) == NULL) 734 inform(a->c, _("Warning: swap could not be turned off.")); 735 if (remove_all_mappings(a) == NULL) 736 inform(a->c, _("Warning: mappings could not be removed.")); 737 } 738