diff options
Diffstat (limited to 'libnvme/nvme.i')
-rw-r--r-- | libnvme/nvme.i | 253 |
1 files changed, 249 insertions, 4 deletions
diff --git a/libnvme/nvme.i b/libnvme/nvme.i index cc939da..eb94cac 100644 --- a/libnvme/nvme.i +++ b/libnvme/nvme.i @@ -28,6 +28,7 @@ #include "nvme/log.h" #include "nvme/ioctl.h" #include "nvme/types.h" + #include "nvme/nbft.h" static int host_iter_err = 0; static int subsys_iter_err = 0; @@ -314,7 +315,7 @@ PyObject *hostid_from_file(); PyDict_SetItemStringDecRef(entry, "asqsz", val); val = PyLong_FromLong(e->eflags); PyDict_SetItemStringDecRef(entry, "eflags", val); - PyList_SetItem(obj, i, entry); /* steals ref. to entry */ + PyList_SetItem(obj, i, entry); /* steals ref. to object - no need to decref */ } $result = obj; }; @@ -325,7 +326,9 @@ PyObject *hostid_from_file(); struct nvme_root { %immutable config_file; + %immutable application; char *config_file; + char *application; }; struct nvme_host { @@ -345,10 +348,12 @@ struct nvme_subsystem { %immutable model; %immutable serial; %immutable firmware; + %immutable application; char *subsysnqn; char *model; char *serial; char *firmware; + char *application; }; struct nvme_ctrl { @@ -611,7 +616,9 @@ struct nvme_ns { %pythonappend nvme_ctrl::connect(struct nvme_host *h, struct nvme_fabrics_config *cfg) { - self.__parent = h # Keep a reference to parent to ensure garbage collection happens in the right order} + self.__host = h # Keep a reference to parent to ensure ctrl obj gets GCed before host} +%pythonappend nvme_ctrl::init(struct nvme_host *h, int instance) { + self.__host = h # Keep a reference to parent to ensure ctrl obj gets GCed before host} %extend nvme_ctrl { nvme_ctrl(struct nvme_root *r, const char *subsysnqn, @@ -733,7 +740,7 @@ struct nvme_ns { if (!obj) Py_RETURN_NONE; for (int i = 0; i < NVME_LOG_SUPPORTED_LOG_PAGES_MAX; i++) - PyList_SetItem(obj, i, PyLong_FromLong(le32_to_cpu(log.lid_support[i]))); /* steals ref. */ + PyList_SetItem(obj, i, PyLong_FromLong(le32_to_cpu(log.lid_support[i]))); /* steals ref. to object - no need to decref */ return obj; } @@ -812,12 +819,250 @@ struct nvme_ns { } %}; +/****** + NBFT + ******/ +%{ + static PyObject *ssns_to_dict(struct nbft_info_subsystem_ns *ss) + { + unsigned int i; + PyObject *output = PyDict_New(); + PyObject *hfis = PyList_New(ss->num_hfis); + + for (i = 0; i < ss->num_hfis; i++) + PyList_SetItem(hfis, i, PyLong_FromLong(ss->hfis[i]->index - 1)); /* steals ref. to object - no need to decref */ + + PyDict_SetItemStringDecRef(output, "hfi_indexes", hfis); + + PyDict_SetItemStringDecRef(output, "trtype", PyUnicode_FromString(ss->transport)); + PyDict_SetItemStringDecRef(output, "traddr", PyUnicode_FromString(ss->traddr)); + PyDict_SetItemStringDecRef(output, "trsvcid", PyUnicode_FromString(ss->trsvcid)); + PyDict_SetItemStringDecRef(output, "subsys_port_id", PyLong_FromLong(ss->subsys_port_id)); + PyDict_SetItemStringDecRef(output, "nsid", PyLong_FromLong(ss->nsid)); + + { + PyObject *nid; + switch (ss->nid_type) { + case NBFT_INFO_NID_TYPE_EUI64: + PyDict_SetItemStringDecRef(output, "nid_type", PyUnicode_FromString("eui64")); + nid = PyUnicode_FromFormat("%02x%02x%02x%02x%02x%02x%02x%02x", + ss->nid[0], ss->nid[1], ss->nid[2], ss->nid[3], + ss->nid[4], ss->nid[5], ss->nid[6], ss->nid[7]); + break; + + case NBFT_INFO_NID_TYPE_NGUID: + PyDict_SetItemStringDecRef(output, "nid_type", PyUnicode_FromString("nguid")); + nid = PyUnicode_FromFormat("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + ss->nid[0], ss->nid[1], ss->nid[2], ss->nid[3], + ss->nid[4], ss->nid[5], ss->nid[6], ss->nid[7], + ss->nid[8], ss->nid[9], ss->nid[10], ss->nid[11], + ss->nid[12], ss->nid[13], ss->nid[14], ss->nid[15]); + break; + + case NBFT_INFO_NID_TYPE_NS_UUID: + { + char uuid_str[NVME_UUID_LEN_STRING]; + PyDict_SetItemStringDecRef(output, "nid_type", PyUnicode_FromString("uuid")); + nvme_uuid_to_string(ss->nid, uuid_str); + nid = PyUnicode_FromString(uuid_str); + break; + } + + default: + nid = NULL; + break; + } + if (nid) + PyDict_SetItemStringDecRef(output, "nid", nid); + } + + if (ss->subsys_nqn) + PyDict_SetItemStringDecRef(output, "subsys_nqn", PyUnicode_FromString(ss->subsys_nqn)); + + PyDict_SetItemStringDecRef(output, "controller_id", PyLong_FromLong(ss->controller_id)); + PyDict_SetItemStringDecRef(output, "asqsz", PyLong_FromLong(ss->asqsz)); + + if (ss->dhcp_root_path_string) + PyDict_SetItemStringDecRef(output, "dhcp_root_path_string", PyUnicode_FromString(ss->dhcp_root_path_string)); + + PyDict_SetItemStringDecRef(output, "pdu_header_digest_required", PyBool_FromLong(ss->pdu_header_digest_required)); + PyDict_SetItemStringDecRef(output, "data_digest_required", PyBool_FromLong(ss->data_digest_required)); + + return output; + } + + static PyObject *hfi_to_dict(struct nbft_info_hfi *hfi) + { + PyObject *output = PyDict_New(); + + PyDict_SetItemStringDecRef(output, "trtype", PyUnicode_FromString(hfi->transport)); + + if (!strcmp(hfi->transport, "tcp")) { + PyDict_SetItemStringDecRef(output, "pcidev", + PyUnicode_FromFormat("%x:%x:%x.%x", + ((hfi->tcp_info.pci_sbdf & 0xffff0000) >> 16), + ((hfi->tcp_info.pci_sbdf & 0x0000ff00) >> 8), + ((hfi->tcp_info.pci_sbdf & 0x000000f8) >> 3), + ((hfi->tcp_info.pci_sbdf & 0x00000007) >> 0))); + + PyDict_SetItemStringDecRef(output, "mac_addr", + PyUnicode_FromFormat("%02x:%02x:%02x:%02x:%02x:%02x", + hfi->tcp_info.mac_addr[0], + hfi->tcp_info.mac_addr[1], + hfi->tcp_info.mac_addr[2], + hfi->tcp_info.mac_addr[3], + hfi->tcp_info.mac_addr[4], + hfi->tcp_info.mac_addr[5])); + + PyDict_SetItemStringDecRef(output, "vlan", PyLong_FromLong(hfi->tcp_info.vlan)); + PyDict_SetItemStringDecRef(output, "ip_origin", PyLong_FromLong(hfi->tcp_info.ip_origin)); + PyDict_SetItemStringDecRef(output, "ipaddr", PyUnicode_FromString(hfi->tcp_info.ipaddr)); + PyDict_SetItemStringDecRef(output, "subnet_mask_prefix", PyLong_FromLong(hfi->tcp_info.subnet_mask_prefix)); + PyDict_SetItemStringDecRef(output, "gateway_ipaddr", PyUnicode_FromString(hfi->tcp_info.gateway_ipaddr)); + PyDict_SetItemStringDecRef(output, "route_metric", PyLong_FromLong(hfi->tcp_info.route_metric)); + PyDict_SetItemStringDecRef(output, "primary_dns_ipaddr", PyUnicode_FromString(hfi->tcp_info.primary_dns_ipaddr)); + PyDict_SetItemStringDecRef(output, "secondary_dns_ipaddr", PyUnicode_FromString(hfi->tcp_info.secondary_dns_ipaddr)); + PyDict_SetItemStringDecRef(output, "dhcp_server_ipaddr", PyUnicode_FromString(hfi->tcp_info.dhcp_server_ipaddr)); + + if (hfi->tcp_info.host_name) + PyDict_SetItemStringDecRef(output, "host_name", PyUnicode_FromString(hfi->tcp_info.host_name)); + + PyDict_SetItemStringDecRef(output, "this_hfi_is_default_route", PyBool_FromLong(hfi->tcp_info.this_hfi_is_default_route)); + PyDict_SetItemStringDecRef(output, "dhcp_override", PyBool_FromLong(hfi->tcp_info.dhcp_override)); + } + + return output; + } + + static PyObject *discovery_to_dict(struct nbft_info_discovery *disc) + { + PyObject *output = PyDict_New(); + + if (disc->security) + PyDict_SetItemStringDecRef(output, "security_index", PyLong_FromLong(disc->security->index)); + if (disc->hfi) + PyDict_SetItemStringDecRef(output, "hfi_index", PyLong_FromLong(disc->hfi->index - 1)); + if (disc->uri) + PyDict_SetItemStringDecRef(output, "uri", PyUnicode_FromString(disc->uri)); + if (disc->nqn) + PyDict_SetItemStringDecRef(output, "nqn", PyUnicode_FromString(disc->nqn)); + + return output; + } + + static PyObject *nbft_to_pydict(struct nbft_info *nbft) + { + PyObject *val; + PyObject *output = PyDict_New(); + + { + PyObject *host = PyDict_New(); + + if (nbft->host.nqn) + PyDict_SetItemStringDecRef(host, "nqn", PyUnicode_FromString(nbft->host.nqn)); + if (nbft->host.id) { + char uuid_str[NVME_UUID_LEN_STRING]; + nvme_uuid_to_string((unsigned char *)nbft->host.id, uuid_str); + PyDict_SetItemStringDecRef(host, "id", PyUnicode_FromString(uuid_str)); + } + + PyDict_SetItemStringDecRef(host, "host_id_configured", PyBool_FromLong(nbft->host.host_id_configured)); + PyDict_SetItemStringDecRef(host, "host_nqn_configured", PyBool_FromLong(nbft->host.host_nqn_configured)); + + val = PyUnicode_FromString(nbft->host.primary == NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_NOT_INDICATED ? "not indicated" : + nbft->host.primary == NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_UNSELECTED ? "unselected" : + nbft->host.primary == NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_SELECTED ? "selected" : "reserved"); + PyDict_SetItemStringDecRef(host, "primary_admin_host_flag", val); + + PyDict_SetItemStringDecRef(output, "host", host); + } + + { + size_t ss_num = 0; + struct nbft_info_subsystem_ns **ss; + PyObject *subsystem; + + /* First, let's find how many entries there are */ + for (ss = nbft->subsystem_ns_list; ss && *ss; ss++) + ss_num++; + + /* Now, let's fill the list using "(*ss)->index - 1" + as the index for writing to the list */ + subsystem = PyList_New(ss_num); + for (ss = nbft->subsystem_ns_list; ss && *ss; ss++) + PyList_SetItem(subsystem, (*ss)->index - 1, ssns_to_dict(*ss)); /* steals ref. to object - no need to decref */ + + PyDict_SetItemStringDecRef(output, "subsystem", subsystem); + } + + { + size_t hfi_num = 0; + struct nbft_info_hfi **hfi; + PyObject *hfis; + + /* First, let's find how many entries there are */ + for (hfi = nbft->hfi_list; hfi && *hfi; hfi++) + hfi_num++; + + /* Now, let's fill the list using "(*hfi)->index - 1" + as the index for writing to the list */ + hfis = PyList_New(hfi_num); + for (hfi = nbft->hfi_list; hfi && *hfi; hfi++) + PyList_SetItem(hfis, (*hfi)->index-1, hfi_to_dict(*hfi)); /* steals ref. to object - no need to decref */ + + PyDict_SetItemStringDecRef(output, "hfi", hfis); + } + + { + size_t disc_num = 0; + struct nbft_info_discovery **disc; + PyObject *discovery; + + /* First, let's find how many entries there are */ + for (disc = nbft->discovery_list; disc && *disc; disc++) + disc_num++; + + /* Now, let's fill the list using "(*disc)->index - 1" + as the index for writing to the list */ + discovery = PyList_New(disc_num); + for (disc = nbft->discovery_list; disc && *disc; disc++) + PyList_SetItem(discovery, (*disc)->index - 1, discovery_to_dict(*disc)); /* steals ref. to object - no need to decref */ + + PyDict_SetItemStringDecRef(output, "discovery", discovery); + } + + /* Security profiles are currently not implemented. */ + + return output; + } + + PyObject *nbft_get(const char * filename) + { + struct nbft_info *nbft; + PyObject *output; + int ret; + + ret = nvme_nbft_read(&nbft, filename); + if (ret) { + Py_RETURN_NONE; + } + + output = nbft_to_pydict(nbft); + nvme_nbft_free(nbft); + return output; + } +%}; + +%feature("autodoc", "@return an NBFT table as a dict on success, None otherwise.\n" + "@param filename: file to read") nbft_get; +PyObject *nbft_get(const char * filename); // We want to swig all the #define and enum from types.h, but none of the structs. +#pragma SWIG nowarn=503 // Supress warnings about unnamed struct #define __attribute__(x) %rename($ignore, %$isclass) ""; // ignore all classes/structs %rename($ignore, %$isfunction) ""; // ignore all functions %rename($ignore, %$isunion) ""; // ignore all unions -%rename($ignore, %$isvariable ) ""; // ignore all variables +%rename($ignore, %$isvariable) ""; // ignore all variables %include "../src/nvme/types.h" |