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