aboutsummaryrefslogtreecommitdiffstats
path: root/tools/pygrub
diff options
context:
space:
mode:
authorM A Young <m.a.young@durham.ac.uk>2012-07-04 15:46:14 +0100
committerM A Young <m.a.young@durham.ac.uk>2012-07-04 15:46:14 +0100
commite7e8937625f5a62f8f15a0dcf98546113446675e (patch)
treefffa0bc581cfc7644fce9b31028626d23f0ace90 /tools/pygrub
parent88fccdd11ca0c2df915d7d56ab78ea70d4b60e52 (diff)
downloadxen-e7e8937625f5a62f8f15a0dcf98546113446675e.tar.gz
xen-e7e8937625f5a62f8f15a0dcf98546113446675e.tar.bz2
xen-e7e8937625f5a62f8f15a0dcf98546113446675e.zip
pygrub: cope better with big files in the guest.
Only read the first megabyte of a configuration file (grub etc.) and read the kernel and ramdisk files from the guest in one megabyte pieces so pygrub doesn't use a lot of memory if the files are large. With --not-really option check that the chosen kernel and ramdisk files exist. If there are problems writing the copy of the kernel or ramdisk, delete the copied files and exit in case they have filled the filesystem. Signed-off-by: Michael Young <m.a.young@durham.ac.uk> Acked-by: Matt Wilson <msw@amazon.com> Acked-by: Ian Campbell <ian.campbell@citrix.com> Acked-by: Ian Jackson <Ian.Jackson@eu.citrix.com> Committed-by: Ian Campbell <ian.campbell@citrix.com>
Diffstat (limited to 'tools/pygrub')
-rw-r--r--tools/pygrub/src/pygrub61
1 files changed, 44 insertions, 17 deletions
diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
index e14df3f45c..6dd44ace6a 100644
--- a/tools/pygrub/src/pygrub
+++ b/tools/pygrub/src/pygrub
@@ -28,6 +28,7 @@ import grub.LiloConf
import grub.ExtLinuxConf
PYGRUB_VER = 0.6
+FS_READ_MAX = 1024 * 1024
def enable_cursor(ison):
if ison:
@@ -448,7 +449,8 @@ class Grub:
if self.__dict__.get('cf', None) is None:
raise RuntimeError, "couldn't find bootloader config file in the image provided."
f = fs.open_file(self.cf.filename)
- buf = f.read()
+ # limit read size to avoid pathological cases
+ buf = f.read(FS_READ_MAX)
del f
self.cf.parse(buf)
@@ -697,6 +699,37 @@ if __name__ == "__main__":
def usage():
print >> sys.stderr, "Usage: %s [-q|--quiet] [-i|--interactive] [-n|--not-really] [--output=] [--kernel=] [--ramdisk=] [--args=] [--entry=] [--output-directory=] [--output-format=sxp|simple|simple0] <image>" %(sys.argv[0],)
+ def copy_from_image(fs, file_to_read, file_type, output_directory,
+ not_really):
+ if not_really:
+ if fs.file_exists(file_to_read):
+ return "<%s:%s>" % (file_type, file_to_read)
+ else:
+ sys.exit("The requested %s file does not exist" % file_type)
+ try:
+ datafile = fs.open_file(file_to_read)
+ except Exception, e:
+ print >>sys.stderr, e
+ sys.exit("Error opening %s in guest" % file_to_read)
+ (tfd, ret) = tempfile.mkstemp(prefix="boot_"+file_type+".",
+ dir=output_directory)
+ dataoff = 0
+ while True:
+ data = datafile.read(FS_READ_MAX, dataoff)
+ if len(data) == 0:
+ os.close(tfd)
+ del datafile
+ return ret
+ try:
+ os.write(tfd, data)
+ except Exception, e:
+ print >>sys.stderr, e
+ os.close(tfd)
+ os.unlink(ret)
+ del datafile
+ sys.exit("Error writing temporary copy of "+file_type)
+ dataoff += len(data)
+
try:
opts, args = getopt.gnu_getopt(sys.argv[1:], 'qinh::',
["quiet", "interactive", "not-really", "help",
@@ -821,24 +854,18 @@ if __name__ == "__main__":
if not fs:
raise RuntimeError, "Unable to find partition containing kernel"
- if not_really:
- bootcfg["kernel"] = "<kernel:%s>" % chosencfg["kernel"]
- else:
- data = fs.open_file(chosencfg["kernel"]).read()
- (tfd, bootcfg["kernel"]) = tempfile.mkstemp(prefix="boot_kernel.",
- dir=output_directory)
- os.write(tfd, data)
- os.close(tfd)
+ bootcfg["kernel"] = copy_from_image(fs, chosencfg["kernel"], "kernel",
+ output_directory, not_really)
if chosencfg["ramdisk"]:
- if not_really:
- bootcfg["ramdisk"] = "<ramdisk:%s>" % chosencfg["ramdisk"]
- else:
- data = fs.open_file(chosencfg["ramdisk"],).read()
- (tfd, bootcfg["ramdisk"]) = tempfile.mkstemp(
- prefix="boot_ramdisk.", dir=output_directory)
- os.write(tfd, data)
- os.close(tfd)
+ try:
+ bootcfg["ramdisk"] = copy_from_image(fs, chosencfg["ramdisk"],
+ "ramdisk", output_directory,
+ not_really)
+ except:
+ if not not_really:
+ os.unlink(bootcfg["kernel"])
+ raise
else:
initrd = None