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; 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 * If SOURCES_CONF_FILE exists, lets read in and 138 * populate our copy sources. If it does not exist 139 * simply set the list by hand. 140 */ 141 if (!is_file("%s%s", a->os_root, SOURCES_CONF_FILE)) { 142 i_log(a, "Using internal copy sources table."); 143 strcpy(cp_src[0],"/COPYRIGHT"); 144 strcpy(cp_src[1],"/bin"); 145 strcpy(cp_src[2],"/boot"); 146 strcpy(cp_src[3],"/cdrom"); 147 strcpy(cp_src[4],"/dev"); 148 strcpy(cp_src[5],"/etc"); 149 strcpy(cp_src[6],"/root"); 150 strcpy(cp_src[7],"/sbin"); 151 strcpy(cp_src[9],"/tmp"); 152 strcpy(cp_src[10],"/usr/Makefile"); 153 strcpy(cp_src[11],"/usr/bin"); 154 strcpy(cp_src[12],"/usr/games"); 155 strcpy(cp_src[13],"/usr/include"); 156 strcpy(cp_src[14],"/usr/lib"); 157 strcpy(cp_src[15],"/usr/libdata"); 158 strcpy(cp_src[16],"/usr/libexec"); 159 strcpy(cp_src[17],"/usr/local"); 160 strcpy(cp_src[18],"/usr/obj"); 161 strcpy(cp_src[19],"/usr/pkg"); 162 strcpy(cp_src[20],"/usr/sbin"); 163 strcpy(cp_src[21],"/usr/share"); 164 strcpy(cp_src[22],"/usr/src"); 165 strcpy(cp_src[23],"/var"); 166 strcpy(cp_src[24],""); 167 } else { 168 snprintf(file_path, 256, "%s%s", a->os_root, SOURCES_CONF_FILE); 169 sources_conf = fopen(file_path, "r"); 170 i_log(a, "Reading %s%s", a->os_root, SOURCES_CONF_FILE); 171 while(fgets(line, 256, sources_conf) != NULL && lines < 63) { 172 if(strlen(line)>0) 173 line[strlen(line)-1] = '\0'; 174 strlcpy(cp_src[lines], line, 256); 175 i_log(a,"Adding %s to copy source table.", cp_src[lines]); 176 lines++; 177 } 178 i_log(a,"Added %i total items to copy source table.", lines); 179 strcpy(cp_src[lines], ""); 180 fclose(sources_conf); 181 } 182 183 cmds = commands_new(); 184 185 /* 186 * If swap isn't mounted yet, mount it. 187 */ 188 if (measure_activated_swap(a) == 0) { 189 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 190 sp != NULL; sp = subpartition_next(sp)) { 191 if (!subpartition_is_swap(sp)) 192 continue; 193 command_add(cmds, "%s%s %sdev/%s", 194 a->os_root, 195 cmd_name(a, "SWAPON"), 196 a->os_root, 197 subpartition_get_device_name(sp)); 198 } 199 } 200 201 /* 202 * Unmount anything already mounted on /mnt. 203 */ 204 unmount_all_under(a, cmds, "%smnt", a->os_root); 205 206 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 207 sp != NULL; sp = subpartition_next(sp)) { 208 if (strcmp(subpartition_get_mountpoint(sp), "/") == 0) { 209 if (use_hammer == 1) { 210 command_add(cmds, "%s%s %sdev/%s %smnt%s", 211 a->os_root, cmd_name(a, "MOUNT_HAMMER"), 212 a->os_root, 213 subpartition_get_device_name(sp), 214 a->os_root, 215 subpartition_get_mountpoint(sp)); 216 } else { 217 command_add(cmds, "%s%s %sdev/%s %smnt%s", 218 a->os_root, cmd_name(a, "MOUNT"), 219 a->os_root, 220 subpartition_get_device_name(sp), 221 a->os_root, 222 subpartition_get_mountpoint(sp)); 223 } 224 } 225 } 226 227 /* 228 * Create mount points and mount subpartitions on them. 229 */ 230 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 231 sp != NULL; sp = subpartition_next(sp)) { 232 if (subpartition_is_swap(sp)) { 233 /* 234 * Set this subpartition as the dump device. 235 */ 236 if (subpartition_get_capacity(sp) < storage_get_memsize(a->s)) 237 continue; 238 239 command_add(cmds, "%s%s -v %sdev/%s", 240 a->os_root, cmd_name(a, "DUMPON"), 241 a->os_root, 242 subpartition_get_device_name(sp)); 243 244 asprintf(&string, "/dev/%s", 245 subpartition_get_device_name(sp)); 246 config_var_set(rc_conf, "dumpdev", string); 247 free(string); 248 continue; 249 } 250 251 if (use_hammer == 0) { 252 /* / is already mounted */ 253 if (strcmp(subpartition_get_mountpoint(sp), "/") != 0) { 254 command_add(cmds, "%s%s -p %smnt%s", 255 a->os_root, cmd_name(a, "MKDIR"), 256 a->os_root, 257 subpartition_get_mountpoint(sp)); 258 /* Don't mount it if it's MFS-backed. */ 259 if (subpartition_is_mfsbacked(sp)) 260 continue; 261 command_add(cmds, "%s%s %sdev/%s %smnt%s", 262 a->os_root, cmd_name(a, "MOUNT"), 263 a->os_root, 264 subpartition_get_device_name(sp), 265 a->os_root, 266 subpartition_get_mountpoint(sp)); 267 } 268 } else if (strcmp(subpartition_get_mountpoint(sp), "/boot") == 0) { 269 command_add(cmds, "%s%s -p %smnt%s", 270 a->os_root, cmd_name(a, "MKDIR"), 271 a->os_root, 272 subpartition_get_mountpoint(sp)); 273 command_add(cmds, "%s%s %sdev/%s %smnt%s", 274 a->os_root, cmd_name(a, "MOUNT"), 275 a->os_root, 276 subpartition_get_device_name(sp), 277 a->os_root, 278 subpartition_get_mountpoint(sp)); 279 } 280 } 281 282 /* 283 * Take care of HAMMER PFS. 284 */ 285 if (use_hammer == 1) 286 handle_pfs(a, cmds); 287 288 /* 289 * Actually copy files now. 290 */ 291 292 for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) { 293 char *src, *dest, *dn, *tmp_dest; 294 295 dest = cp_src[i]; 296 297 /* 298 * If dest would be on an MFS-backed 299 * mountpoint, don't bother copying it. 300 */ 301 sp = subpartition_of(storage_get_selected_slice(a->s), 302 "%s%s", a->os_root, &dest[1]); 303 if (sp != NULL && subpartition_is_mfsbacked(sp)) { 304 continue; 305 } 306 307 /* 308 * Create intermediate directories, if needed. 309 */ 310 tmp_dest = aura_strdup(dest); 311 dn = dirname(tmp_dest); 312 if (is_dir("%s%s", a->os_root, &dn[1]) && 313 !is_dir("%smnt%s", a->os_root, dn)) { 314 command_add(cmds, "%s%s -p %smnt%s", 315 a->os_root, cmd_name(a, "MKDIR"), 316 a->os_root, dn); 317 } 318 aura_free(tmp_dest, "directory name"); 319 320 /* 321 * If a directory by the same name but with the suffix 322 * ".hdd" exists on the installation media, cpdup that 323 * instead. This is particularly useful with /etc, which 324 * may have significantly different behaviour on the 325 * live CD compared to a standard HDD boot. 326 */ 327 if (is_dir("%s%s.hdd", a->os_root, &dest[1])) 328 asprintf(&src, "%s.hdd", &dest[1]); 329 else 330 asprintf(&src, "%s", &dest[1]); 331 332 if (is_dir("%s%s", a->os_root, src) || is_file("%s%s", a->os_root, src)) { 333 /* 334 * Cpdup the chosen file or directory onto the HDD. 335 * if it exists on the source. 336 */ 337 cmd = command_add(cmds, "%s%s %s%s %smnt%s", 338 a->os_root, cmd_name(a, "CPDUP"), 339 a->os_root, src, 340 a->os_root, dest); 341 command_set_log_mode(cmd, COMMAND_LOG_QUIET); 342 } 343 } 344 345 /* 346 * Now, because cpdup does not cross mount points, 347 * we must copy anything that the user might've made a 348 * seperate mount point for (e.g. /usr/libdata/lint.) 349 */ 350 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 351 sp != NULL; sp = subpartition_next(sp)) { 352 /* 353 * If the subpartition is a swap subpartition or an 354 * MFS-backed mountpoint, don't try to copy anything 355 * into it. 356 */ 357 if (subpartition_is_swap(sp) || subpartition_is_mfsbacked(sp)) 358 continue; 359 360 /* 361 * If the mountpoint doesn't even exist on the installation 362 * medium, don't try to copy anything from it! We assume 363 * it's an empty subpartition for the user's needs. 364 */ 365 if (!is_dir("%s%s", a->os_root, &subpartition_get_mountpoint(sp)[1])) 366 continue; 367 368 /* 369 * Don't bother copying the mountpoint IF: 370 * - we've already said to copy it, or something besides it 371 * (it's a prefix of something in cp_src); or 372 * - we haven't said to copy it 373 * (nothing in cp_src is a prefix of it.) 374 */ 375 seen_it = 0; 376 prefix = 0; 377 for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) { 378 if (strncmp(subpartition_get_mountpoint(sp), cp_src[i], 379 strlen(subpartition_get_mountpoint(sp))) == 0) { 380 seen_it = 1; 381 break; 382 } 383 if (strncmp(cp_src[i], subpartition_get_mountpoint(sp), 384 strlen(cp_src[i])) == 0) { 385 prefix = 1; 386 } 387 } 388 if (seen_it || !prefix) 389 continue; 390 391 /* 392 * Otherwise, cpdup the subpartition. 393 * 394 * XXX check for .hdd-extended source dirs here, too, 395 * eventually - but for now, /etc.hdd will never be 396 * the kind of tricky sub-mount-within-a-mount-point 397 * that this part of the code is meant to handle. 398 */ 399 cmd = command_add(cmds, "%s%s %s%s %smnt%s", 400 a->os_root, cmd_name(a, "CPDUP"), 401 a->os_root, &subpartition_get_mountpoint(sp)[1], 402 a->os_root, subpartition_get_mountpoint(sp)); 403 command_set_log_mode(cmd, COMMAND_LOG_QUIET); 404 } 405 406 /* 407 * Create symlinks. 408 */ 409 410 /* Take care of /sys. */ 411 command_add(cmds, "%s%s -s usr/src/sys %smnt/sys", 412 a->os_root, cmd_name(a, "LN"), a->os_root); 413 414 /* 415 * If the user has both /var and /tmp subpartitions, 416 * symlink /var/tmp to /tmp. 417 */ 418 if (subpartition_find(storage_get_selected_slice(a->s), "/tmp") != NULL && 419 subpartition_find(storage_get_selected_slice(a->s), "/var") != NULL) { 420 command_add(cmds, "%s%s 1777 %smnt/tmp", 421 a->os_root, cmd_name(a, "CHMOD"), a->os_root); 422 command_add(cmds, "%s%s -rf %smnt/var/tmp", 423 a->os_root, cmd_name(a, "RM"), a->os_root); 424 command_add(cmds, "%s%s -s /tmp %smnt/var/tmp", 425 a->os_root, cmd_name(a, "LN"), a->os_root); 426 } 427 428 /* 429 * If the user has /var, but no /tmp, 430 * symlink /tmp to /var/tmp. 431 */ 432 if (subpartition_find(storage_get_selected_slice(a->s), "/tmp") == NULL && 433 subpartition_find(storage_get_selected_slice(a->s), "/var") != NULL) { 434 command_add(cmds, "%s%s -rf %smnt/tmp", 435 a->os_root, cmd_name(a, "RM"), a->os_root); 436 command_add(cmds, "%s%s -s /var/tmp %smnt/tmp", 437 a->os_root, cmd_name(a, "LN"), a->os_root); 438 } 439 440 /* 441 * If the user has /usr, but no /home, 442 * symlink /home to /usr/home. 443 */ 444 if (subpartition_find(storage_get_selected_slice(a->s), "/home") == NULL && 445 subpartition_find(storage_get_selected_slice(a->s), "/usr") != NULL) { 446 command_add(cmds, "%s%s -rf %smnt/home", 447 a->os_root, cmd_name(a, "RM"), a->os_root); 448 command_add(cmds, "%s%s %smnt/usr/home", 449 a->os_root, cmd_name(a, "MKDIR"), a->os_root); 450 command_add(cmds, "%s%s -s /usr/home %smnt/home", 451 a->os_root, cmd_name(a, "LN"), a->os_root); 452 } 453 454 /* 455 * XXX check for other possible combinations too? 456 */ 457 458 /* 459 * Clean up. In case some file didn't make it, use rm -f 460 */ 461 command_add(cmds, "%s%s -f %smnt/boot/loader.conf", 462 a->os_root, cmd_name(a, "RM"), a->os_root); 463 command_add(cmds, "%s%s -f %smnt/tmp/install.log", 464 a->os_root, cmd_name(a, "RM"), a->os_root); 465 466 /* 467 * Copy pristine versions over any files we might have installed. 468 * This allows the resulting file tree to be customized. 469 */ 470 for (i = 0; cp_src[i] != NULL && cp_src[i][0] != '\0'; i++) { 471 char *src, *dest, *dn, *tmp_dest; 472 473 src = cp_src[i]; 474 dest = cp_src[i]; 475 476 /* 477 * Get the directory that the desired thing to 478 * copy resides in. 479 */ 480 tmp_dest = aura_strdup(dest); 481 dn = dirname(tmp_dest); 482 483 /* 484 * If this dir doesn't exist in PRISTINE_DIR 485 * on the install media, just skip it. 486 */ 487 if (!is_dir("%s%s%s", a->os_root, PRISTINE_DIR, dn)) { 488 aura_free(tmp_dest, _("directory name")); 489 continue; 490 } 491 492 /* 493 * Create intermediate directories, if needed. 494 */ 495 if (!is_dir("%smnt%s", a->os_root, dn)) { 496 command_add(cmds, "%s%s -p %smnt%s", 497 a->os_root, cmd_name(a, "MKDIR"), 498 a->os_root, dn); 499 } 500 aura_free(tmp_dest, "directory name"); 501 502 /* 503 * Cpdup the chosen file or directory onto the HDD. 504 */ 505 cmd = command_add(cmds, "%s%s %s%s %smnt%s", 506 a->os_root, cmd_name(a, "CPDUP"), 507 a->os_root, src, 508 a->os_root, dest); 509 510 cmd = command_add(cmds, 511 "%s%s %s%s%s %smnt%s", 512 a->os_root, cmd_name(a, "CPDUP"), 513 a->os_root, PRISTINE_DIR, src, 514 a->os_root, dest); 515 command_set_log_mode(cmd, COMMAND_LOG_QUIET); 516 } 517 518 /* 519 * Rebuild the user database, to get rid of any extra users 520 * from the LiveCD that aren't supposed to be installed 521 * (copying a pristine master.passwd isn't enough.) 522 */ 523 command_add(cmds, "%s%s -p -d %smnt/etc %smnt/etc/master.passwd", 524 a->os_root, cmd_name(a, "PWD_MKDB"), a->os_root, a->os_root); 525 526 /* Create missing directories. */ 527 command_add(cmds, "%s%s %smnt/proc", 528 a->os_root, cmd_name(a, "MKDIR"), a->os_root); 529 command_add(cmds, "%s%s %smnt/mnt", 530 a->os_root, cmd_name(a, "MKDIR"), a->os_root); 531 532 /* Write new fstab. */ 533 command_add(cmds, "%s%s '%s' >%smnt/etc/fstab", 534 a->os_root, cmd_name(a, "ECHO"), 535 "# Device\t\tMountpoint\tFStype\tOptions\t\tDump\tPass#", 536 a->os_root); 537 538 for (sp = slice_subpartition_first(storage_get_selected_slice(a->s)); 539 sp != NULL; sp = subpartition_next(sp)) { 540 if (strcmp(subpartition_get_mountpoint(sp), "swap") == 0) { 541 command_add(cmds, "%s%s '/dev/%s\t\tnone\t\tswap\tsw\t\t0\t0' >>%smnt/etc/fstab", 542 a->os_root, cmd_name(a, "ECHO"), 543 subpartition_get_device_name(sp), 544 a->os_root); 545 } else if (use_hammer == 0) { 546 if (strcmp(subpartition_get_mountpoint(sp), "/") == 0) { 547 command_add(cmds, "%s%s '/dev/%s\t\t%s\t\tufs\trw\t\t1\t1' >>%smnt/etc/fstab", 548 a->os_root, cmd_name(a, "ECHO"), 549 subpartition_get_device_name(sp), 550 subpartition_get_mountpoint(sp), 551 a->os_root); 552 } else if (subpartition_is_mfsbacked(sp)) { 553 command_add(cmds, "%s%s 'swap\t\t%s\t\t\tmfs\trw,-s%lu,-b%lu,-f%lu\t\t1\t1' >>%smnt/etc/fstab", 554 a->os_root, cmd_name(a, "ECHO"), 555 subpartition_get_mountpoint(sp), 556 subpartition_get_capacity(sp) * 2048, 557 subpartition_get_bsize(sp), 558 subpartition_get_fsize(sp), 559 a->os_root); 560 } else { 561 command_add(cmds, "%s%s '/dev/%s\t\t%s\t\tufs\trw\t\t2\t2' >>%smnt/etc/fstab", 562 a->os_root, cmd_name(a, "ECHO"), 563 subpartition_get_device_name(sp), 564 subpartition_get_mountpoint(sp), 565 a->os_root); 566 } 567 } else { 568 if (strcmp(subpartition_get_mountpoint(sp), "/") == 0) { 569 command_add(cmds, "%s%s '/dev/%s\t\t%s\t\thammer\trw\t\t1\t1' >>%smnt/etc/fstab", 570 a->os_root, cmd_name(a, "ECHO"), 571 subpartition_get_device_name(sp), 572 subpartition_get_mountpoint(sp), 573 a->os_root); 574 command_add(cmds, "%s%s 'vfs.root.mountfrom=\"hammer:%s\"' >>%smnt/boot/loader.conf", 575 a->os_root, cmd_name(a, "ECHO"), 576 subpartition_get_device_name(sp), 577 a->os_root); 578 } else if (strcmp(subpartition_get_mountpoint(sp), "/boot") == 0) { 579 command_add(cmds, "%s%s '/dev/%s\t\t%s\t\tufs\trw\t\t1\t1' >>%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 } 586 } 587 588 /* 589 * Take care of HAMMER PFS null mounts. 590 */ 591 if (use_hammer == 1) { 592 for (j = 0; pfs_mountpt[j] != NULL; j++) { 593 if (rindex(pfs_mountpt[j]+1, '/') != NULL) 594 command_add(cmds, "%s%s '/pfs%s.%s\t%s\t\tnull\trw\t\t0\t0' >>%smnt/etc/fstab", 595 a->os_root, cmd_name(a, "ECHO"), 596 dirname(pfs_mountpt[j]), 597 basename(pfs_mountpt[j]), 598 pfs_mountpt[j], 599 a->os_root); 600 else 601 command_add(cmds, "%s%s '/pfs%s\t\t%s\t\tnull\trw\t\t0\t0' >>%smnt/etc/fstab", 602 a->os_root, cmd_name(a, "ECHO"), 603 pfs_mountpt[j], 604 pfs_mountpt[j], 605 a->os_root); 606 } 607 } 608 609 command_add(cmds, "%s%s '%s' >>%smnt/etc/fstab", 610 a->os_root, cmd_name(a, "ECHO"), 611 "proc\t\t\t/proc\t\tprocfs\trw\t\t0\t0", 612 a->os_root); 613 614 /* Backup the disklabel and the log. */ 615 command_add(cmds, "%s%s %s > %smnt/etc/disklabel.%s", 616 a->os_root, cmd_name(a, "DISKLABEL64"), 617 slice_get_device_name(storage_get_selected_slice(a->s)), 618 a->os_root, 619 slice_get_device_name(storage_get_selected_slice(a->s))); 620 621 /* 'chflags nohistory' as needed */ 622 for (j = 0; pfs_mountpt[j] != NULL; j++) 623 if (pfs_nohistory[j] == 1) 624 command_add(cmds, "%s%s -R nohistory %smnt%s", 625 a->os_root, cmd_name(a, "CHFLAGS"), 626 a->os_root, pfs_mountpt[j]); 627 628 command_add(cmds, "%s%s %sinstall.log %smnt/var/log/install.log", 629 a->os_root, cmd_name(a, "CP"), 630 a->tmp, a->os_root); 631 command_add(cmds, "%s%s 600 %smnt/var/log/install.log", 632 a->os_root, cmd_name(a, "CHMOD"), a->os_root); 633 634 /* Customize stuff here */ 635 if(is_file("%susr/local/bin/after_installation_routines.sh")) { 636 command_add(cmds, "%susr/local/bin/after_installation_routines.sh", 637 a->os_root, _("Running after installation custom routines...")); 638 } 639 640 /* 641 * Do it! 642 */ 643 /* commands_preview(a->c, cmds); */ 644 if (!commands_execute(a, cmds)) { 645 inform(a->c, _("%s was not fully installed."), OPERATING_SYSTEM_NAME); 646 a->result = 0; 647 } else { 648 a->result = 1; 649 } 650 commands_free(cmds); 651 cmds = commands_new(); 652 653 if (a->result) { 654 config_vars_write(rc_conf, CONFIG_TYPE_SH, "%smnt/etc/rc.conf", 655 a->os_root); 656 config_vars_free(rc_conf); 657 rc_conf = config_vars_new(); 658 } 659 660 /* 661 * Unmount everything we mounted on /mnt. This is done in a seperate 662 * command chain, so that partitions are unmounted, even if an error 663 * occurs in one of the preceding commands, or it is cancelled. 664 */ 665 unmount_all_under(a, cmds, "%smnt", a->os_root); 666 667 /* 668 * Once everything is unmounted, if the install went successfully, 669 * make sure once and for all that the disklabel is bootable. 670 */ 671 if (a->result) 672 command_add(cmds, "%s%s -B %s", 673 a->os_root, cmd_name(a, "DISKLABEL64"), 674 slice_get_device_name(storage_get_selected_slice(a->s))); 675 676 if (!commands_execute(a, cmds)) 677 inform(a->c, _("Warning: subpartitions were not correctly unmounted.")); 678 679 commands_free(cmds); 680 } 681