Skip to content

Commit af3241e

Browse files
author
Martin Belanger
committed
python: Use nvmf_get_discovery_wargs()
Refactor code to use nvmf_get_discovery_wargs() which allows setting the LSP field. Needed for TP8010 support (i.e. setting PLEO bit). Also, added supported_log_pages() which is used to determine whether the PLEO bit is supported (PLOES). Signed-off-by: Martin Belanger <[email protected]>
1 parent ceb1aa3 commit af3241e

3 files changed

Lines changed: 94 additions & 29 deletions

File tree

examples/discover-loop.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,44 @@
1717
under the License.
1818
'''
1919

20+
import sys
21+
import pprint
2022
from libnvme import nvme
23+
24+
def disc_supp_str(disc_log_page_support):
25+
d = {
26+
nvme.NVMF_LOG_DISC_LID_EXTDLPES: "Extended Discovery Log Page Entry Supported (EXTDLPES)",
27+
nvme.NVMF_LOG_DISC_LID_PLEOS: "Port Local Entries Only Supported (PLEOS)",
28+
nvme.NVMF_LOG_DISC_LID_ALLSUBES: "All NVM Subsystem Entries Supported (ALLSUBES)",
29+
}
30+
return [txt for msk, txt in d.items() if disc_log_page_support & msk]
31+
2132
r = nvme.root()
2233
h = nvme.host(r)
23-
c = nvme.ctrl(nvme.NVME_DISC_SUBSYS_NAME, 'loop')
34+
c = nvme.ctrl(r, nvme.NVME_DISC_SUBSYS_NAME, 'loop')
2435
try:
2536
c.connect(h)
26-
except:
27-
sys.exit("Failed to connect!")
37+
except Exception as e:
38+
sys.exit(f'Failed to connect: {e}')
2839

2940
print("connected to %s subsys %s" % (c.name, c.subsystem.name))
41+
42+
slp = c.supported_log_pages()
43+
disc_log_page_support = slp[nvme.NVME_LOG_LID_DISCOVER] if slp is not None else 0
44+
print(f"LID {nvme.NVME_LOG_LID_DISCOVER}h (Discovery), supports: {disc_supp_str(disc_log_page_support)}")
45+
46+
try:
47+
lsp = nvme.NVMF_LOG_DISC_LSP_PLEO if disc_log_page_support & nvme.NVMF_LOG_DISC_LID_PLEOS else 0
48+
d = c.discover(lsp=lsp)
49+
print(pprint.pformat(d))
50+
except Exception as e:
51+
sys.exit(f'Failed to discover: {e}')
52+
3053
try:
31-
d = c.discover()
32-
print (d)
33-
except:
34-
print("Failed to discover!")
35-
pass
3654
c.disconnect()
55+
except Exception as e:
56+
sys.exit(f'Failed to disconnect: {e}')
57+
58+
c = None
59+
h = None
60+
r = None

libnvme/README.md

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,24 @@ import sys
1010
import pprint
1111
from libnvme import nvme
1212

13+
def disc_supp_str(disc_log_page_support):
14+
d = {
15+
nvme.NVMF_LOG_DISC_LID_EXTDLPES: "Extended Discovery Log Page Entry Supported (EXTDLPES)",
16+
nvme.NVMF_LOG_DISC_LID_PLEOS: "Port Local Entries Only Supported (PLEOS)",
17+
nvme.NVMF_LOG_DISC_LID_ALLSUBES: "All NVM Subsystem Entries Supported (ALLSUBES)",
18+
}
19+
return [txt for msk, txt in d.items() if disc_log_page_support & msk]
20+
1321
root = nvme.root() # This is a singleton
1422
root.log_level('debug') # Optional: extra debug info
1523

1624
host = nvme.host(root) # This "may be" a singleton.
17-
sybsysnqn = [string] # e.g. 'nqn.2014-08.org.nvmexpress.discovery', nvme.NVME_DISC_SUBSYS_NAME, ...
18-
transport = [string] # One of: 'tcp, 'rdma', 'fc', 'loop'.
25+
subsysnqn = [string] # e.g. nvme.NVME_DISC_SUBSYS_NAME, ...
26+
transport = [string] # One of: 'tcp', 'rdma', 'fc', 'loop'.
1927
traddr = [IPv4 or IPv6] # e.g. '192.168.10.10', 'fd2e:853b:3cad:e135:506a:65ee:29f2:1b18', ...
2028
trsvcid = [string] # e.g. '8009', '4420', ...
2129
host_iface = [interface] # e.g. 'eth1', ens256', ...
22-
ctrl = nvme.ctrl(subsysnqn=subsysnqn, transport=transport, traddr=traddr, trsvcid=trsvcid, host_iface=host_iface)
30+
ctrl = nvme.ctrl(root, subsysnqn=subsysnqn, transport=transport, traddr=traddr, trsvcid=trsvcid, host_iface=host_iface)
2331

2432
try:
2533
cfg = {
@@ -31,8 +39,17 @@ try:
3139
except Exception as e:
3240
sys.exit(f'Failed to connect: {e}')
3341

42+
supported_log_pages = ctrl.supported_log_pages()
43+
if supported_log_pages is not None:
44+
disc_log_page_support = supported_log_pages[nvme.NVME_LOG_LID_DISCOVER]
45+
print(f"LID {nvme.NVME_LOG_LID_DISCOVER:02x}h (Discovery), supports: {disc_supp_str(disc_log_page_support)}")
46+
3447
try:
35-
log_pages = ctrl.discover()
48+
if disc_log_page_support and (disc_log_page_support & nvme.NVMF_LOG_DISC_LID_PLEOS):
49+
lsp = nvme.NVMF_LOG_DISC_LSP_PLEO
50+
else:
51+
lsp = 0
52+
log_pages = ctrl.discover(lsp=lsp)
3653
print(pprint.pformat(log_pages))
3754
except Exception as e:
3855
sys.exit(f'Failed to retrieve log pages: {e}')
@@ -42,5 +59,8 @@ try:
4259
except Exception as e:
4360
sys.exit(f'Failed to disconnect: {e}')
4461

62+
ctrl = None
63+
host = None
64+
root = None
4565
```
4666

libnvme/nvme.i

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@
2121

2222
%{
2323
#include <ccan/list/list.h>
24+
#include <ccan/endian/endian.h>
2425
#include "nvme/tree.h"
2526
#include "nvme/fabrics.h"
2627
#include "nvme/private.h"
2728
#include "nvme/log.h"
29+
#include "nvme/ioctl.h"
30+
#include "nvme/types.h"
2831

2932
static int host_iter_err = 0;
3033
static int subsys_iter_err = 0;
@@ -625,25 +628,46 @@ struct nvme_ns {
625628
}
626629

627630
%newobject discover;
628-
struct nvmf_discovery_log *discover(int max_retries = 6) {
629-
struct nvmf_discovery_log *logp = NULL;
631+
struct nvmf_discovery_log *discover(int lsp = 0, int max_retries = 6) {
632+
struct nvme_get_discovery_args args = {
633+
.c = $self,
634+
.args_size = sizeof(args),
635+
.max_retries = max_retries,
636+
.result = NULL,
637+
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
638+
.lsp = lsp,
639+
};
640+
struct nvmf_discovery_log *logp = nvmf_get_discovery_wargs(&args);
641+
if (logp == NULL)
642+
discover_err = 1;
643+
return logp;
644+
}
645+
646+
%feature("autodoc", "@return: List of supported log pages") supported_log_pages;
647+
PyObject * supported_log_pages(bool rae=true) {
648+
struct nvme_supported_log_pages log;
649+
PyObject *obj = NULL;
630650
int ret = 0;
631-
ret = nvmf_get_discovery_log($self, &logp, max_retries);
651+
652+
ret = nvme_get_log_supported_log_pages(nvme_ctrl_get_fd($self), rae, &log);
632653
if (ret < 0) {
633-
discover_err = 1;
634-
return NULL;
654+
Py_RETURN_NONE;
635655
}
636-
return logp;
656+
657+
obj = PyList_New(NVME_LOG_SUPPORTED_LOG_PAGES_MAX);
658+
if (!obj)
659+
Py_RETURN_NONE;
660+
661+
for (int i = 0; i < NVME_LOG_SUPPORTED_LOG_PAGES_MAX; i++)
662+
PyList_SetItem(obj, i, PyLong_FromLong(le32_to_cpu(log.lid_support[i]))); /* steals ref. */
663+
664+
return obj;
637665
}
638-
char *__str__() {
639-
static char tmp[1024];
640666

641-
if ($self->address)
642-
sprintf(tmp, "nvme_ctrl(transport=%s,%s)", $self->transport,
643-
$self->address);
644-
else
645-
sprintf(tmp, "nvme_ctrl(transport=%s)", $self->transport);
646-
return tmp;
667+
PyObject *__str__() {
668+
return $self->address ?
669+
PyUnicode_FromFormat("nvme_ctrl(transport=%s,%s)", $self->transport, $self->address) :
670+
PyUnicode_FromFormat("nvme_ctrl(transport=%s)", $self->transport);
647671
}
648672
struct ctrl_iter __iter__() {
649673
struct ctrl_iter ret = { .subsystem = nvme_ctrl_get_subsystem($self),
@@ -710,9 +734,6 @@ struct nvme_ns {
710734

711735

712736
// We want to swig all the #define and enum from types.h, but none of the structs.
713-
%{
714-
#include "nvme/types.h"
715-
%}
716737
#define __attribute__(x)
717738
%rename($ignore, %$isclass) ""; // ignore all classes/structs
718739
%rename($ignore, %$isfunction) ""; // ignore all functions

0 commit comments

Comments
 (0)