Filter devaliases and never open same device twice.

* grub-core/disk/ieee1275/ofdisk.c (last_devpath): New variable.
	(last_ihandle): Likewise.
	(ofdisk_hash_ent): New member shortest.
	(ofdisk_hash_add): Add canonical path too.
	(scan): New function.
	(grub_ofdisk_iterate): Iterate over hashed entries.
	(compute_dev_path): Don't add :0.
	(grub_ofdisk_open): Don't really open the disk.
	(grub_ofdisk_close): Avoid closing unrelated disk.
	(grub_ofdisk_read): Implement reopen logic.
	* grub-core/kern/ieee1275/openfw.c (grub_ieee1275_canonicalise_devname):
	New function.
	* include/grub/ieee1275/ieee1275.h (grub_ieee1275_canonicalise_devname):
	New proto.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-09-13 19:17:29 +02:00
parent fb53b340aa
commit b2a30ac5e4
4 changed files with 227 additions and 86 deletions

View file

@ -423,3 +423,47 @@ grub_reboot (void)
for (;;) ;
}
#endif
/* Resolve aliases. */
char *
grub_ieee1275_canonicalise_devname (const char *path)
{
struct canon_args
{
struct grub_ieee1275_common_hdr common;
grub_ieee1275_cell_t path;
grub_ieee1275_cell_t buf;
grub_ieee1275_cell_t inlen;
grub_ieee1275_cell_t outlen;
}
args;
char *buf = NULL;
grub_size_t bufsize = 64;
int i;
for (i = 0; i < 2; i++)
{
grub_free (buf);
buf = grub_malloc (bufsize);
if (!buf)
return NULL;
INIT_IEEE1275_COMMON (&args.common, "canon", 3, 1);
args.path = (grub_ieee1275_cell_t) path;
args.buf = (grub_ieee1275_cell_t) buf;
args.inlen = (grub_ieee1275_cell_t) (bufsize - 1);
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
return 0;
if (args.outlen > bufsize - 1)
{
bufsize = args.outlen + 2;
continue;
}
return buf;
}
/* Shouldn't reach here. */
grub_free (buf);
return NULL;
}