]>
git.ipfire.org Git - thirdparty/mdadm.git/blob - Monitor.c
2 * mdadm - manage Linux "md" devices aka RAID arrays.
4 * Copyright (C) 2001-2009 Neil Brown <neilb@suse.de>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * Email: <neilb@suse.de>
35 char devnm
[32]; /* to sync with mdstat info */
39 int active
, working
, failed
, spare
, raid
;
43 int devstate
[MAX_DISKS
];
44 dev_t devid
[MAX_DISKS
];
46 char parent_devnm
[32]; /* For subarray, devnm of parent.
49 struct supertype
*metadata
;
50 struct state
*subarray
;/* for a container it is a link to first subarray
51 * for a subarray it is a link to next subarray
52 * in the same container */
53 struct state
*parent
; /* for a subarray it is a link to its container
64 static int make_daemon(char *pidfile
);
65 static int check_one_sharer(int scan
);
66 static void alert(char *event
, char *dev
, char *disc
, struct alert_info
*info
);
67 static int check_array(struct state
*st
, struct mdstat_ent
*mdstat
,
68 int test
, struct alert_info
*info
,
69 int increments
, char *prefer
);
70 static int add_new_arrays(struct mdstat_ent
*mdstat
, struct state
**statelist
,
71 int test
, struct alert_info
*info
);
72 static void try_spare_migration(struct state
*statelist
, struct alert_info
*info
);
73 static void link_containers_with_subarrays(struct state
*list
);
75 int Monitor(struct mddev_dev
*devlist
,
76 char *mailaddr
, char *alert_cmd
,
78 int daemonise
, int oneshot
,
79 int dosyslog
, char *pidfile
, int increments
,
83 * Every few seconds, scan every md device looking for changes
84 * When a change is found, log it, possibly run the alert command,
85 * and possibly send Email
87 * For each array, we record:
89 * active/working/failed/spare drives
90 * State of each device.
91 * %rebuilt if rebuilding
93 * If the update time changes, check out all the data again
94 * It is possible that we cannot get the state of each device
95 * due to bugs in the md kernel module.
96 * We also read /proc/mdstat to get rebuild percent,
97 * and to get state on all active devices incase of kernel bug.
101 * An active device had Faulty set or Active/Sync removed
103 * A spare device had Faulty set
105 * An active device had a reverse transition
107 * percent went from -1 to +ve
109 * percent went from below to not-below NN%
111 * Couldn't access a device which was previously visible
113 * if we detect an array with active<raid and spare==0
114 * we look at other arrays that have same spare-group
115 * If we find one with active==raid and spare>0,
116 * and if we can get_disk_info and find a name
117 * Then we hot-remove and hot-add to the other array
119 * If devlist is NULL, then we can monitor everything because --scan
120 * was given. We get an initial list from config file and add anything
121 * that appears in /proc/mdstat
124 struct state
*statelist
= NULL
;
127 struct mdstat_ent
*mdstat
= NULL
;
128 char *mailfrom
= NULL
;
129 struct alert_info info
;
130 struct mddev_ident
*mdlist
;
133 mailaddr
= conf_get_mailaddr();
134 if (mailaddr
&& ! c
->scan
)
135 pr_err("Monitor using email address \"%s\" from config file\n",
138 mailfrom
= conf_get_mailfrom();
141 alert_cmd
= conf_get_program();
142 if (alert_cmd
&& ! c
->scan
)
143 pr_err("Monitor using program \"%s\" from config file\n",
146 if (c
->scan
&& !mailaddr
&& !alert_cmd
&& !dosyslog
) {
147 pr_err("No mail address or alert command - not monitoring.\n");
150 info
.alert_cmd
= alert_cmd
;
151 info
.mailaddr
= mailaddr
;
152 info
.mailfrom
= mailfrom
;
153 info
.dosyslog
= dosyslog
;
156 int rv
= make_daemon(pidfile
);
162 if (check_one_sharer(c
->scan
))
165 if (devlist
== NULL
) {
166 mdlist
= conf_get_ident(NULL
);
167 for (; mdlist
; mdlist
=mdlist
->next
) {
169 if (mdlist
->devname
== NULL
)
171 if (strcasecmp(mdlist
->devname
, "<ignore>") == 0)
173 st
= xcalloc(1, sizeof *st
);
174 if (mdlist
->devname
[0] == '/')
175 st
->devname
= xstrdup(mdlist
->devname
);
177 st
->devname
= xmalloc(8+strlen(mdlist
->devname
)+1);
178 strcpy(strcpy(st
->devname
, "/dev/md/"),
181 st
->next
= statelist
;
183 st
->percent
= RESYNC_UNKNOWN
;
185 st
->expected_spares
= mdlist
->spare_disks
;
186 if (mdlist
->spare_group
)
187 st
->spare_group
= xstrdup(mdlist
->spare_group
);
191 struct mddev_dev
*dv
;
192 for (dv
=devlist
; dv
; dv
=dv
->next
) {
193 struct state
*st
= xcalloc(1, sizeof *st
);
194 mdlist
= conf_get_ident(dv
->devname
);
195 st
->devname
= xstrdup(dv
->devname
);
196 st
->next
= statelist
;
198 st
->percent
= RESYNC_UNKNOWN
;
199 st
->expected_spares
= -1;
201 st
->expected_spares
= mdlist
->spare_disks
;
202 if (mdlist
->spare_group
)
203 st
->spare_group
= xstrdup(mdlist
->spare_group
);
211 struct state
*st
, **stp
;
216 mdstat
= mdstat_read(oneshot
?0:1, 0);
220 for (st
=statelist
; st
; st
=st
->next
)
221 if (check_array(st
, mdstat
, c
->test
, &info
,
222 increments
, c
->prefer
))
225 /* now check if there are any new devices found in mdstat */
227 new_found
= add_new_arrays(mdstat
, &statelist
, c
->test
,
230 /* If an array has active < raid && spare == 0 && spare_group != NULL
231 * Look for another array with spare > 0 and active == raid and same spare_group
232 * if found, choose a device and hotremove/hotadd
234 if (share
&& anydegraded
)
235 try_spare_migration(statelist
, &info
);
240 mdstat_wait(c
->delay
);
244 for (stp
= &statelist
; (st
= *stp
) != NULL
; ) {
245 if (st
->from_auto
&& st
->err
> 5) {
248 free(st
->spare_group
);
254 for (st2
= statelist
; st2
; st2
= statelist
) {
255 statelist
= st2
->next
;
264 static int make_daemon(char *pidfile
)
267 * -1 in the forked daemon
270 * so a none-negative becomes the exit code.
278 pid_file
=fopen(pidfile
, "w");
280 perror("cannot create pid file");
282 fprintf(pid_file
,"%d\n", pid
);
293 open("/dev/null", O_RDWR
);
300 static int check_one_sharer(int scan
)
307 sprintf(path
, "%s/autorebuild.pid", MDMON_DIR
);
308 fp
= fopen(path
, "r");
310 if (fscanf(fp
, "%d", &pid
) != 1)
312 sprintf(dir
, "/proc/%d", pid
);
313 rv
= stat(dir
, &buf
);
316 pr_err("Only one autorebuild process allowed in scan mode, aborting\n");
320 pr_err("Warning: One autorebuild process already running.\n");
326 if (mkdir(MDMON_DIR
, S_IRWXU
) < 0 &&
328 pr_err("Can't create autorebuild.pid file\n");
330 fp
= fopen(path
, "w");
332 pr_err("Cannot create autorebuild.pidfile\n");
335 fprintf(fp
, "%d\n", pid
);
343 static void alert(char *event
, char *dev
, char *disc
, struct alert_info
*info
)
347 if (!info
->alert_cmd
&& !info
->mailaddr
&& !info
->dosyslog
) {
348 time_t now
= time(0);
350 printf("%1.15s: %s on %s %s\n", ctime(&now
)+4, event
, dev
, disc
?disc
:"unknown device");
352 if (info
->alert_cmd
) {
356 waitpid(pid
, NULL
, 0);
361 execl(info
->alert_cmd
, info
->alert_cmd
,
362 event
, dev
, disc
, NULL
);
366 if (info
->mailaddr
&&
367 (strncmp(event
, "Fail", 4)==0 ||
368 strncmp(event
, "Test", 4)==0 ||
369 strncmp(event
, "Spares", 6)==0 ||
370 strncmp(event
, "Degrade", 7)==0)) {
371 FILE *mp
= popen(Sendmail
, "w");
375 gethostname(hname
, sizeof(hname
));
376 signal(SIGPIPE
, SIG_IGN
);
378 fprintf(mp
, "From: %s\n", info
->mailfrom
);
380 fprintf(mp
, "From: %s monitoring <root>\n", Name
);
381 fprintf(mp
, "To: %s\n", info
->mailaddr
);
382 fprintf(mp
, "Subject: %s event on %s:%s\n\n",
386 "This is an automatically generated mail message from %s\n", Name
);
387 fprintf(mp
, "running on %s\n\n", hname
);
390 "A %s event had been detected on md device %s.\n\n", event
, dev
);
392 if (disc
&& disc
[0] != ' ')
394 "It could be related to component device %s.\n\n", disc
);
395 if (disc
&& disc
[0] == ' ')
396 fprintf(mp
, "Extra information:%s.\n\n", disc
);
398 fprintf(mp
, "Faithfully yours, etc.\n");
400 mdstat
= fopen("/proc/mdstat", "r");
405 "\nP.S. The /proc/mdstat file currently contains the following:\n\n");
406 while ( (n
=fread(buf
, 1, sizeof(buf
), mdstat
)) > 0)
407 n
=fwrite(buf
, 1, n
, mp
);
414 /* log the event to syslog maybe */
415 if (info
->dosyslog
) {
416 /* Log at a different severity depending on the event.
418 * These are the critical events: */
419 if (strncmp(event
, "Fail", 4)==0 ||
420 strncmp(event
, "Degrade", 7)==0 ||
421 strncmp(event
, "DeviceDisappeared", 17)==0)
423 /* Good to know about, but are not failures: */
424 else if (strncmp(event
, "Rebuild", 7)==0 ||
425 strncmp(event
, "MoveSpare", 9)==0 ||
426 strncmp(event
, "Spares", 6) != 0)
427 priority
= LOG_WARNING
;
428 /* Everything else: */
432 if (disc
&& disc
[0] != ' ')
434 "%s event detected on md device %s, component device %s", event
, dev
, disc
);
437 "%s event detected on md device %s: %s",
441 "%s event detected on md device %s",
446 static int check_array(struct state
*st
, struct mdstat_ent
*mdstat
,
447 int test
, struct alert_info
*ainfo
,
448 int increments
, char *prefer
)
450 /* Update the state 'st' to reflect any changes shown in mdstat,
451 * or found by directly examining the array, and return
452 * '1' if the array is degraded, or '0' if it is optimal (or dead).
454 struct { int state
, major
, minor
; } info
[MAX_DISKS
];
455 struct mdinfo
*sra
= NULL
;
456 mdu_array_info_t array
;
457 struct mdstat_ent
*mse
= NULL
, *mse2
;
458 char *dev
= st
->devname
;
467 alert("TestMessage", dev
, NULL
, ainfo
);
471 fd
= open(dev
, O_RDONLY
);
475 if (!md_array_active(fd
))
478 fcntl(fd
, F_SETFD
, FD_CLOEXEC
);
479 if (md_get_array_info(fd
, &array
) < 0)
482 if (st
->devnm
[0] == 0)
483 strcpy(st
->devnm
, fd2devnm(fd
));
485 sra
= sysfs_read(-1, st
->devnm
, GET_LEVEL
| GET_DISKS
| GET_DEGRADED
|
486 GET_MISMATCH
| GET_DEVS
| GET_STATE
);
490 /* It's much easier to list what array levels can't
491 * have a device disappear than all of them that can
493 if (sra
->array
.level
== 0 || sra
->array
.level
== -1) {
494 if (!st
->err
&& !st
->from_config
)
495 alert("DeviceDisappeared", dev
, " Wrong-Level", ainfo
);
500 for (mse2
= mdstat
; mse2
; mse2
=mse2
->next
)
501 if (strcmp(mse2
->devnm
, st
->devnm
) == 0) {
502 mse2
->devnm
[0] = 0; /* flag it as "used" */
507 /* duplicated array in statelist
508 * or re-created after reading mdstat*/
513 /* this array is in /proc/mdstat */
514 if (array
.utime
== 0)
515 /* external arrays don't update utime, so
516 * just make sure it is always different. */
517 array
.utime
= st
->utime
+ 1;;
520 /* New array appeared where previously had an error */
522 st
->percent
= RESYNC_NONE
;
524 alert("NewArray", st
->devname
, NULL
, ainfo
);
527 if (st
->utime
== array
.utime
&& st
->failed
== sra
->array
.failed_disks
&&
528 st
->working
== sra
->array
.working_disks
&&
529 st
->spare
== sra
->array
.spare_disks
&&
530 (mse
== NULL
|| (mse
->percent
== st
->percent
))) {
531 if ((st
->active
< st
->raid
) && st
->spare
== 0)
535 if (st
->utime
== 0 && /* new array */
536 mse
->pattern
&& strchr(mse
->pattern
, '_') /* degraded */)
537 alert("DegradedArray", dev
, NULL
, ainfo
);
539 if (st
->utime
== 0 && /* new array */ st
->expected_spares
> 0 &&
540 sra
->array
.spare_disks
< st
->expected_spares
)
541 alert("SparesMissing", dev
, NULL
, ainfo
);
542 if (st
->percent
< 0 && st
->percent
!= RESYNC_UNKNOWN
&&
544 alert("RebuildStarted", dev
, NULL
, ainfo
);
545 if (st
->percent
>= 0 && mse
->percent
>= 0 &&
546 (mse
->percent
/ increments
) > (st
->percent
/ increments
)) {
547 char percentalert
[15];
549 * "RebuildNN" (10 chars) or "RebuildStarted" (15 chars)
552 if((mse
->percent
/ increments
) == 0)
553 snprintf(percentalert
, sizeof(percentalert
),
556 snprintf(percentalert
, sizeof(percentalert
),
557 "Rebuild%02d", mse
->percent
);
559 alert(percentalert
, dev
, NULL
, ainfo
);
562 if (mse
->percent
== RESYNC_NONE
&& st
->percent
>= 0) {
563 /* Rebuild/sync/whatever just finished.
564 * If there is a number in /mismatch_cnt,
565 * we should report that.
567 if (sra
&& sra
->mismatch_cnt
> 0) {
569 snprintf(cnt
, sizeof(cnt
),
570 " mismatches found: %d (on raid level %d)",
571 sra
->mismatch_cnt
, sra
->array
.level
);
572 alert("RebuildFinished", dev
, cnt
, ainfo
);
574 alert("RebuildFinished", dev
, NULL
, ainfo
);
576 st
->percent
= mse
->percent
;
578 remaining_disks
= sra
->array
.nr_disks
;
579 for (i
= 0; i
< MAX_DISKS
&& remaining_disks
> 0; i
++) {
580 mdu_disk_info_t disc
;
582 if (md_get_disk_info(fd
, &disc
) >= 0) {
583 info
[i
].state
= disc
.state
;
584 info
[i
].major
= disc
.major
;
585 info
[i
].minor
= disc
.minor
;
586 if (disc
.major
|| disc
.minor
)
589 info
[i
].major
= info
[i
].minor
= 0;
593 if (mse
->metadata_version
&&
594 strncmp(mse
->metadata_version
, "external:", 9) == 0 &&
595 is_subarray(mse
->metadata_version
+9)) {
597 strcpy(st
->parent_devnm
, mse
->metadata_version
+10);
598 sl
= strchr(st
->parent_devnm
, '/');
602 st
->parent_devnm
[0] = 0;
603 if (st
->metadata
== NULL
&& st
->parent_devnm
[0] == 0)
604 st
->metadata
= super_by_fd(fd
, NULL
);
606 for (i
=0; i
<MAX_DISKS
; i
++) {
607 mdu_disk_info_t disc
= {0,0,0,0,0};
612 if (i
< last_disk
&& (info
[i
].major
|| info
[i
].minor
)) {
613 newstate
= info
[i
].state
;
614 dv
= map_dev_preferred(info
[i
].major
, info
[i
].minor
, 1,
616 disc
.state
= newstate
;
617 disc
.major
= info
[i
].major
;
618 disc
.minor
= info
[i
].minor
;
620 newstate
= (1 << MD_DISK_REMOVED
);
622 if (dv
== NULL
&& st
->devid
[i
])
623 dv
= map_dev_preferred(major(st
->devid
[i
]),
624 minor(st
->devid
[i
]), 1, prefer
);
625 change
= newstate
^ st
->devstate
[i
];
626 if (st
->utime
&& change
&& !st
->err
&& !new_array
) {
627 if ((st
->devstate
[i
]&change
) & (1 << MD_DISK_SYNC
))
628 alert("Fail", dev
, dv
, ainfo
);
629 else if ((newstate
& (1 << MD_DISK_FAULTY
)) &&
630 (disc
.major
|| disc
.minor
) &&
631 st
->devid
[i
] == makedev(disc
.major
,
633 alert("FailSpare", dev
, dv
, ainfo
);
634 else if ((newstate
&change
) & (1 << MD_DISK_SYNC
))
635 alert("SpareActive", dev
, dv
, ainfo
);
637 st
->devstate
[i
] = newstate
;
638 st
->devid
[i
] = makedev(disc
.major
, disc
.minor
);
640 st
->active
= sra
->array
.active_disks
;
641 st
->working
= sra
->array
.working_disks
;
642 st
->spare
= sra
->array
.spare_disks
;
643 st
->failed
= sra
->array
.failed_disks
;
644 st
->utime
= array
.utime
;
645 st
->raid
= sra
->array
.raid_disks
;
647 if ((st
->active
< st
->raid
) && st
->spare
== 0)
659 alert("DeviceDisappeared", dev
, NULL
, ainfo
);
664 static int add_new_arrays(struct mdstat_ent
*mdstat
, struct state
**statelist
,
665 int test
, struct alert_info
*info
)
667 struct mdstat_ent
*mse
;
671 for (mse
=mdstat
; mse
; mse
=mse
->next
)
673 (!mse
->level
|| /* retrieve containers */
674 (strcmp(mse
->level
, "raid0") != 0 &&
675 strcmp(mse
->level
, "linear") != 0))
677 struct state
*st
= xcalloc(1, sizeof *st
);
678 mdu_array_info_t array
;
681 name
= get_md_name(mse
->devnm
);
687 st
->devname
= xstrdup(name
);
688 if ((fd
= open(st
->devname
, O_RDONLY
)) < 0 ||
689 md_get_array_info(fd
, &array
) < 0) {
693 put_md_name(st
->devname
);
696 st
->metadata
->ss
->free_super(st
->metadata
);
703 st
->next
= *statelist
;
706 strcpy(st
->devnm
, mse
->devnm
);
707 st
->percent
= RESYNC_UNKNOWN
;
708 st
->expected_spares
= -1;
709 if (mse
->metadata_version
&&
710 strncmp(mse
->metadata_version
, "external:", 9) == 0 &&
711 is_subarray(mse
->metadata_version
+9)) {
713 strcpy(st
->parent_devnm
,
714 mse
->metadata_version
+10);
715 sl
= strchr(st
->parent_devnm
, '/');
718 st
->parent_devnm
[0] = 0;
721 alert("TestMessage", st
->devname
, NULL
, info
);
727 static int get_required_spare_criteria(struct state
*st
,
728 struct spare_criteria
*sc
)
733 !st
->metadata
->ss
->get_spare_criteria
) {
739 fd
= open(st
->devname
, O_RDONLY
);
742 if (st
->metadata
->ss
->external
)
743 st
->metadata
->ss
->load_container(st
->metadata
, fd
, st
->devname
);
745 st
->metadata
->ss
->load_super(st
->metadata
, fd
, st
->devname
);
747 if (!st
->metadata
->sb
)
750 st
->metadata
->ss
->get_spare_criteria(st
->metadata
, sc
);
751 st
->metadata
->ss
->free_super(st
->metadata
);
756 static int check_donor(struct state
*from
, struct state
*to
)
763 /* Cannot move from a member */
767 for (sub
= from
->subarray
; sub
; sub
= sub
->subarray
)
768 /* If source array has degraded subarrays, don't
771 if (sub
->active
< sub
->raid
)
773 if (from
->metadata
->ss
->external
== 0)
774 if (from
->active
< from
->raid
)
776 if (from
->spare
<= 0)
781 static dev_t
choose_spare(struct state
*from
, struct state
*to
,
782 struct domainlist
*domlist
, struct spare_criteria
*sc
)
787 for (d
= from
->raid
; !dev
&& d
< MAX_DISKS
; d
++) {
788 if (from
->devid
[d
] > 0 &&
789 from
->devstate
[d
] == 0) {
790 struct dev_policy
*pol
;
791 unsigned long long dev_size
;
792 unsigned int dev_sector_size
;
794 if (to
->metadata
->ss
->external
&&
795 test_partition_from_id(from
->devid
[d
]))
799 dev_size_from_id(from
->devid
[d
], &dev_size
) &&
800 dev_size
< sc
->min_size
)
803 if (sc
->sector_size
&&
804 dev_sector_size_from_id(from
->devid
[d
],
806 sc
->sector_size
!= dev_sector_size
)
809 pol
= devid_policy(from
->devid
[d
]);
810 if (from
->spare_group
)
811 pol_add(&pol
, pol_domain
,
812 from
->spare_group
, NULL
);
813 if (domain_test(domlist
, pol
, to
->metadata
->ss
->name
) == 1)
814 dev
= from
->devid
[d
];
815 dev_policy_free(pol
);
821 static dev_t
container_choose_spare(struct state
*from
, struct state
*to
,
822 struct domainlist
*domlist
,
823 struct spare_criteria
*sc
, int active
)
825 /* This is similar to choose_spare, but we cannot trust devstate,
826 * so we need to read the metadata instead
829 struct supertype
*st
= from
->metadata
;
830 int fd
= open(from
->devname
, O_RDONLY
);
836 if (!st
->ss
->getinfo_super_disks
) {
841 err
= st
->ss
->load_container(st
, fd
, NULL
);
847 /* We must check if number of active disks has not increased
848 * since ioctl in main loop. mdmon may have added spare
849 * to subarray. If so we do not need to look for more spares
850 * so return non zero value */
853 list
= st
->ss
->getinfo_super_disks(st
);
855 st
->ss
->free_super(st
);
860 if (dp
->disk
.state
& (1<<MD_DISK_SYNC
) &&
861 !(dp
->disk
.state
& (1<<MD_DISK_FAULTY
)))
866 if (active
< active_cnt
) {
867 /* Spare just activated.*/
868 st
->ss
->free_super(st
);
873 /* We only need one spare so full list not needed */
874 list
= container_choose_spares(st
, sc
, domlist
, from
->spare_group
,
875 to
->metadata
->ss
->name
, 1);
877 struct mdinfo
*disks
= list
->devs
;
879 dev
= makedev(disks
->disk
.major
, disks
->disk
.minor
);
882 st
->ss
->free_super(st
);
886 static void try_spare_migration(struct state
*statelist
, struct alert_info
*info
)
890 struct spare_criteria sc
;
892 link_containers_with_subarrays(statelist
);
893 for (st
= statelist
; st
; st
= st
->next
)
894 if (st
->active
< st
->raid
&&
895 st
->spare
== 0 && !st
->err
) {
896 struct domainlist
*domlist
= NULL
;
898 struct state
*to
= st
;
900 if (to
->parent_devnm
[0] && !to
->parent
)
901 /* subarray monitored without parent container
902 * we can't move spares here */
906 /* member of a container */
909 if (get_required_spare_criteria(to
, &sc
))
911 if (to
->metadata
->ss
->external
) {
912 /* We must make sure there is
913 * no suitable spare in container already.
914 * If there is we don't add more */
915 dev_t devid
= container_choose_spare(
916 to
, to
, NULL
, &sc
, st
->active
);
920 for (d
= 0; d
< MAX_DISKS
; d
++)
922 domainlist_add_dev(&domlist
,
924 to
->metadata
->ss
->name
);
926 domain_add(&domlist
, to
->spare_group
);
928 * No spare migration if the destination
929 * has no domain. Skip this array.
933 for (from
=statelist
; from
; from
=from
->next
) {
935 if (!check_donor(from
, to
))
937 if (from
->metadata
->ss
->external
)
938 devid
= container_choose_spare(
939 from
, to
, domlist
, &sc
, 0);
941 devid
= choose_spare(from
, to
, domlist
,
944 && move_spare(from
->devname
, to
->devname
, devid
)) {
945 alert("MoveSpare", to
->devname
, from
->devname
, info
);
949 domain_free(domlist
);
953 /* search the statelist to connect external
954 * metadata subarrays with their containers
955 * We always completely rebuild the tree from scratch as
956 * that is safest considering the possibility of entries
957 * disappearing or changing.
959 static void link_containers_with_subarrays(struct state
*list
)
963 for (st
= list
; st
; st
= st
->next
) {
967 for (st
= list
; st
; st
= st
->next
)
968 if (st
->parent_devnm
[0])
969 for (cont
= list
; cont
; cont
= cont
->next
)
971 cont
->parent_devnm
[0] == 0 &&
972 strcmp(cont
->devnm
, st
->parent_devnm
) == 0) {
974 st
->subarray
= cont
->subarray
;
980 /* Not really Monitor but ... */
985 int frozen_remaining
= 3;
987 if (!stat_is_blkdev(dev
, NULL
))
992 struct mdstat_ent
*ms
= mdstat_read(1, 0);
993 struct mdstat_ent
*e
;
995 for (e
=ms
; e
; e
=e
->next
)
996 if (strcmp(e
->devnm
, devnm
) == 0)
999 if (e
&& e
->percent
== RESYNC_NONE
) {
1000 /* We could be in the brief pause before something
1001 * starts. /proc/mdstat doesn't show that, but
1007 if (sysfs_init(&mdi
, -1, devnm
))
1009 if (sysfs_get_str(&mdi
, NULL
, "sync_action",
1011 strcmp(buf
,"idle\n") != 0) {
1012 e
->percent
= RESYNC_UNKNOWN
;
1013 if (strcmp(buf
, "frozen\n") == 0) {
1014 if (frozen_remaining
== 0)
1015 e
->percent
= RESYNC_NONE
;
1017 frozen_remaining
-= 1;
1021 if (!e
|| e
->percent
== RESYNC_NONE
) {
1022 if (e
&& e
->metadata_version
&&
1023 strncmp(e
->metadata_version
, "external:", 9) == 0) {
1024 if (is_subarray(&e
->metadata_version
[9]))
1025 ping_monitor(&e
->metadata_version
[9]);
1027 ping_monitor(devnm
);
1038 static char *clean_states
[] = {
1039 "clear", "inactive", "readonly", "read-auto", "clean", NULL
};
1041 int WaitClean(char *dev
, int sock
, int verbose
)
1048 if (!stat_is_blkdev(dev
, NULL
))
1050 fd
= open(dev
, O_RDONLY
);
1053 pr_err("Couldn't open %s: %s\n", dev
, strerror(errno
));
1057 strcpy(devnm
, fd2devnm(fd
));
1058 mdi
= sysfs_read(fd
, devnm
, GET_VERSION
|GET_LEVEL
|GET_SAFEMODE
);
1061 pr_err("Failed to read sysfs attributes for %s\n", dev
);
1066 switch(mdi
->array
.level
) {
1068 case LEVEL_MULTIPATH
:
1070 /* safemode delay is irrelevant for these levels */
1074 /* for internal metadata the kernel handles the final clean
1075 * transition, containers can never be dirty
1077 if (!is_subarray(mdi
->text_version
))
1080 /* safemode disabled ? */
1081 if (mdi
->safe_mode_delay
== 0)
1085 int state_fd
= sysfs_open(fd2devnm(fd
), NULL
, "array_state");
1089 /* minimize the safe_mode_delay and prepare to wait up to 5s
1090 * for writes to quiesce
1092 sysfs_set_safemode(mdi
, 1);
1094 /* wait for array_state to be clean */
1096 rv
= read(state_fd
, buf
, sizeof(buf
));
1099 if (sysfs_match_word(buf
, clean_states
) <= 4)
1101 rv
= sysfs_wait(state_fd
, &delay
);
1102 if (rv
< 0 && errno
!= EINTR
)
1104 lseek(state_fd
, 0, SEEK_SET
);
1108 else if (fping_monitor(sock
) == 0 ||
1109 ping_monitor(mdi
->text_version
) == 0) {
1110 /* we need to ping to close the window between array
1111 * state transitioning to clean and the metadata being
1118 pr_err("Error waiting for %s to be clean\n",
1121 /* restore the original safe_mode_delay */
1122 sysfs_set_safemode(mdi
, mdi
->safe_mode_delay
);