Skip to content

Commit 6946570

Browse files
klmp200Wescoeur
authored andcommitted
metadata: improve error messages when vdi_type is missing
Explicit error message pointing to missing vdi_type on SRMetadata update Add a distinction for unpacking corrupted empty metadata headers for easier diagnostic Signed-off-by: Antoine Bartuccio <antoine.bartuccio@vates.tech>
1 parent da3b5b5 commit 6946570

File tree

4 files changed

+58
-6
lines changed

4 files changed

+58
-6
lines changed

drivers/LVHDSR.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ def updateSRMetadata(self, allocation):
246246
for vdi in self.session.xenapi.SR.get_VDIs(self.sr_ref):
247247
vdi_uuid = self.session.xenapi.VDI.get_uuid(vdi)
248248

249+
vdi_type = self.session.xenapi.VDI.get_sm_config(vdi).get('vdi_type')
250+
if not vdi_type:
251+
raise xs_errors.XenError('MetadataError', opterr=f"Missing `vdi_type` for VDI {vdi_uuid}")
252+
249253
# Create the VDI entry in the SR metadata
250254
vdi_info[vdi_uuid] = \
251255
{
@@ -261,7 +265,7 @@ def updateSRMetadata(self, allocation):
261265
TYPE_TAG: \
262266
self.session.xenapi.VDI.get_type(vdi),
263267
VDI_TYPE_TAG: \
264-
self.session.xenapi.VDI.get_sm_config(vdi)['vdi_type'],
268+
vdi_type,
265269
READ_ONLY_TAG: \
266270
int(self.session.xenapi.VDI.get_read_only(vdi)),
267271
METADATA_OF_POOL_TAG: \

drivers/srmetadata.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,13 @@ def buildHeader(length, major=metadata.MD_MAJOR, minor=metadata.MD_MINOR):
178178

179179

180180
def unpackHeader(header):
181-
vals = from_utf8(header).split(HEADER_SEP)
181+
decoded = from_utf8(header)
182+
if len(decoded.rstrip('\x00')) == 0:
183+
raise xs_errors.XenError('MetadataError', opterr='Empty header')
184+
vals = decoded.split(HEADER_SEP)
182185
if len(vals) != 4 or vals[0] != metadata.HDR_STRING:
183-
util.SMlog("Exception unpacking metadata header: "
184-
"Error: Bad header '%s'" % (header))
185-
raise xs_errors.XenError('MetadataError', \
186-
opterr='Bad header')
186+
util.SMlog(f"Exception unpacking metadata header: Error: Bad header {header!r}")
187+
raise xs_errors.XenError('MetadataError', opterr='Bad header')
187188
return (vals[0], vals[1], vals[2], vals[3])
188189

189190

tests/test_LVHDSR.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,16 @@ def cmd(args):
276276
self.assertEqual(1, lvm_cache.activate.call_count)
277277
self.assertEqual(1, lvm_cache.deactivate.call_count)
278278

279+
# Act (3)
280+
# This tests SR metadata updates
281+
sr.updateSRMetadata('thick')
282+
283+
# Test that removing vdi_type on a vdi does crash properly
284+
del vdi_data['vdi2_ref']['sm-config']['vdi_type']
285+
with self.assertRaises(Exception):
286+
# Fail on vdi2_ref
287+
sr.updateSRMetadata('thick')
288+
279289
def convert_vdi_to_meta(self, vdi_data):
280290
metadata = {}
281291
for item in vdi_data.items():

tests/test_srmetadata.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import uuid
66
import unittest
77
import unittest.mock as mock
8+
from sm.core import xs_errors
89

910
from srmetadata import (LVMMetadataHandler, buildHeader, buildXMLSector,
1011
getMetadataLength, unpackHeader, updateLengthInHeader,
@@ -25,6 +26,42 @@ def test_unpackHeader(self):
2526
self.assertEqual(int(major), 1)
2627
self.assertEqual(int(minor), 2)
2728

29+
def test_unpackHeader_empty(self):
30+
# Given
31+
headers = [b"", b"\x00", b"\x00"]
32+
33+
for header in headers:
34+
# When
35+
with self.assertRaises(xs_errors.SROSError) as error:
36+
unpackHeader(header)
37+
38+
# Then
39+
self.assertEqual(
40+
error.exception.message(),
41+
'Error in Metadata volume operation for SR. [opterr=Empty header]'
42+
)
43+
44+
def test_unpackHeader_bad(self):
45+
# Given
46+
headers = [
47+
b"BAD:4096 :1:2" + (b' ' * 493),
48+
b"BAD:4096 :1:2",
49+
b"XSSM:4096 :1",
50+
b"XSSM:4096 ",
51+
b"XSSM",
52+
]
53+
54+
for header in headers:
55+
# When
56+
with self.assertRaises(xs_errors.SROSError) as error:
57+
unpackHeader(header)
58+
59+
# Then
60+
self.assertEqual(
61+
error.exception.message(),
62+
'Error in Metadata volume operation for SR. [opterr=Bad header]'
63+
)
64+
2865
def test_buildHeader_unpackHeader_roundTrip(self):
2966
# Given
3067
orig_length = 12345

0 commit comments

Comments
 (0)