8661 AI fails to continue installation if slices exist from previous configuration
--- 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 *);