Merge "Move functions into separate method"
This commit is contained in:
commit
dfbfacef7f
@ -196,6 +196,8 @@ Add DPM-Guest Tools
|
||||
|
||||
cp nova-dpm/dpm_guest_tools/usr/lib/systemd/system/autoconfigure_networking.service /usr/lib/systemd/system/autoconfigure_networking.service
|
||||
|
||||
cp nova-dpm/dpm_guest_tools/usr/bin/dpm_guest_image_tools_common /usr/bin/
|
||||
|
||||
cp nova-dpm/dpm_guest_tools/usr/bin/setmac.sh /usr/bin/setmac.sh
|
||||
|
||||
cp nova-dpm/dpm_guest_tools/etc/udev/rules.d/80-setmac.rules /etc/udev/rules.d/80-setmac.rules
|
||||
|
@ -23,10 +23,14 @@
|
||||
|
||||
# Exit on error
|
||||
set -e
|
||||
source $(dirname "$0")/dpm_guest_image_tools_common
|
||||
|
||||
LOG_PREFIX=$(basename "$0")
|
||||
REGEX_DEV_NO="[0-9A-Fa-f]{4}"
|
||||
REGEX_MAC="[0-9A-Fa-f]{12}"
|
||||
# This script usually gets called by systemd. Systemd takes care of writing
|
||||
# stdout and stderr into the journal. Using "echo" here ensures, that
|
||||
# all the messages show up under the corresponding systemd unit and not as
|
||||
# separate entity.
|
||||
LOG_TARGET="stdout"
|
||||
|
||||
# Regex to match
|
||||
# <devno>,<port>;
|
||||
@ -34,46 +38,7 @@ REGEX_MAC="[0-9A-Fa-f]{12}"
|
||||
REGEX="($REGEX_DEV_NO),([0-1])(,$REGEX_MAC)?;"
|
||||
|
||||
#CMDLINE="some stuff 0001,1,000000000011;0004,;0007,0; more stuff"
|
||||
CMDLINE=$(cat /proc/cmdline)
|
||||
|
||||
function log {
|
||||
# $1 = message to log
|
||||
# This script usually gets called by systemd. Systemd takes care of writing
|
||||
# stdout and stderr into the journal. Using "echo" here ensures, that
|
||||
# all the messages show up under the corresponding systemd unit.
|
||||
echo "$LOG_PREFIX: $1"
|
||||
}
|
||||
|
||||
function get_device_bus_id {
|
||||
# $1 = the device number
|
||||
# returns the corresponding device_bus_id
|
||||
|
||||
echo "0.0.$1"
|
||||
}
|
||||
|
||||
function device_exists {
|
||||
# $1 = the device bus id
|
||||
local dev_bus_id="$1"
|
||||
|
||||
# Check if device is already configured
|
||||
path="/sys/bus/ccwgroup/devices/$dev_bus_id"
|
||||
if ! [ -d "$path" ]; then
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function configure_device {
|
||||
# $1 = the device bus id
|
||||
# $2 = the port no
|
||||
local dev_bus_id="$1"
|
||||
local port_no="$2"
|
||||
|
||||
# TODO(andreas_s): Do not depend on znetconf
|
||||
# Errors of the following command are written to stderr, and therefore
|
||||
# show up in the systemd units journal
|
||||
znetconf -a $dev_bus_id -o portno=$port_no,layer2=1
|
||||
return "$?"
|
||||
}
|
||||
CMDLINE=$(get_cmdline)
|
||||
|
||||
log "Start"
|
||||
|
||||
|
205
guest_image_tools/usr/bin/dpm_guest_image_tools_common
Normal file
205
guest_image_tools/usr/bin/dpm_guest_image_tools_common
Normal file
@ -0,0 +1,205 @@
|
||||
#! /bin/bash
|
||||
# Copyright 2017 IBM Corp. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Allow caller to define a different folder for the root directory
|
||||
ROOT_DIR=${ROOT_DIR:-}
|
||||
# Allow caller to define a different LOG prefix
|
||||
LOG_PREFIX=${LOG_PREFIX:-"DPM-guest-image-tools"}
|
||||
# Allow caller to define a different LOG target
|
||||
LOG_TARGET=${LOG_TARGET:-"syslog"}
|
||||
|
||||
# Matches MAC in format: xxxxxxxxxxxx
|
||||
REGEX_MAC="[0-9A-Fa-f]{12}"
|
||||
REGEX_DEV_NO="[0-9A-Fa-f]{4}"
|
||||
REGEX_EXTRACT_DEVNO="qeth/0\.0\.($REGEX_DEV_NO)/net"
|
||||
REGEX_EXTRACT_IFNAME="/net/(.{1,15})"
|
||||
|
||||
function log {
|
||||
# $1 = message to log
|
||||
|
||||
local log_msg="$LOG_PREFIX: $1"
|
||||
|
||||
if [[ $LOG_TARGET == "syslog" ]]; then
|
||||
logger $log_msg
|
||||
elif [[ $LOG_TARGET == "stdout" ]]; then
|
||||
echo $log_msg
|
||||
else
|
||||
# Logging disabled
|
||||
:
|
||||
fi
|
||||
}
|
||||
|
||||
function extract_devno {
|
||||
# Extracts the device number out of a device path
|
||||
# $1 = the device path, e.g. "/devices/qeth/0.0.0001/net/enc1"
|
||||
# Returns: device number, e.g. "0001"
|
||||
|
||||
local dev_path="$1"
|
||||
if [[ $dev_path =~ $REGEX_EXTRACT_DEVNO ]]; then
|
||||
echo "${BASH_REMATCH[1]}"
|
||||
else
|
||||
log "Could not extract devno from '$dev_path'. Skipping!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function extract_interface_name {
|
||||
# Extracts the interface name out of a device path
|
||||
# $1 = the device path, e.g. "/devices/qeth/0.0.0001/net/enc1"
|
||||
# Returns: interface name, e.g. "enc1"
|
||||
|
||||
local dev_path="$1"
|
||||
if [[ $dev_path =~ $REGEX_EXTRACT_IFNAME ]]; then
|
||||
echo "${BASH_REMATCH[1]}"
|
||||
else
|
||||
log "Could not find interface for device number '$devno' in path 'dev_path'. Skipping!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function extract_mac {
|
||||
# Get the mac address to a given device number from the cmdline
|
||||
# $1 = the device number, e.g. "0001"
|
||||
# $2 = the cmdline, e.g. "0001,0,aabbccddeeff;"
|
||||
# Returns: The MAC address in format xx:xx:xx:xx:xx:xx
|
||||
|
||||
local devno="$1"
|
||||
local cmdline="$2"
|
||||
# Regex matches: <devno>,<port>,<mac>;
|
||||
regex=${devno}",[0-1],("${REGEX_MAC}");"
|
||||
if [[ $cmdline =~ $regex ]]; then
|
||||
local mac_tmp="${BASH_REMATCH[1]}"
|
||||
# Insert ':' into MAC again
|
||||
echo ${mac_tmp:0:2}:${mac_tmp:2:2}:${mac_tmp:4:2}:${mac_tmp:6:2}:${mac_tmp:8:2}:${mac_tmp:10:2}
|
||||
else
|
||||
log "No MAC for devno '$devno' found in cmdline '$cmdline'. Exit."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function is_locally_administered_mac {
|
||||
# Verifies if a MAC is a locally administered unicast MAC
|
||||
# $1 = MAC, e.g. "00:11:22:33:44:55"
|
||||
# Returns <nothing>
|
||||
# rc 0 = True, rc 1 = False
|
||||
|
||||
local mac="$1"
|
||||
|
||||
# Only Unicast MACs that have the "locally administered" bit set are allowed
|
||||
# by OSA. The "locally administered" bit is the "second least significant"
|
||||
# bit of the most significant MAC byte. In addition only unicast addresses
|
||||
# are allowed. The unicast bit is the least significant bit of the most
|
||||
# significant byte.
|
||||
# Example: AA:BB:CC:DD:EE:FF
|
||||
# Most significant Byte: ^^
|
||||
# In Binary: 1010 1010
|
||||
# Second least significant bit: ^ = locally administered = 1
|
||||
# Least significant bit: ^ = unicast = 0
|
||||
# Therefore the only MACs are allowed, that have the 10 as those 2 bits.
|
||||
# This results in the following possible MACs (where X can be any hex char):
|
||||
# X2:XX:XX:XX:XX:XX
|
||||
# X6:XX:XX:XX:XX:XX
|
||||
# XA:XX:XX:XX:XX:XX
|
||||
# XE:XX:XX:XX:XX:XX
|
||||
local regex="^[0-9A-Fa-f][26AaEe]"
|
||||
if [[ $mac =~ $regex ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function get_ip_cmd {
|
||||
# Determines the path of the ip cmd
|
||||
# Returns: Path to ip cmd
|
||||
|
||||
# When this script is called from a udev rule, it is not able to find
|
||||
# the ip command. Also the 'which' command is not working. As different
|
||||
# distros install it to different locations, we need to try out which
|
||||
# path is working.
|
||||
local paths=("/usr/sbin/ip" "/sbin/ip")
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
local full_path=$ROOT_DIR$path
|
||||
if [[ -x $full_path ]]; then
|
||||
echo "$full_path"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
log "'ip' command not found. Exiting."
|
||||
exit 1
|
||||
}
|
||||
|
||||
function set_mac {
|
||||
# This function sets the given MAC on the given interface
|
||||
# $1 = Interface name to set the mac on, e.g. "enc1"
|
||||
# $2 = The mac address, e.g. "00:11:22:33:44:55"
|
||||
|
||||
local if_name="$1"
|
||||
local mac="$2"
|
||||
if ! is_locally_administered_mac "$mac" ; then
|
||||
log "MAC $mac is not a locally administered MAC. Aborting!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local ip_cmd=$(get_ip_cmd)
|
||||
local cmd="$ip_cmd link set $if_name address $mac 2>&1 > /dev/null"
|
||||
stderr=$(eval "$cmd")
|
||||
local rc=$?
|
||||
if [[ $rc != 0 ]]; then
|
||||
log "Operation '$cmd' failed with exit rc '$rc': $stderr. Aborting!"
|
||||
exit 1
|
||||
fi
|
||||
log "Successfully set MAC of interface '$if_name' to '$mac'"
|
||||
|
||||
}
|
||||
|
||||
function get_device_bus_id {
|
||||
# $1 = the device number
|
||||
# returns the corresponding device_bus_id
|
||||
|
||||
echo "0.0.$1"
|
||||
}
|
||||
|
||||
function device_exists {
|
||||
# $1 = the device bus id
|
||||
local dev_bus_id="$1"
|
||||
|
||||
# Check if device is already configured
|
||||
path="/sys/bus/ccwgroup/devices/$dev_bus_id"
|
||||
if ! [ -d "$path" ]; then
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function configure_device {
|
||||
# $1 = the device bus id
|
||||
# $2 = the port no
|
||||
local dev_bus_id="$1"
|
||||
local port_no="$2"
|
||||
|
||||
# TODO(andreas_s): Do not depend on znetconf
|
||||
# Errors of the following command are written to stderr, and therefore
|
||||
# show up in the systemd units journal
|
||||
znetconf -a $dev_bus_id -o portno=$port_no,layer2=1
|
||||
return "$?"
|
||||
}
|
||||
|
||||
function get_cmdline {
|
||||
#Example: "some stuff nics=0001,0,aabbccddeeff;abcd,1,001122334455;"
|
||||
echo $(cat /proc/cmdline)
|
||||
}
|
@ -23,152 +23,10 @@
|
||||
|
||||
# Exit on error
|
||||
set -e
|
||||
source $(dirname "$0")/dpm_guest_image_tools_common
|
||||
|
||||
# Matches MAC in format: xxxxxxxxxxxx
|
||||
REGEX_MAC="[0-9A-Fa-f]{12}"
|
||||
REGEX_EXTRACT_DEVNO="qeth/0\.0\.([0-9A-Fa-f]{4})/net"
|
||||
REGEX_EXTRACT_IFNAME="/net/(.{1,15})"
|
||||
LOG_PREFIX=$(basename "$0")
|
||||
|
||||
|
||||
function log {
|
||||
# $1 = message to log
|
||||
|
||||
# Logging to syslog
|
||||
logger "$LOG_PREFIX: $1"
|
||||
}
|
||||
|
||||
function extract_devno {
|
||||
# Extracts the device number out of a device path
|
||||
# $1 = the device path, e.g. "/devices/qeth/0.0.0001/net/enc1"
|
||||
# Returns: device number, e.g. "0001"
|
||||
|
||||
local dev_path="$1"
|
||||
if [[ $dev_path =~ $REGEX_EXTRACT_DEVNO ]]; then
|
||||
echo "${BASH_REMATCH[1]}"
|
||||
else
|
||||
log "Could not extract devno from '$dev_path'. Skipping!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function extract_interface_name {
|
||||
# Extracts the interface name out of a device path
|
||||
# $1 = the device path, e.g. "/devices/qeth/0.0.0001/net/enc1"
|
||||
# Returns: interface name, e.g. "enc1"
|
||||
|
||||
local dev_path="$1"
|
||||
if [[ $dev_path =~ $REGEX_EXTRACT_IFNAME ]]; then
|
||||
echo "${BASH_REMATCH[1]}"
|
||||
else
|
||||
log "Could not find interface for device number '$devno' in path 'dev_path'. Skipping!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function extract_mac {
|
||||
# Get the mac address to a given device number from the cmdline
|
||||
# $1 = the device number, e.g. "0001"
|
||||
# $2 = the cmdline, e.g. "0001,0,aabbccddeeff;"
|
||||
# Returns: The MAC address in format xx:xx:xx:xx:xx:xx
|
||||
|
||||
local devno="$1"
|
||||
local cmdline="$2"
|
||||
# Regex matches: <devno>,<port>,<mac>;
|
||||
regex=${devno}",[0-1],("${REGEX_MAC}");"
|
||||
if [[ $cmdline =~ $regex ]]; then
|
||||
local mac_tmp="${BASH_REMATCH[1]}"
|
||||
# Insert ':' into MAC again
|
||||
echo ${mac_tmp:0:2}:${mac_tmp:2:2}:${mac_tmp:4:2}:${mac_tmp:6:2}:${mac_tmp:8:2}:${mac_tmp:10:2}
|
||||
else
|
||||
log "No MAC for devno '$devno' found in cmdline '$cmdline'. Exit."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function is_locally_administered_mac {
|
||||
# Verifies if a MAC is a locally administered unicast MAC
|
||||
# $1 = MAC, e.g. "00:11:22:33:44:55"
|
||||
# Returns <nothing>
|
||||
# rc 0 = True, rc 1 = False
|
||||
|
||||
local mac="$1"
|
||||
|
||||
# Only Unicast MACs that have the "locally administered" bit set are allowed
|
||||
# by OSA. The "locally administered" bit is the "second least significant"
|
||||
# bit of the most significant MAC byte. In addition only unicast addresses
|
||||
# are allowed. The unicast bit is the least significant bit of the most
|
||||
# significant byte.
|
||||
# Example: AA:BB:CC:DD:EE:FF
|
||||
# Most significant Byte: ^^
|
||||
# In Binary: 1010 1010
|
||||
# Second least significant bit: ^ = locally administered = 1
|
||||
# Least significant bit: ^ = unicast = 0
|
||||
# Therefore the only MACs are allowed, that have the 10 as those 2 bits.
|
||||
# This results in the following possible MACs (where X can be any hex char):
|
||||
# X2:XX:XX:XX:XX:XX
|
||||
# X6:XX:XX:XX:XX:XX
|
||||
# XA:XX:XX:XX:XX:XX
|
||||
# XE:XX:XX:XX:XX:XX
|
||||
local regex="^[0-9A-Fa-f][26AaEe]"
|
||||
if [[ $mac =~ $regex ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function get_ip_cmd {
|
||||
# Determines the path of the ip cmd
|
||||
# Returns: Path to ip cmd
|
||||
|
||||
# When this script is called from a udev rule, it is not able to find
|
||||
# the ip command. Also the 'which' command is not working. As different
|
||||
# distros install it to different locations, we need to try out which
|
||||
# path is working.
|
||||
local paths=("/usr/sbin/ip" "/sbin/ip")
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
if [[ -x $path ]]; then
|
||||
echo "$path"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
log "'ip' command not found. Exiting."
|
||||
exit 1
|
||||
}
|
||||
|
||||
function set_mac {
|
||||
# This function sets the given MAC on the given interface
|
||||
# $1 = Interface name to set the mac on, e.g. "enc1"
|
||||
# $2 = The mac address, e.g. "00:11:22:33:44:55"
|
||||
|
||||
local if_name="$1"
|
||||
local mac="$2"
|
||||
if ! is_locally_administered_mac "$mac" ; then
|
||||
log "MAC $mac is not a locally administered MAC. Aborting!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local ip_cmd=$(get_ip_cmd)
|
||||
local cmd="$ip_cmd link set $if_name address $mac 2>&1 > /dev/null"
|
||||
stderr=$(eval "$cmd")
|
||||
local rc=$?
|
||||
if [[ $rc != 0 ]]; then
|
||||
log "Operation '$cmd' failed with exit rc '$rc': $stderr. Aborting!"
|
||||
exit 1
|
||||
fi
|
||||
log "Successfully set MAC of interface '$if_name' to '$mac'"
|
||||
|
||||
}
|
||||
|
||||
function get_cmdline {
|
||||
#Example: "some stuff nics=0001,0,aabbccddeeff;abcd,1,001122334455;"
|
||||
echo $(cat /proc/cmdline)
|
||||
}
|
||||
|
||||
# e.g. /devices/qeth/0.0.0001/net/enc1
|
||||
DEV_PATH="$1"
|
||||
CMDLINE=$(get_cmdline)
|
||||
|
Loading…
x
Reference in New Issue
Block a user