From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JQHse-0000Cl-Kn for qemu-devel@nongnu.org; Sat, 16 Feb 2008 02:54:40 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JQHsc-0000Bu-Kx for qemu-devel@nongnu.org; Sat, 16 Feb 2008 02:54:40 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JQHsc-0000Bn-EC for qemu-devel@nongnu.org; Sat, 16 Feb 2008 02:54:38 -0500 Received: from mx20.gnu.org ([199.232.41.8]) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1JQHsb-0005tW-LM for qemu-devel@nongnu.org; Sat, 16 Feb 2008 02:54:37 -0500 Received: from ecfrec.frec.bull.fr ([129.183.4.8]) by mx20.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1JQHs5-0006b0-NU for qemu-devel@nongnu.org; Sat, 16 Feb 2008 02:54:06 -0500 Subject: Re: [Qemu-devel] How to extract content of a raw image on host? From: Laurent Vivier In-Reply-To: <47B68E49.7020906@googlemail.com> References: <47B683F0.3050109@googlemail.com> <47B6858E.3020008@gmail.com> <47B68E49.7020906@googlemail.com> Content-Type: multipart/mixed; boundary="=-IKCbxdL3dAVx6hdmfV1U" Date: Sat, 16 Feb 2008 08:55:06 +0100 Message-Id: <1203148506.5305.4.camel@frecb07144> Mime-Version: 1.0 Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: JonY <10walls@gmail.com> --=-IKCbxdL3dAVx6hdmfV1U Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Le samedi 16 f=C3=A9vrier 2008 =C3=A0 08:18 +0100, Dirk Behme a =C3=A9cri= t : > JonY wrote: > > Dirk Behme wrote: > >=20 > >> Hi, > >> > >> is there a way to extract the contents of a qemu raw image on (x86=20 > >> Linux) host without starting QEMU itself? If so, any hint would be=20 > >> quite nice. > >> > >> I'm looking for anything like the reverse what > >> > >> http://lists.gnu.org/archive/html/qemu-devel/2006-04/msg00448.html > >> > >> seems to do. Extract files/directories from an existing raw image. > >> > >> qemu-img reports me > >> > >> > qemu-img info disk.img > >> image: disk.img > >> file format: raw > >> virtual size: 4.3M (4515328 bytes) > >> disk size: 4.3M > >> > >> but what is in it and how to access the content? > >> > >> Thanks, and sorry if this is a FAQ and I missed the correct search=20 > >> string, > >> > >> Dirk > >> > > Hi, > >=20 > > have you tried using a loop back mount? >=20 > # mount -o loop disk.img mnt/ > mount: You have to specify a file system type > # mount -t raw -o loop disk.img mnt/ > mount: unknown file system type =E2=80=9Eraw=E2=80=9C >=20 > Sorry if I miss the obvious ;) Loop is not able to manage partition. Either you use the offset option to point to the offset of the partition you want to mount in the raw image. Either you use the attached patch to be able to manage partition table with loop (and load the module with parameter "max_part=3D64") Laurent --=20 ----------------- Laurent.Vivier@bull.net ------------------ "Programmers who subconsciously view themselves as artists will enjoy what they do and will do it better." D. Knuth --=-IKCbxdL3dAVx6hdmfV1U Content-Disposition: attachment; filename*0=0001-Modify-loop-device-to-be-able-to-manage-partitions-o.pat; filename*1=ch Content-Type: application/mbox; name=0001-Modify-loop-device-to-be-able-to-manage-partitions-o.patch Content-Transfer-Encoding: 7bit >>From 12bb62c07ee5c69a170bd4e5dea5aaf9fd32c4eb Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Wed, 16 Jan 2008 14:42:21 +0100 Subject: [PATCH] Modify loop device to be able to manage partitions of the image disk Signed-off-by: Laurent Vivier --- drivers/block/loop.c | 44 ++++++++++++++++++++++++++++++++++++++------ 1 files changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 56e2304..52753f6 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -82,6 +82,9 @@ static LIST_HEAD(loop_devices); static DEFINE_MUTEX(loop_devices_mutex); +static int max_part = 1; +static int part_shift; + /* * Transfer functions */ @@ -692,6 +695,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file, goto out_putf; fput(old_file); + if (max_part > 1) + ioctl_by_bdev(bdev, BLKRRPART, 0); return 0; out_putf: @@ -819,6 +824,8 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, } lo->lo_state = Lo_bound; wake_up_process(lo->lo_thread); + if (max_part > 1) + ioctl_by_bdev(bdev, BLKRRPART, 0); return 0; out_clr: @@ -1352,6 +1359,8 @@ static struct block_device_operations lo_fops = { static int max_loop; module_param(max_loop, int, 0); MODULE_PARM_DESC(max_loop, "Maximum number of loop devices"); +module_param(max_part, int, 0); +MODULE_PARM_DESC(max_part, "Maximum number of partition by loop device"); MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); @@ -1404,7 +1413,7 @@ static struct loop_device *loop_alloc(int i) if (!lo->lo_queue) goto out_free_dev; - disk = lo->lo_disk = alloc_disk(1); + disk = lo->lo_disk = alloc_disk(1 << part_shift); if (!disk) goto out_free_queue; @@ -1414,7 +1423,7 @@ static struct loop_device *loop_alloc(int i) init_waitqueue_head(&lo->lo_event); spin_lock_init(&lo->lo_lock); disk->major = LOOP_MAJOR; - disk->first_minor = i; + disk->first_minor = i << part_shift; disk->fops = &lo_fops; disk->private_data = lo; disk->queue = lo->lo_queue; @@ -1477,7 +1486,7 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data) static int __init loop_init(void) { int i, nr; - unsigned long range; + unsigned long range, bitfield; struct loop_device *lo, *next; /* @@ -1494,7 +1503,11 @@ static int __init loop_init(void) * themselves and have kernel automatically instantiate actual * device on-demand. */ - if (max_loop > 1UL << MINORBITS) + + bitfield = max_part; + part_shift = find_first_bit(&bitfield, sizeof(bitfield)); + + if (max_loop > 1UL << (MINORBITS - part_shift)) return -EINVAL; if (max_loop) { @@ -1502,7 +1515,7 @@ static int __init loop_init(void) range = max_loop; } else { nr = 8; - range = 1UL << MINORBITS; + range = 1UL << (MINORBITS - part_shift); } if (register_blkdev(LOOP_MAJOR, "loop")) @@ -1541,7 +1554,7 @@ static void __exit loop_exit(void) unsigned long range; struct loop_device *lo, *next; - range = max_loop ? max_loop : 1UL << MINORBITS; + range = max_loop ? max_loop : 1UL << (MINORBITS - part_shift); list_for_each_entry_safe(lo, next, &loop_devices, lo_list) loop_del_one(lo); @@ -1561,4 +1574,23 @@ static int __init max_loop_setup(char *str) } __setup("max_loop=", max_loop_setup); + +static int __init max_part_setup(char *str) +{ + max_part = simple_strtol(str, NULL, 0); + if (max_part < 1) { + /* there is at least one partition */ + printk(KERN_ERR "loop: max_part cannot be lesser than 1\n"); + return 0; + } + if (max_part > MINORBITS - 1) { + /* we must keep at least one bit for loop device number */ + printk(KERN_ERR "loop: max_part cannot be greater than %d\n", + MINORBITS - 1); + return 0; + } + return 1; +} + +__setup("max_part=", max_part_setup); #endif -- 1.5.2.4 --=-IKCbxdL3dAVx6hdmfV1U--