ia64/xen-unstable

changeset 5782:cd95b96a172e

Incorporate lomount from QEMU into tools/misc. This tool makes it easy to mount
individual partitions held within whole disk images.

Original source from http://www.dad-answers.com/qemu/utilities/QEMU-HD-Mounter/l
omount/lomount.c

* Copyright (c) 2004 Jim Brown
* Copyright (c) 2004 Brad Watson
* Copyright (c) 2004 Mulyadi Santosa

Signed-off-by: ian@xensource.com
author iap10@freefall.cl.cam.ac.uk
date Thu Jul 14 21:02:05 2005 +0000 (2005-07-14)
parents 98b83cc57eca
children 1febf5dabc4f
files .hgignore tools/misc/Makefile tools/misc/lomount/Makefile tools/misc/lomount/lomount.c
line diff
     1.1 --- a/.hgignore	Thu Jul 14 14:01:21 2005 +0000
     1.2 +++ b/.hgignore	Thu Jul 14 21:02:05 2005 +0000
     1.3 @@ -119,6 +119,7 @@
     1.4  ^tools/misc/mbootpack/mbootpack$
     1.5  ^tools/misc/mbootpack/setup$
     1.6  ^tools/misc/miniterm/miniterm$
     1.7 +^tools/misc/lomount/lomount$
     1.8  ^tools/misc/xc_shadow$
     1.9  ^tools/misc/xen_cpuperf$
    1.10  ^tools/misc/xenperf$
     2.1 --- a/tools/misc/Makefile	Thu Jul 14 14:01:21 2005 +0000
     2.2 +++ b/tools/misc/Makefile	Thu Jul 14 21:02:05 2005 +0000
     2.3 @@ -23,6 +23,7 @@ build: $(TARGETS)
     2.4  	$(MAKE) -C miniterm
     2.5  	$(MAKE) -C cpuperf
     2.6  	$(MAKE) -C mbootpack
     2.7 +	$(MAKE) -C lomount
     2.8  
     2.9  install: build
    2.10  	[ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin
    2.11 @@ -30,6 +31,7 @@ install: build
    2.12  	$(INSTALL_PROG) $(INSTALL_BIN) $(DESTDIR)/usr/bin
    2.13  	$(INSTALL_PROG) $(INSTALL_SBIN) $(DESTDIR)/usr/sbin
    2.14  	$(MAKE) -C cpuperf install
    2.15 +	$(MAKE) -C lomount install
    2.16  #       No sense in installing miniterm on the Xen box.
    2.17  #	$(MAKE) -C miniterm install
    2.18  #       Likewise mbootpack
    2.19 @@ -40,6 +42,7 @@ clean:
    2.20  	$(MAKE) -C miniterm clean
    2.21  	$(MAKE) -C cpuperf clean
    2.22  	$(MAKE) -C mbootpack clean
    2.23 +	$(MAKE) -C lomount clean
    2.24  
    2.25  %.o: %.c $(HDRS) Makefile
    2.26  	$(CC) -c $(CFLAGS) -o $@ $<
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/misc/lomount/Makefile	Thu Jul 14 21:02:05 2005 +0000
     3.3 @@ -0,0 +1,27 @@
     3.4 +INSTALL		= install
     3.5 +INSTALL_PROG	= $(INSTALL) -m0755
     3.6 +INSTALL_DIR	= $(INSTALL) -d -m0755
     3.7 +INSTALL_DATA	= $(INSTALL) -m0644
     3.8 +
     3.9 +XEN_ROOT=../../..
    3.10 +include $(XEN_ROOT)/tools/Rules.mk
    3.11 +
    3.12 +CFLAGS  += -Wall -Werror -O3
    3.13 +
    3.14 +HDRS     = $(wildcard *.h)
    3.15 +OBJS     = $(patsubst %.c,%.o,$(wildcard *.c))
    3.16 +
    3.17 +BIN      = lomount
    3.18 +
    3.19 +all: build
    3.20 +build: $(BIN)
    3.21 +
    3.22 +install: build
    3.23 +	$(INSTALL_PROG) $(BIN) $(SCRIPTS) $(DESTDIR)/usr/bin
    3.24 +
    3.25 +clean:
    3.26 +	$(RM) *.a *.so *.o *.rpm $(BIN)
    3.27 +
    3.28 +%: %.c $(HDRS) Makefile
    3.29 +	$(CC) $(CFLAGS) -o $@ $< 
    3.30 +
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/misc/lomount/lomount.c	Thu Jul 14 21:02:05 2005 +0000
     4.3 @@ -0,0 +1,262 @@
     4.4 +/*
     4.5 + * lomount - utility to mount partitions in a hard disk image
     4.6 + *
     4.7 + * Copyright (c) 2004 Jim Brown
     4.8 + * Copyright (c) 2004 Brad Watson
     4.9 + * Copyright (c) 2004 Mulyadi Santosa
    4.10 + *
    4.11 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    4.12 + * of this software and associated documentation files (the "Software"), to deal
    4.13 + * in the Software without restriction, including without limitation the rights
    4.14 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    4.15 + * copies of the Software, and to permit persons to whom the Software is
    4.16 + * furnished to do so, subject to the following conditions:
    4.17 + *
    4.18 + * The above copyright notice and this permission notice shall be included in
    4.19 + * all copies or substantial portions of the Software.
    4.20 + *
    4.21 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    4.22 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    4.23 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    4.24 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    4.25 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    4.26 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    4.27 + * THE SOFTWARE.
    4.28 + */
    4.29 +
    4.30 +#include <unistd.h>
    4.31 +#include <stdio.h>
    4.32 +#include <stdlib.h>
    4.33 +#include <string.h>
    4.34 +#include <strings.h>
    4.35 +#include <errno.h>
    4.36 +
    4.37 +#define BUF 4096
    4.38 +
    4.39 +//#define SECSIZE 4096    /* arbitrarilly large (it's probably just 512) */
    4.40 +#define SECSIZE 512
    4.41 +
    4.42 +struct pentry 
    4.43 +{
    4.44 +	unsigned char bootable; 
    4.45 +	unsigned char start_head;
    4.46 +	unsigned int start_cylinder;
    4.47 +	unsigned char start_sector;
    4.48 +	unsigned char system;
    4.49 +	unsigned char end_head;
    4.50 +	unsigned int  end_cylinder;
    4.51 +	unsigned char end_sector;
    4.52 +	unsigned long start_sector_abs;
    4.53 +	unsigned long no_of_sectors_abs;
    4.54 +};
    4.55 +
    4.56 +char * progname;
    4.57 +
    4.58 +int loadptable(const char *argv, struct pentry parttbl[], struct pentry **exttbl)
    4.59 +{
    4.60 +	FILE *fd; 
    4.61 +	int i, valid, total_known_sectors = 0;
    4.62 +	unsigned char *pi; 
    4.63 +	unsigned char data [SECSIZE]; 
    4.64 +	unsigned long extent = 0, old_extent = 0, e_count = 1;
    4.65 +	struct pentry exttbls[4];
    4.66 +
    4.67 +	fd = fopen(argv, "r");
    4.68 +	if (fd == NULL)
    4.69 +	{
    4.70 +		perror ("lomount"); 
    4.71 +		return 1;
    4.72 +	}
    4.73 +	i = fread (&data, 1, sizeof (data), fd); 
    4.74 +	if (i < SECSIZE)
    4.75 +	{
    4.76 +		fprintf (stderr, "%s: could not read the entire first sector\n", progname); 
    4.77 +		return 1;
    4.78 +	}
    4.79 +	for (i = 0;i < 4;i++)
    4.80 +	{
    4.81 +		pi = &data [446 + 16 * i];
    4.82 +		parttbl [i].bootable = *pi; 
    4.83 +		parttbl [i].start_head  = *(pi + 1); 
    4.84 +		parttbl [i].start_cylinder = *(pi + 3) | ((*(pi + 2) << 2) & 0x300);
    4.85 +		parttbl [i].start_sector = *(pi + 2) & 0x3f;
    4.86 +		parttbl [i].system = *(pi + 4);
    4.87 +		parttbl [i].end_head = *(pi + 5);
    4.88 +		parttbl [i].end_cylinder = *(pi + 7) | ((*(pi + 6) << 2) & 0x300);
    4.89 +		parttbl [i].end_sector = *(pi + 6) & 0x3f;
    4.90 +		parttbl [i].start_sector_abs = 
    4.91 +			(unsigned long) *(pi + 8) | ((unsigned long) *(pi + 9) << 8) | ((unsigned long) *(pi + 10) << 16) | ((unsigned long) *(pi + 11) << 24);
    4.92 +		parttbl [i].no_of_sectors_abs = 
    4.93 +			(unsigned long) *(pi + 12) | ((unsigned long) *(pi + 13) << 8) | ((unsigned long) *(pi + 14) << 16) | ((unsigned long) *(pi + 15) << 24);
    4.94 +		if (parttbl[i].system == 0xF || parttbl[i].system == 0x5)
    4.95 +		{
    4.96 +			extent = parttbl[i].start_sector_abs * SECSIZE;
    4.97 +			/* save the location of the "real" extended partition */
    4.98 +			old_extent = extent;
    4.99 +		}
   4.100 +	}
   4.101 +	valid = (data [510] == 0x55 && data [511] == 0xaa) ? 1 : 0;
   4.102 +	for (i = 0; i < 4; i++)
   4.103 +	{
   4.104 +		total_known_sectors += parttbl[i].no_of_sectors_abs;
   4.105 +	}
   4.106 +	/* Extended Partition layout format was obtained from
   4.107 +	http://wigner.cped.ornl.gov/the-gang/att-0520/03-Partition.htm */
   4.108 +#ifdef DEBUG
   4.109 +	if (extent != 0)
   4.110 +	{
   4.111 +		printf("extended partition detected at offset %d\n", extent);
   4.112 +	}
   4.113 +#endif
   4.114 +	while (extent != 0)
   4.115 +	{
   4.116 +/* according to realloc(3) passing NULL as pointer is same as calling malloc() */
   4.117 +		exttbl[0] = realloc(exttbl[0], e_count * sizeof(struct pentry));
   4.118 +		fseek(fd, extent, SEEK_SET);
   4.119 +		i = fread (&data, 1, sizeof (data), fd); 
   4.120 +		if (i < SECSIZE)
   4.121 +		{
   4.122 +			fprintf (stderr, "%s: could not read the entire first sector\n", progname); 
   4.123 +			return 1;
   4.124 +		}
   4.125 +	/* only first 2 entrys are used in extented partition tables */
   4.126 +		for (i = 0;i < 2;i++)
   4.127 +		{
   4.128 +			pi = &data [446 + 16 * i];
   4.129 +			exttbls [i].bootable = *pi; 
   4.130 +			exttbls [i].start_head  = *(pi + 1); 
   4.131 +			exttbls [i].start_cylinder = *(pi + 3) | ((*(pi + 2) << 2) & 0x300);
   4.132 +			exttbls [i].start_sector = *(pi + 2) & 0x3f;
   4.133 +			exttbls [i].system = *(pi + 4);
   4.134 +			exttbls [i].end_head = *(pi + 5);
   4.135 +			exttbls [i].end_cylinder = *(pi + 7) | ((*(pi + 6) << 2) & 0x300);
   4.136 +			exttbls [i].end_sector = *(pi + 6) & 0x3f;
   4.137 +			exttbls [i].start_sector_abs = 
   4.138 +				(unsigned long) *(pi + 8) | ((unsigned long) *(pi + 9) << 8) | ((unsigned long) *(pi + 10) << 16) | ((unsigned long) *(pi + 11) << 24);
   4.139 +			exttbls [i].no_of_sectors_abs = 
   4.140 +				(unsigned long) *(pi + 12) | ((unsigned long) *(pi + 13) << 8) | ((unsigned long) *(pi + 14) << 16) | ((unsigned long) *(pi + 15) << 24);
   4.141 +			if (i == 0)
   4.142 +			{
   4.143 +				//memmove((void *)exttbl[e_count-1], (void *)exttbls[i], sizeof(struct pentry));
   4.144 +				//memmove() seems broken!
   4.145 +				exttbl[0][e_count-1].bootable = exttbls [i].bootable;
   4.146 +				exttbl[0][e_count-1].start_head  = exttbls [i].start_head;
   4.147 +				exttbl[0][e_count-1].start_cylinder = exttbls [i].start_cylinder;
   4.148 +				exttbl[0][e_count-1].start_sector = exttbls [i].start_sector;
   4.149 +				exttbl[0][e_count-1].system = exttbls [i].system;
   4.150 +				exttbl[0][e_count-1].end_head = exttbls [i].end_head;
   4.151 +				exttbl[0][e_count-1].end_cylinder = exttbls [i].end_cylinder;
   4.152 +				exttbl[0][e_count-1].end_sector = exttbls [i].end_sector;
   4.153 +				exttbl[0][e_count-1].start_sector_abs = exttbls [i].start_sector_abs;
   4.154 +				exttbl[0][e_count-1].no_of_sectors_abs = exttbls [i].no_of_sectors_abs;
   4.155 +			/* adjust for start of image instead of start of ext partition */
   4.156 +				exttbl[0][e_count-1].start_sector_abs += (extent/SECSIZE);
   4.157 +#ifdef DEBUG
   4.158 +				printf("extent %d start_sector_abs %d\n", extent, exttbl[0][e_count-1].start_sector_abs);
   4.159 +#endif
   4.160 +			//else if (parttbl[i].system == 0x5)
   4.161 +			}
   4.162 +			else if (i == 1)
   4.163 +			{
   4.164 +				extent = (exttbls[i].start_sector_abs * SECSIZE);
   4.165 +				if (extent)
   4.166 +					extent += old_extent;
   4.167 +			}
   4.168 +		}
   4.169 +		e_count ++;
   4.170 +	}
   4.171 +	//fclose (fd);
   4.172 +	//the above segfaults (?!!!)
   4.173 +#ifdef DEBUG
   4.174 +	printf("e_count = %d\n", e_count);
   4.175 +#endif
   4.176 +	return valid;
   4.177 +}
   4.178 +
   4.179 +int main(int argc, char ** argv)
   4.180 +{
   4.181 +	struct pentry perttbl [4];
   4.182 +	struct pentry *exttbl[1], *parttbl;
   4.183 +	char buf[BUF], argv2[BUF], diskimage[BUF];
   4.184 +	int partition = 1, sec, num = 0, pnum = 0, len = BUF, i, f = 0, valid;
   4.185 +	progname = argv[0];
   4.186 +	exttbl[0] = NULL;
   4.187 +	for (i = 1; i < argc; i ++)
   4.188 +	{
   4.189 +		if (strncmp(argv[i], "-diskimage", BUF)==0)
   4.190 +		{
   4.191 +			strncpy(diskimage, argv[i+1], BUF);
   4.192 +			i++; f = 1;
   4.193 +		}
   4.194 +		else if (strncmp(argv[i], "-partition", BUF)==0)
   4.195 +		{
   4.196 +			partition = atoi(argv[i+1]);
   4.197 +			i++;
   4.198 +			if (partition < 1) partition = 1;
   4.199 +		}
   4.200 +		else
   4.201 +		{
   4.202 +			strncat(argv2, argv[i], len);
   4.203 +			strncat(argv2, " ", len-1);
   4.204 +			len -= strlen(argv[i]);
   4.205 +			len--;
   4.206 +		}
   4.207 +	}
   4.208 +	if (!f)
   4.209 +	{
   4.210 +		printf("You must specify -diskimage and -partition\n");
   4.211 +		printf("ex. lomount -t fs-type -diskimage hda.img -partition 1 /mnt\n");
   4.212 +		return 0;
   4.213 +	}
   4.214 +	valid = loadptable(diskimage, perttbl, exttbl);
   4.215 +	if (!valid)
   4.216 +	{
   4.217 +		printf("Warning: disk image does not appear to describe a valid partition table.\n");
   4.218 +	}
   4.219 +	/* NOTE: need to make sure this always rounds down */
   4.220 +	//sec = total_known_sectors / sizeof_diskimage;
   4.221 +/* The above doesn't work unless the disk image is completely filled by
   4.222 +partitions ... unused space will thrown off the sector size. The calculation
   4.223 +assumes the disk image is completely filled, and that the few sectors used
   4.224 +to store the partition table/MBR are few enough that the calculated value is
   4.225 +off by (larger than) a value less than one. */
   4.226 +	sec = 512; /* TODO: calculate real sector size */
   4.227 +#ifdef DEBUG
   4.228 +	printf("sec: %d\n", sec);
   4.229 +#endif
   4.230 +	if (partition > 4)
   4.231 +	{
   4.232 +		if (exttbl[0] == NULL)
   4.233 +		{
   4.234 +		    printf("No extended partitions were found in %s.\n", diskimage);
   4.235 +		    return 2;
   4.236 +		}
   4.237 +		parttbl = exttbl[0];
   4.238 +		if (parttbl[partition-5].no_of_sectors_abs == 0)
   4.239 +		{
   4.240 +			printf("Partition %d was not found in %s.\n", partition, diskimage);
   4.241 +			return 3;
   4.242 +		}
   4.243 +		partition -= 4;
   4.244 +	}
   4.245 +	else
   4.246 +	{
   4.247 +		parttbl = perttbl;
   4.248 +		if (parttbl[partition-1].no_of_sectors_abs == 0)
   4.249 +		{
   4.250 +			printf("Partition %d was not found in %s.\n", partition, diskimage);
   4.251 +			return 3;
   4.252 +		}
   4.253 +	}
   4.254 +	num = parttbl[partition-1].start_sector_abs;
   4.255 +	pnum = sec * num;
   4.256 +#ifdef DEBUG
   4.257 +	printf("offset = %d\n", pnum);
   4.258 +#endif
   4.259 +	snprintf(buf, BUF, "mount -oloop,offset=%d %s %s", pnum, diskimage, argv2);
   4.260 +#ifdef DEBUG
   4.261 +	printf("%s\n", buf);
   4.262 +#endif
   4.263 +	system(buf);
   4.264 +	return 0;
   4.265 +}