Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

overlay.d: create new 30gcp-udev-rules overlay #2350

Merged
merged 3 commits into from
Apr 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions manifests/fedora-coreos-base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ ostree-layers:
- overlay/09misc
- overlay/20platform-chrony
- overlay/25azure-udev-rules
- overlay/30gcp-udev-rules

# Be minimal
recommends: false
Expand Down
38 changes: 0 additions & 38 deletions overlay.d/05core/usr/lib/udev/rules.d/65-gce-disk-naming.rules

This file was deleted.

2 changes: 2 additions & 0 deletions overlay.d/30gcp-udev-rules/statoverride
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Config file for overriding permission bits on overlay files/dirs
# Format: =<file mode in decimal> <absolute path to a file or directory>
308 changes: 308 additions & 0 deletions overlay.d/30gcp-udev-rules/usr/lib/udev/google_nvme_id
Original file line number Diff line number Diff line change
@@ -0,0 +1,308 @@
#!/bin/bash
# ATTENTION: This is a copy from https://github.com/GoogleCloudPlatform/guest-configs/blob/18fbc050b135461879e631a5ec2dd2cd7259d8e2/src/lib/udev/google_nvme_id

# Copyright 2020 Google Inc. 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.

# 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 NVMe disk. These are populated
# by the identify_pd_disk function and exported for consumption by udev rules.
ID_SERIAL=''
ID_SERIAL_SHORT=''

#######################################
# Helper function to log an error message to stderr.
# Globals:
# None
# Arguments:
# String to print as the log message
# Outputs:
# Writes error to STDERR
#######################################
function err() {
echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2
}

#######################################
# Retrieves the device name for an NVMe namespace using nvme-cli.
# Globals:
# Uses nvme_cli_bin
# Arguments:
# The path to the nvme namespace (/dev/nvme0n?)
# Outputs:
# The device name parsed from the JSON in the vendor ext of the ns-id command.
# Returns:
# 0 if the device name for the namespace could be retrieved, 1 otherwise
#######################################
function get_namespace_device_name() {
local nvme_json
nvme_json="$("$nvme_cli_bin" id-ns -b "$1" | xxd -p -seek 384 | xxd -p -r)"
if [[ $? -ne 0 ]]; then
return 1
fi

if [[ -z "$nvme_json" ]]; then
err "NVMe Vendor Extension disk information not present"
return 1
fi

local device_name
device_name="$(echo "$nvme_json" | grep device_name | sed -e 's/.*"device_name":[ \t]*"\([a-zA-Z0-9_-]\+\)".*/\1/')"

# Error if our device name is empty
if [[ -z "$device_name" ]]; then
err "Empty name"
return 1
fi

echo "$device_name"
return 0
}

#######################################
# Retrieves the nsid for an NVMe namespace
# Globals:
# None
# Arguments:
# The path to the nvme namespace (/dev/nvme0n*)
# Outputs:
# The namespace number/id
# Returns:
# 0 if the namespace id could be retrieved, 1 otherwise
#######################################
function get_namespace_number() {
local dev_path="$1"
local namespace_number
if [[ "$dev_path" =~ $NAMESPACE_NUMBER_REGEX ]]; then
namespace_number="${BASH_REMATCH[1]}"
else
return 1
fi

echo "$namespace_number"
return 0
}

#######################################
# Retrieves the partition number for a device path if it exists
# Globals:
# None
# Arguments:
# The path to the device partition (/dev/nvme0n*p*)
# Outputs:
# The value after 'p' in the device path, or an empty string if the path has
# no partition.
#######################################
function get_partition_number() {
local dev_path="$1"
local partition_number
if [[ "$dev_path" =~ $PARTITION_NUMBER_REGEX ]]; then
partition_number="${BASH_REMATCH[1]}"
echo "$partition_number"
else
echo ''
fi
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.
# Globals:
# Uses ID_SERIAL_SHORT (can be populated by identify_pd_disk)
# Arguments:
# The device path for the disk
#######################################
function gen_symlink() {
local dev_path="$1"
local partition_number="$(get_partition_number "$dev_path")"

if [[ -n "$partition_number" ]]; then
ln -s "$dev_path" /dev/disk/by-id/google-"$ID_SERIAL_SHORT"-part"$partition_number" > /dev/null 2>&1
else
ln -s "$dev_path" /dev/disk/by-id/google-"$ID_SERIAL_SHORT" > /dev/null 2>&1
fi

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_pd_disk() {
local dev_path="$1"
local dev_name
dev_name="$(get_namespace_device_name "$dev_path")"
if [[ $? -ne 0 ]]; then
return 1
fi

ID_SERIAL_SHORT="$dev_name"
ID_SERIAL="Google_PersistentDisk_${ID_SERIAL_SHORT}"
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"
echo " for. This needs to be a path to an nvme device or namespace"
echo " -s: Create symbolic link for the disk under /dev/disk/by-id."
echo " Otherwise, the disk name will be printed to STDOUT"
echo " -h: Print this help message"
}

function main() {
local opt_gen_symlink='false'
local device_path=''

while getopts :d:sh flag; do
case "$flag" in
d) device_path="$OPTARG";;
s) opt_gen_symlink='true';;
h) print_help_message
return 0
;;
:) echo "Invalid option: ${OPTARG} requires an argument" 1>&2
return 1
;;
*) return 1
esac
done

if [[ -z "$device_path" ]]; then
echo "Device path (-d) argument required. Use -h for full usage." 1>&2
exit 1
fi

# Ensure the nvme-cli command is installed
command -v "$nvme_cli_bin" > /dev/null 2>&1
if [[ $? -ne 0 ]]; then
err "The nvme utility (/usr/sbin/nvme) was not found. You may need to run \
with sudo or install nvme-cli."
return 1
fi

# Ensure the passed device is actually an NVMe device
"$nvme_cli_bin" id-ctrl "$device_path" &>/dev/null
if [[ $? -ne 0 ]]; then
err "Passed device was not an NVMe device. (You may need to run this \
script as root/with sudo)."
return 1
fi

# Detect the type of attached nvme device
local controller_id
controller_id=$("$nvme_cli_bin" id-ctrl "$device_path")
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

# Gen symlinks or print out the globals set by the identify command
if [[ "$opt_gen_symlink" == 'true' ]]; then
gen_symlink "$device_path"
else
# These will be consumed by udev
echo "ID_SERIAL_SHORT=${ID_SERIAL_SHORT}"
echo "ID_SERIAL=${ID_SERIAL}"
fi

return $?

}
main "$@"
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# ATTENTION: It is a copy from https://github.com/GoogleCloudPlatform/guest-configs/blob/18fbc050b135461879e631a5ec2dd2cd7259d8e2/src/lib/udev/rules.d/64-gce-disk-removal.rules
# Copyright 2016 Google Inc. 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.
#

# When a disk is removed, unmount any remaining attached volumes.

ACTION=="remove", SUBSYSTEM=="block", KERNEL=="sd*|vd*|nvme*", RUN+="/bin/sh -c '/bin/umount -fl /dev/$name && /usr/bin/logger -p daemon.warn -s WARNING: hot-removed /dev/$name that was still mounted, data may have been corrupted'"
Loading