2008-08-24 20:49:26

by Tom Spink

[permalink] [raw]
Subject: UML Reboot Panic

Hi,

When using UML with a UML block device, and issuing a reboot, I was
getting a kernel panic on the next kernel startup because UML was
unable to open the file mapped to the UBD. I think this is because
the file is not closed when the UBD is released, and the following
patch appears to resolve this issue. I'm not sure if it's the right
fix, as I may have missed something, but it works for me.

-- Tom

diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index b58fb89..946a171 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -802,6 +802,7 @@ static void ubd_device_release(struct device *dev)
struct ubd *ubd_dev = dev->driver_data;

blk_cleanup_queue(ubd_dev->queue);
+ os_close_file(ubd_dev->fd);
*ubd_dev = ((struct ubd) DEFAULT_UBD);
}


2008-08-25 22:17:21

by Jeff Dike

[permalink] [raw]
Subject: Re: UML Reboot Panic

On Sun, Aug 24, 2008 at 09:49:15PM +0100, Tom Spink wrote:
> When using UML with a UML block device, and issuing a reboot, I was
> getting a kernel panic on the next kernel startup because UML was
> unable to open the file mapped to the UBD.

The crash was because the attempt to get a file lock failed?

> I think this is because
> the file is not closed when the UBD is released, and the following
> patch appears to resolve this issue.

Looks right to me.

> I'm not sure if it's the right
> fix, as I may have missed something, but it works for me.

That's slightly nasty - try the patch below.

Jeff

--
Work email - jdike at linux dot intel dot com


Index: linux-2.6.22/arch/um/drivers/ubd_kern.c
===================================================================
--- linux-2.6.22.orig/arch/um/drivers/ubd_kern.c 2008-06-12 11:56:19.000000000 -0400
+++ linux-2.6.22/arch/um/drivers/ubd_kern.c 2008-08-25 18:09:35.000000000 -0400
@@ -722,6 +722,9 @@ static int create_cow_file(char *cow_fil

static void ubd_close_dev(struct ubd *ubd_dev)
{
+ if(--ubd_dev->count > 0)
+ return;
+
os_close_file(ubd_dev->fd);
if(ubd_dev->cow.file == NULL)
return;
@@ -801,6 +804,7 @@ static void ubd_device_release(struct de
{
struct ubd *ubd_dev = dev->driver_data;

+ ubd_close_dev(ubd_dev);
blk_cleanup_queue(ubd_dev->queue);
*ubd_dev = ((struct ubd) DEFAULT_UBD);
}
@@ -1144,8 +1148,7 @@ static int ubd_release(struct inode * in
struct gendisk *disk = inode->i_bdev->bd_disk;
struct ubd *ubd_dev = disk->private_data;

- if(--ubd_dev->count == 0)
- ubd_close_dev(ubd_dev);
+ ubd_close_dev(ubd_dev);
return 0;
}