svn commit: r184069 - head/sys/geom/part

Marcel Moolenaar marcel at FreeBSD.org
Mon Oct 20 04:50:48 UTC 2008


Author: marcel
Date: Mon Oct 20 04:50:47 2008
New Revision: 184069
URL: http://svn.freebsd.org/changeset/base/184069

Log:
  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.

Modified:
  head/sys/geom/part/g_part_pc98.c

Modified: head/sys/geom/part/g_part_pc98.c
==============================================================================
--- head/sys/geom/part/g_part_pc98.c	Mon Oct 20 04:50:06 2008	(r184068)
+++ head/sys/geom/part/g_part_pc98.c	Mon Oct 20 04:50:47 2008	(r184069)
@@ -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_p
     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
 		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 *bas
 
 	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
 	} 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 *
 
 	/* 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 *ba
 	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 *ba
 	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);


More information about the svn-src-all mailing list