Use libblkid instead of CLI

This patch changes the get_block_uuid function around
to use libblkid instead of scraping the cli.

Closes-Bug: 1660240
Change-Id: Ieebf5714bceb9d41c70fc1dd0cfd17c903c3a107
This commit is contained in:
Chris Holcombe 2017-01-30 13:11:48 -08:00
parent f11843671b
commit a7f29e52ef
1 changed files with 42 additions and 12 deletions

View File

@ -11,6 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from _ctypes import POINTER, byref
import ctypes import ctypes
import collections import collections
import json import json
@ -309,22 +310,52 @@ def set_hdd_read_ahead(dev_name, read_ahead_sectors=256):
def get_block_uuid(block_dev): def get_block_uuid(block_dev):
""" """
This queries blkid to get the uuid for a block device. This queries blkid to get the uuid for a block device. Note: This function
needs to be called with root priv. It will raise an error otherwise.
:param block_dev: Name of the block device to query. :param block_dev: Name of the block device to query.
:return: The UUID of the device or None on Error. :return: The UUID of the device or None on Error. Raises OSError
""" """
try: try:
block_info = subprocess.check_output( blkid = ctypes.cdll.LoadLibrary("libblkid.so")
['blkid', '-o', 'export', block_dev]) # Header signature
for tag in block_info.split('\n'): # extern int blkid_probe_lookup_value(blkid_probe pr, const char *name,
parts = tag.split('=') # const char **data, size_t *len);
if parts[0] == 'UUID': blkid.blkid_new_probe_from_filename.argtypes = [ctypes.c_char_p]
return parts[1] blkid.blkid_probe_lookup_value.argtypes = [ctypes.c_void_p,
return None ctypes.c_char_p,
except subprocess.CalledProcessError as err: POINTER(ctypes.c_char_p),
log('get_block_uuid failed with error: {}'.format(err.output), POINTER(ctypes.c_ulong)]
except OSError as err:
log('get_block_uuid loading libblkid.so failed with error: {}'.format(
os.strerror(err.errno)),
level=ERROR) level=ERROR)
raise err
if not os.path.exists(block_dev):
return None return None
probe = blkid.blkid_new_probe_from_filename(ctypes.c_char_p(block_dev))
if probe < 0:
log('get_block_uuid new_probe_from_filename failed: {}'.format(
os.strerror(probe)),
level=ERROR)
raise OSError(probe, os.strerror(probe))
result = blkid.blkid_do_probe(probe)
if result != 0:
log('get_block_uuid do_probe failed with error: {}'.format(
os.strerror(result)),
level=ERROR)
raise OSError(result, os.strerror(result))
uuid = ctypes.c_char_p()
result = blkid.blkid_probe_lookup_value(probe,
ctypes.c_char_p(
'UUID'.encode('ascii')),
byref(uuid), None)
if result < 0:
log('get_block_uuid lookup_value failed with error: {}'.format(
os.strerror(result)),
level=ERROR)
raise OSError(result, os.strerror(result))
blkid.blkid_free_probe(probe)
return ctypes.string_at(uuid).decode('ascii')
def check_max_sectors(save_settings_dict, def check_max_sectors(save_settings_dict,
@ -1615,7 +1646,6 @@ def list_pools(service):
log("rados lspools failed with error: {}".format(err.output)) log("rados lspools failed with error: {}".format(err.output))
raise raise
# A dict of valid ceph upgrade paths. Mapping is old -> new # A dict of valid ceph upgrade paths. Mapping is old -> new
UPGRADE_PATHS = { UPGRADE_PATHS = {
'firefly': 'hammer', 'firefly': 'hammer',