Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion libs/sm/drivers/LVHDSR.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ def updateSRMetadata(self, allocation):
for vdi in self.session.xenapi.SR.get_VDIs(self.sr_ref):
vdi_uuid = self.session.xenapi.VDI.get_uuid(vdi)

vdi_type = self.session.xenapi.VDI.get_sm_config(vdi).get('vdi_type')
if not vdi_type:
raise xs_errors.XenError('MetadataError', opterr=f"Missing `vdi_type` for VDI {vdi_uuid}")

# Create the VDI entry in the SR metadata
vdi_info[vdi_uuid] = \
{
Expand All @@ -254,7 +258,7 @@ def updateSRMetadata(self, allocation):
TYPE_TAG: \
self.session.xenapi.VDI.get_type(vdi),
VDI_TYPE_TAG: \
self.session.xenapi.VDI.get_sm_config(vdi)['vdi_type'],
vdi_type,
READ_ONLY_TAG: \
int(self.session.xenapi.VDI.get_read_only(vdi)),
METADATA_OF_POOL_TAG: \
Expand Down
11 changes: 6 additions & 5 deletions libs/sm/srmetadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,13 @@ def buildHeader(length, major=metadata.MD_MAJOR, minor=metadata.MD_MINOR):


def unpackHeader(header):
vals = from_utf8(header).split(HEADER_SEP)
decoded = from_utf8(header)
if len(decoded.rstrip('\x00')) == 0:
raise xs_errors.XenError('MetadataError', opterr='Empty header')
vals = decoded.split(HEADER_SEP)
if len(vals) != 4 or vals[0] != metadata.HDR_STRING:
util.SMlog("Exception unpacking metadata header: "
"Error: Bad header '%s'" % (header))
raise xs_errors.XenError('MetadataError', \
opterr='Bad header')
util.SMlog(f"Exception unpacking metadata header: Error: Bad header {header!r}")
raise xs_errors.XenError('MetadataError', opterr='Bad header')
return (vals[0], vals[1], vals[2], vals[3])


Expand Down
10 changes: 10 additions & 0 deletions tests/test_LVHDSR.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,16 @@ def cmd(args):
self.assertEqual(1, lvm_cache.activate.call_count)
self.assertEqual(1, lvm_cache.deactivate.call_count)

# Act (3)
# This tests SR metadata updates
sr.updateSRMetadata('thick')

# Test that removing vdi_type on a vdi does crash properly
del vdi_data['vdi2_ref']['sm-config']['vdi_type']
with self.assertRaises(Exception):
# Fail on vdi2_ref
sr.updateSRMetadata('thick')

def convert_vdi_to_meta(self, vdi_data):
metadata = {}
for item in vdi_data.items():
Expand Down
37 changes: 37 additions & 0 deletions tests/test_srmetadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import uuid
import unittest
import unittest.mock as mock
from sm.core import xs_errors

from sm.srmetadata import (LVMMetadataHandler, buildHeader, buildXMLSector,
getMetadataLength, unpackHeader, updateLengthInHeader,
Expand All @@ -26,6 +27,42 @@ def test_unpackHeader(self):
self.assertEqual(int(major), 1)
self.assertEqual(int(minor), 2)

def test_unpackHeader_empty(self):
# Given
headers = [b"", b"\x00", b"\x00"]

for header in headers:
# When
with self.assertRaises(xs_errors.SROSError) as error:
unpackHeader(header)

# Then
self.assertEqual(
error.exception.message(),
'Error in Metadata volume operation for SR. [opterr=Empty header]'
)

def test_unpackHeader_bad(self):
# Given
headers = [
b"BAD:4096 :1:2" + (b' ' * 493),
b"BAD:4096 :1:2",
b"XSSM:4096 :1",
b"XSSM:4096 ",
b"XSSM",
]

for header in headers:
# When
with self.assertRaises(xs_errors.SROSError) as error:
unpackHeader(header)

# Then
self.assertEqual(
error.exception.message(),
'Error in Metadata volume operation for SR. [opterr=Bad header]'
)

def test_buildHeader_unpackHeader_roundTrip(self):
# Given
orig_length = 12345
Expand Down