e2image.c revision 2d2abcc64604c831c2db1da03fe701baefa1cb68
1/* 2 * e2image.c --- Program which writes an image file backing up 3 * critical metadata for the filesystem. 4 * 5 * Copyright 2000, 2001 by Theodore Ts'o. 6 * 7 * %Begin-Header% 8 * This file may be redistributed under the terms of the GNU Public 9 * License. 10 * %End-Header% 11 */ 12 13#define _LARGEFILE_SOURCE 14#define _LARGEFILE64_SOURCE 15 16#include "config.h" 17#include <fcntl.h> 18#include <grp.h> 19#ifdef HAVE_GETOPT_H 20#include <getopt.h> 21#else 22extern char *optarg; 23extern int optind; 24#endif 25#include <pwd.h> 26#include <stdio.h> 27#ifdef HAVE_STDLIB_H 28#include <stdlib.h> 29#endif 30#include <string.h> 31#include <time.h> 32#include <unistd.h> 33#include <fcntl.h> 34#include <errno.h> 35#include <sys/stat.h> 36#include <sys/types.h> 37#include <assert.h> 38 39#include "ext2fs/ext2_fs.h" 40#include "ext2fs/ext2fs.h" 41#include "et/com_err.h" 42#include "uuid/uuid.h" 43#include "e2p/e2p.h" 44#include "ext2fs/e2image.h" 45#include "ext2fs/qcow2.h" 46 47#include "../version.h" 48#include "nls-enable.h" 49 50#define QCOW_OFLAG_COPIED (1LL << 63) 51 52 53const char * program_name = "e2image"; 54char * device_name = NULL; 55 56static void lseek_error_and_exit(int errnum) 57{ 58 fprintf(stderr, "seek: %s\n", error_message(errnum)); 59 exit(1); 60} 61 62static blk64_t align_offset(blk64_t offset, int n) 63{ 64 return (offset + n - 1) & ~(n - 1); 65} 66 67static int get_bits_from_size(size_t size) 68{ 69 int res = 0; 70 71 if (size == 0) 72 return -1; 73 74 while (size != 1) { 75 /* Not a power of two */ 76 if (size & 1) 77 return -1; 78 79 size >>= 1; 80 res++; 81 } 82 return res; 83} 84 85static void usage(void) 86{ 87 fprintf(stderr, _("Usage: %s [-rsIQ] device image_file\n"), 88 program_name); 89 exit (1); 90} 91 92static void generic_write(int fd, void *buf, int blocksize, blk64_t block) 93{ 94 int count, free_buf = 0; 95 errcode_t err; 96 97 if (!blocksize) 98 return; 99 100 if (!buf) { 101 free_buf = 1; 102 err = ext2fs_get_arrayzero(1, blocksize, &buf); 103 if (err) { 104 com_err(program_name, err, "while allocating buffer"); 105 exit(1); 106 } 107 } 108 109 count = write(fd, buf, blocksize); 110 if (count != blocksize) { 111 if (count == -1) 112 err = errno; 113 else 114 err = 0; 115 116 if (block) 117 com_err(program_name, err, "error writing block %llu", 118 block); 119 else 120 com_err(program_name, err, "error in write()"); 121 122 exit(1); 123 } 124 if (free_buf) 125 ext2fs_free_mem(&buf); 126} 127 128static void write_header(int fd, void *hdr, int hdr_size, int wrt_size) 129{ 130 char *header_buf; 131 int ret; 132 133 /* Sanity check */ 134 if (hdr_size > wrt_size) { 135 fprintf(stderr, _("Error: header size is bigger than " 136 "wrt_size\n")); 137 } 138 139 ret = ext2fs_get_mem(wrt_size, &header_buf); 140 if (ret) { 141 fputs(_("Couldn't allocate header buffer\n"), stderr); 142 exit(1); 143 } 144 145 if (ext2fs_llseek(fd, 0, SEEK_SET) < 0) { 146 perror("ext2fs_llseek while writing header"); 147 exit(1); 148 } 149 memset(header_buf, 0, wrt_size); 150 151 if (hdr) 152 memcpy(header_buf, hdr, hdr_size); 153 154 generic_write(fd, header_buf, wrt_size, 0); 155 156 ext2fs_free_mem(&header_buf); 157} 158 159static void write_image_file(ext2_filsys fs, int fd) 160{ 161 struct ext2_image_hdr hdr; 162 struct stat st; 163 errcode_t retval; 164 165 write_header(fd, NULL, fs->blocksize, fs->blocksize); 166 memset(&hdr, 0, sizeof(struct ext2_image_hdr)); 167 168 hdr.offset_super = ext2fs_llseek(fd, 0, SEEK_CUR); 169 retval = ext2fs_image_super_write(fs, fd, 0); 170 if (retval) { 171 com_err(program_name, retval, _("while writing superblock")); 172 exit(1); 173 } 174 175 hdr.offset_inode = ext2fs_llseek(fd, 0, SEEK_CUR); 176 retval = ext2fs_image_inode_write(fs, fd, 177 (fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0); 178 if (retval) { 179 com_err(program_name, retval, _("while writing inode table")); 180 exit(1); 181 } 182 183 hdr.offset_blockmap = ext2fs_llseek(fd, 0, SEEK_CUR); 184 retval = ext2fs_image_bitmap_write(fs, fd, 0); 185 if (retval) { 186 com_err(program_name, retval, _("while writing block bitmap")); 187 exit(1); 188 } 189 190 hdr.offset_inodemap = ext2fs_llseek(fd, 0, SEEK_CUR); 191 retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP); 192 if (retval) { 193 com_err(program_name, retval, _("while writing inode bitmap")); 194 exit(1); 195 } 196 197 hdr.magic_number = EXT2_ET_MAGIC_E2IMAGE; 198 strcpy(hdr.magic_descriptor, "Ext2 Image 1.0"); 199 gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname)); 200 strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1); 201 hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0; 202 hdr.fs_blocksize = fs->blocksize; 203 204 if (stat(device_name, &st) == 0) 205 hdr.fs_device = st.st_rdev; 206 207 if (fstat(fd, &st) == 0) { 208 hdr.image_device = st.st_dev; 209 hdr.image_inode = st.st_ino; 210 } 211 memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid)); 212 213 hdr.image_time = time(0); 214 write_header(fd, &hdr, fs->blocksize, fs->blocksize); 215} 216 217/* 218 * These set of functions are used to write a RAW image file. 219 */ 220ext2fs_block_bitmap meta_block_map; 221ext2fs_block_bitmap scramble_block_map; /* Directory blocks to be scrambled */ 222blk64_t meta_blocks_count; 223 224struct process_block_struct { 225 ext2_ino_t ino; 226 int is_dir; 227}; 228 229/* 230 * These subroutines short circuits ext2fs_get_blocks and 231 * ext2fs_check_directory; we use them since we already have the inode 232 * structure, so there's no point in letting the ext2fs library read 233 * the inode again. 234 */ 235static ino_t stashed_ino = 0; 236static struct ext2_inode *stashed_inode; 237 238static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)), 239 ext2_ino_t ino, 240 blk_t *blocks) 241{ 242 int i; 243 244 if ((ino != stashed_ino) || !stashed_inode) 245 return EXT2_ET_CALLBACK_NOTHANDLED; 246 247 for (i=0; i < EXT2_N_BLOCKS; i++) 248 blocks[i] = stashed_inode->i_block[i]; 249 return 0; 250} 251 252static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)), 253 ext2_ino_t ino) 254{ 255 if ((ino != stashed_ino) || !stashed_inode) 256 return EXT2_ET_CALLBACK_NOTHANDLED; 257 258 if (!LINUX_S_ISDIR(stashed_inode->i_mode)) 259 return EXT2_ET_NO_DIRECTORY; 260 return 0; 261} 262 263static errcode_t meta_read_inode(ext2_filsys fs EXT2FS_ATTR((unused)), 264 ext2_ino_t ino, 265 struct ext2_inode *inode) 266{ 267 if ((ino != stashed_ino) || !stashed_inode) 268 return EXT2_ET_CALLBACK_NOTHANDLED; 269 *inode = *stashed_inode; 270 return 0; 271} 272 273static void use_inode_shortcuts(ext2_filsys fs, int use_shortcuts) 274{ 275 if (use_shortcuts) { 276 fs->get_blocks = meta_get_blocks; 277 fs->check_directory = meta_check_directory; 278 fs->read_inode = meta_read_inode; 279 stashed_ino = 0; 280 } else { 281 fs->get_blocks = 0; 282 fs->check_directory = 0; 283 fs->read_inode = 0; 284 } 285} 286 287static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)), 288 blk64_t *block_nr, 289 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), 290 blk64_t ref_block EXT2FS_ATTR((unused)), 291 int ref_offset EXT2FS_ATTR((unused)), 292 void *priv_data EXT2FS_ATTR((unused))) 293{ 294 struct process_block_struct *p; 295 296 p = (struct process_block_struct *) priv_data; 297 298 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr); 299 meta_blocks_count++; 300 if (scramble_block_map && p->is_dir && blockcnt >= 0) 301 ext2fs_mark_block_bitmap2(scramble_block_map, *block_nr); 302 return 0; 303} 304 305static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)), 306 blk64_t *block_nr, 307 e2_blkcnt_t blockcnt, 308 blk64_t ref_block EXT2FS_ATTR((unused)), 309 int ref_offset EXT2FS_ATTR((unused)), 310 void *priv_data EXT2FS_ATTR((unused))) 311{ 312 if (blockcnt < 0) { 313 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr); 314 meta_blocks_count++; 315 } 316 return 0; 317} 318 319static void mark_table_blocks(ext2_filsys fs) 320{ 321 blk64_t first_block, b; 322 unsigned int i,j; 323 324 first_block = fs->super->s_first_data_block; 325 /* 326 * Mark primary superblock 327 */ 328 ext2fs_mark_block_bitmap2(meta_block_map, first_block); 329 meta_blocks_count++; 330 331 /* 332 * Mark the primary superblock descriptors 333 */ 334 for (j = 0; j < fs->desc_blocks; j++) { 335 ext2fs_mark_block_bitmap2(meta_block_map, 336 ext2fs_descriptor_block_loc2(fs, first_block, j)); 337 } 338 meta_blocks_count += fs->desc_blocks; 339 340 for (i = 0; i < fs->group_desc_count; i++) { 341 /* 342 * Mark the blocks used for the inode table 343 */ 344 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) && 345 ext2fs_inode_table_loc(fs, i)) { 346 unsigned int end = (unsigned) fs->inode_blocks_per_group; 347 /* skip unused blocks */ 348 if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 349 EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) 350 end -= (ext2fs_bg_itable_unused(fs, i) / 351 EXT2_INODES_PER_BLOCK(fs->super)); 352 for (j = 0, b = ext2fs_inode_table_loc(fs, i); 353 j < end; 354 j++, b++) { 355 ext2fs_mark_block_bitmap2(meta_block_map, b); 356 meta_blocks_count++; 357 } 358 } 359 360 /* 361 * Mark block used for the block bitmap 362 */ 363 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) && 364 ext2fs_block_bitmap_loc(fs, i)) { 365 ext2fs_mark_block_bitmap2(meta_block_map, 366 ext2fs_block_bitmap_loc(fs, i)); 367 meta_blocks_count++; 368 } 369 370 /* 371 * Mark block used for the inode bitmap 372 */ 373 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) && 374 ext2fs_inode_bitmap_loc(fs, i)) { 375 ext2fs_mark_block_bitmap2(meta_block_map, 376 ext2fs_inode_bitmap_loc(fs, i)); 377 meta_blocks_count++; 378 } 379 } 380} 381 382/* 383 * This function returns 1 if the specified block is all zeros 384 */ 385static int check_zero_block(char *buf, int blocksize) 386{ 387 char *cp = buf; 388 int left = blocksize; 389 390 while (left > 0) { 391 if (*cp++) 392 return 0; 393 left--; 394 } 395 return 1; 396} 397 398static void write_block(int fd, char *buf, int sparse_offset, 399 int blocksize, blk64_t block) 400{ 401 ext2_loff_t ret = 0; 402 403 if (sparse_offset) 404 ret = ext2fs_llseek(fd, sparse_offset, SEEK_CUR); 405 406 if (ret < 0) 407 lseek_error_and_exit(errno); 408 generic_write(fd, buf, blocksize, block); 409} 410 411int name_id[256]; 412 413#define EXT4_MAX_REC_LEN ((1<<16)-1) 414 415static void scramble_dir_block(ext2_filsys fs, blk64_t blk, char *buf) 416{ 417 char *p, *end, *cp; 418 struct ext2_dir_entry_2 *dirent; 419 unsigned int rec_len; 420 int id, len; 421 422 end = buf + fs->blocksize; 423 for (p = buf; p < end-8; p += rec_len) { 424 dirent = (struct ext2_dir_entry_2 *) p; 425 rec_len = dirent->rec_len; 426#ifdef WORDS_BIGENDIAN 427 rec_len = ext2fs_swab16(rec_len); 428#endif 429 if (rec_len == EXT4_MAX_REC_LEN || rec_len == 0) 430 rec_len = fs->blocksize; 431 else 432 rec_len = (rec_len & 65532) | ((rec_len & 3) << 16); 433#if 0 434 printf("rec_len = %d, name_len = %d\n", rec_len, dirent->name_len); 435#endif 436 if (rec_len < 8 || (rec_len % 4) || 437 (p+rec_len > end)) { 438 printf("Corrupt directory block %lu: " 439 "bad rec_len (%d)\n", (unsigned long) blk, 440 rec_len); 441 rec_len = end - p; 442 (void) ext2fs_set_rec_len(fs, rec_len, 443 (struct ext2_dir_entry *) dirent); 444#ifdef WORDS_BIGENDIAN 445 dirent->rec_len = ext2fs_swab16(dirent->rec_len); 446#endif 447 continue; 448 } 449 if (dirent->name_len + 8 > rec_len) { 450 printf("Corrupt directory block %lu: " 451 "bad name_len (%d)\n", (unsigned long) blk, 452 dirent->name_len); 453 dirent->name_len = rec_len - 8; 454 continue; 455 } 456 cp = p+8; 457 len = rec_len - dirent->name_len - 8; 458 if (len > 0) 459 memset(cp+dirent->name_len, 0, len); 460 if (dirent->name_len==1 && cp[0] == '.') 461 continue; 462 if (dirent->name_len==2 && cp[0] == '.' && cp[1] == '.') 463 continue; 464 465 memset(cp, 'A', dirent->name_len); 466 len = dirent->name_len; 467 id = name_id[len]++; 468 while ((len > 0) && (id > 0)) { 469 *cp += id % 26; 470 id = id / 26; 471 cp++; 472 len--; 473 } 474 } 475} 476 477static void output_meta_data_blocks(ext2_filsys fs, int fd) 478{ 479 errcode_t retval; 480 blk64_t blk; 481 char *buf, *zero_buf; 482 int sparse = 0; 483 484 retval = ext2fs_get_mem(fs->blocksize, &buf); 485 if (retval) { 486 com_err(program_name, retval, "while allocating buffer"); 487 exit(1); 488 } 489 retval = ext2fs_get_memzero(fs->blocksize, &zero_buf); 490 if (retval) { 491 com_err(program_name, retval, "while allocating buffer"); 492 exit(1); 493 } 494 for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) { 495 if ((blk >= fs->super->s_first_data_block) && 496 ext2fs_test_block_bitmap2(meta_block_map, blk)) { 497 retval = io_channel_read_blk64(fs->io, blk, 1, buf); 498 if (retval) { 499 com_err(program_name, retval, 500 "error reading block %llu", blk); 501 } 502 if (scramble_block_map && 503 ext2fs_test_block_bitmap2(scramble_block_map, blk)) 504 scramble_dir_block(fs, blk, buf); 505 if ((fd != 1) && check_zero_block(buf, fs->blocksize)) 506 goto sparse_write; 507 write_block(fd, buf, sparse, fs->blocksize, blk); 508 sparse = 0; 509 } else { 510 sparse_write: 511 if (fd == 1) { 512 write_block(fd, zero_buf, 0, 513 fs->blocksize, blk); 514 continue; 515 } 516 sparse += fs->blocksize; 517 if (sparse > 1024*1024) { 518 write_block(fd, 0, 1024*1024, 0, 0); 519 sparse -= 1024*1024; 520 } 521 } 522 } 523#ifdef HAVE_FTRUNCATE64 524 if (sparse) { 525 ext2_loff_t offset = ext2fs_llseek(fd, sparse, SEEK_CUR); 526 527 if (offset < 0) 528 lseek_error_and_exit(errno); 529 if (ftruncate64(fd, offset) < 0) 530 write_block(fd, zero_buf, -1, 1, -1); 531 } 532#else 533 if (sparse) 534 write_block(fd, zero_buf, sparse-1, 1, -1); 535#endif 536 ext2fs_free_mem(&zero_buf); 537 ext2fs_free_mem(&buf); 538} 539 540static void init_l1_table(struct ext2_qcow2_image *image) 541{ 542 __u64 *l1_table; 543 errcode_t ret; 544 545 ret = ext2fs_get_arrayzero(image->l1_size, sizeof(__u64), &l1_table); 546 if (ret) { 547 com_err(program_name, ret, "while allocating l1 table"); 548 exit(1); 549 } 550 551 image->l1_table = l1_table; 552} 553 554static void init_l2_cache(struct ext2_qcow2_image *image) 555{ 556 unsigned int count, i; 557 struct ext2_qcow2_l2_cache *cache; 558 struct ext2_qcow2_l2_table *table; 559 errcode_t ret; 560 561 ret = ext2fs_get_arrayzero(1, sizeof(struct ext2_qcow2_l2_cache), 562 &cache); 563 if (ret) 564 goto alloc_err; 565 566 count = (image->l1_size > L2_CACHE_PREALLOC) ? L2_CACHE_PREALLOC : 567 image->l1_size; 568 569 cache->count = count; 570 cache->free = count; 571 cache->next_offset = image->l2_offset; 572 573 for (i = 0; i < count; i++) { 574 ret = ext2fs_get_arrayzero(1, 575 sizeof(struct ext2_qcow2_l2_table), &table); 576 if (ret) 577 goto alloc_err; 578 579 ret = ext2fs_get_arrayzero(image->l2_size, 580 sizeof(__u64), &table->data); 581 if (ret) 582 goto alloc_err; 583 584 table->next = cache->free_head; 585 cache->free_head = table; 586 } 587 588 image->l2_cache = cache; 589 return; 590 591alloc_err: 592 com_err(program_name, ret, "while allocating l2 cache"); 593 exit(1); 594} 595 596static void put_l2_cache(struct ext2_qcow2_image *image) 597{ 598 struct ext2_qcow2_l2_cache *cache = image->l2_cache; 599 struct ext2_qcow2_l2_table *tmp, *table; 600 601 if (!cache) 602 return; 603 604 table = cache->free_head; 605 cache->free_head = NULL; 606again: 607 while (table) { 608 tmp = table; 609 table = table->next; 610 ext2fs_free_mem(&tmp->data); 611 ext2fs_free_mem(&tmp); 612 } 613 614 if (cache->free != cache->count) { 615 fprintf(stderr, "Warning: There are still tables in the " 616 "cache while putting the cache, data will " 617 "be lost so the image may not be valid.\n"); 618 table = cache->used_head; 619 cache->used_head = NULL; 620 goto again; 621 } 622 623 ext2fs_free_mem(&cache); 624} 625 626static int init_refcount(struct ext2_qcow2_image *img, blk64_t table_offset) 627{ 628 struct ext2_qcow2_refcount *ref; 629 blk64_t table_clusters; 630 errcode_t ret; 631 632 ref = &(img->refcount); 633 634 /* 635 * One refcount block addresses 2048 clusters, one refcount table 636 * addresses cluster/sizeof(__u64) refcount blocks, and we need 637 * to address meta_blocks_count clusters + qcow2 metadata clusters 638 * in the worst case. 639 */ 640 table_clusters = meta_blocks_count + (table_offset >> 641 img->cluster_bits); 642 table_clusters >>= (img->cluster_bits + 6 - 1); 643 table_clusters = (table_clusters == 0) ? 1 : table_clusters; 644 645 ref->refcount_table_offset = table_offset; 646 ref->refcount_table_clusters = table_clusters; 647 ref->refcount_table_index = 0; 648 ref->refcount_block_index = 0; 649 650 /* Allocate refcount table */ 651 ret = ext2fs_get_arrayzero(ref->refcount_table_clusters, 652 img->cluster_size, &ref->refcount_table); 653 if (ret) 654 return ret; 655 656 /* Allocate refcount block */ 657 ret = ext2fs_get_arrayzero(1, img->cluster_size, &ref->refcount_block); 658 if (ret) 659 ext2fs_free_mem(&ref->refcount_table); 660 661 return ret; 662} 663 664static int initialize_qcow2_image(int fd, ext2_filsys fs, 665 struct ext2_qcow2_image *image) 666{ 667 struct ext2_qcow2_hdr *header; 668 blk64_t total_size, offset; 669 int shift, l2_bits, header_size, l1_size, ret; 670 int cluster_bits = get_bits_from_size(fs->blocksize); 671 struct ext2_super_block *sb = fs->super; 672 673 /* Allocate header */ 674 ret = ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr), &header); 675 if (ret) 676 return ret; 677 678 total_size = ext2fs_blocks_count(sb) << cluster_bits; 679 image->cluster_size = fs->blocksize; 680 image->l2_size = 1 << (cluster_bits - 3); 681 image->cluster_bits = cluster_bits; 682 image->fd = fd; 683 684 header->magic = ext2fs_cpu_to_be32(QCOW_MAGIC); 685 header->version = ext2fs_cpu_to_be32(QCOW_VERSION); 686 header->size = ext2fs_cpu_to_be64(total_size); 687 header->cluster_bits = ext2fs_cpu_to_be32(cluster_bits); 688 689 header_size = (sizeof(struct ext2_qcow2_hdr) + 7) & ~7; 690 offset = align_offset(header_size, image->cluster_size); 691 692 header->l1_table_offset = ext2fs_cpu_to_be64(offset); 693 image->l1_offset = offset; 694 695 l2_bits = cluster_bits - 3; 696 shift = cluster_bits + l2_bits; 697 l1_size = ((total_size + (1LL << shift) - 1) >> shift); 698 header->l1_size = ext2fs_cpu_to_be32(l1_size); 699 image->l1_size = l1_size; 700 701 /* Make space for L1 table */ 702 offset += align_offset(l1_size * sizeof(blk64_t), image->cluster_size); 703 704 /* Initialize refcounting */ 705 ret = init_refcount(image, offset); 706 if (ret) { 707 ext2fs_free_mem(&header); 708 return ret; 709 } 710 header->refcount_table_offset = ext2fs_cpu_to_be64(offset); 711 header->refcount_table_clusters = 712 ext2fs_cpu_to_be32(image->refcount.refcount_table_clusters); 713 offset += image->cluster_size; 714 offset += image->refcount.refcount_table_clusters << 715 image->cluster_bits; 716 717 /* Make space for L2 tables */ 718 image->l2_offset = offset; 719 offset += image->cluster_size; 720 721 /* Make space for first refcount block */ 722 image->refcount.refcount_block_offset = offset; 723 724 image->hdr = header; 725 /* Initialize l1 and l2 tables */ 726 init_l1_table(image); 727 init_l2_cache(image); 728 729 return 0; 730} 731 732static void free_qcow2_image(struct ext2_qcow2_image *img) 733{ 734 if (!img) 735 return; 736 737 if (img->hdr) 738 ext2fs_free_mem(&img->hdr); 739 740 if (img->l1_table) 741 ext2fs_free_mem(&img->l1_table); 742 743 if (img->refcount.refcount_table) 744 ext2fs_free_mem(&img->refcount.refcount_table); 745 if (img->refcount.refcount_block) 746 ext2fs_free_mem(&img->refcount.refcount_block); 747 748 put_l2_cache(img); 749 750 ext2fs_free_mem(&img); 751} 752 753/** 754 * Put table from used list (used_head) into free list (free_head). 755 * l2_table is used to return pointer to the next used table (used_head). 756 */ 757static void put_used_table(struct ext2_qcow2_image *img, 758 struct ext2_qcow2_l2_table **l2_table) 759{ 760 struct ext2_qcow2_l2_cache *cache = img->l2_cache; 761 struct ext2_qcow2_l2_table *table; 762 763 table = cache->used_head; 764 cache->used_head = table->next; 765 766 assert(table); 767 if (!table->next) 768 cache->used_tail = NULL; 769 770 /* Clean the table for case we will need to use it again */ 771 memset(table->data, 0, img->cluster_size); 772 table->next = cache->free_head; 773 cache->free_head = table; 774 775 cache->free++; 776 777 *l2_table = cache->used_head; 778} 779 780static void flush_l2_cache(struct ext2_qcow2_image *image) 781{ 782 blk64_t seek = 0; 783 ext2_loff_t offset; 784 struct ext2_qcow2_l2_cache *cache = image->l2_cache; 785 struct ext2_qcow2_l2_table *table = cache->used_head; 786 int fd = image->fd; 787 788 /* Store current position */ 789 if ((offset = ext2fs_llseek(fd, 0, SEEK_CUR)) < 0) 790 lseek_error_and_exit(errno); 791 792 assert(table); 793 while (cache->free < cache->count) { 794 if (seek != table->offset) { 795 if (ext2fs_llseek(fd, table->offset, SEEK_SET) < 0) 796 lseek_error_and_exit(errno); 797 seek = table->offset; 798 } 799 800 generic_write(fd, (char *)table->data, image->cluster_size , 0); 801 put_used_table(image, &table); 802 seek += image->cluster_size; 803 } 804 805 /* Restore previous position */ 806 if (ext2fs_llseek(fd, offset, SEEK_SET) < 0) 807 lseek_error_and_exit(errno); 808} 809 810/** 811 * Get first free table (from free_head) and put it into tail of used list 812 * (to used_tail). 813 * l2_table is used to return pointer to moved table. 814 * Returns 1 if the cache is full, 0 otherwise. 815 */ 816static void get_free_table(struct ext2_qcow2_image *image, 817 struct ext2_qcow2_l2_table **l2_table) 818{ 819 struct ext2_qcow2_l2_table *table; 820 struct ext2_qcow2_l2_cache *cache = image->l2_cache; 821 822 if (0 == cache->free) 823 flush_l2_cache(image); 824 825 table = cache->free_head; 826 assert(table); 827 cache->free_head = table->next; 828 829 if (cache->used_tail) 830 cache->used_tail->next = table; 831 else 832 /* First item in the used list */ 833 cache->used_head = table; 834 835 cache->used_tail = table; 836 cache->free--; 837 838 *l2_table = table; 839} 840 841static int add_l2_item(struct ext2_qcow2_image *img, blk64_t blk, 842 blk64_t data, blk64_t next) 843{ 844 struct ext2_qcow2_l2_cache *cache = img->l2_cache; 845 struct ext2_qcow2_l2_table *table = cache->used_tail; 846 blk64_t l1_index = blk / img->l2_size; 847 blk64_t l2_index = blk & (img->l2_size - 1); 848 int ret = 0; 849 850 /* 851 * Need to create new table if it does not exist, 852 * or if it is full 853 */ 854 if (!table || (table->l1_index != l1_index)) { 855 get_free_table(img, &table); 856 table->l1_index = l1_index; 857 table->offset = cache->next_offset; 858 cache->next_offset = next; 859 img->l1_table[l1_index] = 860 ext2fs_cpu_to_be64(table->offset | QCOW_OFLAG_COPIED); 861 ret++; 862 } 863 864 table->data[l2_index] = ext2fs_cpu_to_be64(data | QCOW_OFLAG_COPIED); 865 return ret; 866} 867 868static int update_refcount(int fd, struct ext2_qcow2_image *img, 869 blk64_t offset, blk64_t rfblk_pos) 870{ 871 struct ext2_qcow2_refcount *ref; 872 __u32 table_index; 873 int ret = 0; 874 875 ref = &(img->refcount); 876 table_index = offset >> (2 * img->cluster_bits - 1); 877 878 /* 879 * Need to create new refcount block when the offset addresses 880 * another item in the refcount table 881 */ 882 if (table_index != ref->refcount_table_index) { 883 884 if (ext2fs_llseek(fd, ref->refcount_block_offset, SEEK_SET) < 0) 885 lseek_error_and_exit(errno); 886 887 generic_write(fd, (char *)ref->refcount_block, 888 img->cluster_size, 0); 889 memset(ref->refcount_block, 0, img->cluster_size); 890 891 ref->refcount_table[ref->refcount_table_index] = 892 ext2fs_cpu_to_be64(ref->refcount_block_offset); 893 ref->refcount_block_offset = rfblk_pos; 894 ref->refcount_block_index = 0; 895 ref->refcount_table_index = table_index; 896 ret++; 897 } 898 899 /* 900 * We are relying on the fact that we are creating the qcow2 901 * image sequentially, hence we will always allocate refcount 902 * block items sequentialy. 903 */ 904 ref->refcount_block[ref->refcount_block_index] = ext2fs_cpu_to_be16(1); 905 ref->refcount_block_index++; 906 return ret; 907} 908 909static int sync_refcount(int fd, struct ext2_qcow2_image *img) 910{ 911 struct ext2_qcow2_refcount *ref; 912 913 ref = &(img->refcount); 914 915 ref->refcount_table[ref->refcount_table_index] = 916 ext2fs_cpu_to_be64(ref->refcount_block_offset); 917 if (ext2fs_llseek(fd, ref->refcount_table_offset, SEEK_SET) < 0) 918 lseek_error_and_exit(errno); 919 generic_write(fd, (char *)ref->refcount_table, 920 ref->refcount_table_clusters << img->cluster_bits, 0); 921 922 if (ext2fs_llseek(fd, ref->refcount_block_offset, SEEK_SET) < 0) 923 lseek_error_and_exit(errno); 924 generic_write(fd, (char *)ref->refcount_block, img->cluster_size, 0); 925 return 0; 926} 927 928static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd) 929{ 930 errcode_t retval; 931 blk64_t blk, offset, size, end; 932 char *buf; 933 struct ext2_qcow2_image *img; 934 unsigned int header_size; 935 936 /* allocate struct ext2_qcow2_image */ 937 retval = ext2fs_get_mem(sizeof(struct ext2_qcow2_image), &img); 938 if (retval) { 939 com_err(program_name, retval, 940 "while allocating ext2_qcow2_image"); 941 exit(1); 942 } 943 944 retval = initialize_qcow2_image(fd, fs, img); 945 if (retval) { 946 com_err(program_name, retval, 947 "while initializing ext2_qcow2_image"); 948 exit(1); 949 } 950 header_size = align_offset(sizeof(struct ext2_qcow2_hdr), 951 img->cluster_size); 952 write_header(fd, img->hdr, sizeof(struct ext2_qcow2_hdr), header_size); 953 954 /* Refcount all qcow2 related metadata up to refcount_block_offset */ 955 end = img->refcount.refcount_block_offset; 956 if (ext2fs_llseek(fd, end, SEEK_SET) < 0) 957 lseek_error_and_exit(errno); 958 blk = end + img->cluster_size; 959 for (offset = 0; offset <= end; offset += img->cluster_size) { 960 if (update_refcount(fd, img, offset, blk)) { 961 blk += img->cluster_size; 962 /* 963 * If we create new refcount block, we need to refcount 964 * it as well. 965 */ 966 end += img->cluster_size; 967 } 968 } 969 if (ext2fs_llseek(fd, offset, SEEK_SET) < 0) 970 lseek_error_and_exit(errno); 971 972 retval = ext2fs_get_mem(fs->blocksize, &buf); 973 if (retval) { 974 com_err(program_name, retval, "while allocating buffer"); 975 exit(1); 976 } 977 /* Write qcow2 data blocks */ 978 for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) { 979 if ((blk >= fs->super->s_first_data_block) && 980 ext2fs_test_block_bitmap2(meta_block_map, blk)) { 981 retval = io_channel_read_blk64(fs->io, blk, 1, buf); 982 if (retval) { 983 com_err(program_name, retval, 984 "error reading block %llu", blk); 985 continue; 986 } 987 if (scramble_block_map && 988 ext2fs_test_block_bitmap2(scramble_block_map, blk)) 989 scramble_dir_block(fs, blk, buf); 990 if (check_zero_block(buf, fs->blocksize)) 991 continue; 992 993 if (update_refcount(fd, img, offset, offset)) { 994 /* Make space for another refcount block */ 995 offset += img->cluster_size; 996 if (ext2fs_llseek(fd, offset, SEEK_SET) < 0) 997 lseek_error_and_exit(errno); 998 /* 999 * We have created the new refcount block, this 1000 * means that we need to refcount it as well. 1001 * So the previous update_refcount refcounted 1002 * the block itself and now we are going to 1003 * create refcount for data. New refcount 1004 * block should not be created! 1005 */ 1006 if (update_refcount(fd, img, offset, offset)) { 1007 fprintf(stderr, "Programming error: " 1008 "multiple sequential refcount " 1009 "blocks created!\n"); 1010 exit(1); 1011 } 1012 } 1013 1014 generic_write(fd, buf, fs->blocksize, 0); 1015 1016 if (add_l2_item(img, blk, offset, 1017 offset + img->cluster_size)) { 1018 offset += img->cluster_size; 1019 if (update_refcount(fd, img, offset, 1020 offset + img->cluster_size)) { 1021 offset += img->cluster_size; 1022 if (update_refcount(fd, img, offset, 1023 offset)) { 1024 fprintf(stderr, 1025 "Programming error: multiple sequential refcount " 1026 "blocks created!\n"); 1027 exit(1); 1028 } 1029 } 1030 offset += img->cluster_size; 1031 if (ext2fs_llseek(fd, offset, SEEK_SET) < 0) 1032 lseek_error_and_exit(errno); 1033 continue; 1034 } 1035 1036 offset += img->cluster_size; 1037 } 1038 } 1039 update_refcount(fd, img, offset, offset); 1040 flush_l2_cache(img); 1041 sync_refcount(fd, img); 1042 1043 /* Write l1_table*/ 1044 if (ext2fs_llseek(fd, img->l1_offset, SEEK_SET) < 0) 1045 lseek_error_and_exit(errno); 1046 size = img->l1_size * sizeof(__u64); 1047 generic_write(fd, (char *)img->l1_table, size, 0); 1048 1049 ext2fs_free_mem(&buf); 1050 free_qcow2_image(img); 1051} 1052 1053static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags) 1054{ 1055 struct process_block_struct pb; 1056 struct ext2_inode inode; 1057 ext2_inode_scan scan; 1058 ext2_ino_t ino; 1059 errcode_t retval; 1060 char * block_buf; 1061 1062 meta_blocks_count = 0; 1063 retval = ext2fs_allocate_block_bitmap(fs, "in-use block map", 1064 &meta_block_map); 1065 if (retval) { 1066 com_err(program_name, retval, "while allocating block bitmap"); 1067 exit(1); 1068 } 1069 1070 if (flags & E2IMAGE_SCRAMBLE_FLAG) { 1071 retval = ext2fs_allocate_block_bitmap(fs, "scramble block map", 1072 &scramble_block_map); 1073 if (retval) { 1074 com_err(program_name, retval, 1075 "while allocating scramble block bitmap"); 1076 exit(1); 1077 } 1078 } 1079 1080 mark_table_blocks(fs); 1081 1082 retval = ext2fs_open_inode_scan(fs, 0, &scan); 1083 if (retval) { 1084 com_err(program_name, retval, _("while opening inode scan")); 1085 exit(1); 1086 } 1087 1088 retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf); 1089 if (retval) { 1090 com_err(program_name, 0, "Can't allocate block buffer"); 1091 exit(1); 1092 } 1093 1094 use_inode_shortcuts(fs, 1); 1095 stashed_inode = &inode; 1096 while (1) { 1097 retval = ext2fs_get_next_inode(scan, &ino, &inode); 1098 if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) 1099 continue; 1100 if (retval) { 1101 com_err(program_name, retval, 1102 _("while getting next inode")); 1103 exit(1); 1104 } 1105 if (ino == 0) 1106 break; 1107 if (!inode.i_links_count) 1108 continue; 1109 if (ext2fs_file_acl_block(fs, &inode)) { 1110 ext2fs_mark_block_bitmap2(meta_block_map, 1111 ext2fs_file_acl_block(fs, &inode)); 1112 meta_blocks_count++; 1113 } 1114 if (!ext2fs_inode_has_valid_blocks2(fs, &inode)) 1115 continue; 1116 1117 stashed_ino = ino; 1118 pb.ino = ino; 1119 pb.is_dir = LINUX_S_ISDIR(inode.i_mode); 1120 if (LINUX_S_ISDIR(inode.i_mode) || 1121 (LINUX_S_ISLNK(inode.i_mode) && 1122 ext2fs_inode_has_valid_blocks2(fs, &inode)) || 1123 ino == fs->super->s_journal_inum) { 1124 retval = ext2fs_block_iterate3(fs, ino, 1125 BLOCK_FLAG_READ_ONLY, block_buf, 1126 process_dir_block, &pb); 1127 if (retval) { 1128 com_err(program_name, retval, 1129 "while iterating over inode %u", 1130 ino); 1131 exit(1); 1132 } 1133 } else { 1134 if ((inode.i_flags & EXT4_EXTENTS_FL) || 1135 inode.i_block[EXT2_IND_BLOCK] || 1136 inode.i_block[EXT2_DIND_BLOCK] || 1137 inode.i_block[EXT2_TIND_BLOCK]) { 1138 retval = ext2fs_block_iterate3(fs, 1139 ino, BLOCK_FLAG_READ_ONLY, block_buf, 1140 process_file_block, &pb); 1141 if (retval) { 1142 com_err(program_name, retval, 1143 "while iterating over inode %u", ino); 1144 exit(1); 1145 } 1146 } 1147 } 1148 } 1149 use_inode_shortcuts(fs, 0); 1150 1151 if (type & E2IMAGE_QCOW2) 1152 output_qcow2_meta_data_blocks(fs, fd); 1153 else 1154 output_meta_data_blocks(fs, fd); 1155 1156 ext2fs_free_mem(&block_buf); 1157 ext2fs_close_inode_scan(scan); 1158 ext2fs_free_block_bitmap(meta_block_map); 1159 if (type & E2IMAGE_SCRAMBLE_FLAG) 1160 ext2fs_free_block_bitmap(scramble_block_map); 1161} 1162 1163static void install_image(char *device, char *image_fn, int type) 1164{ 1165 errcode_t retval; 1166 ext2_filsys fs; 1167 int open_flag = EXT2_FLAG_IMAGE_FILE; 1168 int fd = 0; 1169 io_manager io_ptr; 1170 io_channel io; 1171 1172 if (type) { 1173 com_err(program_name, 0, "Raw and qcow2 images cannot" 1174 "be installed"); 1175 exit(1); 1176 } 1177 1178#ifdef CONFIG_TESTIO_DEBUG 1179 if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) { 1180 io_ptr = test_io_manager; 1181 test_io_backing_manager = unix_io_manager; 1182 } else 1183#endif 1184 io_ptr = unix_io_manager; 1185 1186 retval = ext2fs_open (image_fn, open_flag, 0, 0, 1187 io_ptr, &fs); 1188 if (retval) { 1189 com_err (program_name, retval, _("while trying to open %s"), 1190 image_fn); 1191 exit(1); 1192 } 1193 1194 retval = ext2fs_read_bitmaps (fs); 1195 if (retval) { 1196 com_err(program_name, retval, "error reading bitmaps"); 1197 exit(1); 1198 } 1199 1200 fd = ext2fs_open_file(image_fn, O_RDONLY, 0); 1201 if (fd < 0) { 1202 perror(image_fn); 1203 exit(1); 1204 } 1205 1206 retval = io_ptr->open(device, IO_FLAG_RW, &io); 1207 if (retval) { 1208 com_err(device, 0, "while opening device file"); 1209 exit(1); 1210 } 1211 1212 ext2fs_rewrite_to_io(fs, io); 1213 1214 if (ext2fs_llseek(fd, fs->image_header->offset_inode, SEEK_SET) < 0) { 1215 perror("ext2fs_llseek"); 1216 exit(1); 1217 } 1218 1219 retval = ext2fs_image_inode_read(fs, fd, 0); 1220 if (retval) { 1221 com_err(image_fn, 0, "while restoring the image table"); 1222 exit(1); 1223 } 1224 1225 ext2fs_close (fs); 1226 exit (0); 1227} 1228 1229static struct ext2_qcow2_hdr *check_qcow2_image(int *fd, char *name) 1230{ 1231 1232 *fd = ext2fs_open_file(name, O_RDONLY, 0600); 1233 if (*fd < 0) 1234 return NULL; 1235 1236 return qcow2_read_header(*fd); 1237} 1238 1239int main (int argc, char ** argv) 1240{ 1241 int c; 1242 errcode_t retval; 1243 ext2_filsys fs; 1244 char *image_fn; 1245 struct ext2_qcow2_hdr *header = NULL; 1246 int open_flag = EXT2_FLAG_64BITS; 1247 int img_type = 0; 1248 int flags = 0; 1249 int qcow2_fd = 0; 1250 int fd = 0; 1251 int ret = 0; 1252 1253#ifdef ENABLE_NLS 1254 setlocale(LC_MESSAGES, ""); 1255 setlocale(LC_CTYPE, ""); 1256 bindtextdomain(NLS_CAT_NAME, LOCALEDIR); 1257 textdomain(NLS_CAT_NAME); 1258 set_com_err_gettext(gettext); 1259#endif 1260 fprintf (stderr, "e2image %s (%s)\n", E2FSPROGS_VERSION, 1261 E2FSPROGS_DATE); 1262 if (argc && *argv) 1263 program_name = *argv; 1264 add_error_table(&et_ext2_error_table); 1265 while ((c = getopt(argc, argv, "rsIQ")) != EOF) 1266 switch (c) { 1267 case 'I': 1268 flags |= E2IMAGE_INSTALL_FLAG; 1269 break; 1270 case 'Q': 1271 if (img_type) 1272 usage(); 1273 img_type |= E2IMAGE_QCOW2; 1274 break; 1275 case 'r': 1276 if (img_type) 1277 usage(); 1278 img_type |= E2IMAGE_RAW; 1279 break; 1280 case 's': 1281 flags |= E2IMAGE_SCRAMBLE_FLAG; 1282 break; 1283 default: 1284 usage(); 1285 } 1286 if (optind != argc - 2 ) 1287 usage(); 1288 device_name = argv[optind]; 1289 image_fn = argv[optind+1]; 1290 1291 if (flags & E2IMAGE_INSTALL_FLAG) { 1292 install_image(device_name, image_fn, img_type); 1293 exit (0); 1294 } 1295 1296 if (img_type & E2IMAGE_RAW) { 1297 header = check_qcow2_image(&qcow2_fd, device_name); 1298 if (header) { 1299 flags |= E2IMAGE_IS_QCOW2_FLAG; 1300 goto skip_device; 1301 } 1302 } 1303 1304 retval = ext2fs_open (device_name, open_flag, 0, 0, 1305 unix_io_manager, &fs); 1306 if (retval) { 1307 com_err (program_name, retval, _("while trying to open %s"), 1308 device_name); 1309 fputs(_("Couldn't find valid filesystem superblock.\n"), stdout); 1310 exit(1); 1311 } 1312 1313skip_device: 1314 if (strcmp(image_fn, "-") == 0) 1315 fd = 1; 1316 else { 1317 fd = ext2fs_open_file(image_fn, O_CREAT|O_TRUNC|O_WRONLY, 0600); 1318 if (fd < 0) { 1319 com_err(program_name, errno, 1320 _("while trying to open %s"), argv[optind+1]); 1321 exit(1); 1322 } 1323 } 1324 1325 if ((img_type & E2IMAGE_QCOW2) && (fd == 1)) { 1326 com_err(program_name, 0, "QCOW2 image can not be written to " 1327 "the stdout!\n"); 1328 exit(1); 1329 } 1330 1331 if (flags & E2IMAGE_IS_QCOW2_FLAG) { 1332 ret = qcow2_write_raw_image(qcow2_fd, fd, header); 1333 if (ret) { 1334 if (ret == -QCOW_COMPRESSED) 1335 fprintf(stderr, "Image (%s) is compressed\n", 1336 image_fn); 1337 if (ret == -QCOW_ENCRYPTED) 1338 fprintf(stderr, "Image (%s) is encrypted\n", 1339 image_fn); 1340 com_err(program_name, ret, 1341 _("while trying to convert qcow2 image" 1342 " (%s) into raw image (%s)"), 1343 device_name, image_fn); 1344 } 1345 goto out; 1346 } 1347 1348 1349 if (img_type) 1350 write_raw_image_file(fs, fd, img_type, flags); 1351 else 1352 write_image_file(fs, fd); 1353 1354 ext2fs_close (fs); 1355out: 1356 if (header) 1357 free(header); 1358 if (qcow2_fd) 1359 close(qcow2_fd); 1360 remove_error_table(&et_ext2_error_table); 1361 return ret; 1362} 1363