changeset 9958:108c82b6bad3

6776708 Unable to write EFI label with mounted partitions
author Sharath M Srinivasan <Sharath.Srinivasan@Sun.COM>
date Wed, 24 Jun 2009 12:00:21 +0530
parents 8769ec0debbf
children acbef346fd18
files usr/src/cmd/format/checkdev.c
diffstat 1 files changed, 83 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/format/checkdev.c	Tue Jun 23 17:42:42 2009 -0700
+++ b/usr/src/cmd/format/checkdev.c	Wed Jun 24 12:00:21 2009 +0530
@@ -19,12 +19,11 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
  * This file contains miscellaneous device validation routines.
@@ -54,6 +53,7 @@
 #include <libnvpair.h>
 #include "misc.h"
 #include "checkdev.h"
+#include <sys/efi_partition.h>
 
 /* Function prototypes */
 #ifdef	__STDC__
@@ -92,7 +92,7 @@
 	if (num == 0)
 		return (NULL);
 	if ((st = (swaptbl_t *)malloc(num * sizeof (swapent_t) + sizeof (int)))
-			== NULL) {
+	    == NULL) {
 		err_print("getswapentries: malloc  failed.\n");
 		fullabort();
 	}
@@ -311,7 +311,7 @@
 		(void) stat(cur_disk_path, &stbuf);
 		majornum = major(stbuf.st_rdev);
 		(void) modctl(MODGETNAME, majorname, sizeof (majorname),
-				&majornum);
+		    &majornum);
 
 		if (strcmp(majorname, "sd"))
 			if (strcmp(majorname, "ssd"))
@@ -326,7 +326,8 @@
 	name = strrchr(cur_disk_path, 'd');
 	if (name) {
 		name++;
-		for (; (*name <= '9') && (*name >= '0'); name++);
+		for (; (*name <= '9') && (*name >= '0'); name++) {
+		}
 		*name = (char)0;
 	}
 
@@ -362,8 +363,7 @@
 			name = dm_get_name(slices[i], &error);
 			if (error != 0 || !name) {
 				err_print("Error occurred with device "
-				    "in use checking: %s\n",
-				    strerror(error));
+				    "in use checking: %s\n", strerror(error));
 				continue;
 			}
 			if (dm_inuse(name, &usage, DM_WHO_FORMAT, &error) ||
@@ -371,9 +371,9 @@
 				if (error != 0) {
 					dm_free_name(name);
 					name = NULL;
-					err_print("Error occurred with device "
-					    "in use checking: %s\n",
-					    strerror(error));
+					err_print("Error occurred with "
+					    "device in use checking: "
+					    "%s\n", strerror(error));
 					continue;
 				}
 				dm_free_name(name);
@@ -437,8 +437,7 @@
 			name = dm_get_name(slices[i], &error);
 			if (error != 0 || !name) {
 				err_print("Error occurred with device "
-				    "in use checking: %s\n",
-				    strerror(error));
+				    "in use checking: %s\n", strerror(error));
 				nvlist_free(attrs);
 				attrs = NULL;
 				continue;
@@ -448,9 +447,9 @@
 				if (error != 0) {
 					dm_free_name(name);
 					name = NULL;
-					err_print("Error occurred with device "
-					    "in use checking: %s\n",
-					    strerror(error));
+					err_print("Error occurred with "
+					    "device in use checking: "
+					    "%s\n", strerror(error));
 					nvlist_free(attrs);
 					attrs = NULL;
 					continue;
@@ -500,8 +499,7 @@
 			name = dm_get_name(slices[i], &error);
 			if (error != 0 || !name) {
 				err_print("Error occurred with device "
-				    "in use checking: %s\n",
-				    strerror(error));
+				    "in use checking: %s\n", strerror(error));
 				nvlist_free(attrs);
 				attrs = NULL;
 				continue;
@@ -740,6 +738,7 @@
 	struct dk_map		*o;
 	struct dk_allmap	old_map;
 	int			i, found = 0;
+	struct partition64	o_efi;
 
 	/*
 	 * Now we need to check that the current partition list and the
@@ -749,51 +748,83 @@
 	 */
 
 	/*
-	 * Get the "real" (on-disk) version of the partition table
+	 * Check if the user wants to online-label an
+	 * existing EFI label.
 	 */
-	if (ioctl(cur_file, DKIOCGAPART, &old_map) == -1) {
-		err_print("Unable to get current partition map.\n");
-		return (-1);
-	}
-	for (i = 0; i < NDKMAP; i++) {
-		if (bm_mounted & (1 << i)) {
-			/*
-			 * This partition is mounted
-			 */
-			o = &old_map.dka_map[i];
-			n = &cur_parts->pinfo_map[i];
+	if (cur_label == L_TYPE_EFI) {
+		for (i = 0; i < EFI_NUMPAR; i++) {
+			if (bm_mounted & (1 << i)) {
+				o_efi.p_partno = i;
+				if (ioctl(cur_file, DKIOCPARTITION, &o_efi)
+				    == -1) {
+					err_print("Unable to get information "
+					    "for EFI partition %d.\n", i);
+					return (-1);
+				}
+
+				/*
+				 * Partition can grow or remain same.
+				 */
+				if (o_efi.p_start == cur_parts->etoc->
+				    efi_parts[i].p_start && o_efi.p_size
+				    <= cur_parts->etoc->efi_parts[i].p_size) {
+					continue;
+				}
+
+				found = -1;
+			}
+			if (found)
+				break;
+		}
+
+	} else {
+
+		/*
+		 * Get the "real" (on-disk) version of the partition table
+		 */
+		if (ioctl(cur_file, DKIOCGAPART, &old_map) == -1) {
+			err_print("Unable to get current partition map.\n");
+			return (-1);
+		}
+		for (i = 0; i < NDKMAP; i++) {
+			if (bm_mounted & (1 << i)) {
+				/*
+				 * This partition is mounted
+				 */
+				o = &old_map.dka_map[i];
+				n = &cur_parts->pinfo_map[i];
 #ifdef DEBUG
-			fmt_print(
+				fmt_print(
 "checkpartitions :checking partition '%c' \n", i + PARTITION_BASE);
 #endif
-			/*
-			 * If partition is identical, we're fine.
-			 * If the partition grows, we're also fine, because
-			 * the routines in partition.c check for overflow.
-			 * It will (ultimately) be up to the routines in
-			 * partition.c to warn about creation of overlapping
-			 * partitions
-			 */
-			if (o->dkl_cylno == n->dkl_cylno &&
-					o->dkl_nblk <= n->dkl_nblk) {
+				/*
+				 * If partition is identical, we're fine.
+				 * If the partition grows, we're also fine,
+				 * because the routines in partition.c check
+				 * for overflow. It will (ultimately) be up
+				 * to the routines in partition.c to warn
+				 * about creation of overlapping partitions.
+				 */
+				if (o->dkl_cylno == n->dkl_cylno &&
+				    o->dkl_nblk <= n->dkl_nblk) {
 #ifdef	DEBUG
-				if (o->dkl_nblk < n->dkl_nblk) {
-					fmt_print(
+					if (o->dkl_nblk < n->dkl_nblk) {
+						fmt_print(
 "- new partition larger by %d blocks", n->dkl_nblk-o->dkl_nblk);
-				}
-				fmt_print("\n");
+					}
+					fmt_print("\n");
 #endif
-				continue;
-			}
+					continue;
+				}
 #ifdef DEBUG
-			fmt_print("- changes; old (%d,%d)->new (%d,%d)\n",
-				o->dkl_cylno, o->dkl_nblk, n->dkl_cylno,
-				n->dkl_nblk);
+				fmt_print("- changes; old (%d,%d)->new "
+"(%d,%d)\n", o->dkl_cylno, o->dkl_nblk, n->dkl_cylno, n->dkl_nblk);
 #endif
-			found = -1;
+				found = -1;
+			}
+			if (found)
+				break;
 		}
-		if (found)
-			break;
 	}
 
 	/*