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_names = libvirt_disk .get_non_root_disk_name (session )
86+ if not disk_names :
87+ test .fail ("Can't find the non-root disk as expected!" )
88+ disk_name = disk_names [0 ]
89+ utils_disk .dd_data_to_vm_disk (session , "/dev/%s" % disk_name )
90+ else :
91+ session .cmd (dd_in_guest )
7492 except Exception as e :
7593 if dd_msg not in str (e ):
76- test .fail ("Write data in guest should produce error: %s in %s" % (dd_msg , output ))
94+ test .fail ("Write data in guest should produce error: %s in %s"
95+ % (dd_msg , str (e )))
96+ elif dd_msg in str (e ):
97+ test .log .debug ("Get expected error: %s in %s" % (dd_msg , str (e )))
7798 else :
78- test .fail ("Except error: in %s" % output )
99+ test .fail ("Get unexpected result!" )
79100
80101 test .log .info ("TEST_STEP3: Check event output." )
81102 event_output = virsh .EventTracker .finish_get_event (virsh_session )
@@ -87,6 +108,12 @@ def run_test():
87108 if not libvirt .check_logfile (guest_log_msg , qemu_log , str_in_log = True ):
88109 test .fail ('Find unexpected error:%s in log file:%s' % (guest_log_msg , qemu_log ))
89110
111+ if with_snapshot :
112+ test .log .info ("TEST_STEP6: Create disk snapshot and check I/O error." )
113+ snapshot_file = os .path .join (data_dir .get_data_dir (), "vdb.snap" )
114+ snap_options = ("%s --diskspec %s,snapshot=external,file=%s --disk-only"
115+ % (snapshot_name , target_disk , snapshot_file ))
116+ virsh .snapshot_create_as (vm_name , snap_options , debug = True )
90117 test .log .info ("TEST_STEP5: Check about I/O error in virsh domain info." )
91118 dominfo = virsh .dominfo (vm_name , debug = True )
92119 libvirt .check_result (dominfo , expected_match = dominfo_msg )
@@ -98,11 +125,17 @@ def teardown_test():
98125 test .log .info ("TEST_TEARDOWN: Clean up env." )
99126 if session :
100127 session .close ()
128+ if with_snapshot :
129+ virsh .snapshot_delete (vm_name , snapshot_name , debug = True )
101130 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 )
131+ if enospc_test :
132+ process .run (params .get ("cleanup_cmd" ), ** virsh_dargs )
133+ else :
134+ process .run ('sudo losetup -d %s' % free_loop_dev , ** virsh_dargs )
135+ process .run ('sudo dmsetup remove %s' % params .get ("device_manager" ),
136+ ** virsh_dargs )
137+ if os .path .exists (params .get ("device_manager_path" )):
138+ os .remove (params .get ("device_manager_path" ))
106139
107140 libvirt_version .is_libvirt_feature_supported (params )
108141
@@ -119,6 +152,10 @@ def teardown_test():
119152 event_msg = params .get ("event_msg" )
120153 guest_log_msg = params .get ("guest_log_msg" )
121154 dominfo_msg = params .get ("dominfo_msg" )
155+ enospc_test = "yes" == params .get ("enospc_test" , "no" )
156+ target_disk = params .get ("target_disk" )
157+ with_snapshot = "yes" == params .get ("with_snapshot" , "no" )
158+ snapshot_name = params .get ("snapshot_name" )
122159 session = None
123160
124161 try :
0 commit comments