disk.c revision 114329
1238438Sdteske/* 2238438Sdteske * ---------------------------------------------------------------------------- 3238438Sdteske * "THE BEER-WARE LICENSE" (Revision 42): 4263980Sdteske * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you 5238438Sdteske * can do whatever you want with this stuff. If we meet some day, and you think 6238438Sdteske * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 7238438Sdteske * ---------------------------------------------------------------------------- 8238438Sdteske */ 9238438Sdteske 10238438Sdteske#include <sys/cdefs.h> 11238438Sdteske__FBSDID("$FreeBSD: head/lib/libdisk/disk.c 114329 2003-04-30 21:03:16Z peter $"); 12238438Sdteske 13238438Sdteske#include <stdio.h> 14238438Sdteske#include <stdlib.h> 15238438Sdteske#include <unistd.h> 16238438Sdteske#include <fcntl.h> 17238438Sdteske#include <string.h> 18238438Sdteske#include <inttypes.h> 19238438Sdteske#include <err.h> 20238438Sdteske#include <sys/sysctl.h> 21238438Sdteske#include <sys/stdint.h> 22238438Sdteske#include <sys/types.h> 23238438Sdteske#include <sys/stat.h> 24238438Sdteske#include <sys/ioctl.h> 25238438Sdteske#include <sys/disklabel.h> 26238438Sdteske#include <sys/uuid.h> 27238438Sdteske#include <sys/gpt.h> 28238438Sdteske#include <paths.h> 29238438Sdteske#include "libdisk.h" 30238438Sdteske 31238438Sdteske#include <ctype.h> 32240684Sdteske#include <errno.h> 33240684Sdteske#include <assert.h> 34244675Sdteske#include <uuid.h> 35240684Sdteske 36240684Sdteske#ifdef DEBUG 37240684Sdteske#define DPRINT(x) warn x 38240684Sdteske#define DPRINTX(x) warnx x 39238438Sdteske#else 40238438Sdteske#define DPRINT(x) 41238438Sdteske#define DPRINTX(x) 42238438Sdteske#endif 43238438Sdteske 44238438Sdteskeconst enum platform platform = 45238438Sdteske#if defined (P_DEBUG) 46238438Sdteske P_DEBUG 47238438Sdteske#elif defined (PC98) 48238438Sdteske p_pc98 49238438Sdteske#elif defined(__i386__) 50238438Sdteske p_i386 51263980Sdteske#elif defined(__alpha__) 52263980Sdteske p_alpha 53263980Sdteske#elif defined(__sparc64__) 54263980Sdteske p_sparc64 55263980Sdteske#elif defined(__ia64__) 56263980Sdteske p_ia64 57263980Sdteske#elif defined(__ppc__) 58263980Sdteske p_ppc 59263980Sdteske#elif defined(__amd64__) 60238438Sdteske p_amd64 61263980Sdteske#else 62263980Sdteske IHAVENOIDEA 63263980Sdteske#endif 64263980Sdteske ; 65263980Sdteske 66238438Sdteskeconst char * 67263980Sdteskechunk_name(chunk_e type) 68263980Sdteske{ 69238438Sdteske switch(type) { 70238438Sdteske case unused: return ("unused"); 71249751Sdteske case mbr: return ("mbr"); 72238438Sdteske case part: return ("part"); 73249751Sdteske case gpt: return ("gpt"); 74249751Sdteske case pc98: return ("pc98"); 75238438Sdteske case sun: return ("sun"); 76238438Sdteske case freebsd: return ("freebsd"); 77238438Sdteske case fat: return ("fat"); 78251264Sdteske case spare: return ("spare"); 79251264Sdteske case efi: return ("efi"); 80251264Sdteske default: return ("??"); 81251264Sdteske } 82249751Sdteske}; 83238438Sdteske 84238438Sdteskestatic chunk_e 85238438Sdteskeuuid_type(uuid_t *uuid) 86238438Sdteske{ 87263980Sdteske static uuid_t _efi = GPT_ENT_TYPE_EFI; 88263980Sdteske static uuid_t _mbr = GPT_ENT_TYPE_MBR; 89263980Sdteske static uuid_t _fbsd = GPT_ENT_TYPE_FREEBSD; 90263980Sdteske static uuid_t _swap = GPT_ENT_TYPE_FREEBSD_SWAP; 91263980Sdteske static uuid_t _ufs = GPT_ENT_TYPE_FREEBSD_UFS; 92263980Sdteske static uuid_t _vinum = GPT_ENT_TYPE_FREEBSD_VINUM; 93263980Sdteske 94238438Sdteske if (uuid_is_nil(uuid, NULL)) 95251190Sdteske return (unused); 96251190Sdteske if (uuid_equal(uuid, &_efi, NULL)) 97251190Sdteske return (efi); 98251190Sdteske if (uuid_equal(uuid, &_mbr, NULL)) 99251264Sdteske return (mbr); 100251190Sdteske if (uuid_equal(uuid, &_fbsd, NULL)) 101251190Sdteske return (freebsd); 102238438Sdteske if (uuid_equal(uuid, &_swap, NULL)) 103251236Sdteske return (part); 104251236Sdteske if (uuid_equal(uuid, &_ufs, NULL)) 105249751Sdteske return (part); 106238438Sdteske if (uuid_equal(uuid, &_vinum, NULL)) 107238438Sdteske return (part); 108238438Sdteske return (spare); 109238438Sdteske} 110249751Sdteske 111251264Sdteskestruct disk * 112251190SdteskeOpen_Disk(const char *name) 113251190Sdteske{ 114240768Sdteske 115240768Sdteske return Int_Open_Disk(name); 116240768Sdteske} 117251236Sdteske 118240768Sdteskestruct disk * 119238438SdteskeInt_Open_Disk(const char *name) 120238438Sdteske{ 121263980Sdteske uuid_t uuid; 122238438Sdteske char *conftxt = NULL; 123263980Sdteske struct disk *d; 124263980Sdteske size_t txtsize; 125263980Sdteske int error, i; 126238438Sdteske char *p, *q, *r, *a, *b, *n, *t, *sn; 127238438Sdteske off_t o, len, off; 128238438Sdteske u_int l, s, ty, sc, hd, alt; 129263980Sdteske off_t lo[10]; 130263980Sdteske 131238438Sdteske error = sysctlbyname("kern.geom.conftxt", NULL, &txtsize, NULL, 0); 132238438Sdteske if (error) { 133238438Sdteske warn("kern.geom.conftxt sysctl not available, giving up!"); 134263980Sdteske return (NULL); 135238438Sdteske } 136238438Sdteske conftxt = (char *) malloc(txtsize+1); 137263980Sdteske if (conftxt == NULL) { 138256181Sdteske DPRINT(("cannot malloc memory for conftxt")); 139238438Sdteske return (NULL); 140238438Sdteske } 141263980Sdteske error = sysctlbyname("kern.geom.conftxt", conftxt, &txtsize, NULL, 0); 142263980Sdteske if (error) { 143256181Sdteske DPRINT(("error reading kern.geom.conftxt from the system")); 144238438Sdteske free(conftxt); 145238438Sdteske return (NULL); 146238438Sdteske } 147263980Sdteske conftxt[txtsize] = '\0'; /* in case kernel bug is still there */ 148252795Sdteske 149238438Sdteske for (p = conftxt; p != NULL && *p; p = strchr(p, '\n')) { 150238438Sdteske if (*p == '\n') 151238438Sdteske p++; 152238438Sdteske a = strsep(&p, " "); 153263980Sdteske if (strcmp(a, "0")) 154252795Sdteske continue; 155238438Sdteske 156263980Sdteske a = strsep(&p, " "); 157238438Sdteske if (strcmp(a, "DISK")) 158238438Sdteske continue; 159263980Sdteske 160263980Sdteske a = strsep(&p, " "); 161238438Sdteske if (strcmp(a, name)) 162238438Sdteske continue; 163238438Sdteske break; 164263980Sdteske } 165238438Sdteske 166238438Sdteske q = strchr(p, '\n'); 167238438Sdteske if (q != NULL) 168256181Sdteske *q++ = '\0'; 169238438Sdteske 170238438Sdteske d = (struct disk *)calloc(sizeof *d, 1); 171263980Sdteske if(d == NULL) 172238438Sdteske return NULL; 173263980Sdteske 174263980Sdteske d->name = strdup(name); 175263980Sdteske 176263980Sdteske a = strsep(&p, " "); /* length in bytes */ 177263980Sdteske len = strtoimax(a, &r, 0); 178238438Sdteske if (*r) { 179238438Sdteske printf("BARF %d <%d>\n", __LINE__, *r); 180238438Sdteske exit (0); 181263980Sdteske } 182263980Sdteske 183263980Sdteske a = strsep(&p, " "); /* sectorsize */ 184263980Sdteske s = strtoul(a, &r, 0); 185238438Sdteske if (*r) { 186263980Sdteske printf("BARF %d <%d>\n", __LINE__, *r); 187263980Sdteske exit (0); 188238438Sdteske } 189238438Sdteske 190263980Sdteske if (s == 0) 191238438Sdteske return (NULL); 192263980Sdteske d->sector_size = s; 193238438Sdteske len /= s; /* media size in number of sectors. */ 194263980Sdteske 195263980Sdteske if (Add_Chunk(d, 0, len, name, whole, 0, 0, "-")) 196238438Sdteske DPRINT(("Failed to add 'whole' chunk")); 197238438Sdteske 198263980Sdteske for (;;) { 199238438Sdteske a = strsep(&p, " "); 200263980Sdteske if (a == NULL) 201238438Sdteske break; 202238438Sdteske b = strsep(&p, " "); 203238438Sdteske o = strtoul(b, &r, 0); 204238438Sdteske if (*r) { 205263980Sdteske printf("BARF %d <%d>\n", __LINE__, *r); 206238438Sdteske exit (0); 207263980Sdteske } 208251190Sdteske if (!strcmp(a, "hd")) 209251190Sdteske d->bios_hd = o; 210263980Sdteske else if (!strcmp(a, "sc")) 211251190Sdteske d->bios_sect = o; 212251190Sdteske else 213251190Sdteske printf("HUH ? <%s> <%s>\n", a, b); 214263980Sdteske } 215263980Sdteske 216240768Sdteske /* 217240768Sdteske * Calculate the number of cylinders this disk must have. If we have 218263980Sdteske * an obvious insanity, we set the number of cyclinders to zero. 219263980Sdteske */ 220238438Sdteske o = d->bios_hd * d->bios_sect; 221238438Sdteske d->bios_cyl = (o != 0) ? len / o : 0; 222263980Sdteske 223238438Sdteske p = q; 224263980Sdteske lo[0] = 0; 225251190Sdteske 226251190Sdteske for (; p != NULL && *p; p = q) { 227263980Sdteske q = strchr(p, '\n'); 228251190Sdteske if (q != NULL) 229251190Sdteske *q++ = '\0'; 230251190Sdteske a = strsep(&p, " "); /* Index */ 231263980Sdteske if (!strcmp(a, "0")) 232263980Sdteske break; 233240768Sdteske l = strtoimax(a, &r, 0); 234240768Sdteske if (*r) { 235263980Sdteske printf("BARF %d <%d>\n", __LINE__, *r); 236263980Sdteske exit (0); 237238438Sdteske } 238238438Sdteske t = strsep(&p, " "); /* Type {SUN, BSD, MBR, PC98, GPT} */ 239263980Sdteske n = strsep(&p, " "); /* name */ 240238438Sdteske a = strsep(&p, " "); /* len */ 241238438Sdteske len = strtoimax(a, &r, 0); 242263980Sdteske if (*r) { 243252795Sdteske printf("BARF %d <%d>\n", __LINE__, *r); 244238438Sdteske exit (0); 245238438Sdteske } 246238438Sdteske a = strsep(&p, " "); /* secsize */ 247238438Sdteske s = strtoimax(a, &r, 0); 248263980Sdteske if (*r) { 249251544Sdteske printf("BARF %d <%d>\n", __LINE__, *r); 250263980Sdteske exit (0); 251263980Sdteske } 252263980Sdteske for (;;) { 253263980Sdteske a = strsep(&p, " "); 254263980Sdteske if (a == NULL) 255251547Sdteske break; 256251547Sdteske /* XXX: Slice name may include a space. */ 257251547Sdteske if (!strcmp(a, "sn")) { 258238438Sdteske sn = p; 259263980Sdteske break; 260238438Sdteske } 261238438Sdteske b = strsep(&p, " "); 262263980Sdteske o = strtoimax(b, &r, 0); 263238438Sdteske if (*r) { 264238438Sdteske uint32_t status; 265238438Sdteske 266256181Sdteske uuid_from_string(b, &uuid, &status); 267238438Sdteske if (status != uuid_s_ok) { 268238438Sdteske printf("BARF %d <%d>\n", __LINE__, *r); 269263980Sdteske exit (0); 270238438Sdteske } 271238438Sdteske o = uuid_type(&uuid); 272263980Sdteske } 273238438Sdteske if (!strcmp(a, "o")) 274238438Sdteske off = o; 275238438Sdteske else if (!strcmp(a, "i")) 276238438Sdteske i = o; 277263980Sdteske else if (!strcmp(a, "ty")) 278238438Sdteske ty = o; 279238438Sdteske else if (!strcmp(a, "sc")) 280263980Sdteske sc = o; 281263980Sdteske else if (!strcmp(a, "hd")) 282238438Sdteske hd = o; 283263980Sdteske else if (!strcmp(a, "alt")) 284256181Sdteske alt = o; 285238438Sdteske } 286238438Sdteske 287263980Sdteske /* PLATFORM POLICY BEGIN ----------------------------------- */ 288238438Sdteske if (platform == p_sparc64 && !strcmp(t, "SUN") && i == 2) 289251266Sdteske continue; 290263980Sdteske if (platform == p_sparc64 && !strcmp(t, "SUN") && 291263980Sdteske d->chunks->part->part == NULL) { 292238438Sdteske d->bios_hd = hd; 293238438Sdteske d->bios_sect = sc; 294238438Sdteske o = d->chunks->size / (hd * sc); 295263980Sdteske o *= (hd * sc); 296263980Sdteske o -= alt * hd * sc; 297263980Sdteske if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-")) 298238438Sdteske DPRINT(("Failed to add 'freebsd' chunk")); 299238438Sdteske } 300238438Sdteske if (platform == p_alpha && !strcmp(t, "BSD") && 301238438Sdteske d->chunks->part->part == NULL) { 302263980Sdteske if (Add_Chunk(d, 0, d->chunks->size, name, freebsd, 303263980Sdteske 0, 0, "-")) 304238438Sdteske DPRINT(("Failed to add 'freebsd' chunk")); 305263980Sdteske } 306263980Sdteske if (!strcmp(t, "BSD") && i == RAW_PART) 307251190Sdteske continue; 308251190Sdteske /* PLATFORM POLICY END ------------------------------------- */ 309263980Sdteske 310263980Sdteske off /= s; 311263980Sdteske len /= s; 312251190Sdteske off += lo[l - 1]; 313263980Sdteske lo[l] = off; 314238438Sdteske if (!strcmp(t, "SUN")) 315263980Sdteske i = Add_Chunk(d, off, len, n, part, 0, 0, 0); 316238438Sdteske else if (!strncmp(t, "MBR", 3)) { 317238438Sdteske switch (ty) { 318263980Sdteske case 0xa5: 319238438Sdteske i = Add_Chunk(d, off, len, n, freebsd, ty, 0, 0); 320238438Sdteske break; 321263980Sdteske case 0x01: 322263980Sdteske case 0x04: 323263980Sdteske case 0x06: 324263980Sdteske case 0x0b: 325240768Sdteske case 0x0c: 326240768Sdteske case 0x0e: 327263980Sdteske i = Add_Chunk(d, off, len, n, fat, ty, 0, 0); 328263980Sdteske break; 329263980Sdteske case 0xef: /* EFI */ 330263980Sdteske i = Add_Chunk(d, off, len, n, efi, ty, 0, 0); 331263980Sdteske break; 332238438Sdteske default: 333238438Sdteske i = Add_Chunk(d, off, len, n, mbr, ty, 0, 0); 334263980Sdteske break; 335238438Sdteske } 336263980Sdteske } else if (!strcmp(t, "BSD")) 337263980Sdteske i = Add_Chunk(d, off, len, n, part, ty, 0, 0); 338238438Sdteske else if (!strcmp(t, "PC98")) { 339238438Sdteske switch (ty & 0x7f) { 340238438Sdteske case 0x14: 341263980Sdteske i = Add_Chunk(d, off, len, n, freebsd, ty, 0, 342263980Sdteske sn); 343263980Sdteske break; 344263980Sdteske case 0x20: 345263980Sdteske case 0x21: 346263980Sdteske case 0x22: 347263980Sdteske case 0x23: 348263980Sdteske case 0x24: 349251264Sdteske i = Add_Chunk(d, off, len, n, fat, ty, 0, sn); 350263980Sdteske break; 351263980Sdteske default: 352263980Sdteske i = Add_Chunk(d, off, len, n, pc98, ty, 0, sn); 353263980Sdteske break; 354263980Sdteske } 355263980Sdteske } else if (!strcmp(t, "GPT")) 356263980Sdteske i = Add_Chunk(d, off, len, n, ty, 0, 0, 0); 357263980Sdteske else if (!strcmp(t, "BDE")) 358263980Sdteske ; /* nothing */ 359263980Sdteske else { 360238438Sdteske printf("BARF %d\n", __LINE__); 361238438Sdteske exit(0); 362263980Sdteske } 363263980Sdteske } 364263980Sdteske /* PLATFORM POLICY BEGIN ------------------------------------- */ 365263980Sdteske /* We have a chance to do things on a blank disk here */ 366263980Sdteske if (platform == p_sparc64 && d->chunks->part->part == NULL) { 367263980Sdteske hd = d->bios_hd; 368263980Sdteske sc = d->bios_sect; 369263980Sdteske o = d->chunks->size / (hd * sc); 370263980Sdteske o *= (hd * sc); 371238438Sdteske o -= 2 * hd * sc; 372238438Sdteske if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-")) 373238438Sdteske DPRINT(("Failed to add 'freebsd' chunk")); 374263980Sdteske } 375238438Sdteske /* PLATFORM POLICY END --------------------------------------- */ 376238438Sdteske 377263980Sdteske return (d); 378263980Sdteske i = 0; 379263980Sdteske} 380240768Sdteske 381251236Sdteskevoid 382251236SdteskeDebug_Disk(struct disk *d) 383251236Sdteske{ 384263980Sdteske 385251236Sdteske printf("Debug_Disk(%s)", d->name); 386260678Sdteske#if 0 387251236Sdteske printf(" real_geom=%lu/%lu/%lu", 388251236Sdteske d->real_cyl, d->real_hd, d->real_sect); 389251236Sdteske#endif 390260678Sdteske printf(" bios_geom=%lu/%lu/%lu = %lu\n", 391263980Sdteske d->bios_cyl, d->bios_hd, d->bios_sect, 392238438Sdteske d->bios_cyl * d->bios_hd * d->bios_sect); 393238438Sdteske#if defined(PC98) 394263980Sdteske printf(" boot1=%p, boot2=%p, bootipl=%p, bootmenu=%p\n", 395263980Sdteske d->boot1, d->boot2, d->bootipl, d->bootmenu); 396238438Sdteske#elif defined(__i386__) || defined(__amd64__) 397263980Sdteske printf(" boot1=%p, boot2=%p, bootmgr=%p\n", 398263980Sdteske d->boot1, d->boot2, d->bootmgr); 399251242Sdteske#elif defined(__alpha__) 400251242Sdteske printf(" boot1=%p, bootmgr=%p\n", 401251242Sdteske d->boot1, d->bootmgr); 402238438Sdteske#elif defined(__ia64__) 403263980Sdteske printf("\n"); 404238438Sdteske#else 405238438Sdteske/* Should be: error "Debug_Disk: unknown arch"; */ 406238438Sdteske#endif 407238438Sdteske Debug_Chunk(d->chunks); 408263980Sdteske} 409256181Sdteske 410238438Sdteskevoid 411238438SdteskeFree_Disk(struct disk *d) 412263980Sdteske{ 413263980Sdteske if (d->chunks) 414263980Sdteske Free_Chunk(d->chunks); 415263980Sdteske if (d->name) 416263980Sdteske free(d->name); 417263980Sdteske#ifdef PC98 418263980Sdteske if (d->bootipl) 419263980Sdteske free(d->bootipl); 420263980Sdteske if (d->bootmenu) 421263980Sdteske free(d->bootmenu); 422263980Sdteske#else 423263980Sdteske#if !defined(__ia64__) 424263980Sdteske if (d->bootmgr) 425263980Sdteske free(d->bootmgr); 426263980Sdteske#endif 427263980Sdteske#endif 428263980Sdteske#if !defined(__ia64__) 429263980Sdteske if (d->boot1) 430263980Sdteske free(d->boot1); 431263980Sdteske#endif 432263980Sdteske#if defined(__i386__) || defined(__amd64__) 433263980Sdteske if (d->boot2) 434263980Sdteske free(d->boot2); 435263980Sdteske#endif 436263980Sdteske free(d); 437263980Sdteske} 438263980Sdteske 439263980Sdteske#if 0 440263980Sdteskevoid 441263980SdteskeCollapse_Disk(struct disk *d) 442263980Sdteske{ 443263980Sdteske 444263980Sdteske while (Collapse_Chunk(d, d->chunks)) 445263980Sdteske ; 446263980Sdteske} 447263980Sdteske#endif 448263980Sdteske 449263980Sdteskestatic int 450263980Sdteskeqstrcmp(const void* a, const void* b) 451263980Sdteske{ 452263980Sdteske char *str1 = *(char**)a; 453263980Sdteske char *str2 = *(char**)b; 454263980Sdteske 455263980Sdteske return strcmp(str1, str2); 456263980Sdteske} 457263980Sdteske 458263980Sdteskechar ** 459263980SdteskeDisk_Names() 460263980Sdteske{ 461263980Sdteske int disk_cnt; 462263980Sdteske static char **disks; 463263980Sdteske int error; 464263980Sdteske size_t listsize; 465263980Sdteske char *disklist; 466263980Sdteske 467263980Sdteske error = sysctlbyname("kern.disks", NULL, &listsize, NULL, 0); 468263980Sdteske if (error) { 469263980Sdteske warn("kern.disks sysctl not available"); 470263980Sdteske return NULL; 471263980Sdteske } 472263980Sdteske 473263980Sdteske disks = malloc(sizeof *disks * (1 + MAX_NO_DISKS)); 474263980Sdteske if (disks == NULL) 475263980Sdteske return NULL; 476263980Sdteske disklist = (char *)malloc(listsize + 1); 477263980Sdteske if (disklist == NULL) { 478263980Sdteske free(disks); 479263980Sdteske return NULL; 480263980Sdteske } 481263980Sdteske memset(disks,0,sizeof *disks * (1 + MAX_NO_DISKS)); 482263980Sdteske memset(disklist, 0, listsize + 1); 483263980Sdteske error = sysctlbyname("kern.disks", disklist, &listsize, NULL, 0); 484263980Sdteske if (error) { 485263980Sdteske free(disklist); 486263980Sdteske free(disks); 487263980Sdteske return NULL; 488263980Sdteske } 489263980Sdteske for (disk_cnt = 0; disk_cnt < MAX_NO_DISKS; disk_cnt++) { 490263980Sdteske disks[disk_cnt] = strsep(&disklist, " "); 491263980Sdteske if (disks[disk_cnt] == NULL) 492263980Sdteske break; 493263980Sdteske } 494263980Sdteske qsort(disks, disk_cnt, sizeof(char*), qstrcmp); 495263980Sdteske return disks; 496263980Sdteske} 497263980Sdteske 498263980Sdteske#ifdef PC98 499263980Sdteskevoid 500263980SdteskeSet_Boot_Mgr(struct disk *d, const u_char *bootipl, const size_t bootipl_size, 501263980Sdteske const u_char *bootmenu, const size_t bootmenu_size) 502263980Sdteske#else 503263980Sdteskevoid 504263980SdteskeSet_Boot_Mgr(struct disk *d, const u_char *b, const size_t s) 505263980Sdteske#endif 506263980Sdteske{ 507263980Sdteske#if !defined(__ia64__) 508263980Sdteske#ifdef PC98 509263980Sdteske if (d->sector_size == 0) 510263980Sdteske return; 511263980Sdteske if (bootipl_size % d->sector_size != 0) 512263980Sdteske return; 513263980Sdteske if (d->bootipl) 514263980Sdteske free(d->bootipl); 515263980Sdteske if (!bootipl) { 516263980Sdteske d->bootipl = NULL; 517263980Sdteske } else { 518263980Sdteske d->bootipl_size = bootipl_size; 519263980Sdteske d->bootipl = malloc(bootipl_size); 520263980Sdteske if (!d->bootipl) 521263980Sdteske return; 522263980Sdteske memcpy(d->bootipl, bootipl, bootipl_size); 523263980Sdteske } 524263980Sdteske 525263980Sdteske if (bootmenu_size % d->sector_size != 0) 526263980Sdteske return; 527263980Sdteske if (d->bootmenu) 528263980Sdteske free(d->bootmenu); 529263980Sdteske if (!bootmenu) { 530263980Sdteske d->bootmenu = NULL; 531263980Sdteske } else { 532263980Sdteske d->bootmenu_size = bootmenu_size; 533263980Sdteske d->bootmenu = malloc(bootmenu_size); 534263980Sdteske if (!d->bootmenu) 535263980Sdteske return; 536263980Sdteske memcpy(d->bootmenu, bootmenu, bootmenu_size); 537263980Sdteske } 538263980Sdteske#else 539263980Sdteske if (d->sector_size == 0) 540263980Sdteske return; 541263980Sdteske if (s % d->sector_size != 0) 542263980Sdteske return; 543263980Sdteske if (d->bootmgr) 544263980Sdteske free(d->bootmgr); 545263980Sdteske if (!b) { 546263980Sdteske d->bootmgr = NULL; 547263980Sdteske } else { 548263980Sdteske d->bootmgr_size = s; 549263980Sdteske d->bootmgr = malloc(s); 550263980Sdteske if (!d->bootmgr) 551263980Sdteske return; 552263980Sdteske memcpy(d->bootmgr, b, s); 553263980Sdteske } 554263980Sdteske#endif 555263980Sdteske#endif 556263980Sdteske} 557263980Sdteske 558263980Sdteskeint 559263980SdteskeSet_Boot_Blocks(struct disk *d, const u_char *b1, const u_char *b2) 560263980Sdteske{ 561263980Sdteske#if defined(__i386__) || defined(__amd64__) 562263980Sdteske if (d->boot1) 563263980Sdteske free(d->boot1); 564263980Sdteske d->boot1 = malloc(512); 565263980Sdteske if (!d->boot1) 566263980Sdteske return -1; 567263980Sdteske memcpy(d->boot1, b1, 512); 568263980Sdteske if (d->boot2) 569263980Sdteske free(d->boot2); 570263980Sdteske d->boot2 = malloc(15 * 512); 571263980Sdteske if (!d->boot2) 572263980Sdteske return -1; 573263980Sdteske memcpy(d->boot2, b2, 15 * 512); 574263980Sdteske#elif defined(__alpha__) 575263980Sdteske if (d->boot1) 576263980Sdteske free(d->boot1); 577263980Sdteske d->boot1 = malloc(15 * 512); 578263980Sdteske if (!d->boot1) 579263980Sdteske return -1; 580263980Sdteske memcpy(d->boot1, b1, 15 * 512); 581263980Sdteske#elif defined(__sparc64__) 582263980Sdteske if (d->boot1 != NULL) 583263980Sdteske free(d->boot1); 584263980Sdteske d->boot1 = malloc(16 * 512); 585263980Sdteske if (d->boot1 == NULL) 586263980Sdteske return (-1); 587263980Sdteske memcpy(d->boot1, b1, 16 * 512); 588263980Sdteske#elif defined(__ia64__) 589263980Sdteske /* nothing */ 590263980Sdteske#else 591263980Sdteske/* Should be: #error "Set_Boot_Blocks: unknown arch"; */ 592244675Sdteske#endif 593244675Sdteske return 0; 594244675Sdteske} 595244675Sdteske 596238438Sdteske#ifdef PC98 597const char * 598slice_type_name( int type, int subtype ) 599{ 600 601 switch (type) { 602 case whole: 603 return "whole"; 604 case fat: 605 return "fat"; 606 case freebsd: 607 switch (subtype) { 608 case 0xc494: return "freebsd"; 609 default: return "unknown"; 610 } 611 case unused: 612 return "unused"; 613 default: 614 return "unknown"; 615 } 616} 617#else /* PC98 */ 618const char * 619slice_type_name( int type, int subtype ) 620{ 621 622 switch (type) { 623 case whole: 624 return "whole"; 625 case mbr: 626 switch (subtype) { 627 case 1: return "fat (12-bit)"; 628 case 2: return "XENIX /"; 629 case 3: return "XENIX /usr"; 630 case 4: return "fat (16-bit,<=32Mb)"; 631 case 5: return "extended DOS"; 632 case 6: return "fat (16-bit,>32Mb)"; 633 case 7: return "NTFS/HPFS/QNX"; 634 case 8: return "AIX bootable"; 635 case 9: return "AIX data"; 636 case 10: return "OS/2 bootmgr"; 637 case 11: return "fat (32-bit)"; 638 case 12: return "fat (32-bit,LBA)"; 639 case 14: return "fat (16-bit,>32Mb,LBA)"; 640 case 15: return "extended DOS, LBA"; 641 case 18: return "Compaq Diagnostic"; 642 case 84: return "OnTrack diskmgr"; 643 case 100: return "Netware 2.x"; 644 case 101: return "Netware 3.x"; 645 case 115: return "SCO UnixWare"; 646 case 128: return "Minix 1.1"; 647 case 129: return "Minix 1.5"; 648 case 130: return "linux_swap"; 649 case 131: return "ext2fs"; 650 case 166: return "OpenBSD FFS"; /* 0xA6 */ 651 case 169: return "NetBSD FFS"; /* 0xA9 */ 652 case 182: return "OpenBSD"; /* dedicated */ 653 case 183: return "bsd/os"; 654 case 184: return "bsd/os swap"; 655 case 238: return "EFI GPT"; 656 case 239: return "EFI Sys. Part."; 657 default: return "unknown"; 658 } 659 case fat: 660 return "fat"; 661 case freebsd: 662 switch (subtype) { 663 case 165: return "freebsd"; 664 default: return "unknown"; 665 } 666 case extended: 667 return "extended"; 668 case part: 669 return "part"; 670 case efi: 671 return "efi"; 672 case unused: 673 return "unused"; 674 default: 675 return "unknown"; 676 } 677} 678#endif /* PC98 */ 679