* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#define HAVE_STDINT_H 1
#include "mdadm.h"
#include "mdmon.h"
+#include "sha1.h"
#include <values.h>
#include <scsi/sg.h>
#include <ctype.h>
return st;
}
+#ifndef MDASSEMBLE
static __u8 *get_imsm_version(struct imsm_super *mpb)
{
return &mpb->sig[MPB_SIG_LEN];
}
+#endif
/* retrieve a disk directly from the anchor when the anchor is known to be
* up-to-date, currently only at load time
return &mpb->disk[index];
}
+#ifndef MDASSEMBLE
/* retrieve a disk from the parsed metadata */
static struct imsm_disk *get_imsm_disk(struct intel_super *super, __u8 index)
{
return NULL;
}
+#endif
/* generate a checksum directly from the anchor when the anchor is known to be
* up-to-date, currently only at load or write_super after coalescing
return map->raid_level;
}
+#ifndef MDASSEMBLE
static int cmp_extent(const void *av, const void *bv)
{
const struct extent *a = av;
return rv;
}
-#ifndef MDASSEMBLE
static void print_imsm_dev(struct imsm_dev *dev, int index)
{
__u64 sz;
}
}
+static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info);
+
static void brief_examine_super_imsm(struct supertype *st)
{
- printf("ARRAY /dev/imsm metadata=imsm\n");
+ /* We just write a generic DDF ARRAY entry
+ */
+ struct mdinfo info;
+ char nbuf[64];
+
+ getinfo_super_imsm(st, &info);
+ fname_from_uuid(st, &info, nbuf,'-');
+ printf("ARRAY /dev/imsm metadata=imsm UUID=%s\n", nbuf + 5);
}
static void detail_super_imsm(struct supertype *st, char *homehost)
static void brief_detail_super_imsm(struct supertype *st)
{
- printf("%s\n", __FUNCTION__);
+ struct mdinfo info;
+ char nbuf[64];
+ getinfo_super_imsm(st, &info);
+ fname_from_uuid(st, &info, nbuf,'-');
+ printf(" UUID=%s", nbuf + 5);
}
#endif
{
printf("%s\n", __FUNCTION__);
- return 0;
+ return -1;
}
static void uuid_from_super_imsm(struct supertype *st, int uuid[4])
{
- /* imsm does not track uuid's so just make sure we never return
- * the same value twice to break uuid matching in Manage_subdevs
- * FIXME what about the use of uuid's with bitmap's?
+ /* The uuid returned here is used for:
+ * uuid to put into bitmap file (Create, Grow)
+ * uuid for backup header when saving critical section (Grow)
+ * comparing uuids when re-adding a device into an array
+ * In these cases the uuid required is that of the data-array,
+ * not the device-set.
+ * uuid to recognise same set when adding a missing device back
+ * to an array. This is a uuid for the device-set.
+ *
+ * For each of these we can make do with a truncated
+ * or hashed uuid rather than the original, as long as
+ * everyone agrees.
+ * In each case the uuid required is that of the data-array,
+ * not the device-set.
+ */
+ /* imsm does not track uuid's so we synthesis one using sha1 on
+ * - The signature (Which is constant for all imsm array, but no matter)
+ * - the family_num of the container
+ * - the index number of the volume
+ * - the 'serial' number of the volume.
+ * Hopefully these are all constant.
*/
- static int dummy_id = 0;
+ struct intel_super *super = st->sb;
+
+ char buf[20];
+ struct sha1_ctx ctx;
+ struct imsm_dev *dev = NULL;
- uuid[0] = dummy_id++;
+ sha1_init_ctx(&ctx);
+ sha1_process_bytes(super->anchor->sig, MAX_SIGNATURE_LENGTH, &ctx);
+ sha1_process_bytes(&super->anchor->family_num, sizeof(__u32), &ctx);
+ if (super->current_vol >= 0)
+ dev = get_imsm_dev(super, super->current_vol);
+ if (dev) {
+ __u32 vol = super->current_vol;
+ sha1_process_bytes(&vol, sizeof(vol), &ctx);
+ sha1_process_bytes(dev->volume, MAX_RAID_SERIAL_LEN, &ctx);
+ }
+ sha1_finish_ctx(&ctx, buf);
+ memcpy(uuid, buf, 4*4);
}
#if 0
strncpy(info->name, (char *) dev->volume, MAX_RAID_SERIAL_LEN);
info->name[MAX_RAID_SERIAL_LEN] = 0;
+ info->array.major_version = -1;
+ info->array.minor_version = -2;
sprintf(info->text_version, "/%s/%d",
devnum2devname(st->container_dev),
info->container_member);
info->safe_mode_delay = 4000; /* 4 secs like the Matrix driver */
+ uuid_from_super_imsm(st, info->uuid);
}
info->disk.minor = 0;
info->disk.raid_disk = -1;
info->reshape_active = 0;
+ info->array.major_version = -1;
+ info->array.minor_version = -2;
strcpy(info->text_version, "imsm");
info->safe_mode_delay = 0;
info->disk.number = -1;
info->disk.state = 0;
+ info->name[0] = 0;
if (super->disks) {
disk = &super->disks->disk;
info->disk.state |= s & FAILED_DISK ? (1 << MD_DISK_FAULTY) : 0;
info->disk.state |= s & USABLE_DISK ? (1 << MD_DISK_SYNC) : 0;
}
+ uuid_from_super_imsm(st, info->uuid);
}
static int update_super_imsm(struct supertype *st, struct mdinfo *info,
memcpy(dest, src, sizeof_imsm_dev(src, 0));
}
+#ifndef MDASSEMBLE
/* When migrating map0 contains the 'destination' state while map1
* contains the current state. When not migrating map0 contains the
* current state. This routine assumes that map[0].map_state is set to
memcpy(dest, src, sizeof_imsm_map(src));
src->map_state = to_state;
}
+#endif
static int parse_raid_devices(struct intel_super *super)
{
st->minor_version = 0;
st->max_devs = IMSM_MAX_DEVICES;
}
+ st->loaded_container = 1;
return 0;
}
st->minor_version = 0;
st->max_devs = IMSM_MAX_DEVICES;
}
+ st->loaded_container = 0;
return 0;
}
return 1;
}
+#ifndef MDASSEMBLE
static void add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
int fd, char *devname)
{
return 0;
}
+
static int create_array(struct supertype *st)
{
size_t len;
return 0;
}
-static int add_disk(struct supertype *st)
+static int _add_disk(struct supertype *st)
{
struct intel_super *super = st->sb;
size_t len;
/* in the add disk case we are running in mdmon
* context, so don't close fd's
*/
- return add_disk(st);
+ return _add_disk(st);
} else
rv = create_array(st);
} else
return write_super_imsm(st->sb, 1);
}
+#endif
static int store_zero_imsm(struct supertype *st, int fd)
{
return 0;
}
+static int imsm_bbm_log_size(struct imsm_super *mpb)
+{
+ return __le32_to_cpu(mpb->bbm_log_size);
+}
+
+#ifndef MDASSEMBLE
static int validate_geometry_imsm_container(struct supertype *st, int level,
int layout, int raiddisks, int chunk,
unsigned long long size, char *dev,
return 1;
}
-int imsm_bbm_log_size(struct imsm_super *mpb)
-{
- return __le32_to_cpu(mpb->bbm_log_size);
-}
-
static int validate_geometry_imsm(struct supertype *st, int level, int layout,
int raiddisks, int chunk, unsigned long long size,
char *dev, unsigned long long *freesize,
return 1;
}
+#endif /* MDASSEMBLE */
static struct mdinfo *container_content_imsm(struct supertype *st)
{
}
+#ifndef MDASSEMBLE
static int imsm_open_new(struct supertype *c, struct active_array *a,
char *inst)
{
__free_imsm_disk(dl);
}
}
+#endif /* MDASSEMBLE */
struct superswitch super_imsm = {
#ifndef MDASSEMBLE
.detail_super = detail_super_imsm,
.brief_detail_super = brief_detail_super_imsm,
.write_init_super = write_init_super_imsm,
+ .validate_geometry = validate_geometry_imsm,
+ .add_to_super = add_to_super_imsm,
#endif
.match_home = match_home_imsm,
.uuid_from_super= uuid_from_super_imsm,
.load_super = load_super_imsm,
.init_super = init_super_imsm,
- .add_to_super = add_to_super_imsm,
.store_super = store_zero_imsm,
.free_super = free_super_imsm,
.match_metadata_desc = match_metadata_desc_imsm,
.container_content = container_content_imsm,
- .validate_geometry = validate_geometry_imsm,
.external = 1,
+#ifndef MDASSEMBLE
/* for mdmon */
.open_new = imsm_open_new,
.load_super = load_super_imsm,
.activate_spare = imsm_activate_spare,
.process_update = imsm_process_update,
.prepare_update = imsm_prepare_update,
+#endif /* MDASSEMBLE */
};