1616
1717from virttest import virsh
1818from virttest import libvirt_version
19+ from virttest import data_dir
20+ from virttest import utils_disk
1921
2022from virttest .libvirt_xml import vm_xml
2123from virttest .libvirt_xml .devices import disk
2224from virttest .utils_test import libvirt
25+ from virttest .utils_libvirt import libvirt_disk
26+
2327
2428virsh_dargs = {"ignore_status" : False , "shell" : True }
2529
2630
2731def run (test , params , env ):
2832 """
29- Make disk produce I/O error due to "message", then check the error
33+ Make disk produce I/O error due to "message" or "enospc" , then check the error
3034 in "virsh event", vm log and "virsh dominfo"
3135
3236 Note: "message" is a kind of I/O error reason. It means that the hypervisor
3337 reported a string description of the I/O error. The errors are usually logged
3438 into the domain log file or the last instance of the error string can be
3539 queried via virDomainGetMessages().
40+ "enospc" means the host filesystem is full.
3641 """
3742
3843 def setup_test ():
3944 """
40- Prepare one error device mapper。
45+ Prepare env for test.
4146 """
4247 test .log .info ("Setup env." )
43- process .run (prepare_file , ** virsh_dargs )
44- # Find a free loop device
45- global free_loop_dev
46- free_loop_dev = process .run ("losetup --find" , ** virsh_dargs ).stdout_text .strip ()
47- # Setup a loop device and create error device mapper
48- process .run ('losetup %s %s' % (free_loop_dev , device_manager_path ), ** virsh_dargs )
49- dm_table = """0 261144 linear %s 0
50- 261144 5 error
51- 261149 787427 linear %s 261139""" % (free_loop_dev , free_loop_dev )
52- try :
53- subprocess .run (["sudo" , "dmsetup" , "create" , device_manager ],
54- input = dm_table .encode ('utf-8' ), stderr = subprocess .PIPE , check = True )
55- except subprocess .CalledProcessError as e :
56- test .log .debug ("create device manager failed :%s" , e .stderr .decode ('utf-8' ))
48+ if enospc_test :
49+ process .run (prepare_file , ** virsh_dargs )
50+ else :
51+ process .run (prepare_file , ** virsh_dargs )
52+ # Find a free loop device
53+ global free_loop_dev
54+ free_loop_dev = process .run ("losetup --find" , ** virsh_dargs ).stdout_text .strip ()
55+ # Setup a loop device and create error device mapper
56+ process .run ('losetup %s %s' % (free_loop_dev , device_manager_path ),
57+ ** virsh_dargs )
58+ dm_table = """0 261144 linear %s 0
59+ 261144 5 error
60+ 261149 787427 linear %s 261139""" % (free_loop_dev , free_loop_dev )
61+ try :
62+ subprocess .run (["sudo" , "dmsetup" , "create" , device_manager ],
63+ input = dm_table .encode ('utf-8' ), stderr = subprocess .PIPE , check = True )
64+ except subprocess .CalledProcessError as e :
65+ test .log .debug ("create device manager failed :%s" , e .stderr .decode ('utf-8' ))
5766
5867 def run_test ():
5968 """
6069 Attach disk and check error message.
6170 """
71+ nonlocal session
6272 test .log .info ("TEST_STEP1: Attach a new disk" )
6373 vm .start ()
6474 session = vm .wait_for_login ()
6575 new_disk = disk .Disk ()
6676 new_disk .setup_attrs (** disk_dict )
6777 virsh .attach_device (vm_name , new_disk .xml , flagstr = "--current" ,
6878 wait_for_event = True , event_timeout = 100 , ** virsh_dargs )
79+ test .log .debug ("The current guest xml is: %s" % virsh .dumpxml (vm_name ).stdout_text )
6980
7081 test .log .info ("TEST_STEP2: Write file in guest and check I/O error message." )
7182 virsh_session = virsh .EventTracker .start_get_event (vm_name )
7283 try :
73- output = session .cmd (dd_in_guest )
84+ if enospc_test :
85+ disk_name = libvirt_disk .get_non_root_disk_name (session )[0 ]
86+ utils_disk .dd_data_to_vm_disk (session , "/dev/%s" % disk_name )
87+ else :
88+ session .cmd (dd_in_guest )
7489 except Exception as e :
7590 if dd_msg not in str (e ):
76- test .fail ("Write data in guest should produce error: %s in %s" % (dd_msg , output ))
91+ test .fail ("Write data in guest should produce error: %s in %s"
92+ % (dd_msg , str (e )))
93+ elif dd_msg in str (e ):
94+ test .log .debug ("Get expected error: %s in %s" % (dd_msg , str (e )))
7795 else :
78- test .fail ("Except error: in %s" % output )
96+ test .fail ("Get unexpected result!" )
7997
8098 test .log .info ("TEST_STEP3: Check event output." )
8199 event_output = virsh .EventTracker .finish_get_event (virsh_session )
@@ -87,6 +105,12 @@ def run_test():
87105 if not libvirt .check_logfile (guest_log_msg , qemu_log , str_in_log = True ):
88106 test .fail ('Find unexpected error:%s in log file:%s' % (guest_log_msg , qemu_log ))
89107
108+ if with_snapshot :
109+ test .log .info ("TEST_STEP6: Create disk snapshot and check I/O error." )
110+ snapshot_file = os .path .join (data_dir .get_data_dir (), "vdb.snap" )
111+ snap_options = ("%s --diskspec %s,snapshot=external,file=%s --disk-only"
112+ % (snapshot_name , disk_name , snapshot_file ))
113+ virsh .snapshot_create_as (vm_name , snap_options , debug = True )
90114 test .log .info ("TEST_STEP5: Check about I/O error in virsh domain info." )
91115 dominfo = virsh .dominfo (vm_name , debug = True )
92116 libvirt .check_result (dominfo , expected_match = dominfo_msg )
@@ -98,11 +122,17 @@ def teardown_test():
98122 test .log .info ("TEST_TEARDOWN: Clean up env." )
99123 if session :
100124 session .close ()
125+ if with_snapshot :
126+ virsh .snapshot_delete (vm_name , snapshot_name , debug = True )
101127 bkxml .sync ()
102- process .run ('sudo losetup -d %s' % free_loop_dev , ** virsh_dargs )
103- process .run ('sudo dmsetup remove %s' % device_manager , ** virsh_dargs )
104- if os .path .exists (device_manager_path ):
105- os .remove (device_manager_path )
128+ if enospc_test :
129+ process .run (params .get ("cleanup_cmd" ), ** virsh_dargs )
130+ else :
131+ process .run ('sudo losetup -d %s' % free_loop_dev , ** virsh_dargs )
132+ process .run ('sudo dmsetup remove %s' % params .get ("device_manager" ),
133+ ** virsh_dargs )
134+ if os .path .exists (params .get ("device_manager_path" )):
135+ os .remove (params .get ("device_manager_path" ))
106136
107137 libvirt_version .is_libvirt_feature_supported (params )
108138
@@ -119,6 +149,9 @@ def teardown_test():
119149 event_msg = params .get ("event_msg" )
120150 guest_log_msg = params .get ("guest_log_msg" )
121151 dominfo_msg = params .get ("dominfo_msg" )
152+ enospc_test = "yes" == params .get ("enospc_test" , "no" )
153+ with_snapshot = "yes" == params .get ("with_snapshot" , "no" )
154+ snapshot_name = params .get ("snapshot_name" )
122155 session = None
123156
124157 try :
0 commit comments