Skip to content

Commit 1054f12

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Add LVM NVMe support"
2 parents a468076 + 97061c9 commit 1054f12

6 files changed

Lines changed: 154 additions & 27 deletions

File tree

doc/source/configuration.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,35 @@ adjusted by setting ``CINDER_QUOTA_VOLUMES``, ``CINDER_QUOTA_BACKUPS``,
672672
or ``CINDER_QUOTA_SNAPSHOTS`` to the desired value. (The default for
673673
each is 10.)
674674

675+
DevStack's Cinder LVM configuration module currently supports both iSCSI and
676+
NVMe connections, and we can choose which one to use with options
677+
``CINDER_TARGET_HELPER``, ``CINDER_TARGET_PROTOCOL``, ``CINDER_TARGET_PREFIX``,
678+
and ``CINDER_TARGET_PORT``.
679+
680+
Defaults use iSCSI with the LIO target manager::
681+
682+
CINDER_TARGET_HELPER="lioadm"
683+
CINDER_TARGET_PROTOCOL="iscsi"
684+
CINDER_TARGET_PREFIX="iqn.2010-10.org.openstack:"
685+
CINDER_TARGET_PORT=3260
686+
687+
Additionally there are 3 supported transport protocols for NVMe,
688+
``nvmet_rdma``, ``nvmet_tcp``, and ``nvmet_fc``, and when the ``nvmet`` target
689+
is selected the protocol, prefix, and port defaults will change to more
690+
sensible defaults for NVMe::
691+
692+
CINDER_TARGET_HELPER="nvmet"
693+
CINDER_TARGET_PROTOCOL="nvmet_rdma"
694+
CINDER_TARGET_PREFIX="nvme-subsystem-1"
695+
CINDER_TARGET_PORT=4420
696+
697+
When selecting the RDMA transport protocol DevStack will create on Cinder nodes
698+
a Software RoCE device on top of the ``HOST_IP_IFACE`` and if it is not defined
699+
then on top of the interface with IP address ``HOST_IP`` or ``HOST_IPV6``.
700+
701+
This Soft-RoCE device will always be created on the Nova compute side since we
702+
cannot tell beforehand whether there will be an RDMA connection or not.
703+
675704

676705
Keystone
677706
~~~~~~~~

lib/cinder

Lines changed: 80 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ GITDIR["python-cinderclient"]=$DEST/python-cinderclient
4343
GITDIR["python-brick-cinderclient-ext"]=$DEST/python-brick-cinderclient-ext
4444
CINDER_DIR=$DEST/cinder
4545

46+
if [[ $SERVICE_IP_VERSION == 6 ]]; then
47+
CINDER_MY_IP="$HOST_IPV6"
48+
else
49+
CINDER_MY_IP="$HOST_IP"
50+
fi
51+
52+
4653
# Cinder virtual environment
4754
if [[ ${USE_VENV} = True ]]; then
4855
PROJECT_VENV["cinder"]=${CINDER_DIR}.venv
@@ -88,13 +95,32 @@ CINDER_ENABLED_BACKENDS=${CINDER_ENABLED_BACKENDS:-lvm:lvmdriver-1}
8895
CINDER_VOLUME_CLEAR=${CINDER_VOLUME_CLEAR:-${CINDER_VOLUME_CLEAR_DEFAULT:-zero}}
8996
CINDER_VOLUME_CLEAR=$(echo ${CINDER_VOLUME_CLEAR} | tr '[:upper:]' '[:lower:]')
9097

91-
# Default to lioadm
92-
CINDER_ISCSI_HELPER=${CINDER_ISCSI_HELPER:-lioadm}
98+
99+
if [[ -n "$CINDER_ISCSI_HELPER" ]]; then
100+
if [[ -z "$CINDER_TARGET_HELPER" ]]; then
101+
deprecated 'Using CINDER_ISCSI_HELPER is deprecated, use CINDER_TARGET_HELPER instead'
102+
CINDER_TARGET_HELPER="$CINDER_ISCSI_HELPER"
103+
else
104+
deprecated 'Deprecated CINDER_ISCSI_HELPER is set, but is being overwritten by CINDER_TARGET_HELPER'
105+
fi
106+
fi
107+
CINDER_TARGET_HELPER=${CINDER_TARGET_HELPER:-lioadm}
108+
109+
if [[ $CINDER_TARGET_HELPER == 'nvmet' ]]; then
110+
CINDER_TARGET_PROTOCOL=${CINDER_TARGET_PROTOCOL:-'nvmet_rdma'}
111+
CINDER_TARGET_PREFIX=${CINDER_TARGET_PREFIX:-'nvme-subsystem-1'}
112+
CINDER_TARGET_PORT=${CINDER_TARGET_PORT:-4420}
113+
else
114+
CINDER_TARGET_PROTOCOL=${CINDER_TARGET_PROTOCOL:-'iscsi'}
115+
CINDER_TARGET_PREFIX=${CINDER_TARGET_PREFIX:-'iqn.2010-10.org.openstack:'}
116+
CINDER_TARGET_PORT=${CINDER_TARGET_PORT:-3260}
117+
fi
118+
93119

94120
# EL and SUSE should only use lioadm
95121
if is_fedora || is_suse; then
96-
if [[ ${CINDER_ISCSI_HELPER} != "lioadm" ]]; then
97-
die "lioadm is the only valid Cinder target_helper config on this platform"
122+
if [[ ${CINDER_TARGET_HELPER} != "lioadm" && ${CINDER_TARGET_HELPER} != 'nvmet' ]]; then
123+
die "lioadm and nvmet are the only valid Cinder target_helper config on this platform"
98124
fi
99125
fi
100126

@@ -187,7 +213,7 @@ function _cinder_cleanup_apache_wsgi {
187213
function cleanup_cinder {
188214
# ensure the volume group is cleared up because fails might
189215
# leave dead volumes in the group
190-
if [ "$CINDER_ISCSI_HELPER" = "tgtadm" ]; then
216+
if [ "$CINDER_TARGET_HELPER" = "tgtadm" ]; then
191217
local targets
192218
targets=$(sudo tgtadm --op show --mode target)
193219
if [ $? -ne 0 ]; then
@@ -215,8 +241,14 @@ function cleanup_cinder {
215241
else
216242
stop_service tgtd
217243
fi
218-
else
244+
elif [ "$CINDER_TARGET_HELPER" = "lioadm" ]; then
219245
sudo cinder-rtstool get-targets | sudo xargs -rn 1 cinder-rtstool delete
246+
elif [ "$CINDER_TARGET_HELPER" = "nvmet" ]; then
247+
# If we don't disconnect everything vgremove will block
248+
sudo nvme disconnect-all
249+
sudo nvmetcli clear
250+
else
251+
die $LINENO "Unknown value \"$CINDER_TARGET_HELPER\" for CINDER_TARGET_HELPER"
220252
fi
221253

222254
if is_service_enabled c-vol && [[ -n "$CINDER_ENABLED_BACKENDS" ]]; then
@@ -267,19 +299,15 @@ function configure_cinder {
267299

268300
iniset $CINDER_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
269301

270-
iniset $CINDER_CONF DEFAULT target_helper "$CINDER_ISCSI_HELPER"
302+
iniset $CINDER_CONF DEFAULT target_helper "$CINDER_TARGET_HELPER"
271303
iniset $CINDER_CONF database connection `database_connection_url cinder`
272304
iniset $CINDER_CONF DEFAULT api_paste_config $CINDER_API_PASTE_INI
273305
iniset $CINDER_CONF DEFAULT rootwrap_config "$CINDER_CONF_DIR/rootwrap.conf"
274306
iniset $CINDER_CONF DEFAULT osapi_volume_extension cinder.api.contrib.standard_extensions
275307
iniset $CINDER_CONF DEFAULT osapi_volume_listen $CINDER_SERVICE_LISTEN_ADDRESS
276308
iniset $CINDER_CONF DEFAULT state_path $CINDER_STATE_PATH
277309
iniset $CINDER_CONF oslo_concurrency lock_path $CINDER_STATE_PATH
278-
if [[ $SERVICE_IP_VERSION == 6 ]]; then
279-
iniset $CINDER_CONF DEFAULT my_ip "$HOST_IPV6"
280-
else
281-
iniset $CINDER_CONF DEFAULT my_ip "$HOST_IP"
282-
fi
310+
iniset $CINDER_CONF DEFAULT my_ip "$CINDER_MY_IP"
283311
iniset $CINDER_CONF key_manager backend cinder.keymgr.conf_key_mgr.ConfKeyManager
284312
iniset $CINDER_CONF key_manager fixed_key $(openssl rand -hex 16)
285313
if [[ -n "$CINDER_ALLOWED_DIRECT_URL_SCHEMES" ]]; then
@@ -473,9 +501,9 @@ function init_cinder {
473501
function install_cinder {
474502
git_clone $CINDER_REPO $CINDER_DIR $CINDER_BRANCH
475503
setup_develop $CINDER_DIR
476-
if [[ "$CINDER_ISCSI_HELPER" == "tgtadm" ]]; then
504+
if [[ "$CINDER_TARGET_HELPER" == "tgtadm" ]]; then
477505
install_package tgt
478-
elif [[ "$CINDER_ISCSI_HELPER" == "lioadm" ]]; then
506+
elif [[ "$CINDER_TARGET_HELPER" == "lioadm" ]]; then
479507
if is_ubuntu; then
480508
# TODO(frickler): Workaround for https://launchpad.net/bugs/1819819
481509
sudo mkdir -p /etc/target
@@ -484,6 +512,43 @@ function install_cinder {
484512
else
485513
install_package targetcli
486514
fi
515+
elif [[ "$CINDER_TARGET_HELPER" == "nvmet" ]]; then
516+
install_package nvme-cli
517+
518+
# TODO: Remove manual installation of the dependency when the
519+
# requirement is added to nvmetcli:
520+
# http://lists.infradead.org/pipermail/linux-nvme/2022-July/033576.html
521+
if is_ubuntu; then
522+
install_package python3-configshell-fb
523+
else
524+
install_package python3-configshell
525+
fi
526+
# Install from source because Ubuntu doesn't have the package and some packaged versions didn't work on Python 3
527+
pip_install git+git://git.infradead.org/users/hch/nvmetcli.git
528+
529+
sudo modprobe nvmet
530+
sudo modprobe nvme-fabrics
531+
532+
if [[ $CINDER_TARGET_PROTOCOL == 'nvmet_rdma' ]]; then
533+
install_package rdma-core
534+
sudo modprobe nvme-rdma
535+
536+
# Create the Soft-RoCE device over the networking interface
537+
local iface=${HOST_IP_IFACE:-`ip -br -$SERVICE_IP_VERSION a | grep $CINDER_MY_IP | awk '{print $1}'`}
538+
if [[ -z "$iface" ]]; then
539+
die $LINENO "Cannot find interface to bind Soft-RoCE"
540+
fi
541+
542+
if ! sudo rdma link | grep $iface ; then
543+
sudo rdma link add rxe_$iface type rxe netdev $iface
544+
fi
545+
546+
elif [[ $CINDER_TARGET_PROTOCOL == 'nvmet_tcp' ]]; then
547+
sudo modprobe nvme-tcp
548+
549+
else # 'nvmet_fc'
550+
sudo modprobe nvme-fc
551+
fi
487552
fi
488553
}
489554

@@ -520,7 +585,7 @@ function start_cinder {
520585
service_port=$CINDER_SERVICE_PORT_INT
521586
service_protocol="http"
522587
fi
523-
if [ "$CINDER_ISCSI_HELPER" = "tgtadm" ]; then
588+
if [ "$CINDER_TARGET_HELPER" = "tgtadm" ]; then
524589
if is_service_enabled c-vol; then
525590
# Delete any old stack.conf
526591
sudo rm -f /etc/tgt/conf.d/stack.conf

lib/cinder_backends/fake_gate

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function configure_cinder_backend_lvm {
5050
iniset $CINDER_CONF $be_name volume_backend_name $be_name
5151
iniset $CINDER_CONF $be_name volume_driver "cinder.tests.fake_driver.FakeGateDriver"
5252
iniset $CINDER_CONF $be_name volume_group $VOLUME_GROUP_NAME-$be_name
53-
iniset $CINDER_CONF $be_name target_helper "$CINDER_ISCSI_HELPER"
53+
iniset $CINDER_CONF $be_name target_helper "$CINDER_TARGET_HELPER"
5454
iniset $CINDER_CONF $be_name lvm_type "$CINDER_LVM_TYPE"
5555

5656
if [[ "$CINDER_VOLUME_CLEAR" == "non" ]]; then

lib/cinder_backends/lvm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ function configure_cinder_backend_lvm {
5050
iniset $CINDER_CONF $be_name volume_backend_name $be_name
5151
iniset $CINDER_CONF $be_name volume_driver "cinder.volume.drivers.lvm.LVMVolumeDriver"
5252
iniset $CINDER_CONF $be_name volume_group $VOLUME_GROUP_NAME-$be_name
53-
iniset $CINDER_CONF $be_name target_helper "$CINDER_ISCSI_HELPER"
53+
iniset $CINDER_CONF $be_name target_helper "$CINDER_TARGET_HELPER"
54+
iniset $CINDER_CONF $be_name target_protocol "$CINDER_TARGET_PROTOCOL"
55+
iniset $CINDER_CONF $be_name target_port "$CINDER_TARGET_PORT"
56+
iniset $CINDER_CONF $be_name target_prefix "$CINDER_TARGET_PREFIX"
5457
iniset $CINDER_CONF $be_name lvm_type "$CINDER_LVM_TYPE"
5558
iniset $CINDER_CONF $be_name volume_clear "$CINDER_VOLUME_CLEAR"
5659
}

lib/lvm

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,18 +130,22 @@ function init_lvm_volume_group {
130130
local size=$2
131131

132132
# Start the tgtd service on Fedora and SUSE if tgtadm is used
133-
if is_fedora || is_suse && [[ "$CINDER_ISCSI_HELPER" = "tgtadm" ]]; then
133+
if is_fedora || is_suse && [[ "$CINDER_TARGET_HELPER" = "tgtadm" ]]; then
134134
start_service tgtd
135135
fi
136136

137137
# Start with a clean volume group
138138
_create_lvm_volume_group $vg $size
139139

140140
# Remove iscsi targets
141-
if [ "$CINDER_ISCSI_HELPER" = "lioadm" ]; then
141+
if [ "$CINDER_TARGET_HELPER" = "lioadm" ]; then
142142
sudo cinder-rtstool get-targets | sudo xargs -rn 1 cinder-rtstool delete
143-
else
143+
elif [ "$CINDER_TARGET_HELPER" = "tgtadm" ]; then
144144
sudo tgtadm --op show --mode target | awk '/Target/ {print $3}' | sudo xargs -r -n1 tgt-admin --delete
145+
elif [ "$CINDER_TARGET_HELPER" = "nvmet" ]; then
146+
# If we don't disconnect everything vgremove will block
147+
sudo nvme disconnect-all
148+
sudo nvmetcli clear
145149
fi
146150
_clean_lvm_volume_group $vg
147151
}

lib/nova

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ NOVA_SERVICE_LISTEN_ADDRESS=${NOVA_SERVICE_LISTEN_ADDRESS:-$(ipv6_unquote $SERVI
9797
METADATA_SERVICE_PORT=${METADATA_SERVICE_PORT:-8775}
9898
NOVA_ENABLE_CACHE=${NOVA_ENABLE_CACHE:-True}
9999

100+
if [[ $SERVICE_IP_VERSION == 6 ]]; then
101+
NOVA_MY_IP="$HOST_IPV6"
102+
else
103+
NOVA_MY_IP="$HOST_IP"
104+
fi
105+
100106
# Option to enable/disable config drive
101107
# NOTE: Set ``FORCE_CONFIG_DRIVE="False"`` to turn OFF config drive
102108
FORCE_CONFIG_DRIVE=${FORCE_CONFIG_DRIVE:-"False"}
@@ -205,6 +211,9 @@ function cleanup_nova {
205211
done
206212
sudo iscsiadm --mode node --op delete || true
207213

214+
# Disconnect all nvmeof connections
215+
sudo nvme disconnect-all || true
216+
208217
# Clean out the instances directory.
209218
sudo rm -rf $NOVA_INSTANCES_PATH/*
210219
fi
@@ -292,6 +301,7 @@ function configure_nova {
292301
fi
293302
fi
294303

304+
# Due to cinder bug #1966513 we ALWAYS need an initiator name for LVM
295305
# Ensure each compute host uses a unique iSCSI initiator
296306
echo InitiatorName=$(iscsi-iname) | sudo tee /etc/iscsi/initiatorname.iscsi
297307

@@ -312,8 +322,28 @@ EOF
312322
# not work under FIPS.
313323
iniset -sudo /etc/iscsi/iscsid.conf DEFAULT "node.session.auth.chap_algs" "SHA3-256,SHA256"
314324

315-
# ensure that iscsid is started, even when disabled by default
316-
restart_service iscsid
325+
if [[ $CINDER_TARGET_HELPER != 'nvmet' ]]; then
326+
# ensure that iscsid is started, even when disabled by default
327+
restart_service iscsid
328+
329+
# For NVMe-oF we need different packages that many not be present
330+
else
331+
install_package nvme-cli
332+
sudo modprobe nvme-fabrics
333+
334+
# Ensure NVMe is ready and create the Soft-RoCE device over the networking interface
335+
if [[ $CINDER_TARGET_PROTOCOL == 'nvmet_rdma' ]]; then
336+
sudo modprobe nvme-rdma
337+
iface=${HOST_IP_IFACE:-`ip -br -$SERVICE_IP_VERSION a | grep $NOVA_MY_IP | awk '{print $1}'`}
338+
if ! sudo rdma link | grep $iface ; then
339+
sudo rdma link add rxe_$iface type rxe netdev $iface
340+
fi
341+
elif [[ $CINDER_TARGET_PROTOCOL == 'nvmet_tcp' ]]; then
342+
sudo modprobe nvme-tcp
343+
else # 'nvmet_fc'
344+
sudo modprobe nvme-fc
345+
fi
346+
fi
317347
fi
318348

319349
# Rebuild the config file from scratch
@@ -404,11 +434,7 @@ function create_nova_conf {
404434
iniset $NOVA_CONF filter_scheduler enabled_filters "$NOVA_FILTERS"
405435
iniset $NOVA_CONF scheduler workers "$API_WORKERS"
406436
iniset $NOVA_CONF neutron default_floating_pool "$PUBLIC_NETWORK_NAME"
407-
if [[ $SERVICE_IP_VERSION == 6 ]]; then
408-
iniset $NOVA_CONF DEFAULT my_ip "$HOST_IPV6"
409-
else
410-
iniset $NOVA_CONF DEFAULT my_ip "$HOST_IP"
411-
fi
437+
iniset $NOVA_CONF DEFAULT my_ip "$NOVA_MY_IP"
412438
iniset $NOVA_CONF DEFAULT instance_name_template "${INSTANCE_NAME_PREFIX}%08x"
413439
iniset $NOVA_CONF DEFAULT osapi_compute_listen "$NOVA_SERVICE_LISTEN_ADDRESS"
414440
iniset $NOVA_CONF DEFAULT metadata_listen "$NOVA_SERVICE_LISTEN_ADDRESS"

0 commit comments

Comments
 (0)