:: [DNG] Regarding mdadm bug 766
Pàgina inicial
Delete this message
Reply to this message
Autor: Rainer Weikusat
Data:  
A: dng
Assumpte: [DNG] Regarding mdadm bug 766
Copy of a message I also sent to 766@???
------------------------

1| mdadm: DeviceDisappeared event detected on md device /dev/md/md3
1| mdadm: DeviceDisappeared event detected on md device /dev/md/md2
1| mdadm: DeviceDisappeared event detected on md device /dev/md/md1
1| mdadm: DeviceDisappeared event detected on md device /dev/md/md0
2| mdadm: NewArray event detected on md device /dev/md0
2| mdadm: NewArray event detected on md device /dev/md1
2| mdadm: NewArray event detected on md device /dev/md3
2| mdadm: NewArray event detected on md device /dev/md2

Short version: Won't happen anymore with 4.5, bug can be closed.

Long Explanation:
-----------------
The 4.2 Monitor routine (in Monitor.c) uses the following loop to
preprocess mdadm.conf entries:

,----
|         for (; mdlist; mdlist = mdlist->next) {
|             struct state *st;
| 
|             if (mdlist->devname == NULL)
|                 continue;
|             if (strcasecmp(mdlist->devname, "<ignore>") == 0)
|                 continue;
|             st = xcalloc(1, sizeof *st);
|             if (mdlist->devname[0] == '/')
|                 st->devname = xstrdup(mdlist->devname);
|             else {
|                 st->devname = xmalloc(8+strlen(mdlist->devname)+1);
|                 strcat(strcpy(st->devname, "/dev/md/"),
|                        mdlist->devname);
|             }
| 
| [...]
| 
|         }

`----

This means it'll prefix array names which don't start with / with
/dev/md. The so-qualified names will then be passed to the check_array
routine:

,----
| static int check_array(struct state *st, struct mdstat_ent *mdstat,
|                int test, struct alert_info *ainfo,
|                int increments, char *prefer)
| {
|     /* Update the state 'st' to reflect any changes shown in mdstat,
|      * or found by directly examining the array, and return
|      * '1' if the array is degraded, or '0' if it is optimal (or dead).
|      */
| 
| [...]
| 
|     char *dev = st->devname;
| 
| [...]
| 
|     fd = open(dev, O_RDONLY);
|     if (fd < 0)
|         goto disappeared;
| 
| [...]
| 
|  disappeared:
|     if (!st->err && !is_container)
|         alert("DeviceDisappeared", dev, NULL, ainfo);

`----

this will cause a single DeviceDisappeared alert if a name qualified in
this way doesn't actually exist. This is responsible for the quoted
output labelled with '1|' above.

The lines labelled with '2|' were logged because the listed md devices
weren't found in the /etc configuration but by scanning /proc/mdstat.

In 4.5, the Monitor loop was changed to

,----
|         for (; mdlist; mdlist = mdlist->next) {
|             struct state *st;
| 
|             if (mdlist->devname == NULL)
|                 continue;
|             if (is_devname_ignore(mdlist->devname) == true)
|                 continue;
| 
|             st = xcalloc(1, sizeof *st);
|             snprintf(st->devname, sizeof(st->devname), "%s%s",
|                  '/' == *mdlist->devname ? "" : DEV_MD_DIR, mdlist->devname);
|             if (!is_mddev(st->devname)) {
|                 free(st);
|                 continue;
|             }

`----

Among other things, is_mddev tries to open the qualified name and drops
it from the list if this doesn't succeed. The names thus won't be passed
to check_array anymore and won't cause alerts about disappearing devices
anymore.

The underlying issue must have been that a mdadm configuration file
either contained the /dev/md/mdN¹ names or just the mdN names without a
path.

¹ By default, /dev/md contains symlinks of the form /dev/md/N ->
/dev/mdN which are created by a udev rule on aray detection.