From owner-svn-src-head@FreeBSD.ORG Sat Jun 13 00:27:03 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DABCB1065674; Sat, 13 Jun 2009 00:27:03 +0000 (UTC) (envelope-from ivoras@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C69FA8FC0A; Sat, 13 Jun 2009 00:27:03 +0000 (UTC) (envelope-from ivoras@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n5D0R37P097634; Sat, 13 Jun 2009 00:27:03 GMT (envelope-from ivoras@svn.freebsd.org) Received: (from ivoras@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n5D0R3CU097629; Sat, 13 Jun 2009 00:27:03 GMT (envelope-from ivoras@svn.freebsd.org) Message-Id: <200906130027.n5D0R3CU097629@svn.freebsd.org> From: Ivan Voras Date: Sat, 13 Jun 2009 00:27:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r194092 - in head: sbin/geom/class/label sys/conf sys/geom/label X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 13 Jun 2009 00:27:04 -0000 Author: ivoras Date: Sat Jun 13 00:27:03 2009 New Revision: 194092 URL: http://svn.freebsd.org/changeset/base/194092 Log: Add support for labels derived from GPT metadata. Approved by: gnn (mentor) Reviewed by: pjd PR: 128398 Submitted by: Marius Nuennerich < marius at nuenneri.ch > Added: head/sys/geom/label/g_label_gpt.c (contents, props changed) Modified: head/sbin/geom/class/label/glabel.8 head/sys/conf/files head/sys/geom/label/g_label.c head/sys/geom/label/g_label.h Modified: head/sbin/geom/class/label/glabel.8 ============================================================================== --- head/sbin/geom/class/label/glabel.8 Sat Jun 13 00:13:44 2009 (r194091) +++ head/sbin/geom/class/label/glabel.8 Sat Jun 13 00:27:03 2009 (r194092) @@ -1,4 +1,5 @@ .\" Copyright (c) 2004-2005 Pawel Jakub Dawidek +.\" Copyright (c) 2008-2009 Ivan Voras .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -24,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 2, 2004 +.Dd June 13, 2009 .Dt GLABEL 8 .Os .Sh NAME @@ -119,7 +120,18 @@ NTFS (directory .Pa /dev/ntfs/ ) . .El .Pp -Non file-system labels are created in the directory +Support for partition metadata is implemented for: +.Pp +.Bl -bullet -offset indent -compact +.It +GPT labels (directory +.Pa /dev/gpt/ ) . +.It +GPT UUIDs (directory +.Pa /dev/gptid/ ) . +.El +.Pp +Generic labels are created in the directory .Pa /dev/label/ . .Pp The first argument to Modified: head/sys/conf/files ============================================================================== --- head/sys/conf/files Sat Jun 13 00:13:44 2009 (r194091) +++ head/sys/conf/files Sat Jun 13 00:27:03 2009 (r194092) @@ -1852,6 +1852,7 @@ geom/label/g_label_msdosfs.c optional ge 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 Modified: head/sys/geom/label/g_label.c ============================================================================== --- head/sys/geom/label/g_label.c Sat Jun 13 00:13:44 2009 (r194091) +++ head/sys/geom/label/g_label.c Sat Jun 13 00:27:03 2009 (r194092) @@ -84,6 +84,8 @@ const struct g_label_desc *g_labels[] = &g_label_ext2fs, &g_label_reiserfs, &g_label_ntfs, + &g_label_gpt, + &g_label_gpt_uuid, NULL }; Modified: head/sys/geom/label/g_label.h ============================================================================== --- head/sys/geom/label/g_label.h Sat Jun 13 00:13:44 2009 (r194091) +++ head/sys/geom/label/g_label.h Sat Jun 13 00:27:03 2009 (r194092) @@ -71,6 +71,8 @@ extern const struct g_label_desc g_label 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 { Added: head/sys/geom/label/g_label_gpt.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/geom/label/g_label_gpt.c Sat Jun 13 00:27:03 2009 (r194092) @@ -0,0 +1,164 @@ +/*- + * 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" + +#define G_LABEL_GPT_VOLUME_DIR "gpt" +#define G_LABEL_GPT_ID_DIR "gptid" + +/* 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 = G_LABEL_GPT_VOLUME_DIR +}; + +const struct g_label_desc g_label_gpt_uuid = { + .ld_taste = g_label_gpt_uuid_taste, + .ld_dir = G_LABEL_GPT_ID_DIR +};