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