int nlen = strlen(dev) + 20;
char *name;
int dig = isdigit(dev[strlen(dev)-1]);
- char orig[1024];
+ char orig[1001];
char sym[1024];
int err;
minor_num = minor(stb.st_rdev);
odig = -1;
} else if (S_ISLNK(stb.st_mode)) {
- int len = readlink(dev, orig, sizeof(orig));
- if (len < 0 || len > 1000)
+ int len;
+
+ len = readlink(dev, orig, sizeof(orig));
+ if (len < 0 || len >= (int)sizeof(orig))
return;
orig[len] = 0;
odig = isdigit(orig[len-1]);
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)
*/
int create_mddev(char *dev, char *name, int autof, int trustworthy,
- char *chosen)
+ char *chosen, int block_udev)
{
int mdfd;
struct stat stb;
char devname[37];
char devnm[32];
char cbuf[400];
+
+ if (!use_udev())
+ block_udev = 0;
+
if (chosen == NULL)
chosen = cbuf;
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) {
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 (num >= 0) {
- int fd;
- int n = -1;
sprintf(devnm, "md%d", num);
- 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;
- }
- 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;
+ 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);
*/
int open_mddev(char *dev, int report_errors)
{
- struct mdu_array_info_s array;
int mdfd = open(dev, O_RDONLY);
if (mdfd < 0) {
return -1;
}
- if (md_get_array_info(mdfd, &array) != 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);