summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2002-10-29 12:13:36 +0000
committerphk <phk@FreeBSD.org>2002-10-29 12:13:36 +0000
commit9ac588fcdc62b97e03cc79a1fec7c4d7d3db67e7 (patch)
treebd294afda02938a99937d9c7ff93f81898710561 /lib
parent3957c08bfc58678219af04363a20d93436d1bc01 (diff)
downloadFreeBSD-src-9ac588fcdc62b97e03cc79a1fec7c4d7d3db67e7.zip
FreeBSD-src-9ac588fcdc62b97e03cc79a1fec7c4d7d3db67e7.tar.gz
Since make release is toast anyway, add wood to the pyre:
This significantly rewamps libdisks discovery of existing disk layout. Please send me reports if this does not work as expected on i386 or sparc64 platforms. I need to sort out alpha, pc98 and ia64 (in that order) before testing on those platforms make a lot of sense. Belived to work for: i386 sparc64 Unknown state: pc98 alpha ia64
Diffstat (limited to 'lib')
-rw-r--r--lib/libdisk/Makefile13
-rw-r--r--lib/libdisk/chunk.c92
-rw-r--r--lib/libdisk/disk.c882
-rw-r--r--lib/libdisk/libdisk.h50
-rw-r--r--lib/libdisk/rules.c21
5 files changed, 314 insertions, 744 deletions
diff --git a/lib/libdisk/Makefile b/lib/libdisk/Makefile
index 95e6444..7ac8042 100644
--- a/lib/libdisk/Makefile
+++ b/lib/libdisk/Makefile
@@ -24,6 +24,10 @@ SRCS += write_ia64_disk.c
SRCS += write_alpha_disk.c
.endif
+.if ${MACHINE_ARCH} == "sparc64"
+SRCS += write_sparc64_disk.c
+.endif
+
CLEANFILES+= tmp.c tst01 tst01.o
NOPROFILE= yes
NOPIC= yes
@@ -34,3 +38,12 @@ MAN= libdisk.3
tst01: tst01.o libdisk.a
cc ${CFLAGS} -static tst01.o -o tst01 libdisk.a
+
+ad0: all install tst01
+ ./tst01 ad0
+
+da0: all install tst01
+ ./tst01 da0
+
+da1: all install tst01
+ ./tst01 da1
diff --git a/lib/libdisk/chunk.c b/lib/libdisk/chunk.c
index 14e9500..9dfcad0 100644
--- a/lib/libdisk/chunk.c
+++ b/lib/libdisk/chunk.c
@@ -54,7 +54,6 @@ Find_Mother_Chunk(struct chunk *chunks, u_long offset, u_long end, chunk_e type)
case whole:
if (Chunk_Inside(chunks, &ct))
return chunks;
-#ifndef PC98
case extended:
for(c1 = chunks->part; c1; c1 = c1->next) {
if (c1->type != type)
@@ -63,7 +62,6 @@ Find_Mother_Chunk(struct chunk *chunks, u_long offset, u_long end, chunk_e type)
return c1;
}
return 0;
-#endif
case freebsd:
for(c1 = chunks->part; c1; c1 = c1->next) {
if (c1->type == type)
@@ -122,7 +120,7 @@ Clone_Chunk(const struct chunk *c1)
return c2;
}
-static int
+int
Insert_Chunk(struct chunk *c2, u_long offset, u_long size, const char *name,
chunk_e type, int subtype, u_long flags, const char *sname)
{
@@ -236,38 +234,68 @@ Add_Chunk(struct disk *d, long offset, u_long size, const char *name,
c1->subtype = subtype;
return 0;
}
- if (type == freebsd)
-#ifdef PC98
- subtype = 0xc494;
-#else
- subtype = 0xa5;
-#endif
+
c1 = 0;
-#ifndef PC98
- if(!c1 && (type == freebsd || type == fat || type == unknown))
- c1 = Find_Mother_Chunk(d->chunks, offset, end, extended);
-#endif
- if(!c1 && (type == freebsd || type == fat || type == unknown))
- c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
-#ifndef PC98
- if(!c1 && type == extended)
- c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
-#endif
- if(!c1 && type == part)
- c1 = Find_Mother_Chunk(d->chunks, offset, end, freebsd);
+ /* PLATFORM POLICY BEGIN ------------------------------------- */
+ switch(platform) {
+ case p_i386:
+ switch (type) {
+ case fat:
+ case mbr:
+ case extended:
+ case freebsd:
+ subtype = 0xa5;
+ c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
+ break;
+ case part:
+ c1 = Find_Mother_Chunk(d->chunks, offset, end, freebsd);
+ break;
+ default:
+ return(-1);
+ }
+ break;
+ case p_pc98:
+ subtype = 0xc494;
+ break;
+ case p_sparc64:
+ case p_alpha:
+ switch (type) {
+ case freebsd:
+ c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
+ break;
+ case part:
+ c1 = Find_Mother_Chunk(d->chunks, offset, end, freebsd);
+ break;
+ default:
+ return(-1);
+ }
+ break;
+ default:
+ return (-1);
+ }
+ /* PLATFORM POLICY END ---------------------------------------- */
+
if(!c1)
return __LINE__;
for(c2 = c1->part; c2; c2 = c2->next) {
if (c2->type != unused)
continue;
- if(Chunk_Inside(c2, &ct)) {
+ if(!Chunk_Inside(c2, &ct))
+ continue;
+/* PLATFORM POLICY BEGIN ------------------------------------- */
+ if (platform == p_sparc64) {
+ offset = Prev_Cyl_Aligned(d, offset);
+ size = Next_Cyl_Aligned(d, size);
+ break;
+ }
+ if (platform == p_i386) {
if (type != freebsd)
- goto doit;
+ break;
if (!(flags & CHUNK_ALIGN))
- goto doit;
+ break;
if (offset == d->chunks->offset
&& end == d->chunks->end)
- goto doit;
+ break;
/* Round down to prev cylinder */
offset = Prev_Cyl_Aligned(d,offset);
@@ -279,7 +307,6 @@ Add_Chunk(struct disk *d, long offset, u_long size, const char *name,
/* Keep one track clear in front of parent */
if (offset == c1->offset)
offset = Next_Track_Aligned(d, offset + 1);
-
/* Work on the (end+1) */
size += offset;
/* Round up to cylinder */
@@ -292,13 +319,14 @@ Add_Chunk(struct disk *d, long offset, u_long size, const char *name,
/* Convert back to size */
size -= offset;
-
- doit:
- return Insert_Chunk(c2, offset, size, name,
- type, subtype, flags, sname);
}
+
+/* PLATFORM POLICY END ------------------------------------- */
}
- return __LINE__;
+ if (c2 == NULL)
+ return (__LINE__);
+ return Insert_Chunk(c2, offset, size, name,
+ type, subtype, flags, sname);
}
char *
@@ -325,7 +353,7 @@ Print_Chunk(struct chunk *c1,int offset)
for(; i < 10; i++) putchar(' ');
printf("%p %8ld %8lu %8lu %-8s %-16s %-8s 0x%02x %s",
c1, c1->offset, c1->size, c1->end, c1->name, c1->sname,
- chunk_n[c1->type], c1->subtype,
+ chunk_name(c1->type), c1->subtype,
ShowChunkFlags(c1));
putchar('\n');
Print_Chunk(c1->part, offset + 2);
diff --git a/lib/libdisk/disk.c b/lib/libdisk/disk.c
index 3675b44..267ea19 100644
--- a/lib/libdisk/disk.c
+++ b/lib/libdisk/disk.c
@@ -15,30 +15,24 @@ __FBSDID("$FreeBSD$");
#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/diskslice.h>
-#ifndef PC98
#include <sys/diskmbr.h>
-#endif
#include <paths.h>
#include "libdisk.h"
-#ifndef PC98
-#define HAVE_GEOM
-#endif
#include <ctype.h>
#include <errno.h>
#include <assert.h>
-#ifndef PC98
#define DOSPTYP_EXTENDED 5
-#endif
-
#ifdef DEBUG
#define DPRINT(x) warn x
#define DPRINTX(x) warnx x
@@ -47,716 +41,219 @@ __FBSDID("$FreeBSD$");
#define DPRINTX(x)
#endif
-const char *chunk_n[] = {
- "whole",
- "unknown",
- "fat",
- "freebsd",
- "extended",
- "part",
- "unused",
- NULL
+const char *
+chunk_name(chunk_e type)
+{
+ switch(type) {
+ case unused: return ("unused");
+ case mbr: return ("mbr");
+ case part: return ("part");
+ case gpt: return ("gpt");
+ case pc98: return ("pc98");
+ case sun: return ("sun");
+ case freebsd: return ("freebsd");
+ case fat: return ("fat");
+ case spare: return ("spare");
+ default: return ("??");
+ }
};
struct disk *
Open_Disk(const char *name)
{
- return Int_Open_Disk(name, 0);
-}
-
-#ifndef PC98
-static u_int32_t
-Read_Int32(u_int32_t *p)
-{
- u_int8_t *bp = (u_int8_t *)p;
- return bp[0] | (bp[1] << 8) | (bp[2] << 16) | (bp[3] << 24);
-}
-#endif
-
-/*
- * XXX BEGIN HACK XXX
- * Scan/parse the XML geom data to retrieve what we need to
- * carry out the work of Int_Open_Disk. This is a total hack
- * and should be replaced with a real XML parser.
- */
-typedef enum {
- XML_MESH,
- XML_MESH_END,
- XML_CLASS,
- XML_CLASS_END,
- XML_GEOM,
- XML_GEOM_END,
- XML_CONFIG,
- XML_CONFIG_END,
- XML_PROVIDER,
- XML_PROVIDER_END,
- XML_NAME,
- XML_NAME_END,
- XML_INDEX,
- XML_INDEX_END,
- XML_SECLENGTH,
- XML_SECLENGTH_END,
- XML_SECOFFSET,
- XML_SECOFFSET_END,
- XML_TYPE,
- XML_TYPE_END,
- XML_MEDIASIZE,
- XML_MEDIASIZE_END,
- XML_SECTORSIZE,
- XML_SECTORSIZE_END,
- XML_FWHEADS,
- XML_FWHEADS_END,
- XML_FWSECTORS,
- XML_FWSECTORS_END,
-
- XML_OTHER,
- XML_OTHER_END
-} XMLToken;
-
-const struct {
- XMLToken t;
- const char* token;
- const char* name;
-} xmltokens[] = {
- { XML_MESH, "mesh", "XML_MESH" },
- { XML_CLASS, "class", "XML_CLASS" },
- { XML_GEOM, "geom", "XML_GEOM" },
- { XML_CONFIG, "config", "XML_CONFIG" },
- { XML_PROVIDER, "provider", "XML_PROVIDE" },
- { XML_NAME, "name", "XML_NAME" },
- { XML_INDEX, "index", "XML_INDEX" },
- { XML_SECLENGTH, "seclength", "XML_SECLENGTH" },
- { XML_SECOFFSET, "secoffset", "XML_SECOFFSET" },
- { XML_TYPE, "type", "XML_TYPE" },
- { XML_FWHEADS, "fwheads", "XML_FWHEADS" },
- { XML_FWSECTORS, "fwsectors", "XML_FWSECTORS" },
- { XML_MEDIASIZE, "mediasize", "XML_MEDIASIZE" },
- { XML_SECTORSIZE, "sectorsize", "XML_SECTORSIZE" },
- /* NB: this must be last */
- { XML_OTHER, NULL, "XML_OTHER" },
-};
-#define N(x) (sizeof (x) / sizeof (x[0]))
-
-#ifdef DEBUG
-static const char*
-xmltokenname(XMLToken t)
-{
- int i;
-
- for (i = 0; i < N(xmltokens); i++) {
- if (t == xmltokens[i].t)
- return xmltokens[i].name;
- if ((t-1) == xmltokens[i].t) {
- static char tbuf[80];
- snprintf(tbuf, sizeof (tbuf), "%s_END",
- xmltokens[i].name);
- return tbuf;
- }
- }
- return "???";
-}
-#endif /*DEBUG*/
-
-/*
- * Parse the next XML token delimited by <..>. If the token
- * has a "builtin terminator" (<... />) then just skip it and
- * go the next token.
- */
-static int
-xmltoken(const char *start, const char **next, XMLToken *t)
-{
- const char *cp = start;
- const char *token;
- int i;
-
-again:
- while (*cp != '<') {
- if (*cp == '\0') {
- *next = cp;
- DPRINTX(("xmltoken: EOD"));
- return 0;
- }
- cp++;
- }
- token = ++cp;
- for (; *cp && *cp != '>' && !isspace(*cp); cp++)
- ;
- if (*cp == '\0') {
- *next = cp;
- DPRINTX(("xmltoken: EOD"));
- return 0;
- }
- *t = (*token == '/');
- if (*t)
- token++;
- for (i = 0; xmltokens[i].token != NULL; i++)
- if (strncasecmp(token, xmltokens[i].token, cp-token) == 0)
- break;
- *t += xmltokens[i].t;
- /* now collect the remainder of the string */
- for (; *cp != '>' && *cp != '\0'; cp++)
- ;
- if (*cp == '\0') {
- *next = cp;
- DPRINTX(("xmltoken: EOD"));
- return 0;
- }
- if (cp > token && cp[-1] == '/') {
- /* e.g. <geom ref="0xc1c8c100"/> */
- start = cp+1;
- goto again;
- }
- *next = cp+1;
- DPRINTX(("xmltoken: %s \"%.*s\"", xmltokenname(*t), cp-token, token));
- return 1;
-}
-
-/*
- * Parse and discard XML up to the token terminator.
- */
-static int
-discardxml(const char **next, XMLToken terminator)
-{
- const char *xml = *next;
- XMLToken t;
-
- DPRINTX(("discard XML up to %s", xmltokenname(terminator)));
- for (;;) {
- if (xmltoken(xml, next, &t) == 0)
- return EINVAL;
- if (t == terminator)
- break;
- if ((t & 1) == 0) {
- int error = discardxml(next, t+1);
- if (error)
- return error;
- }
- xml = *next;
- }
- return 0;
-}
-
-/*
- * Parse XML from between a range of markers; e.g. <mesh> ... </mesh>.
- * When the specified class name is located we descend looking for the
- * geometry information given by diskname. Once inside there we process
- * tags calling f back for each useful one. The arg is passed into f
- * for use in storing the parsed data.
- */
-static int
-parsexmlpair(
- const char *xml,
- const char **next,
- const char *classname,
- XMLToken terminator,
- const char *diskname,
- int (*f)(void *, XMLToken, u_int *, u_int64_t),
- void *arg
-)
-{
- const char *cp;
- XMLToken t;
- int error;
- u_int ix = (u_int) -1;
-
- DPRINTX(("parse XML up to %s", xmltokenname(terminator)));
- do {
- if (xmltoken(xml, next, &t) == 0) {
- error = EINVAL;
- break;
- }
- if (t == terminator) {
- error = 0;
- break;
- }
- if (t & 1) { /* </mumble> w/o matching <mumble> */
- DPRINTX(("Unexpected token %s", xmltokenname(t)));
- error = EINVAL;
- break;
- }
- switch ((int) t) {
- case XML_NAME:
- for (cp = *next; *cp && *cp != '<'; cp++)
- ;
- if (*cp == '\0') {
- DPRINTX(("parsexmlpair: EOD"));
- error = EINVAL;
- goto done;
- }
- DPRINTX(("parsexmlpair: \"%.*s\"", cp-*next, *next));
- switch ((int) terminator) {
- case XML_CLASS_END:
- if (strncasecmp(*next, classname, cp-*next))
- return discardxml(next, terminator);
- break;
- case XML_GEOM_END:
- if (strncasecmp(*next, diskname, cp-*next))
- return discardxml(next, terminator);
- break;
- }
- break;
- case XML_SECOFFSET:
- case XML_SECLENGTH:
- case XML_TYPE:
- if (ix == (u_int) -1) {
- DPRINTX(("parsexmlpair: slice data w/o "
- "preceding index"));
- error = EINVAL;
- goto done;
- }
- /* fall thru... */
- case XML_INDEX:
- case XML_FWHEADS:
- case XML_FWSECTORS:
- case XML_MEDIASIZE:
- case XML_SECTORSIZE:
- if (terminator != XML_CONFIG_END &&
- terminator != XML_PROVIDER_END) {
- DPRINTX(("parsexmlpair: %s in unexpected "
- "context: terminator %s",
- xmltokenname(t),
- xmltokenname(terminator)));
- error = EINVAL;
- goto done;
- }
- error = (*f)(arg, t, &ix, strtoull(*next, NULL, 10));
- if (error)
- goto done;
- break;
- }
- error = parsexmlpair(*next, &xml, classname,
- t+1, diskname, f, arg);
- } while (error == 0);
-done:
- return error;
-}
-
-/*
- * XML parser. Just barely smart enough to handle the
- * gibberish that geom passed back from the kernel.
- */
-static int
-xmlparse(
- const char *confxml,
- const char *classname,
- const char *diskname,
- int (*f)(void *, XMLToken, u_int *, u_int64_t),
- void *arg
-)
-{
- const char *next;
- XMLToken t;
- int error;
-
- next = confxml;
- while (xmltoken(next, &next, &t) && t != XML_MESH)
- ;
- if (t == XML_MESH)
- error = parsexmlpair(next, &next, classname, XML_MESH_END, diskname, f, arg);
- else {
- DPRINTX(("xmlparse: expecting mesh token, got %s",
- xmltokenname(t)));
- error = EINVAL;
- }
-
- return (error ? -1 : 0);
-}
-
-/*
- * Callback to collect slice-related data.
- */
-static int
-assignToSlice(void *arg, XMLToken t, u_int *slice, u_int64_t v)
-{
- struct diskslices *ds = (struct diskslices *) arg;
-
- switch ((int) t) {
- case XML_INDEX:
- *slice = BASE_SLICE + (u_int) v;
- if (*slice >= MAX_SLICES) {
- DPRINTX(("assignToSlice: invalid slice index %u > max %u",
- *slice, MAX_SLICES));
- return EINVAL;
- }
- if (*slice >= ds->dss_nslices)
- ds->dss_nslices = (*slice)+1;
- break;
- case XML_SECOFFSET:
- ds->dss_slices[*slice].ds_offset = (u_long) v;
- break;
- case XML_SECLENGTH:
- ds->dss_slices[*slice].ds_size = (u_long) v;
- break;
- case XML_TYPE:
- ds->dss_slices[*slice].ds_type = (int) v;
- break;
- }
- return 0;
-}
-
-/*
- * Callback to collect disk-related data.
- */
-static int
-assignToDisk(void *arg, XMLToken t, u_int *slice, u_int64_t v)
-{
- struct disklabel *dl = (struct disklabel *) arg;
-
- switch ((int) t) {
- case XML_FWHEADS:
- dl->d_ntracks = (u_int32_t) v;
- case XML_FWSECTORS:
- dl->d_nsectors = (u_int32_t) v;
- break;
- case XML_MEDIASIZE:
- /* store this temporarily; it gets moved later */
- dl->d_secpercyl = v >> 32;
- dl->d_secperunit = v & 0xffffffff;
- break;
- case XML_SECTORSIZE:
- dl->d_secsize = (u_int32_t) v;
- break;
- }
- return 0;
+ return Int_Open_Disk(name);
}
-#ifdef __i386__
-/*
- * Callback to collect partition-related data.
- */
-static int
-assignToPartition(void *arg, XMLToken t, u_int *part, u_int64_t v)
-{
- struct disklabel *dl = (struct disklabel *) arg;
-
- switch ((int) t) {
- case XML_INDEX:
- *part = (u_int) v;
- if (*part >= MAXPARTITIONS) {
- DPRINTX(("assignToPartition: invalid partition index %u > max %u",
- *part, MAXPARTITIONS));
- return EINVAL;
- }
- if (*part >= dl->d_npartitions)
- dl->d_npartitions = (*part)+1;
- break;
- case XML_SECOFFSET:
- dl->d_partitions[*part].p_offset = (u_int32_t) v;
- break;
- case XML_SECLENGTH:
- dl->d_partitions[*part].p_size = (u_int32_t) v;
- break;
- case XML_TYPE:
- dl->d_partitions[*part].p_fstype = (u_int8_t) v;
- break;
- }
- return 0;
-}
-#endif /* __i386__ */
-#undef N
-
struct disk *
-Int_Open_Disk(const char *name, u_long size)
+Int_Open_Disk(const char *name)
{
- int i;
- int fd = -1;
- struct diskslices ds;
- struct disklabel dl;
- char device[64];
+ char *conftxt = NULL;
struct disk *d;
-#ifdef PC98
- unsigned char *p;
-#else
- struct dos_partition *dp;
- void *p;
-#endif
- char *confxml = NULL;
- size_t xmlsize;
- u_int64_t mediasize;
- int error;
-
- strlcpy(device, _PATH_DEV, sizeof(device));
- strlcat(device, name, sizeof(device));
-
- d = (struct disk *)malloc(sizeof *d);
- if(!d) return NULL;
- memset(d, 0, sizeof *d);
-
- fd = open(device, O_RDONLY);
- if (fd < 0) {
- DPRINT(("open(%s) failed", device));
- goto bad;
- }
-
- memset(&dl, 0, sizeof dl);
- memset(&ds, 0, sizeof ds);
- /*
- * Read and hack-parse the XML that provides the info we need.
- */
- error = sysctlbyname("kern.geom.confxml", NULL, &xmlsize, NULL, 0);
+ size_t txtsize;
+ int error, i;
+ char *p, *q, *r, *a, *b, *n, *t;
+ off_t o, len, off;
+ u_int l, s, ty, sc, hd, alt;
+ off_t lo[10];
+
+ error = sysctlbyname("kern.geom.conftxt", NULL, &txtsize, NULL, 0);
if (error) {
- warn("kern.geom.confxml sysctl not available, giving up!");
- goto bad;
+ warn("kern.geom.conftxt sysctl not available, giving up!");
+ return (NULL);
}
- confxml = (char *) malloc(xmlsize+1);
- if (confxml == NULL) {
- DPRINT(("cannot malloc memory for confxml"));
- goto bad;
+ conftxt = (char *) malloc(txtsize+1);
+ if (conftxt == NULL) {
+ DPRINT(("cannot malloc memory for conftxt"));
+ return (NULL);
}
- error = sysctlbyname("kern.geom.confxml", confxml, &xmlsize, NULL, 0);
+ error = sysctlbyname("kern.geom.conftxt", conftxt, &txtsize, NULL, 0);
if (error) {
- DPRINT(("error reading kern.geom.confxml from the system"));
- goto bad;
+ DPRINT(("error reading kern.geom.conftxt from the system"));
+ free(conftxt);
+ return (NULL);
}
- confxml[xmlsize] = '\0'; /* in case kernel bug is still there */
+ conftxt[txtsize] = '\0'; /* in case kernel bug is still there */
- if (xmlparse(confxml, "MBR", name, assignToSlice, &ds) != 0) {
- DPRINTX(("Error parsing MBR geometry specification."));
- goto bad;
- }
- if (xmlparse(confxml, "DISK", name, assignToDisk, &dl) != 0) {
- DPRINTX(("Error parsing DISK geometry specification."));
- goto bad;
- }
- if (dl.d_nsectors == 0) {
- DPRINTX(("No (zero) sector information in DISK geometry"));
- goto bad;
- }
- if (dl.d_ntracks == 0) {
- DPRINTX(("No (zero) track information in DISK geometry"));
- goto bad;
- }
- if (dl.d_secsize == 0) {
- DPRINTX(("No (zero) sector size information in DISK geometry"));
- goto bad;
- }
- if (dl.d_secpercyl == 0 && dl.d_secperunit == 0) {
- DPRINTX(("No (zero) media size information in DISK geometry"));
- goto bad;
- }
- /*
- * Now patch up disklabel and diskslice.
- */
- d->sector_size = dl.d_secsize;
- /* NB: media size was stashed in two parts while parsing */
- mediasize = (((u_int64_t) dl.d_secpercyl) << 32) + dl.d_secperunit;
- dl.d_secpercyl = 0;
- dl.d_secperunit = 0;
- size = mediasize / d->sector_size;
- dl.d_ncylinders = size / (dl.d_ntracks * dl.d_nsectors);
- /* "whole disk" slice maintained for compatibility */
- ds.dss_slices[WHOLE_DISK_SLICE].ds_size = size;
+ for (p = conftxt; p != NULL && *p; p = strchr(p, '\n')) {
+ if (*p == '\n')
+ p++;
+ a = strsep(&p, " ");
+ if (strcmp(a, "0"))
+ continue;
-#ifdef PC98
- p = (unsigned char*)read_block(fd, 1, d->sector_size);
-#else
- p = read_block(fd, 0, d->sector_size);
- dp = (struct dos_partition*)(p + DOSPARTOFF);
- for (i = 0; i < NDOSPART; i++) {
- if (Read_Int32(&dp->dp_start) >= size)
- continue;
- if (Read_Int32(&dp->dp_start) + Read_Int32(&dp->dp_size) >= size)
- continue;
- if (!Read_Int32(&dp->dp_size))
- continue;
+ a = strsep(&p, " ");
+ if (strcmp(a, "DISK"))
+ continue;
+
+ a = strsep(&p, " ");
+ if (strcmp(a, name))
+ continue;
+ break;
}
- free(p);
-#endif
- d->bios_sect = dl.d_nsectors;
- d->bios_hd = dl.d_ntracks;
+ 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 */
+ o = strtoimax(a, &r, 0);
+ if (*r) { printf("BARF %d <%d>\n", __LINE__, *r); exit (0); }
- if (dl.d_ntracks && dl.d_nsectors)
- d->bios_cyl = size / (dl.d_ntracks * dl.d_nsectors);
+ a = strsep(&p, " "); /* sectorsize */
+ s = strtoul(a, &r, 0);
+ if (*r) { printf("BARF %d <%d>\n", __LINE__, *r); exit (0); }
- if (Add_Chunk(d, 0, size, name, whole, 0, 0, "-"))
+ if (Add_Chunk(d, 0, o / s, name, whole, 0, 0, "-"))
DPRINT(("Failed to add 'whole' chunk"));
-#ifdef __i386__
-#ifdef PC98
- /* XXX -- Quick Hack!
- * Check MS-DOS MO
- */
- if ((*p == 0xf0 || *p == 0xf8) &&
- (*(p+1) == 0xff) &&
- (*(p+2) == 0xff)) {
- Add_Chunk(d, 0, size, name, fat, 0xa0a0, 0, name);
- free(p);
- goto pc98_mo_done;
+ len = o / s;
+
+ 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);
}
- free(p);
-#endif /* PC98 */
- for(i=BASE_SLICE;i<ds.dss_nslices;i++) {
- char sname[20];
- char pname[20];
- chunk_e ce;
- u_long flags=0;
- int subtype=0;
- int j;
-
- if (! ds.dss_slices[i].ds_size)
- continue;
- snprintf(sname, sizeof(sname), "%ss%d", name, i - 1);
-#ifdef PC98
- subtype = ds.dss_slices[i].ds_type |
- ds.dss_slices[i].ds_subtype << 8;
- switch (ds.dss_slices[i].ds_type & 0x7f) {
- case 0x14:
- ce = freebsd;
- break;
- case 0x20:
- case 0x21:
- case 0x22:
- case 0x23:
- case 0x24:
- ce = fat;
- break;
-#else /* IBM-PC */
- subtype = ds.dss_slices[i].ds_type;
- switch (ds.dss_slices[i].ds_type) {
- case 0xa5:
- ce = freebsd;
- break;
- case 0x1:
- case 0x6:
- case 0x4:
- case 0xb:
- case 0xc:
- case 0xe:
- ce = fat;
- break;
- case DOSPTYP_EXTENDED:
- case 0xf:
- ce = extended;
- break;
-#endif
- default:
- ce = unknown;
+
+ 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, 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;
+ 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;
}
-#ifdef PC98
- if (Add_Chunk(d, ds.dss_slices[i].ds_offset,
- ds.dss_slices[i].ds_size, sname, ce, subtype, flags,
- ds.dss_slices[i].ds_name))
-#else
- if (Add_Chunk(d, ds.dss_slices[i].ds_offset,
- ds.dss_slices[i].ds_size, sname, ce, subtype, flags, ""))
-#endif
- DPRINT(("failed to add chunk for slice %d", i - 1));
-#ifdef PC98
- if ((ds.dss_slices[i].ds_type & 0x7f) != 0x14)
-#else
- if (ds.dss_slices[i].ds_type != 0xa5)
-#endif
+ /* PLATFORM POLICY BEGIN ------------------------------------- */
+ if (platform == p_sparc64 && !strcmp(t, "SUN") && i == 2)
continue;
- if (xmlparse(confxml, "BSD", sname, assignToPartition, &dl) != 0) {
- DPRINTX(("Error parsing MBR geometry specification."));
- goto bad;
+ 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"));
}
-
- for(j = 0; j <= dl.d_npartitions; j++) {
- if (j == RAW_PART)
- continue;
- if (j == 3)
- continue;
- if (j == dl.d_npartitions) {
- j = 3;
- dl.d_npartitions = 0;
- }
- if (!dl.d_partitions[j].p_size)
- continue;
- if (dl.d_partitions[j].p_size +
- dl.d_partitions[j].p_offset >
- ds.dss_slices[i].ds_size)
- continue;
- snprintf(pname, sizeof(pname), "%s%c", sname, j + 'a');
- if (Add_Chunk(d,
- dl.d_partitions[j].p_offset +
- ds.dss_slices[i].ds_offset,
- dl.d_partitions[j].p_size,
- pname,part,
- dl.d_partitions[j].p_fstype,
-#ifdef PC98
- 0,
- ds.dss_slices[i].ds_name) && j != 3)
-#else
- 0, "") && j != 3)
-#endif
- DPRINT((
- "Failed to add chunk for partition %c [%lu,%lu]",
- j + 'a', dl.d_partitions[j].p_offset,
- dl.d_partitions[j].p_size));
+ if (platform == p_alpha && !strcmp(t, "BSD") &&
+ d->chunks->part->part == NULL) {
+ o = d->chunks->size;
+ if (Add_Chunk(d, 0, d->chunks->size, name, freebsd, 0, 0, "-"))
+ DPRINT(("Failed to add 'freebsd' chunk"));
}
+ if (platform == p_i386 && !strcmp(t, "BSD") && i == 2)
+ continue;
+ /* PLATFORM POLICY END --------------------------------------- */
+
+ off /= s;
+ len /= s;
+ off += lo[l - 1];
+ lo[l] = off;
+ printf("%s [%s] %jd %jd\n", t, n, (intmax_t)(off / s), (intmax_t) (len / s));
+ if (!strcmp(t, "SUN"))
+ i = Add_Chunk(d, off, len, n, part, 0, 0, 0);
+ else if (!strcmp(t, "MBR") && ty == 165)
+ i = Add_Chunk(d, off, len, n, freebsd, 0, 0, 0);
+ else if (!strcmp(t, "MBR"))
+ i = Add_Chunk(d, off, len, n, mbr, 0, 0, 0);
+ else if (!strcmp(t, "BSD"))
+ i = Add_Chunk(d, off, len, n, part, 0, 0, 0);
+ else if (!strcmp(t, "PC98"))
+ i = Add_Chunk(d, off, len, n, pc98, 0, 0, 0);
+ else if (!strcmp(t, "GPT"))
+ i = Add_Chunk(d, off, len, n, gpt, 0, 0, 0);
+ else
+ {printf("BARF %d\n", __LINE__); exit(0); }
+ printf("error = %d\n", i);
}
-#endif /* __i386__ */
-#ifdef __alpha__
- {
- struct disklabel dl;
- char pname[20];
- int j,k;
-
- strlcpy(pname, _PATH_DEV, sizeof(pname));
- strlcat(pname, name, sizeof(pname));
- j = open(pname, O_RDONLY);
- if (j < 0) {
- DPRINT(("open(%s)", pname));
- goto nolabel;
- }
- k = ioctl(j, DIOCGDINFO, &dl);
- if (k < 0) {
- DPRINT(("ioctl(%s, DIOCGDINFO)", pname));
- close(j);
- goto nolabel;
- }
- close(j);
- All_FreeBSD(d, 1);
-
- for(j = 0; j <= dl.d_npartitions; j++) {
- if (j == RAW_PART)
- continue;
- if (j == 3)
- continue;
- if (j == dl.d_npartitions) {
- j = 3;
- dl.d_npartitions = 0;
- }
- if (!dl.d_partitions[j].p_size)
- continue;
- if (dl.d_partitions[j].p_size +
- dl.d_partitions[j].p_offset >
- ds.dss_slices[WHOLE_DISK_SLICE].ds_size)
- continue;
- snprintf(pname, sizeof(pname), "%s%c", name, j + 'a');
- if (Add_Chunk(d,
- dl.d_partitions[j].p_offset,
- dl.d_partitions[j].p_size,
- pname,part,
- dl.d_partitions[j].p_fstype,
- 0, "") && j != 3)
- DPRINT((
- "Failed to add chunk for partition %c [%lu,%lu]",
- j + 'a', dl.d_partitions[j].p_offset,
- dl.d_partitions[j].p_size));
- }
- nolabel:;
+ /* PLATFORM POLICY BEGIN ------------------------------------- */
+ /* We have a chance to do things on a blank disk here */
+printf("c %p\n", d->chunks);
+printf("c->p %p\n", d->chunks->part);
+printf("c->p->p %p\n", d->chunks->part->part);
+ if (platform == p_sparc64 && d->chunks->part->part == NULL) {
+printf("HERE %d\n", __LINE__);
+ hd = d->bios_hd;
+ sc = d->bios_sect;
+ o = d->chunks->size / (hd * sc);
+ o *= (hd * sc);
+ o -= 2 * hd * sc;
+printf("HERE %d\n", __LINE__);
+ if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-"))
+ DPRINT(("Failed to add 'freebsd' chunk"));
}
-#endif /* __alpha__ */
-#ifdef PC98
-pc98_mo_done:
-#endif
- close(fd);
- Fixup_Names(d);
- return d;
-bad:
- if (confxml != NULL)
- free(confxml);
- if (fd >= 0)
- close(fd);
- return NULL;
+ /* PLATFORM POLICY END --------------------------------------- */
+
+ return (d);
+ i = 0;
}
void
@@ -769,10 +266,7 @@ Debug_Disk(struct disk *d)
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);
-#if defined(PC98)
- printf(" boot1=%p, boot2=%p, bootipl=%p, bootmenu=%p\n",
- d->boot1, d->boot2, d->bootipl, d->bootmenu);
-#elif defined(__i386__)
+#if defined(__i386__)
printf(" boot1=%p, boot2=%p, bootmgr=%p\n",
d->boot1, d->boot2, d->bootmgr);
#elif defined(__alpha__)
@@ -867,14 +361,8 @@ Disk_Names()
return disks;
}
-#ifdef PC98
-void
-Set_Boot_Mgr(struct disk *d, const u_char *bootipl, const size_t bootipl_size,
- const u_char *bootmenu, const size_t bootmenu_size)
-#else
void
Set_Boot_Mgr(struct disk *d, const u_char *b, const size_t s)
-#endif
{
#if !defined(__ia64__)
#ifdef PC98
@@ -950,7 +438,6 @@ slice_type_name( int type, int subtype )
{
switch (type) {
case 0: return "whole";
-#ifndef PC98
case 1: switch (subtype) {
case 1: return "fat (12-bit)";
case 2: return "XENIX /";
@@ -984,21 +471,14 @@ slice_type_name( int type, int subtype )
case 239: return "EFI Sys. Part.";
default: return "unknown";
}
-#endif
case 2: return "fat";
case 3: switch (subtype) {
-#ifdef PC98
- case 0xc494: return "freebsd";
-#else
case 165: return "freebsd";
-#endif
default: return "unknown";
}
-#ifndef PC98
case 4: return "extended";
case 5: return "part";
case 6: return "unused";
-#endif
default: return "unknown";
}
}
diff --git a/lib/libdisk/libdisk.h b/lib/libdisk/libdisk.h
index bf9b54d..2a4cd1a 100644
--- a/lib/libdisk/libdisk.h
+++ b/lib/libdisk/libdisk.h
@@ -10,19 +10,61 @@
*
*/
+#define DEBUG 1
+/* You can define a particular architecture here if you are debugging. */
+/* #define P_DEBUG p_sparc64 */
+
#define MAX_NO_DISKS 32
/* Max # of disks Disk_Names() will return */
#define MAX_SEC_SIZE 2048 /* maximum sector size that is supported */
#define MIN_SEC_SIZE 512 /* the sector size to end sensing at */
+const static enum platform {
+ p_any, /* for debugging ! */
+ p_alpha,
+ p_i386,
+ p_pc98,
+ p_sparc64,
+ p_ia64,
+ p_ppc
+} platform =
+#if defined (P_DEBUG)
+ P_DEBUG
+#elif defined (PC98)
+ p_pc98
+#elif defined(__i386__)
+ p_i386
+#elif defined(__alpha__)
+ p_alpha
+#elif defined(__sparc64__)
+ p_sparc64
+#elif defined(__ia64__)
+ p_ia64
+#elif defined(__ppc__)
+ p_ppc
+#else
+ IHAVENOIDEA
+#endif
+ ;
+
+
+
+
typedef enum {
whole,
unknown,
+
+ sun,
+ pc98,
+ mbr,
+ gpt,
+
fat,
freebsd,
extended,
part,
+ spare,
unused
} chunk_e;
@@ -104,7 +146,7 @@ struct chunk {
#define DELCHUNK_RECOVER 0x0001
-extern const char *chunk_n[];
+const char *chunk_name(chunk_e type);
const char *
slice_type_name( int type, int subtype );
@@ -137,6 +179,10 @@ Sanitize_Bios_Geom(struct disk *disk);
*/
int
+Insert_Chunk(struct chunk *c2, u_long offset, u_long size, const char *name,
+ chunk_e type, int subtype, u_long flags, const char *sname);
+
+int
Delete_Chunk2(struct disk *disk, struct chunk *, int flags);
/* Free a chunk of disk_space modified by the passed
* flags.
@@ -256,7 +302,7 @@ int Add_Chunk(struct disk *, long, u_long, const char *, chunk_e, int, u_long, c
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 *name, u_long size);
+struct disk * Int_Open_Disk(const char *name);
int Fixup_Names(struct disk *);
int MakeDevChunk(const struct chunk *c1, const char *path);
__END_DECLS
diff --git a/lib/libdisk/rules.c b/lib/libdisk/rules.c
index a6a2255..87846c9 100644
--- a/lib/libdisk/rules.c
+++ b/lib/libdisk/rules.c
@@ -233,15 +233,18 @@ Rule_004(const struct disk *d, const struct chunk *c, char *msg)
static void
Check_Chunk(const struct disk *d, const struct chunk *c, char *msg)
{
- Rule_000(d, c, msg);
- Rule_001(d, c, msg);
- Rule_002(d, c, msg);
- Rule_003(d, c, msg);
- Rule_004(d, c, msg);
- if (c->part)
- Check_Chunk(d, c->part, msg);
- if (c->next)
- Check_Chunk(d, c->next, msg);
+
+ if (platform == p_i386) {
+ Rule_000(d, c, msg);
+ Rule_001(d, c, msg);
+ Rule_002(d, c, msg);
+ Rule_003(d, c, msg);
+ Rule_004(d, c, msg);
+ if (c->part)
+ Check_Chunk(d, c->part, msg);
+ if (c->next)
+ Check_Chunk(d, c->next, msg);
+ }
}
char *
OpenPOWER on IntegriCloud