Symlinks,
AutoDetect,
Waitclean,
+ DetailPlatform,
};
/* structures read from config file */
extern void map_unlock(struct map_ent **melp);
/* various details can be requested */
-#define GET_LEVEL 1
-#define GET_LAYOUT 2
-#define GET_COMPONENT 4
-#define GET_CHUNK 8
-#define GET_CACHE 16
-#define GET_MISMATCH 32
-#define GET_VERSION 64
-#define GET_DISKS 128
-#define GET_DEGRADED 256
-#define GET_SAFEMODE 512
-
-#define GET_DEVS 1024 /* gets role, major, minor */
-#define GET_OFFSET 2048
-#define GET_SIZE 4096
-#define GET_STATE 8192
-#define GET_ERROR 16384
+enum sysfs_read_flags {
+ GET_LEVEL = (1 << 0),
+ GET_LAYOUT = (1 << 1),
+ GET_COMPONENT = (1 << 2),
+ GET_CHUNK = (1 << 3),
+ GET_CACHE = (1 << 4),
+ GET_MISMATCH = (1 << 5),
+ GET_VERSION = (1 << 6),
+ GET_DISKS = (1 << 7),
+ GET_DEGRADED = (1 << 8),
+ GET_SAFEMODE = (1 << 9),
+ GET_DEVS = (1 << 10), /* gets role, major, minor */
+ GET_OFFSET = (1 << 11),
+ GET_SIZE = (1 << 12),
+ GET_STATE = (1 << 13),
+ GET_ERROR = (1 << 14),
+ SKIP_GONE_DEVS = (1 << 15),
+};
/* If fd >= 0, get the array it is open on,
* else use devnum. >=0 -> major9. <0.....
extern int sysfs_uevent(struct mdinfo *sra, char *event);
extern int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
char *name, unsigned long long *val);
+extern int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev,
+ char *name, char *val, int size);
extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms);
extern int sysfs_set_array(struct mdinfo *info, int vers);
extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd);
extern char *map_num(mapping_t *map, int num);
extern int map_name(mapping_t *map, char *name);
-extern mapping_t r5layout[], pers[], modes[], faultylayout[];
+extern mapping_t r5layout[], r6layout[], pers[], modes[], faultylayout[];
extern char *map_dev(int major, int minor, int create);
void (*brief_detail_super)(struct supertype *st);
void (*export_detail_super)(struct supertype *st);
+ /* Optional: platform hardware / firmware details */
+ int (*detail_platform)(int verbose, int enumerate_only);
+
/* Used:
* to get uuid to storing in bitmap metadata
* and 'reshape' backup-data metadata
*/
void (*uuid_from_super)(struct supertype *st, int uuid[4]);
- /* Extra generic details from metadata. This could be details about
+ /* Extract generic details from metadata. This could be details about
* the container, or about an individual array within the container.
* The determination is made either by:
* load_super being given a 'component' string.
/* update the metadata to include new device, either at create or
* when hot-adding a spare.
*/
- void (*add_to_super)(struct supertype *st, mdu_disk_info_t *dinfo,
+ int (*add_to_super)(struct supertype *st, mdu_disk_info_t *dinfo,
int fd, char *devname);
/* Write metadata to one device when fixing problems or adding
* added to validate changing size and new devices. If there are
* inter-device dependencies, it should record sufficient details
* so these can be validated.
+ * Both 'size' and '*freesize' are in sectors. chunk is bytes.
*/
int (*validate_geometry)(struct supertype *st, int level, int layout,
int raiddisks,
int verbose);
struct mdinfo *(*container_content)(struct supertype *st);
+ /* Allow a metadata handler to override mdadm's default layouts */
+ int (*default_layout)(int level); /* optional */
/* for mdmon */
int (*open_new)(struct supertype *c, struct active_array *a,
int swapuuid; /* true if uuid is bigending rather than hostendian */
int external;
+ const char *name; /* canonical metadata name */
} super0, super1, super_ddf, *superlist[];
extern struct superswitch super_imsm;
* external:/md0/12
*/
int devcnt;
- char *device_name; /* e.g. /dev/md/whatever */
struct mdinfo *devs;
extern int get_dev_size(int fd, char *dname, unsigned long long *sizep);
extern void get_one_disk(int mdfd, mdu_array_info_t *ainf,
mdu_disk_info_t *disk);
+void wait_for(char *dev);
#if __GNUC__ < 3
struct stat64;
#define HAVE_NFTW we assume
#define HAVE_FTW
-#ifdef UCLIBC
+#ifdef __UCLIBC__
# include <features.h>
+# ifndef __UCLIBC_HAS_LFS__
+# define lseek64 lseek
+# endif
# ifndef __UCLIBC_HAS_FTW__
# undef HAVE_FTW
# undef HAVE_NFTW
char *bitmap_file, int bitmap_chunk, int write_behind, int delay, int autof);
extern int Detail(char *dev, int brief, int export, int test, char *homehost);
+extern int Detail_Platform(struct superswitch *ss, int scan, int verbose);
extern int Query(char *dev);
extern int Examine(mddev_dev_t devlist, int brief, int export, int scan,
int SparcAdjust, struct supertype *forcest, char *homehost);
extern int get_mdp_major(void);
extern int dev_open(char *dev, int flags);
+extern int open_dev(int devnum);
extern int open_dev_excl(int devnum);
extern int is_standard(char *dev, int *nump);
extern int same_dev(char *one, char *two);
#define dprintf(fmt, arg...) \
({ if (0) fprintf(stderr, fmt, ##arg); 0; })
#endif
+#include <assert.h>
+#include <stdarg.h>
+static inline int xasprintf(char **strp, const char *fmt, ...) {
+ va_list ap;
+ int ret;
+ va_start(ap, fmt);
+ ret = vasprintf(strp, fmt, ap);
+ va_end(ap);
+ assert(ret >= 0);
+ return ret;
+}
#define LEVEL_MULTIPATH (-4)
#define LEVEL_LINEAR (-1)
#define makedev(M,m) (((M)<<8) | (m))
#endif
-/* for raid5 */
+/* for raid4/5/6 */
#define ALGORITHM_LEFT_ASYMMETRIC 0
#define ALGORITHM_RIGHT_ASYMMETRIC 1
#define ALGORITHM_LEFT_SYMMETRIC 2
#define ALGORITHM_RIGHT_SYMMETRIC 3
+
+/* Define non-rotating (raid4) algorithms. These allow
+ * conversion of raid4 to raid5.
+ */
+#define ALGORITHM_PARITY_0 4 /* P or P,Q are initial devices */
+#define ALGORITHM_PARITY_N 5 /* P or P,Q are final devices. */
+
+/* DDF RAID6 layouts differ from md/raid6 layouts in two ways.
+ * Firstly, the exact positioning of the parity block is slightly
+ * different between the 'LEFT_*' modes of md and the "_N_*" modes
+ * of DDF.
+ * Secondly, or order of datablocks over which the Q syndrome is computed
+ * is different.
+ * Consequently we have different layouts for DDF/raid6 than md/raid6.
+ * These layouts are from the DDFv1.2 spec.
+ * Interestingly DDFv1.2-Errata-A does not specify N_CONTINUE but
+ * leaves RLQ=3 as 'Vendor Specific'
+ */
+
+#define ALGORITHM_ROTATING_ZERO_RESTART 8 /* DDF PRL=6 RLQ=1 */
+#define ALGORITHM_ROTATING_N_RESTART 9 /* DDF PRL=6 RLQ=2 */
+#define ALGORITHM_ROTATING_N_CONTINUE 10 /*DDF PRL=6 RLQ=3 */
+
+
+/* For every RAID5 algorithm we define a RAID6 algorithm
+ * with exactly the same layout for data and parity, and
+ * with the Q block always on the last device (N-1).
+ * This allows trivial conversion from RAID5 to RAID6
+ */
+#define ALGORITHM_LEFT_ASYMMETRIC_6 16
+#define ALGORITHM_RIGHT_ASYMMETRIC_6 17
+#define ALGORITHM_LEFT_SYMMETRIC_6 18
+#define ALGORITHM_RIGHT_SYMMETRIC_6 19
+#define ALGORITHM_PARITY_0_6 20
+#define ALGORITHM_PARITY_N_6 ALGORITHM_PARITY_N
+