[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] pygrub: cope better with big files in the guest.


  • To: xen-changelog@xxxxxxxxxxxxxxxxxxx
  • From: Xen patchbot-unstable <patchbot@xxxxxxx>
  • Date: Thu, 05 Jul 2012 22:22:07 +0000
  • Delivery-date: Thu, 05 Jul 2012 22:22:19 +0000
  • List-id: "Change log for Mercurial \(receive only\)" <xen-changelog.lists.xen.org>

# HG changeset patch
# User M A Young <m.a.young@xxxxxxxxxxxx>
# Date 1341413174 -3600
# Node ID 60f09d1ab1fe5dee87db1bf55c7479a5d71e85a5
# Parent  42f76d536b116d2ebad1b6705ae51ecd171d2581
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@xxxxxxxxxxxx>
Acked-by: Matt Wilson <msw@xxxxxxxxxx>
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Acked-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
Committed-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---


diff -r 42f76d536b11 -r 60f09d1ab1fe tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub   Tue Jul 03 13:39:01 2012 +0100
+++ b/tools/pygrub/src/pygrub   Wed Jul 04 15:46:14 2012 +0100
@@ -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
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.