kern/128398: [PATCH] Teach geom_label to recognise gpt labels and uuids

Marius Nuennerich marius at nuenneri.ch
Sun Oct 26 18:20:03 UTC 2008


>Number:         128398
>Category:       kern
>Synopsis:       [PATCH] Teach geom_label to recognise gpt labels and uuids
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Oct 26 18:20:02 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Marius Nuennerich
>Release:        8-current
>Organization:
>Environment:
8.0-CURRENT #0 r184181
>Description:
Attached is a patch which adds gpt label and uuid support to geom_label.
>How-To-Repeat:

>Fix:


Patch attached with submission follows:

Index: sbin/geom/class/label/glabel.8
===================================================================
--- sbin/geom/class/label/glabel.8	(revision 184181)
+++ sbin/geom/class/label/glabel.8	(working copy)
@@ -81,13 +81,13 @@
 method uses on-disk metadata to store the label and detect it automatically in
 the future.
 .Pp
-This class also provides volume label detection for file systems.
-Those labels cannot be set with
+This class also provides volume label detection for file systems and
+partitions. Those labels cannot be set with
 .Nm ,
-but must be set with the appropriate file system utility, e.g.\& for UFS
+but must be set with the appropriate utility, e.g.\& for UFS
 the file system label is set with
 .Xr tunefs 8 .
-Currently supported file systems are:
+Currently supported file systems and partitions are:
 .Pp
 .Bl -bullet -offset indent -compact
 .It
@@ -111,6 +111,12 @@
 .It
 NTFS (directory
 .Pa /dev/ntfs/ ) .
+.lt
+GPT (directory
+.Pa /dev/gpt/ ) .
+.lt
+GPT UUIDs (directory
+.Pa /dev/gpt/ ) .
 .El
 .Pp
 Non file-system labels are created in the directory
Index: sys/conf/files
===================================================================
--- sys/conf/files	(revision 184181)
+++ sys/conf/files	(working copy)
@@ -1521,6 +1521,7 @@
 geom/label/g_label_ntfs.c	optional geom_label
 geom/label/g_label_reiserfs.c	optional geom_label
 geom/label/g_label_ufs.c	optional geom_label
+geom/label/g_label_gpt.c	optional geom_label
 geom/linux_lvm/g_linux_lvm.c	optional geom_linux_lvm
 geom/mirror/g_mirror.c		optional geom_mirror
 geom/mirror/g_mirror_ctl.c	optional geom_mirror
Index: sys/modules/geom/geom_label/Makefile
===================================================================
--- sys/modules/geom/geom_label/Makefile	(revision 184181)
+++ sys/modules/geom/geom_label/Makefile	(working copy)
@@ -10,5 +10,6 @@
 SRCS+=	g_label_ntfs.c
 SRCS+=	g_label_reiserfs.c
 SRCS+=	g_label_ufs.c
+SRCS+=	g_label_gpt.c
 
 .include <bsd.kmod.mk>
Index: sys/geom/label/g_label_gpt.c
===================================================================
--- sys/geom/label/g_label_gpt.c	(revision 0)
+++ sys/geom/label/g_label_gpt.c	(revision 0)
@@ -0,0 +1,161 @@
+/*-
+ * Copyright (c) 2008 Marius Nuennerich
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/kobj.h>
+#include <sys/gpt.h>
+
+#include <geom/geom.h>
+#include <geom/label/g_label.h>
+#include <geom/part/g_part.h>
+
+#define	PART_CLASS_NAME	"PART"
+#define	SCHEME_NAME	"GPT"
+
+/* also defined in geom/part/g_part_gpt.c */
+struct g_part_gpt_entry {
+	struct g_part_entry     base;
+	struct gpt_ent          ent;
+};
+
+/* shamelessly stolen from g_part_gpt.c */
+static void
+sbuf_nprintf_utf16(struct sbuf *sb, uint16_t *str, size_t len)
+{
+	u_int bo;
+	uint32_t ch;
+	uint16_t c;
+
+	bo = LITTLE_ENDIAN;	/* GPT is little-endian */
+	while (len > 0 && *str != 0) {
+		ch = (bo == BIG_ENDIAN) ? be16toh(*str) : le16toh(*str);
+		str++, len--;
+		if ((ch & 0xf800) == 0xd800) {
+			if (len > 0) {
+				c = (bo == BIG_ENDIAN) ? be16toh(*str)
+				    : le16toh(*str);
+				str++, len--;
+			} else
+				c = 0xfffd;
+			if ((ch & 0x400) == 0 && (c & 0xfc00) == 0xdc00) {
+				ch = ((ch & 0x3ff) << 10) + (c & 0x3ff);
+				ch += 0x10000;
+			} else
+				ch = 0xfffd;
+		} else if (ch == 0xfffe) { /* BOM (U+FEFF) swapped. */
+			bo = (bo == BIG_ENDIAN) ? LITTLE_ENDIAN : BIG_ENDIAN;
+			continue;
+		} else if (ch == 0xfeff) /* BOM (U+FEFF) unswapped. */
+			continue;
+
+		/* Write the Unicode character in UTF-8 */
+		if (ch < 0x80)
+			sbuf_printf(sb, "%c", ch);
+		else if (ch < 0x800)
+			sbuf_printf(sb, "%c%c", 0xc0 | (ch >> 6),
+			    0x80 | (ch & 0x3f));
+		else if (ch < 0x10000)
+			sbuf_printf(sb, "%c%c%c", 0xe0 | (ch >> 12),
+			    0x80 | ((ch >> 6) & 0x3f), 0x80 | (ch & 0x3f));
+		else if (ch < 0x200000)
+			sbuf_printf(sb, "%c%c%c%c", 0xf0 | (ch >> 18),
+			    0x80 | ((ch >> 12) & 0x3f),
+			    0x80 | ((ch >> 6) & 0x3f), 0x80 | (ch & 0x3f));
+	}
+}
+
+static void
+g_label_gpt_taste(struct g_consumer *cp, char *label, size_t size)
+{
+	struct g_provider *pp;
+	struct g_part_table *tp;
+	struct g_part_gpt_entry *part_gpt_entry;
+	struct sbuf *lbl;
+
+	g_topology_assert_not();
+	pp = cp->provider;
+	tp = (struct g_part_table *)pp->geom->softc;
+	label[0] = '\0';
+
+	/* We taste only partitions from GPART */
+	if (strncmp(pp->geom->class->name, PART_CLASS_NAME, sizeof(PART_CLASS_NAME)))
+		return;
+	/* and only GPT */
+	if (strncmp(tp->gpt_scheme->name, SCHEME_NAME, sizeof(SCHEME_NAME)))
+		return;
+
+	part_gpt_entry = (struct g_part_gpt_entry *)pp->private;
+
+	/*
+	 * create sbuf with biggest possible size
+	 * we need max. 4 bytes for every 2-byte utf16 char
+	 */
+	lbl = sbuf_new(NULL, NULL, sizeof(part_gpt_entry->ent.ent_name) << 1, SBUF_FIXEDLEN);
+	/* size ist the number of characters, not bytes */
+	sbuf_nprintf_utf16(lbl, part_gpt_entry->ent.ent_name, sizeof(part_gpt_entry->ent.ent_name) >> 1);
+	sbuf_finish(lbl);
+	strlcpy(label, sbuf_data(lbl), size);
+	sbuf_delete(lbl);
+}
+
+static void
+g_label_gpt_uuid_taste(struct g_consumer *cp, char *label, size_t size)
+{
+	struct g_provider *pp;
+	struct g_part_table *tp;
+	struct g_part_gpt_entry *part_gpt_entry;
+
+	g_topology_assert_not();
+	pp = cp->provider;
+	tp = (struct g_part_table *)pp->geom->softc;
+	label[0] = '\0';
+
+	/* we taste only partitions from GPART */
+	if (strncmp(pp->geom->class->name, PART_CLASS_NAME, sizeof(PART_CLASS_NAME)))
+		return;
+	/* and only GPT */
+	if (strncmp(tp->gpt_scheme->name, SCHEME_NAME, sizeof(SCHEME_NAME)))
+		return;
+
+	part_gpt_entry = (struct g_part_gpt_entry *)pp->private;
+	snprintf_uuid(label, size, &part_gpt_entry->ent.ent_uuid);
+}
+
+const struct g_label_desc g_label_gpt = {
+	.ld_taste = g_label_gpt_taste,
+	.ld_dir = "gpt"
+};
+
+const struct g_label_desc g_label_gpt_uuid = {
+	.ld_taste = g_label_gpt_uuid_taste,
+	.ld_dir = "gpt"
+};
Index: sys/geom/label/g_label.c
===================================================================
--- sys/geom/label/g_label.c	(revision 184181)
+++ sys/geom/label/g_label.c	(working copy)
@@ -83,6 +83,8 @@
 	&g_label_ext2fs,
 	&g_label_reiserfs,
 	&g_label_ntfs,
+	&g_label_gpt,
+	&g_label_gpt_uuid,
 	NULL
 };
 
Index: sys/geom/label/g_label.h
===================================================================
--- sys/geom/label/g_label.h	(revision 184181)
+++ sys/geom/label/g_label.h	(working copy)
@@ -70,6 +70,8 @@
 extern const struct g_label_desc g_label_ext2fs;
 extern const struct g_label_desc g_label_reiserfs;
 extern const struct g_label_desc g_label_ntfs;
+extern const struct g_label_desc g_label_gpt;
+extern const struct g_label_desc g_label_gpt_uuid;
 #endif	/* _KERNEL */
 
 struct g_label_metadata {


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list