On Fri, Jun 19, 2009 at 5:20 PM, Pavel Roskin
<address@hidden> wrote:
On Fri, 2009-06-19 at 16:58 +0200, Vladimir 'phcoder' Serbinenko wrote:
> Hello when testing grub-emu with USB support I stumbled across several problems
> 1) compile time warning of undefined grub_usb_libinit
> 2) When launched under normal user it crashed
> 3) When launched as superuser it hanged on ls
> Here is the fix. Formatting omitted for readability
It's not clear which changes are responsible for fixing which problems.
Please post separate patches if you want a meaningful review.
I thought it was clear. Here is an explanation hunk by hunk:
diff --git a/disk/scsi.c b/disk/scsi.c
index 046dcb8..312d58a 100644
--- a/disk/scsi.c
+++ b/disk/scsi.c
@@ -246,8 +246,9 @@ grub_scsi_open (const char *name, grub_disk_t disk)
for (p = grub_scsi_dev_list; p; p = p->next)
{
- if (! p->open (name, scsi))
- {
+ if (p->open (name, scsi))
+ continue;
+
disk->id = (unsigned long) "scsi"; /* XXX */
disk->data = ""> scsi->dev = p;
This is purely stilistic to avoid unnecessarily long if
@@ -266,7 +267,7 @@ grub_scsi_open (const char *name, grub_disk_t disk)
{
grub_free (scsi);
grub_dprintf ("scsi", "inquiry failed\n");
- return grub_errno;
+ return err;
}
grub_dprintf ("scsi", "inquiry: devtype=0x%02x removable=%d\n",
Error wasn't propagated which caused double closing which resulted in sigsegv. With another hunk (adding grub-error) this hunk wouldn't be necessary but I consider construction
err = ....;
if (err)
return err;
more logical than
err = ....;
if (err)
return grub_errno;
@@ -306,7 +307,6 @@ grub_scsi_open (const char *name, grub_disk_t disk)
return GRUB_ERR_NONE;
}
- }
grub_free (scsi);
Counterpart of first hunk
diff --git a/disk/usbms.c b/disk/usbms.c
index 3c7ebaf..f67f918 100644
--- a/disk/usbms.c
+++ b/disk/usbms.c
@@ -226,7 +226,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
retry:
if (retrycnt == 0)
- return err;
+ return grub_error (GRUB_ERR_IO, "USB Mass Storage stalled");
/* Setup the request. */
grub_memset (&cbw, 0, sizeof (cbw));
when retry numbers failed returned error was ERR_NONE even if nothing was read
@@ -246,6 +246,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
if (err == GRUB_USB_ERR_STALL)
{
grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
+ retrycnt--;
goto retry;
}
return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed");;
retrycnt wasn't decreased which caused grub2 to retry infinitely hence a hang.
diff --git a/include/grub/usb.h b/include/grub/usb.h
index 8dd3b6e..d6d9a3e 100644
--- a/include/grub/usb.h
+++ b/include/grub/usb.h
@@ -204,4 +204,9 @@ grub_usb_get_config_interface (struct grub_usb_desc_config *config)
return interf;
}
+#ifdef GRUB_UTIL
+grub_err_t grub_libusb_init (void);
+grub_err_t grub_libusb_fini (void);
+#endif
+
#endif /* GRUB_USB_H */
diff --git a/util/grub-emu.c b/util/grub-emu.c
index c133dbe..2621d18 100644
--- a/util/grub-emu.c
+++ b/util/grub-emu.c
@@ -39,6 +39,10 @@
#include <grub_emu_init.h>
+#if HAVE_USB_H
+#include <grub/usb.h>
+#endif
+
/* Used for going back to the main function. */
jmp_buf main_env;
@@ -223,6 +227,10 @@ main (int argc, char *argv[])
if (setjmp (main_env) == 0)
grub_main ();
+#if HAVE_USB_H
+ grub_libusb_fini ();
+#endif
+
grub_fini_all ();
grub_machine_fini ();
Previous hunks just fixed warnings
diff --git a/util/usb.c b/util/usb.c
index e1d8c71..4ca1c10 100644
--- a/util/usb.c
+++ b/util/usb.c
@@ -51,6 +51,7 @@ grub_libusb_devices (void)
for (usbdev = bus->devices; usbdev; usbdev = usbdev->next)
{
struct usb_device_descriptor *desc = &usbdev->descriptor;
+ grub_err_t err;
if (! desc->bcdUSB)
continue;
@@ -62,7 +63,9 @@ grub_libusb_devices (void)
dev->data = "">
/* Fill in all descriptors. */
- grub_usb_device_initialize (dev);
+ err = grub_usb_device_initialize (dev);
+ if (err)
+ continue;
/* Register the device. */
grub_usb_devs[last++] = dev;
When device couldn'r be initialized (e.g. because of privilege problem) it was still added to list. Subsequent access created sigsegv
Regarding the compile warning fix, I would try to make
grub_libusb_init() and grub_libusb_fini() appear in grub_emu_init.h
rather than declare them elsewhere.
I was inspired by previous example of disk subsystems:
#ifdef GRUB_UTIL
void grub_raid_init (void);
void grub_raid_fini (void);
void grub_lvm_init (void);
void grub_lvm_fini (void);
#endif
file: include/grub/disk.h
--
Regards,
Pavel Roskin
_______________________________________________
Grub-devel mailing list
address@hidden
http://lists.gnu.org/mailman/listinfo/grub-devel