2013-04-25 20:23:41

by Stephen M. Cameron

[permalink] [raw]
Subject: [RFC PATCH] block: Add new generic block device naming interface

From: Stephen M. Cameron <[email protected]>

Currently, when adding a new block device driver, if grub support is needed,
then grub needs to be modified to know about this new driver.

See this thread:
https://lists.gnu.org/archive/html/grub-devel/2013-03/msg00049.html

If block drivers could (optionally) share a common device namespace then
grub could be taught about this common namespace once, and any new block
device drivers could take advantage of this namespace and grub would
automatically work with them.

The idea is that instead of each new block driver manually setting the
gendisk's disk_name field (though legacy drivers could still do that) they
would call blk_get_new_disk_name(struct gendisk *disk), and the block layer
hands out a name. When removing a device, blk_put_disk_name() releases the
device name.

The scheme implemented in this patch is to name the devices /dev/bdn, with n
being an integer starting at zero that counts up, so you'd get device names
like /dev/bd0, /dev/bd1, /dev/bd2, etc.

Signed-off-by: Stephen M. Cameron <[email protected]>
---
block/genhd.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/genhd.h | 2 ++
2 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index 3c001fb..d4f1588 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -568,6 +568,58 @@ exit:
disk_part_iter_exit(&piter);
}

+static DEFINE_SPINLOCK(bd_index_lock);
+static DEFINE_IDA(bd_index_ida);
+char *blk_get_disk_name(struct gendisk *disk)
+{
+ int index, error;
+ char name[DISK_NAME_LEN + 1];
+
+ do {
+ if (!ida_pre_get(&bd_index_ida, GFP_KERNEL))
+ goto out;
+
+ spin_lock(&bd_index_lock);
+ error = ida_get_new(&bd_index_ida, &index);
+ spin_unlock(&bd_index_lock);
+ } while (error == -EAGAIN);
+
+ if (error) {
+ pr_warn("blk_get_disk_name: memory exhausted\n");
+ goto out;
+ }
+
+ snprintf(name, DISK_NAME_LEN, "bd%d", index);
+ if (strlen(name) > DISK_NAME_LEN - 1) {
+ pr_warn("block disk (bd) name length exceeded.\n");
+ goto out_free_index;
+ }
+ strncpy(disk->disk_name, name, DISK_NAME_LEN - 1);
+ return disk->disk_name;
+
+out_free_index:
+ spin_lock(&bd_index_lock);
+ ida_remove(&bd_index_ida, index);
+ spin_unlock(&bd_index_lock);
+out:
+ return NULL;
+}
+EXPORT_SYMBOL(blk_get_disk_name);
+
+int blk_put_disk_name(char *name)
+{
+ int index;
+
+ if (sscanf(name, "bd%d", &index) != 1)
+ return -EINVAL;
+
+ spin_lock(&bd_index_lock);
+ ida_remove(&bd_index_ida, index);
+ spin_unlock(&bd_index_lock);
+ return 0;
+}
+EXPORT_SYMBOL(blk_put_disk_name);
+
/**
* add_disk - add partitioning information to kernel list
* @disk: per-device partitioning information
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 9f3c275..fddb41d 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -602,6 +602,8 @@ extern int blk_alloc_devt(struct hd_struct *part, dev_t *devt);
extern void blk_free_devt(dev_t devt);
extern dev_t blk_lookup_devt(const char *name, int partno);
extern char *disk_name (struct gendisk *hd, int partno, char *buf);
+extern char *blk_get_disk_name(struct gendisk *disk);
+extern int blk_put_disk_name(char *name);

extern int disk_expand_part_tbl(struct gendisk *disk, int target);
extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);


2013-04-25 20:40:41

by Tejun Heo

[permalink] [raw]
Subject: Re: [RFC PATCH] block: Add new generic block device naming interface

Hello,

On Thu, Apr 25, 2013 at 03:22:15PM -0500, Stephen M. Cameron wrote:
> If block drivers could (optionally) share a common device namespace then
> grub could be taught about this common namespace once, and any new block
> device drivers could take advantage of this namespace and grub would
> automatically work with them.

Hmmm... maybe I'm missing something but the names assigned this way
wouldn't have any kind of stability across boots. Is that good
enough? But, if so, I'm kinda having hard time understanding what
it'd be able to do which any other name can't do.

Can you please elaborate the use case?

Thanks.

--
tejun

2013-04-25 21:09:01

by Stephen M. Cameron

[permalink] [raw]
Subject: Re: [RFC PATCH] block: Add new generic block device naming interface

On Thu, Apr 25, 2013 at 01:40:33PM -0700, Tejun Heo wrote:
> Hello,
>
> On Thu, Apr 25, 2013 at 03:22:15PM -0500, Stephen M. Cameron wrote:
> > If block drivers could (optionally) share a common device namespace then
> > grub could be taught about this common namespace once, and any new block
> > device drivers could take advantage of this namespace and grub would
> > automatically work with them.
>
> Hmmm... maybe I'm missing something but the names assigned this way
> wouldn't have any kind of stability across boots. Is that good
> enough?

Perhaps not. I am open to suggestions on that front -- perhaps there's
some way for udev to help sort things out?

> But, if so, I'm kinda having hard time understanding what
> it'd be able to do which any other name can't do.
>
> Can you please elaborate the use case?

Sure.

Right now, if you add a new block driver, if you want grub to be able
to boot it, you also have to modify grub. This is true for each new
block driver that comes along. This is not the case for SCSI HBA
drivers, because they all get to share the sd driver and its device
name space, and grub already knows about that. You can add all kinds
of SCSI HBA drivers and never have to worry about needing to modify
grub to get boot support.

It seems wrong to me that for every new block driver needing boot support
grub has to be modified. If there were a common block device name space
which grub knew about, any new block driver which comes along that needs
support from grub could get it by using this common block device name space.

So that is the problem I'd like to solve. I realize the patch I've put
up for discussion may fall short. And it's possible there's a good reason
such a thing as I propose isn't already present, in which case I'd like
to learn what that reason is.

Thanks,

-- steve

2013-04-25 21:15:08

by Tejun Heo

[permalink] [raw]
Subject: Re: [RFC PATCH] block: Add new generic block device naming interface

Hello,

On Thu, Apr 25, 2013 at 04:07:26PM -0500, [email protected] wrote:
> > Hmmm... maybe I'm missing something but the names assigned this way
> > wouldn't have any kind of stability across boots. Is that good
> > enough?
>
> Perhaps not. I am open to suggestions on that front -- perhaps there's
> some way for udev to help sort things out?

udev already does that by adding names by types, connection, UUID,
what not. They aren't the names recognized by the kernel, so I
suppose aren't useful for your purpose? But then again udev can't
really do anything further.

> > But, if so, I'm kinda having hard time understanding what
> > it'd be able to do which any other name can't do.
> >
> > Can you please elaborate the use case?
>
> Sure.
>
> Right now, if you add a new block driver, if you want grub to be able
> to boot it, you also have to modify grub. This is true for each new
> block driver that comes along. This is not the case for SCSI HBA
> drivers, because they all get to share the sd driver and its device
> name space, and grub already knows about that. You can add all kinds
> of SCSI HBA drivers and never have to worry about needing to modify
> grub to get boot support.

So, the question, I suppose, is why grub needs to be changed when the
stem of device names changes. Why does it need to do that? Is it
just an implementation detail or is it something more fundamental?

Thanks.

--
tejun

2013-04-25 22:13:48

by Stephen M. Cameron

[permalink] [raw]
Subject: Re: [RFC PATCH] block: Add new generic block device naming interface

On Thu, Apr 25, 2013 at 02:14:59PM -0700, Tejun Heo wrote:
> Hello,
[...]
> >
> > Right now, if you add a new block driver, if you want grub to be able
> > to boot it, you also have to modify grub. This is true for each new
> > block driver that comes along. This is not the case for SCSI HBA
> > drivers, because they all get to share the sd driver and its device
> > name space, and grub already knows about that. You can add all kinds
> > of SCSI HBA drivers and never have to worry about needing to modify
> > grub to get boot support.
>
> So, the question, I suppose, is why grub needs to be changed when the
> stem of device names changes. Why does it need to do that? Is it
> just an implementation detail or is it something more fundamental?
>

I don't know. I do know that it looks like a lot of the the various block
device name schemes are more or less hard coded into grub with bits of code
like this:

static void
get_ide_disk_name (char *name, int unit)
{
#if defined(__linux__)
/* GNU/Linux */
sprintf (name, "/dev/hd%c", unit + 'a');
#elif defined(__GNU__)
/* GNU/Hurd */
sprintf (name, "/dev/hd%d", unit);
#elif defined(__FreeBSD_kernel__)
[...]

static void
get_scsi_disk_name (char *name, int unit)
{
#if defined(__linux__)
/* GNU/Linux */
sprintf (name, "/dev/sd%c", unit + 'a');
#elif defined(__GNU__)
/* GNU/Hurd */
sprintf (name, "/dev/sd%d", unit);
#elif defined(__FreeBSD_kernel__)

there are about 9 different get_blah_disk_name() type functions in there
for the various device naming schemes.

It looks like these are called from a function called init_device_map()
that is called from grub_stage2() at least in the version of grub I looked
at (0.97, from rhel6).

So my assumption is that adding a new block driver with yet another name space
would require adding another bit of code into grub like those above. When I
asked about "best practices" for new block driver device names on the grub devel
mailing list to minimize required changes to grub, nobody argued against that
assumption.

-- steve

2013-04-26 19:03:40

by Tejun Heo

[permalink] [raw]
Subject: Re: [RFC PATCH] block: Add new generic block device naming interface

hey,

On Thu, Apr 25, 2013 at 05:12:20PM -0500, [email protected] wrote:
> It looks like these are called from a function called init_device_map()
> that is called from grub_stage2() at least in the version of grub I looked
> at (0.97, from rhel6).
>
> So my assumption is that adding a new block driver with yet another name space
> would require adding another bit of code into grub like those above. When I
> asked about "best practices" for new block driver device names on the grub devel
> mailing list to minimize required changes to grub, nobody argued against that
> assumption.

I think we kinda need to get down to the root cause of the issue.
Nothing against giving common names to devices in itself but there's a
non-insigificant chance that we end up with something half-way if the
original problem isn't properly understodd.

Thanks.

--
tejun

2013-04-29 14:56:42

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [RFC PATCH] block: Add new generic block device naming interface

On 04/26/2013 09:03 PM, Tejun Heo wrote:
> hey,
>
> On Thu, Apr 25, 2013 at 05:12:20PM -0500, [email protected] wrote:
>> It looks like these are called from a function called init_device_map()
>> that is called from grub_stage2() at least in the version of grub I looked
>> at (0.97, from rhel6).
>>
>> So my assumption is that adding a new block driver with yet another name space
>> would require adding another bit of code into grub like those above. When I
>> asked about "best practices" for new block driver device names on the grub devel
>> mailing list to minimize required changes to grub, nobody argued against that
>> assumption.
>
> I think we kinda need to get down to the root cause of the issue.
> Nothing against giving common names to devices in itself but there's a
> non-insigificant chance that we end up with something half-way if the
> original problem isn't properly understodd.
>
Oh, the problem _is_ well understood.

It's the design of grub :-)

grub requires you to re-implement _every_ device naming scheme which
is present in the kernel.
And no, you cannot use the kernel itself as grub is run _prior_ to
the kernel.

As there is no common naming scheme for block devices each and
every block device driver has implemented it own.
So grub need to re-implement each and every device naming
for these drivers.
The approach from Stephen would solve that.

Cheers,

Hannes
--
Dr. Hannes Reinecke zSeries & Storage
[email protected] +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: J. Hawn, J. Guild, F. Imend?rffer, HRB 16746 (AG N?rnberg)

2013-04-29 15:18:46

by Vivek Goyal

[permalink] [raw]
Subject: Re: [RFC PATCH] block: Add new generic block device naming interface

On Mon, Apr 29, 2013 at 04:56:38PM +0200, Hannes Reinecke wrote:
> On 04/26/2013 09:03 PM, Tejun Heo wrote:
> > hey,
> >
> > On Thu, Apr 25, 2013 at 05:12:20PM -0500, [email protected] wrote:
> >> It looks like these are called from a function called init_device_map()
> >> that is called from grub_stage2() at least in the version of grub I looked
> >> at (0.97, from rhel6).
> >>
> >> So my assumption is that adding a new block driver with yet another name space
> >> would require adding another bit of code into grub like those above. When I
> >> asked about "best practices" for new block driver device names on the grub devel
> >> mailing list to minimize required changes to grub, nobody argued against that
> >> assumption.
> >
> > I think we kinda need to get down to the root cause of the issue.
> > Nothing against giving common names to devices in itself but there's a
> > non-insigificant chance that we end up with something half-way if the
> > original problem isn't properly understodd.
> >
> Oh, the problem _is_ well understood.
>
> It's the design of grub :-)
>
> grub requires you to re-implement _every_ device naming scheme which
> is present in the kernel.

So then grub needs to be fixed and not the other way around?

Thanks
Vivek

2013-04-29 16:06:13

by Tejun Heo

[permalink] [raw]
Subject: Re: [RFC PATCH] block: Add new generic block device naming interface

Hey,

On Mon, Apr 29, 2013 at 04:56:38PM +0200, Hannes Reinecke wrote:
> grub requires you to re-implement _every_ device naming scheme which
> is present in the kernel.

Are you saying that it's just a limitation in grub?

> And no, you cannot use the kernel itself as grub is run _prior_ to
> the kernel.

I don't get this part. While booting, it's all about the number BIOS
assigned to disks. After boot, we might as well just do mknod
/dev/grub-device-N if grub is picky about the names it accept. What
am I missing here?

> As there is no common naming scheme for block devices each and
> every block device driver has implemented it own.
> So grub need to re-implement each and every device naming
> for these drivers.

Sure, I heard that a couple times but nobody really explained why
that's the case. Is it something fundamental or is it just an
implementation artifact? Can't it be fixed from grub side? If not,
why?

> The approach from Stephen would solve that.

At the cost of losing per-driver semi-stable enumeration. I don't
think we want to lose that in favor of working around an
implementation detail in grub.

Thanks.

--
tejun