as I just now was in the situation to call update-grub quite a few times and hit this bug, and found it somewhat annoying, I tried to track it down.
# time update-grub Searching for GRUB installation directory ... found: /boot/grub Searching for default file ... found: /boot/grub/default Testing for an existing GRUB menu.lst file ... found: /boot/grub/menu.lst Searching for splash image ... found: /boot/grub/splash.xpm.gz Found kernel: ... Updating /boot/grub/menu.lst ... done real 1m18.955s user 0m2.612s sys 0m41.603s 80 seconds wall clock time. doh. (yes, I did that several times, and it is consistent) my root is on LVM, btw. strace and gdb revealed that it is spending much time in repeatedly doing open_device for my PV, basically you get this access pattern: open() getgeom flushbufs lseek read 4k close repeated about 32 thousand times ;) I tracked this down grub_lvm_scan_device, disk/lvm.c:289 err = grub_disk_read (disk, 0, mda_offset, mda_size, metadatabuf); actually to this loop in grub_disk_read: /* Until SIZE is zero... */ while (size) { char *data; grub_disk_addr_t start_sector; grub_size_t len; grub_size_t pos; /* For reading bulk data. */ start_sector = sector & ~(GRUB_DISK_CACHE_SIZE - 1); pos = (sector - start_sector) << GRUB_DISK_SECTOR_BITS; len = ((GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS) - pos - real_offset); if (len > size) len = size; /* Fetch the cache. */ data = grub_disk_cache_fetch (disk->dev->id, disk->id, start_sector); if (data) ... else { /* Otherwise read data from the disk actually. */ if ((disk->dev->read) (disk, start_sector, GRUB_DISK_CACHE_SIZE, tmp_buf) != GRUB_ERR_NONE) now, guess what GRUB_DISK_CACHE_SIZE is? right, 4k. and, what happens to be my mda_size? hm, happens to be 128 MiB. so I changed: # cat debian/patches/00_increase_grub_disk_cache.diff --- a/include/grub/disk.h.orig 2010-01-12 19:30:32.125277561 +0100 +++ b/include/grub/disk.h 2010-01-12 19:33:47.261239353 +0100 @@ -131,8 +131,8 @@ #define GRUB_DISK_CACHE_NUM 1021 /* The size of a disk cache in sector units. */ -#define GRUB_DISK_CACHE_SIZE 8 -#define GRUB_DISK_CACHE_BITS 3 +#define GRUB_DISK_CACHE_BITS 11 +#define GRUB_DISK_CACHE_SIZE (1<<GRUB_DISK_CACHE_BITS) /* This is called from the memory manager. */ void grub_disk_cache_invalidate_all (void); rebuilt, installed: r...@rum:~/src# dpkg -i grub-common_1.96+20080724-16.1_amd64.deb timed again: # time update-grub ... Updating /boot/grub/menu.lst ... done real 0m13.463s user 0m1.668s sys 0m5.592s not too bad for a "one line" patch. comments welcome, maybe this approach is not the best, maybe 1MiB is overkill, maybe I forgot to adjust some other "grub disk cache" internals... maybe rather (or additionally) keep a single instance static last-used cache inside of open_device(), which could save a lot of syscalls as well. also, as has been mentioned before, some special mode for grub-probe would be great so it need not be called five times from udate-grub. what does grub upstream have to say about this? Cheers, Lars -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org