#!/bin/ksh93 # ALTRAN_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Copyright (C) Altran ACT S.A.S. 2021. All rights reserved. # # ALTRAN_PROLOG_END_TAG # # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Licensed Materials - Property of IBM # # Restricted Materials of IBM # # COPYRIGHT International Business Machines Corp. 2012,2013 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG # @(#) 7b36ae1 43haes/lib/ksh93/hacmp/KLIB_HACMP_add_logical_volume.sh, 726, 2147A_aha726, Sep 08 2021 09:17 PM #================================================ # The following, commented line enforces coding # standards when this file is edited via vim. #================================================ # vim:tabstop=4:shiftwidth=4:expandtab:smarttab #================================================ # Start of POD-formatted documentation. Viewing suggestions: # perldoc # pod2text -c # pod2text -c --code # pod2html function devDoc { : <<'=cut' >/dev/null 2>&1 =head1 NAME KLIB_HACMP_add_logical_volume =head1 VERSION Version Number: 1.5 Last Extracted: 1/31/14 04:42:06 Last Changed: 8/6/13 16:54:53 Path, Component, Release(, Level): src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_logical_volume.sh, hacmp.assist, 61haes_r714 =head1 SYNOPSIS clmgr add logical_volume [ ] \ VOLUME_GROUP= \ LOGICAL_PARTITIONS=## \ [ PHYSICAL_VOLUMES="[,,...]" ] \ [ TYPE={jfs|jfs2|sysdump|paging| jfslog|jfs2log|aio_cache|boot} ] \ [ POSITION={outer_middle|outer_edge|center| inner_middle|inner_edge } ] \ [ PV_RANGE={minimum|maximum} ] \ [ MAX_PVS_FOR_NEW_ALLOC=## ] \ [ LPART_COPIES={1|2|3} ] \ [ WRITE_CONSISTENCY={active|passive|off} ] \ [ LPARTS_ON_SEPARATE_PVS={yes|no|superstrict} ] \ [ RELOCATE={yes|no} ] \ [ LABEL="" ] \ [ MAX_LPARTS=#### ] \ [ BAD_BLOCK_RELOCATION={yes|no} ] \ [ SCHEDULING_POLICY={parallel|sequential| parallel_sequential| parallel_round_robin} ] \ [ VERIFY_WRITES={false|true} ] \ [ ALLOCATION_MAP= ] \ [ STRIPE_SIZE={4K|8K|16K|32K|64K|128K|256K|512K| 1M|2M|4M|8M|16M|32M|64M|128M} ] \ [ SERIALIZE_IO={false|true} ] \ [ FIRST_BLOCK_AVAILABLE={false|true} ] \ [ FIRST_COPY_MIRROR_POOL= ] \ [ SECOND_COPY_MIRROR_POOL= ] \ [ THIRD_COPY_MIRROR_POOL= ] \ [ GROUP= ] \ [ PERMISSIONS=#### ] \ [ NODE= ] \ [ ENABLE_LV_ENCRYPTION={yes|no} ] \ [ AUTH_METHOD={keyserv|pks} ] \ [ METHOD_DETAILS= ] \ [ AUTH_METHOD_NAME= ] NOTE: STRIPE_SIZE may not be used with LPARTS_ON_SEPARATE_PVS, PV_RANGE, or SCHEDULING_POLICY. NOTE: an alias for "logical_volume" is "lv". =head1 DESCRIPTION Attempts to add a new volume group. =head1 ARGUMENTS 1. properties [REQUIRED] [hash ref] An associative array within which data about the created object can be returned to the caller. 2. logical_volume [OPTIONAL] [string] The logical volume label. The default label is None. The maximum size of the Label variable is 127 characters. Note: If the logical volume is going to be used as a journaled file system (jfs), then the JFS will use this field to store the mount point of the file system on the logical volume for future reference. 3. volume_group [REQUIRED] [string] The name of the volume group to add this logical volume to. 4. logical_partitions [REQUIRED] [string] The minimum number of logical partitions to allocate to the logical volume. The minimum value must be equal to or less than the maximum. 5. physical_volumes [REQUIRED] [string] The name(s) of the physical volume(s) to build this logical volume on. Physical volume names are typically in the form "hdiskx" where x is a system wide unique number. This name is assigned when the disk is detected for the first time on a system startup or when the system management commands are used at runtime to add a disk to the system. 6. type [OPTIONAL] [set] Sets the logical volume type. The default type is "jfs" ("journaled file system"). Valid values: jfs, jfs2, sysdump, paging, jfslog, jfs2log, aio_cache, boot 7. position [OPTIONAL] [set] The Intra-Physical Volume Allocation Policy to use for choosing physical partitions on a physical volume. "EDGE" and "INNER EDGE" - allocates partitions to the edges of the physical volume. These partitions have the slowest average seek times, which generally result in longer response times for any application that uses them. "MIDDLE" and "INNER MIDDLE" - allocates partitions away from the edges of the physical volume and out of the center. These strategies allocate reasonably good locations for partitions with reasonably good average seek times. Most of the partitions on a physical volume are available for allocation using these strategies. "CENTER" - allocates partitions to the center section of each physical volume. These partitions have the fastest average seek times, which generally result in the best response time for any application that uses them. There are fewer partitions on a physical volume that satisfy the "CENTER" strategy than for any other general strategy. Valid values: outer_edge, outer_middle, center, inner_middle, inner_edge 8. pv_range [OPTIONAL] [set] Specifies which Inter-Physical Volume Allocation Policy to use for choosing physical devices to allocate the physical partitions of a logical volume: "MINIMUM" - with 1 copy specified, indicates that, if possible, one physical volume should contain all the physical partitions of this logical volume. Otherwise, use the minimum number possible consistent with other parameters. This policy provides the greatest reliability, without mirrored copies, for a logical volume. "MINIMUM" - with 2 or 3 copies specified, indicates that as many physical volumes as there are copies should be used. Otherwise, the minimum number of physical volumes possible are used to hold all the physical partitions. At all times, the constraints imposed by other parameters are observed. "MAXIMUM" - indicates that the physical partitions of this logical volume should be spread over as many physical volumes as possible. This is a performance-oriented option and should be used with copies to improve availability. If a logical volume is not copied and is spread across multiple physical volumes, the loss of any physical volume containing a physical partition from that logical volume is enough to cause the logical volume to be incomplete. Valid values: minimum, maximum 9. max_pvs_for_new_alloc [OPTIONAL] [integer] Sets the maximum number of physical volumes for new allocation. The value should be between one and the total number of physical volumes in the volume group. 10. lpart_copies [OPTIONAL] [integer] The number of physical partitions allocated for each logical partition. The value can be from 1 to 3; the default is 1. A value of 2 or 3 indicates a mirrored logical volume. Valid values: 1, 2, 3 11. write_consistency [OPTIONAL] [set] Specifies whether to ensure data consistency among mirrored copies of a logical volume during normal I/O processing. Valid values: active, passive, off 12. lparts_on_sep_pvs [OPTIONAL] [set] Select "Yes" to follow a strict allocation policy. Copies for a logical partition cannot share the same physical volume. Select "No" to not follow a strict allocation policy. Copies for a logical partition can share the same physical volume. Select "Superstrict" to follow a super strict allocation policy. Partitions allocated for one mirror cannot share a physical volume with the partitions from another mirror. Valid values: no, yes, superstrict 13. relocate [OPTIONAL] [boolean] Specifies whether to allow the relocation of the logical volume during reorganization. Defaults to yes. 14. max_lparts [OPTIONAL] [integer] Sets the maximum number of logical partitions that can be allocated to the logical volume. 15. bad_block_reloc [OPTIONAL] [boolean] Specifies whether to use Bad Block Relocation. Bad-Block Relocation redirects read-write requests from a disk block that can no longer retain data to one that can. The process is transparent; the application does not receive notice that requests directed to a physical block are actually serviced by a different block. Defaults to yes. 16. sched_policy [OPTIONAL] [set] The scheduling policy to use for the mirrored (copies > 1) logical volume: Sequential - performs copied write procedures in order: primary, secondary, tertiary. This policy waits for the write operation to complete for the previous physical partition before starting the write operation to the next one. For read operations, the primary copy is read. If the read operation is unsuccessful, the next copy is read. The primary copy is then fixed by turning the read operation into a write operation with hardware relocation specified on the call to the physical device driver. Parallel - starts the write operation for all the physical partitions in a logical partition at the same time. When the write operation to the physical partition that takes the longest to complete finishes, the write operation returns. Valid values: parallel, sequential, parallel/sequential, parallel/round robin 17. verify_writes [OPTIONAL] [set] Specifies whether to verify all writes to the logical volume with a follow-up read. Defaults to no. 18. allocation_map [OPTIONAL] [abspath] File containing the exact physical partitions to allocate. See the documentation on the mklv command for more information on map files. 19. stripe_size [OPTIONAL] [integer] The size of the stripe for a striped logical volume. This value is also known as stripe unit size. If no size is specified, the logical volume is assumed to be a non-striped logical volume. Valid values: 4 KB, 16 KB, 32 KB, 64 KB, 128 KB, 256K, 512K, 1M, 2M, 4M, 8M, 16M, 32M, 64M, 128M 20. serialize_io [OPTIONAL] [boolean] Turn on or off serialization of overlapping I/Os. If serialization is turned on then overlapping IOs are not allowed on a block range and only a single IO in a block range is processed at any one time. Most applications like file systems and databases do serialization so serialization should be turned off. Defaults to no. 21. first_block_avail [OPTIONAL] [boolean] For big vg format volume groups, this option indicates that the logical volume control block will not occupy the first block of the logical volume. Therefore, the space is available for application data. Defaults to no. 22. mpool_copy1 [OPTIONAL] [string] Assigns the first copy of the logical volume to the specified mirror pool. Logical volume copies that are assigned to a mirror pool will only allocate partitions from the physical volumes in that mirror pool. This provides the ability to restrict the disks that a logical volume copy can use. 23. mpool_copy2 [OPTIONAL] [string] Assigns the second copy of the logical volume to the specified mirror pool. Logical volume copies that are assigned to a mirror pool will only allocate partitions from the physical volumes in that mirror pool. This provides the ability to restrict the disks that a logical volume copy can use. 24. mpool_copy3 [OPTIONAL] [string] Assigns the third copy of the logical volume to the specified mirror pool. Logical volume copies that are assigned to a mirror pool will only allocate partitions from the physical volumes in that mirror pool. This provides the ability to restrict the disks that a logical volume copy can use. 25. group [OPTIONAL] [string] Specifies group ID for the logical volume special file. 26. permissions [OPTIONAL] [set] Sets the access permission to read-write or read-only. Valid values: "w": Sets the access permission to read-write. "r": Sets the access permission to read-only. Note: Mounting a JFS file system on a read-only logical volume is not supported. 27. label [OPTIONAL] [string] Sets the logical volume label. The default label is "None". The maximum size of the label is 127 characters. Note: If the logical volume is going to be used as a journaled file system (JFS), then the JFS will use this field to store the mount point of the file system on that logical volume for future reference. 28. refnode [OPTIONAL] [string] A reference node to use to resolve any specified physical volumes. 29. ENABLE_LV_ENCRYPTION [OPTIONAL] [boolean] Enables the data encryption option for the logical volume. To enable the encryption, auth_method should be passed. 30. AUTH_METHOD [OPTIONAL] Supported authentication methods are pks or keyserv. For pks authentication, AUTH_METHOD_NAME should be passed. For keyserv authentication, METHOD_DETAILS and AUTH_METHOD_NAME should be passed. 31. METHOD_DETAILS [OPTIONAL] If keyserv is configured as an authentication methods, key server ID should be passed to this attribute. 32. AUTH_METHOD_NAME [OPTIONAL] Alias name should be passed for both pks and keyserv authentication methods. =head1 RETURN 0: no errors were detected; the operation appears to have been successful 1: a general error has occurred 2: a specified resource does not exist, or could not be found 3: some required input was missing 4: some detected input was incorrect in some way 5: a required dependency does not exist 6: a specified search failed to match any data =head1 COPYRIGHT COPYRIGHT International Business Machines Corp. 2005,2010 All Rights Reserved =cut } # End of POD-formatted documentation. function KLIB_HACMP_add_logical_volume { LINENO=2 . $HALIBROOT/log_entry "$0()" "$CL" : INPUTS: $* typeset -n properties=$1 typeset logical_volume=${2//\"/} typeset volume_group=${3//\"/} typeset logical_partitions=${4//\"/} typeset physical_volumes=${5//\"/} typeset type=${6//\"/} typeset position=${7//\"/} typeset pv_range=${8//\"/} typeset max_pvs_for_new_alloc=${9//\"/} typeset lpart_copies=${10//\"/} typeset write_consistency=${11//\"/} typeset -l lparts_on_sep_pvs=${12//\"/} typeset relocate=${13//\"/} typeset max_lparts=${14//\"/} typeset bad_block_reloc=${15//\"/} typeset sched_policy=${16//\"/} typeset -l verify_writes=${17//\"/} typeset allocation_map=${18//\"/} typeset stripe_size=${19//\"/} typeset -l serialize_io=${20//\"/} typeset -l first_block_avail=${21//\"/} typeset mpool_copy1=${22//\"/} typeset mpool_copy2=${23//\"/} typeset mpool_copy3=${24//\"/} typeset group=${25//\"/} typeset permissions=${26//\"/} typeset label=${27//\"/} typeset refnode=${28//\"/} typeset -l enable_encryption=${29//\"/} typeset -l auth_method=${30//\"/} typeset method_details=${31//\"/} typeset auth_method_name=${32//\"/} typeset enable_encrypt_support="true" typeset cur_oslevel=$(oslevel -r|sed 's/-//g') typeset -i min_req_ver=730000 [[ $CLMGR_LOGGING == 'med' ]] && set +x # Only trace param values #=================================== : Declare and initialize variables #=================================== typeset -i rc=$RC_UNKNOWN typeset typeOpt="" nodes="" [[ -z $_CSPOC_CALLED_FROM_SMIT ]] && _CSPOC_CALLED_FROM_SMIT=true export _CSPOC_CALLED_FROM_SMIT #================= : Validate input #================= if [[ -n $logical_volume ]]; then CL=$LINENO KLIB_HACMP_is_known_logical_volume $logical_volume if (( $? == RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 229 "\nERROR: the specified object already exists: \"%1\$s\"\n\n" "$logical_volume" 1>&2 rc=$RC_INCORRECT_INPUT fi fi if [[ -n $type ]]; then typeset -l type_lc=$type case $type_lc in a*) typeOpt=" -t aio_cache" ;; b*) typeOpt=" -t boot" ;; jfs) typeOpt=" -t jfs" ;; jfs2) typeOpt=" -t jfs2" ;; jfsl*) typeOpt=" -t jfslog" ;; jfs2l*) typeOpt=" -t jfs2log" ;; p*) typeOpt=" -t paging" ;; s*) typeOpt=" -t sysdump" ;; *) CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\"\n" TYPE "$type" 1>&2 CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "aio_cache, boot, jfs, jfs2, jfslog, jfs2log, paging, sysdump" 1>&2 rc=$RC_INCORRECT_INPUT ;; esac fi if [[ -z $volume_group ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" VOLUME_GROUP 1>&2 rc=$RC_MISSING_INPUT else CL=$LINENO KLIB_HACMP_is_known_volume_group $volume_group >/dev/null if (( $? != RC_SUCCESS )); then (( invalid_nodes++ )) dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$volume_group" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 160 "Available Volume Groups:\n\n" 1>&2 typeset available CL=$LINENO KLIB_HACMP_list_volume_groups available for (( i=0; i<${#available[*]}; i++ )); do if [[ ${available[$i]} != *([[:space:]]) ]]; then print -u2 "\t${available[$i]}" fi done print -u2 "" rc=$RC_NOT_FOUND else : Get the nodes for the volume group $volume_group typeset -A vgProps CL=$LINENO KLIB_HACMP_get_volume_group_attributes $volume_group vgProps nodes=${vgProps[NODES]} fi fi if [[ -n $physical_volumes ]]; then : Only need a reference node if disks are specified explicitly if [[ -z $nodes ]]; then [[ -z $refnode ]] && refnode=$LOCAL_NODE # Best we can do... else if [[ -n $refnode ]]; then : Make sure the specified node is valid if [[ " ${nodes//,/ } " != *\ $refnode\ * ]]; then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 279 '\nERROR: the specified reference node, "%1$s", does not appear to host the given volume group, "%2$s".\n\n' "$refnode" "$volume_group" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 151 "Available Nodes:\n\n" 1>&2 typeset node="" for node in ${nodes//,/ }; do print -u2 "\t$node" done print -u2 "" rc=$RC_INCORRECT_INPUT fi else refnode=$LOCAL_NODE if [[ " ${nodes//,/ } " != *\ $LOCAL_NODE\ * ]]; then refnode=${nodes%%,*} # Hope for the best... fi fi fi fi if [[ -z $logical_partitions ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" LOGICAL_PARTITIONS 1>&2 rc=$RC_MISSING_INPUT fi #============================== : Validate the integer inputs #============================== for INPUT in LOGICAL_PARTITIONS@$logical_partitions \ MAX_PVS_FOR_NEW_ALLOC@$max_pvs_for_new_alloc \ MAX_LPARTS@$max_lparts \ PERMISSIONS@$permissions do print -- "$INPUT" | IFS=@ read ATTR VALUE if [[ -n $VALUE ]]; then if [[ $VALUE != +([[:digit:]]) ]] || \ (( $VALUE == 0 )) then dspmsg -s $CLMGR_SET $CLMGR_MSGS 111 "\nERROR: \"%1\$s\" requires a positive, integer value.\n\n" "$ATTR" 1>&2 rc=$RC_INCORRECT_INPUT fi fi done #============================== : Validate the boolean inputs #============================== for INPUT in RELOCATE@$relocate@yes, no \ BAD_BLOCK_RELOCATION@$bad_block_reloc@yes, no \ SERIALIZE_IO@$serialize_io@no, yes \ FIRST_BLOCK_AVAILABLE@$first_block_avail@no, yes \ ENABLE_LV_ENCRYPTION@$enable_encryption@no,yes do print -- "$INPUT" | IFS=@ read ATTR VALUE ORDER if [[ -n $VALUE && $VALUE != @(y|t|n|f)* ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" "$ATTR" "$VALUE" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "$ORDER" 1>&2 rc=$RC_INCORRECT_INPUT fi done #=============================================================== : check for aix version 7.3 if lvm encryption option is provided #=============================================================== if [[ $enable_encryption == @(y|t)* || -n $auth_method || -n $method_details || -n $auth_method_name ]];then hdcrypt_version=$(LC_ALL=C lslpp -L | grep -w hdcrypt | awk '{print $2}') if [[ -z $hdcrypt_version || $cur_oslevel < $min_req_ver ]] then dspmsg -s $CLMGR_SET $CLMGR_MSGS 1480 "\nERROR: Installed AIX level %1\$s is not supported to use LVM Encryption,\n\ minimum level required to use AIX LVM Encryption is AIX %2\$s.\n\n" "$cur_oslevel" "$min_req_ver" 1>&2 enable_encrypt_support="false" rc=$RC_MISSING_DEPENDENCY fi if [[ $auth_method == "pks" ]];then print -- "$0()[$LINENO]($SECONDS): check for pks support by executing command: hdcryptmgr pksshow" >>$CLMGR_TMPLOG pks_status=$(hdcryptmgr pksshow >>$CLMGR_TMPLOG 2>&1) if (( $? != 0 ));then # Get clutils.log fullpath clutils_log_dir=$(clodmget -q "name = clutils.log" -f value -n HACMPlogs) [[ -z $clutils_log_dir ]] && clutils_log_dir=$(clodmget -q "name = clutils.log" -f defaultdir -n HACMPlogs) clutils_log_dir=${clutils_log_dir:-"/var/hacmp/log"} clutils_log=${clutils_log_dir}/clutils.log dspmsg -s $CLMGR_SET $CLMGR_MSGS 1481 "\nERROR: %1\$s authentication is not supported on node %2\$s, enable %1\$s authentication and rerun the command.\n\ Check log file %3\$s for more details.\n" "pks" "$LOCAL_NODE" "$clutils_log" 1>&2 enable_encrypt_support="false" rc=$RC_MISSING_DEPENDENCY fi fi fi #========================== : Validate the set inputs #========================== typeset ACCEPTED="" ATTR="" VALUE="" typeset -l ACCEPTED_LC="" VALUE_LC="" for INPUT in TYPE@$type@jfs,jfs2,sysdump,paging,jfslog,jfs2log,aio_cache,boot \ POSITION@$position@outer_middle,outer_edge,center,inner_middle,inner_edge \ PV_RANGE@$pv_range@minimum,maximum \ LPART_COPIES@$lpart_copies@1,2,3 \ WRITE_CONSISTENCY@$write_consistency@active,passive,off \ LPARTS_ON_SEPARATE_PVS@$lparts_on_sep_pvs@yes,no,superstrict \ SCHEDULING_POLICY@$sched_policy@parallel,sequential,parallel_sequential,parallel_round_robin \ STRIPE_SIZE@$stripe_size@none,4K,8K,16K,32K,64K,128K,256K,512K,1M,2M,4M,8M,16M,32M,64M,128M do print -- "$INPUT" | IFS=@ read ATTR VALUE ACCEPTED ACCEPTED=${ACCEPTED//$NL/,} ACCEPTED_LC=$ACCEPTED typeset -i INVALID=0 for VALUE in ${VALUE//,/ }; do VALUE_LC=$VALUE if [[ ",$ACCEPTED_LC," != *,$VALUE_LC,* ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" "$ATTR" "$VALUE" 1>&2 INVALID=1 fi done if (( INVALID )); then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "$ACCEPTED" 1>&2 rc=$RC_INCORRECT_INPUT fi done typeset -l auth_method_lc=$auth_method if [[ -n $auth_method && $enable_encrypt_support == "true" && $enable_encryption == @(y|t)* ]];then CL=$LINENO verify_in_set auth_method "$auth_method_lc" "keyserv pks" auth_method_lc (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT fi #============================================================== # Verify all arguments are passed for LV encryption or not. #============================================================== if [[ $rc != $RC_INCORRECT_INPUT && $enable_encryption == @(y|t)* && $enable_encrypt_support == "true" ]] then if [[ -z $auth_method ]];then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1478 "\nERROR: Enabling logical volume encryption requires %1\$s attribute.\n" "AUTH_METHOD" 1>&2 rc=$RC_INCORRECT_INPUT elif [[ $auth_method == "keyserv" ]] && [[ -z $auth_method_name || -z $method_details ]] then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1476 "\nERROR: Enabling logical volume encryption using %1\$s authentication method requires %2\$s and %3\$s attributes.\n" "keyserv" "AUTH_METHOD_NAME" "METHOD_DETAILS" 1>&2 rc=$RC_INCORRECT_INPUT elif [[ $auth_method == "pks" && -z $auth_method_name ]] then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1475 "\nERROR: Enabling logical volume encryption using %1\$s authentication method requires %2\$s attribute.\n" "pks" "AUTH_METHOD_NAME" 1>&2 rc=$RC_INCORRECT_INPUT fi fi if [[ $rc != $RC_INCORRECT_INPUT && $enable_encryption != @(y|t)* && $enable_encrypt_support == "true" ]] then if [[ -n $auth_method || -n $auth_method_name || -n $method_details ]];then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1479 "\nERROR: To use the authentication attributes, %1\$s should be set with yes.\n" "ENABLE_LV_ENCRYPTION" 1>&2 rc=$RC_INCORRECT_INPUT fi fi #============================================ # Validate any mirror pool copy assignments #============================================ if [[ -n $volume_group ]]; then typeset -i NEED_LIST=0 for PAIR in FIRST_COPY_MIRROR_POOL@$mpool_copy1 \ SECOND_COPY_MIRROR_POOL@$mpool_copy2 \ THIRD_COPY_MIRROR_POOL@$mpool_copy3 do print -- "$PAIR" | read ATTR VALUE if [[ -n $VALUE ]]; then typeset FOUND=$(CL=$LINENO KLIB_HACMP_is_known_mirror_pool "$mirror_pool" $volume_group) if (( $? != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 '\nERROR: "%1$s" does not appear to exist!\n\n' "$mirror_pool" 1>&2 rc=$RC_NOT_FOUND NEED_LIST=1 else typeset pool_name pool_vg print -- "$FOUND" | read pool_name pool_vg pool_vg=${pool_vg#\(} pool_vg=${pool_vg%\)} dspmsg -s $CLMGR_SET $CLMGR_MSGS 280 '\nERROR: "%1$s" resides within a different volume group, "%2$s".\n\n' "$mirror_pool" "$pool_vg" 1>&2 rc=$RC_INCORRECT_INPUT fi fi done if (( NEED_LIST )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 173 "Available Mirror Pools:\n\n" 1>&2 typeset available CL=$LINENO KLIB_HACMP_list_mirror_pools available VOLUME_GROUP=$volume_group for (( i=0; i<${#available[*]}; i++ )); do if [[ ${available[$i]} != *([[:space:]]) ]]; then print -u2 "\t${available[$i]}" fi done print -u2 "" rc=$RC_NOT_FOUND fi fi #============================================ # Validate the allocation map, if specified #============================================ if [[ $allocation_map != *([[:space:]]) ]]; then if [[ $allocation_map == *[[:space:]]* ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 108 "\nERROR: the \"%1\$s\" attribute's value contains whitespace,\nwhich is not allowed: \"%2\$s\"\n\n" ALLOCATION_MAP "$allocation_map" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ $allocation_map != /* ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 106 "\nERROR: the specified path does not appear to be in absolute format:\n%1\$s\n\n" "$allocation_map" 1>&2 rc=$RC_INCORRECT_INPUT elif [[ ! -e $allocation_map ]]; then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 107 '\nERROR: the specified path/file does not appear to exist on "%2$s": %1$s\n\n' "$allocation_map" "$LOCAL_NODE" 1>&2 rc=$RC_NOT_FOUND fi fi if [[ $group != *([[:space:]]) ]]; then CL=$LINENO KLIB_HACMP_is_known_group $group if (( $? != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$group" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 161 "Available Groups:\n\n" 1>&2 typeset available CL=$LINENO KLIB_HACMP_list_groups available for (( i=0; i<${#available[*]}; i++ )); do if [[ ${available[$i]} != *([[:space:]]) ]]; then print -u2 "\t${available[$i]}" fi done print -u2 "" rc=$RC_INCORRECT_INPUT fi fi #==================================================================== : If no errors have been detect in the input, perform the operation #==================================================================== if (( $rc == RC_UNKNOWN )); then typeset yOpt="" tOpt="" aOpt="" eOpt="" uOpt="" wOpt="" sOpt="" rOpt="" typeset LOpt="" xOpt="" bOpt="" dOpt="" vOpt="" mOpt="" SOpt="" TOpt="" typeset pOpt="" GOpt="" POpt="" ROpt="" kOpt="" typeOpt="" mdOpt="" anOpt="" [[ $lpart_copies != *([[:space:]]) ]] && cOpt=" -c $lpart_copies" [[ $label != *([[:space:]]) ]] && LOpt=" -L $label" [[ $max_lparts != *([[:space:]]) ]] && xOpt=" -x $max_lparts" [[ $logical_volume != *([[:space:]]) ]] && yOpt=" -y $logical_volume" [[ $type != *([[:space:]]) ]] && tOpt=" -t $type" [[ $allocation_map != *([[:space:]]) ]] && mOpt=" -m $allocation_map" [[ $first_block_avail != *([[:space:]]) ]] && TOpt=" -T O" [[ $group != *([[:space:]]) ]] && GOpt=" -G $group" [[ $enable_encryption == @(y|t)* ]] && kOpt=" -k y" [[ $auth_method != *([[:space:]]) ]] && typeOpt=" -t $auth_method" [[ $method_details != *([[:space:]]) ]] && mdOpt=" -m $method_details" [[ $auth_method_name != *([[:space:]]) ]] && anOpt=" -n $auth_method_name" if [[ $stripe_size != *([[:space:]]) && \ $strip_size == +([0-9])@(K|M) ]] then SOpt=" -S $stripe_size" fi if [[ $max_pvs_for_new_alloc != *([[:space:]]) ]]; then uOpt=" -u $max_pvs_for_new_alloc" fi if [[ $relocate != *([[:space:]]) ]]; then [[ $relocate == @(y|t)* ]] && rOpt=" -r y" || rOpt=" -r n" fi if [[ $bad_block_reloc != *([[:space:]]) ]]; then [[ $bad_block_reloc == @(y|t)* ]] && bOpt=" -b y" || bOpt=" -b n" fi if [[ $verify_writes != *([[:space:]]) ]]; then [[ $verify_writes == @(y|t)* ]] && vOpt=" -v y" || vOpt=" -v n" fi if [[ $position != *([[:space:]]) ]]; then case $position in center) aOpt=" -a c" ;; inner_middle) aOpt=" -a im" ;; inner_edge) aOpt=" -a ie" ;; outer_edge) aOpt=" -a e" ;; outer_middle) aOpt=" -a m" ;; esac fi if [[ $pv_range != *([[:space:]]) ]]; then case $pv_range in min*) eOpt=" -e m" ;; max*) eOpt=" -e x" ;; esac fi if [[ $write_consistency != *([[:space:]]) ]]; then case $write_consistency in o*) wOpt=" -w n" ;; p*) wOpt=" -w p" ;; a*) wOpt=" -w a" ;; esac fi if [[ $lparts_on_sep_pvs != *([[:space:]]) ]]; then case $lparts_on_sep_pvs in y*) sOpt=" -s y" ;; n*) sOpt=" -s n" ;; s*) sOpt=" -s s" ;; esac fi if [[ $sched_policy != *([[:space:]]) ]]; then case $sched_policy in parallel) dOpt=" -d p" ;; sequential) dOpt=" -d s" ;; parallel_sequential) dOpt=" -d ps" ;; parallel_round_robin) dOpt=" -d pr" ;; esac fi if [[ $mpool_copy1 != *([[:space:]]) ]]; then pOpt=" -p copy1=$mpool_copy1" fi if [[ $mpool_copy2 != *([[:space:]]) ]]; then pOpt="$pOpt -p copy2=$mpool_copy2" fi if [[ $mpool_copy3 != *([[:space:]]) ]]; then pOpt="$pOpt -p copy3=$mpool_copy3" fi [[ -n $refnode ]] && ROpt=" -R $refnode" typeset isVG_encrypted="" # : Get volume group properties before creating the logical volume. # typeset -A vgProps CL=$LINENO KLIB_HACMP_get_volume_group_attributes $volume_group vgProps isVG_encrypted=${vgProps[ENCRYPTION]} if [[ -z $logical_volume ]];then lvs=${vgProps[LOGICAL_VOLUMES]} fi print -- "$0()[$LINENO]($SECONDS): _CSPOC_MODE=both $HASBIN/cl_mklv -cspoc \"-n $nodes\"$ROpt$aOpt$bOpt$cOpt$dOpt$eOpt$GOpt$LOpt$mOpt$pOpt$POpt$rOpt$sOpt$SOpt$tOpt$TOpt$uOpt$vOpt$wOpt$xOpt$yOpt $volume_group $logical_partitions ${physical_volumes//,/ }" >>$CLMGR_TMPLOG # Always log commands _CSPOC_MODE=both cl_mklv -cspoc "-n $nodes"$ROpt$aOpt$bOpt$cOpt$dOpt$eOpt$GOpt$LOpt$mOpt$pOpt$POpt$rOpt$sOpt$SOpt$tOpt$TOpt$uOpt$vOpt$wOpt$xOpt$yOpt $volume_group $logical_partitions ${physical_volumes//,/ } rc=$? print "cl_mklv RC: $rc" >>$CLMGR_TMPLOG # Always log command result if (( $rc != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 201 "\nERROR: failed to create \"%1\$s\".\n\n" "$logical_volume" 1>&2 rc=$RC_ERROR #=========================================================== : If output from this operation was requested, retrieve it #=========================================================== else if (( CLMGR_VERBOSE )) || [[ -n $CLMGR_ATTRS || -z $logical_volume ]]; then CL=$LINENO KLIB_HACMP_get_volume_group_attributes "$volume_group" properties if [[ -z $logical_volume ]];then # : Fetch logical volumes list which should have newly created logical volume to find out the name of LV name if name is not passed. # lvs_after=${properties[LOGICAL_VOLUMES]} logical_volume=${lvs_after//$lvs/} logical_volume=${logical_volume//,/} fi fi if [[ $enable_encryption == @(y|t)* && -n $logical_volume ]] then print "$0()[$LINENO]($SECONDS): cl_enable_encryption -a authadd -l $logical_volume -v $volume_group $typeOpt $mdOpt $anOpt $kOpt" >>$CLMGR_TMPLOG # Always log commands cl_enable_encryption -a authadd -l $logical_volume -v $volume_group $typeOpt $mdOpt $anOpt $kOpt rc1=$? print "cl_enable_encryption RC: $rc1" >>$CLMGR_TMPLOG # Always log command result if (( $rc1 != RC_SUCCESS )) && [[ $isVG_encrypted == "yes" ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 1477 "\nWARNING: Failed to add authentication for \"%1\$s\".\nYou can run \"%2\$s %1\$s [..]\" or\n\ \"use Change a Logical Volume from %3\$s menu\" to provide the authentication.\n\ If the problem persists, please contact IBM support.\n" "$logical_volume" "clmgr modify lv" "smitty cl_lv" 1>&2 fi elif [[ $enable_encryption != @(y|t)* && -n $logical_volume ]] && [[ $isVG_encrypted == "yes" ]];then dspmsg -s 32 cspoc.cat 6 "\nWARNING: Encryption for volume group \"%1\$s\" is enabled, but the logical volume \"%2\$s\" is not encrypted.\n\ To enable the encryption for logical volume,\n\ You can run \"%3\$s %2\$s [...] or\n\ use Change a Logical Volume from %4\$s menu\".\n\n" "$volume_group" "$logical_volume" "clmgr modify lv" "smitty cl_lv" 1>&2 fi fi fi #======================================================================= : If a user input error was detected, provide some helpful suggestions #======================================================================= if (( $rc == RC_MISSING_INPUT || $rc == RC_INCORRECT_INPUT )) && \ [[ $CLMGR_GUI == *([[:space:]]) ]] then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 104 "For more information about available options and syntax, try\n\"$HAUTILS/clmgr %1\$s\". As an\nalternative, if the PowerHA SystemMirror man pages have been installed, invoke\n\"$HAUTILS/clmgr -hv\" (or \"/usr/bin/man clmgr\"),\nsearching for \"%2\$s\" in the displayed text.\n\n" \ "add volume_group -h" "VOLUME GROUP:" "$CLMGR_PROGNAME" 1>&2 fi log_return_msg "$rc" "$0()" "$LINENO" return $? } # End of "KLIB_HACMP_add_logical_volume()"