Richard W.M. Jones
2009-Jul-13 17:23 UTC
[Libguestfs] [PATCH] Fix: virt-inspector takes ages to run on RHEL 3 guests
Currently virt-inspector takes ages to run on RHEL 3 guests. I tracked this down to processing the old-style initrd images in these guests. These initrd images are compressed ext2 filesystems. 'cpio' tries to parse them as cpio files, and takes a very long time to fail (and spews out a lot of errors in the process). These two patches fix the problem: Firstly we introduce a new command 'zfile' for doing the 'file' operation inside compressed files. eg: guestfs_zfile (g, "gzip", "/boot/initrd.img") ==> "Linux rev 1.0 ext2 filesystem data" Second patch updates Sys::Guestfs::Lib to ignore such files. Rich. -- Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://et.redhat.com/~rjones/virt-df/ -------------- next part -------------->From 7d41d75c1d4e6dbe61f6cd353bc104663340483f Mon Sep 17 00:00:00 2001From: Richard Jones <rjones at trick.home.annexia.org> Date: Mon, 13 Jul 2009 18:00:07 +0100 Subject: [PATCH 1/2] Implement new 'zfile' command, to show file type inside compressed files. --- daemon/file.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/MAX_PROC_NR | 2 +- src/generator.ml | 51 +++++++++++++++++++++++++++------------------ 3 files changed, 92 insertions(+), 21 deletions(-) diff --git a/daemon/file.c b/daemon/file.c index 3ef7441..98c356d 100644 --- a/daemon/file.c +++ b/daemon/file.c @@ -376,3 +376,63 @@ do_file (char *path) return out; /* caller frees */ } + +/* zcat | file */ +char * +do_zfile (char *method, char *path) +{ + int len; + char *cmd; + FILE *fp; + char line[256]; + + NEED_ROOT (NULL); + ABS_PATH (path, NULL); + + len = 2 * strlen (path) + 64; + cmd = malloc (len); + if (!cmd) { + reply_with_perror ("malloc"); + return NULL; + } + + if (strcmp (method, "gzip") == 0 || strcmp (method, "compress") == 0) + strcpy (cmd, "zcat"); + else if (strcmp (method, "bzip2") == 0) + strcpy (cmd, "bzcat"); + else { + free (cmd); + reply_with_error ("zfile: unknown method"); + return NULL; + } + + strcat (cmd, " /sysroot"); + shell_quote (cmd + strlen (cmd), len - strlen (cmd), path); + strcat (cmd, " | file -bsL -"); + + fp = popen (cmd, "r"); + if (fp == NULL) { + reply_with_perror ("%s", cmd); + free (cmd); + return NULL; + } + + free (cmd); + + if (fgets (line, sizeof line, fp) == NULL) { + reply_with_perror ("zfile: fgets"); + fclose (fp); + return NULL; + } + + if (fclose (fp) == -1) { + reply_with_perror ("zfile: fclose"); + return NULL; + } + + len = strlen (line); + if (len > 0 && line[len-1] == '\n') + line[len-1] = '\0'; + + return strdup (line); +} diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR index 897bdc8..dee261d 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -139 +140 diff --git a/src/generator.ml b/src/generator.ml index 8c864f0..e3293d1 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -1718,8 +1718,8 @@ This uses the L<blockdev(8)> command."); ("upload", (RErr, [FileIn "filename"; String "remotefilename"]), 66, [], [InitBasicFS, Always, TestOutput ( (* Pick a file from cwd which isn't likely to change. *) - [["upload"; "../COPYING.LIB"; "/COPYING.LIB"]; - ["checksum"; "md5"; "/COPYING.LIB"]], "e3eda01d9815f8d24aae2dbd89b68b06")], + [["upload"; "../COPYING.LIB"; "/COPYING.LIB"]; + ["checksum"; "md5"; "/COPYING.LIB"]], "e3eda01d9815f8d24aae2dbd89b68b06")], "upload a file from the local machine", "\ Upload local file C<filename> to C<remotefilename> on the @@ -1732,10 +1732,10 @@ See also C<guestfs_download>."); ("download", (RErr, [String "remotefilename"; FileOut "filename"]), 67, [], [InitBasicFS, Always, TestOutput ( (* Pick a file from cwd which isn't likely to change. *) - [["upload"; "../COPYING.LIB"; "/COPYING.LIB"]; - ["download"; "/COPYING.LIB"; "testdownload.tmp"]; - ["upload"; "testdownload.tmp"; "/upload"]; - ["checksum"; "md5"; "/upload"]], "e3eda01d9815f8d24aae2dbd89b68b06")], + [["upload"; "../COPYING.LIB"; "/COPYING.LIB"]; + ["download"; "/COPYING.LIB"; "testdownload.tmp"]; + ["upload"; "testdownload.tmp"; "/upload"]; + ["checksum"; "md5"; "/upload"]], "e3eda01d9815f8d24aae2dbd89b68b06")], "download a file to the local machine", "\ Download file C<remotefilename> and save it as C<filename> @@ -2357,19 +2357,19 @@ are activated or deactivated."); ("lvresize", (RErr, [String "device"; Int "mbytes"]), 105, [], [InitNone, Always, TestOutput ( - [["sfdiskM"; "/dev/sda"; ","]; - ["pvcreate"; "/dev/sda1"]; - ["vgcreate"; "VG"; "/dev/sda1"]; - ["lvcreate"; "LV"; "VG"; "10"]; - ["mkfs"; "ext2"; "/dev/VG/LV"]; - ["mount"; "/dev/VG/LV"; "/"]; - ["write_file"; "/new"; "test content"; "0"]; - ["umount"; "/"]; - ["lvresize"; "/dev/VG/LV"; "20"]; - ["e2fsck_f"; "/dev/VG/LV"]; - ["resize2fs"; "/dev/VG/LV"]; - ["mount"; "/dev/VG/LV"; "/"]; - ["cat"; "/new"]], "test content")], + [["sfdiskM"; "/dev/sda"; ","]; + ["pvcreate"; "/dev/sda1"]; + ["vgcreate"; "VG"; "/dev/sda1"]; + ["lvcreate"; "LV"; "VG"; "10"]; + ["mkfs"; "ext2"; "/dev/VG/LV"]; + ["mount"; "/dev/VG/LV"; "/"]; + ["write_file"; "/new"; "test content"; "0"]; + ["umount"; "/"]; + ["lvresize"; "/dev/VG/LV"; "20"]; + ["e2fsck_f"; "/dev/VG/LV"]; + ["resize2fs"; "/dev/VG/LV"]; + ["mount"; "/dev/VG/LV"; "/"]; + ["cat"; "/new"]], "test content")], "resize an LVM logical volume", "\ This resizes (expands or shrinks) an existing LVM logical @@ -2441,7 +2441,7 @@ This command is only needed because of C<guestfs_resize2fs> ("sleep", (RErr, [Int "secs"]), 109, [], [InitNone, Always, TestRun ( - [["sleep"; "1"]])], + [["sleep"; "1"]])], "sleep for some seconds", "\ Sleep for C<secs> seconds."); @@ -2857,6 +2857,17 @@ were rarely if ever used anyway. See also C<guestfs_sfdisk> and the L<sfdisk(8)> manpage."); + ("zfile", (RString "description", [String "method"; String "path"]), 140, [], + [], + "determine file type inside a compressed file", + "\ +This command runs C<file> after first decompressing C<path> +using C<method>. + +C<method> must be one of C<gzip>, C<compress> or C<bzip2>. + +See also: C<guestfs_file>"); + ] let all_functions = non_daemon_functions @ daemon_functions -- 1.6.2.5 -------------- next part -------------->From 4e444d5c09d78b0d292d95d1f97de12f26cc139d Mon Sep 17 00:00:00 2001From: Richard Jones <rjones at trick.home.annexia.org> Date: Mon, 13 Jul 2009 18:06:10 +0100 Subject: [PATCH 2/2] Ignore old-style initrd which is a compressed ext2 filesystem. 'cpio' chokes on these, taking ages to decide that they are not cpio files, and producing masses of messages. This was causing virt-inspector to be very slow (many minutes) on RHEL 3 guests. With this fix, speed is back to normal. --- perl/lib/Sys/Guestfs/Lib.pm | 22 ++++++++++++++-------- 1 files changed, 14 insertions(+), 8 deletions(-) diff --git a/perl/lib/Sys/Guestfs/Lib.pm b/perl/lib/Sys/Guestfs/Lib.pm index 27a7b9e..d5dfb4e 100644 --- a/perl/lib/Sys/Guestfs/Lib.pm +++ b/perl/lib/Sys/Guestfs/Lib.pm @@ -1208,14 +1208,20 @@ sub _check_for_initrd my $version = $1; my @modules; - eval { - @modules = $g->initrd_list ("/boot/$initrd"); - }; - unless ($@) { - @modules = grep { m,([^/]+)\.ko$, || m,([^/]+)\.o$, } @modules; - $initrd_modules{$version} = \@modules - } else { - warn "/boot/$initrd: could not read initrd format" + # Disregard old-style compressed ext2 files, since cpio + # takes ages to (fail to) process these. + if ($g->file ("/boot/$initrd") !~ /gzip compressed/ || + $g->zfile ("gzip", "/boot/$initrd") !~ /ext2 filesystem/) { + eval { + @modules = $g->initrd_list ("/boot/$initrd"); + }; + unless ($@) { + @modules = grep { m,([^/]+)\.ko$, || m,([^/]+)\.o$, } + @modules; + $initrd_modules{$version} = \@modules + } else { + warn "/boot/$initrd: could not read initrd format"; + } } } } -- 1.6.2.5
Reasonably Related Threads
- Re: [PATCH] inspector: Fix virt-inspector on *BSD guests (RHBZ#1144138).
- Re: [PATCH] inspector: Fix virt-inspector on *BSD guests (RHBZ#1144138).
- Re: [PATCH] inspector: Fix virt-inspector on *BSD guests (RHBZ#1144138).
- [PATCH] inspector: Fix virt-inspector on *BSD guests (RHBZ#1144138).
- Re: [PATCH] inspector: Fix virt-inspector on *BSD guests (RHBZ#1144138).