Manage: when stopping an array, delete all names from /dev.

This only applies if udev isn't installed or is disabled
by MDADM_NO_UDEV
We try to remove partitions too.
We find names to remove by looking in /var/run/mdadm/map

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2008-11-04 20:50:39 +11:00
parent ac2ecf5543
commit 4ccad7b163
3 changed files with 72 additions and 7 deletions

View File

@ -30,6 +30,7 @@
#include "mdadm.h"
#include "md_u.h"
#include "md_p.h"
#include <ctype.h>
#define REGISTER_DEV _IO (MD_MAJOR, 1)
#define START_MD _IO (MD_MAJOR, 2)
@ -120,6 +121,52 @@ int Manage_ro(char *devname, int fd, int readonly)
#ifndef MDASSEMBLE
static void remove_devices(int devnum, char *path)
{
/* Remove all 'standard' devices for 'devnum', including
* partitions. Also remove names at 'path' - possibly with
* partition suffixes - which link to those names.
*/
char base[40];
char *path2;
char link[1024];
int n;
int part;
char *be;
char *pe;
if (devnum >= 0)
sprintf(base, "/dev/md%d", devnum);
else
sprintf(base, "/dev/md_d%d", -1-devnum);
be = base + strlen(base);
if (path) {
path2 = malloc(strlen(path)+20);
strcpy(path2, path);
pe = path2 + strlen(path2);
} else
path = NULL;
for (part = 0; part < 16; part++) {
if (part) {
sprintf(be, "p%d", part);
if (isdigit(pe[-1]))
sprintf(pe, "p%d", part);
else
sprintf(pe, "%d", part);
}
/* FIXME test if really is md device ?? */
unlink(base);
if (path) {
n = readlink(path2, link, sizeof(link));
if (n && strlen(base) == n &&
strncmp(link, base, n) == 0)
unlink(path2);
}
}
}
int Manage_runstop(char *devname, int fd, int runstop, int quiet)
{
/* Run or stop the array. array must already be configured
@ -163,9 +210,11 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet)
struct map_ent *map = NULL;
struct stat stb;
struct mdinfo *mdi;
int devnum;
/* If this is an mdmon managed array, just write 'inactive'
* to the array state and let mdmon clear up.
*/
devnum = fd2devnum(fd);
mdi = sysfs_read(fd, -1, GET_LEVEL|GET_VERSION);
if (mdi &&
mdi->array.level > 0 &&
@ -216,14 +265,18 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet)
if (mdi)
sysfs_uevent(mdi, "change");
if (devnum != NoMdDev &&
(stat("/dev/.udev", &stb) != 0 ||
check_env("MDADM_NO_UDEV"))) {
struct map_ent *mp = map_by_devnum(&map, devnum);
remove_devices(devnum, mp ? mp->path : NULL);
}
if (quiet <= 0)
fprintf(stderr, Name ": stopped %s\n", devname);
if (fd >= 0 && fstat(fd, &stb) == 0) {
int devnum;
if (major(stb.st_rdev) == MD_MAJOR)
devnum = minor(stb.st_rdev);
else
devnum = -1-(minor(stb.st_rdev)>>6);
if (devnum != NoMdDev) {
map_delete(&map, devnum);
map_write(map);
map_free(map);

View File

@ -195,5 +195,16 @@ struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4])
if (memcmp(uuid, mp->uuid, 16) == 0)
return mp;
return NULL;
}
struct map_ent *map_by_devnum(struct map_ent **map, int devnum)
{
struct map_ent *mp;
if (!*map)
map_read(map);
for (mp = *map ; mp ; mp = mp->next)
if (mp->devnum == devnum)
return mp;
return NULL;
}

View File

@ -318,6 +318,7 @@ struct map_ent {
extern int map_update(struct map_ent **mpp, int devnum, char *metadata,
int uuid[4], char *path);
extern struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4]);
struct map_ent *map_by_devnum(struct map_ent **map, int devnum);
extern void map_read(struct map_ent **melp);
extern int map_write(struct map_ent *mel);
extern void map_delete(struct map_ent **mapp, int devnum);