summaryrefslogtreecommitdiff
path: root/mdopen.c
diff options
context:
space:
mode:
authorDimitri John Ledkov <xnox@ubuntu.com>2018-05-15 12:11:18 +0100
committerDimitri John Ledkov <xnox@ubuntu.com>2018-05-15 12:11:18 +0100
commitf0819c18672a939ad2a6c00c6fa37f73be7a54f3 (patch)
tree8e82f1fe6b2f2979c2329eb5e2b72cb8f108048a /mdopen.c
parent22464b6f492163fabe1041b09e1d2f753fd0d31a (diff)
New upstream release.
Diffstat (limited to 'mdopen.c')
-rw-r--r--mdopen.c92
1 files changed, 66 insertions, 26 deletions
diff --git a/mdopen.c b/mdopen.c
index 685ca328..4ec13f5e 100644
--- a/mdopen.c
+++ b/mdopen.c
@@ -100,6 +100,31 @@ void make_parts(char *dev, int cnt)
free(name);
}
+int create_named_array(char *devnm)
+{
+ int fd;
+ int n = -1;
+ static const char new_array_file[] = {
+ "/sys/module/md_mod/parameters/new_array"
+ };
+
+ fd = open(new_array_file, O_WRONLY);
+ if (fd < 0 && errno == ENOENT) {
+ if (system("modprobe md_mod") == 0)
+ fd = open(new_array_file, O_WRONLY);
+ }
+ if (fd >= 0) {
+ n = write(fd, devnm, strlen(devnm));
+ close(fd);
+ }
+ if (fd < 0 || n != (int)strlen(devnm)) {
+ pr_err("Fail create %s when using %s\n", devnm, new_array_file);
+ return 0;
+ }
+
+ return 1;
+}
+
/*
* We need a new md device to assemble/build/create an array.
* 'dev' is a name given us by the user (command line or mdadm.conf)
@@ -135,7 +160,7 @@ void make_parts(char *dev, int cnt)
*/
int create_mddev(char *dev, char *name, int autof, int trustworthy,
- char *chosen)
+ char *chosen, int block_udev)
{
int mdfd;
struct stat stb;
@@ -147,6 +172,10 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
char devname[37];
char devnm[32];
char cbuf[400];
+
+ if (!use_udev())
+ block_udev = 0;
+
if (chosen == NULL)
chosen = cbuf;
@@ -194,7 +223,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
return -1;
}
if (cname[0] == 0) {
- pr_err("%s is an invalid name for an md device (empty!).", dev);
+ pr_err("%s is an invalid name for an md device (empty!).\n", dev);
return -1;
}
if (num < 0) {
@@ -302,34 +331,42 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
devnm[0] = 0;
if (num < 0 && cname && ci->names) {
- int fd;
- int n = -1;
sprintf(devnm, "md_%s", cname);
- fd = open("/sys/module/md_mod/parameters/new_array", O_WRONLY);
- if (fd >= 0) {
- n = write(fd, devnm, strlen(devnm));
- close(fd);
- }
- if (n < 0)
+ if (block_udev)
+ udev_block(devnm);
+ if (!create_named_array(devnm)) {
devnm[0] = 0;
+ udev_unblock();
+ }
}
- if (devnm[0])
- ;
- else if (num < 0) {
- /* need to choose a free number. */
- char *_devnm = find_free_devnm(use_mdp);
- if (_devnm == NULL) {
- pr_err("No avail md devices - aborting\n");
- return -1;
+ if (num >= 0) {
+ sprintf(devnm, "md%d", num);
+ if (block_udev)
+ udev_block(devnm);
+ if (!create_named_array(devnm)) {
+ devnm[0] = 0;
+ udev_unblock();
}
- strcpy(devnm, _devnm);
- } else {
- sprintf(devnm, "%s%d", use_mdp?"md_d":"md", num);
- if (mddev_busy(devnm)) {
- pr_err("%s is already in use.\n",
- dev);
- return -1;
+ }
+ if (devnm[0] == 0) {
+ if (num < 0) {
+ /* need to choose a free number. */
+ char *_devnm = find_free_devnm(use_mdp);
+ if (_devnm == NULL) {
+ pr_err("No avail md devices - aborting\n");
+ return -1;
+ }
+ strcpy(devnm, _devnm);
+ } else {
+ sprintf(devnm, "%s%d", use_mdp?"md_d":"md", num);
+ if (mddev_busy(devnm)) {
+ pr_err("%s is already in use.\n",
+ dev);
+ return -1;
+ }
}
+ if (block_udev)
+ udev_block(devnm);
}
sprintf(devname, "/dev/%s", devnm);
@@ -417,18 +454,21 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
int open_mddev(char *dev, int report_errors)
{
int mdfd = open(dev, O_RDONLY);
+
if (mdfd < 0) {
if (report_errors)
pr_err("error opening %s: %s\n",
dev, strerror(errno));
return -1;
}
- if (md_get_version(mdfd) <= 0) {
+
+ if (md_array_valid(mdfd) == 0) {
close(mdfd);
if (report_errors)
pr_err("%s does not appear to be an md device\n", dev);
return -2;
}
+
return mdfd;
}