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