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