summaryrefslogtreecommitdiffstats
path: root/sys/geom/part
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2008-10-20 04:50:47 +0000
committermarcel <marcel@FreeBSD.org>2008-10-20 04:50:47 +0000
commit491c7479e7367e870a1911a9b9c7a0c3069b648a (patch)
treee3aaa66f6af660bbd5c3ff1aef4a19d9d0371642 /sys/geom/part
parent57a7a67ea5c79c99191dda0e574a27b1ee8405c8 (diff)
downloadFreeBSD-src-491c7479e7367e870a1911a9b9c7a0c3069b648a.zip
FreeBSD-src-491c7479e7367e870a1911a9b9c7a0c3069b648a.tar.gz
The active and bootable flags are not part of the type.
Export the active and bootable flags as attributes in the configuration XML and allow them to be manipulated with the set/unset commands. Since libdisk treats the flags as part of the partition type, preserve behavior by keeping them included in the configuration text.
Diffstat (limited to 'sys/geom/part')
-rw-r--r--sys/geom/part/g_part_pc98.c93
1 files changed, 82 insertions, 11 deletions
diff --git a/sys/geom/part/g_part_pc98.c b/sys/geom/part/g_part_pc98.c
index 4a763de..2b997bc 100644
--- a/sys/geom/part/g_part_pc98.c
+++ b/sys/geom/part/g_part_pc98.c
@@ -45,6 +45,14 @@ __FBSDID("$FreeBSD$");
#include "g_part_if.h"
+#define PC98_MID_BOOTABLE 0x80
+#define PC98_MID_MASK 0x7f
+#define PC98_MID_386BSD 0x14
+
+#define PC98_SID_ACTIVE 0x80
+#define PC98_SID_MASK 0x7f
+#define PC98_SID_386BSD 0x44
+
#define SECSIZE 512
struct g_part_pc98_table {
@@ -72,8 +80,10 @@ static char *g_part_pc98_name(struct g_part_table *, struct g_part_entry *,
char *, size_t);
static int g_part_pc98_probe(struct g_part_table *, struct g_consumer *);
static int g_part_pc98_read(struct g_part_table *, struct g_consumer *);
-static const char *g_part_pc98_type(struct g_part_table *, struct g_part_entry *,
- char *, size_t);
+static int g_part_pc98_setunset(struct g_part_table *, struct g_part_entry *,
+ const char *, unsigned int);
+static const char *g_part_pc98_type(struct g_part_table *,
+ struct g_part_entry *, char *, size_t);
static int g_part_pc98_write(struct g_part_table *, struct g_consumer *);
static kobj_method_t g_part_pc98_methods[] = {
@@ -87,6 +97,7 @@ static kobj_method_t g_part_pc98_methods[] = {
KOBJMETHOD(g_part_name, g_part_pc98_name),
KOBJMETHOD(g_part_probe, g_part_pc98_probe),
KOBJMETHOD(g_part_read, g_part_pc98_read),
+ KOBJMETHOD(g_part_setunset, g_part_pc98_setunset),
KOBJMETHOD(g_part_type, g_part_pc98_type),
KOBJMETHOD(g_part_write, g_part_pc98_write),
{ 0, 0 }
@@ -115,14 +126,17 @@ pc98_parse_type(const char *type, u_char *dp_mid, u_char *dp_sid)
if (type[1] == '\0' || *endp != '\0' || lt <= 0 ||
lt >= 65536)
return (EINVAL);
- *dp_mid = (u_char)lt;
- *dp_sid = (u_char)(lt >> 8);
+ /* Make sure the active and bootable flags aren't set. */
+ if (lt & ((PC98_SID_ACTIVE << 8) | PC98_MID_BOOTABLE))
+ return (ENOATTR);
+ *dp_mid = (*dp_mid & PC98_MID_BOOTABLE) | (u_char)lt;
+ *dp_sid = (*dp_sid & PC98_SID_ACTIVE) | (u_char)(lt >> 8);
return (0);
}
alias = g_part_alias_name(G_PART_ALIAS_FREEBSD);
if (!strcasecmp(type, alias)) {
- *dp_mid = (u_char)DOSMID_386BSD;
- *dp_sid = (u_char)DOSSID_386BSD;
+ *dp_mid = (*dp_mid & PC98_MID_BOOTABLE) | PC98_MID_386BSD;
+ *dp_sid = (*dp_sid & PC98_SID_ACTIVE) | PC98_SID_386BSD;
return (0);
}
return (EINVAL);
@@ -176,6 +190,8 @@ g_part_pc98_add(struct g_part_table *basetable, struct g_part_entry *baseentry,
if (baseentry->gpe_deleted)
bzero(&entry->ent, sizeof(entry->ent));
+ else
+ entry->ent.dp_mid = entry->ent.dp_sid = 0;
KASSERT(baseentry->gpe_start <= start, (__func__));
KASSERT(baseentry->gpe_end >= start + size - 1, (__func__));
@@ -259,7 +275,13 @@ g_part_pc98_dumpconf(struct g_part_table *table,
} else {
/* confxml: partition entry information */
sbuf_printf(sb, "%s<label>%s</label>\n", indent, name);
- sbuf_printf(sb, "%s<rawtype>%u</rawtype>\n", indent, type);
+ if (entry->ent.dp_mid & PC98_MID_BOOTABLE)
+ sbuf_printf(sb, "%s<attrib>bootable</attrib>\n",
+ indent);
+ if (entry->ent.dp_sid & PC98_SID_ACTIVE)
+ sbuf_printf(sb, "%s<attrib>active</attrib>\n", indent);
+ sbuf_printf(sb, "%s<rawtype>%u</rawtype>\n", indent,
+ type & 0x7f7f);
}
return (0);
}
@@ -271,8 +293,8 @@ g_part_pc98_dumpto(struct g_part_table *table, struct g_part_entry *baseentry)
/* Allow dumping to a FreeBSD partition only. */
entry = (struct g_part_pc98_entry *)baseentry;
- return ((entry->ent.dp_mid == DOSMID_386BSD &&
- entry->ent.dp_sid == DOSSID_386BSD) ? 1 : 0);
+ return (((entry->ent.dp_mid & PC98_MID_MASK) == PC98_MID_386BSD &&
+ (entry->ent.dp_sid & PC98_SID_MASK) == PC98_SID_386BSD) ? 1 : 0);
}
static int
@@ -412,6 +434,54 @@ g_part_pc98_read(struct g_part_table *basetable, struct g_consumer *cp)
return (0);
}
+static int
+g_part_pc98_setunset(struct g_part_table *table, struct g_part_entry *baseentry,
+ const char *attrib, unsigned int set)
+{
+ struct g_part_entry *iter;
+ struct g_part_pc98_entry *entry;
+ int changed, mid, sid;
+
+ mid = sid = 0;
+ if (strcasecmp(attrib, "active") == 0)
+ sid = 1;
+ else if (strcasecmp(attrib, "bootable") == 0)
+ mid = 1;
+ if (mid == 0 && sid == 0)
+ return (EINVAL);
+
+ LIST_FOREACH(iter, &table->gpt_entry, gpe_entry) {
+ if (iter->gpe_deleted)
+ continue;
+ if (iter != baseentry)
+ continue;
+ changed = 0;
+ entry = (struct g_part_pc98_entry *)iter;
+ if (set) {
+ if (mid && !(entry->ent.dp_mid & PC98_MID_BOOTABLE)) {
+ entry->ent.dp_mid |= PC98_MID_BOOTABLE;
+ changed = 1;
+ }
+ if (sid && !(entry->ent.dp_sid & PC98_SID_ACTIVE)) {
+ entry->ent.dp_sid |= PC98_SID_ACTIVE;
+ changed = 1;
+ }
+ } else {
+ if (mid && (entry->ent.dp_mid & PC98_MID_BOOTABLE)) {
+ entry->ent.dp_mid &= ~PC98_MID_BOOTABLE;
+ changed = 1;
+ }
+ if (sid && (entry->ent.dp_sid & PC98_SID_ACTIVE)) {
+ entry->ent.dp_sid &= ~PC98_SID_ACTIVE;
+ changed = 1;
+ }
+ }
+ if (changed && !iter->gpe_created)
+ iter->gpe_modified = 1;
+ }
+ return (0);
+}
+
static const char *
g_part_pc98_type(struct g_part_table *basetable, struct g_part_entry *baseentry,
char *buf, size_t bufsz)
@@ -420,8 +490,9 @@ g_part_pc98_type(struct g_part_table *basetable, struct g_part_entry *baseentry,
u_int type;
entry = (struct g_part_pc98_entry *)baseentry;
- type = entry->ent.dp_mid + (entry->ent.dp_sid << 8);
- if (type == DOSPTYP_386BSD)
+ type = (entry->ent.dp_mid & PC98_MID_MASK) |
+ ((entry->ent.dp_sid & PC98_SID_MASK) << 8);
+ if (type == (PC98_MID_386BSD | (PC98_SID_386BSD << 8)))
return (g_part_alias_name(G_PART_ALIAS_FREEBSD));
snprintf(buf, bufsz, "!%d", type);
return (buf);
OpenPOWER on IntegriCloud