8661 AI fails to continue installation if slices exist from previous configuration Build138
authorWilliam Schumann <william.schumann@sun.com>
Mon, 19 Apr 2010 16:22:56 +0200
changeset 810 8f09387744e3
parent 809 8d8b29a4e1f0
child 811 6b2217f81b65
8661 AI fails to continue installation if slices exist from previous configuration
usr/src/cmd/auto-install/ai_manifest.defval.xml
usr/src/cmd/auto-install/ai_manifest.rng
usr/src/cmd/auto-install/auto_install.c
usr/src/cmd/auto-install/auto_install.h
usr/src/cmd/auto-install/auto_parse.c
usr/src/lib/liborchestrator/disk_slices.c
usr/src/lib/liborchestrator/orchestrator_api.h
--- a/usr/src/cmd/auto-install/ai_manifest.defval.xml	Wed Apr 14 16:47:16 2010 -0700
+++ b/usr/src/cmd/auto-install/ai_manifest.defval.xml	Mon Apr 19 16:22:56 2010 +0200
@@ -18,7 +18,7 @@
 
 CDDL HEADER END
 
-Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
 Use is subject to license terms.
 -->
 
@@ -97,4 +97,8 @@
 	    from="value" type="element" missing_parent="skip">
 		0
 	</default>
+	<default nodepath="ai_device_vtoc_slices/slice_on_existing"
+	    from="value" type="element" missing_parent="skip">
+		error
+	</default>
 </defaults_and_validation_manifest>
--- a/usr/src/cmd/auto-install/ai_manifest.rng	Wed Apr 14 16:47:16 2010 -0700
+++ b/usr/src/cmd/auto-install/ai_manifest.rng	Mon Apr 19 16:22:56 2010 +0200
@@ -19,7 +19,7 @@
 
 CDDL HEADER END
 
-Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
 Use is subject to license terms.
 -->
 
@@ -439,6 +439,10 @@
 					<optional>
 						<ref name="slice_size_units_contents"/>
 					</optional>
+					<optional>
+						<!-- define behavior on create action if specified slice exists -->
+						<ref name="slice_on_existing_contents"/>
+					</optional>
 				</interleave>
 			</group>
 			<!-- delete slice - by slice number only -->
@@ -454,6 +458,9 @@
 					<optional>
 						<ref name="slice_size_units_contents"/>
 					</optional>
+					<optional>
+						<ref name="slice_on_existing_contents"/>
+					</optional>
 				</interleave>
 			</group>
 			<!-- preserve slice - by slice number only -->
@@ -469,6 +476,9 @@
 					<optional>
 						<ref name="slice_size_units_contents"/>
 					</optional>
+					<optional>
+						<ref name="slice_on_existing_contents"/>
+					</optional>
 				</interleave>
 			</group>
 		</choice>
@@ -493,6 +503,18 @@
 			<ref name="disk_space_size_units"/>
 		</element>
 	</define>
+        <define name="slice_on_existing_contents">
+               	<element name="slice_on_existing">
+			<choice>
+				<value>error</value>
+				<value>ERROR</value>
+				<value>Error</value>
+				<value>overwrite</value>
+				<value>OVERWRITE</value>
+				<value>Overwrite</value>
+			</choice>
+		</element>
+	</define>
 
         <!--
         =======================================================================
--- a/usr/src/cmd/auto-install/auto_install.c	Wed Apr 14 16:47:16 2010 -0700
+++ b/usr/src/cmd/auto-install/auto_install.c	Mon Apr 19 16:22:56 2010 +0200
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -433,7 +433,7 @@
 			else
 				slice_tag = OM_UNASSIGNED;
 			if (!om_create_slice(asi->slice_number, slice_size_sec,
-			    slice_tag))
+			    slice_tag, asi->on_existing))
 				return (AUTO_INSTALL_FAILURE);
 		} else if (strcmp(asi->slice_action, "delete") == 0) {
 			if (!om_delete_slice(asi->slice_number))
--- a/usr/src/cmd/auto-install/auto_install.h	Wed Apr 14 16:47:16 2010 -0700
+++ b/usr/src/cmd/auto-install/auto_install.h	Mon Apr 19 16:22:56 2010 +0200
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -161,6 +161,8 @@
 #define	AIM_SLICE_SIZE "ai_manifest/ai_device_vtoc_slices/slice_size"
 #define	AIM_SLICE_SIZE_UNITS	\
 	"ai_manifest/ai_device_vtoc_slices/slice_size_units"
+#define	AIM_SLICE_ON_EXISTING	\
+	"ai_manifest/ai_device_vtoc_slices/slice_on_existing"
 #define	AIM_AUTO_REBOOT	"ai_manifest/ai_auto_reboot"
 
 #define	AIM_PROXY_URL "ai_manifest/ai_http_proxy/url"
@@ -320,6 +322,7 @@
 	int		slice_number;
 	uint64_t	slice_size;
 	auto_size_units_t	slice_size_units;
+	om_on_existing_t	on_existing; /* action to take if it exists */
 } auto_slice_info;
 
 typedef struct auto_mirror_repo {
--- a/usr/src/cmd/auto-install/auto_parse.c	Wed Apr 14 16:47:16 2010 -0700
+++ b/usr/src/cmd/auto-install/auto_parse.c	Mon Apr 19 16:22:56 2010 +0200
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -362,7 +362,7 @@
 	adsi->swap_size = -1;
 	p = ai_get_manifest_element_value(AIM_SWAP_SIZE);
 	if (p != NULL) {
-		if (sscanf(p, "%lu", &adsi->swap_size) > 0) {
+		if (sscanf(p, "%ld", &adsi->swap_size) > 0) {
 			auto_debug_print(AUTO_DBGLVL_INFO,
 			    "Swap Size Requested=%lu\n",
 			    adsi->swap_size);
@@ -394,7 +394,7 @@
 	addi->dump_size = -1;
 	p = ai_get_manifest_element_value(AIM_DUMP_SIZE);
 	if (p != NULL) {
-		if (sscanf(p, "%lu", &addi->dump_size) > 0) {
+		if (sscanf(p, "%ld", &addi->dump_size) > 0) {
 			auto_debug_print(AUTO_DBGLVL_INFO,
 			    "Dump Size Requested=%lu\n",
 			    addi->dump_size);
@@ -734,6 +734,23 @@
 		}
 		free(p);
 	}
+
+	/*
+	 * Determine behavior for create action on existing slices.
+	 */
+	p = get_manifest_element_array(AIM_SLICE_ON_EXISTING);
+	if (p != NULL) {
+		/*
+		 * Since the slice information array is initialized to zero,
+		 * and the default enum value is also zero, the "error" case
+		 * will also be the default in the slice information array.
+		 */
+		for (i = 0; i < len; i++)
+			if (p[i] != NULL && strcasecmp(p[i], "overwrite") == 0)
+				(asi + i)->on_existing =
+				    OM_ON_EXISTING_OVERWRITE;
+		free(p);
+	}
 	return (asi);
 }
 
--- a/usr/src/lib/liborchestrator/disk_slices.c	Wed Apr 14 16:47:16 2010 -0700
+++ b/usr/src/lib/liborchestrator/disk_slices.c	Mon Apr 19 16:22:56 2010 +0200
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -412,7 +412,7 @@
 
 boolean_t
 om_create_slice(uint8_t slice_id, uint64_t slice_size,
-    om_slice_tag_type_t slice_tag)
+    om_slice_tag_type_t slice_tag, om_on_existing_t on_existing)
 {
 	slice_info_t *psinfo;
 	int isl;
@@ -446,13 +446,35 @@
 	}
 	psinfo = committed_disk_target->dslices->sinfo;
 	log_slice_map();
+	/*
+	 * take indicated action if slice already exists
+	 */
 	for (isl = 0; isl < NDKMAP; isl++, psinfo++) {
 		if (slice_id == psinfo->slice_id &&
 		    psinfo->slice_size != 0) { /* slice already exists */
-			om_debug_print(OM_DBGLVL_ERR,
-			    "creating slice which already exists\n");
-			om_set_error(OM_ALREADY_EXISTS);
-			return (B_FALSE);
+			switch (on_existing) {
+			case OM_ON_EXISTING_OVERWRITE:
+				om_debug_print(OM_DBGLVL_INFO,
+				    "overwriting VTOC entry for existing "
+				    "slice %d\n", slice_id);
+				(void) remove_slice_from_table(slice_id);
+				break; /* proceed with create */
+			case OM_ON_EXISTING_ERROR:
+				om_debug_print(OM_DBGLVL_ERR,
+				    "trying to create slice %d which already "
+				    "exists in the VTOC\n", slice_id);
+				om_set_error(OM_ALREADY_EXISTS);
+				return (B_FALSE);
+			default: /* unrecognized parameter value */
+				om_debug_print(OM_DBGLVL_ERR,
+				    "unrecognized \"on exists\" option "
+				    "while attempting to create slice %d when "
+				    "it it already exists in the VTOC. "
+				    "Specify \"overwrite\" or "
+				    "take the default.\n", slice_id);
+				om_set_error(OM_ALREADY_EXISTS);
+				return (B_FALSE);
+			}
 		}
 	}
 	psinfo = committed_disk_target->dslices->sinfo;
@@ -624,7 +646,8 @@
 		om_debug_print(OM_DBGLVL_INFO,
 		    "Creating install slice %d in largest free region in "
 		    "partition\n", install_slice_id);
-		if (!om_create_slice(install_slice_id, 0, OM_ROOT)) {
+		if (!om_create_slice(install_slice_id, 0, OM_ROOT,
+		    OM_ON_EXISTING_ERROR)) {
 			om_debug_print(OM_DBGLVL_ERR,
 			    "Install slice %d could not be created.\n",
 			    install_slice_id);
@@ -712,7 +735,8 @@
 			 * indicating VTOC partition tag
 			 */
 			if (!om_create_slice(1,
-			    swap_size * BLOCKS_TO_MB, OM_SWAP)) {
+			    swap_size * BLOCKS_TO_MB, OM_SWAP,
+			    OM_ON_EXISTING_ERROR)) {
 				swap_slice_1_failure = B_TRUE;
 				/*
 				 * indicate error, but no install failure
@@ -1191,9 +1215,12 @@
 }
 
 /*
- * find contiguous space that fits requested size most closely
- * must have previous call to build_free_space_table()
- * return size + offset of region or NULL if none found
+ * Find contiguous space that fits most closely requested size
+ * Must have previous call to build_free_space_table()
+ * Returns size + offset of region or NULL if none found
+ * Will accept match if region is up to 1 cylinder smaller than requested
+ *	due to Target Instantiation rounding - facilitates AI manifest reuse
+ *	with slice_on_existing=overwrite option
  */
 static struct free_region *
 find_free_region_best_fit(uint64_t slice_size)
@@ -1202,6 +1229,12 @@
 	struct free_region *best_fit = NULL;
 	int ireg;
 
+	/*
+	 * search for the best fit for a region 1 cylinder less than requested
+	 */
+	if (committed_disk_target != NULL &&
+	    slice_size > committed_disk_target->dinfo.disk_cyl_size)
+		slice_size -= committed_disk_target->dinfo.disk_cyl_size;
 	for (pregion = free_space_table, ireg = 0;
 	    ireg < n_fragments; ireg++, pregion++) {
 		if (best_fit == NULL) { /* find first fit */
@@ -1302,14 +1335,16 @@
 	slice_info_t *sinfo;
 
 	sinfo = &committed_disk_target->dslices->sinfo[0];
-	om_debug_print(OM_DBGLVL_INFO, "Modified slice table\n");
-	om_debug_print(OM_DBGLVL_INFO, "\tid\toffset\tsize\toff+size\ttag\n");
+	om_debug_print(OM_DBGLVL_INFO, "Modified slice table:\n");
+	om_debug_print(OM_DBGLVL_INFO,
+	    "\tid      offset        size    off+size tag\n");
 	for (isl = 0; isl < NDKMAP; isl++) {
 		if (sinfo[isl].slice_size == 0)
 			continue;
 		if (RESERVED_SLICE(sinfo[isl].slice_id))
 			continue;
-		om_debug_print(OM_DBGLVL_INFO, "\t%d\t%lld\t%lld\t%lld\t%d\n",
+		om_debug_print(OM_DBGLVL_INFO,
+		    "\t%2d %11lld %11lld %11lld %d\n",
 		    sinfo[isl].slice_id,
 		    sinfo[isl].slice_offset,
 		    sinfo[isl].slice_size,
@@ -1331,9 +1366,10 @@
 		om_debug_print(OM_DBGLVL_INFO, "\tno slices in sorted table\n");
 		return;
 	}
-	om_debug_print(OM_DBGLVL_INFO, "\tslice\toffset\tsize\toffset+size\n");
+	om_debug_print(OM_DBGLVL_INFO,
+	    "\tslice      offset        size offset+size\n");
 	for (isl = 0; isl < n_sorted_slices; isl++) {
-		om_debug_print(OM_DBGLVL_INFO, "\t%d\t%lld\t%lld\t%lld\n",
+		om_debug_print(OM_DBGLVL_INFO, "\t%5d %11lld %11lld %11lld\n",
 		    sorted_slices[isl].slice_id,
 		    sorted_slices[isl].slice_offset,
 		    sorted_slices[isl].slice_size,
@@ -1350,16 +1386,17 @@
 {
 	int i;
 
-	om_debug_print(OM_DBGLVL_INFO, "Free space fragments - count %d\n",
+	om_debug_print(OM_DBGLVL_INFO, "Free space fragments - count %d:\n",
 	    n_fragments);
 	if (n_fragments == 0) {
 		om_debug_print(OM_DBGLVL_INFO,
 		    "\tentire disk/partition now in use\n");
 		return;
 	}
-	om_debug_print(OM_DBGLVL_INFO, "\toffset\tsize\tnoffset+size\n");
+	om_debug_print(OM_DBGLVL_INFO,
+	    "\t     offset        size offset+size\n");
 	for (i = 0; i < n_fragments; i++)
-		om_debug_print(OM_DBGLVL_INFO, "\t%lld\t%lld\t%lld\n",
+		om_debug_print(OM_DBGLVL_INFO, "\t%11lld %11lld %11lld\n",
 		    free_space_table[i].free_offset,
 		    free_space_table[i].free_size,
 		    free_space_table[i].free_offset +
--- a/usr/src/lib/liborchestrator/orchestrator_api.h	Wed Apr 14 16:47:16 2010 -0700
+++ b/usr/src/lib/liborchestrator/orchestrator_api.h	Mon Apr 19 16:22:56 2010 +0200
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -141,6 +141,17 @@
 	OM_RESERVED
 } om_slice_tag_type_t;
 
+/*
+ * on AI slice create action, if slice with specified number already exists,
+ *	determine behavior:
+ *	- error (default) - treat as configuration error and halt installation
+ *	- overwrite - supersede existing definition with new
+ */
+typedef enum {
+	OM_ON_EXISTING_ERROR = 0,
+	OM_ON_EXISTING_OVERWRITE
+} om_on_existing_t;
+
 typedef	enum {
 	KBD_NUM = 1,
 	KBD_NAME,
@@ -504,7 +515,8 @@
 disk_slices_t   *om_duplicate_slice_info(om_handle_t handle,
 			disk_slices_t *dslices);
 int		om_set_slice_info(om_handle_t, disk_slices_t *);
-boolean_t	om_create_slice(uint8_t, uint64_t, om_slice_tag_type_t);
+boolean_t	om_create_slice(uint8_t, uint64_t, om_slice_tag_type_t,
+			om_on_existing_t);
 boolean_t	om_delete_slice(uint8_t);
 boolean_t	om_preserve_slice(uint8_t);
 disk_slices_t   *om_init_slice_info(const char *);