On 08.06.2013 09:12, Andrey Borzenkov wrote: > After commit "Fix order to discover ambigouos RAID before discovering > RAIDs on top of it" diskfilter scans all volumes exactly once. This > means that only first level is found. Scanning second time will find > next level etc. > > This means that e.g. MD RAID on top of MD RAID is not found. Do you mean raid on top of raid on top of raid? Otherwise I don't understand the problem. > > Change scan to iteratively rescan volume list until nothing new was > detected (or scan depth exceeded). > > Signed-off-by: Andrey Borzenkov > > --- > ChangeLog | 5 +++++ > grub-core/disk/diskfilter.c | 29 +++++++++++++++++++++-------- > 2 files changed, 26 insertions(+), 8 deletions(-) > > diff --git a/ChangeLog b/ChangeLog > index 4d8f343..bebcc8a 100644 > --- a/ChangeLog > +++ b/ChangeLog > @@ -1,3 +1,8 @@ > +2013-06-08 Andrey Borzenkov > + > + * grub-core/disk/diskfilter.c (scan_devices): Iteratively > + rescan diskfilter devices until nothing new is found. > + > 2013-06-07 Andrey Borzenkov > > * grub-core/script/execute.c (grub_script_execute_sourcecode): Split > diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c > index c8d267a..0455177 100644 > --- a/grub-core/disk/diskfilter.c > +++ b/grub-core/disk/diskfilter.c > @@ -188,6 +188,7 @@ scan_disk (const char *name, int accept_diskfilter) > if (!accept_diskfilter && is_valid_diskfilter_name (name)) > return 0; > > + /* FIXME do we still need it? It is not called recursively anymore */ > if (scan_depth > 100) > return 0; Still need it. Consider raid on loopback where underlying OS may call into diskfilter again. > > @@ -219,6 +220,8 @@ scan_devices (const char *arname) > grub_disk_pull_t pull; > struct grub_diskfilter_vg *vg; > struct grub_diskfilter_lv *lv = NULL; > + int scan_depth; > + int need_rescan; > > for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) > for (p = grub_disk_dev_list; p; p = p->next) > @@ -231,16 +234,26 @@ scan_devices (const char *arname) > return; > } > > - for (vg = array_list; vg; vg = vg->next) > + scan_depth = 0; > + need_rescan = 1; > + while (need_rescan && scan_depth++ < 100) > { > - if (vg->lvs) > - for (lv = vg->lvs; lv; lv = lv->next) > - if (!lv->scanned && lv->fullname && lv->became_readable_at) > - { > - scan_disk (lv->fullname, 1); > - lv->scanned = 1; > - } > + need_rescan = 0; > + for (vg = array_list; vg; vg = vg->next) > + { > + if (vg->lvs) > + for (lv = vg->lvs; lv; lv = lv->next) > + if (!lv->scanned && lv->fullname && lv->became_readable_at) > + { > + scan_disk (lv->fullname, 1); > + lv->scanned = 1; > + need_rescan = 1; > + } > + } > } > + > + if (need_rescan) > + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "DISKFILTER scan depth exceeded"); > } > > static int >