1
0
Fork 0

Merging upstream version 4.2+20230508.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-14 06:05:31 +01:00
parent 8119c4e7dc
commit 8f10cd7248
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
27 changed files with 335 additions and 232 deletions

View file

@ -328,7 +328,7 @@ static int update_metadata(int mdfd, struct shape *s, struct supertype *st,
* again returns container info.
*/
st->ss->getinfo_super(st, &info_new, NULL);
if (st->ss->external && is_container(s->level) &&
if (st->ss->external && !is_container(s->level) &&
!same_uuid(info_new.uuid, info->uuid, 0)) {
map_update(map, fd2devnm(mdfd),
info_new.text_version,
@ -636,11 +636,6 @@ int Create(struct supertype *st, char *mddev,
break;
case LEVEL_LINEAR:
/* a chunksize of zero 0s perfectly valid (and preferred) since 2.6.16 */
if (get_linux_version() < 2006016 && s->chunk == 0) {
s->chunk = 64;
if (c->verbose > 0)
pr_err("chunk size defaults to 64K\n");
}
break;
case 1:
case LEVEL_FAULTY:
@ -1029,10 +1024,9 @@ int Create(struct supertype *st, char *mddev,
* it could be in conflict with already existing device
* e.g. container, array
*/
if (strncmp(chosen_name, "/dev/md/", 8) == 0 &&
map_by_name(&map, chosen_name+8) != NULL) {
pr_err("Array name %s is in use already.\n",
chosen_name);
if (strncmp(chosen_name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 &&
map_by_name(&map, chosen_name + DEV_MD_DIR_LEN)) {
pr_err("Array name %s is in use already.\n", chosen_name);
close(mdfd);
map_unlock(&map);
udev_unblock();

View file

@ -254,10 +254,9 @@ int Detail(char *dev, struct context *c)
fname_from_uuid(st, info, nbuf, ':');
printf("MD_UUID=%s\n", nbuf + 5);
mp = map_by_uuid(&map, info->uuid);
if (mp && mp->path &&
strncmp(mp->path, "/dev/md/", 8) == 0) {
if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) {
printf("MD_DEVNAME=");
print_escape(mp->path + 8);
print_escape(mp->path + DEV_MD_DIR_LEN);
putchar('\n');
}
@ -273,9 +272,9 @@ int Detail(char *dev, struct context *c)
printf("MD_UUID=%s\n", nbuf+5);
}
if (mp && mp->path &&
strncmp(mp->path, "/dev/md/", 8) == 0) {
strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) {
printf("MD_DEVNAME=");
print_escape(mp->path+8);
print_escape(mp->path + DEV_MD_DIR_LEN);
putchar('\n');
}
map_free(map);

20
Grow.c
View file

@ -1708,14 +1708,6 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
return NULL;
}
if (re->after.data_disks == re->before.data_disks &&
get_linux_version() < 2006032)
return "in-place reshape is not safe before 2.6.32 - sorry.";
if (re->after.data_disks < re->before.data_disks &&
get_linux_version() < 2006030)
return "reshape to fewer devices is not supported before 2.6.30 - sorry.";
re->backup_blocks = compute_backup_blocks(
info->new_chunk, info->array.chunk_size,
re->after.data_disks, re->before.data_disks);
@ -1895,14 +1887,6 @@ int Grow_reshape(char *devname, int fd,
return 1;
}
if (s->raiddisks && s->raiddisks < array.raid_disks &&
array.level > 1 && get_linux_version() < 2006032 &&
!check_env("MDADM_FORCE_FEWER")) {
pr_err("reducing the number of devices is not safe before Linux 2.6.32\n"
" Please use a newer kernel\n");
return 1;
}
if (array.level > 1 && s->size > 1 &&
(unsigned long long) (array.chunk_size / 1024) > s->size) {
pr_err("component size must be larger than chunk size.\n");
@ -3516,7 +3500,7 @@ started:
if (!forked)
if (continue_via_systemd(container ?: sra->sys_name,
GROW_SERVICE)) {
GROW_SERVICE, NULL)) {
free(fdlist);
free(offsets);
sysfs_free(sra);
@ -3714,7 +3698,7 @@ int reshape_container(char *container, char *devname,
ping_monitor(container);
if (!forked && !freeze_reshape)
if (continue_via_systemd(container, GROW_SERVICE))
if (continue_via_systemd(container, GROW_SERVICE, NULL))
return 0;
switch (forked ? 0 : fork()) {

View file

@ -202,8 +202,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
if (!match && rv == 2)
goto out;
if (match && match->devname &&
strcasecmp(match->devname, "<ignore>") == 0) {
if (match && match->devname && is_devname_ignore(match->devname) == true) {
if (c->verbose >= 0)
pr_err("array containing %s is explicitly ignored by mdadm.conf\n",
devname);
@ -460,8 +459,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
info.array.working_disks ++;
}
if (strncmp(chosen_name, "/dev/md/", 8) == 0)
md_devname = chosen_name+8;
if (strncmp(chosen_name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0)
md_devname = chosen_name + DEV_MD_DIR_LEN;
else
md_devname = chosen_name;
if (c->export) {
@ -507,6 +506,9 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
GET_OFFSET | GET_SIZE));
active_disks = count_active(st, sra, mdfd, &avail, &info);
if (!avail)
goto out_unlock;
journal_device_missing = (info.journal_device_required) && (info.journal_clean == 0);
if (info.consistency_policy == CONSISTENCY_POLICY_PPL)
@ -1564,8 +1566,7 @@ static int Incremental_container(struct supertype *st, char *devname,
break;
}
if (match && match->devname &&
strcasecmp(match->devname, "<ignore>") == 0) {
if (match && match->devname && is_devname_ignore(match->devname) == true) {
if (c->verbose > 0)
pr_err("array %s/%s is explicitly ignored by mdadm.conf\n",
match->container, match->member);

View file

@ -461,17 +461,6 @@ done:
goto out;
}
if (get_linux_version() < 2006028) {
/* 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. Drop any
* partitions as well...
*/
if (fd >= 0)
ioctl(fd, BLKRRPART, 0);
if (mdi)
sysfs_uevent(mdi, "change");
}
if (devnm[0] && use_udev()) {
struct map_ent *mp = map_by_devnm(&map, devnm);
remove_devices(devnm, mp ? mp->path : NULL);
@ -621,12 +610,6 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv,
* though.
*/
mdu_disk_info_t disc;
/* re-add doesn't work for version-1 superblocks
* before 2.6.18 :-(
*/
if (array->major_version == 1 &&
get_linux_version() <= 2006018)
goto skip_re_add;
disc.number = mdi.disk.number;
if (md_get_disk_info(fd, &disc) != 0 ||
disc.major != 0 || disc.minor != 0)

View file

@ -36,9 +36,18 @@
#define EVENT_NAME_MAX 32
#define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid"
/**
* struct state - external array or container properties.
* @devname: has length of %DEV_MD_DIR + device name + terminating byte
* @devnm: to sync with mdstat info
* @parent_devnm: or subarray, devnm of parent, for others, ""
* @subarray: for a container it is a link to first subarray, for a subarray it is a link to next
* subarray in the same container
* @parent: for a subarray it is a link to its container
*/
struct state {
char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/
char devnm[MD_NAME_MAX]; /* to sync with mdstat info */
char devname[MD_NAME_MAX + sizeof(DEV_MD_DIR)];
char devnm[MD_NAME_MAX];
unsigned int utime;
int err;
char *spare_group;
@ -49,15 +58,10 @@ struct state {
int devstate[MAX_DISKS];
dev_t devid[MAX_DISKS];
int percent;
char parent_devnm[MD_NAME_MAX]; /* For subarray, devnm of parent.
* For others, ""
*/
char parent_devnm[MD_NAME_MAX];
struct supertype *metadata;
struct state *subarray;/* for a container it is a link to first subarray
* for a subarray it is a link to next subarray
* in the same container */
struct state *parent; /* for a subarray it is a link to its container
*/
struct state *subarray;
struct state *parent;
struct state *next;
};
@ -246,14 +250,14 @@ int Monitor(struct mddev_dev *devlist,
if (mdlist->devname == NULL)
continue;
if (strcasecmp(mdlist->devname, "<ignore>") == 0)
if (is_devname_ignore(mdlist->devname) == true)
continue;
if (!is_mddev(mdlist->devname))
continue;
st = xcalloc(1, sizeof *st);
snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"),
"/dev/md/%s", basename(mdlist->devname));
snprintf(st->devname, MD_NAME_MAX + sizeof(DEV_MD_DIR), DEV_MD_DIR "%s",
basename(mdlist->devname));
st->next = statelist;
st->devnm[0] = 0;
st->percent = RESYNC_UNKNOWN;
@ -274,7 +278,7 @@ int Monitor(struct mddev_dev *devlist,
st = xcalloc(1, sizeof *st);
mdlist = conf_get_ident(dv->devname);
snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", dv->devname);
snprintf(st->devname, MD_NAME_MAX + sizeof(DEV_MD_DIR), "%s", dv->devname);
st->next = statelist;
st->devnm[0] = 0;
st->percent = RESYNC_UNKNOWN;
@ -942,7 +946,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist)
continue;
}
snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", name);
snprintf(st->devname, MD_NAME_MAX + sizeof(DEV_MD_DIR), "%s", name);
if ((fd = open(st->devname, O_RDONLY)) < 0 ||
md_get_array_info(fd, &array) < 0) {
/* no such array */

View file

@ -119,6 +119,18 @@ int match_keyword(char *word)
return -1;
}
/**
* is_devname_ignore() - check if &devname is a special "<ignore>" keyword.
*/
bool is_devname_ignore(char *devname)
{
static const char keyword[] = "<ignore>";
if (strcasecmp(devname, keyword) == 0)
return true;
return false;
}
/**
* ident_init() - Set defaults.
* @ident: ident pointer, not NULL.
@ -373,17 +385,6 @@ void devline(char *line)
struct mddev_ident *mddevlist = NULL;
struct mddev_ident **mddevlp = &mddevlist;
static int is_number(char *w)
{
/* check if there are 1 or more digits and nothing else */
int digits = 0;
while (*w && isdigit(*w)) {
digits++;
w++;
}
return (digits && ! *w);
}
void arrayline(char *line)
{
char *w;
@ -404,13 +405,11 @@ void arrayline(char *line)
* <ignore>
* or anything that doesn't start '/' or '<'
*/
if (strcasecmp(w, "<ignore>") == 0 ||
strncmp(w, "/dev/md/", 8) == 0 ||
if (is_devname_ignore(w) == true ||
strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 ||
(w[0] != '/' && w[0] != '<') ||
(strncmp(w, "/dev/md", 7) == 0 &&
is_number(w + 7)) ||
(strncmp(w, "/dev/md_d", 9) == 0 &&
is_number(w + 9))) {
is_devname_md_numbered(w) == true ||
is_devname_md_d_numbered(w) == true) {
/* This is acceptable */;
if (mis.devname)
pr_err("only give one device per ARRAY line: %s and %s\n",
@ -571,7 +570,7 @@ void homehostline(char *line)
char *w;
for (w = dl_next(line); w != line; w = dl_next(w)) {
if (strcasecmp(w, "<ignore>") == 0)
if (is_devname_ignore(w) == true)
require_homehost = 0;
else if (home_host == NULL) {
if (strcasecmp(w, "<none>") == 0)
@ -1102,13 +1101,13 @@ int devname_matches(char *name, char *match)
* mdNN with NN
* then just strcmp
*/
if (strncmp(name, "/dev/md/", 8) == 0)
name += 8;
if (strncmp(name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0)
name += DEV_MD_DIR_LEN;
else if (strncmp(name, "/dev/", 5) == 0)
name += 5;
if (strncmp(match, "/dev/md/", 8) == 0)
match += 8;
if (strncmp(match, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0)
match += DEV_MD_DIR_LEN;
else if (strncmp(match, "/dev/", 5) == 0)
match += 5;

4
lib.c
View file

@ -313,7 +313,7 @@ char *map_dev_preferred(int major, int minor, int create,
for (p = devlist; p; p = p->next)
if (p->major == major && p->minor == minor) {
if (strncmp(p->name, "/dev/md/",8) == 0 ||
if (strncmp(p->name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 ||
(prefer && strstr(p->name, prefer))) {
if (preferred == NULL ||
strlen(p->name) < strlen(preferred))
@ -570,7 +570,7 @@ void free_line(char *line)
*
* Return: 0 on success, 1 otherwise.
*/
int parse_num(int *dest, char *num)
int parse_num(int *dest, const char *num)
{
char *c = NULL;
long temp;

View file

@ -320,9 +320,9 @@ struct map_ent *map_by_name(struct map_ent **map, char *name)
for (mp = *map ; mp ; mp = mp->next) {
if (!mp->path)
continue;
if (strncmp(mp->path, "/dev/md/", 8) != 0)
if (strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) != 0)
continue;
if (strcmp(mp->path+8, name) != 0)
if (strcmp(mp->path + DEV_MD_DIR_LEN, name) != 0)
continue;
if (!mddev_busy(mp->devnm)) {
mp->bad = 1;
@ -413,7 +413,7 @@ void RebuildMap(void)
devid = devnm2devid(md->devnm);
path = map_dev(major(devid), minor(devid), 0);
if (path == NULL ||
strncmp(path, "/dev/md/", 8) != 0) {
strncmp(path, DEV_MD_DIR, DEV_MD_DIR_LEN) != 0) {
/* We would really like a name that provides
* an MD_DEVNAME for udev.
* The name needs to be unique both in /dev/md/
@ -434,7 +434,7 @@ void RebuildMap(void)
if (match && match->devname && match->devname[0] == '/') {
path = match->devname;
if (path[0] != '/') {
strcpy(namebuf, "/dev/md/");
strcpy(namebuf, DEV_MD_DIR);
strcat(namebuf, path);
path = namebuf;
}
@ -478,10 +478,10 @@ void RebuildMap(void)
while (conflict) {
if (unum >= 0)
sprintf(namebuf, "/dev/md/%s%s%d",
sprintf(namebuf, DEV_MD_DIR "%s%s%d",
name, sep, unum);
else
sprintf(namebuf, "/dev/md/%s",
sprintf(namebuf, DEV_MD_DIR "%s",
name);
unum++;
if (lstat(namebuf, &stb) != 0 &&

View file

@ -3197,6 +3197,11 @@ environment. This can be useful for testing or for disaster
recovery. You should be aware that interoperability may be
compromised by setting this value.
These change can also be suppressed by adding
.B mdadm.imsm.test=1
to the kernel command line. This makes it easy to test IMSM
code in a virtual machine that doesn't have IMSM virtual hardware.
.TP
.B MDADM_GROW_ALLOW_OLD
If an array is stopped while it is performing a reshape and that

View file

@ -107,8 +107,8 @@ int main(int argc, char *argv[])
srandom(time(0) ^ getpid());
if (get_linux_version() < 2006015) {
pr_err("This version of mdadm does not support kernels older than 2.6.15\n");
if (get_linux_version() < 2006032) {
pr_err("This version of mdadm does not support kernels older than 2.6.32\n");
exit(1);
}
@ -154,7 +154,7 @@ int main(int argc, char *argv[])
continue;
case HomeHost:
if (strcasecmp(optarg, "<ignore>") == 0)
if (is_devname_ignore(optarg) == true)
c.require_homehost = 0;
else
c.homehost = optarg;
@ -1749,8 +1749,7 @@ static int scan_assemble(struct supertype *ss,
int r;
if (a->assembled)
continue;
if (a->devname &&
strcasecmp(a->devname, "<ignore>") == 0)
if (a->devname && is_devname_ignore(a->devname) == true)
continue;
r = Assemble(ss, a->devname,

25
mdadm.h
View file

@ -100,6 +100,22 @@ struct dlm_lksb {
#define DEFAULT_BITMAP_DELAY 5
#define DEFAULT_MAX_WRITE_BEHIND 256
/* DEV_NUM_PREF is a subpath to numbered MD devices, e.g. /dev/md1 or directory name.
* DEV_NUM_PREF_LEN is a length with Null byte excluded.
*/
#ifndef DEV_NUM_PREF
#define DEV_NUM_PREF "/dev/md"
#define DEV_NUM_PREF_LEN (sizeof(DEV_NUM_PREF) - 1)
#endif /* DEV_NUM_PREF */
/* DEV_MD_DIR points to named MD devices directory.
* DEV_MD_DIR_LEN is a length with Null byte excluded.
*/
#ifndef DEV_MD_DIR
#define DEV_MD_DIR "/dev/md/"
#define DEV_MD_DIR_LEN (sizeof(DEV_MD_DIR) - 1)
#endif /* DEV_MD_DIR */
/* MAP_DIR should be somewhere that persists across the pivotroot
* from early boot to late boot.
* /run seems to have emerged as the best standard.
@ -1263,6 +1279,8 @@ extern struct superswitch super0, super1;
extern struct superswitch super_imsm, super_ddf;
extern struct superswitch mbr, gpt;
void imsm_set_no_platform(int v);
struct metadata_update {
int len;
char *buf;
@ -1583,7 +1601,7 @@ int default_layout(struct supertype *st, int level, int verbose);
extern int is_near_layout_10(int layout);
extern int parse_layout_10(char *layout);
extern int parse_layout_faulty(char *layout);
extern int parse_num(int *dest, char *num);
extern int parse_num(int *dest, const char *num);
extern int parse_cluster_confirm_arg(char *inp, char **devname, int *slot);
extern int check_ext2(int fd, char *name);
extern int check_reiser(int fd, char *name);
@ -1608,7 +1626,7 @@ extern int same_dev(char *one, char *two);
extern int compare_paths (char* path1,char* path2);
extern void enable_fds(int devices);
extern void manage_fork_fds(int close_all);
extern int continue_via_systemd(char *devnm, char *service_name);
extern int continue_via_systemd(char *devnm, char *service_name, char *prefix);
extern void ident_init(struct mddev_ident *ident);
@ -1632,6 +1650,9 @@ extern void print_escape(char *str);
extern int use_udev(void);
extern unsigned long GCD(unsigned long a, unsigned long b);
extern int conf_name_is_free(char *name);
extern bool is_devname_ignore(char *devname);
extern bool is_devname_md_numbered(const char *devname);
extern bool is_devname_md_d_numbered(const char *devname);
extern int conf_verify_devnames(struct mddev_ident *array_list);
extern int devname_matches(char *name, char *match);
extern struct mddev_ident *conf_match(struct supertype *st,

22
mdmon.c
View file

@ -318,6 +318,12 @@ int main(int argc, char *argv[])
{NULL, 0, NULL, 0}
};
/*
* mdmon should never complain due to lack of a platform,
* that is mdadm's job if at all.
*/
imsm_set_no_platform(1);
while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) {
switch (opt) {
case 'a':
@ -352,7 +358,6 @@ int main(int argc, char *argv[])
}
}
if (in_initrd()) {
/*
* set first char of argv[0] to @. This is used by
@ -362,12 +367,15 @@ int main(int argc, char *argv[])
argv[0][0] = '@';
}
if (all == 0 && container_name == NULL) {
if (argv[optind]) {
container_name = get_md_name(argv[optind]);
if (!container_name)
return 1;
}
if (!all && argv[optind]) {
static const char prefix[] = "initrd/";
container_name = argv[optind];
if (strncmp(container_name, prefix,
sizeof(prefix) - 1) == 0)
container_name += sizeof(prefix)-1;
container_name = get_md_name(container_name);
if (!container_name)
return 1;
}
if (container_name == NULL || argc - optind > 1)

View file

@ -188,12 +188,12 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
parts = autof >> 3;
autof &= 7;
strcpy(chosen, "/dev/md/");
strcpy(chosen, DEV_MD_DIR);
cname = chosen + strlen(chosen);
if (dev) {
if (strncmp(dev, "/dev/md/", 8) == 0) {
strcpy(cname, dev+8);
if (strncmp(dev, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) {
strcpy(cname, dev + DEV_MD_DIR_LEN);
} else if (strncmp(dev, "/dev/", 5) == 0) {
char *e = dev + strlen(dev);
while (e > dev && isdigit(e[-1]))
@ -370,6 +370,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
}
if (block_udev)
udev_block(devnm);
create_named_array(devnm);
}
sprintf(devname, "/dev/%s", devnm);
@ -411,11 +412,11 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
make_parts(devname, parts);
if (strcmp(chosen, devname) != 0) {
if (mkdir("/dev/md",0700) == 0) {
if (chown("/dev/md", ci->uid, ci->gid))
perror("chown /dev/md");
if (chmod("/dev/md", ci->mode| ((ci->mode>>2) & 0111)))
perror("chmod /dev/md");
if (mkdir(DEV_NUM_PREF, 0700) == 0) {
if (chown(DEV_NUM_PREF, ci->uid, ci->gid))
perror("chown " DEV_NUM_PREF);
if (chmod(DEV_NUM_PREF, ci->mode | ((ci->mode >> 2) & 0111)))
perror("chmod " DEV_NUM_PREF);
}
if (dev && strcmp(chosen, dev) == 0)

View file

@ -64,9 +64,10 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver)
if (strcmp(driver, "isci") == 0)
type = SYS_DEV_SAS;
else if (strcmp(driver, "ahci") == 0)
else if (strcmp(driver, "ahci") == 0) {
vmd = find_driver_devices("pci", "vmd");
type = SYS_DEV_SATA;
else if (strcmp(driver, "nvme") == 0) {
} else if (strcmp(driver, "nvme") == 0) {
/* if looking for nvme devs, first look for vmd */
vmd = find_driver_devices("pci", "vmd");
type = SYS_DEV_NVME;
@ -115,6 +116,17 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver)
free(rp);
}
/* change sata type if under a vmd controller */
if (type == SYS_DEV_SATA) {
struct sys_dev *dev;
char *rp = realpath(path, NULL);
for (dev = vmd; dev; dev = dev->next) {
if ((strncmp(dev->path, rp, strlen(dev->path)) == 0))
type = SYS_DEV_SATA_VMD;
}
free(rp);
}
/* if it's not Intel device or mark as VMD connected - skip it. */
if (devpath_to_vendor(path) != 0x8086 || skip == 1)
continue;
@ -166,7 +178,8 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver)
}
closedir(driver_dir);
if (vmd) {
/* nvme vmd needs a list separate from sata vmd */
if (vmd && type == SYS_DEV_NVME) {
if (list)
list->next = vmd;
else
@ -273,6 +286,7 @@ struct sys_dev *find_intel_devices(void)
free_sys_dev(&intel_devices);
isci = find_driver_devices("pci", "isci");
/* Searching for AHCI will return list of SATA and SATA VMD controllers */
ahci = find_driver_devices("pci", "ahci");
/* Searching for NVMe will return list of NVMe and VMD controllers */
nvme = find_driver_devices("pci", "nvme");
@ -638,6 +652,7 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba)
break;
case SYS_DEV_VMD:
case SYS_DEV_SATA_VMD:
for (i = 0; i < ARRAY_SIZE(vmd_efivars); i++) {
if (!read_efi_variable(&orom, sizeof(orom),
vmd_efivars[i], VENDOR_GUID))

View file

@ -196,6 +196,7 @@ enum sys_dev_type {
SYS_DEV_SATA,
SYS_DEV_NVME,
SYS_DEV_VMD,
SYS_DEV_SATA_VMD,
SYS_DEV_MAX
};

12
sha1.c
View file

@ -229,7 +229,17 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
if (len >= 64)
{
#if !_STRING_ARCH_unaligned
# define alignof(type) offsetof (struct { char c; type x; }, x)
/* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023>.
clang versions < 8.0.0 have the same bug. */
# if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \
|| (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \
&& !defined __clang__) \
|| (defined __clang__ && __clang_major__ < 8))
# define alignof(type) offsetof (struct { char c; type x; }, x)
# else
# define alignof(type) _Alignof(type)
# endif
# define UNALIGNED_P(p) (((size_t) p) % alignof (sha1_uint32) != 0)
if (UNALIGNED_P (buffer))
while (len > 64)

View file

@ -1648,7 +1648,7 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose)
fname_from_uuid(st, &info, nbuf1, ':');
_ddf_array_name(namebuf, ddf, i);
printf("ARRAY%s%s container=%s member=%d UUID=%s\n",
namebuf[0] == '\0' ? "" : " /dev/md/", namebuf,
namebuf[0] == '\0' ? "" : " " DEV_MD_DIR, namebuf,
nbuf+5, i, nbuf1+5);
}
}

View file

@ -20,6 +20,7 @@
#define HAVE_STDINT_H 1
#include "mdadm.h"
#include "mdmon.h"
#include "dlink.h"
#include "sha1.h"
#include "platform-intel.h"
#include <values.h>
@ -626,9 +627,48 @@ static const char *_sys_dev_type[] = {
[SYS_DEV_SAS] = "SAS",
[SYS_DEV_SATA] = "SATA",
[SYS_DEV_NVME] = "NVMe",
[SYS_DEV_VMD] = "VMD"
[SYS_DEV_VMD] = "VMD",
[SYS_DEV_SATA_VMD] = "SATA VMD"
};
static int no_platform = -1;
static int check_no_platform(void)
{
static const char search[] = "mdadm.imsm.test=1";
FILE *fp;
if (no_platform >= 0)
return no_platform;
if (check_env("IMSM_NO_PLATFORM")) {
no_platform = 1;
return 1;
}
fp = fopen("/proc/cmdline", "r");
if (fp) {
char *l = conf_line(fp);
char *w = l;
do {
if (strcmp(w, search) == 0)
no_platform = 1;
w = dl_next(w);
} while (w != l);
free_line(l);
fclose(fp);
if (no_platform >= 0)
return no_platform;
}
no_platform = 0;
return 0;
}
void imsm_set_no_platform(int v)
{
no_platform = v;
}
const char *get_sys_dev_type(enum sys_dev_type type)
{
if (type >= SYS_DEV_MAX)
@ -2270,7 +2310,7 @@ static void brief_examine_subarrays_imsm(struct supertype *st, int verbose)
super->current_vol = i;
getinfo_super_imsm(st, &info, NULL);
fname_from_uuid(st, &info, nbuf1, ':');
printf("ARRAY /dev/md/%.16s container=%s member=%d UUID=%s\n",
printf("ARRAY " DEV_MD_DIR "%.16s container=%s member=%d UUID=%s\n",
dev->volume, nbuf + 5, i, nbuf1 + 5);
}
}
@ -2559,6 +2599,8 @@ static void print_found_intel_controllers(struct sys_dev *elem)
if (elem->type == SYS_DEV_VMD)
fprintf(stderr, "VMD domain");
else if (elem->type == SYS_DEV_SATA_VMD)
fprintf(stderr, "SATA VMD domain");
else
fprintf(stderr, "RAID controller");
@ -2699,7 +2741,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle
int result=1;
if (enumerate_only) {
if (check_env("IMSM_NO_PLATFORM"))
if (check_no_platform())
return 0;
list = find_intel_devices();
if (!list)
@ -2729,8 +2771,9 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle
if (!find_imsm_capability(hba)) {
char buf[PATH_MAX];
pr_err("imsm capabilities not found for controller: %s (type %s)\n",
hba->type == SYS_DEV_VMD ? vmd_domain_to_controller(hba, buf) : hba->path,
get_sys_dev_type(hba->type));
hba->type == SYS_DEV_VMD || hba->type == SYS_DEV_SATA_VMD ?
vmd_domain_to_controller(hba, buf) :
hba->path, get_sys_dev_type(hba->type));
continue;
}
result = 0;
@ -2783,11 +2826,12 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle
printf(" I/O Controller : %s (%s)\n",
hba->path, get_sys_dev_type(hba->type));
if (hba->type == SYS_DEV_SATA) {
if (hba->type == SYS_DEV_SATA || hba->type == SYS_DEV_SATA_VMD) {
host_base = ahci_get_port_count(hba->path, &port_count);
if (ahci_enumerate_ports(hba->path, port_count, host_base, verbose)) {
if (verbose > 0)
pr_err("failed to enumerate ports on SATA controller at %s.\n", hba->pci_id);
pr_err("failed to enumerate ports on %s controller at %s.\n",
get_sys_dev_type(hba->type), hba->pci_id);
result |= 2;
}
}
@ -2817,7 +2861,8 @@ static int export_detail_platform_imsm(int verbose, char *controller_path)
if (!find_imsm_capability(hba) && verbose > 0) {
char buf[PATH_MAX];
pr_err("IMSM_DETAIL_PLATFORM_ERROR=NO_IMSM_CAPABLE_DEVICE_UNDER_%s\n",
hba->type == SYS_DEV_VMD ? vmd_domain_to_controller(hba, buf) : hba->path);
hba->type == SYS_DEV_VMD || hba->type == SYS_DEV_SATA_VMD ?
vmd_domain_to_controller(hba, buf) : hba->path);
}
else
result = 0;
@ -2826,7 +2871,7 @@ static int export_detail_platform_imsm(int verbose, char *controller_path)
const struct orom_entry *entry;
for (entry = orom_entries; entry; entry = entry->next) {
if (entry->type == SYS_DEV_VMD) {
if (entry->type == SYS_DEV_VMD || entry->type == SYS_DEV_SATA_VMD) {
for (hba = list; hba; hba = hba->next)
print_imsm_capability_export(&entry->orom);
continue;
@ -4722,7 +4767,7 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, char *de
devname);
return 1;
}
if (!is_fd_valid(fd) || check_env("IMSM_NO_PLATFORM")) {
if (!is_fd_valid(fd) || check_no_platform()) {
super->orom = NULL;
super->hba = NULL;
return 0;
@ -4743,10 +4788,12 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, char *de
" but the container is assigned to Intel(R) %s %s (",
devname,
get_sys_dev_type(hba_name->type),
hba_name->type == SYS_DEV_VMD ? "domain" : "RAID controller",
hba_name->type == SYS_DEV_VMD || hba_name->type == SYS_DEV_SATA_VMD ?
"domain" : "RAID controller",
hba_name->pci_id ? : "Err!",
get_sys_dev_type(super->hba->type),
hba->type == SYS_DEV_VMD ? "domain" : "RAID controller");
hba->type == SYS_DEV_VMD || hba_name->type == SYS_DEV_SATA_VMD ?
"domain" : "RAID controller");
while (hba) {
fprintf(stderr, "%s", hba->pci_id ? : "Err!");
@ -10697,7 +10744,7 @@ static int imsm_get_allowed_degradation(int level, int raid_disks,
******************************************************************************/
int validate_container_imsm(struct mdinfo *info)
{
if (check_env("IMSM_NO_PLATFORM"))
if (check_no_platform())
return 0;
struct sys_dev *idev;
@ -11235,7 +11282,7 @@ static const char *imsm_get_disk_controller_domain(const char *path)
hba = find_disk_attached_hba(-1, path);
if (hba && hba->type == SYS_DEV_SAS)
drv = "isci";
else if (hba && hba->type == SYS_DEV_SATA)
else if (hba && (hba->type == SYS_DEV_SATA || hba->type == SYS_DEV_SATA_VMD))
drv = "ahci";
else if (hba && hba->type == SYS_DEV_VMD)
drv = "vmd";

126
super1.c
View file

@ -192,7 +192,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
unsigned int disk_csum, csum;
unsigned long long newcsum;
int size = sizeof(*sb) + __le32_to_cpu(sb->max_dev)*2;
unsigned int *isuper = (unsigned int*)sb;
unsigned int *isuper = (unsigned int *)sb;
/* make sure I can count... */
if (offsetof(struct mdp_superblock_1,data_offset) != 128 ||
@ -204,7 +204,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
disk_csum = sb->sb_csum;
sb->sb_csum = 0;
newcsum = 0;
for (; size>=4; size -= 4 ) {
for (; size >= 4; size -= 4) {
newcsum += __le32_to_cpu(*isuper);
isuper++;
}
@ -319,7 +319,7 @@ static inline unsigned int choose_ppl_space(int chunk)
static void examine_super1(struct supertype *st, char *homehost)
{
struct mdp_superblock_1 *sb = st->sb;
bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE);
bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE);
time_t atime;
unsigned int d;
int role;
@ -343,8 +343,9 @@ static void examine_super1(struct supertype *st, char *homehost)
printf(".0\n");
printf(" Feature Map : 0x%x\n", __le32_to_cpu(sb->feature_map));
printf(" Array UUID : ");
for (i=0; i<16; i++) {
if ((i&3)==0 && i != 0) printf(":");
for (i = 0; i < 16; i++) {
if ((i & 3) == 0 && i != 0)
printf(":");
printf("%02x", sb->set_uuid[i]);
}
printf("\n");
@ -416,11 +417,11 @@ static void examine_super1(struct supertype *st, char *homehost)
UINT64_MAX - info.space_after);
}
printf(" State : %s%s\n",
(__le64_to_cpu(sb->resync_offset)+1) ? "active":"clean",
(__le64_to_cpu(sb->resync_offset) + 1) ? "active":"clean",
(info.space_after > INT64_MAX) ? " TRUNCATED DEVICE" : "");
printf(" Device UUID : ");
for (i=0; i<16; i++) {
if ((i&3)==0 && i != 0)
for (i = 0; i < 16; i++) {
if ((i & 3)==0 && i != 0)
printf(":");
printf("%02x", sb->device_uuid[i]);
}
@ -546,7 +547,7 @@ static void examine_super1(struct supertype *st, char *homehost)
#if 0
/* This turns out to just be confusing */
printf(" Array Slot : %d (", __le32_to_cpu(sb->dev_number));
for (i = __le32_to_cpu(sb->max_dev); i> 0 ; i--)
for (i = __le32_to_cpu(sb->max_dev); i > 0 ; i--)
if (__le16_to_cpu(sb->dev_roles[i-1]) != MD_DISK_ROLE_SPARE)
break;
for (d = 0; d < i; d++) {
@ -597,7 +598,7 @@ static void examine_super1(struct supertype *st, char *homehost)
#if 0
/* This is confusing too */
faulty = 0;
for (i = 0; i< __le32_to_cpu(sb->max_dev); i++) {
for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) {
int role = __le16_to_cpu(sb->dev_roles[i]);
if (role == MD_DISK_ROLE_FAULTY)
faulty++;
@ -616,10 +617,12 @@ static void examine_super1(struct supertype *st, char *homehost)
if (inconsistent) {
printf("WARNING Array state is inconsistent - each number should appear only once\n");
for (d = 0; d < __le32_to_cpu(sb->max_dev); d++)
if (__le16_to_cpu(sb->dev_roles[d]) >= MD_DISK_ROLE_FAULTY)
if (__le16_to_cpu(sb->dev_roles[d]) >=
MD_DISK_ROLE_FAULTY)
printf(" %d:-", d);
else
printf(" %d:%d", d, __le16_to_cpu(sb->dev_roles[d]));
printf(" %d:%d", d,
__le16_to_cpu(sb->dev_roles[d]));
printf("\n");
}
}
@ -642,8 +645,7 @@ static void brief_examine_super1(struct supertype *st, int verbose)
printf("ARRAY ");
if (nm) {
printf("/dev/md/");
print_escape(nm);
printf(DEV_MD_DIR "%s", nm);
putchar(' ');
}
if (verbose && c)
@ -659,7 +661,7 @@ static void brief_examine_super1(struct supertype *st, int verbose)
printf("num-devices=%d ", __le32_to_cpu(sb->raid_disks));
printf("UUID=");
for (i = 0; i < 16; i++) {
if ((i&3)==0 && i != 0)
if ((i & 3)==0 && i != 0)
printf(":");
printf("%02x", sb->set_uuid[i]);
}
@ -713,7 +715,7 @@ static void export_examine_super1(struct supertype *st)
}
printf("MD_UUID=");
for (i = 0; i < 16; i++) {
if ((i&3) == 0 && i != 0)
if ((i & 3) == 0 && i != 0)
printf(":");
printf("%02x", sb->set_uuid[i]);
}
@ -722,7 +724,7 @@ static void export_examine_super1(struct supertype *st)
__le64_to_cpu(sb->utime) & 0xFFFFFFFFFFULL);
printf("MD_DEV_UUID=");
for (i = 0; i < 16; i++) {
if ((i&3) == 0 && i != 0)
if ((i & 3) == 0 && i != 0)
printf(":");
printf("%02x", sb->device_uuid[i]);
}
@ -812,7 +814,7 @@ static int copy_metadata1(struct supertype *st, int from, int to)
/* have the header, can calculate
* correct bitmap bytes */
bitmap_super_t *bms;
bms = (void*)buf;
bms = (void *)buf;
bytes = calc_bitmap_size(bms, 512);
if (n > bytes)
n = bytes;
@ -867,7 +869,7 @@ err:
static void detail_super1(struct supertype *st, char *homehost, char *subarray)
{
struct mdp_superblock_1 *sb = st->sb;
bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE);
bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE);
int i;
int l = homehost ? strlen(homehost) : 0;
@ -880,7 +882,7 @@ static void detail_super1(struct supertype *st, char *homehost, char *subarray)
printf("\n Cluster Name : %-64s", bms->cluster_name);
printf("\n UUID : ");
for (i = 0; i < 16; i++) {
if ((i&3) == 0 && i != 0)
if ((i & 3) == 0 && i != 0)
printf(":");
printf("%02x", sb->set_uuid[i]);
}
@ -939,7 +941,7 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname)
}
size = __le16_to_cpu(sb->bblog_size)* 512;
if (posix_memalign((void**)&bbl, 4096, size) != 0) {
if (posix_memalign((void **)&bbl, 4096, size) != 0) {
pr_err("could not allocate badblocks list\n");
return 0;
}
@ -987,7 +989,7 @@ static int match_home1(struct supertype *st, char *homehost)
static void uuid_from_super1(struct supertype *st, int uuid[4])
{
struct mdp_superblock_1 *super = st->sb;
char *cuuid = (char*)uuid;
char *cuuid = (char *)uuid;
int i;
for (i = 0; i < 16; i++)
cuuid[i] = super->set_uuid[i];
@ -996,9 +998,9 @@ static void uuid_from_super1(struct supertype *st, int uuid[4])
static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
{
struct mdp_superblock_1 *sb = st->sb;
struct bitmap_super_s *bsb = (void*)(((char*)sb)+MAX_SB_SIZE);
struct bitmap_super_s *bsb = (void *)(((char *)sb) + MAX_SB_SIZE);
struct misc_dev_info *misc =
(void*)(((char*)sb)+MAX_SB_SIZE+BM_SUPER_SIZE);
(void *)(((char *)sb) + MAX_SB_SIZE+BM_SUPER_SIZE);
int working = 0;
unsigned int i;
unsigned int role;
@ -1166,7 +1168,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
info->recovery_blocked = info->reshape_active;
if (map)
for (i=0; i<map_disks; i++)
for (i = 0; i < map_disks; i++)
map[i] = 0;
for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) {
role = __le16_to_cpu(sb->dev_roles[i]);
@ -1217,7 +1219,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
*/
int rv = 0;
struct mdp_superblock_1 *sb = st->sb;
bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE);
bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE);
if (update == UOPT_HOMEHOST && homehost) {
/*
@ -1228,9 +1230,10 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
update = UOPT_NAME;
c = strchr(sb->set_name, ':');
if (c)
snprintf(info->name, sizeof(info->name), "%s", c+1);
snprintf(info->name, sizeof(info->name), "%s", c + 1);
else
snprintf(info->name, sizeof(info->name), "%s", sb->set_name);
snprintf(info->name, sizeof(info->name), "%s",
sb->set_name);
}
switch (update) {
@ -1331,7 +1334,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
sb->dev_number = __cpu_to_le32(i);
if (i == max)
sb->max_dev = __cpu_to_le32(max+1);
sb->max_dev = __cpu_to_le32(max + 1);
if (i > max)
return -2;
@ -1350,8 +1353,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
sb->data_size = __cpu_to_le64(
ds - __le64_to_cpu(sb->data_offset));
} else {
ds -= 8*2;
ds &= ~(unsigned long long)(4*2-1);
ds -= 8 * 2;
ds &= ~(unsigned long long)(4 * 2 - 1);
sb->super_offset = __cpu_to_le64(ds);
sb->data_size = __cpu_to_le64(
ds - __le64_to_cpu(sb->data_offset));
@ -1367,7 +1370,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
if (i > max)
return -2;
if (i == max)
sb->max_dev = __cpu_to_le32(max+1);
sb->max_dev = __cpu_to_le32(max + 1);
sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
sb->dev_roles[info->disk.number] =
__cpu_to_le16(info->disk.raid_disk);
@ -1645,7 +1648,7 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info,
char defname[10];
int sbsize;
if (posix_memalign((void**)&sb, 4096, SUPER1_SIZE) != 0) {
if (posix_memalign((void **)&sb, 4096, SUPER1_SIZE) != 0) {
pr_err("could not allocate superblock\n");
return 0;
}
@ -1679,8 +1682,8 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info,
name = defname;
}
if (homehost &&
strchr(name, ':')== NULL &&
strlen(homehost)+1+strlen(name) < 32) {
strchr(name, ':') == NULL &&
strlen(homehost) + 1 + strlen(name) < 32) {
strcpy(sb->set_name, homehost);
strcat(sb->set_name, ":");
strcat(sb->set_name, name);
@ -1759,7 +1762,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
if (dk->number >= (int)__le32_to_cpu(sb->max_dev) &&
__le32_to_cpu(sb->max_dev) < MAX_DEVS)
sb->max_dev = __cpu_to_le32(dk->number+1);
sb->max_dev = __cpu_to_le32(dk->number + 1);
sb->dev_number = __cpu_to_le32(dk->number);
sb->devflags = 0; /* don't copy another disks flags */
@ -1840,8 +1843,8 @@ static int store_super1(struct supertype *st, int fd)
return 4;
if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
struct bitmap_super_s *bm = (struct bitmap_super_s*)
(((char*)sb)+MAX_SB_SIZE);
struct bitmap_super_s *bm;
bm = (struct bitmap_super_s *)(((char *)sb) + MAX_SB_SIZE);
if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) {
locate_bitmap1(st, fd, 0);
if (awrite(&afd, bm, sizeof(*bm)) != sizeof(*bm))
@ -1928,7 +1931,7 @@ static int write_empty_r5l_meta_block(struct supertype *st, int fd)
init_afd(&afd, fd);
if (posix_memalign((void**)&mb, 4096, META_BLOCK_SIZE) != 0) {
if (posix_memalign((void **)&mb, 4096, META_BLOCK_SIZE) != 0) {
pr_err("Could not allocate memory for the meta block.\n");
return 1;
}
@ -2029,11 +2032,6 @@ static int write_init_super1(struct supertype *st)
/* same array, so preserve events and
* dev_number */
sb->events = refsb->events;
/* bugs in 2.6.17 and earlier mean the
* dev_number chosen in Manage must be preserved
*/
if (get_linux_version() >= 2006018)
sb->dev_number = refsb->dev_number;
}
free_super1(refst);
}
@ -2197,7 +2195,7 @@ static int compare_super1(struct supertype *st, struct supertype *tst,
return 1;
if (!first) {
if (posix_memalign((void**)&first, 4096, SUPER1_SIZE) != 0) {
if (posix_memalign((void **)&first, 4096, SUPER1_SIZE) != 0) {
pr_err("could not allocate superblock\n");
return 1;
}
@ -2310,7 +2308,7 @@ static int load_super1(struct supertype *st, int fd, char *devname)
return 1;
}
if (posix_memalign((void**)&super, 4096, SUPER1_SIZE) != 0) {
if (posix_memalign((void **)&super, 4096, SUPER1_SIZE) != 0) {
pr_err("could not allocate superblock\n");
return 1;
}
@ -2349,19 +2347,19 @@ static int load_super1(struct supertype *st, int fd, char *devname)
return 2;
}
bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE);
bsb = (struct bitmap_super_s *)(((char *)super) + MAX_SB_SIZE);
misc = (struct misc_dev_info*)
(((char*)super)+MAX_SB_SIZE+BM_SUPER_SIZE);
(((char *)super) + MAX_SB_SIZE+BM_SUPER_SIZE);
misc->device_size = dsize;
if (st->data_offset == INVALID_SECTORS)
st->data_offset = __le64_to_cpu(super->data_offset);
if (st->minor_version >= 1 &&
st->ignore_hw_compat == 0 &&
(dsize < (__le64_to_cpu(super->data_offset) +
__le64_to_cpu(super->size))
||
((role_from_sb(super) != MD_DISK_ROLE_JOURNAL &&
dsize < (__le64_to_cpu(super->data_offset) +
__le64_to_cpu(super->size))) ||
dsize < (__le64_to_cpu(super->data_offset) +
__le64_to_cpu(super->data_size)))) {
if (devname)
@ -2390,8 +2388,8 @@ static int load_super1(struct supertype *st, int fd, char *devname)
return 0;
no_bitmap:
super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map)
& ~MD_FEATURE_BITMAP_OFFSET);
super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map) &
~MD_FEATURE_BITMAP_OFFSET);
return 0;
}
@ -2449,7 +2447,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize,
if (__le32_to_cpu(super->feature_map) & MD_FEATURE_BITMAP_OFFSET) {
/* hot-add. allow for actual size of bitmap */
struct bitmap_super_s *bsb;
bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE);
bsb = (struct bitmap_super_s *)(((char *)super) + MAX_SB_SIZE);
bmspace = calc_bitmap_size(bsb, 4096) >> 9;
} else if (md_feature_any_ppl_on(super->feature_map)) {
bmspace = __le16_to_cpu(super->ppl.size);
@ -2518,7 +2516,7 @@ add_internal_bitmap1(struct supertype *st,
int creating = 0;
int len;
struct mdp_superblock_1 *sb = st->sb;
bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE);
bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE);
int uuid[4];
if (__le64_to_cpu(sb->data_size) == 0)
@ -2606,10 +2604,10 @@ add_internal_bitmap1(struct supertype *st,
max_bits = (room * 512 - sizeof(bitmap_super_t)) * 8;
min_chunk = 4096; /* sub-page chunks don't work yet.. */
bits = (size*512)/min_chunk +1;
bits = (size * 512) / min_chunk + 1;
while (bits > max_bits) {
min_chunk *= 2;
bits = (bits+1)/2;
bits = (bits + 1) / 2;
}
if (chunk == UnSet) {
/* For practical purpose, 64Meg is a good
@ -2627,8 +2625,8 @@ add_internal_bitmap1(struct supertype *st,
/* start bitmap on a 4K boundary with enough space for
* the bitmap
*/
bits = (size*512) / chunk + 1;
room = ((bits+7)/8 + sizeof(bitmap_super_t) +4095)/4096;
bits = (size * 512) / chunk + 1;
room = ((bits + 7) / 8 + sizeof(bitmap_super_t) + 4095) / 4096;
room *= 8; /* convert 4K blocks to sectors */
offset = -room - bbl_size;
}
@ -2682,7 +2680,7 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num)
offset = __le64_to_cpu(sb->super_offset) + (int32_t)__le32_to_cpu(sb->bitmap_offset);
if (node_num) {
bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE);
bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE);
bm_sectors_per_node = calc_bitmap_size(bms, 4096) >> 9;
offset += bm_sectors_per_node * node_num;
}
@ -2695,7 +2693,7 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num)
static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update)
{
struct mdp_superblock_1 *sb = st->sb;
bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE);
bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE);
int rv = 0;
void *buf;
int towrite, n, len;
@ -2969,16 +2967,16 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0
copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid);
sprintf(sb->set_name, "%d", sb0->md_minor);
sb->ctime = __cpu_to_le32(info->array.ctime+1);
sb->ctime = __cpu_to_le32(info->array.ctime + 1);
sb->level = __cpu_to_le32(info->array.level);
sb->layout = __cpu_to_le32(info->array.layout);
sb->size = __cpu_to_le64(info->component_size);
sb->chunksize = __cpu_to_le32(info->array.chunk_size/512);
sb->chunksize = __cpu_to_le32(info->array.chunk_size / 512);
sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
if (info->array.level > 0)
sb->data_size = sb->size;
else
sb->data_size = st->ss->avail_size(st, st->devsize/512, 0);
sb->data_size = st->ss->avail_size(st, st->devsize / 512, 0);
sb->resync_offset = MaxSector;
sb->max_dev = __cpu_to_le32(MD_SB_DISKS);
sb->dev_number = __cpu_to_le32(info->disk.number);

View file

@ -1114,7 +1114,7 @@ void sysfsline(char *line)
if (strncasecmp(w, "name=", 5) == 0) {
char *devname = w + 5;
if (strncmp(devname, "/dev/md/", 8) == 0) {
if (strncmp(devname, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) {
if (sr->devname)
pr_err("Only give one device per SYSFS line: %s\n",
devname);

View file

@ -15,4 +15,3 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I
StandardInput=null
StandardOutput=null
StandardError=null
KillMode=none

View file

@ -13,6 +13,4 @@ Documentation=man:mdadm(8)
[Service]
Type=oneshot
Environment="MDADM_CHECK_DURATION=6 hours"
EnvironmentFile=-/run/sysconfig/mdadm
ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION}

View file

@ -13,6 +13,4 @@ Documentation=man:mdadm(8)
[Service]
Type=oneshot
Environment="MDADM_CHECK_DURATION=6 hours"
EnvironmentFile=-/run/sysconfig/mdadm
ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION}

View file

@ -6,24 +6,25 @@
# (at your option) any later version.
[Unit]
Description=MD Metadata Monitor on /dev/%I
Description=MD Metadata Monitor on %I
DefaultDependencies=no
Before=initrd-switch-root.target
Documentation=man:mdmon(8)
# Allow mdmon to keep running after switchroot, until a new
# instance is started.
IgnoreOnIsolate=true
[Service]
# mdmon should never complain due to lack of a platform,
# that is mdadm's job if at all.
Environment=IMSM_NO_PLATFORM=1
# The mdmon starting in the initramfs (with dracut at least)
# cannot see sysfs after root is mounted, so we will have to
# 'takeover'. As the '--offroot --takeover' don't hurt when
# not necessary, are are useful with root-on-md in dracut,
# have them always present.
ExecStart=BINDIR/mdmon --offroot --takeover %I
Type=forking
ExecStart=BINDIR/mdmon --foreground --offroot --takeover %I
# Don't set the PIDFile. It isn't necessary (systemd can work
# it out) and systemd will remove it when transitioning from
# initramfs to rootfs.
#PIDFile=/run/mdadm/%I.pid
KillMode=none
# The default slice is system-mdmon.slice which Conflicts
# with shutdown, causing mdmon to exit early. So use system.slice.
Slice=system.slice

View file

@ -38,7 +38,8 @@ ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service"
# Tell systemd to run mdmon for our container, if we need it.
ENV{MD_LEVEL}=="raid[1-9]*", ENV{MD_CONTAINER}=="?*", PROGRAM="/usr/bin/readlink $env{MD_CONTAINER}", ENV{MD_MON_THIS}="%c"
ENV{MD_MON_THIS}=="?*", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service"
ENV{MD_MON_THIS}=="?*", TEST=="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@initrd-%c.service"
ENV{MD_MON_THIS}=="?*", TEST!="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service"
ENV{RESHAPE_ACTIVE}=="yes", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdadm-grow-continue@%c.service"
LABEL="md_end"

61
util.c
View file

@ -973,6 +973,50 @@ dev_t devnm2devid(char *devnm)
return 0;
}
/**
* is_devname_numbered() - helper for numbered devname verification.
* @devname: path or name to check.
* @pref: expected devname prefix.
* @pref_len: prefix len.
*/
static bool is_devname_numbered(const char *devname, const char *pref, const int pref_len)
{
int val;
assert(devname && pref);
if (strncmp(devname, pref, pref_len) != 0)
return false;
if (parse_num(&val, devname + pref_len) != 0)
return false;
if (val > 127)
return false;
return true;
}
/**
* is_devname_md_numbered() - check if &devname is numbered MD device (md).
* @devname: path or name to check.
*/
bool is_devname_md_numbered(const char *devname)
{
return is_devname_numbered(devname, DEV_NUM_PREF, DEV_NUM_PREF_LEN);
}
/**
* is_devname_md_d_numbered() - check if &devname is secondary numbered MD device (md_d).
* @devname: path or name to check.
*/
bool is_devname_md_d_numbered(const char *devname)
{
static const char d_dev[] = DEV_NUM_PREF "_d";
return is_devname_numbered(devname, d_dev, sizeof(d_dev) - 1);
}
/**
* get_md_name() - Get main dev node of the md device.
* @devnm: Md device name or path.
@ -1916,6 +1960,7 @@ int start_mdmon(char *devnm)
int len;
pid_t pid;
int status;
char *prefix = in_initrd() ? "initrd-" : "";
char pathbuf[1024];
char *paths[4] = {
pathbuf,
@ -1926,7 +1971,7 @@ int start_mdmon(char *devnm)
if (check_env("MDADM_NO_MDMON"))
return 0;
if (continue_via_systemd(devnm, MDMON_SERVICE))
if (continue_via_systemd(devnm, MDMON_SERVICE, prefix))
return 0;
/* That failed, try running mdmon directly */
@ -2197,7 +2242,7 @@ void manage_fork_fds(int close_all)
* 1- if systemd service has been started
* 0- otherwise
*/
int continue_via_systemd(char *devnm, char *service_name)
int continue_via_systemd(char *devnm, char *service_name, char *prefix)
{
int pid, status;
char pathbuf[1024];
@ -2209,7 +2254,7 @@ int continue_via_systemd(char *devnm, char *service_name)
case 0:
manage_fork_fds(1);
snprintf(pathbuf, sizeof(pathbuf),
"%s@%s.service", service_name, devnm);
"%s@%s%s.service", service_name, prefix ?: "", devnm);
status = execl("/usr/bin/systemctl", "systemctl", "restart",
pathbuf, NULL);
status = execl("/bin/systemctl", "systemctl", "restart",
@ -2227,15 +2272,7 @@ int continue_via_systemd(char *devnm, char *service_name)
int in_initrd(void)
{
/* This is based on similar function in systemd. */
struct statfs s;
/* statfs.f_type is signed long on s390x and MIPS, causing all
sorts of sign extension problems with RAMFS_MAGIC being
defined as 0x858458f6 */
return statfs("/", &s) >= 0 &&
((unsigned long)s.f_type == TMPFS_MAGIC ||
((unsigned long)s.f_type & 0xFFFFFFFFUL) ==
((unsigned long)RAMFS_MAGIC & 0xFFFFFFFFUL));
return access("/etc/initrd-release", F_OK) >= 0;
}
void reopen_mddev(int mdfd)