Bug 30174

Summary: hald does not refresh the status of a RAID array
Product: hal Reporter: Christophe Vu-Brugier <cvubrugier>
Component: haldAssignee: David Zeuthen (not reading bugmail) <zeuthen>
Status: NEW --- QA Contact:
Severity: normal    
Priority: medium    
Version: unspecified   
Hardware: All   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments: Set "sysfs_path" to "/sys/devices/virtual/block/mdX".

Description Christophe Vu-Brugier 2010-09-14 00:22:50 UTC
Created attachment 38682 [details] [review]
Set "sysfs_path" to "/sys/devices/virtual/block/mdX".

When a RAID array is modified, HAL does not take the changes into
account. For instance, when a disk is added to a one disk RAID
array, HAL continues to see only one disk instead of two.

To reproduce this bug, you can create a RAID1 containing only one
disk. At this step, `lshal` correctly shows that the RAID array has
one component (i.e. num_components = 1).

 # lshal | grep num_components
   storage.linux_raid.num_components = 1  (0x1)  (int)
   storage.linux_raid.num_components_active = 1  (0x1)  (int)

Then, add a new device with mdadm --add and grow the RAID array to two
disks:

 # mdadm --add /dev/md0 /dev/sdc2
 mdadm: added /dev/sdc2
 # mdadm --grow /dev/md0 --raid-devices=2

lshal will continue to see only one component:

 # lshal | grep num_components
   storage.linux_raid.num_components = 1  (0x1)  (int)
   storage.linux_raid.num_components_active = 1  (0x1)  (int)

This is caused by a bug in HAL that prevents it from refreshing the
properties of its RAID arrays.

The problem is located in hald/linux/blockdev.c at the end
blockdev_process_mdstat():

<pre>
  2075          /* finally, refresh all md devices */
  2076          for (i = md_devs; i != NULL; i = i->next) {
  2077                  char *sysfs_path = i->data;
  2078                  HalDevice *d;
  2079
  2080                  d = hal_device_store_match_key_value_string (hald_get_gdl (),
  2081                                                               "storage.linux_raid.sysfs_path",
  2082                                                               sysfs_path);
  2083                  if (d == NULL)
  2084                          d = hal_device_store_match_key_value_string (hald_get_tdl (),
  2085                                                                       "storage.linux_raid.sysfs_path",
  2086                                                                       sysfs_path);
  2087                  if (d != NULL)
  2088                          refresh_md_state (d);
  2089          }
</pre>

The purpose of blockdev_process_mdstat() is to parse /proc/mdstat.
It is invoked every time an important change is made to
/proc/mdstat. It performs three different tasks:

    * add new RAID devices to the device tree;
    * remove old RAID devices from the device tree;
    * refresh all RAID devices.

There is a bug in the last step.

The sysfs_path variable contains the path of a RAID device in the form
/sys/block/mdX. However, the "storage.linux_raid.sysfs_path" attribute
is not stored in this form in the device tree: the path follows this
format instead: /sys/devices/virtual/block/mdX.

As a result the calls to hal_device_store_match_key_value_string()
return NULL and refresh_md_state() is never invoked.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.