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>
This commit is contained in:
NeilBrown 2008-11-04 20:50:39 +11:00
parent 757a5d74ff
commit 9759037678
7 changed files with 42 additions and 6 deletions

View File

@ -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;
}

View File

@ -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",

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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)

16
sysfs.c
View File

@ -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)
{