return (remainder < rv) ? remainder : rv;
}
-/*
- * Return minimum size of a spare and sector size
- * that can be used in this array
- */
-int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c)
-{
- struct intel_super *super = st->sb;
- struct dl *dl;
- struct extent *e;
- int i;
- unsigned long long size = 0;
-
- c->min_size = 0;
- c->sector_size = 0;
-
- if (!super)
- return -EINVAL;
- /* find first active disk in array */
- dl = super->disks;
- while (dl && (is_failed(&dl->disk) || dl->index == -1))
- dl = dl->next;
- if (!dl)
- return -EINVAL;
- /* find last lba used by subarrays */
- e = get_extents(super, dl, 0);
- if (!e)
- return -EINVAL;
- for (i = 0; e[i].size; i++)
- continue;
- if (i > 0)
- size = e[i-1].start + e[i-1].size;
- free(e);
-
- /* add the amount of space needed for metadata */
- size += imsm_min_reserved_sectors(super);
-
- c->min_size = size * 512;
- c->sector_size = super->sector_size;
-
- return 0;
-}
-
static bool is_gen_migration(struct imsm_dev *dev);
#define IMSM_4K_DIV 8
printf("\n");
printf(" Failed disk : ");
if (map->failed_disk_num == 0xff)
- printf("none");
+ printf(STR_COMMON_NONE);
else
printf("%i", map->failed_disk_num);
printf("\n");
else
printf("Rapid Storage Technology%s\n",
imsm_orom_is_enterprise(orom) ? " enterprise" : "");
- if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build)
- printf(" Version : %d.%d.%d.%d\n", orom->major_ver,
- orom->minor_ver, orom->hotfix_ver, orom->build);
+ if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build) {
+ if (imsm_orom_is_vmd_without_efi(orom))
+ printf(" Version : %d.%d\n", orom->major_ver,
+ orom->minor_ver);
+ else
+ printf(" Version : %d.%d.%d.%d\n", orom->major_ver,
+ orom->minor_ver, orom->hotfix_ver, orom->build);
+ }
printf(" RAID Levels :%s%s%s%s%s\n",
imsm_orom_has_raid0(orom) ? " raid0" : "",
imsm_orom_has_raid1(orom) ? " raid1" : "",
memcpy(uuid, buf, 4*4);
}
-#if 0
-static void
-get_imsm_numerical_version(struct imsm_super *mpb, int *m, int *p)
-{
- __u8 *v = get_imsm_version(mpb);
- __u8 *end = mpb->sig + MAX_SIGNATURE_LENGTH;
- char major[] = { 0, 0, 0 };
- char minor[] = { 0 ,0, 0 };
- char patch[] = { 0, 0, 0 };
- char *ver_parse[] = { major, minor, patch };
- int i, j;
-
- i = j = 0;
- while (*v != '\0' && v < end) {
- if (*v != '.' && j < 2)
- ver_parse[i][j++] = *v;
- else {
- i++;
- j = 0;
- }
- v++;
- }
-
- *m = strtol(minor, NULL, 0);
- *p = strtol(patch, NULL, 0);
-}
-#endif
-
static __u32 migr_strip_blocks_resync(struct imsm_dev *dev)
{
/* migr_strip_size when repairing or initializing parity */
*/
max_enough = max(max_enough, enough);
}
- dprintf("enough: %d\n", max_enough);
+
info->container_enough = max_enough;
if (super->disks) {
memset(buf, 0, sizeof(buf));
+ if (check_env("IMSM_DEVNAME_AS_SERIAL")) {
+ memset(serial, 0, serial_buf_len);
+ fd2devname(fd, (char *) serial);
+ return 0;
+ }
+
rv = nvme_get_serial(fd, buf, sizeof(buf));
if (rv)
rv = scsi_get_serial(fd, buf, sizeof(buf));
- if (rv && check_env("IMSM_DEVNAME_AS_SERIAL")) {
- memset(serial, 0, MAX_RAID_SERIAL_LEN);
- fd2devname(fd, (char *) serial);
- return 0;
- }
-
if (rv != 0) {
if (devname)
pr_err("Failed to retrieve serial for %s\n",
}
}
-static int check_name(struct intel_super *super, char *name, int quiet)
+/**
+ * imsm_check_name() - check imsm naming criteria.
+ * @super: &intel_super pointer, not NULL.
+ * @name: name to check.
+ * @verbose: verbose level.
+ *
+ * Name must be no longer than &MAX_RAID_SERIAL_LEN and must be unique across volumes.
+ *
+ * Returns: &true if @name matches, &false otherwise.
+ */
+static bool imsm_is_name_allowed(struct intel_super *super, const char * const name,
+ const int verbose)
{
struct imsm_super *mpb = super->anchor;
- char *reason = NULL;
- char *start = name;
- size_t len = strlen(name);
int i;
- if (len > 0) {
- while (isspace(start[len - 1]))
- start[--len] = 0;
- while (*start && isspace(*start))
- ++start, --len;
- memmove(name, start, len + 1);
+ if (is_string_lq(name, MAX_RAID_SERIAL_LEN + 1) == false) {
+ pr_vrb("imsm: Name \"%s\" is too long\n", name);
+ return false;
}
- if (len > MAX_RAID_SERIAL_LEN)
- reason = "must be 16 characters or less";
- else if (len == 0)
- reason = "must be a non-empty string";
-
for (i = 0; i < mpb->num_raid_devs; i++) {
struct imsm_dev *dev = get_imsm_dev(super, i);
if (strncmp((char *) dev->volume, name, MAX_RAID_SERIAL_LEN) == 0) {
- reason = "already exists";
- break;
+ pr_vrb("imsm: Name \"%s\" already exists\n", name);
+ return false;
}
}
- if (reason && !quiet)
- pr_err("imsm volume name %s\n", reason);
-
- return !reason;
+ return true;
}
static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
}
}
- if (!check_name(super, name, 0))
+ if (imsm_is_name_allowed(super, name, 1) == false)
return 0;
+
dv = xmalloc(sizeof(*dv));
dev = xcalloc(1, sizeof(*dev) + sizeof(__u32) * (info->raid_disks - 1));
/*
int fd = -1;
while (dev && !is_fd_valid(fd)) {
char *path = xmalloc(strlen(dev->name) + strlen("/dev/") + 1);
- num = sprintf(path, "%s%s", "/dev/", dev->name);
+ num = snprintf(path, PATH_MAX, "%s%s", "/dev/", dev->name);
if (num > 0)
fd = open(path, O_RDONLY, 0);
if (num <= 0 || !is_fd_valid(fd)) {
if (i < current_vol)
continue;
- sprintf(subarray, "%u", i);
+ snprintf(subarray, sizeof(subarray), "%u", i);
if (is_subarray_active(subarray, st->devnm)) {
pr_err("deleting subarray-%d would change the UUID of active subarray-%d, aborting\n",
current_vol, i);
char *ep;
int vol;
- if (!check_name(super, name, 0))
+ if (imsm_is_name_allowed(super, name, 1) == false)
return 2;
vol = strtoul(subarray, &ep, 10);
/* still reshaping, maybe update vol_curr_migr_unit */
goto mark_checkpoint;
} else {
- if (a->last_checkpoint == 0 && a->prev_action == reshape) {
- /* for some reason we aborted the reshape.
- *
- * disable automatic metadata rollback
- * user action is required to recover process
- */
- if (0) {
- struct imsm_map *map2 =
- get_imsm_map(dev, MAP_1);
- dev->vol.migr_state = 0;
- set_migr_type(dev, 0);
- set_vol_curr_migr_unit(dev, 0);
- memcpy(map, map2,
- sizeof_imsm_map(map2));
- super->updates_pending++;
- }
- }
if (a->last_checkpoint >= a->info.component_size) {
unsigned long long array_blocks;
int used_disks;
super->updates_pending++;
}
+ if (a->prev_action == idle)
+ goto skip_mark_checkpoint;
+
mark_checkpoint:
/* skip checkpointing for general migration,
* it is controlled in mdadm
if (a->info.container_member == target)
break;
dev = get_imsm_dev(super, u->dev_idx);
- if (a || !check_name(super, name, 1)) {
+
+ if (a || !dev || imsm_is_name_allowed(super, name, 0) == false) {
dprintf("failed to rename subarray-%d\n", target);
break;
}
unsigned int sector_size = super->sector_size;
unsigned long long curr_migr_unit = current_migr_unit(migr_rec);
unsigned long long num_migr_units = get_num_migr_units(migr_rec);
- char buffer[20];
+ char buffer[SYSFS_MAX_BUF_SIZE];
int skipped_disks = 0;
struct dl *dl_disk;
- err = sysfs_get_str(info, NULL, "array_state", (char *)buffer, 20);
+ err = sysfs_get_str(info, NULL, "array_state", (char *)buffer, sizeof(buffer));
if (err < 1)
return 1;
char *drv=NULL;
struct stat st;
- strcpy(disk_path, disk_by_path);
+ strncpy(disk_path, disk_by_path, PATH_MAX);
strncat(disk_path, path, PATH_MAX - strlen(disk_path) - 1);
if (stat(disk_path, &st) == 0) {
struct sys_dev* hba;
return drv;
}
+/**
+ * get_spare_criteria_imsm() - set spare criteria.
+ * @st: supertype.
+ * @mddev_path: path to md device devnode, it must be container.
+ * @c: spare_criteria struct to fill, not NULL.
+ *
+ * If superblock is not loaded, use mddev_path to load_container. It must be given in this case.
+ * Filles size and sector size accordingly to superblock.
+ */
+mdadm_status_t get_spare_criteria_imsm(struct supertype *st, char *mddev_path,
+ struct spare_criteria *c)
+{
+ mdadm_status_t ret = MDADM_STATUS_ERROR;
+ bool free_superblock = false;
+ unsigned long long size = 0;
+ struct intel_super *super;
+ struct extent *e;
+ struct dl *dl;
+ int i;
+
+ /* If no superblock and no mddev_path, we cannot load superblock. */
+ assert(st->sb || mddev_path);
+
+ if (mddev_path) {
+ int fd = open(mddev_path, O_RDONLY);
+
+ if (!is_fd_valid(fd))
+ return MDADM_STATUS_ERROR;
+
+ if (!st->sb) {
+ if (load_container_imsm(st, fd, st->devnm)) {
+ close(fd);
+ return MDADM_STATUS_ERROR;
+ }
+ free_superblock = true;
+ }
+ close(fd);
+ }
+
+ super = st->sb;
+
+ /* find first active disk in array */
+ dl = super->disks;
+ while (dl && (is_failed(&dl->disk) || dl->index == -1))
+ dl = dl->next;
+
+ if (!dl)
+ goto out;
+
+ /* find last lba used by subarrays */
+ e = get_extents(super, dl, 0);
+ if (!e)
+ goto out;
+
+ for (i = 0; e[i].size; i++)
+ continue;
+ if (i > 0)
+ size = e[i - 1].start + e[i - 1].size;
+ free(e);
+
+ /* add the amount of space needed for metadata */
+ size += imsm_min_reserved_sectors(super);
+
+ c->min_size = size * 512;
+ c->sector_size = super->sector_size;
+ c->criteria_set = true;
+ ret = MDADM_STATUS_SUCCESS;
+
+out:
+ if (free_superblock)
+ free_super_imsm(st);
+
+ if (ret != MDADM_STATUS_SUCCESS)
+ c->criteria_set = false;
+
+ return ret;
+}
+
static char *imsm_find_array_devnm_by_subdev(int subdev, char *container)
{
static char devnm[32];
{
struct spare_criteria sc;
- get_spare_criteria_imsm(st, &sc);
+ get_spare_criteria_imsm(st, NULL, &sc);
return container_choose_spares(st, &sc, NULL, NULL, NULL, 0);
}
static int read_completed(int fd, unsigned long long *val)
{
int ret;
- char buf[50];
+ char buf[SYSFS_MAX_BUF_SIZE];
- ret = sysfs_fd_get_str(fd, buf, 50);
+ ret = sysfs_fd_get_str(fd, buf, sizeof(buf));
if (ret < 0)
return ret;
ret = COMPLETED_OK;
- if (strncmp(buf, "none", 4) == 0) {
+ if (str_is_none(buf) == true) {
ret = COMPLETED_NONE;
} else if (strncmp(buf, "delayed", 7) == 0) {
ret = COMPLETED_DELAYED;
do {
int rc;
- char action[20];
+ char action[SYSFS_MAX_BUF_SIZE];
int timeout = 3000;
sysfs_wait(fd, &timeout);
if (sysfs_get_str(sra, NULL, "sync_action",
- action, 20) > 0 &&
+ action, sizeof(action)) > 0 &&
strncmp(action, "reshape", 7) != 0) {
if (strncmp(action, "idle", 4) == 0)
break;
if (sd->disk.state & (1<<MD_DISK_FAULTY))
continue;
if (sd->disk.state & (1<<MD_DISK_SYNC)) {
- char sbuf[100];
+ char sbuf[SYSFS_MAX_BUF_SIZE];
int raid_disk = sd->disk.raid_disk;
if (sysfs_get_str(info,