diff options
author | sam <sam@FreeBSD.org> | 2002-10-20 22:19:37 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2002-10-20 22:19:37 +0000 |
commit | 8199d9ca41fd41a4d3be227eb9613dab3dc96384 (patch) | |
tree | 6c9e388a42c99d9bcaecc268f36c57af167312f2 | |
parent | e8b44023e46b9186910ff7da8bf17c14e3704d4e (diff) | |
download | FreeBSD-src-8199d9ca41fd41a4d3be227eb9613dab3dc96384.zip FreeBSD-src-8199d9ca41fd41a4d3be227eb9613dab3dc96384.tar.gz |
Another baby step toward getting sysinstall working:
o fillin media s/h/c fields from new XML phk just added; need this because
sysinstall uses them in the fdisk look-alike
o add new tags to xml parser
o cleanup parser a touch; remove unused tags and move tag parsing stuff to
a table to simplify future additions
o redo callback to pass 64-bit values since mediasize overflows u_int32_t
o loosen parsing sanity checks a touch to deal with new xml we must handle
o move sector size probing to non-geom handling since we now get it from xml
o remove WHOLE_DISK_SLICE buggery now that we get mediasize from xml
-rw-r--r-- | lib/libdisk/disk.c | 205 |
1 files changed, 128 insertions, 77 deletions
diff --git a/lib/libdisk/disk.c b/lib/libdisk/disk.c index cf894dfb..e99a0ab 100644 --- a/lib/libdisk/disk.c +++ b/lib/libdisk/disk.c @@ -96,53 +96,64 @@ typedef enum { XML_NAME_END, XML_INDEX, XML_INDEX_END, - XML_LENGTH, - XML_LENGTH_END, XML_SECLENGTH, XML_SECLENGTH_END, XML_SECOFFSET, XML_SECOFFSET_END, - XML_OFFSET, - XML_OFFSET_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) { - switch (t) { - case XML_MESH: return "XML_MESH"; - case XML_MESH_END: return "XML_MESH_END"; - case XML_CLASS: return "XML_CLASS"; - case XML_CLASS_END: return "XML_CLASS_END"; - case XML_GEOM: return "XML_GEOM"; - case XML_GEOM_END: return "XML_GEOM_END"; - case XML_CONFIG: return "XML_CONFIG"; - case XML_CONFIG_END: return "XML_CONFIG_END"; - case XML_PROVIDER: return "XML_PROVIDER"; - case XML_PROVIDER_END: return "XML_PROVIDER_END"; - case XML_NAME: return "XML_NAME"; - case XML_NAME_END: return "XML_NAME_END"; - case XML_INDEX: return "XML_INDEX"; - case XML_INDEX_END: return "XML_INDEX_END"; - case XML_LENGTH: return "XML_LENGTH"; - case XML_LENGTH_END: return "XML_LENGTH_END"; - case XML_SECLENGTH: return "XML_SECLENGTH"; - case XML_SECLENGTH_END: return "XML_SECLENGTH_END"; - case XML_SECOFFSET: return "XML_SECOFFSET"; - case XML_SECOFFSET_END: return "XML_SECOFFSET_END"; - case XML_OFFSET: return "XML_OFFSET"; - case XML_OFFSET_END: return "XML_OFFSET_END"; - case XML_TYPE: return "XML_TYPE"; - case XML_TYPE_END: return "XML_TYPE_END"; - - case XML_OTHER: return "XML_OTHER"; - case XML_OTHER_END: return "XML_OTHER_END"; + 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 "???"; } @@ -158,6 +169,7 @@ xmltoken(const char *start, const char **next, XMLToken *t) { const char *cp = start; const char *token; + int i; again: while (*cp != '<') { @@ -179,32 +191,10 @@ again: *t = (*token == '/'); if (*t) token++; - if (strncasecmp(token, "mesh", cp-token) == 0) - *t += XML_MESH; - else if (strncasecmp(token, "class", cp-token) == 0) - *t += XML_CLASS; - else if (strncasecmp(token, "geom", cp-token) == 0) - *t += XML_GEOM; - else if (strncasecmp(token, "config", cp-token) == 0) - *t += XML_CONFIG; - else if (strncasecmp(token, "provider", cp-token) == 0) - *t += XML_PROVIDER; - else if (strncasecmp(token, "name", cp-token) == 0) - *t += XML_NAME; - else if (strncasecmp(token, "index", cp-token) == 0) - *t += XML_INDEX; - else if (strncasecmp(token, "length", cp-token) == 0) - *t += XML_LENGTH; - else if (strncasecmp(token, "seclength", cp-token) == 0) - *t += XML_SECLENGTH; - else if (strncasecmp(token, "secoffset", cp-token) == 0) - *t += XML_SECOFFSET; - else if (strncasecmp(token, "offset", cp-token) == 0) - *t += XML_OFFSET; - else if (strncasecmp(token, "type", cp-token) == 0) - *t += XML_TYPE; - else - *t += XML_OTHER; + 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++) ; @@ -262,7 +252,7 @@ parsexmlpair( const char *classname, XMLToken terminator, const char *diskname, - int (*f)(void *, XMLToken, u_int *, u_long), + int (*f)(void *, XMLToken, u_int *, u_int64_t), void *arg ) { @@ -318,7 +308,12 @@ parsexmlpair( } /* fall thru... */ case XML_INDEX: - if (terminator != XML_CONFIG_END) { + 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), @@ -326,7 +321,7 @@ parsexmlpair( error = EINVAL; goto done; } - error = (*f)(arg, t, &ix, strtoul(*next, NULL, 10)); + error = (*f)(arg, t, &ix, strtoull(*next, NULL, 10)); if (error) goto done; break; @@ -347,7 +342,7 @@ xmlparse( const char *confxml, const char *classname, const char *diskname, - int (*f)(void *, XMLToken, u_int *, u_long), + int (*f)(void *, XMLToken, u_int *, u_int64_t), void *arg ) { @@ -373,7 +368,7 @@ xmlparse( * Callback to collect slice-related data. */ static int -assignToSlice(void *arg, XMLToken t, u_int *slice, u_long v) +assignToSlice(void *arg, XMLToken t, u_int *slice, u_int64_t v) { struct diskslices *ds = (struct diskslices *) arg; @@ -389,13 +384,39 @@ assignToSlice(void *arg, XMLToken t, u_int *slice, u_long v) ds->dss_nslices = (*slice)+1; break; case XML_SECOFFSET: - ds->dss_slices[*slice].ds_offset = v; + ds->dss_slices[*slice].ds_offset = (u_long) v; break; case XML_SECLENGTH: - ds->dss_slices[*slice].ds_size = v; + ds->dss_slices[*slice].ds_size = (u_long) v; break; case XML_TYPE: - ds->dss_slices[*slice].ds_type = v; + 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_nsectors = (u_int32_t) v; + case XML_FWSECTORS: + dl->d_ntracks = (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; @@ -405,7 +426,7 @@ assignToSlice(void *arg, XMLToken t, u_int *slice, u_long v) * Callback to collect partition-related data. */ static int -assignToPartition(void *arg, XMLToken t, u_int *part, u_long v) +assignToPartition(void *arg, XMLToken t, u_int *part, u_int64_t v) { struct disklabel *dl = (struct disklabel *) arg; @@ -432,6 +453,7 @@ assignToPartition(void *arg, XMLToken t, u_int *part, u_long v) } return 0; } +#undef N #endif /*HAVE_GEOM*/ struct disk * @@ -441,9 +463,8 @@ Int_Open_Disk(const char *name, u_long size) int fd = -1; struct diskslices ds; struct disklabel dl; - char device[64], *buf; + char device[64]; struct disk *d; - u_long sector_size; #ifdef PC98 unsigned char *p; #else @@ -454,7 +475,11 @@ Int_Open_Disk(const char *name, u_long size) #ifdef HAVE_GEOM char *confxml = NULL; size_t xmlsize; + u_int64_t mediasize; int error; +#else + u_long sector_size; + char *buf; #endif /*HAVE_GEOM*/ strlcpy(device, _PATH_DEV, sizeof(device)); @@ -497,12 +522,38 @@ Int_Open_Disk(const char *name, u_long size) DPRINTX(("Error parsing MBR geometry specification.")); goto bad; } - /* XXX how do I get this info from the XML? */ - for (i = BASE_SLICE; i < ds.dss_nslices; i++) { - struct diskslice *dsp = &ds.dss_slices[i]; - if (dsp->ds_offset + dsp->ds_size > ds.dss_slices[WHOLE_DISK_SLICE].ds_size) - ds.dss_slices[WHOLE_DISK_SLICE].ds_size = dsp->ds_offset + dsp->ds_size; + 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; #else /* !HAVE_GEOM */ if (ioctl(fd, DIOCGDINFO, &dl) < 0) { DPRINT(("DIOCGDINFO(%s) failed", device)); @@ -521,7 +572,6 @@ Int_Open_Disk(const char *name, u_long size) i, ds.dss_slices[i].ds_openmask); printf("\n"); #endif -#endif /*SADDLED_WTIH_GEOM*/ /* XXX --- ds.dss_slice[WHOLE_DISK_SLICE].ds.size of MO disk is wrong!!! */ #ifdef PC98 @@ -548,11 +598,12 @@ Int_Open_Disk(const char *name, u_long size) /* could not determine sector size */ goto bad; } +#endif /*HAVE_GEOM*/ #ifdef PC98 - p = (unsigned char*)read_block(fd, 1, sector_size); + p = (unsigned char*)read_block(fd, 1, d->sector_size); #else - p = read_block(fd, 0, sector_size); + 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) |