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 %sdev/%s", 164 a->os_root, 165 cmd_name(a, "SWAPON"), 166 a->os_root, 167 subpartition_is_encrypted(sp) ? 168 "mapper/swap" : subpartition_get_device_name(sp)); 169 } 170 } 171 172 /* 173 * Unmount anything already mounted on /mnt. 174 */ 175 unmount_all_under(a, cmds, "%smnt", a->os_root); 176 177 /* Check if crypto support is needed */ 178 needcrypt = 0; 179 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 180 sp != NULL; sp = subpartition_next(sp)) { 181 if (subpartition_is_encrypted(sp)) { 182 needcrypt = 1; 183 break; 184 } 185 } 186 187 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 188 sp != NULL; sp = subpartition_next(sp)) { 189 if (strcmp(subpartition_get_mountpoint(sp), "/") == 0) { 190 if (use_hammer == 1) { 191 command_add(cmds, "%s%s %sdev/%s %smnt%s", 192 a->os_root, cmd_name(a, "MOUNT_HAMMER"), 193 a->os_root, 194 subpartition_is_encrypted(sp) ? 195 "mapper/root" : subpartition_get_device_name(sp), 196 a->os_root, 197 subpartition_get_mountpoint(sp)); 198 } else { 199 command_add(cmds, "%s%s %sdev/%s %smnt%s", 200 a->os_root, cmd_name(a, "MOUNT"), 201 a->os_root, 202 subpartition_get_device_name(sp), 203 a->os_root, 204 subpartition_get_mountpoint(sp)); 205 } 206 } 207 } 208 209 /* 210 * Create mount points and mount subpartitions on them. 211 */ 212 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 213 sp != NULL; sp = subpartition_next(sp)) { 214 if (subpartition_is_swap(sp)) { 215 /* 216 * Set this subpartition as the dump device. 217 */ 218 if (subpartition_get_capacity(sp) < storage_get_memsize(a->s)) 219 continue; 220 221 command_add(cmds, "%s%s -v %sdev/%s", 222 a->os_root, cmd_name(a, "DUMPON"), 223 a->os_root, 224 subpartition_is_encrypted(sp) ? 225 "mapper/swap" : subpartition_get_device_name(sp)); 226 227 asprintf(&string, "/dev/%s", 228 subpartition_is_encrypted(sp) ? 229 "mapper/swap" : subpartition_get_device_name(sp)); 230 config_var_set(rc_conf, "dumpdev", string); 231 free(string); 232 continue; 233 } 234 235 if (use_hammer == 0) { 236 /* / is already mounted */ 237 if (strcmp(subpartition_get_mountpoint(sp), "/") != 0) { 238 command_add(cmds, "%s%s -p %smnt%s", 239 a->os_root, cmd_name(a, "MKDIR"), 240 a->os_root, 241 subpartition_get_mountpoint(sp)); 242 /* Don't mount it if it's TMPFS-backed. */ 243 if (subpartition_is_tmpfsbacked(sp)) 244 continue; 245 if (subpartition_is_encrypted(sp)) { 246 command_add(cmds, "%s%s %sdev/mapper/%s %smnt%s", 247 a->os_root, cmd_name(a, "MOUNT"), 248 a->os_root, 249 subpartition_get_mountpoint(sp) + 1, 250 a->os_root, 251 subpartition_get_mountpoint(sp)); 252 } else { 253 command_add(cmds, "%s%s %sdev/%s %smnt%s", 254 a->os_root, cmd_name(a, "MOUNT"), 255 a->os_root, 256 subpartition_get_device_name(sp), 257 a->os_root, 258 subpartition_get_mountpoint(sp)); 259 } 260 } 261 } else if (strcmp(subpartition_get_mountpoint(sp), "/boot") == 0) { 262 command_add(cmds, "%s%s -p %smnt%s", 263 a->os_root, cmd_name(a, "MKDIR"), 264 a->os_root, 265 subpartition_get_mountpoint(sp)); 266 command_add(cmds, "%s%s %sdev/%s %smnt%s", 267 a->os_root, cmd_name(a, "MOUNT"), 268 a->os_root, 269 subpartition_get_device_name(sp), 270 a->os_root, 271 subpartition_get_mountpoint(sp)); 272 } 273 } 274 275 /* 276 * Take care of HAMMER PFS. 277 */ 278 if (use_hammer == 1) 279 handle_pfs(a, cmds); 280 281 /* 282 * Actually copy files now. 283 */ 284 285 for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) { 286 char *src, *dest, *dn, *tmp_dest; 287 288 dest = cp_src[i]; 289 290 /* 291 * If dest would be on an TMPFS-backed 292 * mountpoint, don't bother copying it. 293 */ 294 sp = subpartition_of(storage_get_selected_slice(a->s), 295 "%s%s", a->os_root, &dest[1]); 296 if (sp != NULL && subpartition_is_tmpfsbacked(sp)) { 297 continue; 298 } 299 300 /* 301 * Create intermediate directories, if needed. 302 */ 303 tmp_dest = aura_strdup(dest); 304 dn = dirname(tmp_dest); 305 if (is_dir("%s%s", a->os_root, &dn[1]) && 306 !is_dir("%smnt%s", a->os_root, dn)) { 307 command_add(cmds, "%s%s -p %smnt%s", 308 a->os_root, cmd_name(a, "MKDIR"), 309 a->os_root, dn); 310 } 311 aura_free(tmp_dest, "directory name"); 312 313 /* 314 * If a directory by the same name but with the suffix 315 * ".hdd" exists on the installation media, cpdup that 316 * instead. This is particularly useful with /etc, which 317 * may have significantly different behaviour on the 318 * live CD compared to a standard HDD boot. 319 */ 320 if (is_dir("%s%s.hdd", a->os_root, &dest[1])) 321 asprintf(&src, "%s.hdd", &dest[1]); 322 else 323 asprintf(&src, "%s", &dest[1]); 324 325 if (is_dir("%s%s", a->os_root, src) || is_file("%s%s", a->os_root, src)) { 326 /* 327 * Cpdup the chosen file or directory onto the HDD. 328 * if it exists on the source. 329 */ 330 cmd = command_add(cmds, "%s%s %s%s %smnt%s", 331 a->os_root, cmd_name(a, "CPDUP"), 332 a->os_root, src, 333 a->os_root, dest); 334 command_set_log_mode(cmd, COMMAND_LOG_QUIET); 335 } 336 } 337 338 /* 339 * Now, because cpdup does not cross mount points, 340 * we must copy anything that the user might've made a 341 * seperate mount point for (e.g. /usr/libdata/lint.) 342 */ 343 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 344 sp != NULL; sp = subpartition_next(sp)) { 345 /* 346 * If the subpartition is a swap subpartition or an 347 * TMPFS-backed mountpoint, don't try to copy anything 348 * into it. 349 */ 350 if (subpartition_is_swap(sp) || subpartition_is_tmpfsbacked(sp)) 351 continue; 352 353 /* 354 * If the mountpoint doesn't even exist on the installation 355 * medium, don't try to copy anything from it! We assume 356 * it's an empty subpartition for the user's needs. 357 */ 358 if (!is_dir("%s%s", a->os_root, &subpartition_get_mountpoint(sp)[1])) 359 continue; 360 361 /* 362 * Don't bother copying the mountpoint IF: 363 * - we've already said to copy it, or something besides it 364 * (it's a prefix of something in cp_src); or 365 * - we haven't said to copy it 366 * (nothing in cp_src is a prefix of it.) 367 */ 368 seen_it = 0; 369 prefix = 0; 370 for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) { 371 if (strncmp(subpartition_get_mountpoint(sp), cp_src[i], 372 strlen(subpartition_get_mountpoint(sp))) == 0) { 373 seen_it = 1; 374 break; 375 } 376 if (strncmp(cp_src[i], subpartition_get_mountpoint(sp), 377 strlen(cp_src[i])) == 0) { 378 prefix = 1; 379 } 380 } 381 if (seen_it || !prefix) 382 continue; 383 384 /* 385 * Otherwise, cpdup the subpartition. 386 * 387 * XXX check for .hdd-extended source dirs here, too, 388 * eventually - but for now, /etc.hdd will never be 389 * the kind of tricky sub-mount-within-a-mount-point 390 * that this part of the code is meant to handle. 391 */ 392 cmd = command_add(cmds, "%s%s %s%s %smnt%s", 393 a->os_root, cmd_name(a, "CPDUP"), 394 a->os_root, &subpartition_get_mountpoint(sp)[1], 395 a->os_root, subpartition_get_mountpoint(sp)); 396 command_set_log_mode(cmd, COMMAND_LOG_QUIET); 397 } 398 399 /* 400 * Create symlinks. 401 */ 402 403 /* Take care of /sys. */ 404 command_add(cmds, "%s%s -s usr/src/sys %smnt/sys", 405 a->os_root, cmd_name(a, "LN"), a->os_root); 406 407 /* 408 * If the user has both /var and /tmp subpartitions, 409 * symlink /var/tmp to /tmp. 410 */ 411 if (subpartition_find(storage_get_selected_slice(a->s), "/tmp") != NULL && 412 subpartition_find(storage_get_selected_slice(a->s), "/var") != NULL) { 413 command_add(cmds, "%s%s 1777 %smnt/tmp", 414 a->os_root, cmd_name(a, "CHMOD"), a->os_root); 415 command_add(cmds, "%s%s -rf %smnt/var/tmp", 416 a->os_root, cmd_name(a, "RM"), a->os_root); 417 command_add(cmds, "%s%s -s /tmp %smnt/var/tmp", 418 a->os_root, cmd_name(a, "LN"), a->os_root); 419 } 420 421 /* 422 * If the user has /var, but no /tmp, 423 * symlink /tmp to /var/tmp. 424 */ 425 if (subpartition_find(storage_get_selected_slice(a->s), "/tmp") == NULL && 426 subpartition_find(storage_get_selected_slice(a->s), "/var") != NULL) { 427 command_add(cmds, "%s%s -rf %smnt/tmp", 428 a->os_root, cmd_name(a, "RM"), a->os_root); 429 command_add(cmds, "%s%s -s /var/tmp %smnt/tmp", 430 a->os_root, cmd_name(a, "LN"), a->os_root); 431 } 432 433 /* 434 * If the user has /usr, but no /home, 435 * symlink /home to /usr/home. 436 */ 437 if (subpartition_find(storage_get_selected_slice(a->s), "/home") == NULL && 438 subpartition_find(storage_get_selected_slice(a->s), "/usr") != NULL) { 439 command_add(cmds, "%s%s -rf %smnt/home", 440 a->os_root, cmd_name(a, "RM"), a->os_root); 441 command_add(cmds, "%s%s %smnt/usr/home", 442 a->os_root, cmd_name(a, "MKDIR"), a->os_root); 443 command_add(cmds, "%s%s -s /usr/home %smnt/home", 444 a->os_root, cmd_name(a, "LN"), a->os_root); 445 } 446 447 /* 448 * XXX check for other possible combinations too? 449 */ 450 451 /* 452 * Clean up. In case some file didn't make it, use rm -f 453 */ 454 command_add(cmds, "%s%s -f %smnt/boot/loader.conf", 455 a->os_root, cmd_name(a, "RM"), a->os_root); 456 command_add(cmds, "%s%s -f %smnt/tmp/install.log", 457 a->os_root, cmd_name(a, "RM"), a->os_root); 458 command_add(cmds, "%s%s -f %smnt/tmp/t[12]", 459 a->os_root, cmd_name(a, "RM"), a->os_root); 460 command_add(cmds, "%s%s -f %smnt/tmp/test_in", 461 a->os_root, cmd_name(a, "RM"), a->os_root); 462 command_add(cmds, "%s%s -f %smnt/tmp/test_out", 463 a->os_root, cmd_name(a, "RM"), a->os_root); 464 465 /* 466 * Copy pristine versions over any files we might have installed. 467 * This allows the resulting file tree to be customized. 468 */ 469 for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) { 470 char *src, *dest, *dn, *tmp_dest; 471 472 src = cp_src[i]; 473 dest = cp_src[i]; 474 475 /* 476 * Get the directory that the desired thing to 477 * copy resides in. 478 */ 479 tmp_dest = aura_strdup(dest); 480 dn = dirname(tmp_dest); 481 482 /* 483 * If this dir doesn't exist in PRISTINE_DIR 484 * on the install media, just skip it. 485 */ 486 if (!is_dir("%s%s%s", a->os_root, PRISTINE_DIR, dn)) { 487 aura_free(tmp_dest, _("directory name")); 488 continue; 489 } 490 491 /* 492 * Create intermediate directories, if needed. 493 */ 494 if (!is_dir("%smnt%s", a->os_root, dn)) { 495 command_add(cmds, "%s%s -p %smnt%s", 496 a->os_root, cmd_name(a, "MKDIR"), 497 a->os_root, dn); 498 } 499 aura_free(tmp_dest, "directory name"); 500 501 /* 502 * Cpdup the chosen file or directory onto the HDD. 503 */ 504 cmd = command_add(cmds, "%s%s %s%s %smnt%s", 505 a->os_root, cmd_name(a, "CPDUP"), 506 a->os_root, src, 507 a->os_root, dest); 508 509 cmd = command_add(cmds, 510 "%s%s %s%s%s %smnt%s", 511 a->os_root, cmd_name(a, "CPDUP"), 512 a->os_root, PRISTINE_DIR, src, 513 a->os_root, dest); 514 command_set_log_mode(cmd, COMMAND_LOG_QUIET); 515 } 516 517 /* 518 * Rebuild the user database, to get rid of any extra users 519 * from the LiveCD that aren't supposed to be installed 520 * (copying a pristine master.passwd isn't enough.) 521 */ 522 command_add(cmds, "%s%s -p -d %smnt/etc %smnt/etc/master.passwd", 523 a->os_root, cmd_name(a, "PWD_MKDB"), a->os_root, a->os_root); 524 525 /* Create missing directories. */ 526 command_add(cmds, "%s%s %smnt/proc", 527 a->os_root, cmd_name(a, "MKDIR"), a->os_root); 528 command_add(cmds, "%s%s %smnt/mnt", 529 a->os_root, cmd_name(a, "MKDIR"), a->os_root); 530 531 /* Write new fstab. */ 532 command_add(cmds, "%s%s '%s' >%smnt/etc/fstab", 533 a->os_root, cmd_name(a, "ECHO"), 534 "# Device\t\tMountpoint\tFStype\tOptions\t\tDump\tPass#", 535 a->os_root); 536 537 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 538 sp != NULL; sp = subpartition_next(sp)) { 539 if (strcmp(subpartition_get_mountpoint(sp), "swap") == 0) { 540 command_add(cmds, "%s%s '/dev/%s\t\tnone\t\tswap\tsw\t\t0\t0' >>%smnt/etc/fstab", 541 a->os_root, cmd_name(a, "ECHO"), 542 subpartition_is_encrypted(sp) ? 543 "mapper/swap" : subpartition_get_device_name(sp), 544 a->os_root); 545 if (subpartition_is_encrypted(sp)) { 546 command_add(cmds, 547 "%s%s 'swap\t/dev/%s\tnone\tnone' >>%smnt/etc/crypttab", 548 a->os_root, cmd_name(a, "ECHO"), 549 subpartition_get_device_name(sp), 550 a->os_root); 551 } 552 } else if (use_hammer == 0) { 553 if (strcmp(subpartition_get_mountpoint(sp), "/") == 0) { 554 command_add(cmds, "%s%s '/dev/%s\t\t%s\t\tufs\trw\t\t1\t1' >>%smnt/etc/fstab", 555 a->os_root, cmd_name(a, "ECHO"), 556 subpartition_get_device_name(sp), 557 subpartition_get_mountpoint(sp), 558 a->os_root); 559 command_add(cmds, "%s%s 'kern.emergency_intr_enable=1' >>%smnt/boot/loader.conf", 560 a->os_root, cmd_name(a, "ECHO"), a->os_root); 561 } else if (subpartition_is_tmpfsbacked(sp)) { 562 command_add(cmds, "%s%s 'tmpfs\t\t\t%s\t\ttmpfs\trw,-s%luM\t1\t1' >>%smnt/etc/fstab", 563 a->os_root, cmd_name(a, "ECHO"), 564 subpartition_get_mountpoint(sp), 565 subpartition_get_capacity(sp), 566 a->os_root); 567 } else if (subpartition_is_encrypted(sp)) { 568 command_add(cmds, "%s%s '%s\t/dev/%s\tnone\tnone' >>%smnt/etc/crypttab", 569 a->os_root, cmd_name(a, "ECHO"), 570 subpartition_get_mountpoint(sp) + 1, 571 subpartition_get_device_name(sp), 572 a->os_root); 573 command_add(cmds, "%s%s '/dev/mapper/%s\t\t%s\t\tufs\trw\t\t2\t2' >>%smnt/etc/fstab", 574 a->os_root, cmd_name(a, "ECHO"), 575 subpartition_get_mountpoint(sp) + 1, 576 subpartition_get_mountpoint(sp), 577 a->os_root); 578 } else { 579 command_add(cmds, "%s%s '/dev/%s\t\t%s\t\tufs\trw\t\t2\t2' >>%smnt/etc/fstab", 580 a->os_root, cmd_name(a, "ECHO"), 581 subpartition_get_device_name(sp), 582 subpartition_get_mountpoint(sp), 583 a->os_root); 584 } 585 } else { 586 if (strcmp(subpartition_get_mountpoint(sp), "/") == 0) { 587 command_add(cmds, "%s%s '/dev/%s\t\t%s\t\thammer\trw\t\t1\t1' >>%smnt/etc/fstab", 588 a->os_root, cmd_name(a, "ECHO"), 589 subpartition_get_device_name(sp), 590 subpartition_get_mountpoint(sp), 591 a->os_root); 592 command_add(cmds, "%s%s 'kern.emergency_intr_enable=1' >>%smnt/boot/loader.conf", 593 a->os_root, cmd_name(a, "ECHO"), a->os_root); 594 if (subpartition_is_encrypted(sp)) { 595 command_add(cmds, 596 "%s%s 'vfs.root.mountfrom=\"ufs:md0s0\"' >>%smnt/boot/loader.conf", 597 a->os_root, cmd_name(a, "ECHO"), 598 a->os_root); 599 command_add(cmds, 600 "%s%s 'vfs.root.realroot=\"crypt:hammer:%s:root\"' >>%smnt/boot/loader.conf", 601 a->os_root, cmd_name(a, "ECHO"), 602 subpartition_get_device_name(sp), 603 a->os_root); 604 } else { 605 command_add(cmds, 606 "%s%s 'vfs.root.mountfrom=\"hammer:%s\"' >>%smnt/boot/loader.conf", 607 a->os_root, cmd_name(a, "ECHO"), 608 subpartition_get_device_name(sp), 609 a->os_root); 610 } 611 } else if (strcmp(subpartition_get_mountpoint(sp), "/boot") == 0) { 612 command_add(cmds, "%s%s '/dev/%s\t\t%s\t\tufs\trw\t\t1\t1' >>%smnt/etc/fstab", 613 a->os_root, cmd_name(a, "ECHO"), 614 subpartition_get_device_name(sp), 615 subpartition_get_mountpoint(sp), 616 a->os_root); 617 } 618 } 619 } 620 621 /* 622 * Take care of HAMMER PFS null mounts. 623 */ 624 if (use_hammer == 1) { 625 for (j = 0; pfs_mountpt[j] != NULL; j++) { 626 if (rindex(pfs_mountpt[j]+1, '/') != NULL) 627 command_add(cmds, "%s%s '/pfs%s.%s\t%s\t\tnull\trw\t\t0\t0' >>%smnt/etc/fstab", 628 a->os_root, cmd_name(a, "ECHO"), 629 dirname(pfs_mountpt[j]), 630 basename(pfs_mountpt[j]), 631 pfs_mountpt[j], 632 a->os_root); 633 else 634 command_add(cmds, "%s%s '/pfs%s\t\t%s\t\tnull\trw\t\t0\t0' >>%smnt/etc/fstab", 635 a->os_root, cmd_name(a, "ECHO"), 636 pfs_mountpt[j], 637 pfs_mountpt[j], 638 a->os_root); 639 } 640 } 641 642 command_add(cmds, "%s%s '%s' >>%smnt/etc/fstab", 643 a->os_root, cmd_name(a, "ECHO"), 644 "proc\t\t\t/proc\t\tprocfs\trw\t\t0\t0", 645 a->os_root); 646 647 /* Backup the disklabel and the log. */ 648 command_add(cmds, "%s%s %s > %smnt/etc/disklabel.%s", 649 a->os_root, cmd_name(a, "DISKLABEL64"), 650 slice_get_device_name(storage_get_selected_slice(a->s)), 651 a->os_root, 652 slice_get_device_name(storage_get_selected_slice(a->s))); 653 654 /* 'chflags nohistory' as needed */ 655 for (j = 0; pfs_mountpt[j] != NULL; j++) 656 if (pfs_nohistory[j] == 1) 657 command_add(cmds, "%s%s -R nohistory %smnt%s", 658 a->os_root, cmd_name(a, "CHFLAGS"), 659 a->os_root, pfs_mountpt[j]); 660 661 command_add(cmds, "%s%s %sinstall.log %smnt/var/log/install.log", 662 a->os_root, cmd_name(a, "CP"), 663 a->tmp, a->os_root); 664 command_add(cmds, "%s%s 600 %smnt/var/log/install.log", 665 a->os_root, cmd_name(a, "CHMOD"), a->os_root); 666 667 /* 668 * Move the kernel used for booting (kernel.UP or kernel.SMP) to 669 * /boot/kernel and remove the other kernel 670 */ 671 command_add(cmds, 672 "%s%s %smnt`%s%s $(%s%s -n kern.bootfile)` %smnt/boot/kernel", 673 a->os_root, cmd_name(a, "MV"), 674 a->os_root, 675 a->os_root, cmd_name(a, "DIRNAME"), 676 a->os_root, cmd_name(a, "SYSCTL"), 677 a->os_root); 678 command_add(cmds, 679 "%s%s -R noschg %smnt/boot/kernel.[SU]M*P; %s%s -rf %smnt/boot/kernel.[SU]M*P", 680 a->os_root, cmd_name(a, "CHFLAGS"), 681 a->os_root, 682 a->os_root, cmd_name(a, "RM"), 683 a->os_root); 684 685 /* Do some preparation if encrypted partitions were configured */ 686 if (needcrypt) { 687 command_add(cmds, 688 "%s%s 'dm_load=\"yes\"' >>%smnt/boot/loader.conf", 689 a->os_root, cmd_name(a, "ECHO"), 690 a->os_root); 691 command_add(cmds, 692 "%s%s 'dm_target_crypt_load=\"yes\"' >>%smnt/boot/loader.conf", 693 a->os_root, cmd_name(a, "ECHO"), 694 a->os_root); 695 if (use_hammer) { 696 command_add(cmds, "%s%s -b %smnt/boot -t %smnt/tmp", 697 a->os_root, cmd_name(a, "MKINITRD"), 698 a->os_root, a->os_root); 699 command_add(cmds, "%s%s -rf %smnt/tmp/initrd", 700 a->os_root, cmd_name(a, "RM"), a->os_root); 701 command_add(cmds, 702 "%s%s 'initrd.img_load=\"YES\"' >>%smnt/boot/loader.conf", 703 a->os_root, cmd_name(a, "ECHO"), 704 a->os_root); 705 command_add(cmds, 706 "%s%s 'initrd.img_type=\"md_image\"' >>%smnt/boot/loader.conf", 707 a->os_root, cmd_name(a, "ECHO"), 708 a->os_root); 709 } 710 } 711 712 /* Customize stuff here */ 713 if(is_file("%susr/local/bin/after_installation_routines.sh", a->os_root)) { 714 command_add(cmds, "%susr/local/bin/after_installation_routines.sh", 715 a->os_root); 716 } 717 718 /* 719 * Do it! 720 */ 721 /* commands_preview(a->c, cmds); */ 722 if (!commands_execute(a, cmds)) { 723 inform(a->c, _("%s was not fully installed."), OPERATING_SYSTEM_NAME); 724 a->result = 0; 725 } else { 726 a->result = 1; 727 } 728 commands_free(cmds); 729 cmds = commands_new(); 730 731 if (a->result) { 732 config_vars_write(rc_conf, CONFIG_TYPE_SH, "%smnt/etc/rc.conf", 733 a->os_root); 734 config_vars_free(rc_conf); 735 rc_conf = config_vars_new(); 736 } 737 738 /* 739 * Unmount everything we mounted on /mnt. This is done in a seperate 740 * command chain, so that partitions are unmounted, even if an error 741 * occurs in one of the preceding commands, or it is cancelled. 742 */ 743 unmount_all_under(a, cmds, "%smnt", a->os_root); 744 745 /* 746 * Once everything is unmounted, if the install went successfully, 747 * make sure once and for all that the disklabel is bootable. 748 */ 749 if (a->result) 750 command_add(cmds, "%s%s -B %s", 751 a->os_root, cmd_name(a, "DISKLABEL64"), 752 slice_get_device_name(storage_get_selected_slice(a->s))); 753 754 if (!commands_execute(a, cmds)) 755 inform(a->c, _("Warning: subpartitions were not correctly unmounted.")); 756 757 commands_free(cmds); 758 759 /* 760 * Finally, remove all swap and any mappings. 761 */ 762 if (swapoff_all(a) == NULL) 763 inform(a->c, _("Warning: swap could not be turned off.")); 764 if (remove_all_mappings(a) == NULL) 765 inform(a->c, _("Warning: mappings could not be removed.")); 766 } 767