Re: [PATCH 001 of 6] md: Send online/offline uevents when an mdarray starts/stops.

From: Neil Brown
Date: Tue Nov 07 2006 - 00:08:57 EST


On Monday November 6, dean@xxxxxxxxxx wrote:
> On Mon, 6 Nov 2006, Neil Brown wrote:
>
> > This creates a deep disconnect between udev and md.
> > udev expects a device to appear first, then it created the
> > device-special-file in /dev.
> > md expect the device-special-file to exist first, and then created the
> > device on the first open.
>
> could you create a special /dev/mdx device which is used to
> assemble/create arrays only? i mean literally "mdx" not "mdX" where X is
> a number. mdx would always be there if md module is loaded... so udev
> would see the driver appear and then create the /dev/mdx. then mdadm
> would use /dev/mdx to do assemble/creates/whatever and cause other devices
> to appear/disappear in a manner which udev is happy with.
>
> (much like how /dev/ptmx is used to create /dev/pts/N entries.)
>
> doesn't help legacy mdadm binaries... but seems like it fits the New World
> Order.
>
> or hm i suppose the New World Order is to eschew binary interfaces and
> suggest a /sys/class/md/ hierarchy with a bunch of files you have to splat
> ascii data into to cause an array to be created/assembled.

I have the following patch sitting in my patch queue (since about
March).
It does what you suggest via /sys/module/md-mod/parameters/MAGIC_FILE
which is the only md-specific part of the /sys namespace that I could
find.

However I'm not at all convinced that it is a good idea. I would much
rather have mdadm control device naming than leave it up to udev.

An in any case, we have the semantic that opening an md device-file
creates the device, and we cannot get rid of that semantic without a
lot of warning and a lot of pain. And adding a new semantic isn't
really going to help.

We simply need to find the best way for udev and md to play together,
and I think we can achieve something quite workable. Both sides just
have to give a bit.

NeilBrown


Allow md devices to be created by writing to sysfs.

Until now, to create an md device, you needed to open the relevant
device-special file. This created a catch-22 with udev.

This patch provides an alternate.
Options include

echo 10 > /sys/module/md-mod/paramters/create
to create legacy device with minor 10,
echo d10 > /sys/module/md-mod/paramters/create
to create partitionable device 10<<6
cat /sys/module/md-mod/paramters/next_free_legacy
to return major:minor device of an unused legacy array, which will exist.
cat /sys/module/md-mod/paramters/next_free_partitionable
to return major:minor device of an unused partitionable array which will exist.


Signed-off-by: Neil Brown <neilb@xxxxxxx>

### Diffstat output
./drivers/md/md.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)

diff ./drivers/md/md.c~current~ ./drivers/md/md.c
--- ./drivers/md/md.c~current~ 2006-03-27 09:20:58.000000000 +1100
+++ ./drivers/md/md.c 2006-03-27 09:20:56.000000000 +1100
@@ -5525,6 +5525,62 @@ module_param_call(start_ro, set_ro, get_
module_param(start_dirty_degraded, int, 0644);


+static int md_create(const char *val, struct kernel_param *kp)
+{
+ /* NN or dNN creates the numbered device */
+ int part = 0;
+ int num;
+ char *e;
+ if (*val == 'd' || *val == 'p') {
+ part = 1;
+ val++;
+ }
+ num = simple_strtoul(val, &e, 10);
+ if (*val && (*e == '\0' || *e == '\n')) {
+ /* success! */
+ dev_t dev;
+ if (part)
+ dev = MKDEV(mdp_major, num << MdpMinorShift);
+ else
+ dev = MKDEV(MD_MAJOR, num);
+ md_probe(dev, NULL, NULL);
+ return 0;
+ }
+ return -EINVAL;
+}
+static int md_next_free(char *buffer, struct kernel_param *kp)
+{
+ mddev_t *mddev;
+ int major = MD_MAJOR;
+ int inc = 1;
+ int next = MKDEV(MD_MAJOR,0);
+ if (kp->arg) {
+ next = MKDEV(mdp_major,0);
+ major = mdp_major;
+ inc = 1 << MdpMinorShift;
+ }
+ spin_lock(&all_mddevs_lock);
+ list_for_each_entry(mddev, &all_mddevs, all_mddevs)
+ if (MAJOR(mddev->unit) == major) {
+ if (atomic_read(&mddev->active)<=1 &&
+ mddev->pers == NULL &&
+ mddev->raid_disks == 0) {
+ next = mddev->unit;
+ break;
+ } else if (mddev->unit >= next)
+ next = mddev->unit + inc;
+ }
+ spin_unlock(&all_mddevs_lock);
+ md_probe(next, NULL, NULL);
+ return sprintf(buffer, "%d:%d", major, MINOR(next));
+}
+static int ignore(const char *val, struct kernel_param *kp) { return -EINVAL; }
+
+
+module_param_call(create, md_create, NULL, NULL, 0200);
+module_param_call(next_free_legacy, ignore, md_next_free, (void*)0, 0400);
+module_param_call(next_free_partitionable, ignore, md_next_free, (void*)1, 0400);
+
EXPORT_SYMBOL(register_md_personality);
EXPORT_SYMBOL(unregister_md_personality);
EXPORT_SYMBOL(md_error);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/