From owner-svn-src-all@FreeBSD.ORG Fri Sep 24 19:33:47 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 614241065674; Fri, 24 Sep 2010 19:33:47 +0000 (UTC) (envelope-from pjd@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 503B98FC16; Fri, 24 Sep 2010 19:33:47 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o8OJXlFV037477; Fri, 24 Sep 2010 19:33:47 GMT (envelope-from pjd@svn.freebsd.org) Received: (from pjd@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o8OJXlCr037475; Fri, 24 Sep 2010 19:33:47 GMT (envelope-from pjd@svn.freebsd.org) Message-Id: <201009241933.o8OJXlCr037475@svn.freebsd.org> From: Pawel Jakub Dawidek Date: Fri, 24 Sep 2010 19:33:47 +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: r213135 - head/sys/geom/part X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 24 Sep 2010 19:33:47 -0000 Author: pjd Date: Fri Sep 24 19:33:47 2010 New Revision: 213135 URL: http://svn.freebsd.org/changeset/base/213135 Log: Allow to configure GPT attributes. It shouldn't be allowed to set bootfailed attribute (it should be allowed only to unset it), but for test purposes it might be useful, so the current code allows it. Reviewed by: arch@ (Message-ID: <20100917234542.GE1902@garage.freebsd.pl>) MFC after: 2 weeks Modified: head/sys/geom/part/g_part_gpt.c Modified: head/sys/geom/part/g_part_gpt.c ============================================================================== --- head/sys/geom/part/g_part_gpt.c Fri Sep 24 19:31:53 2010 (r213134) +++ head/sys/geom/part/g_part_gpt.c Fri Sep 24 19:33:47 2010 (r213135) @@ -100,6 +100,8 @@ static const char *g_part_gpt_name(struc char *, size_t); static int g_part_gpt_probe(struct g_part_table *, struct g_consumer *); static int g_part_gpt_read(struct g_part_table *, struct g_consumer *); +static int g_part_gpt_setunset(struct g_part_table *table, + struct g_part_entry *baseentry, const char *attrib, unsigned int set); static const char *g_part_gpt_type(struct g_part_table *, struct g_part_entry *, char *, size_t); static int g_part_gpt_write(struct g_part_table *, struct g_consumer *); @@ -118,6 +120,7 @@ static kobj_method_t g_part_gpt_methods[ KOBJMETHOD(g_part_name, g_part_gpt_name), KOBJMETHOD(g_part_probe, g_part_gpt_probe), KOBJMETHOD(g_part_read, g_part_gpt_read), + KOBJMETHOD(g_part_setunset, g_part_gpt_setunset), KOBJMETHOD(g_part_type, g_part_gpt_type), KOBJMETHOD(g_part_write, g_part_gpt_write), { 0, 0 } @@ -519,6 +522,16 @@ g_part_gpt_dumpconf(struct g_part_table g_gpt_printf_utf16(sb, entry->ent.ent_name, sizeof(entry->ent.ent_name) >> 1); sbuf_printf(sb, "\n"); + if (entry->ent.ent_attr & GPT_ENT_ATTR_BOOTME) + sbuf_printf(sb, "%sbootme\n", indent); + if (entry->ent.ent_attr & GPT_ENT_ATTR_BOOTONCE) { + sbuf_printf(sb, "%sbootonce\n", + indent); + } + if (entry->ent.ent_attr & GPT_ENT_ATTR_BOOTFAILED) { + sbuf_printf(sb, "%sbootfailed\n", + indent); + } sbuf_printf(sb, "%s", indent); sbuf_printf_uuid(sb, &entry->ent.ent_type); sbuf_printf(sb, "\n"); @@ -755,6 +768,78 @@ g_part_gpt_read(struct g_part_table *bas return (0); } +static int +g_part_gpt_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_gpt_entry *entry; + int changed, bootme, bootonce, bootfailed; + + bootme = bootonce = bootfailed = 0; + if (strcasecmp(attrib, "bootme") == 0) { + bootme = 1; + } else if (strcasecmp(attrib, "bootonce") == 0) { + /* BOOTME is set automatically with BOOTONCE, but not unset. */ + bootonce = 1; + if (set) + bootme = 1; + } else if (strcasecmp(attrib, "bootfailed") == 0) { + /* + * It should only be possible to unset BOOTFAILED, but it might + * be useful for test purposes to also be able to set it. + */ + bootfailed = 1; + } + if (!bootme && !bootonce && !bootfailed) + 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_gpt_entry *)iter; + if (set) { + if (bootme && + !(entry->ent.ent_attr & GPT_ENT_ATTR_BOOTME)) { + entry->ent.ent_attr |= GPT_ENT_ATTR_BOOTME; + changed = 1; + } + if (bootonce && + !(entry->ent.ent_attr & GPT_ENT_ATTR_BOOTONCE)) { + entry->ent.ent_attr |= GPT_ENT_ATTR_BOOTONCE; + changed = 1; + } + if (bootfailed && + !(entry->ent.ent_attr & GPT_ENT_ATTR_BOOTFAILED)) { + entry->ent.ent_attr |= GPT_ENT_ATTR_BOOTFAILED; + changed = 1; + } + } else { + if (bootme && + (entry->ent.ent_attr & GPT_ENT_ATTR_BOOTME)) { + entry->ent.ent_attr &= ~GPT_ENT_ATTR_BOOTME; + changed = 1; + } + if (bootonce && + (entry->ent.ent_attr & GPT_ENT_ATTR_BOOTONCE)) { + entry->ent.ent_attr &= ~GPT_ENT_ATTR_BOOTONCE; + changed = 1; + } + if (bootfailed && + (entry->ent.ent_attr & GPT_ENT_ATTR_BOOTFAILED)) { + entry->ent.ent_attr &= ~GPT_ENT_ATTR_BOOTFAILED; + changed = 1; + } + } + if (changed && !iter->gpe_created) + iter->gpe_modified = 1; + } + return (0); +} + static const char * g_part_gpt_type(struct g_part_table *basetable, struct g_part_entry *baseentry, char *buf, size_t bufsz)