daemon: list-md-devices: Check if a /dev/md<X> device is valid before returning it.

For reasons not fully understood, if md is linked into the kernel (and
not a module), a /dev/md0 device node is created.  However this is not
a real RAID device.  For example running mdadm --detail /dev/md0 will
fail on it.

Check the /dev/md<X> devices are real RAID devices before returning
them from the list-md-devices API.
This commit is contained in:
Richard W.M. Jones
2013-08-12 21:49:55 +01:00
parent 52188f1ea3
commit 90cafed4c2
2 changed files with 38 additions and 0 deletions

View File

@@ -286,6 +286,7 @@ AC_CHECK_HEADERS([\
byteswap.h \
endian.h \
errno.h \
linux/raid/md_u.h \
printf.h \
sys/inotify.h \
sys/socket.h \

View File

@@ -22,8 +22,16 @@
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <unistd.h>
#include <fcntl.h>
#include <glob.h>
#ifdef HAVE_LINUX_RAID_MD_U_H
#include <sys/ioctl.h>
#include <linux/major.h>
#include <linux/raid/md_u.h>
#endif /* HAVE_LINUX_RAID_MD_U_H */
#include "daemon.h"
#include "actions.h"
#include "optgroups.h"
@@ -176,6 +184,30 @@ glob_errfunc (const char *epath, int eerrno)
return 1;
}
/* Check if 'dev' is a real RAID device, because in the case where md
* is linked directly into the kernel (not a module), /dev/md0 is
* sometimes created.
*/
static int
is_raid_device (const char *dev)
{
int ret = 1;
#if defined(HAVE_LINUX_RAID_MD_U_H) && defined(GET_ARRAY_INFO)
int fd;
mdu_array_info_t array;
fd = open (dev, O_RDONLY);
if (fd >= 0) {
if (ioctl (fd, GET_ARRAY_INFO, &array) == -1 && errno == ENODEV)
ret = 0;
close (fd);
}
#endif
return ret;
}
char **
do_list_md_devices (void)
{
@@ -219,6 +251,11 @@ do_list_md_devices (void)
n = mempcpy (n, &mds.gl_pathv[i][strlen(PREFIX)], len);
*n = '\0';
if (!is_raid_device (dev)) {
free (dev);
continue;
}
if (add_string_nodup (&ret, dev) == -1) goto error;
}