1- #!/usr/bin/env python2.7
1+ #!/usr/bin/env python
22
3- # Copyright 2017 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3+ # Copyright Amazon.com, Inc. and its affiliates. All Rights Reserved.
44#
55# Licensed under the MIT License. See the LICENSE accompanying this file
66# for the specific language governing permissions and limitations under
@@ -13,7 +13,8 @@ the volume.
1313"""
1414
1515import argparse
16- from ctypes import *
16+ from ctypes import Structure , c_uint8 , c_uint16 , \
17+ c_uint32 , c_uint64 , c_char , addressof , sizeof
1718from fcntl import ioctl
1819import sys
1920
@@ -22,6 +23,7 @@ NVME_IOCTL_ADMIN_CMD = 0xC0484E41
2223AMZN_NVME_VID = 0x1D0F
2324AMZN_NVME_EBS_MN = "Amazon Elastic Block Store"
2425
26+
2527class nvme_admin_command (Structure ):
2628 _pack_ = 1
2729 _fields_ = [("opcode" , c_uint8 ), # op code
@@ -41,11 +43,13 @@ class nvme_admin_command(Structure):
4143 ("cdw15" , c_uint32 ),
4244 ("reserved1" , c_uint64 )]
4345
46+
4447class nvme_identify_controller_amzn_vs (Structure ):
4548 _pack_ = 1
4649 _fields_ = [("bdev" , c_char * 32 ), # block device name
4750 ("reserved0" , c_char * (1024 - 32 ))]
4851
52+
4953class nvme_identify_controller_psd (Structure ):
5054 _pack_ = 1
5155 _fields_ = [("mp" , c_uint16 ), # maximum power
@@ -58,6 +62,7 @@ class nvme_identify_controller_psd(Structure):
5862 ("rwl" , c_uint8 ), # relative write latency
5963 ("reserved1" , c_char * 16 )]
6064
65+
6166class nvme_identify_controller (Structure ):
6267 _pack_ = 1
6368 _fields_ = [("vid" , c_uint16 ), # PCI Vendor ID
@@ -77,7 +82,7 @@ class nvme_identify_controller(Structure):
7782 ("lpa" , c_uint8 ), # Log Page Attributes
7883 ("elpe" , c_uint8 ), # Error Log Page Entries
7984 ("npss" , c_uint8 ), # Number of Power States Support
80- ("avscc" , c_uint8 ), # Admin Vendor Specific Command Configuration
85+ ("avscc" , c_uint8 ), # Admin Vendor Specific Command Configuration # noqa
8186 ("reserved1" , c_uint8 * (512 - 265 )),
8287 ("sqes" , c_uint8 ), # Submission Queue Entry Size
8388 ("cqes" , c_uint8 ), # Completion Queue Entry Size
@@ -89,60 +94,64 @@ class nvme_identify_controller(Structure):
8994 ("vwc" , c_uint8 ), # Volatile Write Cache
9095 ("awun" , c_uint16 ), # Atomic Write Unit Normal
9196 ("awupf" , c_uint16 ), # Atomic Write Unit Power Fail
92- ("nvscc" , c_uint8 ), # NVM Vendor Specific Command Configuration
97+ ("nvscc" , c_uint8 ), # NVM Vendor Specific Command Configuration # noqa
9398 ("reserved3" , c_uint8 * (704 - 531 )),
9499 ("reserved4" , c_uint8 * (2048 - 704 )),
95- ("psd" , nvme_identify_controller_psd * 32 ), # Power State Descriptor
100+ ("psd" , nvme_identify_controller_psd * 32 ), # Power State Descriptor # noqa
96101 ("vs" , nvme_identify_controller_amzn_vs )] # Vendor Specific
97102
103+
98104class ebs_nvme_device :
99105 def __init__ (self , device ):
100106 self .device = device
101107 self .ctrl_identify ()
102108
103109 def _nvme_ioctl (self , id_response , id_len ):
104- admin_cmd = nvme_admin_command (opcode = NVME_ADMIN_IDENTIFY ,
105- addr = id_response ,
106- alen = id_len ,
107- cdw10 = 1 )
110+ admin_cmd = nvme_admin_command (opcode = NVME_ADMIN_IDENTIFY ,
111+ addr = id_response ,
112+ alen = id_len ,
113+ cdw10 = 1 )
108114
109- with open (self .device , "rw " ) as nvme :
115+ with open (self .device , "r+ " ) as nvme :
110116 ioctl (nvme , NVME_IOCTL_ADMIN_CMD , admin_cmd )
111117
112118 def ctrl_identify (self ):
113119 self .id_ctrl = nvme_identify_controller ()
114120 self ._nvme_ioctl (addressof (self .id_ctrl ), sizeof (self .id_ctrl ))
115121
116- if self .id_ctrl .vid != AMZN_NVME_VID or self .id_ctrl .mn .strip () != AMZN_NVME_EBS_MN :
117- raise TypeError ("[ERROR] Not an EBS device: '{0}'" .format (self .device ))
122+ if self .id_ctrl .vid != AMZN_NVME_VID \
123+ or self .id_ctrl .mn .decode ().strip () != AMZN_NVME_EBS_MN :
124+ raise TypeError ("[ERROR] Not an EBS device: '{0}'" .format (self .device )) # noqa
118125
119126 def get_volume_id (self ):
120- vol = self .id_ctrl .sn
127+ vol = self .id_ctrl .sn . decode ()
121128
122129 if vol .startswith ("vol" ) and vol [3 ] != "-" :
123130 vol = "vol-" + vol [3 :]
124131
125132 return vol
126133
127134 def get_block_device (self , stripped = False ):
128- dev = self .id_ctrl .vs .bdev .strip ()
135+ dev = self .id_ctrl .vs .bdev .decode (). strip ()
129136
130137 if stripped and dev .startswith ("/dev/" ):
131138 dev = dev [5 :]
132139
133140 return dev
134141
142+
135143if __name__ == "__main__" :
136- parser = argparse .ArgumentParser (description = "Reads EBS information from NVMe devices." )
144+ parser = \
145+ argparse .ArgumentParser (description = "Reads EBS information from NVMe devices." ) # noqa
137146 parser .add_argument ("device" , nargs = 1 , help = "Device to query" )
138147
139148 display = parser .add_argument_group ("Display Options" )
140149 display .add_argument ("-v" , "--volume" , action = "store_true" ,
141- help = "Return volume-id" )
150+ help = "Return volume-id" )
142151 display .add_argument ("-b" , "--block-dev" , action = "store_true" ,
143- help = "Return block device mapping" )
152+ help = "Return block device mapping" )
144153 display .add_argument ("-u" , "--udev" , action = "store_true" ,
145- help = "Output data in format suitable for udev rules" )
154+ help = "Output data in format suitable for udev rules" )
146155
147156 if len (sys .argv ) < 2 :
148157 parser .print_help ()
@@ -155,10 +164,10 @@ if __name__ == "__main__":
155164 try :
156165 dev = ebs_nvme_device (args .device [0 ])
157166 except (IOError , TypeError ) as err :
158- print >> sys .stderr , err
167+ print ( err , file = sys .stderr )
159168 sys .exit (1 )
160169
161170 if get_all or args .volume :
162- print "Volume ID: {0}" .format (dev .get_volume_id ())
171+ print ( "Volume ID: {0}" .format (dev .get_volume_id () ))
163172 if get_all or args .block_dev or args .udev :
164- print dev .get_block_device (args .udev )
173+ print ( dev .get_block_device (args .udev ) )
0 commit comments