1
0
Fork 0

Adding upstream version 2.2.1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Benjamin Drung 2025-02-16 12:41:59 +01:00 committed by Daniel Baumann
parent 1d36de0179
commit 757b718eff
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
129 changed files with 16110 additions and 0 deletions

1
doc/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*.xml~

118
doc/dbus-idl-to-docbooks.py Executable file
View file

@ -0,0 +1,118 @@
#!/usr/bin/python3
import os
import sys
import pathlib
import tempfile
import subprocess
from argparse import ArgumentParser
from lxml import etree
def parse_args():
parser = ArgumentParser(description='Generate DocBook documentation from D-Bus IDL.')
parser.add_argument(
'--idl',
action='store',
help='IDL file',
required=True,
type=str,
metavar='FILE',
)
parser.add_argument(
'--output-directory',
action='store',
help='Output directory where DocBook files will be saved',
required=True,
type=str,
metavar='DIR',
)
parser.add_argument(
'--tmp',
action='store',
help='Temporary directory for intermediate files',
required=True,
type=str,
metavar='DIR',
)
return parser.parse_args()
ARGS = parse_args()
pathlib.Path(ARGS.output_directory).mkdir(parents=True, exist_ok=True)
REF_ENTRY_INFO = '''\
<refentryinfo>
<title>stafctl</title>
<productname>nvme-stas</productname>
<author>
<personname>
<honorific>Mr</honorific>
<firstname>Martin</firstname>
<surname>Belanger</surname>
</personname>
<affiliation>
<orgname>Dell, Inc.</orgname>
</affiliation>
</author>
</refentryinfo>
'''
MANVOLNUM = '<manvolnum>5</manvolnum>'
PURPOSE = '<refpurpose>DBus interface</refpurpose>'
PARSER = etree.XMLParser(remove_blank_text=True)
def add_missing_info(fname, stem):
xml = etree.parse(fname, PARSER)
root = xml.getroot()
if root.tag != 'refentry':
return
if xml.find('refentryinfo'):
return
root.insert(0, etree.fromstring(REF_ENTRY_INFO))
refmeta = xml.find('refmeta')
if refmeta is not None:
if refmeta.find('refentrytitle') is None:
refmeta.append(etree.fromstring(f'<refentrytitle>{stem}</refentrytitle>'))
refmeta.append(etree.fromstring(MANVOLNUM))
refnamediv = xml.find('refnamediv')
if refnamediv is not None:
refpurpose = refnamediv.find('refpurpose')
if refpurpose is not None:
refnamediv.remove(refpurpose)
refnamediv.append(etree.fromstring(PURPOSE))
et = etree.ElementTree(root)
et.write(fname, pretty_print=True)
FILE_PREFIX = 'nvme-stas'
FINAL_PREFIX = FILE_PREFIX + '-'
pathlib.Path(ARGS.tmp).mkdir(parents=True, exist_ok=True)
with tempfile.TemporaryDirectory(dir=ARGS.tmp) as tmpdirname:
try:
subprocess.run(['gdbus-codegen', '--output-directory', tmpdirname, '--generate-docbook', FILE_PREFIX, ARGS.idl])
except subprocess.CalledProcessError as ex:
sys.exit(f'Failed to generate DocBook file. {ex}')
stems = []
with os.scandir(tmpdirname) as it:
for entry in it:
if entry.is_file() and entry.name.endswith('.xml') and entry.name.startswith(FINAL_PREFIX):
fname = entry.name[len(FINAL_PREFIX) :] # Strip prefix
stem = fname[0:-4] # Strip '.xml' suffix
stems.append(stem)
tmp_file = os.path.join(tmpdirname, entry.name)
add_missing_info(tmp_file, stem)
os.replace(tmp_file, os.path.join(ARGS.output_directory, fname))
print(';'.join(stems))

36
doc/genlist-from-docbooks.py Executable file
View file

@ -0,0 +1,36 @@
#!/usr/bin/python3
import glob
from lxml import etree
exclude_list = list(glob.glob('standard-*.xml'))
PARSER = etree.XMLParser(remove_blank_text=True)
def extract_data(fname):
et = etree.parse(fname, PARSER)
manvolnum = et.find('./refmeta/manvolnum')
manvolnum = manvolnum.text if manvolnum is not None else 0
deps = set()
for elem in et.iter():
keys = elem.keys()
if 'href' in keys and 'xpointer' in keys:
dep = elem.values()[0]
if dep in exclude_list:
deps.add(dep)
return manvolnum, list(deps)
output = list()
file_list = glob.glob('*.xml')
for fname in file_list:
if fname not in exclude_list:
stem = fname[0:-4]
manvolnum, deps = extract_data(fname)
deps = ':'.join(deps) if deps else 'None'
output.append(','.join([stem, manvolnum, fname, deps]))
print(';'.join(output))

63
doc/html.xsl Normal file
View file

@ -0,0 +1,63 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
<xsl:template match="citerefentry[not(@project)]">
<a>
<xsl:attribute name="href">
<xsl:value-of select="refentrytitle"/>
<xsl:text>.html#</xsl:text>
<xsl:value-of select="refentrytitle/@target"/>
</xsl:attribute>
<xsl:call-template name="inline.charseq"/>
</a>
</xsl:template>
<xsl:template name="user.header.content">
<style>
a.headerlink {
color: #c60f0f;
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
visibility: hidden;
}
a.headerlink:hover {
background-color: #c60f0f;
color: white;
}
h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, dt:hover > a.headerlink {
visibility: visible;
}
</style>
<a>
<xsl:text xml:space="preserve" white-space="pre"> &#160; </xsl:text>
</a>
<span style="float:right">
<xsl:text>nvme-stas </xsl:text>
<xsl:value-of select="$nvme-stas.version"/>
</span>
<hr/>
</xsl:template>
<xsl:template match="literal">
<xsl:text>"</xsl:text>
<xsl:call-template name="inline.monoseq"/>
<xsl:text>"</xsl:text>
</xsl:template>
<xsl:output method="html" encoding="UTF-8" indent="no"/>
</xsl:stylesheet>

BIN
doc/images/Coverage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

41
doc/man.xsl Normal file
View file

@ -0,0 +1,41 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl"
version="1.0">
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl"/>
<xsl:template name="TH.title.line">
<xsl:param name="title"/>
<xsl:param name="section"/>
<xsl:call-template name="mark.subheading"/>
<xsl:text>.TH "</xsl:text>
<xsl:call-template name="string.upper">
<xsl:with-param name="string">
<xsl:value-of select="normalize-space($title)"/>
</xsl:with-param>
</xsl:call-template>
<xsl:text>" "</xsl:text>
<xsl:value-of select="normalize-space($section)"/>
<xsl:text>" "" "nvme-stas </xsl:text>
<xsl:value-of select="$nvme-stas.version"/>
<xsl:text>" "</xsl:text>
<xsl:text>"&#10;</xsl:text>
<xsl:call-template name="mark.subheading"/>
</xsl:template>
</xsl:stylesheet>

126
doc/meson.build Normal file
View file

@ -0,0 +1,126 @@
# Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# See the LICENSE file for details.
#
# This file is part of NVMe STorage Appliance Services (nvme-stas).
#
# Authors: Martin Belanger <Martin.Belanger@dell.com>
#
if want_man or want_html or want_readthedocs
docbklst = find_program('genlist-from-docbooks.py')
dbus2doc = find_program('dbus-idl-to-docbooks.py')
dbusgen = find_program('gdbus-codegen', required: false) # Needed by dbus2doc
if not dbusgen.found()
error('gdbus-codegen missing: Install libglib2.0-dev (deb) / glib2-devel (rpm)')
endif
# Get the list of DocBook files to process. The result will
# be saved to variable docbooks as a list of tuples as follows:
# docbooks = [ ['file1', 'manvolnum-from-file1.xml', 'file1.xml'],
# ['file2', 'manvolnum-from-file2.xml', 'file2.xml'], ... ]
docbooks = []
rr = run_command(docbklst, check: true)
output = rr.stdout().strip()
if output != ''
foreach item : output.split(';')
items = item.split(',')
stem = items[0]
manvolnum = items[1]
fname = items[2]
deps = items[3]
if deps == 'None'
deps = []
else
deps = deps.split(':')
endif
docbooks += [ [stem, manvolnum, fname, deps] ]
endforeach
endif
# Generate DocBooks from IDL queried directly from the D-Bus services.
out_dir = conf.get('BUILD_DIR') / 'man-tmp'
env = environment({'PYTHONPATH': PYTHONPATH})
idls = [ 'stafd.idl', 'stacd.idl' ]
foreach idl : idls
rr = run_command(
dbus2doc,
'--idl', conf.get('BUILD_DIR') / 'staslib' / idl,
'--output-directory', out_dir,
'--tmp', meson.current_build_dir(),
env: env,
check: true)
output = rr.stdout().strip()
if output != ''
foreach stem : output.split(';')
docbooks += [ [stem, '5', out_dir / stem + '.xml', []] ]
endforeach
endif
endforeach
xsltproc = find_program('xsltproc')
if xsltproc.found()
manpage_style = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl'
if run_command(xsltproc, '--nonet', manpage_style, check: false).returncode() != 0
error('Docbook style sheet missing: Install docbook-xsl (deb) / docbook-style-xsl (rpm)')
endif
endif
xslt_cmd = [
xsltproc,
'--nonet',
'--xinclude',
'--stringparam', 'man.output.quietly', '1',
'--stringparam', 'funcsynopsis.style', 'ansi',
'--stringparam', 'man.th.extra1.suppress', '1',
'--stringparam', 'man.authors.section.enabled', '0',
'--stringparam', 'man.copyright.section.enabled', '0',
'--stringparam', 'nvme-stas.version', '@0@'.format(meson.project_version()),
'-o', '@OUTPUT@',
]
man_xsl = files('man.xsl')
html_xsl = files('html.xsl')
html_files = [] # Will be used as input to readthedocs
foreach tuple: docbooks
stem = tuple[0]
sect = tuple[1]
file = files(tuple[2])
deps = tuple[3]
if want_man
man = stem + '.' + sect
custom_target(
man,
input: file,
output: man,
depend_files: deps,
command: xslt_cmd + [man_xsl, '@INPUT@'],
install: true,
install_dir: mandir / ('man' + sect)
)
endif
if want_html or want_readthedocs
html = stem + '.html'
html_file = custom_target(
html,
input: file,
output: html,
depend_files: deps,
command: xslt_cmd + [html_xsl, '@INPUT@'],
install: want_html,
install_dir: docdir / 'html'
)
html_files += [ [stem, html_file ] ]
endif
endforeach
endif
if want_readthedocs
subdir('readthedocs')
endif

185
doc/nvme-stas.xml Normal file
View file

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<refentry id="nvme-stas">
<refentryinfo>
<title>nvme-stas</title>
<productname>nvme-stas</productname>
<author>
<personname>
<honorific>Mr</honorific>
<firstname>Martin</firstname>
<surname>Belanger</surname>
</personname>
<affiliation>
<orgname>Dell, Inc.</orgname>
</affiliation>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>nvme-stas</refentrytitle>
<manvolnum>7</manvolnum>
</refmeta>
<refnamediv>
<refname>nvme-stas</refname>
<refpurpose>NVMe over Fabrics STorage Appliance Services</refpurpose>
</refnamediv>
<refsect1>
<title>Introduction</title>
<para>
This page describes the services provided by the <code>nvme-stas</code> package.
</para>
<para>
<code>nvme-stas</code> is composed of two services, <citerefentry><refentrytitle>stafd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
and <citerefentry><refentrytitle>stacd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
running on a host computer (the NVMe Host).
</para>
<refsect2>
<title>STorage Appliance Finder (<code>stafd</code>)</title>
<para>
The tasks performed by <code>stafd</code> include:
</para>
<itemizedlist mark='opencircle'>
<listitem>
<para>
Register for mDNS service type <parameter>_nvme-disc._tcp</parameter>
with Avahi, the service discovery daemon. This allows <code>stafd</code>
to automatically locate Central or Direct Discovery
Controllers (CDC, DDC) with zero-configuration networking
(zeroconf). <code>stafd</code> also allows users to manually enter CDCs
and DDCs in a configuration file
(<filename>/etc/stas/stafd.conf</filename>) when users
prefer not to enable mDNS-based zeroconf.
</para>
</listitem>
<listitem>
<para>
Connect to discovered or configured CDCs or DDCs.
</para>
</listitem>
<listitem>
<para>
Retrieve the list of NVMe subsystem IO Controllers or
Discovery Controller referrals from the Discovery Log Page
using the NVMe command "Get Log Page".
</para>
</listitem>
<listitem>
<para>
Maintain a cache of the discovery log pages.
</para>
</listitem>
<listitem>
<para>
Provide a D-Bus API where other applications can interact
with <code>stafd</code>. This API can be used, for example, to retrieve
the list of cached discovery log pages.
</para>
</listitem>
</itemizedlist>
</refsect2>
<refsect2>
<title>STorage Appliance Connector (<code>stacd</code>)</title>
<para>
The tasks performed by <code>stacd</code> include:
</para>
<itemizedlist mark='opencircle'>
<listitem>
<para>
Read the list of storage subsystems (i.e., discovery log pages)
from <code>stafd</code> over the D-Bus API.
</para>
</listitem>
<listitem>
<para>
Similar to <code>stafd</code>, <code>stacd</code> can also read a list of storage
subsystems to connect to from a configuration
file: (<filename>/etc/stas/stacd.conf</filename>).
</para>
</listitem>
<listitem>
<para>
Set up the I/O controller connections to each storage subsystem.
</para>
</listitem>
<listitem>
<para>
Provide a D-Bus API where other applications can interact
with <code>stacd</code>. For example, an application could retrieve the
list of I/O controllers that <code>stacd</code> connected to.
</para>
</listitem>
</itemizedlist>
</refsect2>
<refsect2>
<title>System configuration</title>
<para>
A host must be provided with a Host NQN and a Host ID. <code>nvme-stas</code>
will not run without these two mandatory configuration parameters.
To follow in the footsteps of <code>nvme-cli</code> and <code>libnvme</code>,
<code>nvme-stas</code> will use the same Host NQN and ID that
<code>nvme-cli</code> and <code>libnvme</code> use by default.
In other words, <code>nvme-stas</code> will read the Host NQN and ID
from these two files by default:
</para>
<itemizedlist mark='opencircle'>
<listitem>
<para>
<filename>/etc/nvme/hostnqn</filename>
</para>
</listitem>
<listitem>
<para>
<filename>/etc/nvme/hostid</filename>
</para>
</listitem>
</itemizedlist>
<para>
Using the same configuration files will ensure consistency between
<code>nvme-stas</code>, <code>nvme-cli</code>, and <code>libnvme</code>.
On the other hand, <code>nvme-stas</code> can operate with a
different Host NQN and/or ID. In that case, one can specify them
in <filename>/etc/stas/sys.conf</filename>.
</para>
A new optional configuration parameters introduced in TP8010, the
Host Symbolic Name, can also be specified in <filename>/etc/stas/sys.conf</filename>.
The documentation for <filename>/etc/stas/sys.conf</filename>
can be found <filename>/etc/stas/sys.conf.doc</filename>.
<para>
</para>
</refsect2>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>stacctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>stacd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>stacd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>stacd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>stafctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>stafd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>stafd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>stafd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
</para>
</refsect1>
</refentry>

22
doc/readthedocs/Makefile Normal file
View file

@ -0,0 +1,22 @@
# Minimal makefile for Sphinx documentation
#
.DEFAULT_GOAL := help
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
.PHONY: help
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
.PHONY: Makefile
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

34
doc/readthedocs/conf.py Normal file
View file

@ -0,0 +1,34 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Project information -----------------------------------------------------
project = 'nvme-stas'
copyright = 'Copyright (c) 2022, Dell Inc. or its subsidiaries. All rights reserved.'
author = 'Martin Belanger <martin.belanger@dell.com>'
master_doc = 'index'
version = '@VERSION@'
release = '@VERSION@'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autosummary',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['Thumbs.db', '.DS_Store']

View file

@ -0,0 +1 @@
sphinx==5.3.0

30
doc/readthedocs/index.rst Normal file
View file

@ -0,0 +1,30 @@
Welcome to nvme-stas's documentation!
=====================================
What does nvme-stas provide?
* A Central Discovery Controller (CDC) client for Linux
* Asynchronous Event Notifications (AEN) handling
* Automated NVMe subsystem connection controls
* Error handling and reporting
* Automatic (zeroconf) and Manual configuration
.. toctree::
:maxdepth: 2
:caption: Contents:
installation.rst
nvme-stas.rst
stafd-index.rst
stacd-index.rst
stasadm.rst
sys.conf.rst
stas-config.target.rst
stas-config@.service.rst
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View file

@ -0,0 +1,28 @@
Installation
============
Debian / Ubuntu:
----------------
.. code-block:: sh
$ apt-get install nvme-stas
Fedora / Red Hat:
-----------------
.. code-block:: sh
$ dnf install nvme-stas
Python Version
--------------
The latest Python 3 version is always recommended, since it has all the latest bells and
whistles. libnvme supports Python 3.6 and above.
Dependencies
------------
nvme-stas is built on top of libnvme, which is used to interact with the kernel's NVMe driver (i.e. drivers/nvme/host/). To support all the features of nvme-stas, several changes to the Linux kernel are required. nvme-stas can also operate with older kernels, but with limited functionality. Kernel 5.18 provides all the features needed by nvme-stas. nvme-stas can also work with older kernels that include back-ported changes to the NVMe driver.

35
doc/readthedocs/make.bat Normal file
View file

@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

View file

@ -0,0 +1,64 @@
# Copyright (c) 2022, Dell Inc. or its subsidiaries. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# See the LICENSE file for details.
#
# This file is part of NVMe STorage Appliance Services (nvme-stas).
#
# Authors: Martin Belanger <Martin.Belanger@dell.com>
#
pandoc = find_program('pandoc', required: true)
components = [
'conf.py',
'Makefile',
'make.bat',
'index.rst',
'environment.txt',
'installation.rst',
'nvme-stas.rst',
'org.nvmexpress.stac.debug.rst',
'org.nvmexpress.stac.rst',
'org.nvmexpress.staf.debug.rst',
'org.nvmexpress.staf.rst',
'stacctl.rst',
'stacd-index.rst',
'stacd.conf.rst',
'stacd.rst',
'stacd.service.rst',
'stafctl.rst',
'stafd-index.rst',
'stafd.conf.rst',
'stafd.rst',
'stafd.service.rst',
'stas-config.target.rst',
'stas-config@.service.rst',
'stasadm.rst',
'sys.conf.rst',
]
foreach component : components
configure_file(
input: component,
output: component,
configuration: conf,
)
endforeach
foreach tuple: html_files
stem = tuple[0]
html_file = tuple[1]
rst = '_' + stem + '.rst'
custom_target(
rst,
input: html_file,
output: rst,
build_by_default: true,
command: [
pandoc,
'-f', 'html',
'-t', 'rst',
'-o', '@OUTPUT@',
'@INPUT@'
]
)
endforeach

View file

@ -0,0 +1,5 @@
==========================
STorage Appliance Services
==========================
.. include:: _nvme-stas.rst

View file

@ -0,0 +1,7 @@
=========================
org.nvmexpress.stac.debug
=========================
.. module:: org.nvmexpress.stac.debug
.. include:: _org.nvmexpress.stac.debug.rst

View file

@ -0,0 +1,7 @@
===================
org.nvmexpress.stac
===================
.. module:: org.nvmexpress.stac
.. include:: _org.nvmexpress.stac.rst

View file

@ -0,0 +1,7 @@
=========================
org.nvmexpress.staf.debug
=========================
.. module:: org.nvmexpress.staf.debug
.. include:: _org.nvmexpress.staf.debug.rst

View file

@ -0,0 +1,7 @@
===================
org.nvmexpress.staf
===================
.. module:: org.nvmexpress.staf
.. include:: _org.nvmexpress.staf.rst

View file

@ -0,0 +1,7 @@
=======
stacctl
=======
.. module:: stacctl
.. include:: _stacctl.rst

View file

@ -0,0 +1,13 @@
STorage Appliance Connector
===========================
.. toctree::
:maxdepth: 1
stacd.rst
stacd.conf.rst
stacd.service.rst
stacctl.rst
org.nvmexpress.stac.rst
org.nvmexpress.stac.debug.rst

View file

@ -0,0 +1,7 @@
==========
stacd.conf
==========
.. module:: stacd.conf
.. include:: _stacd.conf.rst

View file

@ -0,0 +1,8 @@
=====
stacd
=====
.. module:: stacd
.. include:: _stacd.rst

View file

@ -0,0 +1,7 @@
=============
stacd.service
=============
.. module:: stacd.service
.. include:: _stacd.service.rst

View file

@ -0,0 +1,7 @@
=======
stafctl
=======
.. module:: stafctl
.. include:: _stafctl.rst

View file

@ -0,0 +1,13 @@
STorage Appliance Finder
========================
.. toctree::
:maxdepth: 1
stafd.rst
stafd.conf.rst
stafd.service.rst
stafctl.rst
org.nvmexpress.staf.rst
org.nvmexpress.staf.debug.rst

View file

@ -0,0 +1,7 @@
==========
stafd.conf
==========
.. module:: stafd.conf
.. include:: _stafd.conf.rst

View file

@ -0,0 +1,7 @@
=====
stafd
=====
.. module:: stafd
.. include:: _stafd.rst

View file

@ -0,0 +1,7 @@
=============
stafd.service
=============
.. module:: stafd.service
.. include:: _stafd.service.rst

View file

@ -0,0 +1,7 @@
==================
stas-config.target
==================
.. module:: stas-config.target
.. include:: _stas-config.target.rst

View file

@ -0,0 +1,7 @@
====================
stas-config@.service
====================
.. module:: stas-config@.service
.. include:: _stas-config@.service.rst

View file

@ -0,0 +1,7 @@
=======
stasadm
=======
.. module:: stasadm
.. include:: _stasadm.rst

View file

@ -0,0 +1,7 @@
========
sys.conf
========
.. module:: sys.conf
.. include:: _sys.conf.rst

223
doc/stacctl.xml Normal file
View file

@ -0,0 +1,223 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<refentry id="stacctl" xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>stacctl</title>
<productname>nvme-stas</productname>
<author>
<personname>
<honorific>Mr</honorific>
<firstname>Martin</firstname>
<surname>Belanger</surname>
</personname>
<affiliation>
<orgname>Dell, Inc.</orgname>
</affiliation>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>stacctl</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>stacctl</refname>
<refpurpose>STorage Appliance Connector (STAC) utility program</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>stacctl</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="req">COMMAND</arg>
<arg choice="opt" rep="repeat">OPTIONS</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>stacctl</command> is a tool that can be used to communicate
with the <citerefentry><refentrytitle>stacd</refentrytitle>
<manvolnum>8</manvolnum></citerefentry> daemon to retrieve
operational data.
</para>
</refsect1>
<refsect1>
<title>Commands</title>
<para>The following commands are understood:</para>
<variablelist>
<xi:include href="standard-options.xml" xpointer="tron"/>
<xi:include href="standard-options.xml" xpointer="troff"/>
<xi:include href="standard-options.xml" xpointer="status"/>
<varlistentry>
<term><command>ls</command></term>
<listitem>
<para>
Show the list of I/O controllers. This will list
all the I/O controllers configured in
<citerefentry>
<refentrytitle>stacd.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> as well as those discovered by the
<citerefentry>
<refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry> daemon.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Options</title>
<para>The following options are understood:</para>
<variablelist>
<xi:include href="standard-options.xml" xpointer="help"/>
<xi:include href="standard-options.xml" xpointer="version"/>
<xi:include href="standard-options.xml" xpointer="detailed"/>
</variablelist>
</refsect1>
<refsect1>
<title>Exit status</title>
<para>
On success, 0 is returned; otherwise, a non-zero failure code is
returned.
</para>
</refsect1>
<refsect1>
<title>Examples</title>
<example>
<title>List I/O controllers</title>
<programlisting>$ stacctl ls --detailed
[{'connect attempts': 0,
'device': 'nvme1',
'host-iface': '',
'host-traddr': '',
'hostid': '3e518ec3-72ec-46a5-a603-2510e3140e29',
'hostnqn': 'nqn.2014-08.org.nvmexpress:uuid:13730573-e8d7-446e-81f6-042a497846d5',
'model': 'Linux',
'retry connect timer': '60.0s [off]',
'serial': '8d22fa96da912fb13f5a',
'subsysnqn': 'nqn.1988-11.com.dell:PowerSANxxx:01:20210225100113-454f73093ceb4847a7bdfc6e34aedead',
'traddr': '::1',
'transport': 'tcp',
'trsvcid': '8009'},
{'connect attempts': 0,
'device': 'nvme2',
'host-iface': '',
'host-traddr': '',
'hostid': '3e518ec3-72ec-46a5-a603-2510e3140e29',
'hostnqn': 'nqn.2014-08.org.nvmexpress:uuid:13730573-e8d7-446e-81f6-042a497846d5',
'model': 'Linux',
'retry connect timer': '60.0s [off]',
'serial': 'a9987ae2fd173d100fd0',
'subsysnqn': 'nqn.1988-11.com.dell:PowerSANxxx:01:20210225100113-454f73093ceb4847a7bdfc6e34aebeef',
'traddr': '::1',
'transport': 'tcp',
'trsvcid': '8009'},
{'connect attempts': 0,
'device': 'nvme3',
'host-iface': '',
'host-traddr': '',
'hostid': '3e518ec3-72ec-46a5-a603-2510e3140e29',
'hostnqn': 'nqn.2014-08.org.nvmexpress:uuid:13730573-e8d7-446e-81f6-042a497846d5',
'model': 'Linux',
'retry connect timer': '60.0s [off]',
'serial': '13e122f1a8122bed5a8d',
'subsysnqn': 'nqn.1988-11.com.dell:PowerSANxxx:01:20210225100113-454f73093ceb4847a7bdfc6e34ae8e28',
'traddr': '::1',
'transport': 'tcp',
'trsvcid': '8009'}]</programlisting>
</example>
<example>
<title>Disable tracing</title>
<programlisting>$ stacctl troff</programlisting>
</example>
<example>
<title>
Show <citerefentry><refentrytitle>stacd</refentrytitle>
<manvolnum>8</manvolnum></citerefentry> operational status.
</title>
<programlisting>$ stacctl status
{'config soak timer': '1.5s [off]',
'controllers': [{'connect attempts': 0,
'device': 'nvme1',
'host-iface': '',
'host-traddr': '',
'hostid': '3e518ec3-72ec-46a5-a603-2510e3140e29',
'hostnqn': 'nqn.2014-08.org.nvmexpress:uuid:13730573-e8d7-446e-81f6-042a497846d5',
'model': 'Linux',
'retry connect timer': '60.0s [off]',
'serial': '8d22fa96da912fb13f5a',
'subsysnqn': 'nqn.1988-11.com.dell:PowerSANxxx:01:20210225100113-454f73093ceb4847a7bdfc6e34aedead',
'traddr': '::1',
'transport': 'tcp',
'trsvcid': '8009'},
{'connect attempts': 0,
'device': 'nvme2',
'host-iface': '',
'host-traddr': '',
'hostid': '3e518ec3-72ec-46a5-a603-2510e3140e29',
'hostnqn': 'nqn.2014-08.org.nvmexpress:uuid:13730573-e8d7-446e-81f6-042a497846d5',
'model': 'Linux',
'retry connect timer': '60.0s [off]',
'serial': 'a9987ae2fd173d100fd0',
'subsysnqn': 'nqn.1988-11.com.dell:PowerSANxxx:01:20210225100113-454f73093ceb4847a7bdfc6e34aebeef',
'traddr': '::1',
'transport': 'tcp',
'trsvcid': '8009'},
{'connect attempts': 0,
'device': 'nvme3',
'host-iface': '',
'host-traddr': '',
'hostid': '3e518ec3-72ec-46a5-a603-2510e3140e29',
'hostnqn': 'nqn.2014-08.org.nvmexpress:uuid:13730573-e8d7-446e-81f6-042a497846d5',
'model': 'Linux',
'retry connect timer': '60.0s [off]',
'serial': '13e122f1a8122bed5a8d',
'subsysnqn': 'nqn.1988-11.com.dell:PowerSANxxx:01:20210225100113-454f73093ceb4847a7bdfc6e34ae8e28',
'traddr': '::1',
'transport': 'tcp',
'trsvcid': '8009'}],
'log-level': 'DEBUG',
'tron': True}</programlisting>
</example>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry>
<refentrytitle>stacd.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>stacd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
<citerefentry project="man-pages"/>
</para>
</refsect1>
</refentry>

652
doc/stacd.conf.xml Normal file
View file

@ -0,0 +1,652 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<refentry id="stacd.conf" xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>stacd.conf</title>
<productname>nvme-stas</productname>
<author>
<personname>
<honorific>Mr</honorific>
<firstname>Martin</firstname>
<surname>Belanger</surname>
</personname>
<affiliation>
<orgname>Dell, Inc.</orgname>
</affiliation>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>stacd.conf</refentrytitle>
<manvolnum>5</manvolnum>
</refmeta>
<refnamediv>
<refname>stacd.conf</refname>
<refpurpose>
<citerefentry project="man-pages">
<refentrytitle>stacd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
configuration file
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para>
<filename>/etc/stas/stacd.conf</filename>
</para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
When <citerefentry project="man-pages"><refentrytitle>stacd</refentrytitle>
<manvolnum>8</manvolnum></citerefentry> starts up, it reads its
configuration from <filename>stacd.conf</filename>.
</para>
</refsect1>
<refsect1>
<title>Configuration File Format</title>
<para>
<filename>stacd.conf</filename> is a plain text file divided into
sections, with configuration entries in the style
<replaceable>key</replaceable>=<replaceable>value</replaceable>.
Spaces immediately before or after the <literal>=</literal> are
ignored. Empty lines are ignored as well as lines starting with
<literal>#</literal>, which may be used for commenting.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<refsect2>
<title>[Global] section</title>
<para>
The following options are available in the
<literal>[Global]</literal> section:
</para>
<variablelist>
<xi:include href="standard-conf.xml" xpointer="tron"/>
<xi:include href="standard-conf.xml" xpointer="hdr-digest"/>
<xi:include href="standard-conf.xml" xpointer="data-digest"/>
<xi:include href="standard-conf.xml" xpointer="kato"/>
<xi:include href="standard-conf.xml" xpointer="ip-family"/>
<varlistentry>
<term><varname>nr-io-queues=</varname></term>
<listitem>
<para>
Takes a value in the range 1...N. Overrides the
default number of I/O queues create by the driver.
</para>
<para>Note: This parameter is identical to that provided by nvme-cli.</para>
<para>
Default: Depends on kernel and other run
time factors (e.g. number of CPUs).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>nr-write-queues=</varname></term>
<listitem>
<para>
Takes a value in the range 1...N. Adds additional
queues that will be used for write I/O.
</para>
<para>Note: This parameter is identical to that provided by nvme-cli.</para>
<para>
Default: Depends on kernel and other run
time factors (e.g. number of CPUs).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>nr-poll-queues=</varname></term>
<listitem>
<para>
Takes a value in the range 1...N. Adds additional
queues that will be used for polling latency
sensitive I/O.
</para>
<para>Note: This parameter is identical to that provided by nvme-cli.</para>
<para>
Default: Depends on kernel and other run
time factors (e.g. number of CPUs).
</para>
</listitem>
</varlistentry>
<xi:include href="standard-conf.xml" xpointer="queue-size"/>
<xi:include href="standard-conf.xml" xpointer="reconnect-delay"/>
<xi:include href="standard-conf.xml" xpointer="ctrl-loss-tmo"/>
<xi:include href="standard-conf.xml" xpointer="disable-sqflow"/>
<varlistentry>
<term><varname>ignore-iface=</varname></term>
<listitem>
<para>
Takes a boolean argument. This option controls how
connections with I/O Controllers (IOC) are made.
</para>
<para>
There is no guarantee that there will be a route to
reach that IOC. However, we can use the socket
option SO_BINDTODEVICE to force the connection to be
made on a specific interface instead of letting the
routing tables decide where to make the connection.
</para>
<para>
This option determines whether <code>stacd</code> will use
SO_BINDTODEVICE to force connections on an interface
or just rely on the routing tables. The default is
to use SO_BINDTODEVICE, in other words, <code>stacd</code> does
not ignore the interface.
</para>
<para>
BACKGROUND:
By default, <code>stacd</code> will connect to IOCs on the same
interface that was used to retrieve the discovery
log pages. If stafd discovers a DC on an interface
using mDNS, and stafd connects to that DC and
retrieves the log pages, it is expected that the
storage subsystems listed in the log pages are
reachable on the same interface where the DC was
discovered.
</para>
<para>
For example, let's say a DC is discovered on
interface ens102. Then all the subsystems listed in
the log pages retrieved from that DC must be
reachable on interface ens102. If this doesn't work,
for example you cannot "ping -I ens102 [storage-ip]",
then the most likely explanation is that proxy arp
is not enabled on the switch that the host is
connected to on interface ens102. Whatever you do,
resist the temptation to manually set up the routing
tables or to add alternate routes going over a
different interface than the one where the DC is
located. That simply won't work. Make sure proxy arp
is enabled on the switch first.
</para>
<para>
Setting routes won't work because, by default, <code>stacd</code>
uses the SO_BINDTODEVICE socket option when it
connects to IOCs. This option is used to force a
socket connection to be made on a specific interface
instead of letting the routing tables decide where
to connect the socket. Even if you were to manually
configure an alternate route on a different interface,
the connections (i.e. host to IOC) will still be
made on the interface where the DC was discovered by
stafd.
</para>
<para>
Defaults to <parameter>false</parameter>.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect2>
<title>[I/O controller connection management] section</title>
<para>
Connectivity between hosts and subsystems in a fabric is
controlled by Fabric Zoning. Entities that share a common
zone (i.e., are zoned together) are allowed to discover each
other and establish connections between them. Fabric Zoning is
configured on Discovery Controllers (DC). Users can add/remove
controllers and/or hosts to/from zones.
</para>
<para>
Hosts have no direct knowledge of the Fabric Zoning configuration
that is active on a given DC. As a result, if a host is impacted
by a Fabric Zoning configuration change, it will be notified of
the connectivity configuration change by the DC via Asynchronous
Event Notifications (AEN).
</para>
<table frame='all'>
<title>List of terms used in this section:</title>
<tgroup cols="2" align='left' colsep='1' rowsep='1'>
<thead>
<row>
<entry>Term</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>AEN</entry>
<entry>Asynchronous Event Notification. A CQE (Completion Queue Entry) for an Asynchronous Event Request that was previously transmitted by the host to a Discovery Controller. AENs are used by DCs to notify hosts that a change (e.g., a connectivity configuration change) has occurred.</entry>
</row>
<row>
<entry>DC</entry>
<entry>Discovery Controller.</entry>
</row>
<row>
<entry>DLP</entry>
<entry>Discovery Log Page. A host will issue a Get Log Page command to retrieve the list of controllers it may connect to.</entry>
</row>
<row>
<entry>DLPE</entry>
<entry><simpara>
Discovery Log Page Entry. The response
to a Get Log Page command contains a list of DLPEs identifying
each controller that the host is allowed to connect with.
</simpara><simpara>
Note that DLPEs may contain both I/O Controllers (IOCs)
and Discovery Controllers (DCs). DCs listed in DLPEs
are called referrals. <code>stacd</code> only deals with IOCs.
Referrals (DCs) are handled by <code>stafd</code>.
</simpara>
</entry>
</row>
<row>
<entry>IOC</entry>
<entry>I/O Controller.</entry>
</row>
<row>
<entry>Manual Config</entry>
<entry>Refers to manually adding entries to <filename>stacd.conf</filename> with the <varname>controller=</varname> parameter.</entry>
</row>
<row>
<entry>Automatic Config</entry>
<entry>Refers to receiving configuration from a DC as DLPEs</entry>
</row>
<row>
<entry>External Config</entry>
<entry>Refers to configuration done outside of the <code>nvme-stas</code> framework, for example using <code>nvme-cli</code> commands</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
DCs notify hosts of connectivity configuration changes by sending
AENs indicating a "Discovery Log" change. The host uses these AENs as
a trigger to issue a Get Log Page command. The response to this command
is used to update the list of DLPEs containing the controllers
the host is allowed to access.
Upon reception of the current DLPEs, the host will determine
whether DLPEs were added and/or removed, which will trigger the
addition and/or removal of controller connections. This happens in real time
and may affect active connections to controllers including controllers
that support I/O operations (IOCs). A host that was previously
connected to an IOC may suddenly be told that it is no longer
allowed to connect to that IOC and should disconnect from it.
</para>
<formalpara><title>IOC connection creation</title>
<para>
There are 3 ways to configure IOC connections on a host:
</para>
<orderedlist>
<listitem>
<para>
Manual Config by adding <varname>controller=</varname> entries
to the <literal>[Controllers]</literal> section (see below).
</para>
</listitem>
<listitem>
<para>
Automatic Config received in the form of
DLPEs from a remote DC.
</para>
</listitem>
<listitem>
<para>
External Config using <code>nvme-cli</code> (e.g. "<code>nvme connect</code>")
</para>
</listitem>
</orderedlist>
</formalpara>
<formalpara><title>IOC connection removal/prevention</title>
<para>
There are 3 ways to remove (or prevent) connections to an IOC:
</para>
<orderedlist>
<listitem>
<para>
Manual Config.
<orderedlist numeration='lowerroman'>
<listitem>
<para>
by adding <varname>exclude=</varname> entries to
the <literal>[Controllers]</literal> section (see below).
</para>
</listitem>
<listitem>
<para>
by removing <varname>controller=</varname> entries
from the <literal>[Controllers]</literal> section.
</para>
</listitem>
</orderedlist>
</para>
</listitem>
<listitem>
<para>
Automatic Config. As explained above, a host gets a
new list of DLPEs upon connectivity configuration
changes. On DLPE removal, the host should remove the
connection to the IOC matching that DLPE. This
behavior is configurable using the
<varname>disconnect-scope=</varname> parameter
described below.
</para>
</listitem>
<listitem>
<para>
External Config using <code>nvme-cli</code> (e.g. "<code>nvme
disconnect</code>" or "<code>nvme disconnect-all</code>")
</para>
</listitem>
</orderedlist>
</formalpara>
<para>
The decision by the host to automatically disconnect from an
IOC following connectivity configuration changes is controlled
by two parameters: <code>disconnect-scope</code>
and <code>disconnect-trtypes</code>.
</para>
<variablelist>
<varlistentry>
<term><varname>disconnect-scope=</varname></term>
<listitem>
<para>
Takes one of: <parameter>only-stas-connections</parameter>,
<parameter>all-connections-matching-disconnect-trtypes</parameter>, or <parameter>no-disconnect</parameter>.
</para>
<para>
In theory, hosts should only connect to IOCs that have
been zoned for them. Connections to IOCs that a host
is not zoned to have access to should simply not exist.
In practice, however, users may not want hosts to
disconnect from all IOCs in reaction to connectivity
configuration changes (or at least for some of the IOC
connections).
</para>
<para>
Some users may prefer for IOC connections to be "sticky"
and only be removed manually (<code>nvme-cli</code> or
<varname>exclude=</varname>) or removed by a system
reboot. Specifically, they don't want IOC connections
to be removed unexpectedly on DLPE removal. These users
may want to set <varname>disconnect-scope</varname>
to <parameter>no-disconnect</parameter>.
</para>
<para>
It is important to note that when IOC connections
are removed, ongoing I/O transactions will be
terminated immediately. There is no way to tell what
happens to the data being exchanged when such an abrupt
termination happens. If a host was in the middle of writing
to a storage subsystem, there is a chance that outstanding
I/O operations may not successfully complete.
</para>
<refsect3>
<title>Values:</title>
<variablelist>
<varlistentry>
<term><parameter>only-stas-connections</parameter></term>
<listitem>
<para>
Only remove connections previously made by <code>stacd</code>.
</para>
<para>
In this mode, when a DLPE is removed as a result of
connectivity configuration changes, the corresponding
IOC connection will be removed by <code>stacd</code>.
</para>
<para>
Connections to IOCs made externally, e.g. using <code>nvme-cli</code>,
will not be affected, unless they happen to be duplicates
of connections made by <code>stacd</code>. It's simply not
possible for <code>stacd</code> to tell that a connection
was previously made with <code>nvme-cli</code> (or any other external tool).
So, it's good practice to avoid duplicating
configuration between <code>stacd</code> and external tools.
</para>
<para>
Users wanting to persist some of their IOC connections
regardless of connectivity configuration changes should not use
<code>nvme-cli</code> to make those connections. Instead,
they should hard-code them in <filename>stacd.conf</filename>
with the <varname>controller=</varname> parameter. Using the
<varname>controller=</varname> parameter is the only way for a user
to tell <code>stacd</code> that a connection must be made and
not be deleted "<emphasis>no-matter-what</emphasis>".
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>all-connections-matching-disconnect-trtypes</parameter></term>
<listitem>
<para>
All connections that match the transport type specified by
<varname>disconnect-trtypes=</varname>, whether they were
made automatically by <code>stacd</code> or externally
(e.g., <code>nvme-cli</code>), will be audited and are
subject to removal on DLPE removal.
</para>
<para>
In this mode, as DLPEs are removed as a result of
connectivity configuration changes, the corresponding
IOC connections will be removed by the host immediately
whether they were made by <code>stacd</code>, <code>nvme-cli</code>,
or any other way. Basically, <code>stacd</code> audits
<emphasis>all</emphasis> IOC connections matching the
transport type specified by <varname>disconnect-trtypes=</varname>.
</para>
<formalpara><title><emphasis>NOTE</emphasis></title>
<para>
This mode implies that <code>stacd</code> will
only allow Manually Configured or Automatically
Configured IOC connections to exist. Externally
Configured connections using <code>nvme-cli</code>
(or other external mechanism)
that do not match any Manual Config
(<filename>stacd.conf</filename>)
or Automatic Config (DLPEs) will get deleted
immediately by <code>stacd</code>.
</para>
</formalpara>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>no-disconnect</parameter></term>
<listitem>
<para>
<code>stacd</code> does not disconnect from IOCs
when a DPLE is removed or a <varname>controller=</varname>
entry is removed from <filename>stacd.conf</filename>.
All IOC connections are "sticky".
</para>
<para>
Instead, users can remove connections
by issuing the <code>nvme-cli</code>
command "<code>nvme disconnect</code>", add an
<varname>exclude=</varname> entry to
<filename>stacd.conf</filename>, or wait
until the next system reboot at which time all
connections will be removed.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect3>
<para>
Defaults to <parameter>only-stas-connections</parameter>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>disconnect-trtypes=</varname></term>
<listitem>
<para>
This parameter only applies when <varname>disconnect-scope</varname>
is set to <parameter>all-connections-matching-disconnect-trtypes</parameter>.
It limits the scope of the audit to specific transport types.
</para>
<para>
Can take the values <parameter>tcp</parameter>,
<parameter>rdma</parameter>, <parameter>fc</parameter>, or
a combination thereof by separating them with a plus (+) sign.
For example: <parameter>tcp+fc</parameter>. No spaces
are allowed between values and the plus (+) sign.
</para>
<refsect3>
<title>Values:</title>
<variablelist>
<varlistentry>
<term><parameter>tcp</parameter></term>
<listitem>
<para>
Audit TCP connections.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>rdma</parameter></term>
<listitem>
<para>
Audit RDMA connections.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>fc</parameter></term>
<listitem>
<para>
Audit Fibre Channel connections.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect3>
<para>
Defaults to <parameter>tcp</parameter>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>connect-attempts-on-ncc=</varname></term>
<listitem>
<para>
The NCC bit (Not Connected to CDC) is a bit returned
by the CDC in the EFLAGS field of the DLPE. Only CDCs
will set the NCC bit. DDCs will always clear NCC to
0. The NCC bit is a way for the CDC to let hosts
know that the subsystem is currently not reachable
by the CDC. This may indicate that the subsystem is
currently down or that there is an outage on the
section of the network connecting the CDC to the
subsystem.
</para>
<para>
If a host is currently failing to connect to an I/O
controller and if the NCC bit associated with that
I/O controller is asserted, the host can decide to
stop trying to connect to that subsystem until
connectivity is restored. This will be indicated by
the CDC when it clears the NCC bit.
</para>
<para>
The parameter <varname>connect-attempts-on-ncc=</varname>
controls whether <code>stacd</code> will take the
NCC bit into account when attempting to connect to
an I/O Controller. Setting <varname>connect-attempts-on-ncc=</varname>
to 0 means that <code>stacd</code> will ignore
the NCC bit and will keep trying to connect. Setting
<varname>connect-attempts-on-ncc=</varname> to a
non-zero value indicates the number of connection
attempts that will be made before <code>stacd</code>
gives up trying. Note that this value should be set
to a value greater than 1. In fact, when set to 1,
<code>stacd</code> will automatically use 2 instead.
The reason for this is simple. It is possible that a
first connect attempt may fail.
</para>
<para>
Defaults to <parameter>0</parameter>.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
<xi:include href="standard-conf.xml" xpointer="controller"/>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry>
<refentrytitle>stacd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
</para>
</refsect1>
</refentry>

74
doc/stacd.service.xml Normal file
View file

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<refentry id="stacd.service">
<refentryinfo>
<title>stacd.service</title>
<productname>nvme-stas</productname>
<author>
<personname>
<honorific>Mr</honorific>
<firstname>Martin</firstname>
<surname>Belanger</surname>
</personname>
<affiliation>
<orgname>Dell, Inc.</orgname>
</affiliation>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>stacd.service</refentrytitle>
<manvolnum>8</manvolnum>
</refmeta>
<refnamediv>
<refname>stacd.service</refname>
<refpurpose>Systemd unit file for the stacd service</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para>
<filename>/usr/lib/systemd/system/stacd.service</filename>
</para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<citerefentry>
<refentrytitle>stacd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
is a system service used to automatically connect to I/O controllers
discovered by <citerefentry>
<refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry>
<refentrytitle>stacd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>stas-config.target</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
</para>
</refsect1>
</refentry>

229
doc/stacd.xml Normal file
View file

@ -0,0 +1,229 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY daemon "stacd">
<!ENTITY deamondesc "STorage Appliance Connector">
<!ENTITY control "stacctl">
]>
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<refentry id="&daemon;" xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>&daemon;</title>
<productname>nvme-stas</productname>
<author>
<personname>
<honorific>Mr</honorific>
<firstname>Martin</firstname>
<surname>Belanger</surname>
</personname>
<affiliation>
<orgname>Dell, Inc.</orgname>
</affiliation>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>&daemon;</refentrytitle>
<manvolnum>8</manvolnum>
</refmeta>
<refnamediv>
<refname>&daemon;</refname>
<refpurpose>&deamondesc;</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>&daemon;</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>&daemon;</command>
is a system daemon that can be used to automatically connect to
NVMe-oF I/O Controllers using the discovery log pages collected by
<citerefentry>
<refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>. It can also be manually configured with
<citerefentry>
<refentrytitle>&daemon;.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>
to connect to I/O Controllers that otherwise cannot be found
automatically.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<para>The following options are understood:</para>
<variablelist>
<xi:include href="standard-options.xml" xpointer="help"/>
<xi:include href="standard-options.xml" xpointer="version"/>
</variablelist>
<varlistentry>
<term><option>-fFILE</option></term>
<term><option>--conf-file=FILE</option></term>
<listitem>
<para>
Specify a different configuration file than
<citerefentry>
<refentrytitle>&daemon;.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>
(default: <filename>/etc/stas/&daemon;.conf</filename>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-s</option></term>
<term><option>--syslog</option></term>
<listitem>
<para>
Send messages to syslog instead of stdout. Use this when
running &daemon; as a daemon. (default: <literal>false</literal>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--tron</option></term>
<listitem>
<para>Trace ON. (default: <literal>false</literal>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--idl=FILE</option></term>
<listitem>
<para>Print D-Bus IDL to FILE and exit.</para>
</listitem>
</varlistentry>
</refsect1>
<refsect1>
<title>Exit status</title>
<para>
On success, 0 is returned, a non-zero failure code otherwise.
</para>
</refsect1>
<refsect1>
<title>Daemonization</title>
<para>
&daemon; is managed by <code>systemd</code>. The following
operations are supported:
</para>
<table align='left' frame='all'>
<tgroup cols="2" align='left' colsep='1' rowsep='1'>
<thead>
<row>
<entry>Command</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><programlisting>$ systemctl start &daemon; </programlisting></entry>
<entry>Start daemon.</entry>
</row>
<row>
<entry><programlisting>$ systemctl stop &daemon; </programlisting></entry>
<entry>Stop daemon. The <code>SIGTERM</code> signal is used to tell the daemon to stop.</entry>
</row>
<row>
<entry><programlisting>$ systemctl restart &daemon; </programlisting></entry>
<entry>Effectively a <code>stop</code> + <code>start</code>.</entry>
</row>
<row>
<entry><programlisting>$ systemctl reload &daemon; </programlisting></entry>
<entry>Reload configuration. This is done in real time without restarting the daemon. The <code>SIGHUP</code> signal is used to tell the daemon to reload its configuration file. Note that configuration parameters that affect connections (e.g. <code>kato</code>), will not apply to existing connections. Only connections established after the configuration was changed will utilize the new configuration parameters.</entry>
</row>
</tbody>
</tgroup>
</table>
</refsect1>
<refsect1>
<title>Design</title>
<para>
<command>&daemon;</command> use the <code>GLib</code> main loop.
The <code>GLib</code> Python module provides several low-level
building blocks that <command>&daemon;</command> requires. In
addition, many Python modules "play nice" with <code>GLib</code>
such as <code>dasbus</code> (D-Bus package) and <code>pyudev</code>
(UDev package). <code>GLib</code> also provides additional components
such as timers, signal handlers, and much more.
</para>
</refsect1>
<refsect1>
<title>Configuration</title>
<para>
<command>&daemon;</command> can automatically set up the I/O
connections to discovered storage subsystems. However,
<command>&daemon;</command> can also operate in a non-automatic
mode based on manually entered configuration. In other words,
storage subsystems can be entered in a configuration file named
<filename>/etc/stas/&daemon;.conf</filename>.
This configuration file also provides additional parameters,
as log-level attributes used for debugging purposes.
</para>
</refsect1>
<refsect1>
<title>D-Bus API</title>
<para>
The interface to <command>&daemon;</command> is D-Bus.
This allows other programs, such as <command>&control;</command>,
to communicate with <command>&daemon;</command>. The D-Bus address
is <code>org.nvmexpress.stac</code>.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry>
<refentrytitle>&daemon;.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>&daemon;.service</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>stacctl</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>org.nvmexpress.stac</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>.
</para>
</refsect1>
</refentry>

205
doc/stafctl.xml Normal file
View file

@ -0,0 +1,205 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<refentry id="stafctl" xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>stafctl</title>
<productname>nvme-stas</productname>
<author>
<personname>
<honorific>Mr</honorific>
<firstname>Martin</firstname>
<surname>Belanger</surname>
</personname>
<affiliation>
<orgname>Dell, Inc.</orgname>
</affiliation>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>stafctl</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>stafctl</refname>
<refpurpose>STorage Appliance Finder (STAF) utility program</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>stafctl</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="req">COMMAND</arg>
<arg choice="opt" rep="repeat">OPTIONS</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>stafctl</command> is a tool that can be used to communicate
with the <citerefentry><refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum></citerefentry> daemon to retrieve
operational data.
</para>
</refsect1>
<refsect1>
<title>Commands</title>
<para>The following commands are understood:</para>
<variablelist>
<xi:include href="standard-options.xml" xpointer="tron"/>
<xi:include href="standard-options.xml" xpointer="troff"/>
<xi:include href="standard-options.xml" xpointer="status"/>
<varlistentry>
<term><command>ls</command></term>
<listitem>
<para>
Show the list of discovery controllers. This will list
all the controllers configured in
<citerefentry><refentrytitle>stafd.conf</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> as well as those
discovered with mDNS service discovery.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>dlp</command></term>
<listitem>
<para>Show discovery log pages.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>adlp</command></term>
<listitem>
<para>Show all discovery log pages.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Options</title>
<para>The following options are understood:</para>
<variablelist>
<xi:include href="standard-options.xml" xpointer="help"/>
<xi:include href="standard-options.xml" xpointer="version"/>
<xi:include href="standard-options.xml" xpointer="detailed"/>
<xi:include href="standard-options.xml" xpointer="transport"/>
<xi:include href="standard-options.xml" xpointer="traddr"/>
<xi:include href="standard-options.xml" xpointer="trsvcid"/>
<xi:include href="standard-options.xml" xpointer="host-traddr"/>
<xi:include href="standard-options.xml" xpointer="host-iface"/>
<xi:include href="standard-options.xml" xpointer="nqn"/>
</variablelist>
</refsect1>
<refsect1>
<title>Values</title>
<variablelist>
<xi:include href="standard-options.xml" xpointer="TRTYPE-value"/>
<xi:include href="standard-options.xml" xpointer="TRADDR-value"/>
<xi:include href="standard-options.xml" xpointer="TRSVCID-value"/>
<xi:include href="standard-options.xml" xpointer="IFACE-value"/>
<xi:include href="standard-options.xml" xpointer="NQN-value"/>
</variablelist>
</refsect1>
<refsect1>
<title>Exit status</title>
<para>
On success, 0 is returned; otherwise, a non-zero failure code is
returned.
</para>
</refsect1>
<refsect1>
<title>Examples</title>
<example>
<title>List all the discovery controllers</title>
<programlisting>$ stafctl ls
[{'device': 'nvme0',
'host-iface': '',
'host-traddr': '',
'subsysnqn': 'nqn.2014-08.org.nvmexpress.discovery',
'traddr': '::1',
'transport': 'tcp',
'trsvcid': '8009'}]</programlisting>
</example>
<example>
<title>Enable tracing</title>
<programlisting>$ stafctl tron</programlisting>
</example>
<example>
<title>
Show discovery log pages from a specific discovery controller
</title>
<programlisting>$ stafctl dlp --transport tcp --traddr ::1 --trsvcid 8009
[{'adrfam': 'ipv6',
'asqsz': '32',
'cntlid': '65535',
'portid': '1',
'subnqn': 'nqn.1988-11.com.dell:PowerSANxxx:01:20210225100113-454f73093ceb4847a7bdfc6e34ae8e28',
'subtype': 'nvme',
'traddr': '::1',
'treq': 'disable sqflow',
'trsvcid': '8009',
'trtype': 'tcp'},
{'adrfam': 'ipv6',
'asqsz': '32',
'cntlid': '65535',
'portid': '1',
'subnqn': 'nqn.1988-11.com.dell:PowerSANxxx:01:20210225100113-454f73093ceb4847a7bdfc6e34aedead',
'subtype': 'nvme',
'traddr': '::1',
'treq': 'disable sqflow',
'trsvcid': '8009',
'trtype': 'tcp'},
{'adrfam': 'ipv6',
'asqsz': '32',
'cntlid': '65535',
'portid': '1',
'subnqn': 'nqn.1988-11.com.dell:PowerSANxxx:01:20210225100113-454f73093ceb4847a7bdfc6e34aebeef',
'subtype': 'nvme',
'traddr': '::1',
'treq': 'disable sqflow',
'trsvcid': '8009',
'trtype': 'tcp'}]</programlisting>
</example>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry>
<refentrytitle>stafd.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
<citerefentry project="man-pages"/>
</para>
</refsect1>
</refentry>

280
doc/stafd.conf.xml Normal file
View file

@ -0,0 +1,280 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<refentry id="stafd.conf" xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>stafd.conf</title>
<productname>nvme-stas</productname>
<author>
<personname>
<honorific>Mr</honorific>
<firstname>Martin</firstname>
<surname>Belanger</surname>
</personname>
<affiliation>
<orgname>Dell, Inc.</orgname>
</affiliation>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>stafd.conf</refentrytitle>
<manvolnum>5</manvolnum>
</refmeta>
<refnamediv>
<refname>stafd.conf</refname>
<refpurpose>
<citerefentry project="man-pages">
<refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
configuration file
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para>
<filename>/etc/stas/stafd.conf</filename>
</para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
When <citerefentry project="man-pages"><refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum></citerefentry> starts up, it reads its
configuration from <filename>stafd.conf</filename>.
</para>
</refsect1>
<refsect1>
<title>Configuration File Format</title>
<para>
<filename>stafd.conf</filename> is a plain text file divided into
sections, with configuration entries in the style
<replaceable>key</replaceable>=<replaceable>value</replaceable>.
Spaces immediately before or after the <literal>=</literal> are
ignored. Empty lines are ignored as well as lines starting with
<literal>#</literal>, which may be used for commenting.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<refsect2>
<title>[Global] section</title>
<para>
The following options are available in the
<literal>[Global]</literal> section:
</para>
<variablelist>
<xi:include href="standard-conf.xml" xpointer="tron"/>
<xi:include href="standard-conf.xml" xpointer="hdr-digest"/>
<xi:include href="standard-conf.xml" xpointer="data-digest"/>
<xi:include href="standard-conf.xml" xpointer="kato"/>
<xi:include href="standard-conf.xml" xpointer="ip-family"/>
<xi:include href="standard-conf.xml" xpointer="queue-size"/>
<xi:include href="standard-conf.xml" xpointer="reconnect-delay"/>
<xi:include href="standard-conf.xml" xpointer="ctrl-loss-tmo"/>
<xi:include href="standard-conf.xml" xpointer="disable-sqflow"/>
<varlistentry>
<term><varname>ignore-iface=</varname></term>
<listitem>
<para>
Takes a boolean argument. This option controls how
connections with Discovery Controllers (DC) are made.
</para>
<para>
DCs are automatically discovered using DNS-SD/mDNS.
mDNS provides the DC's IP address and the interface
on which the DC was discovered.
</para>
<para>
There is no guarantee that there will be a route to
reach that DC. However, we can use the socket option
SO_BINDTODEVICE to force the connection to be made
on a specific interface instead of letting the
routing tables decide where to make the connection.
</para>
<para>
This option determines whether <code>stafd</code>
will use SO_BINDTODEVICE to force connections on an
interface or just rely on the routing tables. The
default is to use SO_BINDTODEVICE, in other words,
<code>stafd</code> does not ignore the interface by
default.
</para>
<para>
Defaults to <parameter>false</parameter>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>pleo=</varname></term>
<listitem>
<para>
Port Local Entries Only. Takes a string argument
<parameter>enabled</parameter> or
<parameter>disabled</parameter>. This option is sent in
the LSP field (Log SPecific) of the Get Discovery Log
Page (DLP) command. It is used by <code>stafd</code> to
tell Discovery Controllers (DC) whether the response to
a Get DLP command should contain all the NVM subsystems
or only those reachable by the host on the interface
where the Get DLP command was issued by the host.
</para>
<para>
This parameter was introduced in TP8010. When
<varname>pleo=</varname><parameter>enabled</parameter>,
then the DC shall return records for only NVM subsystem
ports that are presented through the same NVM subsystem
port that received the Get Log Page command. When
<varname>pleo=</varname><parameter>disabled</parameter>,
then the DC may return all the NVM subsystem ports
that it holds, even those that can only be reached
on NVM subsystem ports that did not receive the Get
Log Page command. In other words, the host may not
even be able to reach those subsystems.
</para>
<para>
Defaults to <parameter>enabled</parameter>.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect2>
<title>[Service Discovery] section</title>
<para>
The following options are available in the
<literal>[Service Discovery]</literal> section:
</para>
<variablelist>
<varlistentry>
<term><varname>zeroconf=</varname></term>
<listitem>
<para>
Enable zeroconf provisioning using DNS-SD/mDNS.
Takes a string argument <parameter>enabled</parameter> or
<parameter>disabled</parameter>.
</para>
<para>
When <parameter>enabled</parameter>, the default,
<code>stafd</code> makes a request with the
Avahi daemon to locate Discovery Controllers using
DNS-SD/mDNS.
</para>
<para>
Discovery Controllers that support zeroconf advertize
themselves over mDNS with the service type
<literal>_nvme-disc._tcp</literal>.
</para>
<para>
Defaults to <parameter>true</parameter>.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect2>
<title>[Discovery controller connection management] section</title>
<para>
The following options are available in the
<literal>[Discovery controller connection management]</literal> section:
</para>
<varlistentry>
<term><varname>persistent-connections=</varname></term>
<listitem>
<para>
Takes a boolean argument. Whether connections to
Discovery Controllers (DC) are persistent. When
true, connections initiated by stafd will persists
even when stafd is stopped. When
<parameter>false</parameter>, <code>stafd</code>
will disconnect from all DCs it is connected to on
exit.
</para>
<para>
Defaults to <parameter>false</parameter>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>zeroconf-connections-persistence=</varname></term>
<listitem>
<para>
Takes a unit-less value in seconds, or a time span value
such as "72hours" or "5days". A value of 0 means no
persistence. In other words, configuration acquired through
zeroconf (mDNS service discovery) will be removed
immediately when mDNS no longer reports the presence of
a Discovery Controller (DC) and connectivity to that DC
is lost. A value of -1 means that configuration acquired
through zeroconf will persist forever.
</para>
<para>
This is used for the case where a DC that was discovered
through mDNS service discovery no longer advertises
itself through mDNS and can no longer be connected to.
For example, the DC had some catastrophic failure
(e.g. power surge) and needs to be replaced. In that
case, the connection to that DC can never be restored
and a replacement DC will be needed. The replacement
DC will likely have a different NQN (or IP address).
In that scenario, the host won't be able to determine
that the old DC is not coming back. It won't know either
that a newly discovered DC is really the replacement for
the old one. For that reason, the host needs a way to
"age" zeroconf-acquired configuration and remove it
automatically after a certain amount of time. This is
what this parameter is for.
</para>
<para>
Defaults to <parameter>72hours</parameter>.
</para>
</listitem>
</varlistentry>
</refsect2>
<xi:include href="standard-conf.xml" xpointer="controller"/>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry>
<refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
</para>
</refsect1>
</refentry>

67
doc/stafd.service.xml Normal file
View file

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<refentry id="stafd.service">
<refentryinfo>
<title>stafd.service</title>
<productname>nvme-stas</productname>
<author>
<personname>
<honorific>Mr</honorific>
<firstname>Martin</firstname>
<surname>Belanger</surname>
</personname>
<affiliation>
<orgname>Dell, Inc.</orgname>
</affiliation>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>stafd.service</refentrytitle>
<manvolnum>8</manvolnum>
</refmeta>
<refnamediv>
<refname>stafd.service</refname>
<refpurpose>Systemd unit file for the stafd service</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para>
<filename>/usr/lib/systemd/system/stafd.service</filename>
</para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<citerefentry>
<refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
is a system service used to automatically locate NVMe-oF Discovery
Controllers using mDNS service discovery.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry>
<refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>stas-config.target</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
</para>
</refsect1>
</refentry>

237
doc/stafd.xml Normal file
View file

@ -0,0 +1,237 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY daemon "stafd">
<!ENTITY deamondesc "STorage Appliance Finder">
<!ENTITY control "stafctl">
]>
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<refentry id="&daemon;" xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>&daemon;</title>
<productname>nvme-stas</productname>
<author>
<personname>
<honorific>Mr</honorific>
<firstname>Martin</firstname>
<surname>Belanger</surname>
</personname>
<affiliation>
<orgname>Dell, Inc.</orgname>
</affiliation>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>&daemon;</refentrytitle>
<manvolnum>8</manvolnum>
</refmeta>
<refnamediv>
<refname>&daemon;</refname>
<refpurpose>&deamondesc;</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>&daemon;</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>&daemon;</command>
is a system daemon that can be used to automatically locate and
connect to NVMe-oF Discovery Controllers using mDNS service discovery.
It can also be manually configured with
<citerefentry>
<refentrytitle>&daemon;.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>
to connect to Discovery Controllers that cannot be located using
mDNS.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<para>The following options are understood:</para>
<variablelist>
<xi:include href="standard-options.xml" xpointer="help"/>
<xi:include href="standard-options.xml" xpointer="version"/>
</variablelist>
<varlistentry>
<term><option>-fFILE</option></term>
<term><option>--conf-file=FILE</option></term>
<listitem>
<para>
Specify a different configuration file than
<citerefentry>
<refentrytitle>&daemon;.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>
(default: <filename>/etc/stas/&daemon;.conf</filename>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-s</option></term>
<term><option>--syslog</option></term>
<listitem>
<para>
Send messages to syslog instead of stdout. Use this when
running &daemon; as a daemon. (default: <literal>false</literal>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--tron</option></term>
<listitem>
<para>Trace ON. (default: <literal>false</literal>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--idl=FILE</option></term>
<listitem>
<para>Print D-Bus IDL to FILE and exit.</para>
</listitem>
</varlistentry>
</refsect1>
<refsect1>
<title>Exit status</title>
<para>
On success, 0 is returned, a non-zero failure code otherwise.
</para>
</refsect1>
<refsect1>
<title>Daemonization</title>
<para>
&daemon; is managed by <code>systemd</code>. The following
operations are supported:
</para>
<table frame='all'>
<tgroup cols="2" align='left' colsep='1' rowsep='1'>
<thead>
<row>
<entry>Command</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><programlisting>$ systemctl start &daemon; </programlisting></entry>
<entry>Start daemon.</entry>
</row>
<row>
<entry><programlisting>$ systemctl stop &daemon; </programlisting></entry>
<entry>Stop daemon. The <code>SIGTERM</code> signal is used to tell the daemon to stop.</entry>
</row>
<row>
<entry><programlisting>$ systemctl restart &daemon; </programlisting></entry>
<entry>Effectively a <code>stop</code> + <code>start</code>.</entry>
</row>
<row>
<entry><programlisting>$ systemctl reload &daemon; </programlisting></entry>
<entry>Reload configuration. This is done in real time without restarting the daemon. The <code>SIGHUP</code> signal is used to tell the daemon to reload its configuration file. Note that configuration parameters that affect connections (e.g. <code>kato</code>), will not apply to existing connections. Only connections established after the configuration was changed will utilize the new configuration parameters.</entry>
</row>
</tbody>
</tgroup>
</table>
</refsect1>
<refsect1>
<title>Design</title>
<para>
<command>&daemon;</command> use the <code>GLib</code> main loop.
The <code>GLib</code> Python module provides several low-level
building blocks that <command>&daemon;</command> requires. In
addition, many Python modules "play nice" with <code>GLib</code>
such as <code>dasbus</code> (D-Bus package) and <code>pyudev</code>
(UDev package). <code>GLib</code> also provides additional components
such as timers, signal handlers, and much more.
</para>
<para>
<command>&daemon;</command> connects to the <code>avahi-daemon</code>
using D-Bus. The <code>avahi-daemon</code>, or simply
<emphasis>Avahi</emphasis>, is an mDNS discovery service used for
zero-configuration networking (zeroconf). <command>&daemon;</command>
registers with Avahi to automatically locate Central Discovery
Controllers (CDC) and Direct Discovery Controllers (DDC). When Avahi
finds Discovery Controllers (DC), it notifies <command>&daemon;</command>
which connects to the DC with the help of the <code>libnvme</code> library.
Once a connection to a DC is established, <command>&daemon;</command>
can retrieve the <emphasis>discovery log pages</emphasis> from
that DC and cache them in memory.
</para>
</refsect1>
<refsect1>
<title>Configuration</title>
<para>
<command>&daemon;</command> can automatically locate discovery
controllers (DC) with the help of Avahi and connect to them. However,
<command>&daemon;</command> can also operate in a non-automatic
mode based on manually entered configuration. In other words,
DCs can be entered in a configuration named
<filename>/etc/stas/&daemon;.conf</filename>.
This configuration file also provides additional parameters, such
as log-level attributes used for debugging purposes.
</para>
</refsect1>
<refsect1>
<title>D-Bus API</title>
<para>
The interface to <command>&daemon;</command> is D-Bus.
This allows other programs, such as <command>&control;</command>,
to communicate with <command>&daemon;</command>. The D-Bus address
is <code>org.nvmexpress.staf</code>.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry>
<refentrytitle>&daemon;.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>&daemon;.service</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>stafctl</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>org.nvmexpress.staf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>.
</para>
</refsect1>
</refentry>

562
doc/standard-conf.xml Normal file
View file

@ -0,0 +1,562 @@
<?xml version="1.0"?>
<!DOCTYPE refsection PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<root>
<variablelist>
<varlistentry id='tron'>
<term><varname>tron=</varname></term>
<listitem id='tron-text'>
<para>
Trace ON. Takes a boolean argument. If <parameter>true</parameter>,
enables full code tracing. The trace will be displayed in
the system log such as systemd's journal. Defaults to
<parameter>false</parameter>.
</para>
</listitem>
</varlistentry>
<varlistentry id='hdr-digest'>
<term><varname>hdr-digest=</varname></term>
<listitem id='hdr-digest-text'>
<para>
Enable Protocol Data Unit (PDU) Header Digest. Takes a
boolean argument. NVMe/TCP facilitates an optional PDU
Header digest. Digests are calculated using the CRC32C
algorithm. If <parameter>true</parameter>, Header Digests
are inserted in PDUs and checked for errors. Defaults to
<parameter>false</parameter>.
</para>
</listitem>
</varlistentry>
<varlistentry id='data-digest'>
<term><varname>data-digest=</varname></term>
<listitem id='data-digest-text'>
<para>
Enable Protocol Data Unit (PDU) Data Digest. Takes a
boolean argument. NVMe/TCP facilitates an optional PDU
Data digest. Digests are calculated using the CRC32C
algorithm. If <parameter>true</parameter>, Data Digests
are inserted in PDUs and checked for errors. Defaults to
<parameter>false</parameter>.
</para>
</listitem>
</varlistentry>
<varlistentry id='kato'>
<term><varname>kato=</varname></term>
<listitem id='kato-text'>
<para>
Keep Alive Timeout (KATO) in seconds. Takes an unsigned
integer. This field specifies the timeout value for the Keep
Alive feature in seconds. Defaults to 30 seconds for
Discovery Controller connections and 120 seconds for I/O
Controller connections.
</para>
</listitem>
</varlistentry>
<varlistentry id='ip-family'>
<term><varname>ip-family=</varname></term>
<listitem id='ip-family-text'>
<para>
Takes a string argument. With this you can specify
whether IPv4, IPv6, or both are supported when
connecting to a Controller. Connections will not be
attempted to IP addresses (whether discovered or
manually configured with <varname>controller=</varname>)
disabled by this option. If an invalid value
is entered, then the default (see below) will apply.
</para>
<para>
Choices are <parameter>ipv4</parameter>, <parameter>ipv6</parameter>, or <parameter>ipv4+ipv6</parameter>.
</para>
<para>
Defaults to <parameter>ipv4+ipv6</parameter>.
</para>
</listitem>
</varlistentry>
<varlistentry id='queue-size'>
<term><varname>queue-size=</varname></term>
<listitem id='queue-size-text'>
<para>
Takes a value in the range 16...1024.
</para>
<para>
Overrides the default number of elements in the I/O queues
created by the driver. This option will be ignored for
discovery, but will be passed on to the subsequent connect
call.
</para>
<para>Note: This parameter is identical to that provided by nvme-cli.</para>
<para>
Defaults to <parameter>128</parameter>.
</para>
</listitem>
</varlistentry>
<varlistentry id='reconnect-delay'>
<term><varname>reconnect-delay=</varname></term>
<listitem id='reconnect-delay-text'>
<para>
Takes a value in the range 1 to N seconds.
</para>
<para>
Overrides the default delay before reconnect is attempted
after a connect loss.
</para>
<para>Note: This parameter is identical to that provided by nvme-cli.</para>
<para>
Defaults to <parameter>10</parameter>. Retry to connect every 10 seconds.
</para>
</listitem>
</varlistentry>
<varlistentry id='ctrl-loss-tmo'>
<term><varname>ctrl-loss-tmo=</varname></term>
<listitem id='ctrl-loss-tmo-text'>
<para>
Takes a value in the range -1, 0, ..., N seconds. -1 means
retry forever. 0 means do not retry.
</para>
<para>
Overrides the default controller loss timeout period (in seconds).
</para>
<para>Note: This parameter is identical to that provided by nvme-cli.</para>
<para>
Defaults to <parameter>600</parameter> seconds (10 minutes).
</para>
</listitem>
</varlistentry>
<varlistentry id='disable-sqflow'>
<term><varname>disable-sqflow=</varname></term>
<listitem id='disable-sqflow-text'>
<para>
Takes a boolean argument. Disables SQ flow control to omit
head doorbell update for submission queues when sending nvme
completions.
</para>
<para>Note: This parameter is identical to that provided by nvme-cli.</para>
<para>
Defaults to <parameter>false</parameter>.
</para>
</listitem>
</varlistentry>
</variablelist>
<refsect2 id='controller'>
<title>[Controllers] section</title>
<para>The following options are available in the
<literal>[Controllers]</literal> section:</para>
<varlistentry>
<term><varname>controller=</varname></term>
<listitem id='controller-text'>
<para>
Controllers are specified with the <varname>controller</varname>
option. This option may be specified more than once to specify
more than one controller. The format is one line per Controller
composed of a series of fields separated by semi-colons as follows:
</para>
<programlisting>controller=transport=[trtype];traddr=[traddr];trsvcid=[trsvcid];host-traddr=[traddr],host-iface=[iface];nqn=[nqn]
</programlisting>
<refsect3>
<title>Fields</title>
<variablelist>
<varlistentry id='transport'>
<term><varname>transport=</varname></term>
<listitem id='transport-text'>
<para>
This is a mandatory field that specifies the
network fabric being used for a
NVMe-over-Fabrics network. Current
<parameter>trtype</parameter> values understood
are:
</para>
<table id='transport-types'>
<title>Transport type</title>
<tgroup cols="2">
<thead>
<row>
<entry>trtype</entry>
<entry>Definition</entry>
</row>
</thead>
<tbody>
<row>
<entry>rdma</entry>
<entry>
The network fabric is an rdma network (RoCE, iWARP, Infiniband, basic rdma, etc)
</entry>
</row>
<row>
<entry>fc</entry>
<entry>
The network fabric is a Fibre Channel network.
</entry>
</row>
<row>
<entry>tcp</entry>
<entry>
The network fabric is a TCP/IP network.
</entry>
</row>
<row>
<entry>loop</entry>
<entry>
Connect to a NVMe over Fabrics target on the local host
</entry>
</row>
</tbody>
</tgroup>
</table>
</listitem>
</varlistentry>
<varlistentry id='tradd'>
<term>
<varname>traddr=</varname>
</term>
<listitem>
<para>
This is a mandatory field that specifies the
network address of the Controller. For
transports using IP addressing (e.g. rdma)
this should be an IP-based address (ex.
IPv4, IPv6). It could also be a resolvable
host name (e.g. localhost).
</para>
</listitem>
</varlistentry>
<varlistentry id='trsvcid'>
<term>
<varname>trsvcid=</varname>
</term>
<listitem>
<para>
This is an optional field that specifies the
transport service id. For transports using
IP addressing (e.g. rdma, tcp) this field is
the port number.
</para>
<para>
Depending on the transport type, this field
will default to either 8009 or 4420 as
follows.
</para>
<para>
UDP port 4420 and TCP port 4420 have been
assigned by IANA for use by NVMe over
Fabrics. NVMe/RoCEv2 controllers use UDP
port 4420 by default. NVMe/iWARP controllers
use TCP port 4420 by default.
</para>
<para>
TCP port 4420 has been assigned for use by
NVMe over Fabrics and TCP port 8009 has been
assigned by IANA for use by NVMe over
Fabrics discovery. TCP port 8009 is the
default TCP port for NVMe/TCP discovery
controllers. There is no default TCP port
for NVMe/TCP I/O controllers, the Transport
Service Identifier (TRSVCID) field in the
Discovery Log Entry indicates the TCP port
to use.
</para>
<para>
The TCP ports that may be used for NVMe/TCP
I/O controllers include TCP port 4420, and
the Dynamic and/or Private TCP ports (i.e.,
ports in the TCP port number range from
49152 to 65535). NVMe/TCP I/O controllers
should not use TCP port 8009. TCP port 4420
shall not be used for both NVMe/iWARP and
NVMe/TCP at the same IP address on the same
network.
</para>
<para>
Ref:
<ulink
url="https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=nvme">
IANA Service names port numbers
</ulink>
</para>
</listitem>
</varlistentry>
<varlistentry id='nqn'>
<term><varname>nqn=</varname></term>
<listitem>
<para>
This field specifies the Controller's NVMe
Qualified Name.
</para>
<para>
This field is mandatory for I/O Controllers, but is optional for
Discovery Controllers (DC). For the latter, the NQN will default
to the well-known DC NQN: <literal>nqn.2014-08.org.nvmexpress.discovery</literal>
if left undefined.
</para>
</listitem>
</varlistentry>
<varlistentry id='host-traddr'>
<term><varname>host-traddr=</varname></term>
<listitem>
<para>
This is an optional field that specifies the
network address used on the host to connect
to the Controller. For TCP, this sets the
source address on the socket.
</para>
</listitem>
</varlistentry>
<varlistentry id='host-iface'>
<term><varname>host-iface=</varname></term>
<listitem>
<para>
This is an optional field that specifies the
network interface used on the host to
connect to the Controller (e.g. IP eth1,
enp2s0, enx78e7d1ea46da). This forces the
connection to be made on a specific
interface instead of letting the system
decide.
</para>
</listitem>
</varlistentry>
<varlistentry id='dhchap-ctrl-secret'>
<term><varname>dhchap-ctrl-secret=</varname></term>
<listitem>
<para>
This is an optional field that specifies the
NVMe In-band authentication controller secret
(i.e. key) for bi-directional authentication;
needs to be in ASCII format as specified in
NVMe 2.0 section 8.13.5.8 'Secret representation'.
Bi-directional authentication will be attempted
when present.
</para>
</listitem>
</varlistentry>
<varlistentry id='hdr-digest-override'>
<term><varname>hdr-digest=</varname></term>
<listitem>
<para>
See definition in [Global] section. This is
an optional field used to override the value
specified in the [Global] section.
</para>
</listitem>
</varlistentry>
<varlistentry id='data-digest-override'>
<term><varname>data-digest=</varname></term>
<listitem>
<para>
See definition in [Global] section. This is
an optional field used to override the value
specified in the [Global] section.
</para>
</listitem>
</varlistentry>
<varlistentry id='nr-io-queues-override'>
<term><varname>nr-io-queues=</varname></term>
<listitem>
<para>
See definition in [Global] section. This is
an optional field used to override the value
specified in the [Global] section.
</para>
</listitem>
</varlistentry>
<varlistentry id='nr-write-queues-override'>
<term><varname>nr-write-queues=</varname></term>
<listitem>
<para>
See definition in [Global] section. This is
an optional field used to override the value
specified in the [Global] section.
</para>
</listitem>
</varlistentry>
<varlistentry id='nr-poll-queues-override'>
<term><varname>nr-poll-queues=</varname></term>
<listitem>
<para>
See definition in [Global] section. This is
an optional field used to override the value
specified in the [Global] section.
</para>
</listitem>
</varlistentry>
<varlistentry id='queue-size-override'>
<term><varname>queue-size=</varname></term>
<listitem>
<para>
See definition in [Global] section. This is
an optional field used to override the value
specified in the [Global] section.
</para>
</listitem>
</varlistentry>
<varlistentry id='kato-override'>
<term><varname>kato=</varname></term>
<listitem>
<para>
See definition in [Global] section. This is
an optional field used to override the value
specified in the [Global] section.
</para>
</listitem>
</varlistentry>
<varlistentry id='reconnect-delay-override'>
<term><varname>reconnect-delay=</varname></term>
<listitem>
<para>
See definition in [Global] section. This is
an optional field used to override the value
specified in the [Global] section.
</para>
</listitem>
</varlistentry>
<varlistentry id='ctrl-loss-tmo-override'>
<term><varname>ctrl-loss-tmo=</varname></term>
<listitem>
<para>
See definition in [Global] section. This is
an optional field used to override the value
specified in the [Global] section.
</para>
</listitem>
</varlistentry>
<varlistentry id='disable-sqflow-override'>
<term><varname>disable-sqflow=</varname></term>
<listitem>
<para>
See definition in [Global] section. This is
an optional field used to override the value
specified in the [Global] section.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect3>
<para>
Examples:
<programlisting>controller = transport=tcp;traddr=localhost;trsvcid=8009
controller = transport=tcp;traddr=2001:db8::370:7334;host-iface=enp0s8
controller = transport=fc;traddr=nn-0x204600a098cbcac6:pn-0x204700a098cbcac6
</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>exclude=</varname></term>
<listitem id='exclude-text'>
<para>
Controllers that should be excluded can be specified with the
<varname>exclude=</varname> option. Using mDNS to
automatically discover and connect to controllers, can result
in unintentional connections being made. This keyword allows
configuring the controllers that should not be connected to.
</para>
<para>
The syntax is the same as for "controller", except that only
<parameter>transport</parameter>, <parameter>traddr</parameter>,
<parameter>trsvcid</parameter>, <parameter>nqn</parameter>, and
<parameter>host-iface</parameter> apply. Multiple
<varname>exclude=</varname> keywords may appear in the config
file to specify more than 1 excluded controller.
</para>
<para>
Note 1: A minimal match approach is used to eliminate unwanted
controllers. That is, you do not need to specify all the
parameters to identify a controller. Just specifying the
<parameter>host-iface</parameter>, for example, can be used to
exclude all controllers on an interface.
</para>
<para>
Note 2: <varname>exclude=</varname> takes precedence over
<varname>controller</varname>. A controller specified by the
<varname>controller</varname> keyword, can be eliminated by
the <varname>exclude=</varname> keyword.
</para>
<para>
Examples:
<programlisting>exclude = transport=tcp;traddr=fe80::2c6e:dee7:857:26bb # Eliminate a specific address
exclude = host-iface=enp0s8 # Eliminate everything on this interface
</programlisting>
</para>
</listitem>
</varlistentry>
</refsect2>
</root>

163
doc/standard-options.xml Normal file
View file

@ -0,0 +1,163 @@
<?xml version="1.0"?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<variablelist>
<varlistentry id='help'>
<term><option>-h</option></term>
<term><option>--help</option></term>
<listitem id='help-text'>
<para>Print the help text and exit.
</para></listitem>
</varlistentry>
<varlistentry id='version'>
<term><option>--version</option></term>
<listitem id='version-text'>
<para>Print the version string and exit.</para>
</listitem>
</varlistentry>
<varlistentry id='tron'>
<term><command>tron</command></term>
<listitem>
<para>Trace ON. Enable code tracing, which is to say that lots of
debug information will be printed to the syslog
(e.g. systemd-journal).</para>
</listitem>
</varlistentry>
<varlistentry id='troff'>
<term><command>troff</command></term>
<listitem>
<para>Trace OFF. Disable code tracing.</para>
</listitem>
</varlistentry>
<varlistentry id='status'>
<term><command>status</command></term>
<listitem>
<para>Show runtime status information.</para>
</listitem>
</varlistentry>
<varlistentry id='detailed'>
<term><option>-d</option></term>
<term><option>--detailed</option></term>
<listitem>
<para>Print additional details.</para>
</listitem>
</varlistentry>
<varlistentry id='transport'>
<term><option>-tTRTYPE</option></term>
<term><option>--transport=TRTYPE</option></term>
<listitem>
<para>NVMe-over-Fabrics fabric type (default: "tcp").</para>
</listitem>
</varlistentry>
<varlistentry id='traddr'>
<term><option>-aTRADDR</option></term>
<term><option>--traddr=TRADDR</option></term>
<listitem>
<para>Discovery controller's network address.</para>
</listitem>
</varlistentry>
<varlistentry id='trsvcid'>
<term><option>-sTRSVCID</option></term>
<term><option>--trsvcid=TRSVCID</option></term>
<listitem>
<para>
Transport service id (for IP addressing, e.g. tcp, rdma,
this field is the port number).
</para>
</listitem>
</varlistentry>
<varlistentry id='host-traddr'>
<term><option>-wTRADDR</option></term>
<term><option>--host-traddr=TRADDR</option></term>
<listitem>
<para>
Network source address used on the host to connect to
the controller.
</para>
</listitem>
</varlistentry>
<varlistentry id='host-iface'>
<term><option>-fIFACE</option></term>
<term><option>--host-iface=IFACE</option></term>
<listitem>
<para>
This field specifies the network interface used on the
host to connect to the controller.
</para>
</listitem>
</varlistentry>
<varlistentry id='nqn'>
<term><option>-nNQN</option></term>
<term><option>--nqn=NQN</option></term>
<listitem>
<para>
This field specifies the Controller's NVMe Qualified Name.
</para>
<para>
This field is mandatory for I/O Controllers, but is optional for
Discovery Controllers (DC). For the latter, the NQN will default
to the well-known DC NQN: <literal>nqn.2014-08.org.nvmexpress.discovery</literal>
if left undefined.
</para>
</listitem>
</varlistentry>
<varlistentry id='TRTYPE-value'>
<term><replaceable>TRTYPE</replaceable></term>
<listitem>
<para>rdma, fc, tcp, loop.</para>
</listitem>
</varlistentry>
<varlistentry id='TRADDR-value'>
<term><replaceable>TRADDR</replaceable></term>
<listitem>
<para>IP or Fibre Channel address. E.g. 10.10.0.100.</para>
</listitem>
</varlistentry>
<varlistentry id='TRSVCID-value'>
<term><replaceable>TRSVCID</replaceable></term>
<listitem>
<para>E.g., 8009.</para>
</listitem>
</varlistentry>
<varlistentry id='IFACE-value'>
<term><replaceable>IFACE</replaceable></term>
<listitem>
<para>
Network interface name. E.g., eth1, enp0s8, wlp0s20f3.
</para>
</listitem>
</varlistentry>
<varlistentry id='NQN-value'>
<term><replaceable>NQN</replaceable></term>
<listitem>
<para>
NVMe Qualified Name.
</para>
</listitem>
</varlistentry>
</variablelist>

View file

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2022, Dell Inc. or its subsidiaries. All rights reserved.
-->
<refentry id="stas-config.target">
<refentryinfo>
<title>stas-config.target</title>
<productname>nvme-stas</productname>
<author>
<personname>
<honorific>Mr</honorific>
<firstname>Martin</firstname>
<surname>Belanger</surname>
</personname>
<affiliation>
<orgname>Dell, Inc.</orgname>
</affiliation>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>stas-config.target</refentrytitle>
<manvolnum>8</manvolnum>
</refmeta>
<refnamediv>
<refname>stas-config.target</refname>
<refpurpose>Used to synchronize the start of nvme-stas processes</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para>
<filename>/usr/lib/systemd/system/stas-config.target</filename>
</para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
This target is used as a synchronization point before starting
<citerefentry><refentrytitle>stacd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry> and
<citerefentry><refentrytitle>stafd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
</para>
<para>
It ensures that <filename>/etc/nvme/hostnqn</filename> and
<filename>/etc/nvme/hostid</filename> are present before starting
<citerefentry><refentrytitle>stacd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry> and
<citerefentry><refentrytitle>stafd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry>
<refentrytitle>stacd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
<citerefentry>
<refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
</para>
</refsect1>
</refentry>

View file

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2022, Dell Inc. or its subsidiaries. All rights reserved.
-->
<refentry id="stas-config@.service">
<refentryinfo>
<title>stas-config@.service</title>
<productname>nvme-stas</productname>
<author>
<personname>
<honorific>Mr</honorific>
<firstname>Martin</firstname>
<surname>Belanger</surname>
</personname>
<affiliation>
<orgname>Dell, Inc.</orgname>
</affiliation>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>stas-config@.service</refentrytitle>
<manvolnum>8</manvolnum>
</refmeta>
<refnamediv>
<refname>stas-config@.service</refname>
<refpurpose>Used for auto-generation of nvme-stas configuration files.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para>
<filename>/usr/lib/systemd/system/stas-config@.service</filename>
</para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
This service is used for the automatic run-time generation of
NVMe configuration located in <filename>/etc/nvme</filename>
(e.g. <filename>/etc/nvme/hostnqn</filename>). This is needed by
<citerefentry><refentrytitle>stacd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry> and
<citerefentry><refentrytitle>stafd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry>
<refentrytitle>stacd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
<citerefentry>
<refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
</para>
</refsect1>
</refentry>

201
doc/stasadm.xml Normal file
View file

@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<refentry id="stasadm" xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>stasadm</title>
<productname>nvme-stas</productname>
<author>
<personname>
<honorific>Mr</honorific>
<firstname>Martin</firstname>
<surname>Belanger</surname>
</personname>
<affiliation>
<orgname>Dell, Inc.</orgname>
</affiliation>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>stasadm</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>stasadm</refname>
<refpurpose>STorage Appliance Services admin functions</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>stasadm</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="req">COMMAND</arg>
<arg choice="opt" rep="repeat">OPTIONS</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>stasadm</command> is used to configure <code>nvme-stas</code>. The
configuration is saved to <filename>/etc/stas/sys.conf</filename>.
</para>
<para>
Although <code>nvme-stas</code>' configuration is saved to
<filename>/etc/stas/sys.conf</filename>, it's still possible to
interoperate with the configuration of <command>nvme-cli</command>
and <command>libnvme</command>. <code>nvme-stas</code> allows one to
save individual parameters such as the Host NQN and ID outside of
<filename>/etc/stas/sys.conf</filename>. This allows, for example,
using the same default Host NQN and ID defined by
<command>nvme-cli</command> and <command>libnvme</command> in
<filename>/etc/nvme/hostnqn</filename> and <filename>/etc/nvme/hostid</filename>
respectively. To tell <code>nvme-stas</code> that you want to use the
those files, simply use <command>stasadm</command>'s
<option>--file=FILE</option> option.
</para>
</refsect1>
<refsect1>
<title>Commands</title>
<para>The following commands are understood:</para>
<variablelist>
<varlistentry>
<term><command>hostnqn</command></term>
<listitem>
<para>
Generate the Host NQN. This is typically used as a post
installation step to generate <filename>/etc/nvme/hostnqn</filename>.
</para>
<para>
The NVMe base specifications says: <quote>An NQN is
permanent for the lifetime of the host</quote>. For
this reason, the host NQN should only be generated
if <filename>/etc/nvme/hostnqn</filename> does not exist
already.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>hostid</command></term>
<listitem>
<para>
Generate the Host ID. This is typically used as a post
installation step to generate <filename>/etc/nvme/hostid</filename>.
</para>
<para>
Although not explicitly specified in the NVMe
specifications, the Host ID, like the Host NQN, should
be permanent for the lifetime of the host. Only generate
the Host ID if <filename>/etc/nvme/hostid</filename>
does not exist.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>set-symname [SYMNAME]</command></term>
<listitem>
<para>
Set the host symbolic name.
</para>
<para>
The symbolic name is an optional parameter that can be
used for explicit registration with a discovery controller.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>clear-symname</command></term>
<listitem>
<para>
Clear the host symbolic name.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Options</title>
<para>The following options are understood:</para>
<variablelist>
<xi:include href="standard-options.xml" xpointer="help"/>
<xi:include href="standard-options.xml" xpointer="version"/>
<varlistentry>
<term><option>-fFILE</option></term>
<term><option>--file=FILE</option></term>
<listitem>
<para>
By default, <command>hostnqn</command> and <command>hostid</command>
save the values to <filename>/etc/stas/sys.conf</filename>.
This option allows saving to a separate file.
</para>
<para>
Traditionally, <command>nvme-cli</command> and
<command>libnvme</command> retrieve the default Host NQN
and ID from <filename>/etc/nvme/hostnqn</filename> and
<filename>/etc/nvme/hostid</filename> respectively. The
<option>--file=FILE</option> option can be
used to tell <code>nvme-stas</code> that it should
use those same configuration files.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Exit status</title>
<para>
On success, 0 is returned; otherwise, a non-zero failure code is
returned.
</para>
</refsect1>
<refsect1>
<title>Examples</title>
<example>
<title>Generate <filename>/etc/nvme/hostnqn</filename></title>
<programlisting>$ stasadm hostnqn --file /etc/nvme/hostnqn</programlisting>
</example>
<example>
<title>Generate <filename>/etc/nvme/hostid</filename></title>
<programlisting>$ stasadm hostid -f /etc/nvme/hostid</programlisting>
</example>
<example>
<title>Configure the host's symbolic name</title>
<programlisting>$ stasadm set-symname LukeSkywalker</programlisting>
</example>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry>
<refentrytitle>nvme-stas</refentrytitle>
<manvolnum>7</manvolnum>
</citerefentry>
</para>
</refsect1>
</refentry>

141
doc/sys.conf.xml Normal file
View file

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2021, Dell Inc. or its subsidiaries. All rights reserved.
-->
<refentry id="sys.conf" xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>sys.conf</title>
<productname>nvme-stas</productname>
<author>
<personname>
<honorific>Mr</honorific>
<firstname>Martin</firstname>
<surname>Belanger</surname>
</personname>
<affiliation>
<orgname>Dell, Inc.</orgname>
</affiliation>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>sys.conf</refentrytitle>
<manvolnum>5</manvolnum>
</refmeta>
<refnamediv>
<refname>sys.conf</refname>
<refpurpose>
<citerefentry project="man-pages">
<refentrytitle>nvme-stas</refentrytitle>
<manvolnum>7</manvolnum>
</citerefentry>
configuration file
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para>
<filename>/etc/stas/sys.conf</filename>
</para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
When <citerefentry project="man-pages"><refentrytitle>stafd</refentrytitle>
<manvolnum>8</manvolnum></citerefentry> and
<citerefentry project="man-pages"><refentrytitle>stacd</refentrytitle>
<manvolnum>8</manvolnum></citerefentry> start up, they read the
system configuration from <filename>sys.conf</filename>.
</para>
</refsect1>
<refsect1>
<title>Configuration File Format</title>
<para>
<filename>sys.conf</filename> is a plain text file divided into
sections, with configuration entries in the style
<replaceable>key</replaceable>=<replaceable>value</replaceable>.
Whitespace immediately before or after the <literal>=</literal> is
ignored. Empty lines and lines starting with <literal>#</literal>
are ignored, which may be used for commenting.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<refsect2>
<title>[Host] section</title>
<para>
The following options are available in the
<literal>[Host]</literal> section:
</para>
<variablelist>
<varlistentry>
<term><varname>nqn=</varname></term>
<listitem>
<para>
Takes a string argument identifying the Host NQN.
A value starting with <code>file://</code>
indicates that the Host NQN can be retrieved from
a separate file. This is a mandatory parameter.
Defaults to: <literal>file:///etc/nvme/hostnqn</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
<variablelist>
<varlistentry>
<term><varname>id=</varname></term>
<listitem>
<para>
Takes a string argument identifying the Host ID.
A value starting with <code>file://</code>
indicates that the Host ID can be retrieved from
a separate file. This is a mandatory parameter.
Defaults to: <literal>file:///etc/nvme/hostid</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
<variablelist>
<varlistentry>
<term><varname>symname=</varname></term>
<listitem>
<para>
Takes a string argument identifying the Host symbolic name.
A value starting with <code>file://</code>
indicates that the symbolic name can be retrieved from
a separate file. This is an optional parameter.
There is no default value.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry>
<refentrytitle>nvme-stas</refentrytitle>
<manvolnum>7</manvolnum>
</citerefentry>
</para>
</refsect1>
</refentry>