On Sat, Jul 18 2020, Zhao Heming wrote: > After kernel md module commit 480523feae581, in md-cluster env, > mddev->in_sync always zero, it will make array.state never set > up MD_SB_CLEAN. it causes "mdadm -D /dev/mdX" show state 'active' > all the time. > > bitmap.c: add a new API IsBitmapDirty() to support inquiry bitmap > dirty or clean. > > Signed-off-by: Zhao Heming <heming.zhao@xxxxxxxx> > --- > Detail.c | 21 ++++++++++++++++++++- > bitmap.c | 27 +++++++++++++++++++++++++++ > mdadm.h | 1 + > 3 files changed, 48 insertions(+), 1 deletion(-) > > diff --git a/Detail.c b/Detail.c > index 24eeba0..fd580a3 100644 > --- a/Detail.c > +++ b/Detail.c > @@ -495,8 +495,27 @@ int Detail(char *dev, struct context *c) > sra->array_state); > else > arrayst = "clean"; > - } else > + } else { > arrayst = "active"; > + if (array.state & (1<<MD_SB_CLUSTERED)) { > + int dirty = 0; > + for (d = 0; d < max_disks * 2; d++) { > + char *dv; > + mdu_disk_info_t disk = disks[d]; > + > + if (d >= array.raid_disks * 2 && > + disk.major == 0 && disk.minor == 0) > + continue; > + if ((d & 1) && disk.major == 0 && disk.minor == 0) > + continue; > + dv = map_dev_preferred(disk.major, disk.minor, 0, c->prefer); > + if (dv != NULL) > + if ((dirty = IsBitmapDirty(dv))) break; You don't need to read the bitmap from every device - they should all be the same. Just reading one is sufficient. However .... > + } > + if (dirty == 0) > + arrayst = "clean"; > + } > + } > > printf(" State : %s%s%s%s%s%s%s \n", > arrayst, st, > diff --git a/bitmap.c b/bitmap.c > index e38cb96..90ad932 100644 > --- a/bitmap.c > +++ b/bitmap.c > @@ -368,6 +368,33 @@ free_info: > return rv; > } > > +int IsBitmapDirty(char *filename) > +{ > + /* > + * Read the bitmap file > + * return: 1(dirty), 0 (clean), -1(error) > + */ > + > + struct supertype *st = NULL; > + bitmap_info_t *info; > + int fd = -1, rv = -1; > + > + fd = bitmap_file_open(filename, &st, 0); > + if (fd < 0) > + return rv; > + > + info = bitmap_fd_read(fd, 0); This only examines the first bitmap. For a cluster-array there is a separate bitmap for each node in the cluster. See the for (i = 0; i < (int)sb->nodes; i++) { loop in ExamineBitmap(). You need to check for active bits in every bitmap on the selected device. NeilBrown > + if (!info) { > + goto out; > + } > + rv = info->dirty_bits ? 1 : 0; > + free(info); > +out: > + close(fd); > + free(st); > + return rv; > +} > + > int CreateBitmap(char *filename, int force, char uuid[16], > unsigned long chunksize, unsigned long daemon_sleep, > unsigned long write_behind, > diff --git a/mdadm.h b/mdadm.h > index 399478b..ba8ba91 100644 > --- a/mdadm.h > +++ b/mdadm.h > @@ -1447,6 +1447,7 @@ extern int CreateBitmap(char *filename, int force, char uuid[16], > unsigned long long array_size, > int major); > extern int ExamineBitmap(char *filename, int brief, struct supertype *st); > +extern int IsBitmapDirty(char *filename); > extern int Write_rules(char *rule_name); > extern int bitmap_update_uuid(int fd, int *uuid, int swap); > > -- > 2.25.0
Attachment:
signature.asc
Description: PGP signature