From owner-freebsd-bugs@FreeBSD.ORG Sun Oct 26 18:20:03 2008 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D09FC106566B for ; Sun, 26 Oct 2008 18:20:03 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 7421B8FC24 for ; Sun, 26 Oct 2008 18:20:03 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id m9QIK3fK093811 for ; Sun, 26 Oct 2008 18:20:03 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id m9QIK2wO093810; Sun, 26 Oct 2008 18:20:02 GMT (envelope-from gnats) Resent-Date: Sun, 26 Oct 2008 18:20:02 GMT Resent-Message-Id: <200810261820.m9QIK2wO093810@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Marius Nuennerich Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EC3BC1065673 for ; Sun, 26 Oct 2008 18:10:57 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id D9BBE8FC0C for ; Sun, 26 Oct 2008 18:10:57 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.3/8.14.3) with ESMTP id m9QIAv9o024496 for ; Sun, 26 Oct 2008 18:10:57 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.3/8.14.3/Submit) id m9QIAvNC024495; Sun, 26 Oct 2008 18:10:57 GMT (envelope-from nobody) Message-Id: <200810261810.m9QIAvNC024495@www.freebsd.org> Date: Sun, 26 Oct 2008 18:10:57 GMT From: Marius Nuennerich To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/128398: [PATCH] Teach geom_label to recognise gpt labels and uuids X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 26 Oct 2008 18:20:03 -0000 >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 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#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: