# 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>
#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!! */
#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.
#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"
#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.
#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 {
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;
ARRAY_ACTIVE,
ARRAY_WRITE_PENDING,
ARRAY_ACTIVE_IDLE,
+ ARRAY_BROKEN,
ARRAY_UNKNOWN_STATE,
} array_state;
struct md_bb bb;
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,
};
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[];
*/
enum special_options {
AssumeClean = 300,
+ WriteZeroes,
BitmapChunk,
WriteBehind,
ReAdd,
BackupFile,
HomeHost,
AutoHomeHost,
- Symlinks,
AutoDetect,
Waitclean,
DetailPlatform,
NoSharing,
HelpOptions,
Brief,
+ NoDevices,
ManageOpt,
Add,
AddSpare,
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
int uuid_set;
int uuid[4];
- char name[33];
+ char name[MD_NAME_MAX + 1];
int super_minor;
int runstop;
int verbose;
int brief;
+ int no_devices;
int force;
char *homehost;
int require_homehost;
int export;
int test;
char *subarray;
- char *update;
+ enum update_opt update;
int scan;
int SparcAdjust;
int autof;
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;
};
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);
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.
*/
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);
int source, unsigned long long read_offset,
unsigned long long start, unsigned long long length,
char *src_buf);
+extern bool sysfs_is_libata_allow_tpm_enabled(const int verbose);
#ifndef Sendmail
#define Sendmail "/usr/lib/sendmail -t"
#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);
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;
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
/* 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 */
* 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);
* 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);
* 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
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
*/
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.*/
/* 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
/* 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)
*/
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);
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;
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
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,
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
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);
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);
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 verbose);
extern int SetAction(char *dev, char *action);
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);
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);
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);
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);
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 bool conf_get_sata_opal_encryption_no_verify(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);
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);
#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,
#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);
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);
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)) \
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)
#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;
#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);
#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
#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
#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;
+}