I sometimes want to mount a disk image which has several partitions. I need to offset option with mount command when I do that. however, I'm too lazy to do that every time so I wrote a script :)
This is the script.
#!/usr/bin/env python from optparse import OptionParser import os import commands def get_options(): parser = OptionParser() parser.add_option("-f", "--file", dest="filename", help="disk image file", metavar="DISK IMAGE FILE") parser.add_option("-m", "--mountdir", dest="mountdir", help="mount point for a disk image", metavar="MOUNT POINT") parser.add_option("-c", "--creatdir", dest="createdir", action="store_true", help="create a directory if given mount point is not exists", default=False) parser.add_option("-p", "--partition", dest="partition", help="partition number", default=1) (options, args) = parser.parse_args() if options.filename == None or options.mountdir == None: parser.error("disk image file and mount point are required") options.partition = int(options.partition) return options def check_file(path): if os.path.isfile(path) != True: print "%s is not found" % path return False if os.access(path, os.R_OK | os.W_OK) != True: print "You do not have right permission to %s" % path return False return True def check_dir(path, createdir): if os.path.isdir(path) != True: if createdir == True: try: os.mkdir(path) print "%s was created" % path except OSError: print "You are not allowed to create dierctory in %s" % os.path.dirname(path) return False else: print "%s is not found" % path return False else: if os.access(os.path.dirname(path), os.R_OK | os.W_OK | os.X_OK) != True: print "You do not have right permission to %s" % path return False return True def get_fdisk_path(): paths = [ "/bin", "/sbin", "/usr/bin", "/usr/sbin", "/usr/local/bin", "/usr/local/sbin" ] for path in paths: path = path + "/fdisk" if os.path.exists(path) == True: return path return None def get_sector_size(strings): for s in strings: if s.startswith("Sector size ") == True: return long(s.split(':')[1].split('/')[1].split(' ')[1]) print "could not get sector size" return -1 def get_start_address(strings, image, partition): part_num = "%(image)s%(partition)d" % { 'image':image, 'partition':partition } for s in strings: if s.startswith(part_num) == True: tmp = s[len(part_num):] return long(tmp.strip().split(' ')[0]) return -1 def get_mount_offset(fdisk, image, partition): """ fdisk (util-linux-ng 2.18)'s result is like this. Disk tmp/test.img: 5368 MB, 5368709120 bytes 16 heads, 63 sectors/track, 10402 cylinders, total 10485760 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000 Device Boot Start End Blocks Id System tmp/test.img1 1 8192015 4096007+ 83 Linux tmp/test.img2 8192016 10240271 1024128 83 Linux """ cmd = "%(command)s -l %(file)s" % { 'command':fdisk, 'file':image } (status, results) = commands.getstatusoutput(cmd) if status != 0: print "executing fdisk failed" return -1 strings = results.split('\n') size = get_sector_size(strings) address = get_start_address(strings, image, partition) if address < 0: print "partition %d is not found in the image." % partition return -1 return long(size * address) def mount_image(image, mountdir, offset): cmd = "mount -o loop,offset=%(offset)s %(image)s %(mountdir)s" % \ { 'offset':offset, 'image':image, 'mountdir':mountdir } (status, results) = commands.getstatusoutput(cmd) if status != 0: print results return False return True if __name__ == "__main__": opts = get_options() if check_file(opts.filename) != True: exit(-1) if check_dir(opts.mountdir, opts.createdir) != True: exit(-1) fdisk_path = get_fdisk_path() if fdisk_path == None: exit(-1) offset = get_mount_offset(fdisk_path, opts.filename, opts.partition) if offset < 0: exit(-1) if mount_image(opts.filename, opts.mountdir, offset) != True: exit(-1) print "mounted %(imagefile)s on %(mountdir)s success." % { 'imagefile':opts.filename, 'mountdir':opts.mountdir }
And, this is a test script.
#!/usr/bin/env python import os import guestfs if __name__ == "__main__": g = guestfs.GuestFS () f = open("/home/masami/tmp/test.img", "w") f.truncate (1024 * 1024 * 1024 * 5) f.close() g.add_drive("/home/masami/tmp/test.img") g.launch() g.sfdiskM("/dev/sda",[",4000,83", ",1000,c"]) print "sfdiskM was finished." print g.list_partitions() print "setup /dev/sda1" g.mkfs("ext3", "/dev/sda1") g.mount("/dev/sda1", "/") g.mkdir("/test1") g.mkdir("/test2") g.sync g.umount_all() print "setup /dev/sda2" g.mkfs("vfat", "/dev/sda2") g.mount("/dev/sda2", "/") g.mkdir("/test3") g.mkdir("/test4") g.sync() g.umount_all() print "file systems were created\n"
You can see the result.
[masami@moon]~% ./partition.py sfdiskM was finished. ['/dev/vda1', '/dev/vda2'] setup /dev/sda1 setup /dev/sda2 file systems were created [masami@moon]~% sudo ./mount_img.py -f tmp/test.img -m /mnt/test_ext3 -p 1 -c [sudo] password for masami: /mnt/test_ext3 was created mounted tmp/test.img on /mnt/test_ext3 success. [masami@moon]~% sudo ./mount_img.py -f tmp/test.img -m /mnt/test_vfat -p 2 -c /mnt/test_vfat was created mounted tmp/test.img on /mnt/test_vfat success. [masami@moon]~% mount /dev/mapper/vg_moon-lv_root on / type ext4 (rw) proc on /proc type proc (rw) sysfs on /sys type sysfs (rw) >>>snip<<< /home/masami/tmp/test.img on /mnt/test_ext3 type ext3 (rw,loop=/dev/loop1,offset=512) /home/masami/tmp/test.img on /mnt/test_vfat type vfat (rw,loop=/dev/loop2,offset=4194312192) [masami@moon]~% ls /mnt/test_ext3 /mnt/test_vfat /mnt/test_ext3: . .. lost+found test1 test2 /mnt/test_vfat: . .. test3 test4 [masami@moon]~% df -m Filesystem 1M-blocks Used Available Use% Mounted on /dev/mapper/vg_moon-lv_root 50397 19468 30417 40% / >>>snip<<< /home/masami/tmp/test.img 3938 72 3666 2% /mnt/test_ext3 /home/masami/tmp/test.img 999 1 999 1% /mnt/test_vfat