Skip to content

Commit

Permalink
udev: Move udev_block() and udev_unblock() into udev.c
Browse files Browse the repository at this point in the history
Add kernel style comments and better error handling.

Signed-off-by: Mateusz Grzonka <[email protected]>
Signed-off-by: Kinga Tanska <[email protected]>
Signed-off-by: Jes Sorensen <[email protected]>
  • Loading branch information
mgrzonka authored and jessorensen committed Nov 21, 2023
1 parent 9935cf0 commit 9f376da
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 37 deletions.
1 change: 1 addition & 0 deletions Create.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/

#include "mdadm.h"
#include "udev.h"
#include "md_u.h"
#include "md_p.h"
#include <ctype.h>
Expand Down
29 changes: 0 additions & 29 deletions lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 0 additions & 2 deletions mdadm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
12 changes: 6 additions & 6 deletions mdopen.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,17 +336,17 @@ 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();
}
}
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();
Expand All @@ -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);
}

Expand Down
44 changes: 44 additions & 0 deletions udev.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include <syslog.h>
#include <libudev.h>

static char *unblock_path;

/*
* udev_is_available() - Checks for udev in the system.
*
Expand Down Expand Up @@ -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;
}
3 changes: 3 additions & 0 deletions udev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 9f376da

Please sign in to comment.