Skip to content

Commit

Permalink
Support multiple local SSD controllers. (#39)
Browse files Browse the repository at this point in the history
Two changes have been included in this commit:
1. Extended `google_nvme_id` script to handle multi-controllers for local SSD.
2. Added new match rules for local SSD multi-controllers in 65-gce-disk-naming.rules

Co-authored-by: Fan Yang <fanyanf@google.com>
  • Loading branch information
aswfan and Fan Yang authored Feb 17, 2023
1 parent 8b3117f commit 3841945
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 13 deletions.
85 changes: 72 additions & 13 deletions src/lib/udev/google_nvme_id
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# Used to generate symlinks for PD-NVMe devices using the disk names reported by
# the metadata server
# Used to generate symlinks for NVMe devices (both local SSD and
# persistent disk) using the disk names reported by the metadata server.

# Locations of the script's dependencies
readonly nvme_cli_bin=/usr/sbin/nvme

# Bash regex to parse device paths and controller identification
readonly PD_CONTROLLER_REGEX="nvme_card-pd"
readonly SSD_CONTROLLER_REGEX="nvme_card[0-9]*"
readonly CONTROLLER_NUMBER_REGEX="nvme_card([[:digit:]]+)"
readonly NAMESPACE_NUMBER_REGEX="/dev/nvme[[:digit:]]+n([[:digit:]]+).*"
readonly PARTITION_NUMBER_REGEX="/dev/nvme[[:digit:]]+n[[:digit:]]+p([[:digit:]]+)"
readonly PD_NVME_REGEX="sn[[:space:]]+:[[:space]]+nvme_card-pd"

# Globals used to generate the symlinks for a PD-NVMe disk. These are populated
# Globals used to generate the symlinks for a NVMe disk. These are populated
# by the identify_pd_disk function and exported for consumption by udev rules.
ID_SERIAL=''
ID_SERIAL_SHORT=''
Expand Down Expand Up @@ -124,6 +127,28 @@ function get_partition_number() {
return 0
}

#######################################
# Retrieves the controller number from the device model if it exists
# Globals:
# None
# Arguments:
# The NVMe device model (nvme_card or nvme_card1/2/3/...)
# Outputs:
# The controller id/number
#######################################
function get_controller_number() {
local dev_model="$1"
local controller_number
if [[ "$dev_model" =~ $CONTROLLER_NUMBER_REGEX ]]; then
controller_number="${BASH_REMATCH[1]}"
echo "$controller_number"
else
# if it's 'nvme_card', echo 0. This is for backward compatibility.
echo '0'
fi
return 0
}

#######################################
# Generates a symlink for a PD-NVMe device using the metadata's disk name.
# Primarily used for testing but can be used if the script is directly invoked.
Expand Down Expand Up @@ -152,7 +177,7 @@ function gen_symlink() {
# Arguments:
# The device path for the disk
# Returns:
# 0 on success and 1 if an error occurrs
# 0 on success and 1 if an error occurs
#######################################
function identify_pd_disk() {
local dev_path="$1"
Expand All @@ -167,6 +192,35 @@ function identify_pd_disk() {
return 0
}

#######################################
# Populates the ID_* global variables with a disk's device name and namespace
# Globals:
# Populates ID_SERIAL_SHORT, and ID_SERIAL
# Arguments:
# The device path for the disk
# Returns:
# 0 on success and 1 if an error occurs
#######################################
function identify_local_ssd_disk() {
local dev_model="$1"
local dev_path="$2"
local controller_number
controller_number="$(get_controller_number "$dev_model")"
if [[ $? -ne 0 ]]; then
return 1
fi

local namespace_number
namespace_number="$(get_namespace_number "$dev_path")"
if [[ $? -ne 0 ]]; then
return 1
fi

ID_SERIAL_SHORT="local-nvme-ssd-$(($controller_number+$namespace_number-1))"
ID_SERIAL="Google_EphemeralDisk_${ID_SERIAL_SHORT}"
return 0
}

function print_help_message() {
echo "Usage: google_nvme_id [-s] [-h] -d device_path"
echo " -d <device_path> (Required): Specifies the path to generate a name"
Expand Down Expand Up @@ -218,18 +272,23 @@ script as root/with sudo)."
# Detect the type of attached nvme device
local controller_id
controller_id=$("$nvme_cli_bin" id-ctrl "$device_path")
if [[ ! "$controller_id" =~ nvme_card-pd ]] ; then
err "Device is not a PD-NVMe device"
if [[ "$controller_id" =~ $PD_CONTROLLER_REGEX ]] ; then
# Fill the global variables for the id command for the given disk type
# Error messages will be printed closer to error, no need to reprint here
identify_pd_disk "$device_path"
if [[ $? -ne 0 ]]; then
return $?
fi
elif [[ "$controller_id" =~ $SSD_CONTROLLER_REGEX ]] ; then
identify_local_ssd_disk "$controller_id" "$device_path"
if [[ $? -ne 0 ]]; then
return $?
fi
else
err "Device is not a NVMe device"
return 1
fi

# Fill the global variables for the id command for the given disk type
# Error messages will be printed closer to error, no need to reprint here
identify_pd_disk "$device_path"
if [[ $? -ne 0 ]]; then
return $?
fi

# Gen symlinks or print out the globals set by the identify command
if [[ "$opt_gen_symlink" == 'true' ]]; then
gen_symlink "$device_path"
Expand Down
2 changes: 2 additions & 0 deletions src/lib/udev/rules.d/65-gce-disk-naming.rules
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ KERNEL=="sd*|vd*", IMPORT{program}="scsi_id --export --whitelisted -d $tempnode"
# NVME Local SSD naming
KERNEL=="nvme*n*", ATTRS{model}=="nvme_card", PROGRAM="/bin/sh -c 'nsid=$$(echo %k|sed -re s/nvme[0-9]+n\([0-9]+\).\*/\\1/); echo $$((nsid-1))'", ENV{ID_SERIAL_SHORT}="local-nvme-ssd-%c"
KERNEL=="nvme*", ATTRS{model}=="nvme_card", ENV{ID_SERIAL}="Google_EphemeralDisk_$env{ID_SERIAL_SHORT}"
# Support for local SSD multi-controller
KERNEL=="nvme*n*", ATTRS{model}=="nvme_card[0-9]*", IMPORT{program}="google_nvme_id -d $tempnode"

# NVME Persistent Disk IO Timeout
KERNEL=="nvme*n*", ENV{DEVTYPE}=="disk", ATTRS{model}=="nvme_card-pd", ATTR{queue/io_timeout}="4294967295"
Expand Down

0 comments on commit 3841945

Please sign in to comment.