summaryrefslogtreecommitdiffstats
path: root/sysfs.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2008-09-15 20:58:42 -0700
committerDan Williams <dan.j.williams@intel.com>2008-09-15 20:58:42 -0700
commit1770662bcac724915520fd0784b6f806c8d96752 (patch)
treeeadc61fbd375d5120cbe9eb1a5036967bdf0f716 /sysfs.c
parentc94709e83f662c4780aa9c6917b03c774747eca5 (diff)
downloadmdadm-1770662bcac724915520fd0784b6f806c8d96752.tar.gz
mdadm-1770662bcac724915520fd0784b6f806c8d96752.tar.xz
mdadm-1770662bcac724915520fd0784b6f806c8d96752.zip
'mdadm --wait-clean' wait for array to be marked clean
For use in distro shutdown scripts with a RAID root file system. Returns immediately if the array is 'readonly', or not an externally managed array. It is up to the distro's scripts to make sure no new writes hit the device after this returns 'true'. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'sysfs.c')
-rw-r--r--sysfs.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/sysfs.c b/sysfs.c
index dced322..182028c 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -25,6 +25,7 @@
#include "mdadm.h"
#include <dirent.h>
+#include <ctype.h>
int load_sys(char *path, char *buf)
{
@@ -185,6 +186,35 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
goto abort;
sra->mismatch_cnt = strtoul(buf, NULL, 0);
}
+ if (options & GET_SAFEMODE) {
+ int scale = 1;
+ int dot = 0;
+ int i;
+ unsigned long msec;
+ size_t len;
+
+ strcpy(base, "safe_mode_delay");
+ if (load_sys(fname, buf))
+ goto abort;
+
+ /* remove a period, and count digits after it */
+ len = strlen(buf);
+ for (i = 0; i < len; i++) {
+ if (dot) {
+ if (isdigit(buf[i])) {
+ buf[i-1] = buf[i];
+ scale *= 10;
+ }
+ buf[i] = 0;
+ } else if (buf[i] == '.') {
+ dot=1;
+ buf[i] = 0;
+ }
+ }
+ msec = strtoul(buf, NULL, 10);
+ msec = (msec * 1000) / scale;
+ sra->safe_mode_delay = msec;
+ }
if (! (options & GET_DEVS))
return sra;
@@ -265,6 +295,31 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
return NULL;
}
+int sysfs_attr_match(const char *attr, const char *str)
+{
+ /* See if attr, read from a sysfs file, matches
+ * str. They must either be the same, or attr can
+ * have a trailing newline or comma
+ */
+ while (*attr && *str && *attr == *str) {
+ attr++;
+ str++;
+ }
+
+ if (*str || (*attr && *attr != ',' && *attr != '\n'))
+ return 0;
+ return 1;
+}
+
+int sysfs_match_word(const char *word, char **list)
+{
+ int n;
+ for (n=0; list[n]; n++)
+ if (sysfs_attr_match(word, list[n]))
+ break;
+ return n;
+}
+
unsigned long long get_component_size(int fd)
{
/* Find out the component size of the array.