/[smeserver]/cdrom.image/sme9/updates/storage/udev.py
ViewVC logotype

Contents of /cdrom.image/sme9/updates/storage/udev.py

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Sun Dec 22 04:27:51 2013 UTC (10 years, 7 months ago) by wellsi
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-python
FILE REMOVED
anaconda updates now handled via patches

1 # udev.py
2 # Python module for querying the udev database for device information.
3 #
4 # Copyright (C) 2009 Red Hat, Inc.
5 #
6 # This copyrighted material is made available to anyone wishing to use,
7 # modify, copy, or redistribute it subject to the terms and conditions of
8 # the GNU General Public License v.2, or (at your option) any later version.
9 # This program is distributed in the hope that it will be useful, but WITHOUT
10 # ANY WARRANTY expressed or implied, including the implied warranties of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
12 # Public License for more details. You should have received a copy of the
13 # GNU General Public License along with this program; if not, write to the
14 # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 # 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
16 # source code or documentation are not subject to the GNU General Public
17 # License and may only be used or replicated with the express permission of
18 # Red Hat, Inc.
19 #
20 # Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
21 #
22
23 import os
24 import re
25
26 import iutil
27 from errors import *
28 from baseudev import *
29
30 import logging
31 log = logging.getLogger("storage")
32
33 def udev_resolve_devspec(devspec):
34 if not devspec:
35 return None
36
37 import devices as _devices
38 ret = None
39 for dev in udev_get_block_devices():
40 if devspec.startswith("LABEL="):
41 if udev_device_get_label(dev) == devspec[6:]:
42 ret = dev
43 break
44 elif devspec.startswith("UUID="):
45 if udev_device_get_uuid(dev) == devspec[5:]:
46 ret = dev
47 break
48 elif udev_device_get_name(dev) == _devices.devicePathToName(devspec):
49 ret = dev
50 break
51 else:
52 spec = devspec
53 if not spec.startswith("/dev/"):
54 spec = os.path.normpath("/dev/" + spec)
55
56 for link in dev["symlinks"]:
57 if spec == link:
58 ret = dev
59 break
60
61 del _devices
62 if ret:
63 return udev_device_get_name(ret)
64
65 def udev_resolve_glob(glob):
66 import fnmatch
67 ret = []
68
69 if not glob:
70 return ret
71
72 for dev in udev_get_block_devices():
73 name = udev_device_get_name(dev)
74
75 if fnmatch.fnmatch(name, glob):
76 ret.append(name)
77 else:
78 for link in dev["symlinks"]:
79 if fnmatch.fnmatch(link, glob):
80 ret.append(name)
81
82 return ret
83
84 def udev_get_block_devices():
85 # Wait for scsi adapters to be done with scanning their busses (#583143)
86 iutil.execWithRedirect("modprobe", [ "scsi_wait_scan" ],
87 stdout = "/dev/tty5", stderr="/dev/tty5")
88 iutil.execWithRedirect("rmmod", [ "scsi_wait_scan" ],
89 stdout = "/dev/tty5", stderr="/dev/tty5")
90 udev_settle()
91 entries = []
92 for path in udev_enumerate_block_devices():
93 entry = udev_get_block_device(path)
94 if entry:
95 if entry["name"].startswith("md"):
96 # mdraid is really braindead, when a device is stopped
97 # it is no longer usefull in anyway (and we should not
98 # probe it) yet it still sticks around, see bug rh523387
99 state = None
100 state_file = "/sys/%s/md/array_state" % entry["sysfs_path"]
101 if os.access(state_file, os.R_OK):
102 state = open(state_file).read().strip()
103 if state == "clear":
104 continue
105 entries.append(entry)
106 return entries
107
108 def __is_blacklisted_blockdev(dev_name):
109 """Is this a blockdev we never want for an install?"""
110 if dev_name.startswith("loop") or dev_name.startswith("ram") or dev_name.startswith("fd"):
111 return True
112
113 if os.path.exists("/sys/class/block/%s/device/model" %(dev_name,)):
114 model = open("/sys/class/block/%s/device/model" %(dev_name,)).read()
115 for bad in ("IBM *STMF KERNEL", "SCEI Flash-5", "DGC LUNZ"):
116 if model.find(bad) != -1:
117 log.info("ignoring %s with model %s" %(dev_name, model))
118 return True
119
120 return False
121
122 def udev_enumerate_block_devices():
123 import os.path
124
125 return filter(lambda d: not __is_blacklisted_blockdev(os.path.basename(d)),
126 udev_enumerate_devices(deviceClass="block"))
127
128 def udev_get_block_device(sysfs_path):
129 dev = udev_get_device(sysfs_path)
130 if not dev or not dev.has_key("name"):
131 return None
132 else:
133 return dev
134
135 def udev_parse_block_entry(buf):
136 dev = udev_parse_entry(buf)
137
138 for (key, value) in dev.iteritems():
139 if value.count(" "):
140 # eg: DEVLINKS
141 dev.update({key: value.split()})
142
143 return dev
144
145
146 # These are functions for retrieving specific pieces of information from
147 # udev database entries.
148 def udev_device_get_name(udev_info):
149 """ Return the best name for a device based on the udev db data. """
150 return udev_info.get("DM_NAME", udev_info["name"])
151
152 def udev_device_get_format(udev_info):
153 """ Return a device's format type as reported by udev. """
154 return udev_info.get("ID_FS_TYPE")
155
156 def udev_device_get_uuid(udev_info):
157 """ Get the UUID from the device's format as reported by udev. """
158 md_uuid = udev_info.get("MD_UUID", '')
159 uuid = udev_info.get("ID_FS_UUID", '')
160 # we don't want to return the array's uuid as a member's uuid
161 if len(uuid) > 0 and \
162 re.sub(r'\W', '', md_uuid) != re.sub(r'\W', '', uuid):
163 return udev_info.get("ID_FS_UUID")
164
165 def udev_device_get_label(udev_info):
166 """ Get the label from the device's format as reported by udev. """
167 return udev_info.get("ID_FS_LABEL")
168
169 def udev_device_is_dm(info):
170 """ Return True if the device is a device-mapper device. """
171 return info.has_key("DM_NAME")
172
173 def udev_device_is_md(info):
174 """ Return True if the device is a mdraid array device. """
175 # Don't identify partitions on mdraid arrays as raid arrays
176 if udev_device_is_partition(info):
177 return False
178 # isw raid set *members* have MD_METADATA set, but are not arrays!
179 return info.has_key("MD_METADATA") and \
180 info.get("ID_FS_TYPE") != "isw_raid_member"
181
182 def udev_device_is_cciss(info):
183 """ Return True if the device is a CCISS device. """
184 return udev_device_get_name(info).startswith("cciss")
185
186 def udev_device_is_dasd(info):
187 """ Return True if the device is a dasd device. """
188 devname = info.get("DEVNAME")
189 if devname:
190 return devname.startswith("dasd")
191 else:
192 return False
193
194 def udev_device_is_zfcp(info):
195 """ Return True if the device is a zfcp device. """
196 if info.get("DEVTYPE") != "disk":
197 return False
198
199 subsystem = "/sys" + info.get("sysfs_path")
200
201 while True:
202 topdir = os.path.realpath(os.path.dirname(subsystem))
203 driver = "%s/driver" % (topdir,)
204
205 if os.path.islink(driver):
206 subsystemname = os.path.basename(os.readlink(subsystem))
207 drivername = os.path.basename(os.readlink(driver))
208
209 if subsystemname == 'ccw' and drivername == 'zfcp':
210 return True
211
212 newsubsystem = os.path.dirname(topdir)
213
214 if newsubsystem == topdir:
215 break
216
217 subsystem = newsubsystem + "/subsystem"
218
219 return False
220
221 def udev_device_get_zfcp_attribute(info, attr=None):
222 """ Return the value of the specified attribute of the zfcp device. """
223 if not attr:
224 log.debug("udev_device_get_zfcp_attribute() called with attr=None")
225 return None
226
227 attribute = "/sys%s/device/%s" % (info.get("sysfs_path"), attr,)
228 attribute = os.path.realpath(attribute)
229
230 if not os.path.isfile(attribute):
231 log.warning("%s is not a valid zfcp attribute" % (attribute,))
232 return None
233
234 return open(attribute, "r").read().strip()
235
236 def udev_device_get_dasd_bus_id(info):
237 """ Return the CCW bus ID of the dasd device. """
238 return info.get("sysfs_path").split("/")[-3]
239
240 def udev_device_get_dasd_flag(info, flag=None):
241 """ Return the specified flag for the dasd device. """
242 if flag is None:
243 return None
244
245 path = "/sys" + info.get("sysfs_path") + "/device/" + flag
246 if not os.path.isfile(path):
247 return None
248
249 return open(path, 'r').read().strip()
250
251 def udev_device_is_cdrom(info):
252 """ Return True if the device is an optical drive. """
253 # FIXME: how can we differentiate USB drives from CD-ROM drives?
254 # -- USB drives also generate a sdX device.
255 return info.get("ID_CDROM") == "1"
256
257 def udev_device_is_disk(info):
258 """ Return True is the device is a disk. """
259 if udev_device_is_cdrom(info):
260 return False
261 has_range = os.path.exists("/sys/%s/range" % info['sysfs_path'])
262 return info.get("DEVTYPE") == "disk" or has_range
263
264 def udev_device_is_partition(info):
265 has_start = os.path.exists("/sys/%s/start" % info['sysfs_path'])
266 return info.get("DEVTYPE") == "partition" or has_start
267
268 def udev_device_get_serial(udev_info):
269 """ Get the serial number/UUID from the device as reported by udev. """
270 return udev_info.get("ID_SERIAL_RAW", udev_info.get("ID_SERIAL_SHORT", udev_info.get("ID_SERIAL")))
271
272 def udev_device_get_wwid(udev_info):
273 """ The WWID of a device is typically just its serial number, but with
274 colons in the name to make it more readable. """
275 def insert_colons(a_string):
276 suffix = a_string[-2:]
277 if len(a_string) > 2:
278 return insert_colons(a_string[:-2]) + ':' + suffix
279 else:
280 return suffix
281
282 serial = udev_device_get_serial(udev_info)
283 return insert_colons(serial) if serial else ""
284
285 def udev_device_get_vendor(udev_info):
286 """ Get the vendor of the device as reported by udev. """
287 return udev_info.get("ID_VENDOR_FROM_DATABASE", udev_info.get("ID_VENDOR"))
288
289 def udev_device_get_model(udev_info):
290 """ Get the model of the device as reported by udev. """
291 return udev_info.get("ID_MODEL_FROM_DATABASE", udev_info.get("ID_MODEL"))
292
293 def udev_device_get_bus(udev_info):
294 """ Get the bus a device is connected to the system by. """
295 return udev_info.get("ID_BUS", "").upper()
296
297 def udev_device_get_path(info):
298 return info["ID_PATH"]
299
300 def udev_device_get_by_path(info):
301 if info.has_key('symlinks'):
302 for link in info['symlinks']:
303 if link.startswith('/dev/disk/by-path/'):
304 return link
305
306 return udev_device_get_name(info)
307
308 def udev_device_get_sysfs_path(info):
309 return info['sysfs_path']
310
311 def udev_device_get_major(info):
312 return int(info["MAJOR"])
313
314 def udev_device_get_minor(info):
315 return int(info["MINOR"])
316
317 def udev_device_get_md_level(info):
318 return info.get("MD_LEVEL")
319
320 def udev_device_get_md_devices(info):
321 return int(info["MD_DEVICES"])
322
323 def udev_device_get_md_uuid(info):
324 return info["MD_UUID"]
325
326 def udev_device_get_md_container(info):
327 return info.get("MD_CONTAINER")
328
329 def udev_device_get_md_name(info):
330 return info.get("MD_DEVNAME")
331
332 def udev_device_get_vg_name(info):
333 return info['LVM2_VG_NAME']
334
335 def udev_device_get_vg_uuid(info):
336 return info['LVM2_VG_UUID']
337
338 def udev_device_get_vg_size(info):
339 # lvm's decmial precision is not configurable, so we tell it to use
340 # KB and convert to MB here
341 return float(info['LVM2_VG_SIZE']) / 1024
342
343 def udev_device_get_vg_free(info):
344 # lvm's decmial precision is not configurable, so we tell it to use
345 # KB and convert to MB here
346 return float(info['LVM2_VG_FREE']) / 1024
347
348 def udev_device_get_vg_extent_size(info):
349 # lvm's decmial precision is not configurable, so we tell it to use
350 # KB and convert to MB here
351 return float(info['LVM2_VG_EXTENT_SIZE']) / 1024
352
353 def udev_device_get_vg_extent_count(info):
354 return int(info['LVM2_VG_EXTENT_COUNT'])
355
356 def udev_device_get_vg_free_extents(info):
357 return int(info['LVM2_VG_FREE_COUNT'])
358
359 def udev_device_get_vg_pv_count(info):
360 return int(info['LVM2_PV_COUNT'])
361
362 def udev_device_get_pv_pe_start(info):
363 # lvm's decmial precision is not configurable, so we tell it to use
364 # KB and convert to MB here
365 return float(info['LVM2_PE_START']) / 1024
366
367 def udev_device_get_lv_names(info):
368 names = info['LVM2_LV_NAME']
369 if not names:
370 names = []
371 elif not isinstance(names, list):
372 names = [names]
373 return names
374
375 def udev_device_get_lv_uuids(info):
376 uuids = info['LVM2_LV_UUID']
377 if not uuids:
378 uuids = []
379 elif not isinstance(uuids, list):
380 uuids = [uuids]
381 return uuids
382
383 def udev_device_get_lv_sizes(info):
384 # lvm's decmial precision is not configurable, so we tell it to use
385 # KB and convert to MB here
386 sizes = info['LVM2_LV_SIZE']
387 if not sizes:
388 sizes = []
389 elif not isinstance(sizes, list):
390 sizes = [sizes]
391
392 return [float(s) / 1024 for s in sizes]
393
394 def udev_device_get_lv_attr(info):
395 attr = info['LVM2_LV_ATTR']
396 if not attr:
397 attr = []
398 elif not isinstance(attr, list):
399 attr = [attr]
400 return attr
401
402 def udev_device_dm_subsystem_match(info, subsystem):
403 """ Return True if the device matches a given device-mapper subsystem. """
404 uuid = info.get("DM_UUID", "")
405 uuid_fields = uuid.split("-")
406 _subsystem = uuid_fields[0]
407 if _subsystem.lower().startswith("part") and len(uuid_fields) > 1:
408 # kpartx uses partN- as a subsystem prefix, which we ignore because
409 # we only care about the subsystem of the partitions' parent device.
410 _subsystem = uuid_fields[1]
411
412 if _subsystem == uuid or not _subsystem:
413 return False
414
415 return _subsystem.lower() == subsystem.lower()
416
417 def udev_device_is_dm_lvm(info):
418 """ Return True if the device is an LVM logical volume. """
419 return udev_device_dm_subsystem_match(info, "lvm")
420
421 def udev_device_is_dm_crypt(info):
422 """ Return True if the device is a mapped dm-crypt device. """
423 return udev_device_dm_subsystem_match(info, "crypt")
424
425 def udev_device_is_dm_luks(info):
426 """ Return True if the device is a mapped LUKS device. """
427 is_crypt = udev_device_dm_subsystem_match(info, "crypt")
428 try:
429 _type = info.get("DM_UUID", "").split("-")[1].lower()
430 except IndexError:
431 _type = ""
432
433 return is_crypt and _type.startswith("luks")
434
435 def udev_device_is_dm_raid(info):
436 """ Return True if the device is a dmraid array device. """
437 return udev_device_dm_subsystem_match(info, "dmraid")
438
439 def udev_device_is_dm_mpath(info):
440 """ Return True if the device is a multipath device. """
441 return udev_device_dm_subsystem_match(info, "mpath")
442
443 def udev_device_is_biosraid(info):
444 # Note that this function does *not* identify raid sets.
445 # Tests to see if device is parto of a dmraid set.
446 # dmraid and mdraid have the same ID_FS_USAGE string, ID_FS_TYPE has a
447 # string that describes the type of dmraid (isw_raid_member...), I don't
448 # want to maintain a list and mdraid's ID_FS_TYPE='linux_raid_member', so
449 # dmraid will be everything that is raid and not linux_raid_member
450 from formats.dmraid import DMRaidMember
451 from formats.mdraid import MDRaidMember
452 if info.has_key("ID_FS_TYPE") and \
453 (info["ID_FS_TYPE"] in DMRaidMember._udevTypes or \
454 info["ID_FS_TYPE"] in MDRaidMember._udevTypes) and \
455 info["ID_FS_TYPE"] != "linux_raid_member":
456 return True
457
458 return False
459
460 def udev_device_get_dm_partition_disk(info):
461 try:
462 p_index = info["DM_NAME"].rindex("p")
463 except (KeyError, AttributeError, ValueError):
464 return None
465
466 if not info["DM_NAME"][p_index+1:].isdigit():
467 return None
468
469 return info["DM_NAME"][:p_index]
470
471 def udev_device_is_dm_partition(info):
472 if not udev_device_is_dm(info):
473 return False
474
475 diskname = udev_device_get_dm_partition_disk(info)
476 return diskname not in ("", None)
477
478 def udev_device_is_multipath_member(info):
479 """ Return True if the device is part of a multipath. """
480 return info.get("ID_FS_TYPE") == "multipath_member"
481
482 def udev_device_get_multipath_name(info):
483 """ Return the name of the multipath that the device is a member of. """
484 if udev_device_is_multipath_member(info):
485 return info['ID_MPATH_NAME']
486 return None
487
488 # iscsi disks' ID_PATH form depends on the driver:
489 # for software iscsi:
490 # ip-${iscsi_address}:${iscsi_port}-iscsi-${iscsi_tgtname}-lun-${lun}
491 # for partial offload iscsi:
492 # pci-${pci_address}-ip-${iscsi_address}:${iscsi_port}-iscsi-${iscsi_tgtname}-lun-${lun}
493 # Note that in the case of IPV6 iscsi_address itself can contain :
494 # too, but iscsi_port never contains :
495
496 def udev_device_is_sw_iscsi(info):
497 # software iscsi
498 try:
499 path_components = udev_device_get_path(info).split("-")
500
501 if info["ID_BUS"] == "scsi" and len(path_components) >= 6 and \
502 path_components[0] == "ip" and path_components[2] == "iscsi":
503 return True
504 except KeyError:
505 pass
506
507 return False
508
509 def udev_device_is_partoff_iscsi(info):
510 # partial offload iscsi
511 try:
512 path_components = udev_device_get_path(info).split("-")
513
514 if info["ID_BUS"] == "scsi" and len(path_components) >= 8 and \
515 path_components[2] == "ip" and path_components[4] == "iscsi":
516 return True
517 except KeyError:
518 pass
519
520 return False
521
522 def udev_device_is_iscsi(info):
523 return udev_device_is_sw_iscsi(info) or udev_device_is_partoff_iscsi(info)
524
525 def udev_device_get_iscsi_name(info):
526 name_field = 3
527 if udev_device_is_partoff_iscsi(info):
528 name_field = 5
529
530 path_components = udev_device_get_path(info).split("-")
531
532 # Tricky, the name itself contains atleast 1 - char
533 return "-".join(path_components[name_field:len(path_components)-2])
534
535 def udev_device_get_iscsi_address(info):
536 address_field = 1
537 if udev_device_is_partoff_iscsi(info):
538 address_field = 3
539
540 path_components = udev_device_get_path(info).split("-")
541
542 # IPV6 addresses contain : within the address, so take everything
543 # before the last : as address
544 return ":".join(path_components[address_field].split(":")[:-1])
545
546 def udev_device_get_iscsi_port(info):
547 address_field = 1
548 if udev_device_is_partoff_iscsi(info):
549 address_field = 3
550
551 path_components = udev_device_get_path(info).split("-")
552
553 # IPV6 contains : within the address, the part after the last : is the port
554 return path_components[address_field].split(":")[-1]
555
556 def udev_device_get_iscsi_session(info):
557 # '/devices/pci0000:00/0000:00:02.0/0000:09:00.0/0000:0a:01.0/0000:0e:00.2/host3/session1/target3:0:0/3:0:0:0/block/sda'
558 # The position of sessionX part depends on device
559 # (e.g. offload vs. sw; also varies for different offload devs)
560 session = None
561 match = re.match('/.*/(session\d+)', info["sysfs_path"])
562 if match:
563 session = match.groups()[0]
564 else:
565 log.error("udev_device_get_iscsi_session: session not found in %s" % info)
566 return session
567
568
569 def udev_device_get_iscsi_nic(info):
570 iface = None
571 session = udev_device_get_iscsi_session(info)
572 if session:
573 iface = open("/sys/class/iscsi_session/%s/ifacename" %
574 session).read().strip()
575 return iface
576
577 def udev_device_get_iscsi_initiator(info):
578 initiator = None
579 if udev_device_is_partoff_iscsi(info):
580 host = re.match('.*/(host\d+)', info["sysfs_path"]).groups()[0]
581 if host:
582 initiator_file = "/sys/class/iscsi_host/%s/initiatorname" % host
583 if os.access(initiator_file, os.R_OK):
584 initiator = open(initiator_file).read().strip()
585 if initiator is None:
586 session = udev_device_get_iscsi_session(info)
587 if session:
588 initiator = open("/sys/class/iscsi_session/%s/initiatorname" %
589 session).read().strip()
590 return initiator
591
592
593 # fcoe disks have ID_PATH in the form of:
594 # For FCoE directly over the NIC (so no VLAN and thus no DCB):
595 # pci-eth#-fc-${id}
596 # For FCoE over a VLAN (the DCB case)
597 # fc-${id}
598 # fcoe parts look like this:
599 # pci-eth#-fc-${id}-part#
600 # fc-${id}-part#
601
602 # For the FCoE over VLAN case we also do some checks on the sysfs_path as
603 # the ID_PATH does not contain all info we need there, the sysfs_path for
604 # an fcoe disk over VLAN looks like this:
605 # /devices/virtual/net/eth4.802-fcoe/host3/rport-3:0-4/target3:0:1/3:0:1:0/block/sde
606 # And for a partition:
607 # /devices/virtual/net/eth4.802-fcoe/host3/rport-3:0-4/target3:0:1/3:0:1:0/block/sde/sde1
608
609 # This is completely different for Broadcom FCoE devices (bnx2fc), where we use
610 # the sysfs path:
611 # /devices/pci0000:00/0000:00:02.0/0000:09:00.0/0000:0a:01.0/0000:0e:00.0/host3/rport-3:0-2/target3:0:1/3:0:1:3/block/sdm
612 # and find whether the host has 'fc_host' and if it the device has a bound
613 # Ethernet interface.
614
615 def _detect_broadcom_fcoe(info):
616 re_pci_host=re.compile('/(.*)/(host\d+)')
617 match = re_pci_host.match(info["sysfs_path"])
618 if match:
619 sysfs_pci, host = match.groups()
620 if os.access('/sys/%s/%s/fc_host' %(sysfs_pci, host), os.X_OK) and \
621 os.access('/sys/%s/net' %(sysfs_pci), os.X_OK):
622 return (sysfs_pci, host)
623 return (None, None)
624
625 def udev_device_is_fcoe(info):
626 if info.get("ID_BUS") != "scsi":
627 return False
628
629 path = info.get("ID_PATH", "")
630 path_components = path.split("-")
631
632 if path.startswith("pci-eth") and len(path_components) >= 4 and \
633 path_components[2] == "fc":
634 return True
635
636 if path.startswith("fc-") and "fcoe" in info["sysfs_path"]:
637 return True
638
639 if _detect_broadcom_fcoe(info) != (None, None):
640 return True
641
642 return False
643
644 def udev_device_get_fcoe_nic(info):
645 path = info.get("ID_PATH", "")
646 path_components = path.split("-")
647
648 if path.startswith("pci-eth") and len(path_components) >= 4 and \
649 path_components[2] == "fc":
650 return path_components[1]
651
652 if path.startswith("fc-") and "fcoe" in info["sysfs_path"]:
653 return info["sysfs_path"].split("/")[4].split(".")[0]
654
655 (sysfs_pci, host) = _detect_broadcom_fcoe(info)
656 if (sysfs_pci, host) != (None, None):
657 net_path = '/sys/%s/net' % sysfs_pci
658 listdir = os.listdir(net_path)
659 if len(listdir) > 0 :
660 return listdir[0]
661
662 def udev_device_get_fcoe_identifier(info):
663 path = info.get("ID_PATH", "")
664 path_components = path.split("-")
665
666 if path.startswith("pci-eth") and len(path_components) >= 4 and \
667 path_components[2] == "fc":
668 return path_components[3]
669
670 if path.startswith("fc-") and "fcoe" in info["sysfs_path"]:
671 return path_components[1]
672
673 if udev_device_is_fcoe(info) and len(path_components) >= 4 and \
674 path_components[2] == 'fc':
675 return path_components[3]

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed