-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #78 from raharper/feature/probe-dasd
storage: add dasd prober
- Loading branch information
Showing
6 changed files
with
421 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
# Copyright 2020 Canonical, Ltd. | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
# published by the Free Software Foundation, either version 3 of the | ||
# License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU Affero General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
import logging | ||
import os | ||
import platform | ||
import pyudev | ||
import re | ||
import subprocess | ||
|
||
log = logging.getLogger('probert.dasd') | ||
|
||
DASD_FORMAT = r"^format\s+:.+\s+(?P<format>\w+\s\w+)$" | ||
DASD_BLKSIZE = r"^blocksize\s+:\shex\s\w+\s+dec\s(?P<blksize>\d+)$" | ||
|
||
|
||
def _search(regex, content, groupkey): | ||
m = re.search(regex, content, re.MULTILINE) | ||
if m: | ||
return m.group(groupkey) | ||
|
||
|
||
def blocksize(dasdview_output): | ||
""" Read and return device_id's 'blocksize' value. | ||
:param: device_id: string of device ccw bus_id. | ||
:returns: int: the device's current blocksize. | ||
""" | ||
if not dasdview_output: | ||
return | ||
|
||
blksize = _search(DASD_BLKSIZE, dasdview_output, 'blksize') | ||
if blksize: | ||
return int(blksize) | ||
|
||
|
||
def disk_format(dasdview_output): | ||
""" Read and return specified device "disk_layout" value. | ||
:returns: string: One of ['cdl', 'ldl', 'not-formatted']. | ||
:raises: ValueError if dasdview result missing 'format' section. | ||
""" | ||
if not dasdview_output: | ||
return | ||
|
||
mapping = { | ||
'cdl formatted': 'cdl', | ||
'ldl formatted': 'ldl', | ||
'not formatted': 'not-formatted', | ||
} | ||
diskfmt = _search(DASD_FORMAT, dasdview_output, 'format') | ||
if diskfmt: | ||
return mapping.get(diskfmt.lower()) | ||
|
||
|
||
def dasdview(devname): | ||
''' Run dasdview on devname and return the output. | ||
dasdview --extended has 3 sections | ||
general (2:6), geometry (8:12), extended (14:) | ||
''' | ||
if not os.path.exists(devname): | ||
raise ValueError("Invalid dasd device name: '%s'" % devname) | ||
|
||
cmd = ['dasdview', '--extended', devname] | ||
try: | ||
result = subprocess.run(cmd, stdout=subprocess.PIPE, | ||
stderr=subprocess.DEVNULL) | ||
except (subprocess.CalledProcessError, FileNotFoundError): | ||
log.error('Failed to run cmd: %s', cmd) | ||
return None | ||
|
||
return result.stdout.decode('utf-8') | ||
|
||
|
||
def get_dasd_info(device): | ||
""" from a udev blockdev device entry, return all required dasd info | ||
""" | ||
name = device.get('DEVNAME') | ||
device_id = device.get('ID_PATH', '').replace('ccw-', '') | ||
dasdview_output = dasdview(name) | ||
diskfmt = disk_format(dasdview_output) | ||
blksize = blocksize(dasdview_output) | ||
if not all([name, device_id, diskfmt, blksize]): | ||
vals = ("name=%s device_id=%s format=%s blksize=%s" % ( | ||
name, device_id, diskfmt, blksize)) | ||
log.debug('Failed to probe some DASD values: %s', vals) | ||
return None | ||
|
||
return {'name': name, 'device_id': device_id, | ||
'disk_layout': diskfmt, 'blocksize': blksize} | ||
|
||
|
||
def probe(context=None): | ||
"""Examine all dasd devices present and extract configuration attributes | ||
This data is useful for determining if the dasd device has been | ||
formatted, if so what the block size, the partition layout used | ||
and the s390x device_id used to uniquely identify the device. | ||
""" | ||
log.debug('Probing DASD devies') | ||
machine = platform.machine() | ||
if machine != "s390x": | ||
log.debug('DASD devices only present on s390x, arch=%s', machine) | ||
return {} | ||
|
||
dasds = {} | ||
if not context: | ||
context = pyudev.Context() | ||
|
||
for device in context.list_devices(subsystem='block'): | ||
# dasd devices have MAJOR 94 | ||
if device['MAJOR'] != "94": | ||
continue | ||
# ignore dasd partitions | ||
if 'PARTN' in device: | ||
continue | ||
|
||
try: | ||
dasd_info = get_dasd_info(device) | ||
except ValueError as e: | ||
log.error('Error probing dasd device %s: %s', device['DEVNAME'], e) | ||
dasd_info = None | ||
|
||
if dasd_info: | ||
dasds[device['DEVNAME']] = dasd_info | ||
|
||
return dasds |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
|
||
--- general DASD information -------------------------------------------------- | ||
device node : /dev/dasdd | ||
busid : 0.0.1544 | ||
type : ECKD | ||
device type : hex 3390 dec 13200 | ||
|
||
--- DASD geometry ------------------------------------------------------------- | ||
number of cylinders : hex 7563 dec 30051 | ||
tracks per cylinder : hex f dec 15 | ||
blocks per track : hex c dec 12 | ||
blocksize : hex 1000 dec 4096 | ||
|
||
--- extended DASD information ------------------------------------------------- | ||
real device number : hex 0 dec 0 | ||
subchannel identifier : hex 1a4 dec 420 | ||
CU type (SenseID) : hex 3990 dec 14736 | ||
CU model (SenseID) : hex e9 dec 233 | ||
device type (SenseID) : hex 3390 dec 13200 | ||
device model (SenseID) : hex c dec 12 | ||
open count : hex 2 dec 2 | ||
req_queue_len : hex 0 dec 0 | ||
chanq_len : hex 0 dec 0 | ||
status : hex 5 dec 5 | ||
label_block : hex 2 dec 2 | ||
FBA_layout : hex 0 dec 0 | ||
characteristics_size : hex 40 dec 64 | ||
confdata_size : hex 100 dec 256 | ||
format : hex 2 dec 2 CDL formatted | ||
features : hex 0 dec 0 default | ||
|
||
characteristics : 3990e933 900c5e0c 39f72032 7563000f | ||
e000e5a2 05940222 13090674 00000000 | ||
00000000 00000000 32321502 dfee0001 | ||
0677080f 007f4800 1f3c0000 00007563 | ||
|
||
configuration_data : dc010100 f0f0f2f1 f0f7f9f0 f0c9c2d4 | ||
f7f5f0f0 f0f0f0f0 f0c4e7d7 f7f10844 | ||
d4020000 f0f0f2f1 f0f7f9f6 f1c9c2d4 | ||
f7f5f0f0 f0f0f0f0 f0c4e7d7 f7f10800 | ||
d0000000 f0f0f2f1 f0f7f9f6 f1c9c2d4 | ||
f7f5f0f0 f0f0f0f0 f0c4e7d7 f7f00800 | ||
f0000001 f0f0f2f1 f0f7f9f0 f0c9c2d4 | ||
f7f5f0f0 f0f0f0f0 f0c4e7d7 f7f10800 | ||
00000000 00000000 00000000 00000000 | ||
00000000 00000000 00000000 00000000 | ||
00000000 00000000 00000000 00000000 | ||
00000000 00000000 00000000 00000000 | ||
00000000 00000000 00000000 00000000 | ||
00000000 00000000 00000000 00000000 | ||
81000003 2d001e00 15000247 000c0016 | ||
000cc044 0a0f61ca 00030000 0000a000 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
|
||
--- general DASD information -------------------------------------------------- | ||
device node : /dev/dasde | ||
busid : 0.0.2520 | ||
type : ECKD | ||
device type : hex 3390 dec 13200 | ||
|
||
--- DASD geometry ------------------------------------------------------------- | ||
number of cylinders : hex 2721 dec 10017 | ||
tracks per cylinder : hex f dec 15 | ||
blocks per track : hex 0 dec 0 | ||
blocksize : hex 200 dec 512 | ||
|
||
--- extended DASD information ------------------------------------------------- | ||
real device number : hex 0 dec 0 | ||
subchannel identifier : hex 5e0 dec 1504 | ||
CU type (SenseID) : hex 3990 dec 14736 | ||
CU model (SenseID) : hex e9 dec 233 | ||
device type (SenseID) : hex 3390 dec 13200 | ||
device model (SenseID) : hex c dec 12 | ||
open count : hex 1 dec 1 | ||
req_queue_len : hex 0 dec 0 | ||
chanq_len : hex 0 dec 0 | ||
status : hex 3 dec 3 | ||
label_block : hex 2 dec 2 | ||
FBA_layout : hex 1 dec 1 | ||
characteristics_size : hex 40 dec 64 | ||
confdata_size : hex 100 dec 256 | ||
format : hex 0 dec 0 NOT formatted | ||
features : hex 0 dec 0 default | ||
|
||
characteristics : 3990e933 900c5e0c 39f72032 2721000f | ||
e000e5a2 05940222 13090674 00000000 | ||
00000000 00000000 32321502 dfee0001 | ||
0677080f 007f4800 1f3c0000 00002721 | ||
|
||
configuration_data : dc010100 f0f0f2f1 f0f7f9f0 f0c9c2d4 | ||
f7f5f0f0 f0f0f0f0 f0c4e7d7 f7f10920 | ||
d4020000 f0f0f2f1 f0f7f9f6 f1c9c2d4 | ||
f7f5f0f0 f0f0f0f0 f0c4e7d7 f7f10900 | ||
d0000000 f0f0f2f1 f0f7f9f6 f1c9c2d4 | ||
f7f5f0f0 f0f0f0f0 f0c4e7d7 f7f00900 | ||
f0000001 f0f0f2f1 f0f7f9f0 f0c9c2d4 | ||
f7f5f0f0 f0f0f0f0 f0c4e7d7 f7f10900 | ||
00000000 00000000 00000000 00000000 | ||
00000000 00000000 00000000 00000000 | ||
00000000 00000000 00000000 00000000 | ||
00000000 00000000 00000000 00000000 | ||
00000000 00000000 00000000 00000000 | ||
00000000 00000000 00000000 00000000 | ||
81000003 2d001e00 25000246 000c0016 | ||
000cc020 84228958 00030000 0000a000 |
Oops, something went wrong.