install.c revision 8628
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.29 1995/05/19 01:49:57 gpalmer 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 <unistd.h> 49 50Boolean SystemWasInstalled; 51 52static void make_filesystems(void); 53static void copy_self(void); 54static void cpio_extract(void); 55static void install_configuration_files(void); 56static void do_final_setup(void); 57 58static Boolean 59preInstallCheck(void) 60{ 61 if (!getenv(DISK_PARTITIONED)) { 62 msgConfirm("You need to partition your disk before you can proceed with\nthe installation."); 63 64 return FALSE; 65 } 66 if (!getenv(DISK_LABELLED)) { 67 msgConfirm("You need to assign disk labels before you can proceed with\nthe installation."); 68 return FALSE; 69 } 70 if (!Dists) { 71 msgConfirm("You haven't told me what distributions to load yet!\nPlease select a distribution from the Distributions menu."); 72 return FALSE; 73 } 74 if (!mediaVerify()) 75 return FALSE; 76 return TRUE; 77} 78 79int 80installCommit(char *str) 81{ 82 extern u_char boot1[], boot2[]; 83 extern u_char mbr[], bteasy17[]; 84 u_char *mbrContents; 85 Device **devs; 86 int i; 87 88 /* If things aren't kosher, or we refuse to proceed, bail. */ 89 if (!preInstallCheck() 90 || 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!")) 91 return 0; 92 93 mbrContents = NULL; 94 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.")) 95 mbrContents = bteasy17; 96 else if (!msgYesNo("Would you like to remove an existing boot manager?")) 97 mbrContents = mbr; 98 devs = deviceFind(NULL, DEVICE_TYPE_DISK); 99 for (i = 0; devs[i]; i++) { 100 Disk *d = (Disk *)devs[i]->private; 101 Chunk *c1; 102 103 if (!devs[i]->enabled) 104 continue; 105 106 if (mbrContents) { 107 Set_Boot_Mgr(d, mbrContents); 108 mbrContents = NULL; 109 } 110 Set_Boot_Blocks(d, boot1, boot2); 111 msgNotify("Writing partition information to drive %s", d->name); 112 Write_Disk(d); 113 114 /* Now scan for bad blocks, if necessary */ 115 for (c1 = d->chunks->part; c1; c1 = c1->next) { 116 if (c1->flags & CHUNK_BAD144) { 117 int ret; 118 119 msgNotify("Running bad block scan on partition %s", c1->name); 120 ret = vsystem("bad144 -v /dev/r%s 1234", c1->name); 121 if (ret) 122 msgConfirm("Bad144 init on %s returned status of %d!", c1->name, ret); 123 ret = vsystem("bad144 -v -s /dev/r%s", c1->name); 124 if (ret) 125 msgConfirm("Bad144 scan on %s returned status of %d!", c1->name, ret); 126 } 127 } 128 } 129 make_filesystems(); 130 copy_self(); 131 cpio_extract(); 132 distExtractAll(); 133 install_configuration_files(); 134 do_final_setup(); 135 return 1; 136} 137 138/* Go newfs and/or mount all the filesystems we've been asked to */ 139static void 140make_filesystems(void) 141{ 142 int i; 143 Disk *disk; 144 Chunk *c1, *c2; 145 Device **devs; 146 147 command_clear(); 148 devs = deviceFind(NULL, DEVICE_TYPE_DISK); 149 150 /* First look for the root device and mount it */ 151 for (i = 0; devs[i]; i++) { 152 disk = (Disk *)devs[i]->private; 153 msgDebug("Scanning disk %s for root filesystem\n", disk->name); 154 if (!disk->chunks) 155 msgFatal("No chunk list found for %s!", disk->name); 156 for (c1 = disk->chunks->part; c1; c1 = c1->next) { 157 if (c1->type == freebsd) { 158 for (c2 = c1->part; c2; c2 = c2->next) { 159 if (c2->type == part && c2->subtype != FS_SWAP && 160 c2->private && c2->flags & CHUNK_IS_ROOT) { 161 char dname[40]; 162 PartInfo *p = (PartInfo *)c2->private; 163 164 if (strcmp(p->mountpoint, "/")) { 165 msgConfirm("Warning: %s is marked as a root partition but is mounted on %s", c2->name, p->mountpoint); 166 continue; 167 } 168 if (p->newfs) { 169 int i; 170 171 sprintf(dname, "/dev/r%sa", disk->name); 172 msgNotify("Making a new root filesystem on %s", dname); 173 i = vsystem("newfs %s", dname); 174 if (i) { 175 msgConfirm("Unable to make new root filesystem! Command returned status %d", i); 176 return; 177 } 178 } 179 else 180 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."); 181 sprintf(dname, "/dev/%sa", disk->name); 182 if (Mount("/mnt", dname)) { 183 msgConfirm("Unable to mount the root file system! Giving up."); 184 return; 185 } 186 else { 187 extern int makedevs(void); 188 189 if (Mkdir("/mnt/dev", NULL) 190 || chdir("/mnt/dev") 191 || makedevs()) 192 msgConfirm("Failed to make some of the devices in /mnt!"); 193 if (Mkdir("/mnt/stand", NULL)) 194 msgConfirm("Unable to make /mnt/stand directory!"); 195 chdir("/"); 196 break; 197 } 198 } 199 } 200 } 201 } 202 } 203 204 /* Now buzz through the rest of the partitions and mount them too */ 205 for (i = 0; devs[i]; i++) { 206 disk = (Disk *)devs[i]->private; 207 if (!disk->chunks) 208 msgFatal("No chunk list found for %s!", disk->name); 209 210 /* Make the proper device mount points in /mnt/dev */ 211 MakeDevDisk(disk, "/mnt/dev"); 212 213 for (c1 = disk->chunks->part; c1; c1 = c1->next) { 214 if (c1->type == freebsd) { 215 for (c2 = c1->part; c2; c2 = c2->next) { 216 if (c2->type == part && c2->subtype != FS_SWAP && c2->private) { 217 PartInfo *tmp = (PartInfo *)c2->private; 218 219 if (!strcmp(tmp->mountpoint, "/")) 220 continue; 221 222 if (tmp->newfs) 223 command_shell_add(tmp->mountpoint, 224 "%s /mnt/dev/r%s", tmp->newfs_cmd, c2->name); 225 command_func_add(tmp->mountpoint, Mount, c2->name); 226 } 227 } 228 } 229 } 230 } 231 command_sort(); 232 command_execute(); 233} 234 235/* Copy the boot floppy contents into /stand */ 236static void 237copy_self(void) 238{ 239 int i; 240 241 msgNotify("Copying the boot floppy to /stand on root filesystem"); 242 chdir("/"); 243 i = vsystem("find -x . | cpio -pdmv /mnt/stand"); 244 if (i) 245 msgConfirm("Copy returned error status of %d!", i); 246} 247 248static void 249cpio_extract(void) 250{ 251 int i, j, zpid, cpid, pfd[2]; 252 extern int wait(int *status); 253 254 while (CpioFD == -1) { 255 msgConfirm("Please Insert CPIO floppy in floppy drive 0"); 256 CpioFD = open("/dev/rfd0", O_RDONLY); 257 } 258 msgNotify("Extracting contents of CPIO floppy..."); 259 pipe(pfd); 260 zpid = fork(); 261 if (!zpid) { 262 close(0); dup(CpioFD); close(CpioFD); 263 close(1); dup(pfd[1]); close(pfd[1]); 264 close(pfd[0]); 265 i = execl("/stand/gunzip", "/stand/gunzip", 0); 266 msgDebug("/stand/gunzip command returns %d status\n", i); 267 exit(i); 268 } 269 cpid = fork(); 270 if (!cpid) { 271 close(0); dup(pfd[0]); close(pfd[0]); 272 close(CpioFD); 273 close(pfd[1]); 274 if (DebugFD != -1) { 275 dup2(DebugFD, 1); 276 dup2(DebugFD, 2); 277 } 278 else { 279 close(1); open("/dev/null", O_WRONLY); 280 dup2(1, 2); 281 } 282 chdir("/mnt"); 283 i = execl("/stand/cpio", "/stand/cpio", "-iduvm", 0); 284 msgDebug("/stand/cpio command returns %d status\n", i); 285 exit(i); 286 } 287 close(pfd[0]); 288 close(pfd[1]); 289 close(CpioFD); 290 i = wait(&j); 291 if (i < 0 || j) 292 msgFatal("Pid %d, status %d, cpio=%d, gunzip=%d.\nerror:%s", 293 i, j, cpid, zpid, strerror(errno)); 294 i = wait(&j); 295 if (i < 0 || j) 296 msgFatal("Pid %d, status %d, cpio=%d, gunzip=%d.\nerror:%s", 297 i, j, cpid, zpid, strerror(errno)); 298} 299 300static void 301install_configuration_files(void) 302{ 303} 304 305static void 306do_final_setup(void) 307{ 308} 309