php除了写网站吗,做网站公司怎样,手工制作钟表,建站公司排名 软通旧的 QEMU 图像格式#xff0c;支持备份文件、紧凑图像文件、加密和压缩。 backing_file 基础镜像的文件名#xff08;参见create子命令#xff09; encryption 此选项已弃用#xff0c;相当于encrypt.formataes encrypt.format 如果设置为aes#xff0c;则图像将使用 128… 旧的 QEMU 图像格式支持备份文件、紧凑图像文件、加密和压缩。 backing_file 基础镜像的文件名参见create子命令 encryption 此选项已弃用相当于encrypt.formataes encrypt.format 如果设置为aes则图像将使用 128 位 AES-CBC 加密。加密密钥由参数给出encrypt.key-secret。现代密码学标准认为这种加密格式存在缺陷存在许多针对qcow2图像格式的先前列举的设计问题。 系统模拟器不再支持使用此功能。仅命令行实用程序仍支持此功能用于数据释放和与旧版 QEMU 的互操作性。 需要本机加密的用户应该使用qcow2格式代替encrypt.formatluks。 encrypt.key-secret secret提供包含加密密钥的对象的 ID ( encrypt.formataes)。 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;
}