2N/A# The contents of this file are subject to the terms of the 2N/A# Common Development and Distribution License (the "License"). 2N/A# You may not use this file except in compliance with the License. 2N/A# See the License for the specific language governing permissions 2N/A# and limitations under the License. 2N/A# When distributing Covered Code, include this CDDL HEADER in each 2N/A# If applicable, add the following below this CDDL HEADER, with the 2N/A# fields enclosed by brackets "[]" replaced with your own identifying 2N/A# information: Portions Copyright [yyyy] [name of copyright owner] 2N/A# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. 2N/A if (( ${#fields[@]} < 6 )); then 2N/A error "%s: unknown data returned from zoneadm list -p" \ 2N/A# run cmd undo rollback 2N/A# Runs the command given in the cmd array. If all goes well, it adds the 2N/A# command in the undo array to the rollback array (of arrays) and returns 0. 2N/A# If the command does not return 0, the commands that exist in the rollback 2N/A# array are executed in the reverse of the order that they were added. 2N/A# In all cases, the exit value from the command in cmd is returned. 2N/A ( eval "${cmd[@]}" ) 2N/A # Push the undo array onto the rollback stack 2N/A error "Command <%s> failed with exit status %d. Rolling back." \ 2N/A for (( i = ${#rollback[@]} - 1; i >= 0; i-- )); do 2N/A log "Executing rollback command <%s>" "${rollback[i][*]}" 2N/A ( eval "${rollback[i][@]}" ) 2N/A# Overrides shared get_active_be. Is used instead of brand-specific 2N/A# get_active_be because they know about the new layout, not the old. 2N/A # solaris10 only supports a single for those that need to be converted. 2N/A # The rest is solaris brand or something that uses the solaris brand 2N/A # Load an associative array of global zone BEs. Store current uuid 2N/A # of GZBE in $active_gzbe. 2N/A # Initially the gzbes associative array is one dimensional. The 2N/A # following loop (beginning with zfs list) will add a second 2N/A # dimension. The fully populated uiid2gzbe structure will look like: 2N/A # uuid2gzbe[<gzbe uuid>]=<gzbe name> 2N/A # uuid2gzbe[<gzbe uuid>][ngzbe name]=<ngz active> 2N/A # Look for the best match of zone BEs 2N/A # skip the non-BE top-level dataset 2N/A # Active dataset was not found by property. See if something is mounted 2N/A # If no active boot environment was found, offer a table of available 2N/A print "\nThe following unconverted boot environments exist this zone.\n" 2N/A print -- "Boot Environment NGZ Active Global Zone Boot Environment" \ 2N/A print -- "----------------- ----------- ----------------------------" \ 2N/A print "\tdsconvert -b <bootenv> ...\n" 2N/A print "to specify the boot environment to activate during conversion.\n" 2N/A print "Usage: dsconvert [-hnv] [-b <BE>] zone\n\n" \ 2N/A " -h\t\tShow this help message\n" \ 2N/A " -n\t\tDry run - make no changes\n" \ 2N/A " -v\t\tVerbose\n" \ 2N/A " -b <BE>\tActivate the specified zone boot environment\n" 2N/Aif (( $# != 1 )); then 2N/A# This check is used for the brief window where people may be trying to use 2N/A# an ON build with a build of the solaris brand that is too old. Since the 2N/A# sysboot script was introduced with the dataset layout change, it makes for 2N/A error "%s: %s must be updated before converting\n\t%s branded zones" \ 2N/A # Be sure that there's a dataset under the old ROOT 2N/A if (( ${#be_datasets[@]} < 2 )); then 2N/A log "%s: configured but no BE mounted at %s" \ 2N/A *) error "%s: Unable to convert zone in state %s" "${zonename}" \ 2N/A error "%s: The -b option is not supported with the %s brand" \ 2N/A error "%s: Zone has no boot environment named %s" \ 2N/A# Look at zonecfg fs and dataset resources to see if anything under /export 2N/A# is added. The message that comes out of zonecfg_has_export is not helpful 2N/A# in this particular case, so we ignore it. 2N/A# Moving the dataset hierarchy is problematic when clones are involved. 2N/A# The easiest way to avoid the problem with clones is to use more of them. 2N/A# Unconventional quoting of date format string is to silence SCCS keyword 2N/A# Get a list of all the old datasets and their properties. Once we 2N/A# have that, use that information to create clones. 2N/A error "%s: Unable to get list of datasets under %s" \ 2N/A# Go through the list and be sure they are all unmounted and won't become 2N/A# mounted. This is needed because the clones that get created will need to use 2N/A# the mount points currently used by the originals. Ignore the first item in 2N/A# the array because that is the ROOT dataset. 2N/Afor (( i = ${#dslist[@]} - 1; i > 1; i-- )); do 2N/A # Before this conversion multiple datasets in the BE were broken. 2N/A # Therefore, we don't deal with them here either. 2N/A # Force a rollback and exit 2N/A "%s: Unsupported non-root dataset %s in boot environment" \ 2N/A set -A undo echo "this command will never run" 2N/A # Create undo using existing mountpoint 2N/A "$(nawk -F '\t' -v "dev=${dslist[i].name}" \ 2N/A # This conversion process assumes no one uses temporary 2N/A # mount points for zones before this conversion is 2N/A# The sources are all unmounted and along the way we verified that it is only 2N/A# root datasets. Create clones. 2N/Afor (( i = 1; i < ${#dslist[@]}; i++ )); do 2N/A # preserve user properties 2N/A # Skip non-user properties and inherited user properties 2N/A # The layout is now correct, except for datasets that need to be 2N/A # deleted. Load the brand-specific common functions. Note that 2N/A # all of the non-solaris10 brands that this script support use 2N/A # Clean up boot environment properties as needed 2N/A # If we started this exercise with a zone that was attached, just run 2N/A # the rough equivalent of the sysboot hook to mount it. If it wasn't 2N/A # attached, then we need to remount the active dataset at the zone 2N/A log "\n%8s: zone %s needs to be updated with attach -u" \ 2N/A log "%8s: \"zoneadm -z %s detach\" to detach, then" \ 2N/A log "%8s: \"zoneadm -z %s attach -u\" to attach.\n" \ 2N/A log "%8s: \"zoneadm -z %s attach\" to attach.\n" \ 2N/A log "\n%8s: zone %s needs to be updated with attach -u" \ 2N/A log "%8s: \"zoneadm -z %s attach -u\" to attach.\n" \ 2N/A # Before the dataset revision, each BE only supported a single 2N/A # (root) dataset. As such, we can use a rather simplistic 2N/A # approach to mounting the active BE. 2N/A log "\n%8s: zone %s converted, but is still detached" \ 2N/A log "%8s: \"zoneadm -z %s attach\" to attach.\n" \ 2N/A log "%8s: \"zoneadm -z %s attach -u\" to attach.\n" \ 2N/A# Clean up old datasets 2N/Afor (( i = ${#dslist[@]} - 1; i >= 0; i-- )); do 2N/A log "%s: Migrating /export from the active boot environent" \ 2N/A# Convert for dataset aliases 2N/A# If there are no delegated datasets, this does nothing. If there are 2N/A# delegated datasets that don't have aliases defined (none should have 2N/A# aliases yet), the default aliases get populated into the zone configuration. 2N/A nawk '$1 == "name:" { printf "select dataset name=%s; end;", $2 }')" 2N/Aif (( $? != 0 )); then 2N/A The automated conversion process is complete. 2N/A Before the zone will boot zone configuration problems need to be 2N/A corrected. Run 'zonecfg -z $zonename' then use the verify subcommand 2N/A within zonecfg to get a list of configuration problems that must be 2N/A corrected within zonecfg. 2N/Alog "%s: Verifying zone with zoneadm\n" "$zonename" 2N/Azoneadm -z "$zonename" verify 2N/Aif (( $? != 0 )); then 2N/A if (( errors == 0 )); then 2N/A print "\nThe automated conversion process is complete." 2N/A As displayed above, system configuration problems exist that must 2N/A be corrected befor the zone will boot. Before booting $zonename you 2N/A will need to manually correct those problems. 2N/A You may run 'zoneadm -z $zonename verify' at any time to re-verify the 2N/A system configuration related to this zone. 2N/A# Check for potential /dev/zvol conflicts. While this may emit warnings, it 2N/A# it should not cause the exit code to change from 0. 2N/Alog "%s: Checking for potential configuration conflicts\n" "$zonename" 2N/Azonecfg -z "$zonename" verify -v 2N/Aif (( $? != 0 )); then 2N/A With Zone Dataset Aliasing, ZFS datasets that are delegated to 2N/A $zonename appear within the zone as virtual ZFS pools. One or more 2N/A of the device resources that appears in the configuration for 2N/A $zonename may hide the existence of similarly named ZFS volumes 2N/A within these virtual pools. See zonecfg(1M) and dev(7FS) for 2N/A You may run 'zonecfg -z $zonename verify -v' at any time to perform 2N/Aif (( errors != 0 )); then 2N/Alog "$m_conversion_complete" "$zonename"