summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2023-05-12 12:47:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2023-05-12 12:47:09 +0000
commitb959dcfcd0319d4311e67fa40ebb407605efc9d9 (patch)
treeac91bd6261967ff19b62a1859a4f544112ec4522
parentReleasing debian version 4.2+20230313-1. (diff)
downloadmdadm-b959dcfcd0319d4311e67fa40ebb407605efc9d9.tar.xz
mdadm-b959dcfcd0319d4311e67fa40ebb407605efc9d9.zip
Merging upstream version 4.2+20230508.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--Create.c14
-rw-r--r--Detail.c9
-rw-r--r--Grow.c20
-rw-r--r--Incremental.c13
-rw-r--r--Manage.c17
-rw-r--r--Monitor.c34
-rw-r--r--config.c43
-rw-r--r--lib.c4
-rw-r--r--mapfile.c12
-rw-r--r--mdadm.8.in5
-rw-r--r--mdadm.c9
-rw-r--r--mdadm.h25
-rw-r--r--mdmon.c22
-rw-r--r--mdopen.c17
-rw-r--r--platform-intel.c21
-rw-r--r--platform-intel.h1
-rw-r--r--sha1.c12
-rw-r--r--super-ddf.c2
-rw-r--r--super-intel.c75
-rw-r--r--super1.c126
-rw-r--r--sysfs.c2
-rw-r--r--systemd/mdadm-grow-continue@.service1
-rw-r--r--systemd/mdcheck_continue.service2
-rw-r--r--systemd/mdcheck_start.service2
-rw-r--r--systemd/mdmon@.service15
-rw-r--r--udev-md-raid-arrays.rules3
-rw-r--r--util.c61
27 files changed, 335 insertions, 232 deletions
diff --git a/Create.c b/Create.c
index bbe9e13..ea6a474 100644
--- a/Create.c
+++ b/Create.c
@@ -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();
diff --git a/Detail.c b/Detail.c
index 4ef2646..206d88e 100644
--- a/Detail.c
+++ b/Detail.c
@@ -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);
diff --git a/Grow.c b/Grow.c
index bb5fe45..8fa9787 100644
--- a/Grow.c
+++ b/Grow.c
@@ -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()) {
diff --git a/Incremental.c b/Incremental.c
index 09b94b9..f13ce02 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -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);
diff --git a/Manage.c b/Manage.c
index fde6aba..f54de7c 100644
--- a/Manage.c
+++ b/Manage.c
@@ -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)
diff --git a/Monitor.c b/Monitor.c
index 4491818..6617596 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -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 */
diff --git a/config.c b/config.c
index eeedd0c..450880e 100644
--- a/config.c
+++ b/config.c
@@ -120,6 +120,18 @@ int match_keyword(char *word)
}
/**
+ * 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;
diff --git a/lib.c b/lib.c
index e395b28..fe5c8d2 100644
--- a/lib.c
+++ b/lib.c
@@ -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;
diff --git a/mapfile.c b/mapfile.c
index ac35176..34fea17 100644
--- a/mapfile.c
+++ b/mapfile.c
@@ -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 &&
diff --git a/mdadm.8.in b/mdadm.8.in
index 6f0f6c1..b715950 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -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
diff --git a/mdadm.c b/mdadm.c
index 4685ad6..076b45e 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -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,
diff --git a/mdadm.h b/mdadm.h
index b9127f9..83f2cf7 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -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,
diff --git a/mdmon.c b/mdmon.c
index 60ba318..cef5bbc 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -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)
diff --git a/mdopen.c b/mdopen.c
index d18c931..d3022a5 100644
--- a/mdopen.c
+++ b/mdopen.c
@@ -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)
diff --git a/platform-intel.c b/platform-intel.c
index 757f0b1..914164c 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -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))
diff --git a/platform-intel.h b/platform-intel.h
index 6238d23..2c0f4e3 100644
--- a/platform-intel.h
+++ b/platform-intel.h
@@ -196,6 +196,7 @@ enum sys_dev_type {
SYS_DEV_SATA,
SYS_DEV_NVME,
SYS_DEV_VMD,
+ SYS_DEV_SATA_VMD,
SYS_DEV_MAX
};
diff --git a/sha1.c b/sha1.c
index 89b32f4..1e4ad5d 100644
--- a/sha1.c
+++ b/sha1.c
@@ -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)
diff --git a/super-ddf.c b/super-ddf.c
index b86c6ac..7213284 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -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);
}
}
diff --git a/super-intel.c b/super-intel.c
index e155a8a..ae0f4a8 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -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";
diff --git a/super1.c b/super1.c
index f702032..856b020 100644
--- a/super1.c
+++ b/super1.c
@@ -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);
diff --git a/sysfs.c b/sysfs.c
index ca1d888..94d02f5 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -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);
diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service
index 9ccadca..64b8254 100644
--- a/systemd/mdadm-grow-continue@.service
+++ b/systemd/mdadm-grow-continue@.service
@@ -15,4 +15,3 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I
StandardInput=null
StandardOutput=null
StandardError=null
-KillMode=none
diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service
index f532490..70892a1 100644
--- a/systemd/mdcheck_continue.service
+++ b/systemd/mdcheck_continue.service
@@ -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}
diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service
index 703a658..fc4fc43 100644
--- a/systemd/mdcheck_start.service
+++ b/systemd/mdcheck_start.service
@@ -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}
diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service
index cb6482d..020cc7e 100644
--- a/systemd/mdmon@.service
+++ b/systemd/mdmon@.service
@@ -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
diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules
index 2967ace..4e64b24 100644
--- a/udev-md-raid-arrays.rules
+++ b/udev-md-raid-arrays.rules
@@ -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"
diff --git a/util.c b/util.c
index 9f1e1f7..fa378eb 100644
--- a/util.c
+++ b/util.c
@@ -974,6 +974,50 @@ dev_t devnm2devid(char *devnm)
}
/**
+ * 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)