summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2008-11-04 20:50:39 +1100
committerNeilBrown <neilb@suse.de>2008-11-04 20:50:39 +1100
commit975903767837c572971675a7bf6d866d3be5fa56 (patch)
treee199783fd86efde8dc1049f37021ed82a87c37ec
parent757a5d74ff11aadb87c9ff8e038c7140d2c457a8 (diff)
downloadmdadm-975903767837c572971675a7bf6d866d3be5fa56.tar.gz
mdadm-975903767837c572971675a7bf6d866d3be5fa56.tar.xz
mdadm-975903767837c572971675a7bf6d866d3be5fa56.zip
Generate 'change' uevents when arrays change in non-obvious ways.
When a 'container' gets started, we need udev to notice, but the kernel has no way of knowing that a KOBJ_CHANGE event is needed. So send one directly via the 'uevent' sysfs attribute. Also, uevents don't get generated when md arrays are stopped (prior to 2.6.28) so send 'change' events then too. Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--Assemble.c1
-rw-r--r--Create.c10
-rw-r--r--Incremental.c7
-rw-r--r--Manage.c9
-rw-r--r--mdadm.h1
-rw-r--r--mdassemble.c4
-rw-r--r--sysfs.c16
7 files changed, 42 insertions, 6 deletions
diff --git a/Assemble.c b/Assemble.c
index 5c5a13e..f801a73 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -984,6 +984,7 @@ int Assemble(struct supertype *st, char *mddev,
info.array.raid_disks);
fprintf(stderr, "\n");
}
+ sysfs_uevent(&info, "change");
close(mdfd);
return 0;
}
diff --git a/Create.c b/Create.c
index 23047c9..a66ed0c 100644
--- a/Create.c
+++ b/Create.c
@@ -735,11 +735,12 @@ int Create(struct supertype *st, char *mddev,
free(infos);
st->ss->free_super(st);
- /* param is not actually used */
- if (level == LEVEL_CONTAINER)
- /* No need to start */
+ if (level == LEVEL_CONTAINER) {
+ /* No need to start. But we should signal udev to
+ * create links */
+ sysfs_uevent(&info, "change");
;
- else if (runstop == 1 || subdevs >= raiddisks) {
+ } else if (runstop == 1 || subdevs >= raiddisks) {
if (st->ss->external) {
switch(level) {
case LEVEL_LINEAR:
@@ -756,6 +757,7 @@ int Create(struct supertype *st, char *mddev,
}
sysfs_set_safemode(&info, safe_mode_delay);
} else {
+ /* param is not actually used */
mdu_param_t param;
if (ioctl(mdfd, RUN_ARRAY, &param)) {
fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",
diff --git a/Incremental.c b/Incremental.c
index 1cccdf7..f0f0c00 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -376,6 +376,7 @@ int Incremental(char *devname, int verbose, int runstop,
if (info.array.level == LEVEL_CONTAINER) {
/* Try to assemble within the container */
close(mdfd);
+ sysfs_uevent(&info, "change");
if (verbose >= 0)
fprintf(stderr, Name
": container %s now has %d devices\n",
@@ -625,9 +626,15 @@ void RebuildMap(void)
st->ss->free_super(st);
break;
}
+ sysfs_free(sra);
}
map_write(map);
map_free(map);
+ for (md = mdstat ; md ; md = md->next) {
+ struct mdinfo *sra = sysfs_read(-1, md->devnum, GET_VERSION);
+ sysfs_uevent(sra, "change");
+ sysfs_free(sra);
+ }
}
int IncrementalScan(int verbose)
diff --git a/Manage.c b/Manage.c
index 6b9825b..fea563a 100644
--- a/Manage.c
+++ b/Manage.c
@@ -195,8 +195,6 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet)
*/
ping_monitor(mdi->sys_name);
}
- if (mdi)
- sysfs_free(mdi);
if (fd >= 0 && ioctl(fd, STOP_ARRAY, NULL)) {
if (quiet == 0) {
@@ -208,8 +206,15 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet)
"process, mounted filesystem "
"or active volume group?\n");
}
+ if (mdi)
+ sysfs_free(mdi);
return 1;
}
+ /* prior to 2.6.28, KOBJ_CHANGE was not sent when an md array
+ * was stopped, so We'll do it here just to be sure.
+ */
+ if (mdi)
+ sysfs_uevent(mdi, "change");
if (quiet <= 0)
fprintf(stderr, Name ": stopped %s\n", devname);
diff --git a/mdadm.h b/mdadm.h
index 8b82087..c34efe9 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -356,6 +356,7 @@ extern int sysfs_set_str(struct mdinfo *sra, struct mdinfo *dev,
char *name, char *val);
extern int sysfs_set_num(struct mdinfo *sra, struct mdinfo *dev,
char *name, unsigned long long val);
+extern int sysfs_uevent(struct mdinfo *sra, char *event);
extern int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
char *name, unsigned long long *val);
extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms);
diff --git a/mdassemble.c b/mdassemble.c
index ef5639a..02afc2d 100644
--- a/mdassemble.c
+++ b/mdassemble.c
@@ -74,6 +74,10 @@ int create_mddev(char *dev, char *name, int autof/*unused*/, int trustworthy,
{
return open_mddev(dev, 0);
}
+int sysfs_uevent(struct mdinfo *info, char *event)
+{
+ return 0;
+}
#endif
int map_update(struct map_ent **mpp, int devnum, char *metadata,
int *uuid, char *path)
diff --git a/sysfs.c b/sysfs.c
index 00f42ea..7f94d55 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -405,6 +405,22 @@ int sysfs_set_num(struct mdinfo *sra, struct mdinfo *dev,
return sysfs_set_str(sra, dev, name, valstr);
}
+int sysfs_uevent(struct mdinfo *sra, char *event)
+{
+ char fname[50];
+ int n;
+ int fd;
+
+ sprintf(fname, "/sys/block/%s/uevent",
+ sra->sys_name);
+ fd = open(fname, O_WRONLY);
+ if (fd < 0)
+ return -1;
+ n = write(fd, event, strlen(event));
+ close(fd);
+ return 0;
+}
+
int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
char *name, unsigned long long *val)
{