]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - mdadm.h
mdadm: Move pr_vrb define to mdadm.h
[thirdparty/mdadm.git] / mdadm.h
diff --git a/mdadm.h b/mdadm.h
index 3cbf82f18d9ebb0cf20b787f16bedb10c70b4ba8..fbb161ba4dc2bfa5ced6326ccc7b125655f3ed5a 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -33,8 +33,10 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
 # endif
 #endif
 
+#include       <assert.h>
 #include       <sys/types.h>
 #include       <sys/stat.h>
+#include       <stdarg.h>
 #include       <stdint.h>
 #include       <stdlib.h>
 #include       <time.h>
@@ -45,10 +47,10 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
 #include       <errno.h>
 #include       <string.h>
 #include       <syslog.h>
-#ifdef __GLIBC__
+#include       <stdbool.h>
+#include       <signal.h>
 /* Newer glibc requires sys/sysmacros.h directly for makedev() */
 #include       <sys/sysmacros.h>
-#endif
 #ifdef __dietlibc__
 #include       <strings.h>
 /* dietlibc has deprecated random and srandom!! */
@@ -98,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.
@@ -131,6 +149,14 @@ struct dlm_lksb {
 #define FAILED_SLOTS_DIR "/run/mdadm/failed-slots"
 #endif /* FAILED_SLOTS */
 
+#ifndef MDMON_SERVICE
+#define MDMON_SERVICE "mdmon"
+#endif /* MDMON_SERVICE */
+
+#ifndef GROW_SERVICE
+#define GROW_SERVICE "mdadm-grow-continue"
+#endif /* GROW_SERVICE */
+
 #include       "md_u.h"
 #include       "md_p.h"
 #include       "bitmap.h"
@@ -191,6 +217,36 @@ struct dlm_lksb {
 #endif
 #endif /* __KLIBC__ */
 
+/*
+ * Partially stolen from include/linux/unaligned/packed_struct.h
+ */
+struct __una_u16 { __u16 x; } __attribute__ ((packed));
+struct __una_u32 { __u32 x; } __attribute__ ((packed));
+
+static inline __u16 __get_unaligned16(const void *p)
+{
+       const struct __una_u16 *ptr = (const struct __una_u16 *)p;
+       return ptr->x;
+}
+
+static inline __u32 __get_unaligned32(const void *p)
+{
+       const struct __una_u32 *ptr = (const struct __una_u32 *)p;
+       return ptr->x;
+}
+
+static inline void __put_unaligned16(__u16 val, void *p)
+{
+       struct __una_u16 *ptr = (struct __una_u16 *)p;
+       ptr->x = val;
+}
+
+static inline void __put_unaligned32(__u32 val, void *p)
+{
+       struct __una_u32 *ptr = (struct __una_u32 *)p;
+       ptr->x = val;
+}
+
 /*
   * Check at compile time that something is of a particular type.
   * Always evaluates to 1 so you may use it easily in comparisons.
@@ -235,6 +291,14 @@ struct dlm_lksb {
 
 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
 
+#define KIB_TO_BYTES(x)        ((x) << 10)
+#define SEC_TO_BYTES(x)        ((x) << 9)
+
+/**
+ * This is true for native and DDF, IMSM allows 16.
+ */
+#define MD_NAME_MAX 32
+
 extern const char Name[];
 
 struct md_bb_entry {
@@ -313,9 +377,13 @@ struct mdinfo {
        int container_member; /* for assembling external-metatdata arrays
                               * This is to be used internally by metadata
                               * handler only */
-       int container_enough; /* flag external handlers can set to
-                              * indicate that subarrays have not enough (-1),
-                              * enough to start (0), or all expected disks (1) */
+       /**
+        * flag external handlers can set to indicate that subarrays have:
+        * - not enough disks to start (-1),
+        * - enough disks to start (0),
+        * - all expected disks (1).
+        */
+       int container_enough;
        char            sys_name[32];
        struct mdinfo *devs;
        struct mdinfo *next;
@@ -345,6 +413,7 @@ struct mdinfo {
                ARRAY_ACTIVE,
                ARRAY_WRITE_PENDING,
                ARRAY_ACTIVE_IDLE,
+               ARRAY_BROKEN,
                ARRAY_UNKNOWN_STATE,
        } array_state;
        struct md_bb bb;
@@ -355,17 +424,24 @@ struct createinfo {
        int     gid;
        int     autof;
        int     mode;
-       int     symlinks;
        int     names;
        int     bblist;
        struct supertype *supertype;
 };
 
 struct spare_criteria {
+       bool criteria_set;
        unsigned long long min_size;
        unsigned int sector_size;
+       struct dev_policy *pols;
 };
 
+typedef enum mdadm_status {
+       MDADM_STATUS_SUCCESS = 0,
+       MDADM_STATUS_ERROR,
+       MDADM_STATUS_UNDEF,
+} mdadm_status_t;
+
 enum mode {
        ASSEMBLE=1,
        BUILD,
@@ -380,6 +456,7 @@ enum mode {
 };
 
 extern char short_options[];
+extern char short_monitor_options[];
 extern char short_bitmap_options[];
 extern char short_bitmap_auto_options[];
 extern struct option long_options[];
@@ -394,6 +471,7 @@ extern char Version[], Usage[], Help[], OptionHelp[],
  */
 enum special_options {
        AssumeClean = 300,
+       WriteZeroes,
        BitmapChunk,
        WriteBehind,
        ReAdd,
@@ -402,7 +480,6 @@ enum special_options {
        BackupFile,
        HomeHost,
        AutoHomeHost,
-       Symlinks,
        AutoDetect,
        Waitclean,
        DetailPlatform,
@@ -412,6 +489,7 @@ enum special_options {
        NoSharing,
        HelpOptions,
        Brief,
+       NoDevices,
        ManageOpt,
        Add,
        AddSpare,
@@ -456,6 +534,51 @@ enum special_options {
        ConsistencyPolicy,
 };
 
+enum update_opt {
+       UOPT_NAME = 1,
+       UOPT_PPL,
+       UOPT_NO_PPL,
+       UOPT_BITMAP,
+       UOPT_NO_BITMAP,
+       UOPT_SUBARRAY_ONLY,
+       UOPT_SPARC22,
+       UOPT_SUPER_MINOR,
+       UOPT_SUMMARIES,
+       UOPT_RESYNC,
+       UOPT_UUID,
+       UOPT_HOMEHOST,
+       UOPT_HOME_CLUSTER,
+       UOPT_NODES,
+       UOPT_DEVICESIZE,
+       UOPT_BBL,
+       UOPT_NO_BBL,
+       UOPT_FORCE_NO_BBL,
+       UOPT_METADATA,
+       UOPT_REVERT_RESHAPE,
+       UOPT_LAYOUT_ORIGINAL,
+       UOPT_LAYOUT_ALTERNATE,
+       UOPT_LAYOUT_UNSPECIFIED,
+       UOPT_BYTEORDER,
+       UOPT_HELP,
+       UOPT_USER_ONLY,
+       /*
+        * Code specific options, cannot be set by the user
+        */
+       UOPT_SPEC_FORCE_ONE,
+       UOPT_SPEC_FORCE_ARRAY,
+       UOPT_SPEC_ASSEMBLE,
+       UOPT_SPEC_LINEAR_GROW_NEW,
+       UOPT_SPEC_LINEAR_GROW_UPDATE,
+       UOPT_SPEC__RESHAPE_PROGRESS,
+       UOPT_SPEC_WRITEMOSTLY,
+       UOPT_SPEC_READWRITE,
+       UOPT_SPEC_FAILFAST,
+       UOPT_SPEC_NOFAILFAST,
+       UOPT_SPEC_REVERT_RESHAPE_NOBACKUP,
+       UOPT_UNDEFINED
+};
+extern void fprint_update_options(FILE *outf, enum update_opt update_mode);
+
 enum prefix_standard {
        JEDEC,
        IEC
@@ -487,7 +610,7 @@ struct mddev_ident {
 
        int     uuid_set;
        int     uuid[4];
-       char    name[33];
+       char    name[MD_NAME_MAX + 1];
 
        int super_minor;
 
@@ -522,6 +645,7 @@ struct context {
        int     runstop;
        int     verbose;
        int     brief;
+       int     no_devices;
        int     force;
        char    *homehost;
        int     require_homehost;
@@ -529,7 +653,7 @@ struct context {
        int     export;
        int     test;
        char    *subarray;
-       char    *update;
+       enum    update_opt update;
        int     scan;
        int     SparcAdjust;
        int     autof;
@@ -553,8 +677,10 @@ struct shape {
        int     bitmap_chunk;
        char    *bitmap_file;
        int     assume_clean;
+       bool    write_zeroes;
        int     write_behind;
        unsigned long long size;
+       unsigned long long data_offset;
        int     consistency_policy;
 };
 
@@ -597,7 +723,7 @@ struct mdstat_ent {
 extern struct mdstat_ent *mdstat_read(int hold, int start);
 extern void mdstat_close(void);
 extern void free_mdstat(struct mdstat_ent *ms);
-extern void mdstat_wait(int seconds);
+extern int mdstat_wait(int seconds);
 extern void mdstat_wait_fd(int fd, const sigset_t *sigmask);
 extern int mddev_busy(char *devnm);
 extern struct mdstat_ent *mdstat_by_component(char *name);
@@ -647,8 +773,13 @@ enum sysfs_read_flags {
        GET_ERROR       = (1 << 24),
        GET_ARRAY_STATE = (1 << 25),
        GET_CONSISTENCY_POLICY  = (1 << 26),
+       GET_DEVS_ALL    = (1 << 27),
 };
 
+#define SYSFS_MAX_BUF_SIZE 64
+
+extern void sysfs_get_container_devnm(struct mdinfo *mdi, char *buf);
+
 /* If fd >= 0, get the array it is open on,
  * else use devnm.
  */
@@ -680,7 +811,7 @@ extern int sysfs_attribute_available(struct mdinfo *sra, struct mdinfo *dev,
 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_set_array(struct mdinfo *info);
 extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume);
 extern int sysfs_disk_to_scsi_id(int fd, __u32 *id);
 extern int sysfs_unique_holder(char *devnm, long rdev);
@@ -728,11 +859,12 @@ extern int restore_stripes(int *dest, unsigned long long *offsets,
 #endif
 
 #define SYSLOG_FACILITY LOG_DAEMON
-
+extern char *map_num_s(mapping_t *map, int num);
 extern char *map_num(mapping_t *map, int num);
 extern int map_name(mapping_t *map, char *name);
-extern mapping_t r5layout[], r6layout[], pers[], modes[], faultylayout[];
-extern mapping_t consistency_policies[], sysfs_array_states[];
+extern mapping_t r0layout[], r5layout[], r6layout[],
+       pers[], modes[], faultylayout[];
+extern mapping_t consistency_policies[], sysfs_array_states[], update_options[];
 
 extern char *map_dev_preferred(int major, int minor, int create,
                               char *prefer);
@@ -741,6 +873,42 @@ static inline char *map_dev(int major, int minor, int create)
        return map_dev_preferred(major, minor, create, NULL);
 }
 
+/**
+ * is_fd_valid() - check file descriptor.
+ * @fd: file descriptor.
+ *
+ * The function checks if @fd is nonnegative integer and shall be used only
+ * to verify open() result.
+ */
+static inline int is_fd_valid(int fd)
+{
+       return (fd > -1);
+}
+
+/**
+ * is_level456() - check whether given level is between inclusive 4 and 6.
+ * @level: level to check.
+ *
+ * Return: true if condition is met, false otherwise
+ */
+static inline bool is_level456(int level)
+{
+       return (level >= 4 && level <= 6);
+}
+
+/**
+ * close_fd() - verify, close and unset file descriptor.
+ * @fd: pointer to file descriptor.
+ *
+ * The function closes and invalidates file descriptor if appropriative. It
+ * ignores incorrect file descriptor quitely to simplify error handling.
+ */
+static inline void close_fd(int *fd)
+{
+       if (is_fd_valid(*fd) && close(*fd) == 0)
+               *fd = -1;
+}
+
 struct active_array;
 struct metadata_update;
 
@@ -773,6 +941,23 @@ struct reshape {
        unsigned long long new_size; /* New size of array in sectors */
 };
 
+/**
+ * struct dev_policy - Data structure for policy management.
+ * @next: pointer to next dev_policy.
+ * @name: policy name, category.
+ * @metadata: the metadata type it affects.
+ * @value: value of the policy.
+ *
+ * The functions to manipulate dev_policy lists do not free elements, so they must be statically
+ * allocated. @name and @metadata can be compared by address.
+ */
+typedef struct dev_policy {
+       struct dev_policy *next;
+       char *name;
+       const char *metadata;
+       const char *value;
+} dev_policy_t;
+
 /* A superswitch provides entry point to a metadata handler.
  *
  * The superswitch primarily operates on some "metadata" that
@@ -815,8 +1000,9 @@ extern struct superswitch {
        /* Used to report details of an active array.
         * ->load_super was possibly given a 'component' string.
         */
-       void (*detail_super)(struct supertype *st, char *homehost);
-       void (*brief_detail_super)(struct supertype *st);
+       void (*detail_super)(struct supertype *st, char *homehost,
+                            char *subarray);
+       void (*brief_detail_super)(struct supertype *st, char *subarray);
        void (*export_detail_super)(struct supertype *st);
 
        /* Optional: platform hardware / firmware details */
@@ -884,7 +1070,7 @@ extern struct superswitch {
         *                    it will resume going in the opposite direction.
         */
        int (*update_super)(struct supertype *st, struct mdinfo *info,
-                           char *update,
+                           enum update_opt update,
                            char *devname, int verbose,
                            int uuid_set, char *homehost);
 
@@ -924,7 +1110,8 @@ extern struct superswitch {
         * moved in, otherwise the superblock in 'st' is compared with
         * 'tst'.
         */
-       int (*compare_super)(struct supertype *st, struct supertype *tst);
+       int (*compare_super)(struct supertype *st, struct supertype *tst,
+                            int verbose);
        /* Load metadata from a single device.  If 'devname' is not NULL
         * print error messages as appropriate */
        int (*load_super)(struct supertype *st, int fd, char *devname);
@@ -949,10 +1136,9 @@ extern struct superswitch {
         * Return spare criteria for array:
         * - minimum disk size can be used in array;
         * - sector size can be used in array.
-        * Return values: 0 - for success and -EINVAL on error.
         */
-       int (*get_spare_criteria)(struct supertype *st,
-                                 struct spare_criteria *sc);
+       mdadm_status_t (*get_spare_criteria)(struct supertype *st, char *mddev_path,
+                                            struct spare_criteria *sc);
        /* Find somewhere to put a bitmap - possibly auto-size it - and
         * update the metadata to record this.  The array may be newly
         * created, in which case data_size may be updated, or it might
@@ -964,6 +1150,9 @@ extern struct superswitch {
        int (*add_internal_bitmap)(struct supertype *st, int *chunkp,
                                   int delay, int write_behind,
                                   unsigned long long size, int may_change, int major);
+       /* Perform additional setup required to activate a bitmap.
+        */
+       int (*set_bitmap)(struct supertype *st, struct mdinfo *info);
        /* Seek 'fd' to start of write-intent-bitmap.  Must be an
         * md-native format bitmap
         */
@@ -997,6 +1186,25 @@ extern struct superswitch {
                                 char *subdev, unsigned long long *freesize,
                                 int consistency_policy, int verbose);
 
+       /**
+        * test_and_add_drive_policies() - test new and add custom policies from metadata handler.
+        * @pols: list of currently recorded policies.
+        * @disk_fd: file descriptor of the device to check.
+        * @verbose: verbose flag.
+        *
+        * Used by IMSM to verify all drives in container/array, against requirements not recored
+        * in superblock, like controller type for IMSM. It should check all drives even if
+        * they are not actually used, because mdmon or kernel are free to use any drive assigned to
+        * container automatically.
+        *
+        * Generating and comparison methods belong to metadata handler. It is not mandatory to be
+        * implemented.
+        *
+        * Return: MDADM_STATUS_SUCCESS is expected on success.
+        */
+       mdadm_status_t (*test_and_add_drive_policies)(dev_policy_t **pols, int disk_fd,
+                                                     const int verbose);
+
        /* Return a linked list of 'mdinfo' structures for all arrays
         * in the container.  For non-containers, it is like
         * getinfo_super with an allocated mdinfo.*/
@@ -1004,10 +1212,17 @@ extern struct superswitch {
        /* query the supertype for default geometry */
        void (*default_geometry)(struct supertype *st, int *level, int *layout, int *chunk); /* optional */
        /* Permit subarray's to be deleted from inactive containers */
-       int (*kill_subarray)(struct supertype *st); /* optional */
-       /* Permit subarray's to be modified */
+       int (*kill_subarray)(struct supertype *st,
+                            char *subarray_id); /* optional */
+       /**
+        * update_subarray() - Permit subarray to be modified.
+        * @st: Supertype.
+        * @subarray: Subarray name.
+        * @update: Update option.
+        * @ident: Optional identifiers.
+        */
        int (*update_subarray)(struct supertype *st, char *subarray,
-                              char *update, struct mddev_ident *ident); /* optional */
+                              enum update_opt update, struct mddev_ident *ident);
        /* Check if reshape is supported for this external format.
         * st is obtained from super_by_fd() where st->subarray[0] is
         * initialized to indicate if reshape is being performed at the
@@ -1030,7 +1245,7 @@ extern struct superswitch {
 
 /* for mdmon */
        int (*open_new)(struct supertype *c, struct active_array *a,
-                       char *inst);
+                       int inst);
 
        /* Tell the metadata handler the current state of the array.
         * This covers whether it is known to be consistent (no pending writes)
@@ -1071,21 +1286,6 @@ extern struct superswitch {
         */
        struct mdinfo *(*activate_spare)(struct active_array *a,
                                         struct metadata_update **updates);
-       /*
-        * Return statically allocated string that represents metadata specific
-        * controller domain of the disk. The domain is used in disk domain
-        * matching functions. Disks belong to the same domain if the they have
-        * the same domain from mdadm.conf and belong the same metadata domain.
-        * Returning NULL or not providing this handler means that metadata
-        * does not distinguish the differences between disks that belong to
-        * different controllers. They are in the domain specified by
-        * configuration file (mdadm.conf).
-        * In case when the metadata has the notion of domains based on disk
-        * it shall return NULL for disks that do not belong to the controller
-        * the supported domains. Such disks will form another domain and won't
-        * be mixed with supported ones.
-        */
-       const char *(*get_disk_controller_domain)(const char *path);
 
        /* for external backup area */
        int (*recover_backup)(struct supertype *st, struct mdinfo *info);
@@ -1120,6 +1320,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;
@@ -1190,27 +1392,8 @@ extern struct supertype *dup_super(struct supertype *st);
 extern int get_dev_size(int fd, char *dname, unsigned long long *sizep);
 extern int get_dev_sector_size(int fd, char *dname, unsigned int *sectsizep);
 extern int must_be_container(int fd);
-extern int dev_size_from_id(dev_t id, unsigned long long *size);
-extern int dev_sector_size_from_id(dev_t id, unsigned int *size);
 void wait_for(char *dev, int fd);
 
-/*
- * Data structures for policy management.
- * Each device can have a policy structure that lists
- * various name/value pairs each possibly with a metadata associated.
- * The policy list is sorted by name/value/metadata
- */
-struct dev_policy {
-       struct dev_policy *next;
-       char *name;     /* None of these strings are allocated.  They are
-                        * all just references to strings which are known
-                        * to exist elsewhere.
-                        * name and metadata can be compared by address equality.
-                        */
-       const char *metadata;
-       const char *value;
-};
-
 extern char pol_act[], pol_domain[], pol_metadata[], pol_auto[];
 
 /* iterate over the sublist starting at list, having the same
@@ -1247,15 +1430,21 @@ extern void policyline(char *line, char *type);
 extern void policy_add(char *type, ...);
 extern void policy_free(void);
 
-extern struct dev_policy *path_policy(char *path, char *type);
+extern struct dev_policy *path_policy(char **paths, char *type);
 extern struct dev_policy *disk_policy(struct mdinfo *disk);
 extern struct dev_policy *devid_policy(int devid);
 extern void dev_policy_free(struct dev_policy *p);
 
-//extern void pol_new(struct dev_policy **pol, char *name, char *val, char *metadata);
 extern void pol_add(struct dev_policy **pol, char *name, char *val, char *metadata);
 extern struct dev_policy *pol_find(struct dev_policy *pol, char *name);
 
+extern mdadm_status_t drive_test_and_add_policies(struct supertype *st, dev_policy_t **pols,
+                                                 int fd, const int verbose);
+extern mdadm_status_t sysfs_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols,
+                                                       struct mdinfo *mdi, const int verbose);
+extern mdadm_status_t mddev_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols,
+                                                       int array_fd, const int verbose);
+
 enum policy_action {
        act_default,
        act_include,
@@ -1291,6 +1480,9 @@ void domain_add(struct domainlist **domp, char *domain);
 extern void policy_save_path(char *id_path, struct map_ent *array);
 extern int policy_check_path(struct mdinfo *disk, struct map_ent *array);
 
+extern void sysfs_rules_apply(char *devnm, struct mdinfo *dev);
+extern void sysfsline(char *line);
+
 #if __GNUC__ < 3
 struct stat64;
 #endif
@@ -1337,14 +1529,13 @@ extern int Manage_stop(char *devname, int fd, int quiet,
                       int will_retry);
 extern int Manage_subdevs(char *devname, int fd,
                          struct mddev_dev *devlist, int verbose, int test,
-                         char *update, int force);
+                         enum update_opt update, int force);
 extern int autodetect(void);
 extern int Grow_Add_device(char *devname, int fd, char *newdev);
 extern int Grow_addbitmap(char *devname, int fd,
                          struct context *c, struct shape *s);
 extern int Grow_reshape(char *devname, int fd,
                        struct mddev_dev *devlist,
-                       unsigned long long data_offset,
                        struct context *c, struct shape *s);
 extern int Grow_restart(struct supertype *st, struct mdinfo *info,
                        int *fdlist, int cnt, char *backup_file, int verbose);
@@ -1368,15 +1559,11 @@ extern int Assemble(struct supertype *st, char *mddev,
                    struct mddev_dev *devlist,
                    struct context *c);
 
-extern int Build(char *mddev, struct mddev_dev *devlist,
-                struct shape *s, struct context *c);
+extern int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s,
+                struct context *c);
 
-extern int Create(struct supertype *st, char *mddev,
-                 char *name, int *uuid,
-                 int subdevs, struct mddev_dev *devlist,
-                 struct shape *s,
-                 struct context *c,
-                 unsigned long long data_offset);
+extern int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
+                 struct mddev_dev *devlist, struct shape *s, struct context *c);
 
 extern int Detail(char *dev, struct context *c);
 extern int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, char *controller_path);
@@ -1393,9 +1580,9 @@ extern int Monitor(struct mddev_dev *devlist,
 
 extern int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl);
 extern int Kill_subarray(char *dev, char *subarray, int verbose);
-extern int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident *ident, int quiet);
+extern int Update_subarray(char *dev, char *subarray, enum update_opt update, struct mddev_ident *ident, int quiet);
 extern int Wait(char *dev);
-extern int WaitClean(char *dev, int sock, int verbose);
+extern int WaitClean(char *dev, int verbose);
 extern int SetAction(char *dev, char *action);
 
 extern int Incremental(struct mddev_dev *devlist, struct context *c,
@@ -1409,6 +1596,7 @@ extern int CreateBitmap(char *filename, int force, char uuid[16],
                        unsigned long long array_size,
                        int major);
 extern int ExamineBitmap(char *filename, int brief, struct supertype *st);
+extern int IsBitmapDirty(char *filename);
 extern int Write_rules(char *rule_name);
 extern int bitmap_update_uuid(int fd, int *uuid, int swap);
 
@@ -1434,10 +1622,11 @@ extern int get_linux_version(void);
 extern int mdadm_version(char *version);
 extern unsigned long long parse_size(char *size);
 extern int parse_uuid(char *str, int uuid[4]);
+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 long parse_num(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);
@@ -1445,11 +1634,15 @@ extern int check_raid(int fd, char *name);
 extern int check_partitions(int fd, char *dname,
                            unsigned long long freesize,
                            unsigned long long size);
+extern bool is_name_posix_compatible(const char *path);
 extern int fstat_is_blkdev(int fd, char *devname, dev_t *rdev);
 extern int stat_is_blkdev(char *devname, dev_t *rdev);
 
+extern bool is_string_lq(const char * const str, size_t max_len);
+extern bool is_dev_alive(char *path);
 extern int get_mdp_major(void);
 extern int get_maj_min(char *dev, int *major, int *minor);
+extern bool is_bit_set(int *val, unsigned char index);
 extern int dev_open(char *dev, int flags);
 extern int open_dev(char *devnm);
 extern void reopen_mddev(int mdfd);
@@ -1459,6 +1652,12 @@ extern int is_standard(char *dev, int *nump);
 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, char *prefix);
+
+extern void ident_init(struct mddev_ident *ident);
+extern mdadm_status_t ident_set_devname(struct mddev_ident *ident, const char *devname);
+extern mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name);
 
 extern int parse_auto(char *str, char *msg, int config);
 extern struct mddev_ident *conf_get_ident(char *dev);
@@ -1472,20 +1671,23 @@ extern char *conf_get_mailfrom(void);
 extern char *conf_get_program(void);
 extern char *conf_get_homehost(int *require_homehostp);
 extern char *conf_get_homecluster(void);
+extern int conf_get_monitor_delay(void);
 extern char *conf_line(FILE *file);
 extern char *conf_word(FILE *file, int allow_key);
 extern void print_quoted(char *str);
-extern void print_escape(char *str);
 extern int use_udev(void);
+extern void print_escape(char *str);
 extern unsigned long GCD(unsigned long a, unsigned long b);
 extern int conf_name_is_free(char *name);
+extern bool is_devname_ignore(const 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,
                                      struct mdinfo *info,
                                      char *devname,
                                      int verbose, int *rvp);
-extern int experimental(void);
 
 extern void free_line(char *line);
 extern int match_oneof(char *devices, char *devname);
@@ -1494,8 +1696,7 @@ extern const int uuid_zero[4];
 extern int same_uuid(int a[4], int b[4], int swapuuid);
 extern void copy_uuid(void *a, int b[4], int swapuuid);
 extern char *__fname_from_uuid(int id[4], int swap, char *buf, char sep);
-extern char *fname_from_uuid(struct supertype *st,
-                            struct mdinfo *info, char *buf, char sep);
+extern char *fname_from_uuid(struct mdinfo *info, char *buf);
 extern unsigned long calc_csum(void *super, int bytes);
 extern int enough(int level, int raid_disks, int layout, int clean,
                   char *avail);
@@ -1517,6 +1718,9 @@ extern int assemble_container_content(struct supertype *st, int mdfd,
 #define        INCR_UNSAFE     2
 #define        INCR_ALREADY    4
 #define        INCR_YES        8
+
+extern bool devid_matches_criteria(struct supertype *st, dev_t devid, struct spare_criteria *sc);
+extern bool disk_fd_matches_criteria(struct supertype *st, int disk_fd, struct spare_criteria *sc);
 extern struct mdinfo *container_choose_spares(struct supertype *st,
                                              struct spare_criteria *criteria,
                                              struct domainlist *domlist,
@@ -1554,6 +1758,7 @@ extern int create_mddev(char *dev, char *name, int autof, int trustworthy,
 #define        FOREIGN 2
 #define        METADATA 3
 extern int open_mddev(char *dev, int report_errors);
+extern int is_mddev(char *dev);
 extern int open_container(int fd);
 extern int metadata_container_matches(char *metadata, char *devnm);
 extern int metadata_subdev_matches(char *metadata, char *devnm);
@@ -1580,9 +1785,8 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0
 extern char *stat2kname(struct stat *st);
 extern char *fd2kname(int fd);
 extern char *stat2devnm(struct stat *st);
+bool stat_is_md_dev(struct stat *st);
 extern char *fd2devnm(int fd);
-extern void udev_block(char *devnm);
-extern void udev_unblock(void);
 
 extern int in_initrd(void);
 
@@ -1604,6 +1808,7 @@ struct dlm_hooks {
 
        dlm_lshandle_t (*create_lockspace)(const char *name,
                                           unsigned int mode);
+       dlm_lshandle_t (*open_lockspace)(const char *name);
        int (*release_lockspace)(const char *name, dlm_lshandle_t ls,
                                 int force);
        int (*ls_lock)(dlm_lshandle_t lockspace, uint32_t mode,
@@ -1612,19 +1817,25 @@ struct dlm_hooks {
                       uint32_t parent, void (*astaddr) (void *astarg),
                       void *astarg, void (*bastaddr) (void *astarg),
                       void *range);
-       int (*ls_unlock)(dlm_lshandle_t lockspace, uint32_t lkid,
-                        uint32_t flags, struct dlm_lksb *lksb,
-                        void *astarg);
+       int (*ls_unlock_wait)(dlm_lshandle_t lockspace, uint32_t lkid,
+                             uint32_t flags, struct dlm_lksb *lksb);
        int (*ls_get_fd)(dlm_lshandle_t ls);
        int (*dispatch)(int fd);
 };
 
 extern int get_cluster_name(char **name);
 extern int dlm_funs_ready(void);
-extern int cluster_get_dlmlock(int *lockid);
-extern int cluster_release_dlmlock(int lockid);
+extern int cluster_get_dlmlock(void);
+extern int cluster_release_dlmlock(void);
 extern void set_dlm_hooks(void);
 
+#define MSEC_TO_NSEC(msec) ((msec) * 1000000)
+#define USEC_TO_NSEC(usec) ((usec) * 1000)
+extern void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt);
+extern bool is_directory(const char *path);
+extern bool is_file(const char *path);
+extern int s_gethostname(char *buf, int buf_len);
+
 #define _ROUND_UP(val, base)   (((val) + (base) - 1) & ~(base - 1))
 #define ROUND_UP(val, base)    _ROUND_UP(val, (typeof(val))(base))
 #define ROUND_UP_PTR(ptr, base)        ((typeof(ptr)) \
@@ -1649,6 +1860,26 @@ static inline char *to_subarray(struct mdstat_ent *ent, char *container)
        return &ent->metadata_version[10+strlen(container)+1];
 }
 
+/**
+ * signal_s() - Wrapper for sigaction() with signal()-like interface.
+ * @sig: The signal to set the signal handler to.
+ * @handler: The signal handler.
+ *
+ * Return: previous handler or SIG_ERR on failure.
+ */
+static inline sighandler_t signal_s(int sig, sighandler_t handler)
+{
+       struct sigaction new_act = {0};
+       struct sigaction old_act = {0};
+
+       new_act.sa_handler = handler;
+
+       if (sigaction(sig, &new_act, &old_act) == 0)
+               return old_act.sa_handler;
+
+       return SIG_ERR;
+}
+
 #ifdef DEBUG
 #define dprintf(fmt, arg...) \
        fprintf(stderr, "%s: %s: "fmt, Name, __func__, ##arg)
@@ -1660,8 +1891,7 @@ static inline char *to_subarray(struct mdstat_ent *ent, char *container)
 #define dprintf_cont(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;
@@ -1679,6 +1909,10 @@ static inline int xasprintf(char **strp, const char *fmt, ...) {
 #endif
 #define cont_err(fmt ...) fprintf(stderr, "       " fmt)
 
+#define pr_info(fmt, args...) printf("%s: "fmt, Name, ##args)
+
+#define pr_vrb(fmt, arg...) ((void)(verbose && pr_err(fmt, ##arg)))
+
 void *xmalloc(size_t len);
 void *xrealloc(void *ptr, size_t len);
 void *xcalloc(size_t num, size_t size);
@@ -1723,6 +1957,11 @@ char *xstrdup(const char *str);
 #define makedev(M,m) (((M)<<8) | (m))
 #endif
 
+enum r0layout {
+       RAID0_ORIG_LAYOUT = 1,
+       RAID0_ALT_MULTIZONE_LAYOUT = 2,
+};
+
 /* for raid4/5/6 */
 #define ALGORITHM_LEFT_ASYMMETRIC      0
 #define ALGORITHM_RIGHT_ASYMMETRIC     1
@@ -1773,7 +2012,8 @@ char *xstrdup(const char *str);
 #define RESYNC_NONE -1
 #define RESYNC_DELAYED -2
 #define RESYNC_PENDING -3
-#define RESYNC_UNKNOWN -4
+#define RESYNC_REMOTE  -4
+#define RESYNC_UNKNOWN -5
 
 /* When using "GET_DISK_INFO" it isn't certain how high
  * we need to check.  So we impose an absolute limit of
@@ -1794,3 +2034,33 @@ char *xstrdup(const char *str);
 #define INVALID_SECTORS 1
 /* And another special number needed for --data_offset=variable */
 #define VARIABLE_OFFSET 3
+
+/**
+ * is_container() - check if @level is &LEVEL_CONTAINER
+ * @level: level value
+ *
+ * return:
+ * 1 if level is equal to &LEVEL_CONTAINER, 0 otherwise.
+ */
+static inline int is_container(const int level)
+{
+       if (level == LEVEL_CONTAINER)
+               return 1;
+       return 0;
+}
+
+#define STR_COMMON_NONE "none"
+
+/**
+ * str_is_none() - check if @str starts with "none".
+ * @str: string
+ *
+ * return:
+ * true if string starts with "none", false otherwise.
+ */
+static inline bool str_is_none(char *str)
+{
+       if (strncmp(str, STR_COMMON_NONE, sizeof(STR_COMMON_NONE) - 1) == 0)
+               return true;
+       return false;
+}