aboutsummaryrefslogtreecommitdiff
path: root/lib/libdisk
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libdisk')
-rw-r--r--lib/libdisk/Makefile11
-rw-r--r--lib/libdisk/create_chunk.c18
-rw-r--r--lib/libdisk/disk.c304
-rw-r--r--lib/libdisk/libdisk.h23
-rw-r--r--lib/libdisk/open_disk.c278
-rw-r--r--lib/libdisk/open_ia64_disk.c273
6 files changed, 603 insertions, 304 deletions
diff --git a/lib/libdisk/Makefile b/lib/libdisk/Makefile
index f3c560b9d2e0..762c904d9ac9 100644
--- a/lib/libdisk/Makefile
+++ b/lib/libdisk/Makefile
@@ -1,8 +1,15 @@
# $FreeBSD$
+.if ${MACHINE_ARCH} == "ia64"
+_open_disk= open_ia64_disk.c
+.else
+_change = change.c
+_open_disk= open_disk.c
+.endif
+
LIB= disk
-SRCS= blocks.c chunk.c disk.c change.c \
- create_chunk.c rules.c write_disk.c write_${MACHINE}_disk.c
+SRCS= blocks.c ${_change} chunk.c create_chunk.c disk.c ${_open_disk} \
+ rules.c write_disk.c write_${MACHINE}_disk.c
INCS= libdisk.h
WARNS= 2
diff --git a/lib/libdisk/create_chunk.c b/lib/libdisk/create_chunk.c
index d8e35e8ce232..fb3daecd2dd6 100644
--- a/lib/libdisk/create_chunk.c
+++ b/lib/libdisk/create_chunk.c
@@ -140,7 +140,7 @@ Fixup_Names(struct disk *d)
struct chunk *c1, *c2;
#if defined(__i386__) || defined(__ia64__) || defined(__amd64__)
struct chunk *c3;
- int j;
+ int j, max;
#endif
c1 = d->chunks;
@@ -153,8 +153,14 @@ Fixup_Names(struct disk *d)
c2->oname = malloc(12);
if (!c2->oname)
return -1;
- for (j = 1; j <= NDOSPART; j++) {
- sprintf(c2->oname, "%ss%d", c1->name, j);
+#ifdef __ia64__
+ max = d->gpt_size;
+#else
+ max = NDOSPART;
+#endif
+ for (j = 1; j <= max; j++) {
+ sprintf(c2->oname, "%s%c%d", c1->name,
+ (c1->type == whole) ? 'p' : 's', j);
for (c3 = c1->part; c3; c3 = c3->next)
if (c3 != c2 && !strcmp(c3->name, c2->oname))
goto match;
@@ -188,9 +194,10 @@ Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type,
int subtype, u_long flags, const char *sname)
{
int i;
- u_long l;
-
+
+#ifndef __ia64__
if (!(flags & CHUNK_FORCE_ALL)) {
+ u_long l;
#ifdef PC98
/* Never use the first cylinder */
if (!offset) {
@@ -209,6 +216,7 @@ Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type,
l = (offset+size) % (d->bios_sect * d->bios_hd);
size -= l;
}
+#endif
i = Add_Chunk(d, offset, size, "X", type, subtype, flags, sname);
Fixup_Names(d);
diff --git a/lib/libdisk/disk.c b/lib/libdisk/disk.c
index 6690fba90e8f..42eea97d0736 100644
--- a/lib/libdisk/disk.c
+++ b/lib/libdisk/disk.c
@@ -33,14 +33,6 @@ __FBSDID("$FreeBSD$");
#include <assert.h>
#include <uuid.h>
-#ifdef DEBUG
-#define DPRINT(x) warn x
-#define DPRINTX(x) warnx x
-#else
-#define DPRINT(x)
-#define DPRINTX(x)
-#endif
-
const enum platform platform =
#if defined (P_DEBUG)
P_DEBUG
@@ -81,303 +73,32 @@ chunk_name(chunk_e type)
}
};
-static chunk_e
-uuid_type(uuid_t *uuid)
-{
- static uuid_t _efi = GPT_ENT_TYPE_EFI;
- static uuid_t _mbr = GPT_ENT_TYPE_MBR;
- static uuid_t _fbsd = GPT_ENT_TYPE_FREEBSD;
- static uuid_t _swap = GPT_ENT_TYPE_FREEBSD_SWAP;
- static uuid_t _ufs = GPT_ENT_TYPE_FREEBSD_UFS;
- static uuid_t _vinum = GPT_ENT_TYPE_FREEBSD_VINUM;
-
- if (uuid_is_nil(uuid, NULL))
- return (unused);
- if (uuid_equal(uuid, &_efi, NULL))
- return (efi);
- if (uuid_equal(uuid, &_mbr, NULL))
- return (mbr);
- if (uuid_equal(uuid, &_fbsd, NULL))
- return (freebsd);
- if (uuid_equal(uuid, &_swap, NULL))
- return (part);
- if (uuid_equal(uuid, &_ufs, NULL))
- return (part);
- if (uuid_equal(uuid, &_vinum, NULL))
- return (part);
- return (spare);
-}
-
struct disk *
Open_Disk(const char *name)
{
-
- return Int_Open_Disk(name);
-}
-
-struct disk *
-Int_Open_Disk(const char *name)
-{
- uuid_t uuid;
- char *conftxt = NULL;
- struct disk *d;
+ char *conftxt;
size_t txtsize;
- int error, i;
- char *p, *q, *r, *a, *b, *n, *t, *sn;
- off_t o, len, off;
- u_int l, s, ty, sc, hd, alt;
- off_t lo[10];
+ int error;
error = sysctlbyname("kern.geom.conftxt", NULL, &txtsize, NULL, 0);
if (error) {
warn("kern.geom.conftxt sysctl not available, giving up!");
return (NULL);
}
- conftxt = (char *) malloc(txtsize+1);
+ conftxt = malloc(txtsize+1);
if (conftxt == NULL) {
- DPRINT(("cannot malloc memory for conftxt"));
+ warn("cannot malloc memory for conftxt");
return (NULL);
}
error = sysctlbyname("kern.geom.conftxt", conftxt, &txtsize, NULL, 0);
if (error) {
- DPRINT(("error reading kern.geom.conftxt from the system"));
+ warn("error reading kern.geom.conftxt from the system");
free(conftxt);
return (NULL);
}
conftxt[txtsize] = '\0'; /* in case kernel bug is still there */
- for (p = conftxt; p != NULL && *p; p = strchr(p, '\n')) {
- if (*p == '\n')
- p++;
- a = strsep(&p, " ");
- if (strcmp(a, "0"))
- continue;
-
- a = strsep(&p, " ");
- if (strcmp(a, "DISK"))
- continue;
-
- a = strsep(&p, " ");
- if (strcmp(a, name))
- continue;
- break;
- }
-
- q = strchr(p, '\n');
- if (q != NULL)
- *q++ = '\0';
-
- d = (struct disk *)calloc(sizeof *d, 1);
- if(d == NULL)
- return NULL;
-
- d->name = strdup(name);
-
- a = strsep(&p, " "); /* length in bytes */
- len = strtoimax(a, &r, 0);
- if (*r) {
- printf("BARF %d <%d>\n", __LINE__, *r);
- exit (0);
- }
-
- a = strsep(&p, " "); /* sectorsize */
- s = strtoul(a, &r, 0);
- if (*r) {
- printf("BARF %d <%d>\n", __LINE__, *r);
- exit (0);
- }
-
- if (s == 0)
- return (NULL);
- d->sector_size = s;
- len /= s; /* media size in number of sectors. */
-
- if (Add_Chunk(d, 0, len, name, whole, 0, 0, "-"))
- DPRINT(("Failed to add 'whole' chunk"));
-
- for (;;) {
- a = strsep(&p, " ");
- if (a == NULL)
- break;
- b = strsep(&p, " ");
- o = strtoul(b, &r, 0);
- if (*r) {
- printf("BARF %d <%d>\n", __LINE__, *r);
- exit (0);
- }
- if (!strcmp(a, "hd"))
- d->bios_hd = o;
- else if (!strcmp(a, "sc"))
- d->bios_sect = o;
- else
- printf("HUH ? <%s> <%s>\n", a, b);
- }
-
- /*
- * Calculate the number of cylinders this disk must have. If we have
- * an obvious insanity, we set the number of cyclinders to zero.
- */
- o = d->bios_hd * d->bios_sect;
- d->bios_cyl = (o != 0) ? len / o : 0;
-
- p = q;
- lo[0] = 0;
-
- for (; p != NULL && *p; p = q) {
- q = strchr(p, '\n');
- if (q != NULL)
- *q++ = '\0';
- a = strsep(&p, " "); /* Index */
- if (!strcmp(a, "0"))
- break;
- l = strtoimax(a, &r, 0);
- if (*r) {
- printf("BARF %d <%d>\n", __LINE__, *r);
- exit (0);
- }
- t = strsep(&p, " "); /* Type {SUN, BSD, MBR, PC98, GPT} */
- n = strsep(&p, " "); /* name */
- a = strsep(&p, " "); /* len */
- len = strtoimax(a, &r, 0);
- if (*r) {
- printf("BARF %d <%d>\n", __LINE__, *r);
- exit (0);
- }
- a = strsep(&p, " "); /* secsize */
- s = strtoimax(a, &r, 0);
- if (*r) {
- printf("BARF %d <%d>\n", __LINE__, *r);
- exit (0);
- }
- for (;;) {
- a = strsep(&p, " ");
- if (a == NULL)
- break;
- /* XXX: Slice name may include a space. */
- if (!strcmp(a, "sn")) {
- sn = p;
- break;
- }
- b = strsep(&p, " ");
- o = strtoimax(b, &r, 0);
- if (*r) {
- uint32_t status;
-
- uuid_from_string(b, &uuid, &status);
- if (status != uuid_s_ok) {
- printf("BARF %d <%d>\n", __LINE__, *r);
- exit (0);
- }
- o = uuid_type(&uuid);
- }
- if (!strcmp(a, "o"))
- off = o;
- else if (!strcmp(a, "i"))
- i = o;
- else if (!strcmp(a, "ty"))
- ty = o;
- else if (!strcmp(a, "sc"))
- sc = o;
- else if (!strcmp(a, "hd"))
- hd = o;
- else if (!strcmp(a, "alt"))
- alt = o;
- }
-
- /* PLATFORM POLICY BEGIN ----------------------------------- */
- if (platform == p_sparc64 && !strcmp(t, "SUN") && i == 2)
- continue;
- if (platform == p_sparc64 && !strcmp(t, "SUN") &&
- d->chunks->part->part == NULL) {
- d->bios_hd = hd;
- d->bios_sect = sc;
- o = d->chunks->size / (hd * sc);
- o *= (hd * sc);
- o -= alt * hd * sc;
- if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-"))
- DPRINT(("Failed to add 'freebsd' chunk"));
- }
- if (platform == p_alpha && !strcmp(t, "BSD") &&
- d->chunks->part->part == NULL) {
- if (Add_Chunk(d, 0, d->chunks->size, name, freebsd,
- 0, 0, "-"))
- DPRINT(("Failed to add 'freebsd' chunk"));
- }
- if (!strcmp(t, "BSD") && i == RAW_PART)
- continue;
- /* PLATFORM POLICY END ------------------------------------- */
-
- off /= s;
- len /= s;
- off += lo[l - 1];
- lo[l] = off;
- if (!strcmp(t, "SUN"))
- i = Add_Chunk(d, off, len, n, part, 0, 0, 0);
- else if (!strncmp(t, "MBR", 3)) {
- switch (ty) {
- case 0xa5:
- i = Add_Chunk(d, off, len, n, freebsd, ty, 0, 0);
- break;
- case 0x01:
- case 0x04:
- case 0x06:
- case 0x0b:
- case 0x0c:
- case 0x0e:
- i = Add_Chunk(d, off, len, n, fat, ty, 0, 0);
- break;
- case 0xef: /* EFI */
- i = Add_Chunk(d, off, len, n, efi, ty, 0, 0);
- break;
- default:
- i = Add_Chunk(d, off, len, n, mbr, ty, 0, 0);
- break;
- }
- } else if (!strcmp(t, "BSD"))
- i = Add_Chunk(d, off, len, n, part, ty, 0, 0);
- else if (!strcmp(t, "PC98")) {
- switch (ty & 0x7f) {
- case 0x14:
- i = Add_Chunk(d, off, len, n, freebsd, ty, 0,
- sn);
- break;
- case 0x20:
- case 0x21:
- case 0x22:
- case 0x23:
- case 0x24:
- i = Add_Chunk(d, off, len, n, fat, ty, 0, sn);
- break;
- default:
- i = Add_Chunk(d, off, len, n, pc98, ty, 0, sn);
- break;
- }
- } else if (!strcmp(t, "GPT"))
- i = Add_Chunk(d, off, len, n, ty, 0, 0, 0);
- else if (!strcmp(t, "BDE"))
- ; /* nothing */
- else if (!strcmp(t, "CCD"))
- ; /* nothing */
- else {
- printf("BARF %d\n", __LINE__);
- exit(0);
- }
- }
- /* PLATFORM POLICY BEGIN ------------------------------------- */
- /* We have a chance to do things on a blank disk here */
- if (platform == p_sparc64 && d->chunks->part->part == NULL) {
- hd = d->bios_hd;
- sc = d->bios_sect;
- o = d->chunks->size / (hd * sc);
- o *= (hd * sc);
- o -= 2 * hd * sc;
- if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-"))
- DPRINT(("Failed to add 'freebsd' chunk"));
- }
- /* PLATFORM POLICY END --------------------------------------- */
-
- return (d);
- i = 0;
+ return Int_Open_Disk(name, conftxt);
}
void
@@ -385,10 +106,8 @@ Debug_Disk(struct disk *d)
{
printf("Debug_Disk(%s)", d->name);
-#if 0
- printf(" real_geom=%lu/%lu/%lu",
- d->real_cyl, d->real_hd, d->real_sect);
-#endif
+
+#ifndef __ia64__
printf(" bios_geom=%lu/%lu/%lu = %lu\n",
d->bios_cyl, d->bios_hd, d->bios_sect,
d->bios_cyl * d->bios_hd * d->bios_sect);
@@ -401,11 +120,14 @@ Debug_Disk(struct disk *d)
#elif defined(__alpha__)
printf(" boot1=%p, bootmgr=%p\n",
d->boot1, d->bootmgr);
-#elif defined(__ia64__)
- printf("\n");
#else
/* Should be: error "Debug_Disk: unknown arch"; */
#endif
+#else /* __ia64__ */
+ printf(" media size=%lu, sector size=%lu\n", d->media_size,
+ d->sector_size);
+#endif
+
Debug_Chunk(d->chunks);
}
diff --git a/lib/libdisk/libdisk.h b/lib/libdisk/libdisk.h
index cc6b2fdc5a51..ac97d898b791 100644
--- a/lib/libdisk/libdisk.h
+++ b/lib/libdisk/libdisk.h
@@ -51,6 +51,7 @@ typedef enum {
} chunk_e;
__BEGIN_DECLS
+#ifndef __ia64__
struct disk {
char *name;
u_long bios_cyl;
@@ -62,20 +63,27 @@ struct disk {
u_char *bootmenu;
size_t bootmenu_size;
#else
-#if !defined(__ia64__)
u_char *bootmgr;
size_t bootmgr_size;
#endif
-#endif
-#if !defined(__ia64__)
u_char *boot1;
-#endif
#if defined(__i386__) || defined(__amd64__) /* the i386 needs extra help... */
u_char *boot2;
#endif
struct chunk *chunks;
u_long sector_size; /* media sector size, a power of 2 */
};
+#else /* !__ia64__ */
+struct disk {
+ char *name;
+ struct chunk *chunks;
+ u_long media_size;
+ u_long sector_size;
+ u_long lba_start;
+ u_long lba_end;
+ u_int gpt_size; /* Number of entries */
+};
+#endif
struct chunk {
struct chunk *next;
@@ -123,11 +131,13 @@ struct chunk {
#define CHUNK_FORCE_ALL 0x0040
#define CHUNK_AUTO_SIZE 0x0080
#define CHUNK_NEWFS 0x0100
+#define CHUNK_HAS_INDEX 0x0200
+#define CHUNK_ITOF(i) ((i & 0xFFFF) << 16)
+#define CHUNK_FTOI(f) ((f >> 16) & 0xFFFF)
#define DELCHUNK_NORMAL 0x0000
#define DELCHUNK_RECOVER 0x0001
-
const char *chunk_name(chunk_e);
const char *
@@ -259,6 +269,7 @@ ShowChunkFlags(struct chunk *);
*/
struct disklabel;
+
void Fill_Disklabel(struct disklabel *, const struct disk *,
const struct chunk *);
void Debug_Chunk(struct chunk *);
@@ -269,7 +280,7 @@ int Add_Chunk(struct disk *, long, u_long, const char *, chunk_e, int, u_long,
void *read_block(int, daddr_t, u_long);
int write_block(int, daddr_t, const void *, u_long);
struct disklabel *read_disklabel(int, daddr_t, u_long);
-struct disk *Int_Open_Disk(const char *);
+struct disk *Int_Open_Disk(const char *, char *);
int Fixup_Names(struct disk *);
int MakeDevChunk(const struct chunk *, const char *);
__END_DECLS
diff --git a/lib/libdisk/open_disk.c b/lib/libdisk/open_disk.c
new file mode 100644
index 000000000000..99abba500eeb
--- /dev/null
+++ b/lib/libdisk/open_disk.c
@@ -0,0 +1,278 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <inttypes.h>
+#include <err.h>
+#include <sys/sysctl.h>
+#include <sys/stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/disklabel.h>
+#include <sys/gpt.h>
+#include <paths.h>
+#include "libdisk.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <assert.h>
+
+#ifdef DEBUG
+#define DPRINT(x) warn x
+#define DPRINTX(x) warnx x
+#else
+#define DPRINT(x)
+#define DPRINTX(x)
+#endif
+
+struct disk *
+Int_Open_Disk(const char *name, char *conftxt)
+{
+ struct disk *d;
+ int i;
+ char *p, *q, *r, *a, *b, *n, *t, *sn;
+ off_t o, len, off;
+ u_int l, s, ty, sc, hd, alt;
+ off_t lo[10];
+
+ for (p = conftxt; p != NULL && *p; p = strchr(p, '\n')) {
+ if (*p == '\n')
+ p++;
+ a = strsep(&p, " ");
+ if (strcmp(a, "0"))
+ continue;
+
+ a = strsep(&p, " ");
+ if (strcmp(a, "DISK"))
+ continue;
+
+ a = strsep(&p, " ");
+ if (strcmp(a, name))
+ continue;
+ break;
+ }
+
+ q = strchr(p, '\n');
+ if (q != NULL)
+ *q++ = '\0';
+
+ d = (struct disk *)calloc(sizeof *d, 1);
+ if(d == NULL)
+ return NULL;
+
+ d->name = strdup(name);
+
+ a = strsep(&p, " "); /* length in bytes */
+ len = strtoimax(a, &r, 0);
+ if (*r) {
+ printf("BARF %d <%d>\n", __LINE__, *r);
+ exit (0);
+ }
+
+ a = strsep(&p, " "); /* sectorsize */
+ s = strtoul(a, &r, 0);
+ if (*r) {
+ printf("BARF %d <%d>\n", __LINE__, *r);
+ exit (0);
+ }
+
+ if (s == 0)
+ return (NULL);
+ d->sector_size = s;
+ len /= s; /* media size in number of sectors. */
+
+ if (Add_Chunk(d, 0, len, name, whole, 0, 0, "-"))
+ DPRINT(("Failed to add 'whole' chunk"));
+
+ for (;;) {
+ a = strsep(&p, " ");
+ if (a == NULL)
+ break;
+ b = strsep(&p, " ");
+ o = strtoul(b, &r, 0);
+ if (*r) {
+ printf("BARF %d <%d>\n", __LINE__, *r);
+ exit (0);
+ }
+ if (!strcmp(a, "hd"))
+ d->bios_hd = o;
+ else if (!strcmp(a, "sc"))
+ d->bios_sect = o;
+ else
+ printf("HUH ? <%s> <%s>\n", a, b);
+ }
+
+ /*
+ * Calculate the number of cylinders this disk must have. If we have
+ * an obvious insanity, we set the number of cyclinders to zero.
+ */
+ o = d->bios_hd * d->bios_sect;
+ d->bios_cyl = (o != 0) ? len / o : 0;
+
+ p = q;
+ lo[0] = 0;
+
+ for (; p != NULL && *p; p = q) {
+ q = strchr(p, '\n');
+ if (q != NULL)
+ *q++ = '\0';
+ a = strsep(&p, " "); /* Index */
+ if (!strcmp(a, "0"))
+ break;
+ l = strtoimax(a, &r, 0);
+ if (*r) {
+ printf("BARF %d <%d>\n", __LINE__, *r);
+ exit (0);
+ }
+ t = strsep(&p, " "); /* Type {SUN, BSD, MBR, PC98, GPT} */
+ n = strsep(&p, " "); /* name */
+ a = strsep(&p, " "); /* len */
+ len = strtoimax(a, &r, 0);
+ if (*r) {
+ printf("BARF %d <%d>\n", __LINE__, *r);
+ exit (0);
+ }
+ a = strsep(&p, " "); /* secsize */
+ s = strtoimax(a, &r, 0);
+ if (*r) {
+ printf("BARF %d <%d>\n", __LINE__, *r);
+ exit (0);
+ }
+ for (;;) {
+ a = strsep(&p, " ");
+ if (a == NULL)
+ break;
+ /* XXX: Slice name may include a space. */
+ if (!strcmp(a, "sn")) {
+ sn = p;
+ break;
+ }
+ b = strsep(&p, " ");
+ o = strtoimax(b, &r, 0);
+ if (*r) {
+ printf("BARF %d <%d>\n", __LINE__, *r);
+ exit (0);
+ }
+ if (!strcmp(a, "o"))
+ off = o;
+ else if (!strcmp(a, "i"))
+ i = o;
+ else if (!strcmp(a, "ty"))
+ ty = o;
+ else if (!strcmp(a, "sc"))
+ sc = o;
+ else if (!strcmp(a, "hd"))
+ hd = o;
+ else if (!strcmp(a, "alt"))
+ alt = o;
+ }
+
+ /* PLATFORM POLICY BEGIN ----------------------------------- */
+ if (platform == p_sparc64 && !strcmp(t, "SUN") && i == 2)
+ continue;
+ if (platform == p_sparc64 && !strcmp(t, "SUN") &&
+ d->chunks->part->part == NULL) {
+ d->bios_hd = hd;
+ d->bios_sect = sc;
+ o = d->chunks->size / (hd * sc);
+ o *= (hd * sc);
+ o -= alt * hd * sc;
+ if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-"))
+ DPRINT(("Failed to add 'freebsd' chunk"));
+ }
+ if (platform == p_alpha && !strcmp(t, "BSD") &&
+ d->chunks->part->part == NULL) {
+ if (Add_Chunk(d, 0, d->chunks->size, name, freebsd,
+ 0, 0, "-"))
+ DPRINT(("Failed to add 'freebsd' chunk"));
+ }
+ if (!strcmp(t, "BSD") && i == RAW_PART)
+ continue;
+ /* PLATFORM POLICY END ------------------------------------- */
+
+ off /= s;
+ len /= s;
+ off += lo[l - 1];
+ lo[l] = off;
+ if (!strcmp(t, "SUN"))
+ i = Add_Chunk(d, off, len, n, part, 0, 0, 0);
+ else if (!strncmp(t, "MBR", 3)) {
+ switch (ty) {
+ case 0xa5:
+ i = Add_Chunk(d, off, len, n, freebsd, ty, 0, 0);
+ break;
+ case 0x01:
+ case 0x04:
+ case 0x06:
+ case 0x0b:
+ case 0x0c:
+ case 0x0e:
+ i = Add_Chunk(d, off, len, n, fat, ty, 0, 0);
+ break;
+ case 0xef: /* EFI */
+ i = Add_Chunk(d, off, len, n, efi, ty, 0, 0);
+ break;
+ default:
+ i = Add_Chunk(d, off, len, n, mbr, ty, 0, 0);
+ break;
+ }
+ } else if (!strcmp(t, "BSD"))
+ i = Add_Chunk(d, off, len, n, part, ty, 0, 0);
+ else if (!strcmp(t, "PC98")) {
+ switch (ty & 0x7f) {
+ case 0x14:
+ i = Add_Chunk(d, off, len, n, freebsd, ty, 0,
+ sn);
+ break;
+ case 0x20:
+ case 0x21:
+ case 0x22:
+ case 0x23:
+ case 0x24:
+ i = Add_Chunk(d, off, len, n, fat, ty, 0, sn);
+ break;
+ default:
+ i = Add_Chunk(d, off, len, n, pc98, ty, 0, sn);
+ break;
+ }
+ } else if (!strcmp(t, "GPT"))
+ i = Add_Chunk(d, off, len, n, ty, 0, 0, 0);
+ else if (!strcmp(t, "BDE"))
+ ; /* nothing */
+ else if (!strcmp(t, "CCD"))
+ ; /* nothing */
+ else {
+ printf("BARF %d\n", __LINE__);
+ exit(0);
+ }
+ }
+ /* PLATFORM POLICY BEGIN ------------------------------------- */
+ /* We have a chance to do things on a blank disk here */
+ if (platform == p_sparc64 && d->chunks->part->part == NULL) {
+ hd = d->bios_hd;
+ sc = d->bios_sect;
+ o = d->chunks->size / (hd * sc);
+ o *= (hd * sc);
+ o -= 2 * hd * sc;
+ if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-"))
+ DPRINT(("Failed to add 'freebsd' chunk"));
+ }
+ /* PLATFORM POLICY END --------------------------------------- */
+
+ return (d);
+ i = 0;
+}
diff --git a/lib/libdisk/open_ia64_disk.c b/lib/libdisk/open_ia64_disk.c
new file mode 100644
index 000000000000..019bf36b9f8a
--- /dev/null
+++ b/lib/libdisk/open_ia64_disk.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2003 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/disklabel.h>
+#include <sys/diskmbr.h>
+#include <sys/gpt.h>
+#include <sys/uuid.h>
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <uuid.h>
+
+#include "libdisk.h"
+
+static uuid_t _efi = GPT_ENT_TYPE_EFI;
+static uuid_t _mbr = GPT_ENT_TYPE_MBR;
+static uuid_t _fbsd = GPT_ENT_TYPE_FREEBSD;
+static uuid_t _swap = GPT_ENT_TYPE_FREEBSD_SWAP;
+static uuid_t _ufs = GPT_ENT_TYPE_FREEBSD_UFS;
+
+static struct disk *
+parse_disk(char *conftxt, const char *name)
+{
+ char devname[64];
+ struct disk *disk;
+ struct dos_partition *part;
+ struct gpt_hdr *gpt;
+ char *buffer, *p, *q;
+ int fd, i;
+
+ disk = (struct disk *)calloc(sizeof *disk, 1);
+ if (disk == NULL)
+ return (NULL);
+
+ disk->name = strdup(name);
+ p = strsep(&conftxt, " "); /* media size */
+ disk->media_size = strtoimax(p, &q, 0);
+ if (*q)
+ goto fail;
+
+ p = strsep(&conftxt, " "); /* sector size */
+ disk->sector_size = strtoul(p, &q, 0);
+ if (*q)
+ goto fail;
+
+ if (disk->sector_size == 0)
+ disk->sector_size = 512;
+
+ if (disk->media_size % disk->sector_size)
+ goto fail;
+
+ /*
+ * We need to read the disk to get GPT specific information.
+ */
+
+ snprintf(devname, sizeof(devname), "%s%s", _PATH_DEV, name);
+ fd = open(devname, O_RDONLY);
+ if (fd == -1)
+ goto fail;
+ buffer = malloc(2 * disk->sector_size);
+ if (buffer == NULL) {
+ close (fd);
+ goto fail;
+ }
+ if (read(fd, buffer, 2 * disk->sector_size) == -1) {
+ free(buffer);
+ close(fd);
+ goto fail;
+ }
+ close(fd);
+
+ gpt = (struct gpt_hdr *)(buffer + disk->sector_size);
+ if (memcmp(gpt->hdr_sig, GPT_HDR_SIG, sizeof(gpt->hdr_sig))) {
+ /*
+ * No GPT present. Check if the MBR is empty (if present)
+ * or is a PMBR before declaring this disk as empty. If
+ * the MBR isn't empty, bail out. Let's not risk nuking a
+ * disk.
+ */
+ if (*(u_short *)(buffer + DOSMAGICOFFSET) == DOSMAGIC) {
+ for (i = 0; i < 4; i++) {
+ part = (struct dos_partition *)
+ (buffer + DOSPARTOFF + i * DOSPARTSIZE);
+ if (part->dp_typ != 0 &&
+ part->dp_typ != DOSPTYP_PMBR)
+ break;
+ }
+ if (i < 4) {
+ free(buffer);
+ goto fail;
+ }
+ }
+ disk->gpt_size = 128;
+ disk->lba_start = (disk->gpt_size * sizeof(struct gpt_ent)) /
+ disk->sector_size + 2;
+ disk->lba_end = (disk->media_size * disk->sector_size) -
+ disk->lba_start + 1;
+ } else {
+ disk->lba_start = gpt->hdr_lba_start;
+ disk->lba_end = gpt->hdr_lba_end;
+ disk->gpt_size = gpt->hdr_entries;
+ }
+ free(buffer);
+ Add_Chunk(disk, disk->lba_start, disk->lba_end - disk->lba_start + 1,
+ name, whole, 0, 0, "-");
+ return (disk);
+
+fail:
+ free(disk->name);
+ free(disk);
+ return (NULL);
+}
+
+struct disk *
+Int_Open_Disk(const char *name, char *conftxt)
+{
+ struct chunk chunk;
+ uuid_t uuid;
+ struct disk *disk;
+ char *p, *q, *r, *s, *sd, *type;
+ u_long i;
+ uint32_t status;
+
+ p = conftxt;
+ while (p != NULL && *p != 0) {
+ q = strsep(&p, " ");
+ if (strcmp(q, "0") == 0) {
+ q = strsep(&p, " ");
+ if (strcmp(q, "DISK") == 0) {
+ q = strsep(&p, " ");
+ if (strcmp(q, name) == 0)
+ break;
+ }
+ }
+ p = strchr(p, '\n');
+ if (p != NULL && *p == '\n')
+ p++;
+ conftxt = p;
+ }
+ if (p == NULL || *p == 0)
+ return (NULL);
+
+ conftxt = strchr(p, '\n');
+ if (conftxt != NULL)
+ *conftxt++ = '\0';
+
+ disk = parse_disk(p, name);
+ if (disk == NULL)
+ return (NULL);
+
+ while (conftxt != NULL && *conftxt != 0) {
+ p = conftxt;
+ conftxt = strchr(p, '\n');
+ if (conftxt != NULL)
+ *conftxt++ = '\0';
+
+ sd = strsep(&p, " "); /* depth */
+ if (strcmp(sd, "0") == 0)
+ break;
+
+ type = strsep(&p, " "); /* type */
+ chunk.name = strsep(&p, " "); /* name */
+ q = strsep(&p, " "); /* length */
+ i = strtoimax(q, &r, 0);
+ if (*r)
+ abort();
+ chunk.end = i / disk->sector_size;
+ q = strsep(&p, " "); /* sector size */
+
+ for (;;) {
+ q = strsep(&p, " ");
+ if (q == NULL)
+ break;
+ r = strsep(&p, " ");
+ i = strtoimax(r, &s, 0);
+ if (*s) {
+ uuid_from_string(r, &uuid, &status);
+ if (status != uuid_s_ok)
+ abort();
+ } else
+ status = uuid_s_invalid_string_uuid;
+ if (!strcmp(q, "o"))
+ chunk.offset = i / disk->sector_size;
+ else if (!strcmp(q, "i"))
+ chunk.flags = CHUNK_ITOF(i) | CHUNK_HAS_INDEX;
+ else if (!strcmp(q, "ty"))
+ chunk.subtype = i;
+ }
+
+ if (strncmp(type, "MBR", 3) == 0) {
+ switch (chunk.subtype) {
+ case 0xa5:
+ chunk.type = freebsd;
+ break;
+ case 0x01:
+ case 0x04:
+ case 0x06:
+ case 0x0b:
+ case 0x0c:
+ case 0x0e:
+ chunk.type = fat;
+ break;
+ case 0xef: /* EFI */
+ chunk.type = efi;
+ break;
+ default:
+ chunk.type = mbr;
+ break;
+ }
+ } else if (strcmp(type, "BSD") == 0) {
+ chunk.type = part;
+ } else if (strcmp(type, "GPT") == 0) {
+ chunk.subtype = 0;
+ if (status != uuid_s_ok)
+ abort();
+ if (uuid_is_nil(&uuid, NULL))
+ chunk.type = unused;
+ else if (uuid_equal(&uuid, &_efi, NULL))
+ chunk.type = efi;
+ else if (uuid_equal(&uuid, &_mbr, NULL))
+ chunk.type = unknown;
+ else if (uuid_equal(&uuid, &_fbsd, NULL)) {
+ chunk.type = freebsd;
+ chunk.subtype = 0xa5;
+ } else if (uuid_equal(&uuid, &_swap, NULL)) {
+ chunk.type = part;
+ chunk.subtype = FS_SWAP;
+ } else if (uuid_equal(&uuid, &_ufs, NULL)) {
+ chunk.type = part;
+ chunk.subtype = FS_BSDFFS;
+ } else
+ chunk.type = unknown;
+ } else
+ abort();
+
+ Add_Chunk(disk, chunk.offset, chunk.end, chunk.name,
+ chunk.type, chunk.subtype, chunk.flags, 0);
+ }
+
+ return (disk);
+}