📄 qemu-img.c
字号:
if (*p == 'M') { size *= 1024 * 1024; } else if (*p == 'G') { size *= 1024 * 1024 * 1024; } else if (*p == 'k' || *p == 'K' || *p == '\0') { size *= 1024; } else { help(); } } drv = bdrv_find_format(fmt); if (!drv) error("Unknown file format '%s'", fmt); printf("Formating '%s', fmt=%s", filename, fmt); if (encrypted) printf(", encrypted"); if (base_filename) { printf(", backing_file=%s", base_filename); } printf(", size=%lld kB\n", (long long) (size / 1024)); ret = bdrv_create(drv, filename, size / 512, base_filename, encrypted); if (ret < 0) { if (ret == -ENOTSUP) { error("Formatting or formatting option not supported for file format '%s'", fmt); } else { error("Error while formatting"); } } return 0;}static int img_commit(int argc, char **argv){ int c, ret; const char *filename, *fmt; BlockDriver *drv; BlockDriverState *bs; fmt = NULL; for(;;) { c = getopt(argc, argv, "f:h"); if (c == -1) break; switch(c) { case 'h': help(); break; case 'f': fmt = optarg; break; } } if (optind >= argc) help(); filename = argv[optind++]; bs = bdrv_new(""); if (!bs) error("Not enough memory"); if (fmt) { drv = bdrv_find_format(fmt); if (!drv) error("Unknown file format '%s'", fmt); } else { drv = NULL; } if (bdrv_open2(bs, filename, 0, drv) < 0) { error("Could not open '%s'", filename); } ret = bdrv_commit(bs); switch(ret) { case 0: printf("Image committed.\n"); break; case -ENOENT: error("No disk inserted"); break; case -EACCES: error("Image is read-only"); break; case -ENOTSUP: error("Image is already committed"); break; default: error("Error while committing image"); break; } bdrv_delete(bs); return 0;}static int is_not_zero(const uint8_t *sector, int len){ int i; len >>= 2; for(i = 0;i < len; i++) { if (((uint32_t *)sector)[i] != 0) return 1; } return 0;}static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum){ int v, i; if (n <= 0) { *pnum = 0; return 0; } v = is_not_zero(buf, 512); for(i = 1; i < n; i++) { buf += 512; if (v != is_not_zero(buf, 512)) break; } *pnum = i; return v;}#define IO_BUF_SIZE 65536static int img_convert(int argc, char **argv){ int c, ret, n, n1, compress, cluster_size, cluster_sectors, encrypt; const char *filename, *fmt, *out_fmt, *out_filename; BlockDriver *drv; BlockDriverState *bs, *out_bs; int64_t total_sectors, nb_sectors, sector_num; uint8_t buf[IO_BUF_SIZE]; const uint8_t *buf1; fmt = NULL; out_fmt = "raw"; compress = 0; encrypt = 0; for(;;) { c = getopt(argc, argv, "f:O:hce"); if (c == -1) break; switch(c) { case 'h': help(); break; case 'f': fmt = optarg; break; case 'O': out_fmt = optarg; break; case 'c': compress = 1; break; case 'e': encrypt = 1; break; } } if (optind >= argc) help(); filename = argv[optind++]; if (optind >= argc) help(); out_filename = argv[optind++]; bs = bdrv_new_open(filename, fmt); drv = bdrv_find_format(out_fmt); if (!drv) error("Unknown file format '%s'", fmt); if (compress && drv != &bdrv_qcow) error("Compression not supported for this file format"); if (encrypt && drv != &bdrv_qcow) error("Encryption not supported for this file format"); if (compress && encrypt) error("Compression and encryption not supported at the same time"); bdrv_get_geometry(bs, &total_sectors); ret = bdrv_create(drv, out_filename, total_sectors, NULL, encrypt); if (ret < 0) { if (ret == -ENOTSUP) { error("Formatting not supported for file format '%s'", fmt); } else { error("Error while formatting '%s'", out_filename); } } out_bs = bdrv_new_open(out_filename, out_fmt); if (compress) { cluster_size = qcow_get_cluster_size(out_bs); if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) error("invalid cluster size"); cluster_sectors = cluster_size >> 9; sector_num = 0; for(;;) { nb_sectors = total_sectors - sector_num; if (nb_sectors <= 0) break; if (nb_sectors >= cluster_sectors) n = cluster_sectors; else n = nb_sectors; if (bdrv_read(bs, sector_num, buf, n) < 0) error("error while reading"); if (n < cluster_sectors) memset(buf + n * 512, 0, cluster_size - n * 512); if (is_not_zero(buf, cluster_size)) { if (qcow_compress_cluster(out_bs, sector_num, buf) != 0) error("error while compressing sector %lld", sector_num); } sector_num += n; } } else { sector_num = 0; for(;;) { nb_sectors = total_sectors - sector_num; if (nb_sectors <= 0) break; if (nb_sectors >= (IO_BUF_SIZE / 512)) n = (IO_BUF_SIZE / 512); else n = nb_sectors; if (bdrv_read(bs, sector_num, buf, n) < 0) error("error while reading"); /* NOTE: at the same time we convert, we do not write zero sectors to have a chance to compress the image. Ideally, we should add a specific call to have the info to go faster */ buf1 = buf; while (n > 0) { if (is_allocated_sectors(buf1, n, &n1)) { if (bdrv_write(out_bs, sector_num, buf1, n1) < 0) error("error while writing"); } sector_num += n1; n -= n1; buf1 += n1 * 512; } } } bdrv_delete(out_bs); bdrv_delete(bs); return 0;}#ifdef _WIN32static int64_t get_allocated_file_size(const char *filename){ struct _stati64 st; if (_stati64(filename, &st) < 0) return -1; return st.st_size;}#elsestatic int64_t get_allocated_file_size(const char *filename){ struct stat st; if (stat(filename, &st) < 0) return -1; return (int64_t)st.st_blocks * 512;}#endifstatic int img_info(int argc, char **argv){ int c; const char *filename, *fmt; BlockDriver *drv; BlockDriverState *bs; char fmt_name[128], size_buf[128], dsize_buf[128]; int64_t total_sectors, allocated_size; fmt = NULL; for(;;) { c = getopt(argc, argv, "f:h"); if (c == -1) break; switch(c) { case 'h': help(); break; case 'f': fmt = optarg; break; } } if (optind >= argc) help(); filename = argv[optind++]; bs = bdrv_new(""); if (!bs) error("Not enough memory"); if (fmt) { drv = bdrv_find_format(fmt); if (!drv) error("Unknown file format '%s'", fmt); } else { drv = NULL; } if (bdrv_open2(bs, filename, 0, drv) < 0) { error("Could not open '%s'", filename); } bdrv_get_format(bs, fmt_name, sizeof(fmt_name)); bdrv_get_geometry(bs, &total_sectors); get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512); allocated_size = get_allocated_file_size(filename); if (allocated_size < 0) sprintf(dsize_buf, "unavailable"); else get_human_readable_size(dsize_buf, sizeof(dsize_buf), allocated_size); printf("image: %s\n" "file format: %s\n" "virtual size: %s (%lld bytes)\n" "disk size: %s\n", filename, fmt_name, size_buf, (long long) (total_sectors * 512), dsize_buf); if (bdrv_is_encrypted(bs)) printf("encrypted: yes\n"); bdrv_delete(bs); return 0;}int main(int argc, char **argv){ const char *cmd; bdrv_init(); if (argc < 2) help(); cmd = argv[1]; optind++; if (!strcmp(cmd, "create")) { img_create(argc, argv); } else if (!strcmp(cmd, "commit")) { img_commit(argc, argv); } else if (!strcmp(cmd, "convert")) { img_convert(argc, argv); } else if (!strcmp(cmd, "info")) { img_info(argc, argv); } else { help(); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -