]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Support --grow --bitmap=internal
authorNeil Brown <neilb@suse.de>
Tue, 7 Jun 2005 23:03:46 +0000 (23:03 +0000)
committerNeil Brown <neilb@suse.de>
Tue, 7 Jun 2005 23:03:46 +0000 (23:03 +0000)
Adding a filebased bitmap is not yet supported, and
this code is still under development.

Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Grow.c
Manage.c
mdadm.c
mdadm.h

diff --git a/Grow.c b/Grow.c
index 41c7dc0317aa539884c94a2586ac3c70d69449cb..817a17a8e5b667cae63e4b7e0156572be58dff4f 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -191,3 +191,86 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
 
        return 0;
 }
+
+int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay)
+{
+       /*
+        * First check that array doesn't have a bitmap
+        * Then create the bitmap
+        * Then add it
+        *
+        * For internal bitmaps, we need to check the version,
+        * find all the active devices, and write the bitmap block
+        * to all devices
+        */
+       mdu_bitmap_file_t bmf;
+       mdu_array_info_t array;
+       struct supertype *st;
+
+       if (ioctl(fd, GET_BITMAP_FILE, &bmf) != 0) {
+               if (errno == ENOMEM) 
+                       fprintf(stderr, Name ": Memory allocation failure.\n");
+               else
+                       fprintf(stderr, Name ": bitmaps not supported by this kernel.\n");
+               return 1;
+       }
+       if (bmf.pathname[0]) {
+               fprintf(stderr, Name ": %s already has a bitmap (%s)\n",
+                       devname, bmf.pathname);
+               return 1;
+       }
+       if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) {
+               fprintf(stderr, Name ": cannot get array status for %s\n", devname);
+               return 1;
+       }
+       if (array.state & (1<<MD_SB_BITMAP_PRESENT)) {
+               fprintf(stderr, Name ": Internal bitmap already present on %s\n",
+                       devname);
+               return 1;
+       }
+       st = super_by_version(array.major_version, array.minor_version);
+       if (!st) {
+               fprintf(stderr, Name ": Cannot understand version %d.%d\n",
+                       array.major_version, array.minor_version);
+               return 1;
+       }
+       if (strcmp(file, "internal") == 0) {
+               int d;
+               for (d=0; d< MD_SB_DISKS; d++) {
+                       mdu_disk_info_t disk;
+                       char *dv;
+                       disk.number = d;
+                       if (ioctl(fd, GET_DISK_INFO, &disk) < 0)
+                               continue;
+                       if (disk.major == 0 &&
+                           disk.minor == 0)
+                               continue;
+                       if ((disk.state & (1<<MD_DISK_SYNC))==0)
+                               continue;
+                       dv = map_dev(disk.major, disk.minor);
+                       if (dv) {
+                               void *super;
+                               int fd2 = open(dv, O_RDWR);
+                               if (fd2 < 0)
+                                       continue;
+                               if (st->ss->load_super(st, fd2, &super, NULL)==0) {
+                                       st->ss->add_internal_bitmap(super, 
+                                                                   chunk, delay,
+                                                                   array.size);
+                                       st->ss->write_bitmap(st, fd2, super);
+                               }
+                               close(fd2);
+                       }
+               }
+               array.state |= (1<<MD_SB_BITMAP_PRESENT);
+               if (ioctl(fd, SET_ARRAY_INFO, &array)!= 0) {
+                       fprintf(stderr, Name ": failed to set internal bitmap.\n");
+                       return 1;
+               }
+       } else
+               abort(); /* FIXME */
+
+       return 0;
+}
+
+               
index 85168f4c623e2c773571d991bc02e3ece6b306d6..2806201afcabbb38dc50ccb55b670cb594614d65 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -203,7 +203,11 @@ int Manage_subdevs(char *devname, int fd,
                                return 1;
                        }
                        close(tfd);
+#if 0
                        if (array.major_version == 0) {
+#else
+                               if (md_get_version(fd)%100 < 2) {
+#endif
                                if (ioctl(fd, HOT_ADD_DISK,
                                          (unsigned long)stb.st_rdev)==0) {
                                        fprintf(stderr, Name ": hot added %s\n",
diff --git a/mdadm.c b/mdadm.c
index 39cad1aef890c819cbe6c3d50aa69743f1e55e9f..83b452e25fdbd59e16b233372b4f8b24abf84c53 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -138,7 +138,7 @@ int main(int argc, char *argv[])
                        continue;
 
                case 'b':
-                       if (mode == ASSEMBLE || mode == BUILD || mode == CREATE)
+                       if (mode == ASSEMBLE || mode == BUILD || mode == CREATE || mode == GROW)
                                break; /* b means bitmap */
                        brief = 1;
                        continue;
@@ -587,6 +587,7 @@ int main(int argc, char *argv[])
                        continue;
 
                case O(MONITOR,'d'): /* delay in seconds */
+               case O(GROW, 'd'):
                case O(BUILD,'d'): /* delay for bitmap updates */
                case O(CREATE,'d'):
                        if (delay)
@@ -709,11 +710,14 @@ int main(int argc, char *argv[])
                        }
                        ident.bitmap_fd = bitmap_fd; /* for Assemble */
                        continue;
+
+               case O(GROW,'b'):
                case O(BUILD,'b'):
                case O(CREATE,'b'): /* here we create the bitmap */
                        bitmap_file = optarg;
                        continue;
 
+               case O(GROW,4):
                case O(BUILD,4):
                case O(CREATE,4): /* bitmap chunksize */
                        bitmap_chunk = strtol(optarg, &c, 10);
@@ -1014,15 +1018,19 @@ int main(int argc, char *argv[])
                                if (rv)
                                        break;
                        }
-               } else if ((size >= 0) + (raiddisks != 0) +  (layout != UnSet) > 1) {
-                       fprintf(stderr, Name ": can change at most one of size, raiddisks, and layout\n");
+               } else if ((size >= 0) + (raiddisks != 0) +  (layout != UnSet) + (bitmap_file != NULL)> 1) {
+                       fprintf(stderr, Name ": can change at most one of size, raiddisks, bitmap, and layout\n");
                        rv = 1;
                        break;
                } else if (layout != UnSet)
                        rv = Manage_reconfig(devlist->devname, mdfd, layout);
                else if (size >= 0 || raiddisks)
                        rv = Manage_resize(devlist->devname, mdfd, size, raiddisks);
-               else 
+               else if (bitmap_file) {
+                       if (delay == 0) delay = DEFAULT_BITMAP_DELAY;
+                       rv = Grow_addbitmap(devlist->devname, mdfd, bitmap_file,
+                                           bitmap_chunk, delay);
+               } else
                        fprintf(stderr, Name ": no changes to --grow\n");
                break;
        }
diff --git a/mdadm.h b/mdadm.h
index fb1773d86643b359960c21a069f71c046b4353fb..3f8424e53c0302c7e45771d6dd14c14353bc72f6 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -187,6 +187,7 @@ extern struct superswitch {
        __u64 (*avail_size)(__u64 size);
        int (*add_internal_bitmap)(void *sbv, int chunk, int delay, unsigned long long size);
        void (*locate_bitmap)(struct supertype *st, int fd);
+       int (*write_bitmap)(struct supertype *st, int fd, void *sbv);
        int major;
 } super0, super1, *superlist[];
 
@@ -206,6 +207,7 @@ extern int Manage_reconfig(char *devname, int fd, int layout);
 extern int Manage_subdevs(char *devname, int fd,
                          mddev_dev_t devlist);
 extern int Grow_Add_device(char *devname, int fd, char *newdev);
+extern int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay);
 
 
 extern int Assemble(struct supertype *st, char *mddev, int mdfd,