@@ -23,6 +23,7 @@
*/
#include "mdadm.h"
+#include "udev.h"
#include "md_u.h"
#include "md_p.h"
#include <ctype.h>
@@ -204,35 +204,6 @@ char *fd2devnm(int fd)
return NULL;
}
-/* When we create a new array, we don't want the content to
- * be immediately examined by udev - it is probably meaningless.
- * So create /run/mdadm/creating-mdXXX and expect that a udev
- * rule will noticed this and act accordingly.
- */
-static char block_path[] = "/run/mdadm/creating-%s";
-static char *unblock_path = NULL;
-void udev_block(char *devnm)
-{
- int fd;
- char *path = NULL;
-
- xasprintf(&path, block_path, devnm);
- fd = open(path, O_CREAT|O_RDWR, 0600);
- if (fd >= 0) {
- close(fd);
- unblock_path = path;
- } else
- free(path);
-}
-
-void udev_unblock(void)
-{
- if (unblock_path)
- unlink(unblock_path);
- free(unblock_path);
- unblock_path = NULL;
-}
-
/*
* convert a major/minor pair for a block device into a name in /dev, if possible.
* On the first call, walk /dev collecting name.
@@ -1765,8 +1765,6 @@ extern char *fd2kname(int fd);
extern char *stat2devnm(struct stat *st);
bool stat_is_md_dev(struct stat *st);
extern char *fd2devnm(int fd);
-extern void udev_block(char *devnm);
-extern void udev_unblock(void);
extern int in_initrd(void);
@@ -336,8 +336,8 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
devnm[0] = 0;
if (num < 0 && cname && ci->names) {
sprintf(devnm, "md_%s", cname);
- if (block_udev)
- udev_block(devnm);
+ if (block_udev && udev_block(devnm) != UDEV_STATUS_SUCCESS)
+ return -1;
if (!create_named_array(devnm)) {
devnm[0] = 0;
udev_unblock();
@@ -345,8 +345,8 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
}
if (num >= 0) {
sprintf(devnm, "md%d", num);
- if (block_udev)
- udev_block(devnm);
+ if (block_udev && udev_block(devnm) != UDEV_STATUS_SUCCESS)
+ return -1;
if (!create_named_array(devnm)) {
devnm[0] = 0;
udev_unblock();
@@ -369,8 +369,8 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
return -1;
}
}
- if (block_udev)
- udev_block(devnm);
+ if (block_udev && udev_block(devnm) != UDEV_STATUS_SUCCESS)
+ return -1;
create_named_array(devnm);
}
@@ -28,6 +28,8 @@
#include <syslog.h>
#include <libudev.h>
+static char *unblock_path;
+
/*
* udev_is_available() - Checks for udev in the system.
*
@@ -148,3 +150,45 @@ enum udev_status udev_wait_for_events(int seconds)
return UDEV_STATUS_TIMEOUT;
}
#endif
+
+/*
+ * udev_block() - Block udev from examining newly created arrays.
+ *
+ * When array is created, we don't want udev to examine it immediately.
+ * Function creates /run/mdadm/creating-mdXXX and expects that udev rule
+ * will notice it and act accordingly.
+ *
+ * Return:
+ * UDEV_STATUS_SUCCESS when successfully blocked udev
+ * UDEV_STATUS_ERROR on error
+ */
+enum udev_status udev_block(char *devnm)
+{
+ int fd;
+ char *path = xcalloc(1, BUFSIZ);
+
+ snprintf(path, BUFSIZ, "/run/mdadm/creating-%s", devnm);
+
+ fd = open(path, O_CREAT | O_RDWR, 0600);
+ if (!is_fd_valid(fd)) {
+ pr_err("Cannot block udev, error creating blocking file.\n");
+ pr_err("%s: %s\n", strerror(errno), path);
+ free(path);
+ return UDEV_STATUS_ERROR;
+ }
+
+ close(fd);
+ unblock_path = path;
+ return UDEV_STATUS_SUCCESS;
+}
+
+/*
+ * udev_unblock() - Unblock udev.
+ */
+void udev_unblock(void)
+{
+ if (unblock_path)
+ unlink(unblock_path);
+ free(unblock_path);
+ unblock_path = NULL;
+}
@@ -34,4 +34,7 @@ bool udev_is_available(void);
enum udev_status udev_wait_for_events(int seconds);
#endif
+enum udev_status udev_block(char *devnm);
+void udev_unblock(void);
+
#endif