install.c revision 8651
1/* 2 * The new sysinstall program. 3 * 4 * This is probably the last program in the `sysinstall' line - the next 5 * generation being essentially a complete rewrite. 6 * 7 * $Id: install.c,v 1.37 1995/05/20 14:05:28 jkh Exp $ 8 * 9 * Copyright (c) 1995 10 * Jordan Hubbard. All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer, 17 * verbatim and that no modifications are made prior to this 18 * point in the file. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 3. All advertising materials mentioning features or use of this software 23 * must display the following acknowledgement: 24 * This product includes software developed by Jordan Hubbard 25 * for the FreeBSD Project. 26 * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to 27 * endorse or promote products derived from this software without specific 28 * prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND 31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE 34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 36 * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) 37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 40 * SUCH DAMAGE. 41 * 42 */ 43 44#include "sysinstall.h" 45#include <sys/disklabel.h> 46#include <sys/errno.h> 47#include <sys/fcntl.h> 48#include <sys/wait.h> 49#include <unistd.h> 50 51Boolean SystemWasInstalled; 52 53static void make_filesystems(void); 54static void copy_self(void); 55static void cpio_extract(void); 56static void install_configuration_files(void); 57static void do_final_setup(void); 58 59static Boolean 60preInstallCheck(void) 61{ 62 if (!getenv(DISK_PARTITIONED)) { 63 msgConfirm("You need to partition your disk before you can proceed with\nthe installation."); 64 65 return FALSE; 66 } 67 if (!getenv(DISK_LABELLED)) { 68 msgConfirm("You need to assign disk labels before you can proceed with\nthe installation."); 69 return FALSE; 70 } 71 if (!Dists) { 72 msgConfirm("You haven't told me what distributions to load yet!\nPlease select a distribution from the Distributions menu."); 73 return FALSE; 74 } 75 return TRUE; 76} 77 78static void 79installInitial(void) 80{ 81 extern u_char boot1[], boot2[]; 82 extern u_char mbr[], bteasy17[]; 83 u_char *mbrContents; 84 Device **devs; 85 int i; 86 static Boolean alreadyDone = FALSE; 87 88 if (alreadyDone) 89 return; 90 91 /* If things aren't kosher, or we refuse to proceed, bail. */ 92 if (!preInstallCheck() 93 || msgYesNo("Last Chance! Are you SURE you want continue the installation?\n\nIf you're running this on an existing system, we STRONGLY\nencourage you to make proper backups before proceeding.\nWe take no responsibility for lost disk contents!")) 94 return; 95 96 mbrContents = NULL; 97 if (!msgYesNo("Would you like to install a boot manager?\n\nThis will allow you to easily select between other operating systems\non the first disk, or boot from a disk other than the first.")) 98 mbrContents = bteasy17; 99 else if (!msgYesNo("Would you like to remove an existing boot manager?")) 100 mbrContents = mbr; 101 devs = deviceFind(NULL, DEVICE_TYPE_DISK); 102 for (i = 0; devs[i]; i++) { 103 Disk *d = (Disk *)devs[i]->private; 104 Chunk *c1; 105 106 if (!devs[i]->enabled) 107 continue; 108 109 if (mbrContents) { 110 Set_Boot_Mgr(d, mbrContents); 111 mbrContents = NULL; 112 } 113 Set_Boot_Blocks(d, boot1, boot2); 114 msgNotify("Writing partition information to drive %s", d->name); 115 Write_Disk(d); 116 117 /* Now scan for bad blocks, if necessary */ 118 for (c1 = d->chunks->part; c1; c1 = c1->next) { 119 if (c1->flags & CHUNK_BAD144) { 120 int ret; 121 122 msgNotify("Running bad block scan on partition %s", c1->name); 123 ret = vsystem("bad144 -v /dev/r%s 1234", c1->name); 124 if (ret) 125 msgConfirm("Bad144 init on %s returned status of %d!", c1->name, ret); 126 ret = vsystem("bad144 -v -s /dev/r%s", c1->name); 127 if (ret) 128 msgConfirm("Bad144 scan on %s returned status of %d!", c1->name, ret); 129 } 130 } 131 } 132 make_filesystems(); 133 copy_self(); 134 dialog_clear(); 135 cpio_extract(); 136 alreadyDone = TRUE; 137} 138 139static void 140installFinal(void) 141{ 142 static Boolean alreadyDone = FALSE; 143 144 if (alreadyDone) 145 return; 146 install_configuration_files(); 147 do_final_setup(); 148 alreadyDone = TRUE; 149} 150 151int 152installCommit(char *str) 153{ 154 installInitial(); 155 if (!mediaVerify()) 156 return 0; 157 distExtractAll(); 158 installFinal(); 159 return 0; 160} 161 162/* Go newfs and/or mount all the filesystems we've been asked to */ 163static void 164make_filesystems(void) 165{ 166 int i; 167 Disk *disk; 168 Chunk *c1, *c2; 169 Device **devs; 170 171 command_clear(); 172 devs = deviceFind(NULL, DEVICE_TYPE_DISK); 173 174 /* First look for the root device and mount it */ 175 for (i = 0; devs[i]; i++) { 176 disk = (Disk *)devs[i]->private; 177 msgDebug("Scanning disk %s for root filesystem\n", disk->name); 178 if (!disk->chunks) 179 msgFatal("No chunk list found for %s!", disk->name); 180 for (c1 = disk->chunks->part; c1; c1 = c1->next) { 181 if (c1->type == freebsd) { 182 for (c2 = c1->part; c2; c2 = c2->next) { 183 if (c2->type == part && c2->subtype != FS_SWAP && 184 c2->private && c2->flags & CHUNK_IS_ROOT) { 185 char dname[40]; 186 PartInfo *p = (PartInfo *)c2->private; 187 188 if (strcmp(p->mountpoint, "/")) { 189 msgConfirm("Warning: %s is marked as a root partition but is mounted on %s", c2->name, p->mountpoint); 190 continue; 191 } 192 if (p->newfs) { 193 int i; 194 195 sprintf(dname, "/dev/r%sa", disk->name); 196 msgNotify("Making a new root filesystem on %s", dname); 197 i = vsystem("newfs %s", dname); 198 if (i) { 199 msgConfirm("Unable to make new root filesystem! Command returned status %d", i); 200 return; 201 } 202 } 203 else 204 msgConfirm("Warning: You have selected a Read-Only root device\nand may be unable to find the appropriate device entries on it\nif it is from an older pre-slice version of FreeBSD."); 205 sprintf(dname, "/dev/%sa", disk->name); 206 if (Mount("/mnt", dname)) { 207 msgConfirm("Unable to mount the root file system! Giving up."); 208 return; 209 } 210 else { 211 extern int makedevs(void); 212 213 msgNotify("Making device files"); 214 if (Mkdir("/mnt/dev", NULL) 215 || chdir("/mnt/dev") 216 || makedevs()) 217 msgConfirm("Failed to make some of the devices in /mnt!"); 218 if (Mkdir("/mnt/stand", NULL)) 219 msgConfirm("Unable to make /mnt/stand directory!"); 220 chdir("/"); 221 break; 222 } 223 } 224 } 225 } 226 } 227 } 228 229 /* Now buzz through the rest of the partitions and mount them too */ 230 for (i = 0; devs[i]; i++) { 231 disk = (Disk *)devs[i]->private; 232 if (!disk->chunks) 233 msgFatal("No chunk list found for %s!", disk->name); 234 235 /* Make the proper device mount points in /mnt/dev */ 236 MakeDevDisk(disk, "/mnt/dev"); 237 238 for (c1 = disk->chunks->part; c1; c1 = c1->next) { 239 if (c1->type == freebsd) { 240 for (c2 = c1->part; c2; c2 = c2->next) { 241 if (c2->type == part && c2->subtype != FS_SWAP && c2->private) { 242 PartInfo *tmp = (PartInfo *)c2->private; 243 244 if (!strcmp(tmp->mountpoint, "/")) 245 continue; 246 247 if (tmp->newfs) 248 command_shell_add(tmp->mountpoint, 249 "%s /mnt/dev/r%s", tmp->newfs_cmd, c2->name); 250 command_func_add(tmp->mountpoint, Mount, c2->name); 251 } 252 } 253 } 254 } 255 } 256 command_sort(); 257 command_execute(); 258} 259 260/* Copy the boot floppy contents into /stand */ 261static void 262copy_self(void) 263{ 264 int i; 265 266 msgNotify("Copying the boot floppy to /stand on root filesystem"); 267 i = vsystem("find -x / | cpio -pdmv /mnt"); 268 if (i) 269 msgConfirm("Copy returned error status of %d!", i); 270} 271 272static void 273cpio_extract(void) 274{ 275 int i, j, zpid, cpid, pfd[2]; 276 277 tryagain: 278 while (CpioFD == -1) { 279 msgConfirm("Please Insert CPIO floppy in floppy drive 0"); 280 CpioFD = open("/dev/rfd0", O_RDONLY); 281 if (CpioFD >= 0) 282 break; 283 msgDebug("Error on open of cpio floppy: %s (%d)\n", strerror(errno), errno); 284 } 285 j = fork(); 286 if (!j) { 287 chroot("/mnt"); chdir("/"); 288 msgNotify("Extracting contents of CPIO floppy..."); 289 pipe(pfd); 290 zpid = fork(); 291 if (!zpid) { 292 dup2(CpioFD, 0); close(CpioFD); 293 dup2(pfd[1], 1); close(pfd[1]); 294 close(pfd[0]); 295 i = execl("/stand/gunzip", "/stand/gunzip", 0); 296 msgDebug("/stand/gunzip command returns %d status\n", i); 297 exit(i); 298 } 299 cpid = fork(); 300 if (!cpid) { 301 dup2(pfd[0], 0); close(pfd[0]); 302 close(CpioFD); 303 close(pfd[1]); 304 if (DebugFD != -1) { 305 dup2(DebugFD, 1); 306 dup2(DebugFD, 2); 307 } 308 else { 309 close(1); open("/dev/null", O_WRONLY); 310 dup2(1, 2); 311 } 312 i = execl("/stand/cpio", "/stand/cpio", "-iduvm", 0); 313 msgDebug("/stand/cpio command returns %d status\n", i); 314 exit(i); 315 } 316 close(pfd[0]); 317 close(pfd[1]); 318 close(CpioFD); 319 320 i = waitpid(zpid, &j, 0); 321 if (i < 0 || j) { 322 msgConfirm("gunzip returned status of %d, error was: %s (%d)! Help!", j, strerror(errno), errno); 323 exit(1); 324 } 325 i = waitpid(cpid, &j, 0); 326 if (i < 0 || j) { 327 msgConfirm("cpio returned status of %d, error was: %s (%d)! Help!", j, strerror(errno), errno); 328 exit(2); 329 } 330 exit(0); 331 } 332 else 333 i = wait(&j); 334 if (i < 0 || j || access("/mnt/OK", R_OK) == -1) { 335 msgConfirm("CPIO floppy did not extract properly! Please verify\n\that your media is correct and try again"); 336 close(CpioFD); 337 CpioFD = -1; 338 goto tryagain; 339 } 340 unlink("/mnt/OK"); 341} 342 343static void 344install_configuration_files(void) 345{ 346} 347 348static void 349do_final_setup(void) 350{ 351} 352