install.c revision 8658
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.40 1995/05/20 18:37:03 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!", 126 c1->name, ret); 127 ret = vsystem("bad144 -v -s /dev/r%s", c1->name); 128 if (ret) 129 msgConfirm("Bad144 scan on %s returned status of %d!", 130 c1->name, ret); 131 } 132 } 133 } 134 make_filesystems(); 135 copy_self(); 136 dialog_clear(); 137 cpio_extract(); 138 alreadyDone = TRUE; 139} 140 141static void 142installFinal(void) 143{ 144 static Boolean alreadyDone = FALSE; 145 146 if (alreadyDone) 147 return; 148 install_configuration_files(); 149 do_final_setup(); 150 alreadyDone = TRUE; 151} 152 153int 154installCommit(char *str) 155{ 156 installInitial(); 157 if (!mediaVerify()) 158 return 0; 159 distExtractAll(); 160 installFinal(); 161 return 0; 162} 163 164/* Go newfs and/or mount all the filesystems we've been asked to */ 165static void 166make_filesystems(void) 167{ 168 int i; 169 Disk *disk; 170 Chunk *c1, *c2; 171 Device **devs; 172 173 command_clear(); 174 devs = deviceFind(NULL, DEVICE_TYPE_DISK); 175 176 /* First look for the root device and mount it */ 177 for (i = 0; devs[i]; i++) { 178 disk = (Disk *)devs[i]->private; 179 msgDebug("Scanning disk %s for root filesystem\n", disk->name); 180 if (!disk->chunks) 181 msgFatal("No chunk list found for %s!", disk->name); 182 for (c1 = disk->chunks->part; c1; c1 = c1->next) { 183 if (c1->type == freebsd) { 184 for (c2 = c1->part; c2; c2 = c2->next) { 185 if (c2->type == part && c2->subtype != FS_SWAP && 186 c2->private && c2->flags & CHUNK_IS_ROOT) { 187 char dname[40]; 188 PartInfo *p = (PartInfo *)c2->private; 189 190 if (strcmp(p->mountpoint, "/")) { 191 msgConfirm("Warning: %s is marked as a root partition but is mounted on %s", c2->name, p->mountpoint); 192 continue; 193 } 194 if (p->newfs) { 195 int i; 196 197 sprintf(dname, "/dev/r%sa", disk->name); 198 msgNotify("Making a new root filesystem on %s", dname); 199 i = vsystem("newfs %s", dname); 200 if (i) { 201 msgConfirm("Unable to make new root filesystem! Command returned status %d", i); 202 return; 203 } 204 } 205 else 206 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."); 207 sprintf(dname, "/dev/%sa", disk->name); 208 if (Mount("/mnt", dname)) { 209 msgConfirm("Unable to mount the root file system! Giving up."); 210 return; 211 } 212 else { 213 extern int makedevs(void); 214 215 msgNotify("Making device files"); 216 if (Mkdir("/mnt/dev", NULL) 217 || chdir("/mnt/dev") 218 || makedevs()) 219 msgConfirm("Failed to make some of the devices in /mnt!"); 220 if (Mkdir("/mnt/stand", NULL)) 221 msgConfirm("Unable to make /mnt/stand directory!"); 222 chdir("/"); 223 break; 224 } 225 } 226 } 227 } 228 } 229 } 230 231 /* Now buzz through the rest of the partitions and mount them too */ 232 for (i = 0; devs[i]; i++) { 233 disk = (Disk *)devs[i]->private; 234 if (!disk->chunks) 235 msgFatal("No chunk list found for %s!", disk->name); 236 237 /* Make the proper device mount points in /mnt/dev */ 238 MakeDevDisk(disk, "/mnt/dev"); 239 240 for (c1 = disk->chunks->part; c1; c1 = c1->next) { 241 if (c1->type == freebsd) { 242 for (c2 = c1->part; c2; c2 = c2->next) { 243 if (c2->type == part && c2->subtype != FS_SWAP && c2->private) { 244 PartInfo *tmp = (PartInfo *)c2->private; 245 246 if (!strcmp(tmp->mountpoint, "/")) 247 continue; 248 249 if (tmp->newfs) 250 command_shell_add(tmp->mountpoint, 251 "%s /mnt/dev/r%s", tmp->newfs_cmd, c2->name); 252 command_func_add(tmp->mountpoint, Mount, c2->name); 253 } 254 } 255 } 256 } 257 } 258 command_sort(); 259 command_execute(); 260} 261 262/* Copy the boot floppy contents into /stand */ 263static void 264copy_self(void) 265{ 266 int i; 267 268 msgNotify("Copying the boot floppy to /stand on root filesystem"); 269 i = vsystem("find -x / | cpio -pdmv /mnt"); 270 if (i) 271 msgConfirm("Copy returned error status of %d!", i); 272} 273 274static void 275cpio_extract(void) 276{ 277 int i, j, zpid, cpid, pfd[2]; 278 279 tryagain: 280 while (CpioFD == -1) { 281 msgConfirm("Please Insert CPIO floppy in floppy drive 0"); 282 CpioFD = open("/dev/rfd0", O_RDWR); 283 if (CpioFD >= 0) 284 break; 285 msgDebug("Error on open of cpio floppy: %s (%d)\n", strerror(errno), errno); 286 } 287 j = fork(); 288 if (!j) { 289 chroot("/mnt"); chdir("/"); 290 msgNotify("Extracting contents of CPIO floppy..."); 291 pipe(pfd); 292 zpid = fork(); 293 if (!zpid) { 294 dup2(CpioFD, 0); close(CpioFD); 295 dup2(pfd[1], 1); close(pfd[1]); 296 close(pfd[0]); 297 i = execl("/stand/gunzip", "/stand/gunzip", 0); 298 msgDebug("/stand/gunzip command returns %d status\n", i); 299 exit(i); 300 } 301 cpid = fork(); 302 if (!cpid) { 303 dup2(pfd[0], 0); close(pfd[0]); 304 close(CpioFD); 305 close(pfd[1]); 306 if (DebugFD != -1) { 307 dup2(DebugFD, 1); 308 dup2(DebugFD, 2); 309 } 310 else { 311 close(1); open("/dev/null", O_WRONLY); 312 dup2(1, 2); 313 } 314 i = execl("/stand/cpio", "/stand/cpio", "-iduvm", 0); 315 msgDebug("/stand/cpio command returns %d status\n", i); 316 exit(i); 317 } 318 close(pfd[0]); 319 close(pfd[1]); 320 close(CpioFD); 321 322 i = waitpid(zpid, &j, 0); 323 if (i < 0 || j) { 324 msgConfirm("gunzip returned status of %d, error was: %s (%d)!", j, strerror(errno), errno); 325 exit(1); 326 } 327 i = waitpid(cpid, &j, 0); 328 if (i < 0 || j) { 329 msgConfirm("cpio returned status of %d, error was: %s (%d)!", j, strerror(errno), errno); 330 exit(2); 331 } 332 exit(0); 333 } 334 else 335 i = wait(&j); 336 if (i < 0 || j || access("/mnt/OK", R_OK) == -1) { 337 msgConfirm("CPIO floppy did not extract properly! Please verify\nthat your media is correct and try again"); 338 close(CpioFD); 339 CpioFD = -1; 340 goto tryagain; 341 } 342 unlink("/mnt/OK"); 343} 344 345static void 346install_configuration_files(void) 347{ 348} 349 350static void 351do_final_setup(void) 352{ 353} 354