def copyif(params, nbd_image, target_image, bitmap=None): """ Python implementation of copyif3.sh :params params: utils_params.Params object :params nbd_image: nbd image tag :params target_image: target image tag :params bitmap: bitmap name """ def _qemu_io_read(qemu_io, s, l, img): cmd = '{io} -C -c "r {s} {l}" -f {fmt} {f}'.format( io=qemu_io, s=s, l=l, fmt=img.image_format, f=img.image_filename ) process.system(cmd, ignore_status=False, shell=True) qemu_io = utils_misc.get_qemu_io_binary(params) qemu_img = utils_misc.get_qemu_img_binary(params) img_obj = qemu_storage.QemuImg(params.object_params(target_image), data_dir.get_data_dir(), target_image) nbd_img_obj = qemu_storage.QemuImg(params.object_params(nbd_image), None, nbd_image) max_len = int(params.get('qemu_io_max_len', 2147483136)) if bitmap is None: args = '-f %s %s' % (nbd_img_obj.image_format, nbd_img_obj.image_filename) state = True else: opts = qemu_storage.filename_to_file_opts( nbd_img_obj.image_filename) opt = params.get('dirty_bitmap_opt', 'x-dirty-bitmap') opts[opt] = 'qemu:dirty-bitmap:%s' % bitmap args = "'json:%s'" % json.dumps(opts) state = False img_obj.base_image_filename = nbd_img_obj.image_filename img_obj.base_format = nbd_img_obj.image_format img_obj.base_tag = nbd_img_obj.tag img_obj.rebase(img_obj.params) map_cmd = '{qemu_img} map --output=json {args}'.format( qemu_img=qemu_img, args=args) result = process.run(map_cmd, ignore_status=False, shell=True) for item in json.loads(result.stdout.decode().strip()): if item['data'] is not state: continue # qemu-io can only handle length less than 2147483136, # so here we need to split 'large length' into several parts start, length = item['start'], item['length'] while length > max_len: _qemu_io_read(qemu_io, start, max_len, img_obj) start, length = start+max_len, length-max_len else: if length > 0: _qemu_io_read(qemu_io, start, length, img_obj) img_obj.base_tag = 'null' img_obj.rebase(img_obj.params)
def check_bitmaps_from_export(self): qemu_img = get_qemu_img_binary(self.params) opts = filename_to_file_opts(self._nbd_image_obj.image_filename) for bm in self._bitmaps: opts[self.params['dirty_bitmap_opt']] = 'qemu:dirty-bitmap:%s' % bm args = "'json:%s'" % json.dumps(opts) map_cmd = '{qemu_img} map --output=human {args}'.format( qemu_img=qemu_img, args=args) result = process.run(map_cmd, ignore_status=False, shell=True) if self._nbd_image_obj.image_filename not in result.stdout_text: self.test.fail('Failed to get bitmap info.')
def _check_backing(self, backing): data_image_opts = qemu_storage.filename_to_file_opts( qemu_storage.QemuImg(self.params.object_params(self.base_tag), data_dir.get_data_dir(), self.base_tag).image_filename) base_image_opts = qemu_storage.filename_to_file_opts( qemu_storage.QemuImg( self.params.object_params(self._base_node_tag), data_dir.get_data_dir(), self._base_node_tag).image_filename) try: # datasn1->datasn3: check datasn1 is datasn3's backing file if not self._is_same_file(backing["file"], base_image_opts): self.test.fail("Failed to get backing file for %s" % self.snapshot_tag) # data->datasn1: check data is datasn1's backing file if not self._is_same_file(backing["backing"]["file"], data_image_opts): self.test.fail("Failed to get backing file for %s" % self._base_node_tag) except Exception as e: self.test.fail("Failed to get backing chain: %s" % str(e))
def check_info_from_export_bitmaps(self): qemu_img = utils_misc.get_qemu_img_binary(self.params) for i, nbd_img in enumerate(self.nbd_images): opts = qemu_storage.filename_to_file_opts(nbd_img.image_filename) opts[self.params[ 'dirty_bitmap_opt']] = 'qemu:dirty-bitmap:%s' % self.bitmaps[i] args = "'json:%s'" % json.dumps(opts) map_cmd = '{qemu_img} map --output=human {args}'.format( qemu_img=qemu_img, args=args) result = process.run(map_cmd, ignore_status=True, shell=True) if result.exit_status != 0: self.test.fail('Failed to run map command: %s' % result.stderr.decode()) if nbd_img.image_filename not in result.stdout_text: self.test.fail('Failed to get bitmap info.')
def check_allocation_depth_from_export(self, zero, data): """ check allocation depth from output of qemu-img map local(base image): zero: false, data: false backing(snapshot): zero: true, data: true """ opts = filename_to_file_opts(self._nbd_image_obj.image_filename) opts[self.params['dirty_bitmap_opt']] = 'qemu:allocation-depth' map_cmd = '{qemu_img} map --output=json {args}'.format( qemu_img=get_qemu_img_binary(self.params), args="'json:%s'" % json.dumps(opts)) result = process.run(map_cmd, ignore_status=False, shell=True) for item in json.loads(result.stdout.decode().strip()): if item['zero'] is zero and item['data'] is data: break else: self.test.fail('Failed to get "zero": %s, "data": %s' % (zero, data))
def copyif(self, nbd_img_obj, img_obj, bitmap=None): qemu_img = utils_misc.get_qemu_img_binary(self.params) qemu_io = utils_misc.get_qemu_io_binary(self.params) args = '' if bitmap is None: args = '-f %s %s' % (nbd_img_obj.image_format, nbd_img_obj.image_filename) else: opts = qemu_storage.filename_to_file_opts( nbd_img_obj.image_filename) opts[self. params['dirty_bitmap_opt']] = 'qemu:dirty-bitmap:%s' % bitmap args = "'json:%s'" % json.dumps(opts) img_obj.base_image_filename = nbd_img_obj.image_filename img_obj.base_format = nbd_img_obj.image_format img_obj.base_tag = nbd_img_obj.tag img_obj.rebase(img_obj.params) map_cmd = '{qemu_img} map --output=json {args}'.format( qemu_img=qemu_img, args=args) result = process.run(map_cmd, ignore_status=True, shell=True) if result.exit_status != 0: self.test.fail('Failed to run map command: %s' % result.stderr.decode()) for item in json.loads(result.stdout.decode().strip()): io_cmd = '{io} -C -c "read {s} {l}" -f {fmt} {fn}'.format( io=qemu_io, s=item['start'], l=item['length'], fmt=img_obj.image_format, fn=img_obj.image_filename) result = process.run(io_cmd, ignore_status=True, shell=True) if result.exit_status != 0: self.test.fail('Failed to run qemu-io command: %s' % result.stderr.decode()) img_obj.base_tag = 'null' img_obj.rebase(img_obj.params)