]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Arrange the 'auto' setting in mdadm.conf can choose default type.
authorNeil Brown <neilb@suse.de>
Tue, 16 May 2006 07:35:06 +0000 (07:35 +0000)
committerNeil Brown <neilb@suse.de>
Tue, 16 May 2006 07:35:06 +0000 (07:35 +0000)
So when you say auto=md or auto=part in mdadm.conf, it give a preference
for type of array, but standard name will override.

But --auto=md is more insistant.

FIXME  I'm not at all happy about handling of names that already exist.
  I don't think that should be removed if the device is active.

Signed-off-by: Neil Brown <neilb@suse.de>
config.c
mdadm.c
mdadm.h
mdopen.c

index c48f88e2f5c0e3c5285cf69e8226d15e651e7176..269eb11c899ef709536b84b7d49f7b15ec893b90 100644 (file)
--- a/config.c
+++ b/config.c
@@ -254,17 +254,17 @@ struct createinfo createinfo = {
 #endif
 };
 
-int parse_auto(char *str, char *msg)
+int parse_auto(char *str, char *msg, int config)
 {
        int autof;
        if (str == NULL || *str == 0)
-               autof = -2;
+               autof = 2;
        else if (strcasecmp(str,"no")==0)
-               autof = -3;
+               autof = 1;
        else if (strcasecmp(str,"yes")==0)
-               autof = -2;
+               autof = 2;
        else if (strcasecmp(str,"md")==0)
-               autof = -1;
+               autof = config?5:3;
        else {
                /* There might be digits, and maybe a hypen, at the end */
                char *e = str + strlen(str);
@@ -279,19 +279,24 @@ int parse_auto(char *str, char *msg)
                if (e > str && e[-1] == '-')
                        e--;
                len = e - str;
-               if ((len == 3 && strncasecmp(str,"mdp",3)==0) ||
-                   (len == 1 && strncasecmp(str,"p",1)==0) ||
-                   (len >= 4 && strncasecmp(str,"part",4)==0))
-                       autof = num;
-               else {
+               if ((len == 2 && strncasecmp(str,"md",2)==0)) {
+                       autof = config ? 5 : 3;
+               } else if ((len == 3 && strncasecmp(str,"mdp",3)==0)) {
+                       autof = config ? 6 : 4;
+               } else if ((len == 1 && strncasecmp(str,"p",1)==0) ||
+                          (len >= 4 && strncasecmp(str,"part",4)==0)) {
+                       autof = 6;
+               } else {
                        fprintf(stderr, Name ": %s arg of \"%s\" unrecognised: use no,yes,md,mdp,part\n"
                                "        optionally followed by a number.\n",
                                msg, str);
                        exit(2);
                }
+               autof |= num << 3;
        }
        return autof;
 }
+
 static void createline(char *line)
 {
        char *w;
@@ -299,7 +304,7 @@ static void createline(char *line)
 
        for (w=dl_next(line); w!=line; w=dl_next(w)) {
                if (strncasecmp(w, "auto=", 5) == 0)
-                       createinfo.autof = parse_auto(w+5, "auto=");
+                       createinfo.autof = parse_auto(w+5, "auto=", 1);
                else if (strncasecmp(w, "owner=", 6) == 0) {
                        if (w[6] == 0) {
                                fprintf(stderr, Name ": missing owner name\n");
@@ -475,7 +480,7 @@ void arrayline(char *line)
                                fprintf(stderr, Name ": metadata format %s unknown, ignored.\n", w+9);
                } else if (strncasecmp(w, "auto=", 5) == 0 ) {
                        /* whether to create device special files as needed */
-                       mis.autof = parse_auto(w+5, "auto type");
+                       mis.autof = parse_auto(w+5, "auto type", 0);
                } else {
                        fprintf(stderr, Name ": unrecognised word on ARRAY line: %s\n",
                                w);
diff --git a/mdadm.c b/mdadm.c
index 119b7495f81b7a97284dbfcc2323e0ac6a26a8fa..26a2744b11160f0cff29cde5362734f02e58a619 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -75,15 +75,17 @@ int main(int argc, char *argv[])
        int force = 0;
        int test = 0;
        int assume_clean = 0;
-       int autof = 0; /* -3 means don't create anything,
-                       * -2 means create device based on name:
-                       *    if it ends mdN, then non-partitioned array N
-                       *    if it ends dN, then partitions array N
-                       * -1 means create non-partitioned, choose N
-                       *  1 or more to create partitioned
-                       * If -1 or 1 and name is a 'standard' name, then
-                       * insist on a match of type and number.
-                       */
+       /* autof indicates whether and how to create device node.
+        * bottom 3 bits are style.  Rest (when shifted) are number of parts
+        * 0  - unset
+        * 1  - don't create (no)
+        * 2  - if is_standard, then create (yes)
+        * 3  - create as 'md' - reject is_standard mdp (md)
+        * 4  - create as 'mdp' - reject is_standard md (mdp)
+        * 5  - default to md if not is_standard (md in config file)
+        * 6  - default to mdp if not is_standard (part, or mdp in config file)
+        */
+       int autof = 0;
 
        char *mailaddr = NULL;
        char *program = NULL;
@@ -483,7 +485,7 @@ int main(int argc, char *argv[])
                case O(CREATE,'a'):
                case O(BUILD,'a'):
                case O(ASSEMBLE,'a'): /* auto-creation of device node */
-                       autof = parse_auto(optarg, "--auto flag");
+                       autof = parse_auto(optarg, "--auto flag", 0);
                        continue;
 
                case O(BUILD,'f'): /* force honouring '-n 1' */
diff --git a/mdadm.h b/mdadm.h
index 70aa1508743ae86ce2683fc527ccfa6917a9f553..56c4e5b773179c97f63aefa00bba89a4bafead22 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -374,7 +374,7 @@ extern int get_mdp_major(void);
 extern int dev_open(char *dev, int flags);
 extern int is_standard(char *dev, int *nump);
 
-extern int parse_auto(char *str, char *msg);
+extern int parse_auto(char *str, char *msg, int config);
 extern mddev_ident_t conf_get_ident(char *conffile, char *dev);
 extern mddev_dev_t conf_get_devs(char *conffile);
 extern struct createinfo *conf_get_create_info(char *conffile);
index 598c6a2ab8770decc113f080591425bb4026405e..076985d369e7f710d55843b654cafa7fe3326098 100644 (file)
--- a/mdopen.c
+++ b/mdopen.c
@@ -46,6 +46,7 @@ void make_parts(char *dev, int cnt)
        char *name = malloc(nlen);
        int dig = isdigit(dev[strlen(dev)-1]);
 
+       if (cnt==0) cnt=4;
        if (stat(dev, &stb)!= 0)
                return;
        if (!S_ISBLK(stb.st_mode))
@@ -94,27 +95,59 @@ int open_mddev(char *dev, int autof)
        struct mdstat_ent *mdlist;
        int num;
        struct createinfo *ci = conf_get_create_info(NULL);
+       int parts;
 
        if (autof == 0)
                autof = ci->autof;
 
-       if (autof && autof != -3) {
+       parts = autof >> 3;
+       autof &= 7;
+
+       if (autof && autof != 1) {
                /* autof is set, so we need to check that the name is ok,
                 * and possibly create one if not
                 */
-               if (autof == -2 && !is_standard(dev, NULL)) {
-                       fprintf(stderr, Name ": --auto=yes requires a 'standard' md device name, not %s\n", dev);
-                       return -1;
-               }
+               int std;
                stb.st_mode = 0;
                if (stat(dev, &stb)==0 && ! S_ISBLK(stb.st_mode)) {
                        fprintf(stderr, Name ": %s is not a block device.\n",
                                dev);
                        return -1;
                }
+               if (autof == 2 && stb.st_mode == 0 && !is_standard(dev, NULL)) {
+                       fprintf(stderr, Name ": --auto=yes requires a 'standard' md device name, not %s\n", dev);
+                       return -1;
+               }
                /* check major number is correct */
-               if (autof>0)
-                       major = get_mdp_major();
+               num = -1;
+               std = is_standard(dev, &num);
+               if (std>0) major = get_mdp_major();
+               switch(autof) {
+               case 2: /* only create is_standard names */
+                       if (!std && !stb.st_mode) {
+                               fprintf(stderr, Name ": --auto=yes requires a 'standard' md device name, not %s\n", dev);
+                               return -1;
+                       }
+                       break;
+               case 3: /* create md, reject std>0 */
+                       if (std > 0) {
+                               fprintf(stderr, Name ": that --auto option not compatable with device named %s\n", dev);
+                               return -1;
+                       }
+                       break;
+               case 4: /* create mdp, reject std<0 */
+                       if (std < 0) {
+                               fprintf(stderr, Name ": that --auto option not compatable with device named %s\n", dev);
+                               return -1;
+                       }
+                       break;
+               case 5: /* default to md if not standard */
+                       break;
+               case 6: /* default to mdp if not standard */
+                       if (std == 0) major = get_mdp_major();
+                       break;
+               }
+               /* major is final. num is -1 if not standard */
                if (stb.st_mode && major(stb.st_rdev) != major)
                        must_remove = 1;
                if (stb.st_mode && !must_remove) {
@@ -136,8 +169,8 @@ int open_mddev(char *dev, int autof)
                                must_remove = 1;
                                close(mdfd);
                        } else {
-                               if (autof > 0)
-                                       make_parts(dev, autof);
+                               if (major != MD_MAJOR && parts > 0)
+                                       make_parts(dev, parts);
                                return mdfd;
                        }
                }
@@ -147,37 +180,25 @@ int open_mddev(char *dev, int autof)
                 * easiest to read /proc/mdstat, and hunt through for
                 * an unused number 
                 */
-               switch(is_standard(dev, &num)) {
-               case -1: /* non partitioned */
-                       if (autof > 0) {
-                               fprintf(stderr, Name ": that --auto option not compatable with device named %s\n", dev);
-                               return -1;
-                       }
-                       minor = num;
-                       num = -1-num;
-                       break;
-               case 1: /* partitioned */
-                       if (autof == -1) {
-                               fprintf(stderr, Name ": that --auto option not compatable with device named %s\n", dev);
-                               return -1;
-                       }
-                       minor = num <<  MdpMinorShift;
-                       major = get_mdp_major();
-                       break;
-               case 0: /* not standard, pick an unused number */
+               if (num < 0) {
+                       /* need to pick an unused number */
                        mdlist = mdstat_read(0, 0);
-                       for (num= (autof>0)?-1:0 ; ; num+= (autof>2)?-1:1) {
+                       for (num = 0 ; ; num++) {
                                struct mdstat_ent *me;
+                               int devnum = num;
+                               if (major != MD_MAJOR)
+                                       devnum = -1-num;
+
                                for (me=mdlist; me; me=me->next)
-                                       if (me->devnum == num)
+                                       if (me->devnum == devnum)
                                                break;
                                if (!me) {
                                        /* doesn't exist if mdstat.
                                         * make sure it is new to /dev too
                                         */
                                        char *dn;
-                                       if (autof > 0) 
-                                               minor = (-1-num) << MdpMinorShift;
+                                       if (major != MD_MAJOR)
+                                               minor = num << MdpMinorShift;
                                        else
                                                minor = num;
                                        dn = map_dev(major,minor, 0);
@@ -189,9 +210,12 @@ int open_mddev(char *dev, int autof)
                                        }
                                }
                        }
-               }
+               } else if (major == MD_MAJOR)
+                       minor = num;
+               else
+                       minor = num << MdpMinorShift;
                /* major and minor have been chosen */
-               
+
                /* If it was a 'standard' name and it is in-use, then
                 * the device could already be correct
                 */
@@ -224,7 +248,8 @@ int open_mddev(char *dev, int autof)
                        }
                        stat(dev, &stb);
                        add_dev(dev, &stb, 0, NULL);
-                       make_parts(dev,autof);
+                       if (major != MD_MAJOR)
+                               make_parts(dev,parts);
                }
        }
        mdfd = open(dev, O_RDWR, 0);