当前位置: 首页 > news >正文

qemu解析qcow文件

旧的 QEMU 图像格式,支持备份文件、紧凑图像文件、加密和压缩。
backing_file
基础镜像的文件名(参见create子命令)
encryption
此选项已弃用,相当于encrypt.format=aes
encrypt.format
如果设置为aes,则图像将使用 128 位 AES-CBC 加密。加密密钥由参数给出encrypt.key-secret。现代密码学标准认为这种加密格式存在缺陷,存在许多针对qcow2图像格式的先前列举的设计问题。
系统模拟器不再支持使用此功能。仅命令行实用程序仍支持此功能,用于数据释放和与旧版 QEMU 的互操作性。
需要本机加密的用户应该使用qcow2格式代替encrypt.format=luks。
encrypt.key-secret
secret提供包含加密密钥的对象的 ID ( encrypt.format=aes)。
1、注册qcow块格式
static BlockDriver bdrv_qcow = {.format_name    = "qcow",.instance_size    = sizeof(BDRVQcowState),.bdrv_probe        = qcow_probe,.bdrv_open        = qcow_open,.bdrv_close        = qcow_close,.bdrv_child_perm        = bdrv_default_perms,.bdrv_reopen_prepare    = qcow_reopen_prepare,.bdrv_co_create         = qcow_co_create,.bdrv_co_create_opts    = qcow_co_create_opts,.bdrv_has_zero_init     = bdrv_has_zero_init_1,.is_format              = true,.supports_backing       = true,.bdrv_refresh_limits    = qcow_refresh_limits,.bdrv_co_preadv         = qcow_co_preadv,.bdrv_co_pwritev        = qcow_co_pwritev,.bdrv_co_block_status   = qcow_co_block_status,.bdrv_make_empty        = qcow_make_empty,.bdrv_co_pwritev_compressed = qcow_co_pwritev_compressed,.bdrv_get_info          = qcow_get_info,.create_opts            = &qcow_create_opts,.strong_runtime_opts    = qcow_strong_runtime_opts,
};static void bdrv_qcow_init(void)
{bdrv_register(&bdrv_qcow);
}block_init(bdrv_qcow_init);
2、打开qcow文件
static int qcow_open(BlockDriverState *bs, QDict *options, int flags, Error **errp)
{BDRVQcowState *s = bs->opaque;unsigned int len, i, shift;int ret;QCowHeader header;QCryptoBlockOpenOptions *crypto_opts = NULL;unsigned int cflags = 0;QDict *encryptopts = NULL;const char *encryptfmt;qdict_extract_subqdict(options, &encryptopts, "encrypt.");encryptfmt = qdict_get_try_str(encryptopts, "format");// 打开qcow文件bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, BDRV_CHILD_IMAGE, false, errp);if (!bs->file) {ret = -EINVAL;goto fail;}// 读取并解析qcow头部ret = bdrv_pread(bs->file, 0, &header, sizeof(header));if (ret < 0) {goto fail;}header.magic = be32_to_cpu(header.magic);header.version = be32_to_cpu(header.version);header.backing_file_offset = be64_to_cpu(header.backing_file_offset);header.backing_file_size = be32_to_cpu(header.backing_file_size);header.mtime = be32_to_cpu(header.mtime);header.size = be64_to_cpu(header.size);header.crypt_method = be32_to_cpu(header.crypt_method);header.l1_table_offset = be64_to_cpu(header.l1_table_offset);// 验证有效性if (header.magic != QCOW_MAGIC) {error_setg(errp, "Image not in qcow format");ret = -EINVAL;goto fail;}if (header.version != QCOW_VERSION) {error_setg(errp, "qcow (v%d) does not support qcow version %" PRIu32, QCOW_VERSION, header.version);if (header.version == 2 || header.version == 3) {error_append_hint(errp, "Try the 'qcow2' driver instead.\n");}ret = -ENOTSUP;goto fail;}if (header.size <= 1) {error_setg(errp, "Image size is too small (must be at least 2 bytes)");ret = -EINVAL;goto fail;}if (header.cluster_bits < 9 || header.cluster_bits > 16) {error_setg(errp, "Cluster size must be between 512 and 64k");ret = -EINVAL;goto fail;}/* l2_bits specifies number of entries; storing a uint64_t in each entry,* so bytes = num_entries << 3. */if (header.l2_bits < 9 - 3 || header.l2_bits > 16 - 3) {error_setg(errp, "L2 table size must be between 512 and 64k");ret = -EINVAL;goto fail;}s->crypt_method_header = header.crypt_method;if (s->crypt_method_header) {if (bdrv_uses_whitelist() &&s->crypt_method_header == QCOW_CRYPT_AES) {error_setg(errp,"Use of AES-CBC encrypted qcow images is no longer supported in system emulators");error_append_hint(errp,You can use 'qemu-img convert' to convert your image to an alternative supported format, such ""as unencrypted qcow, or raw with the LUKS format instead.\n");ret = -ENOSYS;goto fail;}if (s->crypt_method_header == QCOW_CRYPT_AES) {if (encryptfmt && !g_str_equal(encryptfmt, "aes")) {error_setg(errp, "Header reported 'aes' encryption format but options specify '%s'", encryptfmt);ret = -EINVAL;goto fail;}qdict_put_str(encryptopts, "format", "qcow");crypto_opts = block_crypto_open_opts_init(encryptopts, errp);if (!crypto_opts) {ret = -EINVAL;goto fail;}if (flags & BDRV_O_NO_IO) {cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;}s->crypto = qcrypto_block_open(crypto_opts, "encrypt.", NULL, NULL, cflags, 1, errp);if (!s->crypto) {ret = -EINVAL;goto fail;}} else {error_setg(errp, "invalid encryption method in qcow header");ret = -EINVAL;goto fail;}bs->encrypted = true;} else {if (encryptfmt) {error_setg(errp, "No encryption in image header, but options " "specified format '%s'", encryptfmt);ret = -EINVAL;goto fail;}}s->cluster_bits = header.cluster_bits;s->cluster_size = 1 << s->cluster_bits;s->l2_bits = header.l2_bits;s->l2_size = 1 << s->l2_bits;bs->total_sectors = header.size / 512;s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1;/* read the level 1 table */shift = s->cluster_bits + s->l2_bits;if (header.size > UINT64_MAX - (1LL << shift)) {error_setg(errp, "Image too large");ret = -EINVAL;goto fail;} else {uint64_t l1_size = (header.size + (1LL << shift) - 1) >> shift;if (l1_size > INT_MAX / sizeof(uint64_t)) {error_setg(errp, "Image too large");ret = -EINVAL;goto fail;}s->l1_size = l1_size;}s->l1_table_offset = header.l1_table_offset;s->l1_table = g_try_new(uint64_t, s->l1_size);if (s->l1_table == NULL) {error_setg(errp, "Could not allocate memory for L1 table");ret = -ENOMEM;goto fail;}// 读取并解析1级缓存ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t));if (ret < 0) {goto fail;}for(i = 0;i < s->l1_size; i++) {s->l1_table[i] = be64_to_cpu(s->l1_table[i]);}// 2级缓存/* alloc L2 cache (max. 64k * 16 * 8 = 8 MB) */s->l2_cache = qemu_try_blockalign(bs->file->bs, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));if (s->l2_cache == NULL) {error_setg(errp, "Could not allocate L2 table cache");ret = -ENOMEM;goto fail;}s->cluster_cache = g_malloc(s->cluster_size);s->cluster_data = g_malloc(s->cluster_size);s->cluster_cache_offset = -1;/* read the backing file name */if (header.backing_file_offset != 0) {len = header.backing_file_size;if (len > 1023 || len >= sizeof(bs->backing_file)) {error_setg(errp, "Backing file name too long");ret = -EINVAL;goto fail;}ret = bdrv_pread(bs->file, header.backing_file_offset, bs->auto_backing_file, len);if (ret < 0) {goto fail;}bs->auto_backing_file[len] = '\0';pstrcpy(bs->backing_file, sizeof(bs->backing_file), bs->auto_backing_file);}// 使用 qcow 镜像时禁用迁移error_setg(&s->migration_blocker, "The qcow format used by node '%s' does not support live migration", bdrv_get_device_or_node_name(bs));ret = migrate_add_blocker(s->migration_blocker, errp);if (ret < 0) {error_free(s->migration_blocker);goto fail;}qobject_unref(encryptopts);qapi_free_QCryptoBlockOpenOptions(crypto_opts);qemu_co_mutex_init(&s->lock);return 0;
fail:g_free(s->l1_table);qemu_vfree(s->l2_cache);g_free(s->cluster_cache);g_free(s->cluster_data);qcrypto_block_free(s->crypto);qobject_unref(encryptopts);qapi_free_QCryptoBlockOpenOptions(crypto_opts);return ret;
}
3、读取qcow文件
static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,uint64_t bytes, QEMUIOVector *qiov,int flags)
{BDRVQcowState *s = bs->opaque;int offset_in_cluster;int ret = 0, n;uint64_t cluster_offset;uint8_t *buf;void *orig_buf;assert(!flags);if (qiov->niov > 1) {buf = orig_buf = qemu_try_blockalign(bs, qiov->size);if (buf == NULL) {return -ENOMEM;}} else {orig_buf = NULL;buf = (uint8_t *)qiov->iov->iov_base;}qemu_co_mutex_lock(&s->lock);while (bytes != 0) {/* prepare next request */ret = get_cluster_offset(bs, offset, 0, 0, 0, 0, &cluster_offset);if (ret < 0) {break;}offset_in_cluster = offset & (s->cluster_size - 1);n = s->cluster_size - offset_in_cluster;if (n > bytes) {n = bytes;}if (!cluster_offset) {if (bs->backing) {/* read from the base image */qemu_co_mutex_unlock(&s->lock);/* qcow2 emits this on bs->file instead of bs->backing */BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);ret = bdrv_co_pread(bs->backing, offset, n, buf, 0);qemu_co_mutex_lock(&s->lock);if (ret < 0) {break;}} else {/* Note: in this case, no need to wait */memset(buf, 0, n);}} else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {/* add AIO support for compressed blocks ? */if (decompress_cluster(bs, cluster_offset) < 0) {ret = -EIO;break;}memcpy(buf, s->cluster_cache + offset_in_cluster, n);} else {if ((cluster_offset & 511) != 0) {ret = -EIO;break;}qemu_co_mutex_unlock(&s->lock);BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);ret = bdrv_co_pread(bs->file, cluster_offset + offset_in_cluster, n, buf, 0);qemu_co_mutex_lock(&s->lock);if (ret < 0) {break;}if (bs->encrypted) {assert(s->crypto);if (qcrypto_block_decrypt(s->crypto,offset, buf, n, NULL) < 0) {ret = -EIO;break;}}}ret = 0;bytes -= n;offset += n;buf += n;}qemu_co_mutex_unlock(&s->lock);if (qiov->niov > 1) {qemu_iovec_from_buf(qiov, 0, orig_buf, qiov->size);qemu_vfree(orig_buf);}return ret;
}

相关文章:

qemu解析qcow文件

旧的 QEMU 图像格式&#xff0c;支持备份文件、紧凑图像文件、加密和压缩。 backing_file 基础镜像的文件名&#xff08;参见create子命令&#xff09; encryption 此选项已弃用&#xff0c;相当于encrypt.formataes encrypt.format 如果设置为aes&#xff0c;则图像将使用 128…...

免费网站源码下载指南:如何安全获取并降低开发成本

许多开发者或是需要建立网站的人&#xff0c;可以方便地获取免费网站源码。这样的下载能帮助他们降低开发费用&#xff0c;迅速构建起基本框架。但在此过程中&#xff0c;仍有许多需要注意的事项。 许多开发者或是需要建立网站的人&#xff0c;可以方便地获取免费网站源码。这…...

【Ubuntu】如何设置 Ubuntu 自动每日更新:轻松保持系统安全

如何设置 Ubuntu 自动每日更新&#xff1a;轻松保持系统安全 大家好&#xff01;今天我们来聊一个非常实用的话题——如何让 Ubuntu 系统自动每日更新。如果你是一个 Ubuntu 用户&#xff0c;尤其是服务器管理员&#xff0c;你可能会经常遇到这样的问题&#xff1a;系统需要频…...

江科大STM32入门——UART通信笔记总结

wx&#xff1a;嵌入式工程师成长日记 1、简介 简单双向串口通信有两根通信线(发送端TX和接收端RX)TX与RX要交叉连接当只需单向的数据传输时&#xff0c;可以只接一根通信线当电平标准不一致时&#xff0c;需要加电平转换芯片 传输模式&#xff1a;全双工&#xff1b;时钟&…...

github gitbook写书

github创建新的仓库 在仓库中添加目录 ‘SUMMARY.md # Summary * [简介](README.md)gitbook 新建一个site https://www.gitbook.com/ 注册账号 取名字 一路 next&#xff0c;注意选免费版 最后 gitbook同步到github 你在主页可以看到 刚刚的test网站 点击右上角圈出来…...

探秘MetaGPT:革新软件开发的多智能体框架(22/30)

一、MetaGPT 引发的 AI 变革浪潮 近年来&#xff0c;人工智能大模型领域取得了令人瞩目的进展&#xff0c;GPT-3、GPT-4、PaLM 等模型展现出了惊人的自然语言处理能力&#xff0c;仿佛为 AI 世界打开了一扇通往无限可能的大门。它们能够生成流畅的文本、回答复杂的问题、进行创…...

【优选算法】Binary-Blade:二分查找的算法刃(下)

文章目录 1.山脉数组的峰顶索引2.寻找峰值3.寻找旋转排序数组中的最小值4.点名希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力&#xff01; 本篇接上一篇二分查找&#xff0c;主要通过部分题目熟悉二分查找的进阶使用&#xff0c;重点强调二段性&#xff0c;…...

Improving Language Understanding by Generative Pre-Training GPT-1详细讲解

Improving Language Understanding by Generative Pre-Training 2018.06 GPT-1 0.有监督、半监督、无监督 CV&#xff1a;ImageNet pre-trained model NLP&#xff1a;pre-trained model? 在计算机视觉中任务包含分类、检测、分割&#xff0c;任务类别数少&#xff0c;对应…...

分治算法——优选算法

本章我们要学习的是分治算法&#xff0c;顾名思义就是分而治之&#xff0c;把大问题分为多个相同的子问题进行处理&#xff0c;其中我们熟知的快速排序和归并排序用的就是分治算法&#xff0c;所以我们需要重新回顾一下这两个排序。 一、快速排序&#xff08;三路划分&#xf…...

EtherCAT转Modbus网关与TwinCAT3的连接及配置详述

在工业自动化控制系统中&#xff0c;常常需要整合不同的通信协议设备。本案例旨在展示如何利用捷米特JM-ECT-RTU协议转换网关模块&#xff0c;实现 EtherCAT 网络与 Modbus 设备之间的无缝连接&#xff0c;并在 TwinCAT3 环境中进行有效配置&#xff0c;以构建一个稳定可靠的自…...

Apache Hadoop YARN框架概述

一、YARN产生和发展简史 1.1背景 数据、程序、运算资源&#xff08;内存、CPU&#xff09;三者组在一起&#xff0c;才能完成数据的计算处理过程。在单机环境下&#xff0c;三者之间协调配合不是太大问题。为了应对海量数据的处理场景&#xff0c;Hadoop软件出现并提供了分布…...

三甲医院等级评审八维数据分析应用(八)--数据治理的持续改进与反馈机制篇

一、引言 1.1 研究背景与意义 当前三甲医院在数据管理方面暴露出诸多棘手问题。一方面,数据治理缺乏系统性与规范性,数据标准不统一,不同科室、信息系统之间的数据格式各异、编码混乱,导致数据整合与共享困难重重,严重制约了数据分析的准确性与深度。以某三甲医院为例,…...

XML通过HTTP POST 请求发送到指定的 API 地址,进行数据回传

代码结构说明 这段代码的主要功能是&#xff1a; 从指定文件夹中读取所有 XML 文件。 将每个 XML 文件的内容通过 HTTP POST 请求发送到指定的 API 地址。 处理服务器的响应&#xff0c;并记录每个文件的处理结果。 using System; using System.IO; using System.Net; usin…...

科大讯飞前端面试题及参考答案 (下)

除了 echarts 还了解其它画图工具吗? 除了 Echarts,还有不少优秀的画图工具可供选择使用。 Highcharts:它是一款功能强大且应用广泛的图表绘制工具,支持多种常见的图表类型,像柱状图、折线图、饼图、散点图等,同时也能创建较为复杂的图表,比如仪表盘图表、极坐标图等。H…...

【理论】测试框架体系TDD、BDD、ATDD、DDT介绍

一、测试框架是什么 测试框架是一组用于创建和设计测试用例的指南或规则。框架由旨在帮助 QA 专业人员更有效地测试的实践和工具的组合组成。 这些指南可能包括编码标准、测试数据处理方法、对象存储库、存储测试结果的过程或有关如何访问外部资源的信息。 A testing framewo…...

如何进行全脑思维(左脑,右脑,全脑)

1&#xff09;每人都有一个价值100万美元的点子 . 谁能帮助实施这个点子? . 实施这个点子需要哪些资源? . 推行这个点子需要得到哪些许可? . 是否有实施这个点子的最佳时间? . 作为实施的开始,最简单的做法是什么? 2) 进行理性的、逻辑的、量的思维那一半,而排除了大脑的…...

领域驱动设计 2

1.幂等设计 1.1.定义 无论进行多少次相同的操作&#xff0c;结果都保持一致的设计。 1.2.写操作的幂等性 1.2.1.Insert 指定唯一标识写&#xff0c;是具有幂等性的。 不指定唯一标识写&#xff0c;不具备幂等性。 1.2.2.Update 如果更新操作依赖于与历史状态&#xff0c…...

十年后LabVIEW编程知识是否会过时?

在考虑LabVIEW编程知识在未来十年内的有效性时&#xff0c;我们可以从几个角度进行分析&#xff1a; ​ 1. 技术发展与软件更新 随着技术的快速发展&#xff0c;许多编程工具和平台不断更新和改进&#xff0c;LabVIEW也不例外。十年后&#xff0c;可能会有新的编程语言或平台…...

ARM交叉编译Boost库

Boost下载&#xff1a;点击跳转 编译过程&#xff1a; 生成project-config.jam ./bootstrap.sh --with-librariesfilesystem,thread --with-toolsetgcc 2. 修改project-config.jam&#xff08;位于第12行附近&#xff09; if ! gcc in [ feature.values <toolset> ] …...

uniapp:钉钉小程序需要录音权限及调用录音

{// ... 其他配置项"mp-dingtalk": {"permission": {"scope.userLocation" : {"desc" : "系统希望获得您的定位用于确认您周围的设施数据"},"scope.bluetooth" : {"desc" : "你的蓝牙权限将用于小…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...

ui框架-文件列表展示

ui框架-文件列表展示 介绍 UI框架的文件列表展示组件&#xff0c;可以展示文件夹&#xff0c;支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项&#xff0c;适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...

aurora与pcie的数据高速传输

设备&#xff1a;zynq7100&#xff1b; 开发环境&#xff1a;window&#xff1b; vivado版本&#xff1a;2021.1&#xff1b; 引言 之前在前面两章已经介绍了aurora读写DDR,xdma读写ddr实验。这次我们做一个大工程&#xff0c;pc通过pcie传输给fpga&#xff0c;fpga再通过aur…...