Skip to content

Commit 1a4d092

Browse files
Martin Belangerigaw
Martin Belanger
authored andcommitted
python, swig: add missing controller attributes
Found that some controller attributes (e.g. tls_key) were missing from the SWIG wrapper code. Also found that for some of the attributes, SWIG was generating code that accessed to attributes directly instead of using the getter/setter methods. For example, SWIG would generate code like this: name = c->name; Instead of that: name = nvme_ctrl_get_name(c); This may have been OK in most cases, but the Python code should really use the getter/setter methods instead of accessing the controller object directly. SWIG is a weird beast to tame. For example, all the setter/getter methods must exactly match the syntax: [class]_[member]_[set|get] (e.g. nvme_ctrl_traddr_get) However, most of the libnvme functions follow this syntax: [class]_[set|get]_[member] (e.g. nvme_ctrl_get_traddr) The trick to force SWIG to use the setter/getter methods is to define the attributes in a %extend block and provide explicit translation methods for all the setter/getter methods. Signed-off-by: Martin Belanger <[email protected]>
1 parent c4bb99a commit 1a4d092

File tree

2 files changed

+191
-39
lines changed

2 files changed

+191
-39
lines changed

libnvme/meson.build

+3-3
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ if build_python_bindings
6262
# Set the PYTHONPATH so that we can run the
6363
# tests directly from the build directory.
6464
test_env = environment()
65-
test_env.append('MALLOC_PERTURB_', '0')
66-
test_env.append('PYTHONPATH', join_paths(meson.current_build_dir(), '..'))
67-
test_env.append('PYTHONMALLOC', 'malloc')
65+
test_env.set('MALLOC_PERTURB_', '90')
66+
test_env.prepend('PYTHONPATH', join_paths(meson.current_build_dir(), '..'))
67+
test_env.set('PYTHONMALLOC', 'malloc')
6868

6969
# Test section
7070
test('python-import-libnvme', python3, args: ['-c', 'from libnvme import nvme'], env: test_env, depends: pynvme_clib)

libnvme/nvme.i

+188-36
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,9 @@ struct nvme_subsystem {
357357
};
358358

359359
struct nvme_ctrl {
360+
%immutable name;
361+
%immutable subsystem;
362+
%immutable state;
360363
%immutable sysfs_dir;
361364
%immutable address;
362365
%immutable firmware;
@@ -369,34 +372,67 @@ struct nvme_ctrl {
369372
%immutable subsysnqn;
370373
%immutable traddr;
371374
%immutable trsvcid;
372-
%immutable dhchap_host_key;
373-
%immutable dhchap_key;
374375
%immutable cntrltype;
376+
%immutable cntlid;
375377
%immutable dctype;
376-
%immutable discovery_ctrl;
378+
%immutable phy_slot;
377379
%immutable discovered;
378-
%immutable persistent;
379-
char *sysfs_dir;
380-
char *address;
381-
char *firmware;
382-
char *model;
383-
char *numa_node;
384-
char *queue_count;
385-
char *serial;
386-
char *sqsize;
387-
char *transport;
388-
char *subsysnqn;
389-
char *traddr;
390-
char *trsvcid;
380+
381+
const char *cntrltype; // Do not put in %extend because there's no getter method in libnvme.map
382+
const char *dctype; // Do not put in %extend because there's no getter method in libnvme.map
383+
const bool discovered; // Do not put in %extend because there's no getter method in libnvme.map
384+
391385
%extend {
392-
char *dhchap_host_key:
393-
char *dhchap_key;
386+
/**
387+
* By putting these attributes in an %extend block, we're
388+
* forcing SWIG to invoke getter/setter methods instead of
389+
* accessing the members directly.
390+
*
391+
* For example, SWIG will generate code like this:
392+
* name = nvme_ctrl_name_get(ctrl)
393+
*
394+
* instead of that:
395+
* name = ctrl->name
396+
*/
397+
const char *name;
398+
const char *state;
399+
const char *sysfs_dir;
400+
const char *address;
401+
const char *firmware;
402+
const char *model;
403+
const char *numa_node;
404+
const char *queue_count;
405+
const char *serial;
406+
const char *sqsize;
407+
const char *transport;
408+
const char *subsysnqn;
409+
const char *traddr;
410+
const char *trsvcid;
411+
const char *cntlid;
412+
const char *phy_slot;
413+
414+
bool unique_discovery_ctrl;
415+
bool discovery_ctrl;
416+
bool persistent;
417+
418+
char *keyring;
419+
char *tls_key_identity;
420+
char *tls_key;
421+
422+
/**
423+
* We are remapping the following members of the C code's
424+
* nvme_ctrl_t to different names in Python. Here's the mapping:
425+
*
426+
* C code Python (SWIG)
427+
* ===================== =====================
428+
* ctrl->s ctrl->subsystem
429+
* ctrl->dhchap_key ctrl->dhchap_host_key
430+
* ctrl->dhchap_ctrl_key ctrl->dhchap_key
431+
*/
432+
struct nvme_subsystem *subsystem; // Maps to "s" in the C code
433+
char *dhchap_host_key; // Maps to "dhchap_key" in the C code
434+
char *dhchap_key; // Maps to "dhchap_ctrl_key" in the C code
394435
}
395-
char *cntrltype;
396-
char *dctype;
397-
bool discovery_ctrl;
398-
bool discovered;
399-
bool persistent;
400436
};
401437

402438
struct nvme_ns {
@@ -634,9 +670,13 @@ struct nvme_ns {
634670
nvme_free_ctrl($self);
635671
}
636672

637-
void discovery_ctrl_set(bool discovery) {
638-
nvme_ctrl_set_discovery_ctrl($self, discovery);
639-
}
673+
%pythoncode %{
674+
def discovery_ctrl_set(self, discovery: bool):
675+
r"""DEPRECATED METHOD: Use property setter instead (e.g. ctrl.discovery_ctrl = True)"""
676+
import warnings
677+
warnings.warn("Use property setter instead (e.g. ctrl_obj.discovery_ctrl = True)", DeprecationWarning, stacklevel=2)
678+
return _nvme.ctrl_discovery_ctrl_set(self, discovery)
679+
%}
640680

641681
bool init(struct nvme_host *h, int instance) {
642682
return nvme_init_ctrl(h, $self, instance) == 0;
@@ -665,9 +705,13 @@ struct nvme_ns {
665705
bool connected() {
666706
return nvme_ctrl_get_name($self) != NULL;
667707
}
668-
void persistent_set(bool persistent) {
669-
nvme_ctrl_set_persistent($self, persistent);
670-
}
708+
%pythoncode %{
709+
def persistent_set(self, persistent: bool):
710+
r"""DEPRECATED METHOD: Use property setter instead (e.g. ctrl.persistent = True)"""
711+
import warnings
712+
warnings.warn("Use property setter instead (e.g. ctrl_obj.persistent = True)", DeprecationWarning, stacklevel=2)
713+
return _nvme.ctrl_persistent_set(self, persistent)
714+
%}
671715
void rescan() {
672716
nvme_rescan_ctrl($self);
673717
}
@@ -760,15 +804,22 @@ struct nvme_ns {
760804
struct nvme_ns* namespaces() {
761805
return nvme_ctrl_first_ns($self);
762806
}
763-
%immutable name;
764-
const char *name;
765-
%immutable subsystem;
766-
struct nvme_subsystem *subsystem;
767-
%immutable state;
768-
const char *state;
769807
}
770808

771809
%{
810+
/**********************************************************************
811+
* SWIG automatically generates getter and setter methods using
812+
* the syntax: [class]_[member]_[get|set]. These need to be mapped
813+
* to the matching methods in libnvme (i.e. those that are defined
814+
* publicly in libnvme.map). Typically, we get the following mapping:
815+
*
816+
* SWIG libnvme.map
817+
* ====================== =======================
818+
* nvme_ctrl_[member]_get -> nvme_ctrl_get_[member]
819+
* nvme_ctrl_[member]_set -> nvme_ctrl_set_[member]
820+
*
821+
*/
822+
772823
const char *nvme_ctrl_name_get(struct nvme_ctrl *c) {
773824
return nvme_ctrl_get_name(c);
774825
}
@@ -787,7 +838,108 @@ struct nvme_ns {
787838
const char *nvme_ctrl_dhchap_host_key_get(struct nvme_ctrl *c) {
788839
return nvme_ctrl_get_dhchap_host_key(c);
789840
}
790-
%};
841+
void nvme_ctrl_dhchap_host_key_set(struct nvme_ctrl *c, const char *key) {
842+
nvme_ctrl_set_dhchap_host_key(c, key);
843+
}
844+
845+
const char *nvme_ctrl_cntlid_get(nvme_ctrl_t c) {
846+
return nvme_ctrl_get_cntlid(c);
847+
}
848+
849+
bool nvme_ctrl_persistent_get(struct nvme_ctrl *c) {
850+
return nvme_ctrl_is_persistent(c);
851+
}
852+
void nvme_ctrl_persistent_set(struct nvme_ctrl *c, bool persistent) {
853+
nvme_ctrl_set_persistent(c, persistent);
854+
}
855+
856+
const char *nvme_ctrl_phy_slot_get(nvme_ctrl_t c) {
857+
return nvme_ctrl_get_phy_slot(c);
858+
}
859+
860+
const char *nvme_ctrl_trsvcid_get(nvme_ctrl_t c) {
861+
return nvme_ctrl_get_trsvcid(c);
862+
}
863+
864+
const char *nvme_ctrl_traddr_get(nvme_ctrl_t c) {
865+
return nvme_ctrl_get_traddr(c);
866+
}
867+
868+
const char *nvme_ctrl_subsysnqn_get(nvme_ctrl_t c) {
869+
return nvme_ctrl_get_subsysnqn(c);
870+
}
871+
872+
const char *nvme_ctrl_transport_get(nvme_ctrl_t c) {
873+
return nvme_ctrl_get_transport(c);
874+
}
875+
876+
const char *nvme_ctrl_sqsize_get(nvme_ctrl_t c) {
877+
return nvme_ctrl_get_sqsize(c);
878+
}
879+
880+
const char *nvme_ctrl_serial_get(nvme_ctrl_t c) {
881+
return nvme_ctrl_get_serial(c);
882+
}
883+
884+
const char *nvme_ctrl_queue_count_get(nvme_ctrl_t c) {
885+
return nvme_ctrl_get_queue_count(c);
886+
}
887+
888+
const char *nvme_ctrl_numa_node_get(nvme_ctrl_t c) {
889+
return nvme_ctrl_get_numa_node(c);
890+
}
891+
892+
const char *nvme_ctrl_model_get(nvme_ctrl_t c) {
893+
return nvme_ctrl_get_model(c);
894+
}
895+
896+
const char *nvme_ctrl_firmware_get(nvme_ctrl_t c) {
897+
return nvme_ctrl_get_firmware(c);
898+
}
899+
900+
const char *nvme_ctrl_address_get(nvme_ctrl_t c) {
901+
return nvme_ctrl_get_address(c);
902+
}
903+
904+
const char *nvme_ctrl_sysfs_dir_get(nvme_ctrl_t c) {
905+
return nvme_ctrl_get_sysfs_dir(c);
906+
}
907+
908+
bool nvme_ctrl_discovery_ctrl_get(struct nvme_ctrl *c) {
909+
return nvme_ctrl_is_discovery_ctrl(c);
910+
}
911+
void nvme_ctrl_discovery_ctrl_set(struct nvme_ctrl *c, bool discovery) {
912+
nvme_ctrl_set_discovery_ctrl(c, discovery);
913+
}
914+
915+
bool nvme_ctrl_unique_discovery_ctrl_get(nvme_ctrl_t c) {
916+
return nvme_ctrl_is_unique_discovery_ctrl(c);
917+
}
918+
void nvme_ctrl_unique_discovery_ctrl_set(nvme_ctrl_t c, bool unique) {
919+
nvme_ctrl_set_unique_discovery_ctrl(c, unique);
920+
}
921+
922+
const char *nvme_ctrl_keyring_get(nvme_ctrl_t c) {
923+
return nvme_ctrl_get_keyring(c);
924+
}
925+
void nvme_ctrl_keyring_set(nvme_ctrl_t c, const char *keyring) {
926+
nvme_ctrl_set_keyring(c, keyring);
927+
}
928+
929+
const char *nvme_ctrl_tls_key_identity_get(nvme_ctrl_t c) {
930+
return nvme_ctrl_get_tls_key_identity(c);
931+
}
932+
void nvme_ctrl_tls_key_identity_set(nvme_ctrl_t c, const char *identity) {
933+
nvme_ctrl_set_tls_key_identity(c, identity);
934+
}
935+
936+
const char *nvme_ctrl_tls_key_get(nvme_ctrl_t c) {
937+
return nvme_ctrl_get_tls_key(c);
938+
}
939+
void nvme_ctrl_tls_key_set(nvme_ctrl_t c, const char *key) {
940+
nvme_ctrl_set_tls_key(c, key);
941+
}
942+
%}
791943

792944
%pythonappend nvme_ns::nvme_ns(struct nvme_subsystem *s,
793945
unsigned int nsid) {

0 commit comments

Comments
 (0)