[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Incorporate lomount from QEMU into tools/misc. This tool makes it easy to mount
# HG changeset patch # User iap10@xxxxxxxxxxxxxxxxxxxxx # Node ID cd95b96a172e57c1f4908601a852a9af33ad9a24 # Parent 98b83cc57eca28c4beff7d76cf0ddf1cc6e2c9da 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@xxxxxxxxxxxxx diff -r 98b83cc57eca -r cd95b96a172e tools/misc/Makefile --- a/tools/misc/Makefile Thu Jul 14 14:01:21 2005 +++ b/tools/misc/Makefile Thu Jul 14 21:02:05 2005 @@ -23,6 +23,7 @@ $(MAKE) -C miniterm $(MAKE) -C cpuperf $(MAKE) -C mbootpack + $(MAKE) -C lomount install: build [ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin @@ -30,6 +31,7 @@ $(INSTALL_PROG) $(INSTALL_BIN) $(DESTDIR)/usr/bin $(INSTALL_PROG) $(INSTALL_SBIN) $(DESTDIR)/usr/sbin $(MAKE) -C cpuperf install + $(MAKE) -C lomount install # No sense in installing miniterm on the Xen box. # $(MAKE) -C miniterm install # Likewise mbootpack @@ -40,6 +42,7 @@ $(MAKE) -C miniterm clean $(MAKE) -C cpuperf clean $(MAKE) -C mbootpack clean + $(MAKE) -C lomount clean %.o: %.c $(HDRS) Makefile $(CC) -c $(CFLAGS) -o $@ $< diff -r 98b83cc57eca -r cd95b96a172e .hgignore --- a/.hgignore Thu Jul 14 14:01:21 2005 +++ b/.hgignore Thu Jul 14 21:02:05 2005 @@ -119,6 +119,7 @@ ^tools/misc/mbootpack/mbootpack$ ^tools/misc/mbootpack/setup$ ^tools/misc/miniterm/miniterm$ +^tools/misc/lomount/lomount$ ^tools/misc/xc_shadow$ ^tools/misc/xen_cpuperf$ ^tools/misc/xenperf$ diff -r 98b83cc57eca -r cd95b96a172e tools/misc/lomount/lomount.c --- /dev/null Thu Jul 14 14:01:21 2005 +++ b/tools/misc/lomount/lomount.c Thu Jul 14 21:02:05 2005 @@ -0,0 +1,262 @@ +/* + * lomount - utility to mount partitions in a hard disk image + * + * Copyright (c) 2004 Jim Brown + * Copyright (c) 2004 Brad Watson + * Copyright (c) 2004 Mulyadi Santosa + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <errno.h> + +#define BUF 4096 + +//#define SECSIZE 4096 /* arbitrarilly large (it's probably just 512) */ +#define SECSIZE 512 + +struct pentry +{ + unsigned char bootable; + unsigned char start_head; + unsigned int start_cylinder; + unsigned char start_sector; + unsigned char system; + unsigned char end_head; + unsigned int end_cylinder; + unsigned char end_sector; + unsigned long start_sector_abs; + unsigned long no_of_sectors_abs; +}; + +char * progname; + +int loadptable(const char *argv, struct pentry parttbl[], struct pentry **exttbl) +{ + FILE *fd; + int i, valid, total_known_sectors = 0; + unsigned char *pi; + unsigned char data [SECSIZE]; + unsigned long extent = 0, old_extent = 0, e_count = 1; + struct pentry exttbls[4]; + + fd = fopen(argv, "r"); + if (fd == NULL) + { + perror ("lomount"); + return 1; + } + i = fread (&data, 1, sizeof (data), fd); + if (i < SECSIZE) + { + fprintf (stderr, "%s: could not read the entire first sector\n", progname); + return 1; + } + for (i = 0;i < 4;i++) + { + pi = &data [446 + 16 * i]; + parttbl [i].bootable = *pi; + parttbl [i].start_head = *(pi + 1); + parttbl [i].start_cylinder = *(pi + 3) | ((*(pi + 2) << 2) & 0x300); + parttbl [i].start_sector = *(pi + 2) & 0x3f; + parttbl [i].system = *(pi + 4); + parttbl [i].end_head = *(pi + 5); + parttbl [i].end_cylinder = *(pi + 7) | ((*(pi + 6) << 2) & 0x300); + parttbl [i].end_sector = *(pi + 6) & 0x3f; + parttbl [i].start_sector_abs = + (unsigned long) *(pi + 8) | ((unsigned long) *(pi + 9) << 8) | ((unsigned long) *(pi + 10) << 16) | ((unsigned long) *(pi + 11) << 24); + parttbl [i].no_of_sectors_abs = + (unsigned long) *(pi + 12) | ((unsigned long) *(pi + 13) << 8) | ((unsigned long) *(pi + 14) << 16) | ((unsigned long) *(pi + 15) << 24); + if (parttbl[i].system == 0xF || parttbl[i].system == 0x5) + { + extent = parttbl[i].start_sector_abs * SECSIZE; + /* save the location of the "real" extended partition */ + old_extent = extent; + } + } + valid = (data [510] == 0x55 && data [511] == 0xaa) ? 1 : 0; + for (i = 0; i < 4; i++) + { + total_known_sectors += parttbl[i].no_of_sectors_abs; + } + /* Extended Partition layout format was obtained from + http://wigner.cped.ornl.gov/the-gang/att-0520/03-Partition.htm */ +#ifdef DEBUG + if (extent != 0) + { + printf("extended partition detected at offset %d\n", extent); + } +#endif + while (extent != 0) + { +/* according to realloc(3) passing NULL as pointer is same as calling malloc() */ + exttbl[0] = realloc(exttbl[0], e_count * sizeof(struct pentry)); + fseek(fd, extent, SEEK_SET); + i = fread (&data, 1, sizeof (data), fd); + if (i < SECSIZE) + { + fprintf (stderr, "%s: could not read the entire first sector\n", progname); + return 1; + } + /* only first 2 entrys are used in extented partition tables */ + for (i = 0;i < 2;i++) + { + pi = &data [446 + 16 * i]; + exttbls [i].bootable = *pi; + exttbls [i].start_head = *(pi + 1); + exttbls [i].start_cylinder = *(pi + 3) | ((*(pi + 2) << 2) & 0x300); + exttbls [i].start_sector = *(pi + 2) & 0x3f; + exttbls [i].system = *(pi + 4); + exttbls [i].end_head = *(pi + 5); + exttbls [i].end_cylinder = *(pi + 7) | ((*(pi + 6) << 2) & 0x300); + exttbls [i].end_sector = *(pi + 6) & 0x3f; + exttbls [i].start_sector_abs = + (unsigned long) *(pi + 8) | ((unsigned long) *(pi + 9) << 8) | ((unsigned long) *(pi + 10) << 16) | ((unsigned long) *(pi + 11) << 24); + exttbls [i].no_of_sectors_abs = + (unsigned long) *(pi + 12) | ((unsigned long) *(pi + 13) << 8) | ((unsigned long) *(pi + 14) << 16) | ((unsigned long) *(pi + 15) << 24); + if (i == 0) + { + //memmove((void *)exttbl[e_count-1], (void *)exttbls[i], sizeof(struct pentry)); + //memmove() seems broken! + exttbl[0][e_count-1].bootable = exttbls [i].bootable; + exttbl[0][e_count-1].start_head = exttbls [i].start_head; + exttbl[0][e_count-1].start_cylinder = exttbls [i].start_cylinder; + exttbl[0][e_count-1].start_sector = exttbls [i].start_sector; + exttbl[0][e_count-1].system = exttbls [i].system; + exttbl[0][e_count-1].end_head = exttbls [i].end_head; + exttbl[0][e_count-1].end_cylinder = exttbls [i].end_cylinder; + exttbl[0][e_count-1].end_sector = exttbls [i].end_sector; + exttbl[0][e_count-1].start_sector_abs = exttbls [i].start_sector_abs; + exttbl[0][e_count-1].no_of_sectors_abs = exttbls [i].no_of_sectors_abs; + /* adjust for start of image instead of start of ext partition */ + exttbl[0][e_count-1].start_sector_abs += (extent/SECSIZE); +#ifdef DEBUG + printf("extent %d start_sector_abs %d\n", extent, exttbl[0][e_count-1].start_sector_abs); +#endif + //else if (parttbl[i].system == 0x5) + } + else if (i == 1) + { + extent = (exttbls[i].start_sector_abs * SECSIZE); + if (extent) + extent += old_extent; + } + } + e_count ++; + } + //fclose (fd); + //the above segfaults (?!!!) +#ifdef DEBUG + printf("e_count = %d\n", e_count); +#endif + return valid; +} + +int main(int argc, char ** argv) +{ + struct pentry perttbl [4]; + struct pentry *exttbl[1], *parttbl; + char buf[BUF], argv2[BUF], diskimage[BUF]; + int partition = 1, sec, num = 0, pnum = 0, len = BUF, i, f = 0, valid; + progname = argv[0]; + exttbl[0] = NULL; + for (i = 1; i < argc; i ++) + { + if (strncmp(argv[i], "-diskimage", BUF)==0) + { + strncpy(diskimage, argv[i+1], BUF); + i++; f = 1; + } + else if (strncmp(argv[i], "-partition", BUF)==0) + { + partition = atoi(argv[i+1]); + i++; + if (partition < 1) partition = 1; + } + else + { + strncat(argv2, argv[i], len); + strncat(argv2, " ", len-1); + len -= strlen(argv[i]); + len--; + } + } + if (!f) + { + printf("You must specify -diskimage and -partition\n"); + printf("ex. lomount -t fs-type -diskimage hda.img -partition 1 /mnt\n"); + return 0; + } + valid = loadptable(diskimage, perttbl, exttbl); + if (!valid) + { + printf("Warning: disk image does not appear to describe a valid partition table.\n"); + } + /* NOTE: need to make sure this always rounds down */ + //sec = total_known_sectors / sizeof_diskimage; +/* The above doesn't work unless the disk image is completely filled by +partitions ... unused space will thrown off the sector size. The calculation +assumes the disk image is completely filled, and that the few sectors used +to store the partition table/MBR are few enough that the calculated value is +off by (larger than) a value less than one. */ + sec = 512; /* TODO: calculate real sector size */ +#ifdef DEBUG + printf("sec: %d\n", sec); +#endif + if (partition > 4) + { + if (exttbl[0] == NULL) + { + printf("No extended partitions were found in %s.\n", diskimage); + return 2; + } + parttbl = exttbl[0]; + if (parttbl[partition-5].no_of_sectors_abs == 0) + { + printf("Partition %d was not found in %s.\n", partition, diskimage); + return 3; + } + partition -= 4; + } + else + { + parttbl = perttbl; + if (parttbl[partition-1].no_of_sectors_abs == 0) + { + printf("Partition %d was not found in %s.\n", partition, diskimage); + return 3; + } + } + num = parttbl[partition-1].start_sector_abs; + pnum = sec * num; +#ifdef DEBUG + printf("offset = %d\n", pnum); +#endif + snprintf(buf, BUF, "mount -oloop,offset=%d %s %s", pnum, diskimage, argv2); +#ifdef DEBUG + printf("%s\n", buf); +#endif + system(buf); + return 0; +} diff -r 98b83cc57eca -r cd95b96a172e tools/misc/lomount/Makefile --- /dev/null Thu Jul 14 14:01:21 2005 +++ b/tools/misc/lomount/Makefile Thu Jul 14 21:02:05 2005 @@ -0,0 +1,27 @@ +INSTALL = install +INSTALL_PROG = $(INSTALL) -m0755 +INSTALL_DIR = $(INSTALL) -d -m0755 +INSTALL_DATA = $(INSTALL) -m0644 + +XEN_ROOT=../../.. +include $(XEN_ROOT)/tools/Rules.mk + +CFLAGS += -Wall -Werror -O3 + +HDRS = $(wildcard *.h) +OBJS = $(patsubst %.c,%.o,$(wildcard *.c)) + +BIN = lomount + +all: build +build: $(BIN) + +install: build + $(INSTALL_PROG) $(BIN) $(SCRIPTS) $(DESTDIR)/usr/bin + +clean: + $(RM) *.a *.so *.o *.rpm $(BIN) + +%: %.c $(HDRS) Makefile + $(CC) $(CFLAGS) -o $@ $< + _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |