[dm-devel] dmraid ./configure ./configure.in include/dmra ...
heinzm at sourceware.org
heinzm at sourceware.org
Fri Jun 20 21:52:27 UTC 2008
CVSROOT: /cvs/dm
Module name: dmraid
Changes by: heinzm at sourceware.org 2008-06-20 21:52:19
Modified files:
. : configure configure.in
include/dmraid : display.h dmraid.h format.h lib_context.h
list.h locking.h metadata.h misc.h reconfig.h
lib : .export.sym version.h
lib/activate : activate.c devmapper.c
lib/datastruct : byteorder.h
lib/device : ata.c ata.h dev-io.h scan.c scsi.c scsi.h
lib/display : display.c
lib/format : format.c register.h
lib/format/ataraid: asr.c asr.h hpt37x.c hpt37x.h hpt45x.c
hpt45x.h isw.c isw.h jm.c jm.h lsi.c lsi.h
nv.c nv.h pdc.c pdc.h sil.c sil.h via.c
via.h
lib/format/ddf : ddf1.c ddf1.h ddf1_crc.c ddf1_cvt.c ddf1_cvt.h
ddf1_dump.c ddf1_lib.c ddf1_lib.h
lib/format/partition: dos.c dos.h
lib/format/template: template.c template.h
lib/locking : locking.c
lib/log : log.c
lib/metadata : log_ops.c metadata.c reconfig.c
lib/misc : file.c init.c lib_context.c misc.c workaround.c
lib/mm : dbg_malloc.c
man : dmraid.8
tools : VERSION commands.c commands.h dmraid.c
toollib.c toollib.h
Log message:
Intel Software RAID create/delete/spare/rebuild support
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/configure.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/configure.in.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/include/dmraid/display.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/include/dmraid/dmraid.h.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/include/dmraid/format.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/include/dmraid/lib_context.h.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/include/dmraid/list.h.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/include/dmraid/locking.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/include/dmraid/metadata.h.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/include/dmraid/misc.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/include/dmraid/reconfig.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/.export.sym.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/version.h.diff?cvsroot=dm&r1=1.5&r2=1.6
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/activate/activate.c.diff?cvsroot=dm&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/activate/devmapper.c.diff?cvsroot=dm&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/datastruct/byteorder.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/device/ata.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/device/ata.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/device/dev-io.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/device/scan.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/device/scsi.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/device/scsi.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/display/display.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/format.c.diff?cvsroot=dm&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/register.h.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/asr.c.diff?cvsroot=dm&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/asr.h.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/hpt37x.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/hpt37x.h.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/hpt45x.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/hpt45x.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/isw.c.diff?cvsroot=dm&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/isw.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/jm.c.diff?cvsroot=dm&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/jm.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/lsi.c.diff?cvsroot=dm&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/lsi.h.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/nv.c.diff?cvsroot=dm&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/nv.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/pdc.c.diff?cvsroot=dm&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/pdc.h.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/sil.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/sil.h.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/via.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/via.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ddf/ddf1.c.diff?cvsroot=dm&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ddf/ddf1.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ddf/ddf1_crc.c.diff?cvsroot=dm&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ddf/ddf1_cvt.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ddf/ddf1_cvt.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ddf/ddf1_dump.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ddf/ddf1_lib.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ddf/ddf1_lib.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/partition/dos.c.diff?cvsroot=dm&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/partition/dos.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/template/template.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/template/template.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/locking/locking.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/log/log.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/metadata/log_ops.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/metadata/metadata.c.diff?cvsroot=dm&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/metadata/reconfig.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/misc/file.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/misc/init.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/misc/lib_context.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/misc/misc.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/misc/workaround.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/mm/dbg_malloc.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/man/dmraid.8.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/tools/VERSION.diff?cvsroot=dm&r1=1.5&r2=1.6
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/tools/commands.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/tools/commands.h.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/tools/dmraid.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/tools/toollib.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/tools/toollib.h.diff?cvsroot=dm&r1=1.1&r2=1.2
--- dmraid/configure 2008/02/22 16:50:38 1.1
+++ dmraid/configure 2008/06/20 21:52:15 1.2
@@ -854,8 +854,10 @@
--enable-jobs=NUM Number of jobs to run simultaneously
--enable-libselinux Use this to link the tools to libselinux
--enable-libsepol Use this to link the tools to libsepol
- --enable-mini Use this to create a minimal binrary suitable
+ --enable-mini Use this to create a minimal binary suitable
for early boot environments
+ --enable-led Use this to enable LED support
+ --enable-intel_led Use this to enable Intel LED support
--disable-native_log Disable native metadata logging. Default is enabled
--enable-static_link Use this to link the tools to the dmraid and devmapper
libraries statically. Default is dynamic linking
@@ -4513,6 +4515,22 @@
DMRAID_MINI=no
fi;
+# Check whether --enable-led or --disable-led was given.
+if test "${enable_led+set}" = set; then
+ enableval="$enable_led"
+ DMRAID_LED=$enableval
+else
+ DMRAID_LED=no
+fi;
+
+# Check whether --enable-intel_led or --disable-intel_led was given.
+if test "${enable_intel_led+set}" = set; then
+ enableval="$enable_intel_led"
+ DMRAID_INTEL_LED=$enableval
+else
+ DMRAID_INTEL_LED=no
+fi;
+
echo $ac_n "checking whether to disable native metadata logging""... $ac_c" 1>&6
# Check whether --enable-native_log or --disable-native_log was given.
if test "${enable_native_log+set}" = set; then
@@ -4577,6 +4595,14 @@
fi
fi
+if test x$DMRAID_LED = xyes; then
+ CFLAGS="$CFLAGS -DDMRAID_LED"
+fi
+
+if test x$DMRAID_INTEL_LED = xyes; then
+ CFLAGS="$CFLAGS -DDMRAID_LED -DDMRAID_INTEL_LED"
+fi
+
if test x$DEBUG = xyes; then
FLAVOUR="${FLAVOUR}debug "
fi
--- dmraid/configure.in 2008/02/22 16:50:38 1.1
+++ dmraid/configure.in 2008/06/20 21:52:15 1.2
@@ -107,9 +107,15 @@
AC_ARG_ENABLE(libsepol, [ --enable-libsepol Use this to link the tools to libsepol ], LIBSEPOL=$enableval, LIBSEPOL=no)
dnl Enables mini binary
-AC_ARG_ENABLE(mini, [ --enable-mini Use this to create a minimal binrary suitable
+AC_ARG_ENABLE(mini, [ --enable-mini Use this to create a minimal binary suitable
for early boot environments], DMRAID_MINI=$enableval, DMRAID_MINI=no)
+dnl Enables LED support
+AC_ARG_ENABLE(led, [ --enable-led Use this to enable LED support], DMRAID_LED=$enableval, DMRAID_LED=no)
+
+dnl Enables Intel LED support
+AC_ARG_ENABLE(intel_led, [ --enable-intel_led Use this to enable Intel LED support], DMRAID_INTEL_LED=$enableval, DMRAID_INTEL_LED=no)
+
echo $ac_n "checking whether to disable native metadata logging""... $ac_c" 1>&6
dnl Disable native metadata logging
AC_ARG_ENABLE(native_log, [ --disable-native_log Disable native metadata logging. Default is enabled], \
@@ -155,6 +161,14 @@
fi
fi
+if test x$DMRAID_LED = xyes; then
+ CFLAGS="$CFLAGS -DDMRAID_LED"
+fi
+
+if test x$DMRAID_INTEL_LED = xyes; then
+ CFLAGS="$CFLAGS -DDMRAID_LED -DDMRAID_INTEL_LED"
+fi
+
if test x$DEBUG = xyes; then
FLAVOUR="${FLAVOUR}debug "
fi
--- dmraid/include/dmraid/display.h 2008/02/22 16:57:35 1.1
+++ dmraid/include/dmraid/display.h 2008/06/20 21:52:16 1.2
@@ -9,15 +9,15 @@
#define _DISPLAY_H_
enum dev_type {
- DEVICE = 0x01, /* ALL devices */
- RAID = 0x02, /* RAID devices */
- NATIVE = 0x04, /* Native metadata of RAID devices */
- SET = 0x08, /* RAID sets */
+ DEVICE = 0x01, /* ALL devices */
+ RAID = 0x02, /* RAID devices */
+ NATIVE = 0x04, /* Native metadata of RAID devices */
+ SET = 0x08, /* RAID sets */
};
enum active_type {
- D_ALL = 0x01, /* All devices */
- D_ACTIVE = 0x02, /* Active devices only */
+ D_ALL = 0x01, /* All devices */
+ D_ACTIVE = 0x02, /* Active devices only */
D_INACTIVE = 0x04, /* Inactive devices only */
};
--- dmraid/include/dmraid/dmraid.h 2008/02/22 17:04:35 1.2
+++ dmraid/include/dmraid/dmraid.h 2008/06/20 21:52:16 1.3
@@ -1,7 +1,10 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
@@ -56,7 +59,7 @@
*/
extern const char *get_set_type(struct lib_context *lc, void *rs);
extern const char *get_set_name(struct lib_context *lc, void *rs);
-extern int group_set(struct lib_context *lc, char *name);
+extern int group_set(struct lib_context *lc, char **name);
extern char *libdmraid_make_table(struct lib_context *lc, struct raid_set *rs);
enum activate_type {
@@ -65,8 +68,8 @@
};
extern void process_sets(struct lib_context *lc,
- int (*func)(struct lib_context *lc, void *rs, int arg),
- int arg, enum set_type type);
+ int (*func) (struct lib_context * lc, void *rs,
+ int arg), int arg, enum set_type type);
extern int change_set(struct lib_context *lc, enum activate_type what,
void *rs);
--- dmraid/include/dmraid/format.h 2008/02/22 16:57:35 1.1
+++ dmraid/include/dmraid/format.h 2008/06/20 21:52:16 1.2
@@ -1,6 +1,9 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
+ *
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
*
* See file LICENSE at the top of this source tree for license information.
*/
@@ -40,7 +43,7 @@
struct event_rd {
struct raid_set *rs;
struct raid_dev *rd;
- enum rd_action action;
+ enum rd_action action;
};
/*
@@ -51,10 +54,46 @@
*/
struct event_handlers {
/* Handle IO error */
- int (*io)(struct lib_context *lc, struct event_io *e_io);
+ int (*io) (struct lib_context * lc, struct event_io * e_io);
/* Handle RAID device add/remove. */
- int (*rd)(struct lib_context *lc, struct event_rd *e_rd);
+ int (*rd) (struct lib_context * lc, struct event_rd * e_rd);
+};
+
+/*
+ * Hot-spare search types list: it can be searched locally/globally
+ */
+enum scope {
+ t_scope_local = 0x01,
+ t_scope_global = 0x02
+};
+
+/* Metadata Handler commands */
+enum handler_commands {
+ UPDATE_REBUILD_STATE,
+ GET_REBUILD_STATE,
+ GET_REBUILD_DRIVE,
+ GET_REBUILD_DRIVE_NO,
+ CHECK_HOT_SPARE,
+ /* ... */
+};
+
+/* Union to return metadata_handler information. */
+struct handler_info {
+ unsigned short size;
+
+ union {
+ char *str;
+ void *ptr;
+ int8_t i8;
+ int16_t i16;
+ int32_t i32;
+ int64_t i64;
+ uint8_t u8;
+ uint16_t u16;
+ uint32_t u32;
+ uint64_t u64;
+ } data;
};
/*
@@ -69,33 +108,54 @@
/*
* Read RAID metadata off a device and unify it.
*/
- struct raid_dev* (*read)(struct lib_context *lc, struct dev_info* di);
+ struct raid_dev *(*read) (struct lib_context * lc,
+ struct dev_info * di);
/*
* Write RAID metadata to a device deunifying it
* or erase ondisk metadata if erase != 0.
*/
- int (*write)(struct lib_context *lc, struct raid_dev* rd, int erase);
+ int (*write) (struct lib_context * lc, struct raid_dev * rd, int erase);
+
+ /*
+ * delete RAID metadata to devices.
+ */
+ int (*delete) (struct lib_context * lc, struct raid_set * rs);
+
+ /*
+ * create RAID metadata to devices.
+ */
+ int (*create) (struct lib_context * lc, struct raid_set * rs);
/*
* Group a RAID device into a set.
*/
- struct raid_set* (*group)(struct lib_context *lc, struct raid_dev *rd);
+ struct raid_set *(*group) (struct lib_context * lc,
+ struct raid_dev * rd);
/*
* Check consistency of the RAID set metadata.
*/
- int (*check)(struct lib_context *lc, struct raid_set *rs);
+ int (*check) (struct lib_context * lc, struct raid_set * rs);
+
+ /* Metadata handler. */
+ int (*metadata_handler) (struct lib_context * lc,
+ enum handler_commands command,
+ struct handler_info * info, void *ptr);
/*
* Event handlers (eg, I/O error).
*/
struct event_handlers *events;
+ /*
+ * Hot-spare disk search scope
+ */
+ enum scope scope;
/*
* Display RAID disk metadata native.
*/
- void (*log)(struct lib_context *lc, struct raid_dev *rd);
+ void (*log) (struct lib_context * lc, struct raid_dev * rd);
};
/* Chain of registered format handlers (needed for library context). */
@@ -113,14 +173,13 @@
*/
#define NO_CHECK_RD NULL
extern int check_raid_set(struct lib_context *lc, struct raid_set *rs,
- unsigned int (*f_devices)(struct raid_dev *rd,
- void *context),
+ unsigned int (*f_devices) (struct raid_dev * rd,
+ void *context),
void *f_devices_context,
- int (*f_check)(struct lib_context *lc,
- struct raid_set *rs,
- struct raid_dev *rd, void *context),
- void *f_check_context,
- const char *handler);
+ int (*f_check) (struct lib_context * lc,
+ struct raid_set * rs,
+ struct raid_dev * rd, void *context),
+ void *f_check_context, const char *handler);
extern int check_valid_format(struct lib_context *lc, char *fmt);
extern int init_raid_set(struct lib_context *lc, struct raid_set *rs,
struct raid_dev *rd, unsigned int stride,
@@ -135,22 +194,29 @@
uint64_t u64;
};
-struct raid_dev *read_raid_dev(
- struct lib_context *lc,
- struct dev_info *di,
- void* (*f_read_metadata)(struct lib_context *lc, struct dev_info *di,
- size_t *size, uint64_t *offset,
- union read_info *info),
- size_t size, uint64_t offset,
- void (*f_to_cpu)(void *meta),
- int (*f_is_meta)(struct lib_context *lc, struct dev_info *di,
- void *meta),
- void (*f_file_metadata)(struct lib_context *lc, struct dev_info *di,
- void *meta),
- int (*f_setup_rd)(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta,
- union read_info *info),
- const char *handler);
+struct raid_dev *read_raid_dev(struct lib_context *lc,
+ struct dev_info *di,
+ void *(*f_read_metadata) (struct lib_context *
+ lc,
+ struct dev_info * di,
+ size_t * size,
+ uint64_t * offset,
+ union read_info *
+ info), size_t size,
+ uint64_t offset, void (*f_to_cpu) (void *meta),
+ int (*f_is_meta) (struct lib_context * lc,
+ struct dev_info * di,
+ void *meta),
+ void (*f_file_metadata) (struct lib_context *
+ lc,
+ struct dev_info * di,
+ void *meta),
+ int (*f_setup_rd) (struct lib_context * lc,
+ struct raid_dev * rd,
+ struct dev_info * di,
+ void *meta,
+ union read_info * info),
+ const char *handler);
extern void *alloc_meta_areas(struct lib_context *lc, struct raid_dev *rd,
const char *who, unsigned int n);
@@ -158,14 +224,17 @@
size_t size);
extern void *alloc_private_and_read(struct lib_context *lc, const char *who,
size_t size, char *path, loff_t offset);
-extern struct raid_set *join_superset(
- struct lib_context *lc,
- char *(*f_name)(struct lib_context *lc, struct raid_dev *rd,
- unsigned int subset),
- void (*f_create)(struct raid_set *super, void *private),
- int (*f_set_sort)(struct list_head *pos, struct list_head *new),
- struct raid_set *rs, struct raid_dev *rd
-);
+extern struct raid_set *join_superset(struct lib_context *lc,
+ char *(*f_name) (struct lib_context * lc,
+ struct raid_dev * rd,
+ unsigned int subset),
+ void (*f_create) (struct raid_set *
+ super, void *private),
+ int (*f_set_sort) (struct list_head *
+ pos,
+ struct list_head *
+ new),
+ struct raid_set *rs, struct raid_dev *rd);
extern int register_format_handler(struct lib_context *lc,
struct dmraid_format *fmt);
extern int write_metadata(struct lib_context *lc, const char *handler,
@@ -175,7 +244,7 @@
#define to_disk to_cpu
-#define struct_offset(s, member) ((unsigned short) &((struct s *) 0)->member)
+#define struct_offset(s, member) ((size_t) &((struct s *) 0)->member)
/* Print macros used in log methods. */
--- dmraid/include/dmraid/lib_context.h 2008/04/02 13:35:31 1.2
+++ dmraid/include/dmraid/lib_context.h 2008/06/20 21:52:16 1.3
@@ -1,7 +1,10 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
@@ -13,12 +16,12 @@
#include <dmraid/misc.h>
enum lc_lists {
- LC_FORMATS = 0, /* Metadata format handlers. */
- LC_DISK_INFOS, /* Disks discovered. */
- LC_RAID_DEVS, /* Raid devices discovered. */
- LC_RAID_SETS, /* Raid sets grouped. */
+ LC_FORMATS = 0, /* Metadata format handlers. */
+ LC_DISK_INFOS, /* Disks discovered. */
+ LC_RAID_DEVS, /* Raid devices discovered. */
+ LC_RAID_SETS, /* Raid sets grouped. */
/* Add new lists below here ! */
- LC_LISTS_SIZE, /* Must be the last enumerator. */
+ LC_LISTS_SIZE, /* Must be the last enumerator. */
};
/* List access macros. */
@@ -39,8 +42,12 @@
LC_IGNORELOCKING,
LC_SEPARATOR,
LC_DEVICES,
- LC_PARTCHAR, /* Add new options below this one ! */
- LC_OPTIONS_SIZE, /* Must be the last enumerator. */
+ LC_PARTCHAR,
+ LC_CREATE,
+ LC_REBUILD_SET,
+ LC_REBUILD_DISK,
+ LC_HOT_SPARE_SET, /* Add new options below this one ! */
+ LC_OPTIONS_SIZE, /* Must be the last enumerator. */
};
/* Options access macros. */
@@ -57,6 +64,9 @@
#define OPT_TEST(lc) (lc_opt(lc, LC_TEST))
#define OPT_VERBOSE(lc) (lc_opt(lc, LC_VERBOSE))
#define OPT_PARTCHAR(lc) (lc_opt(lc, LC_PARTCHAR))
+#define OPT_CREATE(lc) (lc_opt(lc, LC_CREATE))
+#define OPT_HOT_SPARE_SET(lc) (lc_opt(lc, LC_HOT_SPARE_SET))
+#define OPT_REBUILD_DISK(lc) (lc_opt(lc, LC_REBUILD_DISK))
/* Return option value. */
#define OPT_STR(lc, o) (lc->options[o].arg.str)
@@ -64,6 +74,8 @@
#define OPT_STR_FORMAT(lc) OPT_STR(lc, LC_FORMAT)
#define OPT_STR_SEPARATOR(lc) OPT_STR(lc, LC_SEPARATOR)
#define OPT_STR_PARTCHAR(lc) OPT_STR(lc, LC_PARTCHAR)
+#define OPT_STR_HOT_SPARE_SET(lc) OPT_STR(lc, LC_HOT_SPARE_SET)
+#define OPT_STR_REBUILD_DISK(lc) OPT_STR(lc, LC_REBUILD_DISK)
struct lib_version {
const char *text;
@@ -95,29 +107,116 @@
/*
* Lists for:
*
- * o metadata format handlers the library supports
- * o block devices discovered
- * o RAID devices discovered
- * o RAID sets grouped
+ * o metadata format handlers the library supports
+ * o block devices discovered
+ * o RAID devices discovered
+ * o RAID sets grouped
*/
struct list_head lists[LC_LISTS_SIZE];
- char *locking_name; /* Locking mechanism selector. */
- struct locking *lock; /* Resource locking. */
+ char *locking_name; /* Locking mechanism selector. */
+ struct locking *lock; /* Resource locking. */
- mode_t mode; /* File/directrory create modes. */
+ mode_t mode; /* File/directrory create modes. */
struct {
const char *error; /* For error mappings. */
} path;
};
+
+/* Options actions dmraid performs. */
+enum action {
+ UNDEF = 0x0,
+ ACTIVATE = 0x1,
+ DEACTIVATE = 0x2,
+ FORMAT = 0x4,
+#ifndef DMRAID_MINI
+ BLOCK_DEVICES = 0x8,
+ COLUMN = 0x10,
+ DBG = 0x20,
+ DUMP = 0x40,
+ DMERASE = 0x80,
+ GROUP = 0x100,
+#endif
+ HELP = 0x200,
+#ifndef DMRAID_MINI
+ LIST_FORMATS = 0x400,
+# ifdef DMRAID_NATIVE_LOG
+ NATIVE_LOG = 0x800,
+# endif
+#endif
+ NOPARTITIONS = 0x1000,
+#ifndef DMRAID_MINI
+ RAID_DEVICES = 0x2000,
+ RAID_SETS = 0x4000,
+ TEST = 0x8000,
+ VERBOSE = 0x10000,
+ ACTIVE = 0x20000,
+ INACTIVE = 0x40000,
+ SEPARATOR = 0x80000,
+#endif
+ VERSION = 0x100000,
+ IGNORELOCKING = 0x200000,
+#ifndef DMRAID_MINI
+ DEL_SETS = 0x400000,
+ CREATE = 0x800000,
+ REBUILD = 0x1000000,
+ SPARE = 0x2000000,
+ MEDIA = 0x4000000,
+ END_REBUILD = 0x8000000,
+ GET_MEMBERS = 0x10000000,
+ PARTCHAR = 0x20000000,
+
+#endif
+};
+
+/* Arguments allowed ? */
+enum args {
+ NO_ARGS,
+ ARGS,
+};
+
+/* Define which metadata is needed before we can call post functions. */
+enum metadata_need {
+ M_NONE = 0x00,
+ M_DEVICE = 0x01,
+ M_RAID = 0x02,
+ M_SET = 0x04,
+};
+
+enum id {
+ ROOT,
+ ANY_ID,
+};
+
+enum lock {
+ LOCK,
+ NO_LOCK,
+};
+
+/*
+ * Pre and Post functions to perform for an option.
+ */
+struct prepost {
+ enum action action;
+ enum metadata_need metadata;
+ enum id id;
+ enum lock lock;
+ int (*pre) (int arg);
+ int arg;
+ int (*post) (struct lib_context * lc, int arg);
+};
+
+
+
+
extern struct lib_context *alloc_lib_context(char **argv);
extern void free_lib_context(struct lib_context *lc);
extern int lc_opt(struct lib_context *lc, enum lc_options o);
const char *lc_opt_arg(struct lib_context *lc, enum lc_options o);
const char *lc_stralloc_opt(struct lib_context *lc, enum lc_options o,
- char *arg);
+ char *arg);
const char *lc_strcat_opt(struct lib_context *lc, enum lc_options o,
char *arg, const char delim);
extern int lc_inc_opt(struct lib_context *lc, int o);
--- dmraid/include/dmraid/list.h 2008/02/22 17:04:35 1.2
+++ dmraid/include/dmraid/list.h 2008/06/20 21:52:16 1.3
@@ -1,7 +1,10 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
@@ -23,9 +26,9 @@
#define list_empty(pos) ((pos)->next == pos)
-static inline void __list_add(struct list_head *new,
- struct list_head *prev,
- struct list_head *next)
+static inline void
+__list_add(struct list_head *new,
+ struct list_head *prev, struct list_head *next)
{
next->prev = new;
new->next = next;
@@ -74,4 +77,10 @@
pos != (head); \
pos = n, n = pos->next)
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member),\
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+pos = n, n = list_entry(pos->member.next, typeof(*pos), member))
+
#endif
--- dmraid/include/dmraid/locking.h 2008/02/22 16:57:35 1.1
+++ dmraid/include/dmraid/locking.h 2008/06/20 21:52:16 1.2
@@ -17,9 +17,9 @@
struct lib_context;
struct locking {
const char *name;
- int (*lock)(struct lib_context *lc, struct resource *res);
- void (*unlock)(struct lib_context *lc, struct resource *res);
- void *private; /* Private context. */
+ int (*lock) (struct lib_context * lc, struct resource * res);
+ void (*unlock) (struct lib_context * lc, struct resource * res);
+ void *private; /* Private context. */
};
extern int init_locking(struct lib_context *lc);
--- dmraid/include/dmraid/metadata.h 2008/02/22 17:04:35 1.2
+++ dmraid/include/dmraid/metadata.h 2008/06/20 21:52:16 1.3
@@ -1,7 +1,10 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
@@ -15,23 +18,23 @@
* Unified RAID set types.
*/
enum type {
- t_undef = 0x01,
- t_group = 0x02, /* To group subsets (eg, Intel Software RAID). */
- t_partition = 0x04, /* FIXME: remove in favour of kpartx ? */
- t_spare = 0x08,
- t_linear = 0x10,
- t_raid0 = 0x20,
- t_raid1 = 0x40,
+ t_undef = 0x01,
+ t_group = 0x02, /* To group subsets (eg, Intel Software RAID). */
+ t_partition = 0x04, /* FIXME: remove in favour of kpartx ? */
+ t_spare = 0x08,
+ t_linear = 0x10,
+ t_raid0 = 0x20,
+ t_raid1 = 0x40,
/*
* Higher RAID types below not supported (yet)
* because of device-mapper constraints.
*/
- t_raid4 = 0x80,
- t_raid5_ls = 0x100,
- t_raid5_rs = 0x200,
- t_raid5_la = 0x400,
- t_raid5_ra = 0x800,
- t_raid6 = 0x1000,
+ t_raid4 = 0x80,
+ t_raid5_ls = 0x100,
+ t_raid5_rs = 0x200,
+ t_raid5_la = 0x400,
+ t_raid5_ra = 0x800,
+ t_raid6 = 0x1000,
};
/* Check macros for types. */
@@ -64,21 +67,23 @@
* from format specific types to the unified ones above.
*/
struct types {
- unsigned int type; /* Must be long enough for vendor definition. */
- enum type unified_type;
+ unsigned int type; /* Must be long enough for vendor definition. */
+ enum type unified_type;
};
/* RAID disk/set status. */
enum status {
- s_undef = 0x01,
- s_broken = 0x02, /* Completely broken (not accessible). */
- s_inconsistent = 0x04, /* RAID disk/set inconsistent (needs
+ s_undef = 0x01,
+ s_broken = 0x02, /* Completely broken (not accessible). */
+ s_inconsistent = 0x04, /* RAID disk/set inconsistent (needs
synchronization or reconfiguration). */
/* FIXME: is s_nosync sufficient or do I need s_upgrade (eg, NVidia) */
- s_nosync = 0x08, /* RAID disk/set *not* in sync
+ s_nosync = 0x08, /* RAID disk/set *not* in sync
(needs synchronization). */
- s_ok = 0x10, /* Fully operational. */
- s_setup = 0x20, /* Only during RAID setup transition. */
+ s_ok = 0x10, /* Fully operational. */
+ s_setup = 0x20, /* Only during RAID setup transition. */
+ s_init = 0x40, /* RAID set to be created */
+ s_config = 0x80, /* RAID set hasn't been configured */
};
/*
@@ -104,24 +109,24 @@
/* find_*() function enums */
enum find {
- FIND_TOP, /* Search top level RAID sets only. */
- FIND_ALL, /* Decend all RAID set trees. */
+ FIND_TOP, /* Search top level RAID sets only. */
+ FIND_ALL, /* Decend all RAID set trees. */
};
/* Device information. */
struct dev_info {
struct list_head list; /* Global chain of discovered devices. */
- char *path; /* Actual device node path. */
- char *serial; /* ATA/SCSI serial number. */
- uint64_t sectors; /* Device size. */
+ char *path; /* Actual device node path. */
+ char *serial; /* ATA/SCSI serial number. */
+ uint64_t sectors; /* Device size. */
};
/* Metadata areas and size stored on a RAID device. */
struct meta_areas {
- uint64_t offset; /* on disk metadata offset in sectors. */
- size_t size; /* on disk metadata size in bytes. */
- void *area; /* pointer to format specific metadata. */
+ uint64_t offset; /* on disk metadata offset in sectors. */
+ size_t size; /* on disk metadata size in bytes. */
+ void *area; /* pointer to format specific metadata. */
};
/*
@@ -131,29 +136,29 @@
* exist at the lowest level of a RAID set stack (eg, for RAID10).
*/
struct raid_dev {
- struct list_head list; /* Global chain of RAID devices. */
- struct list_head devs; /* Chain of devices belonging to set. */
+ struct list_head list; /* Global chain of RAID devices. */
+ struct list_head devs; /* Chain of devices belonging to set. */
- char *name; /* Metadata format handler generated
- name of set this device belongs to.*/
+ char *name; /* Metadata format handler generated
+ name of set this device belongs to. */
- struct dev_info *di; /* Pointer to dev_info. */
+ struct dev_info *di; /* Pointer to dev_info. */
struct dmraid_format *fmt; /* Format handler for this device. */
- enum status status; /* Status of device. */
- enum type type; /* Type of device. */
+ enum status status; /* Status of device. */
+ enum type type; /* Type of device. */
- uint64_t offset; /* Data offset on device. */
- uint64_t sectors; /* Length of the segment to map. */
+ uint64_t offset; /* Data offset on device. */
+ uint64_t sectors; /* Length of the segment to map. */
- unsigned int areas; /* # of metadata areas on the device. */
+ unsigned int areas; /* # of metadata areas on the device. */
struct meta_areas *meta_areas; /* Dynamic array of metadata areas. */
/*
* For format handler use (eg, to keep references between calls).
*
* WARNING: non pointer members need to get zeroed before exit,
- * because the metadata layer frees private->ptr on cleanup.
+ * because the metadata layer frees private->ptr on cleanup.
*/
union {
void *ptr;
@@ -169,16 +174,16 @@
* Defines RAID attributes for the set as a whole (eg: RAID0, Status).
*/
enum flags {
- f_maximize = 0x01, /* If set, maximize set capacity,
+ f_maximize = 0x01, /* If set, maximize set capacity,
if not set, limit to smallest device. */
- f_partitions = 0x02, /* Set has partitions. */
+ f_partitions = 0x02, /* Set has partitions. */
};
#define F_MAXIMIZE(rs) ((rs)->flags & f_maximize)
#define F_PARTITIONS(rs) ((rs)->flags & f_partitions)
struct raid_set {
- struct list_head list; /* Chain of independent sets. */
+ struct list_head list; /* Chain of independent sets. */
/*
* List of subsets (eg, RAID10) which make up RAID set stacks.
@@ -199,12 +204,13 @@
unsigned int total_devs; /* The number of devices expected */
unsigned int found_devs; /* The number of devices found */
- char *name; /* Name of the set. */
+ char *name; /* Name of the set. */
- unsigned int stride; /* Stride size. */
- enum type type; /* Unified raid type. */
- enum flags flags; /* Set flags. */
- enum status status; /* Status of set. */
+ uint64_t size; /* size of a raid set */
+ unsigned int stride; /* Stride size. */
+ enum type type; /* Unified raid type. */
+ enum flags flags; /* Set flags. */
+ enum status status; /* Status of set. */
};
extern struct raid_set *get_raid_set(struct lib_context *lc,
@@ -220,29 +226,31 @@
extern struct raid_dev *alloc_raid_dev(struct lib_context *lc, const char *who);
extern void free_raid_dev(struct lib_context *lc, struct raid_dev **rd);
extern void list_add_sorted(struct lib_context *lc,
- struct list_head *to, struct list_head *new,
- int (*sort)(struct list_head *pos,
- struct list_head *new));
+ struct list_head *to, struct list_head *new,
+ int (*sort) (struct list_head * pos,
+ struct list_head * new));
extern struct raid_set *alloc_raid_set(struct lib_context *lc, const char *who);
extern unsigned int count_sets(struct lib_context *lc, struct list_head *list);
extern unsigned int count_devs(struct lib_context *lc, struct raid_set *rs,
- enum count_type type);
+ enum count_type type);
extern void free_raid_set(struct lib_context *lc, struct raid_set *rs);
-extern struct raid_set *find_set(struct lib_context *lc, struct list_head *list,
- const char *name, enum find where);
+extern struct raid_set *find_set(struct lib_context *lc,
+ struct list_head *list, const char *name,
+ enum find where);
extern struct raid_set *find_or_alloc_raid_set(struct lib_context *lc,
- char *name, enum find where,
- struct raid_dev *rd,
- struct list_head *list,
- void (*create) (struct raid_set *super,
- void *private),
- void *private);
+ char *name, enum find where,
+ struct raid_dev *rd,
+ struct list_head *list,
+ void (*create) (struct raid_set
+ * super,
+ void *private),
+ void *private);
#define NO_RD NULL
#define NO_LIST NULL
#define NO_CREATE NULL
#define NO_CREATE_ARG NULL
extern const char *get_set_name(struct lib_context *lc, void *rs);
-extern int group_set(struct lib_context *lc, char *name);
+extern int group_set(struct lib_context *lc, char **name);
enum set_type {
SETS,
@@ -250,8 +258,8 @@
};
extern void process_sets(struct lib_context *lc,
- int (*func)(struct lib_context *lc, void *rs, int arg),
- int arg, enum set_type type);
+ int (*func) (struct lib_context * lc, void *rs,
+ int arg), int arg, enum set_type type);
extern int write_set(struct lib_context *lc, void *rs);
extern int partitioned_set(struct lib_context *lc, void *rs);
extern int base_partitioned_set(struct lib_context *lc, void *rs);
@@ -262,10 +270,12 @@
enum compare cmp);
extern enum type rd_type(struct types *types, unsigned int type);
extern void file_metadata(struct lib_context *lc, const char *handler,
- char *path, void *data, size_t size, uint64_t offset);
+ char *path, void *data, size_t size, uint64_t offset);
extern void file_dev_size(struct lib_context *lc, const char *handler,
- struct dev_info *di);
+ struct dev_info *di);
extern int write_dev(struct lib_context *lc, struct raid_dev *rd, int erase);
extern int erase_metadata(struct lib_context *lc);
-
+extern int delete_raidsets(struct lib_context *lc);
+extern int lib_perform(struct lib_context *lc, enum action action,
+ struct prepost *p, char **argv);
#endif
--- dmraid/include/dmraid/misc.h 2008/02/22 16:57:35 1.1
+++ dmraid/include/dmraid/misc.h 2008/06/20 21:52:16 1.2
@@ -1,13 +1,18 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2005 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
#ifndef _MISC_H_
#define _MISC_H_
+#define DM_ASSERT(__cond) do { if (!(__cond)) { printf("ASSERT file:%s line:%d fuction:%s cond: %s\n", __FILE__, __LINE__, __FUNCTION__, #__cond); } } while(0);
+
extern struct lib_context *libdmraid_init(int argc, char **argv);
extern void libdmraid_exit(struct lib_context *lc);
@@ -16,8 +21,10 @@
extern char *get_basename(struct lib_context *lc, char *str);
extern char *get_dirname(struct lib_context *lc, char *str);
extern char *remove_white_space(struct lib_context *lc, char *str, size_t len);
+extern void remove_tail_space(char *str);
extern char *remove_delimiter(char *ptr, char c);
extern void add_delimiter(char **ptr, char c);
+extern char *replace_delimiter(char *str, char delim, char c);
extern int mk_dir(struct lib_context *lc, const char *dir);
@@ -31,21 +38,33 @@
extern void free_string(struct lib_context *lc, char **string);
extern int p_fmt(struct lib_context *lc, char **string, const char *fmt, ...);
-static inline uint64_t round_down(uint64_t what, unsigned int by)
+static inline uint64_t
+round_down(uint64_t what, unsigned int by)
{
return what & ~((uint64_t) by - 1);
}
-static inline uint64_t round_up(uint64_t what, unsigned int by)
+static inline uint64_t
+round_up(uint64_t what, unsigned int by)
{
uint64_t t = round_down(what, by);
return t == what ? t : t + by;
}
-static inline uint64_t div_up(uint64_t what, unsigned int by)
+static inline uint64_t
+div_up(uint64_t what, unsigned int by)
{
return round_up(what, by) / by;
}
+
+#ifdef DMRAID_LED
+/* Definitions for LED support */
+#define LED_OFF 0
+#define LED_REBUILD 1
+
+int led(char *rd, int status);
+#endif
+
#endif
--- dmraid/include/dmraid/reconfig.h 2008/02/22 17:04:35 1.1
+++ dmraid/include/dmraid/reconfig.h 2008/06/20 21:52:16 1.2
@@ -2,8 +2,8 @@
* Copyright (C) 2006 Darrick Wong, IBM.
* All rights reserved.
*
- * Copyright (C) 2006 Heinz Mauelshagen Red Hat GmbH.
- * All rights reserved.
+ * Copyright (C) 2006-2008 Heinz Mauelshagen Red Hat GmbH.
+ * All rights reserved.
*
* See the file LICENSE at the top of this source tree for license information.
*/
@@ -50,5 +50,9 @@
struct raid_dev *rd);
extern void end_log(struct lib_context *lc, struct list_head *log);
extern int revert_log(struct lib_context *lc, struct list_head *log);
+extern int hot_spare_add(struct lib_context *lc, struct raid_set *rs);
+extern struct raid_set *find_group(struct lib_context *lc,
+ struct raid_set *sub_rs);
+extern int rebuild_raidset(struct lib_context *lc, char *set_name);
#endif
--- dmraid/lib/.export.sym 2008/02/22 16:57:35 1.1
+++ dmraid/lib/.export.sym 2008/06/20 21:52:16 1.2
@@ -1,51 +1,58 @@
-Base {
- global:
- add_delimiter;
- change_set;
- check_valid_format;
- collapse_delimiter;
- count_devices;
- count_devs;
- count_sets;
- _dbg_free;
- _dbg_malloc;
- _dbg_realloc;
- _dbg_strdup;
- discover_devices;
- discover_partitions;
- discover_raid_devices;
- display_devices;
- display_set;
- dm_version;
- erase_metadata;
- find_set;
- get_dm_type;
- get_set_type;
- get_set_name;
- get_status;
- get_type;
- group_set;
- init_locking;
- lc_inc_opt;
- lc_list;
- lc_opt;
- lc_stralloc_opt;
- lc_strcat_opt;
- libdmraid_exit;
- libdmraid_init;
- libdmraid_date;
- libdmraid_version;
- libdmraid_make_table;
- list_formats;
- lock_resource;
- log_alloc_err;
- plog;
- process_sets;
- remove_delimiter;
- remove_white_space;
- total_sectors;
- unlock_resource;
-
- local:
- *;
-};
+Base {
+ global:
+ add_delimiter;
+ change_set;
+ check_valid_format;
+ collapse_delimiter;
+ count_devices;
+ count_devs;
+ count_sets;
+ _dbg_free;
+ _dbg_malloc;
+ _dbg_realloc;
+ _dbg_strdup;
+ discover_devices;
+ discover_partitions;
+ discover_raid_devices;
+ display_devices;
+ display_set;
+ dm_version;
+ erase_metadata;
+ find_set;
+ get_dm_type;
+ get_set_type;
+ get_set_name;
+ get_status;
+ get_type;
+ group_set;
+ init_locking;
+ lc_inc_opt;
+ lc_list;
+ lc_opt;
+ lc_stralloc_opt;
+ lc_strcat_opt;
+ libdmraid_exit;
+ libdmraid_init;
+ libdmraid_date;
+ libdmraid_version;
+ libdmraid_make_table;
+ list_formats;
+ lock_resource;
+ log_alloc_err;
+ plog;
+ process_sets;
+ remove_delimiter;
+ remove_white_space;
+ total_sectors;
+ unlock_resource;
+ add_dev_to_array;
+ delete_raidsets;
+ lib_perform;
+ rebuild_raidset;
+ dso_end_rebuild;
+ hot_spare_add;
+ dso_get_members;
+ local:
+ *;
+};
+
--- dmraid/lib/version.h 2008/04/02 13:35:31 1.5
+++ dmraid/lib/version.h 2008/06/20 21:52:16 1.6
@@ -7,6 +7,6 @@
#define DMRAID_LIB_SUBMINOR_VERSION 0
#define DMRAID_LIB_VERSION_SUFFIX "rc15"
-#define DMRAID_LIB_DATE "(2008.04.02)"
+#define DMRAID_LIB_DATE "(2008.06.20)"
#endif
--- dmraid/lib/activate/activate.c 2008/04/02 13:35:31 1.3
+++ dmraid/lib/activate/activate.c 2008/06/20 21:52:16 1.4
@@ -1,7 +1,10 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
@@ -12,26 +15,28 @@
#include "internal.h"
#include "devmapper.h"
-static int valid_rd(struct raid_dev *rd)
+static int
+valid_rd(struct raid_dev *rd)
{
return S_OK(rd->status) && !T_SPARE(rd);
}
-static int valid_rs(struct raid_set *rs)
+static int
+valid_rs(struct raid_set *rs)
{
return S_OK(rs->status) && !T_SPARE(rs);
}
/* Return rounded size in case of unbalanced mappings */
-static uint64_t maximize(struct raid_set *rs, uint64_t sectors,
- uint64_t last, uint64_t min)
+static uint64_t
+maximize(struct raid_set *rs, uint64_t sectors, uint64_t last, uint64_t min)
{
return sectors > min ? min(last, sectors) : last;
}
/* Find smallest set/disk larger than given minimum. */
-static uint64_t _smallest(struct lib_context *lc,
- struct raid_set *rs, uint64_t min)
+static uint64_t
+_smallest(struct lib_context *lc, struct raid_set *rs, uint64_t min)
{
uint64_t ret = ~0;
struct raid_set *r;
@@ -45,7 +50,7 @@
ret = maximize(rs, rd->sectors, ret, min);
}
- return ret == (uint64_t) ~0 ? 0 : ret;
+ return ret == (uint64_t) ~ 0 ? 0 : ret;
}
/*
@@ -53,33 +58,38 @@
*/
/* Undefined/-supported mapping. */
-static int _dm_un(struct lib_context *lc, char **table,
- struct raid_set *rs, const char *what)
+static int
+_dm_un(struct lib_context *lc, char **table,
+ struct raid_set *rs, const char *what)
{
LOG_ERR(lc, 0, "Un%sed RAID type %s[%u] on %s", what,
get_set_type(lc, rs), rs->type, rs->name);
}
-static int dm_undef(struct lib_context *lc, char **table, struct raid_set *rs)
+static int
+dm_undef(struct lib_context *lc, char **table, struct raid_set *rs)
{
return _dm_un(lc, table, rs, "defin");
}
-static int dm_unsup(struct lib_context *lc, char **table, struct raid_set *rs)
+static int
+dm_unsup(struct lib_context *lc, char **table, struct raid_set *rs)
{
return _dm_un(lc, table, rs, "support");
}
/* "Spare mapping". */
-static int dm_spare(struct lib_context *lc, char **table, struct raid_set *rs)
+static int
+dm_spare(struct lib_context *lc, char **table, struct raid_set *rs)
{
- LOG_ERR(lc, 0, "spare set");
+ LOG_ERR(lc, 0, "spare set \"%s\" cannot be activated", rs->name);
}
/* Push path and offset onto a table. */
-static int _dm_path_offset(struct lib_context *lc, char **table,
- int valid, const char *path, uint64_t offset)
+static int
+_dm_path_offset(struct lib_context *lc, char **table,
+ int valid, const char *path, uint64_t offset)
{
return p_fmt(lc, table, " %s %U",
valid ? path : lc->path.error, offset);
@@ -88,17 +98,17 @@
/*
* Create dm table for linear mapping.
*/
-static int _dm_linear(struct lib_context *lc, char **table, int valid,
- const char *path, uint64_t start, uint64_t sectors,
- uint64_t offset)
+static int
+_dm_linear(struct lib_context *lc, char **table, int valid,
+ const char *path, uint64_t start, uint64_t sectors, uint64_t offset)
{
return p_fmt(lc, table, "%U %U %s", start, sectors,
get_dm_type(lc, t_linear)) ?
- _dm_path_offset(lc, table, valid, path, offset) : 0;
+ _dm_path_offset(lc, table, valid, path, offset) : 0;
}
-static int dm_linear(struct lib_context *lc, char **table,
- struct raid_set *rs)
+static int
+dm_linear(struct lib_context *lc, char **table, struct raid_set *rs)
{
unsigned int segments = 0;
uint64_t start = 0, sectors = 0;
@@ -113,14 +123,14 @@
if (!(path = mkdm_path(lc, r->name)))
goto err;
-
+
sectors = total_sectors(lc, r);
ret = _dm_linear(lc, table, valid_rs(r), path,
start, sectors, 0);
dbg_free(path);
segments++;
start += sectors;
-
+
if (!ret ||
(r->sets.next != &rs->sets &&
!p_fmt(lc, table, "\n")))
@@ -131,10 +141,11 @@
/* Devices of a linear set. */
list_for_each_entry(rd, &rs->devs, devs) {
if (!T_SPARE(rd)) {
- if (!_dm_linear(lc, table, valid_rd(rd), rd->di->path,
- start, rd->sectors, rd->offset))
+ if (!_dm_linear
+ (lc, table, valid_rd(rd), rd->di->path, start,
+ rd->sectors, rd->offset))
goto err;
-
+
segments++;
start += rd->sectors;
@@ -146,7 +157,7 @@
return segments ? 1 : 0;
- err:
+ err:
return log_alloc_err(lc, __func__);
}
@@ -156,8 +167,8 @@
* Partitioned RAID set with 1 RAID device
* defining a linear partition mapping.
*/
-static int dm_partition(struct lib_context *lc, char **table,
- struct raid_set *rs)
+static int
+dm_partition(struct lib_context *lc, char **table, struct raid_set *rs)
{
return dm_linear(lc, table, rs);
}
@@ -178,21 +189,22 @@
*
*/
/* Push begin of line onto a RAID0 table. */
-static int _dm_raid0_bol(struct lib_context *lc, char **table,
- uint64_t min, uint64_t last_min,
- unsigned int n, unsigned int stride)
+static int
+_dm_raid0_bol(struct lib_context *lc, char **table,
+ uint64_t min, uint64_t last_min,
+ unsigned int n, unsigned int stride)
{
return p_fmt(lc, table,
n > 1 ? "%U %U %s %u %u" : "%U %U %s",
last_min * n, (min - last_min) * n,
- get_dm_type(lc, n > 1 ? t_raid0 : t_linear),
- n, stride);
+ get_dm_type(lc, n > 1 ? t_raid0 : t_linear), n, stride);
}
/* Push end of line onto a RAID0 table. */
-static int _dm_raid0_eol(struct lib_context *lc,
- char **table, struct raid_set *rs,
- unsigned int *stripes, uint64_t last_min)
+static int
+_dm_raid0_eol(struct lib_context *lc,
+ char **table, struct raid_set *rs,
+ unsigned int *stripes, uint64_t last_min)
{
struct raid_set *r;
struct raid_dev *rd;
@@ -216,7 +228,7 @@
(*stripes)++;
}
}
-
+
list_for_each_entry(rd, &rs->devs, devs) {
if (!T_SPARE(rd) &&
rd->sectors > last_min &&
@@ -229,13 +241,13 @@
return 1;
- err:
+ err:
return 0;
}
/* Count RAID sets/devices larger than given minimum size. */
-static unsigned int _dm_raid_devs(struct lib_context *lc,
- struct raid_set *rs, uint64_t min)
+static unsigned int
+_dm_raid_devs(struct lib_context *lc, struct raid_set *rs, uint64_t min)
{
unsigned int ret = 0;
struct raid_set *r;
@@ -246,7 +258,7 @@
if (!T_SPARE(r) && total_sectors(lc, r) > min)
ret++;
}
-
+
list_for_each_entry(rd, &rs->devs, devs) {
if (!T_SPARE(rd) && rd->sectors > min)
ret++;
@@ -254,9 +266,9 @@
return ret;
}
-
-static int dm_raid0(struct lib_context *lc, char **table,
- struct raid_set *rs)
+
+static int
+dm_raid0(struct lib_context *lc, char **table, struct raid_set *rs)
{
unsigned int stripes = 0;
uint64_t min, last_min = 0;
@@ -266,9 +278,10 @@
goto err;
if (!_dm_raid0_bol(lc, table, round_down(min, rs->stride),
- last_min, _dm_raid_devs(lc, rs, last_min),
- rs->stride) ||
- !_dm_raid0_eol(lc, table, rs, &stripes, last_min))
+ last_min, _dm_raid_devs(lc, rs,
+ last_min),
+ rs->stride)
+ || !_dm_raid0_eol(lc, table, rs, &stripes, last_min))
goto err;
if (!F_MAXIMIZE(rs))
@@ -277,7 +290,7 @@
return stripes ? 1 : 0;
- err:
+ err:
return log_alloc_err(lc, __func__);
}
@@ -286,20 +299,21 @@
*/
/* Calculate dirty log region size. */
-static unsigned int calc_region_size(struct lib_context *lc, uint64_t sectors)
+static unsigned int
+calc_region_size(struct lib_context *lc, uint64_t sectors)
{
- const unsigned int mb_128 = 128*2*1024;
+ const unsigned int mb_128 = 128 * 2 * 1024;
unsigned int max, region_size;
if ((max = sectors / 1024) > mb_128)
max = mb_128;
for (region_size = 128; region_size < max; region_size <<= 1);
-
return region_size >> 1;
}
-static unsigned int get_rds(struct raid_set *rs, int valid)
+static unsigned int
+get_rds(struct raid_set *rs, int valid)
{
unsigned int ret = 0;
struct raid_dev *rd;
@@ -315,7 +329,8 @@
return ret;
}
-static unsigned int get_dm_devs(struct raid_set *rs, int valid)
+static unsigned int
+get_dm_devs(struct raid_set *rs, int valid)
{
unsigned int ret = 0;
struct raid_set *r;
@@ -329,30 +344,68 @@
ret++;
}
- ret+= get_rds(rs, valid);
+ return ret + get_rds(rs, valid);
+}
- return ret;
+/* Retrieve number of drive to rebuild from metadata format handler. */
+static int
+get_rebuild_drive(struct lib_context *lc, struct raid_set *rs,
+ struct handler_info *info)
+{
+ /* Initialize drive to rebuild invalid. */
+ info->data.i32 = -1;
+
+ if (lc->options[LC_REBUILD_SET].opt) {
+ struct raid_dev *rd;
+
+ if (list_empty(&rs->devs))
+ LOG_ERR(lc, 0, "RAID set has no devices!");
+
+ rd = list_entry(rs->devs.next, typeof(*rd), devs);
+ if (rd->fmt->metadata_handler) {
+ if (!rd->
+ fmt->metadata_handler(lc, GET_REBUILD_DRIVE_NO,
+ info, rs))
+ LOG_ERR(lc, 0, "Can't get rebuild drive #!");
+ } else
+ LOG_ERR(lc, 0,
+ "Can't rebuild w/o metadata_handler for %s",
+ rd->fmt->name);
+ }
+
+ return 1;
}
+/* Return true if RAID set needs rebuilding. */
+static inline int
+rs_need_sync(struct raid_set *rs)
+{
+ return S_INCONSISTENT(rs->status) || S_NOSYNC(rs->status);
+}
+
+
/* Push begin of line onto a RAID1 table. */
/* FIXME: persistent dirty log. */
-static int _dm_raid1_bol(struct lib_context *lc, char **table,
- struct raid_set *rs,
- uint64_t sectors, unsigned int mirrors)
+static int
+_dm_raid1_bol(struct lib_context *lc, char **table,
+ struct raid_set *rs,
+ uint64_t sectors, unsigned int mirrors, int need_sync)
{
return (p_fmt(lc, table, "0 %U %s core 2 %u %s %u",
sectors, get_dm_type(lc, t_raid1),
calc_region_size(lc, sectors),
- (S_INCONSISTENT(rs->status) || S_NOSYNC(rs->status)) ?
- "sync" : "nosync", mirrors));
+ (need_sync) ? "sync" : "nosync", mirrors));
}
-static int dm_raid1(struct lib_context *lc, char **table, struct raid_set *rs)
+static int
+dm_raid1(struct lib_context *lc, char **table, struct raid_set *rs)
{
+ int need_sync;
+ struct handler_info rebuild_drive;
uint64_t sectors = 0;
unsigned int mirrors = get_dm_devs(rs, 1);
- struct raid_set *r;
- struct raid_dev *rd;
+ struct raid_set *r, *swap_rs;
+ struct raid_dev *rd, *swap_rd;
switch (mirrors) {
case 0:
@@ -367,23 +420,36 @@
rs->name);
return dm_linear(lc, table, rs);
}
-
+
if (!(sectors = _smallest(lc, rs, 0)))
LOG_ERR(lc, 0, "can't find smallest mirror!");
- if (!_dm_raid1_bol(lc, table, rs, sectors, mirrors))
+ /*
+ * Get drive for reordering - copy is made from first
+ * drive (i.e. the master) to the other mirrors.
+ */
+ need_sync = rs_need_sync(rs);
+ if (need_sync && !get_rebuild_drive(lc, rs, &rebuild_drive))
+ return 0;
+
+ if (!_dm_raid1_bol(lc, table, rs, sectors, mirrors, need_sync))
goto err;
/* Stacked mirror sets. */
+ swap_rs = NULL;
list_for_each_entry(r, &rs->sets, list) {
if (valid_rs(r)) {
- int ret;
+ int ret = 1;
char *path;
if (!(path = mkdm_path(lc, r->name)))
goto err;
- ret = _dm_path_offset(lc, table, 1, path, 0);
+ if (!rebuild_drive.data.i32 && !swap_rs)
+ swap_rs = r;
+ else
+ ret = _dm_path_offset(lc, table, 1, path, 0);
+
dbg_free(path);
if (!ret)
@@ -391,20 +457,47 @@
}
}
- /* Lowest level mirror devices */
- list_for_each_entry(rd, &rs->devs, devs) {
- if (valid_rd(rd) &&
- !_dm_path_offset(lc, table, 1, rd->di->path, rd->offset))
+ /* Add rebuild target to the end of the list. */
+ if (swap_rs && valid_rs(swap_rs)) {
+ int ret = 1;
+ char *path;
+
+ if (!(path = mkdm_path(lc, swap_rs->name)))
goto err;
+
+ ret = _dm_path_offset(lc, table, 1, path, 0);
+ dbg_free(path);
+
+ if (!ret)
+ goto err;
+ }
+
+ /* Lowest level mirror devices. */
+ swap_rd = NULL;
+ list_for_each_entry(rd, &rs->devs, devs) {
+ if (valid_rd(rd)) {
+ if (!rebuild_drive.data.i32 && !swap_rd)
+ swap_rd = rd;
+ else if (!_dm_path_offset(lc, table, 1,
+ rd->di->path, rd->offset))
+ goto err;
+ }
}
- /* Append the flag/feature required for dmraid1
- * event handling in the kernel driver
+ /* Add rebuild target to the end of the list. */
+ if (swap_rd && valid_rd(swap_rd))
+ if (!_dm_path_offset(lc, table, valid_rd(swap_rd),
+ swap_rd->di->path, swap_rd->offset))
+ goto err;
+
+ /*
+ * Append the flag/feature required for dmraid1
+ * event handling in the kernel driver.
*/
- if(p_fmt(lc, table, " 1 handle_errors"))
+ if (p_fmt(lc, table, " 1 handle_errors"))
return 1;
- err:
+ err:
return log_alloc_err(lc, __func__);
}
@@ -414,19 +507,28 @@
/* Push begin of line onto a RAID5 table. */
/* FIXME: persistent dirty log. */
-static int _dm_raid45_bol(struct lib_context *lc, char **table,
- struct raid_set *rs,
- uint64_t sectors, unsigned int members)
+static int
+_dm_raid45_bol(struct lib_context *lc, char **table, struct raid_set *rs,
+ uint64_t sectors, unsigned int members)
{
- return p_fmt(lc, table, "0 %U %s core 2 %u %s %s 1 %u %u -1",
+ int need_sync = rs_need_sync(rs);
+ struct handler_info rebuild_drive;
+
+ /* Get drive as rebuild target. */
+ if (need_sync && !get_rebuild_drive(lc, rs, &rebuild_drive))
+ return 0;
+
+ return p_fmt(lc, table, "0 %U %s core 2 %u %s %s 1 %u %u %d",
sectors, get_dm_type(lc, rs->type),
- calc_region_size(lc, total_sectors(lc, rs) / _dm_raid_devs(lc, rs, 0)),
- (S_INCONSISTENT(rs->status) || S_NOSYNC(rs->status)) ?
- "sync" : "nosync",
- get_type(lc, rs->type), rs->stride, members);
+ calc_region_size(lc,
+ total_sectors(lc, rs) /
+ _dm_raid_devs(lc, rs, 0)),
+ (need_sync) ? "sync" : "nosync", get_type(lc, rs->type),
+ rs->stride, members, rebuild_drive.data.i32);
}
-static int dm_raid45(struct lib_context *lc, char **table, struct raid_set *rs)
+static int
+dm_raid45(struct lib_context *lc, char **table, struct raid_set *rs)
{
uint64_t sectors = 0;
unsigned int members = get_dm_devs(rs, 0);
@@ -465,14 +567,14 @@
/* Lowest level RAID devices */
list_for_each_entry(rd, &rs->devs, devs) {
- if (!_dm_path_offset(lc, table, valid_rd(rd), rd->di->path,
- rd->offset))
+ if (!_dm_path_offset(lc, table, valid_rd(rd), rd->di->path,
+ rd->offset))
goto err;
}
return 1;
- err:
+ err:
return log_alloc_err(lc, __func__);
}
@@ -485,25 +587,28 @@
*/
static struct type_handler {
const enum type type;
- int(*f)(struct lib_context *lc, char **table, struct raid_set *rs);
+ int (*f) (struct lib_context * lc, char **table, struct raid_set * rs);
} type_handler[] = {
- { t_undef, dm_undef }, /* Needs to stay here! */
- { t_partition, dm_partition },
- { t_spare, dm_spare },
- { t_linear, dm_linear },
- { t_raid0, dm_raid0 },
- { t_raid1, dm_raid1 },
- { t_raid4, dm_raid45 },
- { t_raid5_ls, dm_raid45 },
- { t_raid5_rs, dm_raid45 },
- { t_raid5_la, dm_raid45 },
- { t_raid5_ra, dm_raid45 },
- /* RAID types below not supported (yet) */
- { t_raid6, dm_unsup },
-};
+ {
+ t_undef, dm_undef}, /* Needs to stay here! */
+ {
+ t_partition, dm_partition}, {
+ t_spare, dm_spare}, {
+ t_linear, dm_linear}, {
+ t_raid0, dm_raid0}, {
+ t_raid1, dm_raid1}, {
+ t_raid4, dm_raid45}, {
+ t_raid5_ls, dm_raid45}, {
+ t_raid5_rs, dm_raid45}, {
+ t_raid5_la, dm_raid45}, {
+ t_raid5_ra, dm_raid45},
+ /* RAID types below not supported (yet) */
+ {
+t_raid6, dm_unsup},};
/* Retrieve type handler from array. */
-static struct type_handler *handler(struct raid_set *rs)
+static struct type_handler *
+handler(struct raid_set *rs)
{
struct type_handler *th = type_handler;
@@ -516,7 +621,8 @@
}
/* Return mapping table */
-char *libdmraid_make_table(struct lib_context *lc, struct raid_set *rs)
+char *
+libdmraid_make_table(struct lib_context *lc, struct raid_set *rs)
{
char *ret = NULL;
@@ -531,23 +637,25 @@
}
-enum dm_what { DM_ACTIVATE, DM_REGISTER};
+enum dm_what { DM_ACTIVATE, DM_REGISTER };
/* Register devices of the RAID set with the dmeventd. */
/* REMOVEME: dummy functions once linking to the real ones. */
#define ALL_EVENTS 0xffffffff
-static int dm_register_for_event(char *a, char *b, int c)
+static int
+dm_register_for_event(char *a, char *b, int c)
{
return 1;
}
-static int dm_unregister_for_event(char *a, char *b, int c)
+static int
+dm_unregister_for_event(char *a, char *b, int c)
{
return 1;
}
-static int do_device(struct lib_context *lc, struct raid_set *rs,
- int (*f)()) // char *, char *, enum event_type))
+static int
+do_device(struct lib_context *lc, struct raid_set *rs, int (*f) ())
{
int ret = 0;
struct raid_dev *rd;
@@ -555,7 +663,7 @@
if (OPT_TEST(lc))
return 1;
- return 1; /* REMOVEME: */
+ return 1; /* REMOVEME: */
list_for_each_entry(rd, &rs->devs, devs) {
if (!(ret = f("dmraid", rd->di->path, ALL_EVENTS)))
@@ -565,24 +673,27 @@
return ret ? 1 : 0;
}
-static int register_devices(struct lib_context *lc, struct raid_set *rs)
+static int
+register_devices(struct lib_context *lc, struct raid_set *rs)
{
return do_device(lc, rs, dm_register_for_event);
}
/* Unregister devices of the RAID set with the dmeventd. */
-static int unregister_devices(struct lib_context *lc, struct raid_set *rs)
+static int
+unregister_devices(struct lib_context *lc, struct raid_set *rs)
{
return do_device(lc, rs, dm_unregister_for_event);
}
/* Reload a single set. */
-static int reload_subset(struct lib_context *lc, struct raid_set *rs)
+static int
+reload_subset(struct lib_context *lc, struct raid_set *rs)
{
int ret = 0;
char *table = NULL;
- if (T_GROUP(rs))
+ if (T_GROUP(rs) || T_RAID0(rs))
return 1;
/* Suspend device */
@@ -603,23 +714,21 @@
/* Try to resume */
if (ret)
dm_resume(lc, rs);
- else
- if (!(ret = dm_resume(lc, rs)))
- LOG_ERR(lc, ret, "Device resume failed.");
+ else if (!(ret = dm_resume(lc, rs)))
+ LOG_ERR(lc, ret, "Device resume failed.");
return ret;
}
/* Reload a RAID set recursively (eg, RAID1 on top of RAID0). */
-static int reload_set(struct lib_context *lc, struct raid_set *rs)
+static int
+reload_set(struct lib_context *lc, struct raid_set *rs)
{
struct raid_set *r;
/* FIXME: Does it matter if the set is (in)active? */
#if 0
- if (!OPT_TEST(lc) &&
- what == DM_ACTIVATE &&
- dm_status(lc, rs)) {
+ if (!OPT_TEST(lc) && what == DM_ACTIVATE && dm_status(lc, rs)) {
log_print(lc, "RAID set \"%s\" already active", rs->name);
return 1;
}
@@ -629,15 +738,15 @@
list_for_each_entry(r, &rs->sets, list) {
/* Activate set below this one */
if (!reload_set(lc, r) && !T_GROUP(rs))
- return 0;
+ continue;
}
return reload_subset(lc, rs);
}
/* Activate a single set. */
-static int activate_subset(struct lib_context *lc, struct raid_set *rs,
- enum dm_what what)
+static int
+activate_subset(struct lib_context *lc, struct raid_set *rs, enum dm_what what)
{
int ret = 0;
char *table = NULL;
@@ -652,8 +761,12 @@
if ((ret = (handler(rs))->f(lc, &table, rs))) {
if (OPT_TEST(lc))
display_table(lc, rs->name, table);
+ else if ((ret = dm_create(lc, rs, table)))
+ log_print(lc, "RAID set \"%s\" was activated",
+ rs->name);
else
- ret = dm_create(lc, rs, table);
+ log_print(lc, "RAID set \"%s\" was not activated",
+ rs->name);
} else
log_err(lc, "no mapping possible for RAID set %s", rs->name);
@@ -663,14 +776,12 @@
}
/* Activate a RAID set recursively (eg, RAID1 on top of RAID0). */
-static int activate_set(struct lib_context *lc, struct raid_set *rs,
- enum dm_what what)
+static int
+activate_set(struct lib_context *lc, struct raid_set *rs, enum dm_what what)
{
struct raid_set *r;
- if (!OPT_TEST(lc) &&
- what == DM_ACTIVATE &&
- dm_status(lc, rs)) {
+ if (!OPT_TEST(lc) && what == DM_ACTIVATE && dm_status(lc, rs)) {
log_print(lc, "RAID set \"%s\" already active", rs->name);
return 1;
}
@@ -686,30 +797,29 @@
}
/* Deactivate a single set (one level of a device stack). */
-static int deactivate_superset(struct lib_context *lc, struct raid_set *rs,
- enum dm_what what)
+static int
+deactivate_superset(struct lib_context *lc, struct raid_set *rs,
+ enum dm_what what)
{
int ret = 1, status;
if (what == DM_REGISTER)
return unregister_devices(lc, rs);
-
+
status = dm_status(lc, rs);
if (OPT_TEST(lc))
log_print(lc, "%s [%sactive]", rs->name, status ? "" : "in");
else if (status)
ret = dm_remove(lc, rs);
- else {
+ else
log_print(lc, "RAID set \"%s\" is not active", rs->name);
- ret = 1;
- }
return ret;
}
/* Deactivate a RAID set. */
-static int deactivate_set(struct lib_context *lc, struct raid_set *rs,
- enum dm_what what)
+static int
+deactivate_set(struct lib_context *lc, struct raid_set *rs, enum dm_what what)
{
struct raid_set *r;
@@ -717,8 +827,7 @@
* Deactivate myself if not a group set,
* which gets never activated itself.
*/
- if (!T_GROUP(rs) &&
- !deactivate_superset(lc, rs, what))
+ if (!T_GROUP(rs) && !deactivate_superset(lc, rs, what))
return 0;
/* Deactivate any subsets recursively. */
@@ -732,25 +841,30 @@
/* External (de)activate interface. */
-int change_set(struct lib_context *lc, enum activate_type what, void *v)
+int
+change_set(struct lib_context *lc, enum activate_type what, void *v)
{
- int ret = 0;
+ int ret;
struct raid_set *rs = v;
switch (what) {
case A_ACTIVATE:
ret = activate_set(lc, rs, DM_ACTIVATE) &&
- activate_set(lc, rs, DM_REGISTER);
+ activate_set(lc, rs, DM_REGISTER);
break;
case A_DEACTIVATE:
ret = deactivate_set(lc, rs, DM_REGISTER) &&
- deactivate_set(lc, rs, DM_ACTIVATE);
+ deactivate_set(lc, rs, DM_ACTIVATE);
break;
case A_RELOAD:
ret = reload_set(lc, rs);
break;
+
+ default:
+ log_err(lc, "%s: invalid activate type!", __func__);
+ ret = 0;
}
return ret;
--- dmraid/lib/activate/devmapper.c 2008/04/02 13:35:31 1.3
+++ dmraid/lib/activate/devmapper.c 2008/06/20 21:52:16 1.4
@@ -1,7 +1,10 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
@@ -24,7 +27,8 @@
#include <linux/dm-ioctl.h>
/* Make up a dm path. */
-char *mkdm_path(struct lib_context *lc, const char *name)
+char *
+mkdm_path(struct lib_context *lc, const char *name)
{
char *ret;
const char *dir = dm_dir();
@@ -38,20 +42,22 @@
}
/* Device-mapper NULL log function. */
-static void dmraid_log(int level, const char *file, int line,
- const char *f, ...)
+static void
+dmraid_log(int level, const char *file, int line, const char *f, ...)
{
return;
}
/* Init device-mapper library. */
-static void _init_dm(void)
+static void
+_init_dm(void)
{
dm_log_init(dmraid_log);
}
/* Cleanup at exit. */
-static void _exit_dm(struct dm_task *dmt)
+static void
+_exit_dm(struct dm_task *dmt)
{
if (dmt)
dm_task_destroy(dmt);
@@ -65,17 +71,18 @@
*
* dm-library must get inititalized by caller.
*/
-static struct dm_versions *get_target_list(void)
+static struct dm_versions *
+get_target_list(void)
{
struct dm_task *dmt;
return (dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)) &&
- dm_task_run(dmt) ? dm_task_get_versions(dmt) : NULL;
+ dm_task_run(dmt) ? dm_task_get_versions(dmt) : NULL;
}
/* Check a target's name against registered ones. */
-static int valid_ttype(struct lib_context *lc, char *ttype,
- struct dm_versions *targets)
+static int
+valid_ttype(struct lib_context *lc, char *ttype, struct dm_versions *targets)
{
struct dm_versions *t, *last;
@@ -94,18 +101,20 @@
return 1;
last = t;
- t = (void*) t + t->next;
+ t = (void *) t + t->next;
} while (last != t);
- LOG_ERR(lc, 0, "device-mapper target type \"%s\" not in kernel", ttype);
+ LOG_ERR(lc, 0,
+ "device-mapper target type \"%s\" is not in the kernel", ttype);
}
/*
* Parse a mapping table and create the appropriate targets or
* check that a target type is registered with the device-mapper core.
*/
-static int handle_table(struct lib_context *lc, struct dm_task *dmt,
- char *table, struct dm_versions *targets)
+static int
+handle_table(struct lib_context *lc, struct dm_task *dmt,
+ char *table, struct dm_versions *targets)
{
int line = 0, n, ret = 0;
uint64_t start, size;
@@ -138,21 +147,25 @@
}
/* Parse a mapping table and create the appropriate targets. */
-static int parse_table(struct lib_context *lc, struct dm_task *dmt, char *table)
+static int
+parse_table(struct lib_context *lc, struct dm_task *dmt, char *table)
{
return handle_table(lc, dmt, table, NULL);
}
/* Check if a target type is not registered with the kernel after a failure. */
-static int check_table(struct lib_context *lc, char *table)
+static int
+check_table(struct lib_context *lc, char *table)
{
return handle_table(lc, NULL, table, get_target_list());
}
/* Build a UUID for a dmraid device
* Return 1 for sucess; 0 for failure*/
-static int dmraid_uuid(struct lib_context *lc, struct raid_set *rs,
- char *uuid, uint uuid_len) {
+static int
+dmraid_uuid(struct lib_context *lc, struct raid_set *rs,
+ char *uuid, uint uuid_len)
+{
int r;
/* Clear garbage data from uuid string */
@@ -164,35 +177,39 @@
}
/* Create a task, set its name and run it. */
-static int run_task(struct lib_context *lc, struct raid_set *rs,
- char *table, int type)
+static int
+run_task(struct lib_context *lc, struct raid_set *rs, char *table, int type)
{
- /* DM_UUID_LEN is defined in dm-ioctl.h as 129 characters;
+ /*
+ * DM_UUID_LEN is defined in dm-ioctl.h as 129 characters;
* though not all 129 must be used (md uses just 16 from
* a quick review of md.c.
- * We will be using: (len vol grp name)*/
+ * We will be using: (len vol grp name)
+ */
char uuid[DM_UUID_LEN];
int ret;
struct dm_task *dmt;
_init_dm();
- ret = (dmt = dm_task_create(type)) &&
- dm_task_set_name(dmt, rs->name);
+ ret = (dmt = dm_task_create(type)) && dm_task_set_name(dmt, rs->name);
if (ret && table)
ret = parse_table(lc, dmt, table);
- if (ret &&
- DM_DEVICE_CREATE == type)
- ret = dmraid_uuid(lc, rs, uuid, DM_UUID_LEN) &&
- dm_task_set_uuid(dmt, uuid) &&
- dm_task_run(dmt);
+ if (ret) {
+ if (DM_DEVICE_CREATE == type) {
+ ret = dmraid_uuid(lc, rs, uuid, DM_UUID_LEN) &&
+ dm_task_set_uuid(dmt, uuid) && dm_task_run(dmt);
+ } else
+ ret = dm_task_run(dmt);
+ }
_exit_dm(dmt);
return ret;
}
-
+
/* Create a mapped device. */
-int dm_create(struct lib_context *lc, struct raid_set *rs, char *table)
+int
+dm_create(struct lib_context *lc, struct raid_set *rs, char *table)
{
int ret;
@@ -210,21 +227,24 @@
}
/* Suspend a mapped device. */
-int dm_suspend(struct lib_context *lc, struct raid_set *rs)
+int
+dm_suspend(struct lib_context *lc, struct raid_set *rs)
{
/* Suspend <dev_name> */
return run_task(lc, rs, NULL, DM_DEVICE_SUSPEND);
}
/* Resume a mapped device. */
-int dm_resume(struct lib_context *lc, struct raid_set *rs)
+int
+dm_resume(struct lib_context *lc, struct raid_set *rs)
{
/* Resume <dev_name> */
return run_task(lc, rs, NULL, DM_DEVICE_RESUME);
}
/* Reload a mapped device. */
-int dm_reload(struct lib_context *lc, struct raid_set *rs, char *table)
+int
+dm_reload(struct lib_context *lc, struct raid_set *rs, char *table)
{
int ret;
@@ -242,7 +262,8 @@
}
/* Remove a mapped device. */
-int dm_remove(struct lib_context *lc, struct raid_set *rs)
+int
+dm_remove(struct lib_context *lc, struct raid_set *rs)
{
/* Remove <dev_name> */
return run_task(lc, rs, NULL, DM_DEVICE_REMOVE);
@@ -250,7 +271,8 @@
/* Retrieve status of a mapped device. */
/* FIXME: more status for device monitoring... */
-int dm_status(struct lib_context *lc, struct raid_set *rs)
+int
+dm_status(struct lib_context *lc, struct raid_set *rs)
{
int ret;
struct dm_task *dmt;
@@ -260,18 +282,15 @@
/* Status <dev_name>. */
ret = (dmt = dm_task_create(DM_DEVICE_STATUS)) &&
- dm_task_set_name(dmt, rs->name) &&
- dm_task_run(dmt) &&
- dm_task_get_info(dmt, &info) &&
- info.exists;
-
+ dm_task_set_name(dmt, rs->name) &&
+ dm_task_run(dmt) && dm_task_get_info(dmt, &info) && info.exists;
_exit_dm(dmt);
-
return ret;
}
/* Retrieve device-mapper driver version. */
-int dm_version(struct lib_context *lc, char *version, size_t size)
+int
+dm_version(struct lib_context *lc, char *version, size_t size)
{
int ret;
struct dm_task *dmt;
@@ -282,10 +301,8 @@
_init_dm();
ret = (dmt = dm_task_create(DM_DEVICE_VERSION)) &&
- dm_task_run(dmt) &&
- dm_task_get_driver_version(dmt, version, size);
-
+ dm_task_run(dmt) &&
+ dm_task_get_driver_version(dmt, version, size);
_exit_dm(dmt);
-
return ret;
}
--- dmraid/lib/datastruct/byteorder.h 2008/02/22 16:57:35 1.1
+++ dmraid/lib/datastruct/byteorder.h 2008/06/20 21:52:16 1.2
@@ -16,30 +16,33 @@
#ifdef DM_BYTEORDER_SWAB
-static inline uint64_t le64_to_cpu(uint64_t x)
+static inline uint64_t
+le64_to_cpu(uint64_t x)
{
- return((((uint64_t)x & 0x00000000000000ffULL) << 56) |
- (((uint64_t)x & 0x000000000000ff00ULL) << 40) |
- (((uint64_t)x & 0x0000000000ff0000ULL) << 24) |
- (((uint64_t)x & 0x00000000ff000000ULL) << 8) |
- (((uint64_t)x & 0x000000ff00000000ULL) >> 8) |
- (((uint64_t)x & 0x0000ff0000000000ULL) >> 24) |
- (((uint64_t)x & 0x00ff000000000000ULL) >> 40) |
- (((uint64_t)x & 0xff00000000000000ULL) >> 56));
+ return ((((uint64_t) x & 0x00000000000000ffULL) << 56) |
+ (((uint64_t) x & 0x000000000000ff00ULL) << 40) |
+ (((uint64_t) x & 0x0000000000ff0000ULL) << 24) |
+ (((uint64_t) x & 0x00000000ff000000ULL) << 8) |
+ (((uint64_t) x & 0x000000ff00000000ULL) >> 8) |
+ (((uint64_t) x & 0x0000ff0000000000ULL) >> 24) |
+ (((uint64_t) x & 0x00ff000000000000ULL) >> 40) |
+ (((uint64_t) x & 0xff00000000000000ULL) >> 56));
}
-static inline int32_t le32_to_cpu(int32_t x)
+static inline int32_t
+le32_to_cpu(int32_t x)
{
- return((((u_int32_t)x & 0x000000ffU) << 24) |
- (((u_int32_t)x & 0x0000ff00U) << 8) |
- (((u_int32_t)x & 0x00ff0000U) >> 8) |
- (((u_int32_t)x & 0xff000000U) >> 24));
+ return ((((u_int32_t) x & 0x000000ffU) << 24) |
+ (((u_int32_t) x & 0x0000ff00U) << 8) |
+ (((u_int32_t) x & 0x00ff0000U) >> 8) |
+ (((u_int32_t) x & 0xff000000U) >> 24));
}
-static inline int16_t le16_to_cpu(int16_t x)
+static inline int16_t
+le16_to_cpu(int16_t x)
{
- return((((u_int16_t)x & 0x00ff) << 8) |
- (((u_int16_t)x & 0xff00) >> 8));
+ return ((((u_int16_t) x & 0x00ff) << 8) |
+ (((u_int16_t) x & 0xff00) >> 8));
}
#define CVT64(x) do { x = le64_to_cpu(x); } while(0)
--- dmraid/lib/device/ata.c 2008/02/22 16:57:35 1.1
+++ dmraid/lib/device/ata.c 2008/06/20 21:52:17 1.2
@@ -15,7 +15,8 @@
#include "dev-io.h"
#include "ata.h"
-int get_ata_serial(struct lib_context *lc, int fd, struct dev_info *di)
+int
+get_ata_serial(struct lib_context *lc, int fd, struct dev_info *di)
{
int ret = 0;
const int cmd_offset = 4;
@@ -26,11 +27,14 @@
buf[0] = ATA_IDENTIFY_DEVICE;
buf[3] = 1;
if (!ioctl(fd, HDIO_DRIVE_CMD, buf)) {
- ata_ident = (struct ata_identify*) &buf[cmd_offset];
- if ((di->serial = dbg_strdup(remove_white_space(lc, (char*) ata_ident->serial, ATA_SERIAL_LEN))))
+ ata_ident = (struct ata_identify *) &buf[cmd_offset];
+ if ((di->serial =
+ dbg_strdup(remove_white_space
+ (lc, (char *) ata_ident->serial,
+ ATA_SERIAL_LEN))))
ret = 1;
}
-
+
dbg_free(buf);
}
--- dmraid/lib/device/ata.h 2008/02/22 16:57:35 1.1
+++ dmraid/lib/device/ata.h 2008/06/20 21:52:17 1.2
@@ -13,10 +13,10 @@
struct ata_identify {
unsigned short dummy[10];
#define ATA_SERIAL_LEN 20
- unsigned char serial[ATA_SERIAL_LEN];
+ unsigned char serial[ATA_SERIAL_LEN];
unsigned short dummy1[3];
- unsigned char fw_rev[8];
- unsigned char model[40];
+ unsigned char fw_rev[8];
+ unsigned char model[40];
unsigned short dummy2[33];
unsigned short major_rev_num;
unsigned short minor_rev_num;
--- dmraid/lib/device/dev-io.h 2008/02/22 16:57:35 1.1
+++ dmraid/lib/device/dev-io.h 2008/06/20 21:52:17 1.2
@@ -12,8 +12,8 @@
#include <sys/stat.h>
#include "internal.h"
-#define BLKGETSIZE _IO(0x12, 0x60) /* get block device size */
-#define BLKSSZGET _IO(0x12, 0x68) /* get block device sector size */
+#define BLKGETSIZE _IO(0x12, 0x60) /* get block device size */
+#define BLKSSZGET _IO(0x12, 0x68) /* get block device sector size */
#define DMRAID_SECTOR_SIZE 512
--- dmraid/lib/device/scan.c 2008/02/22 16:57:35 1.1
+++ dmraid/lib/device/scan.c 2008/06/20 21:52:17 1.2
@@ -32,7 +32,8 @@
#define _PATH_MOUNTS "/proc/mounts"
#endif
-static char *find_sysfs_mp(struct lib_context *lc)
+static char *
+find_sysfs_mp(struct lib_context *lc)
{
#ifndef __KLIBC__
char *ret = NULL;
@@ -57,12 +58,14 @@
return ret;
#else
- return (char*) "/sys";
+ return (char *) "/sys";
#endif
}
/* Make up an absolute sysfs path given a relative one. */
-static char *mk_sysfs_path(struct lib_context *lc, char const *path) {
+static char *
+mk_sysfs_path(struct lib_context *lc, char const *path)
+{
static char *ret = NULL, *sysfs_mp;
if (!(sysfs_mp = find_sysfs_mp(lc)))
@@ -78,18 +81,19 @@
/* Test with sparse mapped devices. */
#ifdef DMRAID_TEST
-static int dm_test_device(struct lib_context *lc, char *path)
+static int
+dm_test_device(struct lib_context *lc, char *path)
{
struct stat s;
return !lstat(path, &s) &&
- S_ISLNK(s.st_mode) &&
- !strncmp(get_basename(lc, path), "dm-", 3);
+ S_ISLNK(s.st_mode) &&
+ !strncmp(get_basename(lc, path), "dm-", 3);
}
/* Fake a SCSI serial number by reading it from a file. */
-static int get_dm_test_serial(struct lib_context *lc,
- struct dev_info *di, char *path)
+static int
+get_dm_test_serial(struct lib_context *lc, struct dev_info *di, char *path)
{
int ret = 1;
char *serial, buffer[32];
@@ -121,19 +125,20 @@
* Ioctl for sector, optionally for device size
* and get device serial number.
*/
-static int get_device_serial(struct lib_context *lc, int fd,
- struct dev_info *di)
+static int
+get_device_serial(struct lib_context *lc, int fd, struct dev_info *di)
{
/*
* In case new generic SCSI ioctl fails,
* try ATA and fall back to old SCSI ioctl.
*/
- return get_scsi_serial(lc, fd, di, SG) || /* SG: generic scsi ioctl. */
- get_ata_serial(lc, fd, di) || /* Get ATA serial number. */
- get_scsi_serial(lc, fd, di, OLD); /* OLD: Old scsi ioctl. */
+ return get_scsi_serial(lc, fd, di, SG) || /* SG: generic scsi ioctl. */
+ get_ata_serial(lc, fd, di) || /* Get ATA serial number. */
+ get_scsi_serial(lc, fd, di, OLD); /* OLD: Old scsi ioctl. */
}
-static int di_ioctl(struct lib_context *lc, int fd, struct dev_info *di)
+static int
+di_ioctl(struct lib_context *lc, int fd, struct dev_info *di)
{
unsigned int sector_size = 0;
unsigned long size;
@@ -156,11 +161,12 @@
return get_dm_test_serial(lc, di, di->path);
else
#endif
- return get_device_serial(lc, fd, di);
+ return get_device_serial(lc, fd, di);
}
/* Are we interested in this device ? */
-static int interested(struct lib_context *lc, char *path)
+static int
+interested(struct lib_context *lc, char *path)
{
char *name = get_basename(lc, path);
@@ -168,19 +174,19 @@
* Whole IDE and SCSI disks only.
*/
return (!isdigit(name[strlen(name) - 1]) &&
- (*(name + 1) == 'd' && (*name == 'h' || *name == 's')))
-
+ (*(name + 1) == 'd' && (*name == 'h' || *name == 's')))
#ifdef DMRAID_TEST
- /*
- * Include dm devices for testing.
- */
+ /*
+ * Include dm devices for testing.
+ */
|| dm_test_device(lc, path)
#endif
- ;
+ ;
}
/* Ask sysfs, if a device is removable. */
-int removable_device(struct lib_context *lc, char *dev_path)
+int
+removable_device(struct lib_context *lc, char *dev_path)
{
int ret = 0;
char buf[2], *name, *sysfs_path, *sysfs_file;
@@ -200,8 +206,7 @@
sprintf(sysfs_file, "%s/%s/%s", sysfs_path, name, sysfs_removable);
if ((f = fopen(sysfs_file, "r"))) {
/* Using fread for klibc compatibility. */
- if (fread(buf, sizeof(char), sizeof(buf) - 1, f) &&
- *buf == '1') {
+ if (fread(buf, sizeof(char), sizeof(buf) - 1, f) && *buf == '1') {
log_notice(lc, "skipping removable device %s",
dev_path);
ret = 1;
@@ -212,7 +217,7 @@
dbg_free(sysfs_file);
- out:
+ out:
dbg_free(sysfs_path);
return ret;
@@ -222,8 +227,9 @@
* Read the size in sectors from the sysfs "size" file.
* Avoid access to removable devices.
*/
-static int sysfs_get_size(struct lib_context *lc, struct dev_info *di,
- const char *path, char *name)
+static int
+sysfs_get_size(struct lib_context *lc, struct dev_info *di,
+ const char *path, char *name)
{
int ret = 0;
char buf[22], *sysfs_file;
@@ -253,8 +259,8 @@
return ret;
}
-static int get_size(struct lib_context *lc, char *path,
- char *name, int sysfs)
+static int
+get_size(struct lib_context *lc, char *path, char *name, int sysfs)
{
int fd, ret = 0;
char *dev_path;
@@ -282,7 +288,7 @@
close(fd);
- out:
+ out:
dbg_free(dev_path);
if (!ret && di)
@@ -295,7 +301,8 @@
* Find disk devices in sysfs or directly
* in /dev (for Linux 2.4) and keep information.
*/
-int discover_devices(struct lib_context *lc, char **devnodes)
+int
+discover_devices(struct lib_context *lc, char **devnodes)
{
int sysfs, ret = 0;
char *path, *p;
@@ -307,7 +314,7 @@
path = p;
} else {
sysfs = 0;
- path = (char*) _PATH_DEV;
+ path = (char *) _PATH_DEV;
log_print(lc, "carrying on with %s", path);
}
@@ -328,7 +335,7 @@
closedir(d);
ret = 1;
- out:
+ out:
if (p)
dbg_free(p);
--- dmraid/lib/device/scsi.c 2008/02/22 16:57:35 1.1
+++ dmraid/lib/device/scsi.c 2008/06/20 21:52:17 1.2
@@ -1,7 +1,10 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
@@ -21,11 +24,12 @@
/* Thx scsiinfo. */
/* Initialize SCSI inquiry command block (used both with SG and old ioctls). */
-static void set_cmd(unsigned char *cmd, size_t len)
+static void
+set_cmd(unsigned char *cmd, size_t len)
{
- cmd[0] = 0x12; /* INQUIRY */
+ cmd[0] = 0x12; /* INQUIRY */
cmd[1] = 1;
- cmd[2] = 0x80; /* page code: SCSI serial */
+ cmd[2] = 0x80; /* page code: SCSI serial */
cmd[3] = 0;
cmd[4] = (unsigned char) (len & 0xff);
cmd[5] = 0;
@@ -34,7 +38,8 @@
/*
* SCSI SG_IO ioctl to get serial number of a unit.
*/
-static int sg_inquiry(int fd, unsigned char *response, size_t response_len)
+static int
+sg_inquiry(int fd, unsigned char *response, size_t response_len)
{
unsigned char cmd[6];
struct sg_io_hdr io_hdr;
@@ -43,30 +48,29 @@
/* Initialize generic (SG) SCSI ioctl header. */
memset(&io_hdr, 0, sizeof(io_hdr));
- io_hdr.interface_id = 'S';
- io_hdr.cmdp = cmd;
- io_hdr.cmd_len = sizeof(cmd);
- io_hdr.sbp = NULL;
- io_hdr.mx_sb_len = 0;
- io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
- io_hdr.dxferp = response;
- io_hdr.dxfer_len = response_len;
- io_hdr.timeout = 6000; /* [ms] */
-
+ io_hdr.interface_id = 'S';
+ io_hdr.cmdp = cmd;
+ io_hdr.cmd_len = sizeof(cmd);
+ io_hdr.sbp = NULL;
+ io_hdr.mx_sb_len = 0;
+ io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+ io_hdr.dxferp = response;
+ io_hdr.dxfer_len = response_len;
+ io_hdr.timeout = 6000; /* [ms] */
return ioctl(fd, SG_IO, &io_hdr) ? 0 : 1;
}
/*
* Old SCSI ioctl as fallback to get serial number of a unit.
*/
-static int old_inquiry(int fd, unsigned char *response, size_t response_len)
+static int
+old_inquiry(int fd, unsigned char *response, size_t response_len)
{
- unsigned int *i = (unsigned int*) response;
-
- i[0] = 0; /* input data length */
- i[1] = response_len; /* output buffer length */
- set_cmd((unsigned char*) &i[2], response_len);
+ unsigned int *i = (unsigned int *) response;
+ i[0] = 0; /* input data length */
+ i[1] = response_len; /* output buffer length */
+ set_cmd((unsigned char *) &i[2], response_len);
return ioctl(fd, SCSI_IOCTL_SEND_COMMAND, response) ? 0 : 1;
}
@@ -74,8 +78,9 @@
* Retrieve SCSI serial number.
*/
#define MAX_RESPONSE_LEN 255
-int get_scsi_serial(struct lib_context *lc, int fd, struct dev_info *di,
- enum ioctl_type type)
+int
+get_scsi_serial(struct lib_context *lc, int fd, struct dev_info *di,
+ enum ioctl_type type)
{
int ret = 0;
size_t actual_len;
@@ -85,11 +90,11 @@
* string length field (serial string follows length field immediately)
*/
struct {
- int (*ioctl_func)(int, unsigned char*, size_t);
+ int (*ioctl_func) (int, unsigned char *, size_t);
unsigned int start;
} param[] = {
- { sg_inquiry , 3 },
- { old_inquiry, 11 },
+ { sg_inquiry, 3},
+ { old_inquiry, 11},
}, *p = (SG == type) ? param : param + 1;
if (!(response = dbg_malloc(MAX_RESPONSE_LEN)))
@@ -104,10 +109,32 @@
ret = p->ioctl_func(fd, response, actual_len);
}
- ret = ret && (di->serial = dbg_strdup(remove_white_space(lc, (char*) &response[p->start + 1], serial_len)));
+ ret = ret &&
+ (di->serial = dbg_strdup(remove_white_space (lc, (char *) &response[p->start + 1], serial_len)));
}
dbg_free(response);
+ return ret;
+}
+
+int
+get_scsi_id(struct lib_context *lc, int fd, struct sg_scsi_id *sg_id)
+{
+ int ret = 1;
+
+ struct scsi_idlun {
+ int four_in_one;
+ int host_uniqe_id;
+ } lun;
+
+ if (!ioctl(fd, SCSI_IOCTL_GET_IDLUN, &lun)) {
+ sg_id->host_no = (lun.four_in_one >> 24) & 0xff;
+ sg_id->channel = (lun.four_in_one >> 16) & 0xff;
+ sg_id->scsi_id = lun.four_in_one & 0xff;
+ sg_id->lun = (lun.four_in_one >> 8) & 0xff;
+ } else
+ ret = 0;
return ret;
+
}
--- dmraid/lib/device/scsi.h 2008/02/22 16:57:35 1.1
+++ dmraid/lib/device/scsi.h 2008/06/20 21:52:17 1.2
@@ -1,13 +1,18 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
#ifndef _SCSI_H_
#define _SCSI_H_
+#include <scsi/sg.h>
+
/* Ioctl types possible (SG = SCSI generic, OLD = old SCSI command ioctl. */
enum ioctl_type {
SG,
@@ -16,5 +21,6 @@
int get_scsi_serial(struct lib_context *lc, int fd,
struct dev_info *di, enum ioctl_type type);
+int get_scsi_id(struct lib_context *lc, int fd, struct sg_scsi_id *sg_id);
#endif
--- dmraid/lib/display/display.c 2008/02/22 16:57:35 1.1
+++ dmraid/lib/display/display.c 2008/06/20 21:52:17 1.2
@@ -14,28 +14,32 @@
struct log_handler {
const char *field;
const unsigned char minlen;
- void (*log_func)(struct lib_context*, void *arg);
+ void (*log_func) (struct lib_context *, void *arg);
void *arg;
};
-static void log_string(struct lib_context *lc, void *arg)
+static void
+log_string(struct lib_context *lc, void *arg)
{
- log_print_nnl(lc, "%s", (char*) arg);
+ log_print_nnl(lc, "%s", (char *) arg);
}
-static void log_uint64(struct lib_context *lc, void *arg)
+static void
+log_uint64(struct lib_context *lc, void *arg)
{
- log_print_nnl(lc, "%" PRIu64, *((uint64_t*) arg));
+ log_print_nnl(lc, "%" PRIu64, *((uint64_t *) arg));
}
-static void log_uint(struct lib_context *lc, void *arg)
+static void
+log_uint(struct lib_context *lc, void *arg)
{
- log_print_nnl(lc, "%u", *((unsigned int*) arg));
+ log_print_nnl(lc, "%u", *((unsigned int *) arg));
}
/* Log a structure member by field name. */
-static int log_field(struct lib_context *lc, const struct log_handler *lh,
- size_t lh_size, char *field)
+static int
+log_field(struct lib_context *lc, const struct log_handler *lh,
+ size_t lh_size, char *field)
{
const struct log_handler *h;
@@ -55,13 +59,14 @@
}
/* Log a list of structure members by field name. */
-static void log_fields(struct lib_context *lc, const struct log_handler *lh,
- size_t lh_size) {
+static void
+log_fields(struct lib_context *lc, const struct log_handler *lh, size_t lh_size)
+{
int logged = 0, last_logged = 0;
const char delim = *OPT_STR_SEPARATOR(lc);
char *p, *sep, *sep_sav;
- if (!(sep_sav = dbg_strdup((char*) OPT_STR_COLUMN(lc)))) {
+ if (!(sep_sav = dbg_strdup((char *) OPT_STR_COLUMN(lc)))) {
log_alloc_err(lc, __func__);
return;
}
@@ -83,28 +88,30 @@
}
/* Display information about a block device */
-static void log_disk(struct lib_context *lc, struct list_head *pos)
+static void
+log_disk(struct lib_context *lc, struct list_head *pos)
{
struct dev_info *di = list_entry(pos, typeof(*di), list);
if (OPT_STR_COLUMN(lc)) {
const struct log_handler log_handlers[] = {
- { "devpath", 1, log_string, di->path},
- { "path", 1, log_string, di->path},
- { "sectors", 3, log_uint64, &di->sectors},
- { "serialnumber", 3, log_string,
- di->serial ? (void*) di->serial : (void*) "N/A"},
- { "size", 2, log_uint64, &di->sectors},
+ {"devpath", 1, log_string, di->path},
+ {"path", 1, log_string, di->path},
+ {"sectors", 3, log_uint64, &di->sectors},
+ {"serialnumber", 3, log_string,
+ di->serial ? (void *) di->serial : (void *) "N/A"},
+ {"size", 2, log_uint64, &di->sectors},
};
log_fields(lc, log_handlers, ARRAY_SIZE(log_handlers));
- } else {
+ }
+ else {
const char *fmt[] = {
"%s: %12" PRIu64 " total, \"%s\"",
"%s",
"%s:%" PRIu64 ":\"%s\"",
};
-
+
log_print(lc, fmt[ARRAY_LIMIT(fmt, OPT_COLUMN(lc))],
di->path, di->sectors,
di->serial ? di->serial : "N/A");
@@ -112,54 +119,59 @@
}
/* Turn NULL (= "unknown") into a displayable string. */
-static const char *check_null(const char *str)
+static const char *
+check_null(const char *str)
{
return str ? str : "unknown";
}
/* Log native RAID device information. */
-static void log_rd_native(struct lib_context *lc, struct list_head *pos)
+static void
+log_rd_native(struct lib_context *lc, struct list_head *pos)
{
struct raid_dev *rd = list_entry(pos, typeof(*rd), list);
if (rd->fmt->log) {
rd->fmt->log(lc, rd);
log_print(lc, "");
- } else
+ }
+ else
log_print(lc, "\"%s\" doesn't support native logging of RAID "
"device information", rd->fmt->name);
}
/* Display information about a RAID device */
-static void log_rd(struct lib_context *lc, struct list_head *pos)
+static void
+log_rd(struct lib_context *lc, struct list_head *pos)
{
struct raid_dev *rd = list_entry(pos, typeof(*rd), list);
if (OPT_STR_COLUMN(lc)) {
const struct log_handler log_handlers[] = {
- { "dataoffset", 2, log_uint64, &rd->offset},
- { "devpath", 2, log_string, rd->di->path },
- { "format", 1, log_string, (void*) rd->fmt->name },
- { "offset", 1, log_uint64, &rd->offset},
- { "path", 1, log_string, rd->di->path },
- { "raidname", 1, log_string, rd->name },
- { "type", 1, log_string,
- (void*) check_null(get_type(lc, rd->type)) },
- { "sectors", 2, log_uint64, &rd->sectors},
- { "size", 2, log_uint64, &rd->sectors},
- { "status", 2, log_string,
- (void*) check_null(get_status(lc, rd->status)) },
+ {"dataoffset", 2, log_uint64, &rd->offset},
+ {"devpath", 2, log_string, rd->di->path},
+ {"format", 1, log_string, (void *) rd->fmt->name},
+ {"offset", 1, log_uint64, &rd->offset},
+ {"path", 1, log_string, rd->di->path},
+ {"raidname", 1, log_string, rd->name},
+ {"type", 1, log_string,
+ (void *) check_null(get_type(lc, rd->type))},
+ {"sectors", 2, log_uint64, &rd->sectors},
+ {"size", 2, log_uint64, &rd->sectors},
+ {"status", 2, log_string,
+ (void *) check_null(get_status(lc, rd->status))},
};
log_fields(lc, log_handlers, ARRAY_SIZE(log_handlers));
- } else {
+ }
+ else {
const char *fmt[] = {
"%s: %s, \"%s\", %s, %s, %" PRIu64 " sectors, "
- "data@ %" PRIu64,
+ "data@ %" PRIu64,
"%s",
"%s:%s:%s:%s:%s:%" PRIu64 ":%" PRIu64,
};
-
+
log_print(lc, fmt[ARRAY_LIMIT(fmt, OPT_COLUMN(lc))],
rd->di->path, rd->fmt->name, rd->name,
check_null(get_type(lc, rd->type)),
@@ -169,17 +181,18 @@
}
/* Dispatch log functions. */
-static void log_devices(struct lib_context *lc, enum dev_type type)
+static void
+log_devices(struct lib_context *lc, enum dev_type type)
{
struct list_head *pos;
struct {
enum dev_type type;
struct list_head *list;
- void (*log)(struct lib_context *, struct list_head *);
+ void (*log) (struct lib_context *, struct list_head *);
} types[] = {
{ DEVICE, LC_DI(lc), log_disk },
{ NATIVE, LC_RD(lc), log_rd_native },
- { RAID, LC_RD(lc), log_rd },
+ { RAID, LC_RD(lc), log_rd },
}, *t = types;
do {
@@ -189,13 +202,14 @@
return;
}
- } while (t++ < ARRAY_END(types));
+ } while (++t < ARRAY_END(types));
- LOG_ERR(lc, , "%s: unknown device type", __func__);
+ LOG_ERR(lc,, "%s: unknown device type", __func__);
}
/* Display information about a dmraid format handler */
-static void log_format(struct lib_context *lc, struct dmraid_format *fmt)
+static void
+log_format(struct lib_context *lc, struct dmraid_format *fmt)
{
log_print_nnl(lc, "%-7s : %s", fmt->name, fmt->descr);
if (fmt->caps)
@@ -205,7 +219,8 @@
}
/* Pretty print a mapping table. */
-void display_table(struct lib_context *lc, char *rs_name, char *table)
+void
+display_table(struct lib_context *lc, char *rs_name, char *table)
{
char *nl = table, *p;
@@ -217,89 +232,92 @@
}
/* Display information about devices depending on device type. */
-void display_devices(struct lib_context *lc, enum dev_type type)
+void
+display_devices(struct lib_context *lc, enum dev_type type)
{
int devs;
if ((devs = count_devices(lc, type))) {
log_info(lc, "%s device%s discovered:\n",
- (type & (RAID|NATIVE)) ? "RAID" : "Block",
- devs == 1 ? "" : "s");
+ (type & (RAID | NATIVE)) ? "RAID" : "Block",
+ devs == 1 ? "" : "s");
log_devices(lc, type);
}
}
/* Retrieve format name from (hierarchical) raid set. */
-static void *get_format_name(struct raid_set *rs)
+static void *
+get_format_name(struct raid_set *rs)
{
struct dmraid_format *fmt = get_format(rs);
- return (void*) check_null(fmt ? fmt->name : NULL);
+ return (void *) check_null(fmt ? fmt->name : NULL);
}
-static void log_rs(struct lib_context *lc, struct raid_set *rs)
+static void
+log_rs(struct lib_context *lc, struct raid_set *rs)
{
unsigned int devs = 0, spares = 0, subsets = 0;
uint64_t sectors = 0;
if (T_GROUP(rs) && !OPT_GROUP(lc))
return;
-
+
sectors = total_sectors(lc, rs);
subsets = count_sets(lc, &rs->sets);
- devs = count_devs(lc, rs, ct_dev);
- spares = count_devs(lc, rs, ct_spare);
-
+ devs = count_devs(lc, rs, ct_dev);
+ spares = count_devs(lc, rs, ct_spare);
+
if (OPT_STR_COLUMN(lc)) {
const struct log_handler log_handlers[] = {
- { "devices", 1, log_uint, &devs },
- { "format", 1, log_string, get_format_name(rs) },
- { "raidname", 1, log_string, rs->name },
- { "sectors", 2, log_uint64, §ors },
- { "size", 2, log_uint64, §ors },
- { "spares", 2, log_uint, &spares },
- { "status", 3, log_string,
- (void*) check_null(get_status(lc, rs->status)) },
- { "stride", 3, log_uint, &rs->stride },
- { "subsets", 2, log_uint, &subsets },
- { "type", 1, log_string,
- (void*) check_null(get_set_type(lc, rs)) },
+ {"devices", 1, log_uint, &devs},
+ {"format", 1, log_string, get_format_name(rs)},
+ {"raidname", 1, log_string, rs->name},
+ {"sectors", 2, log_uint64, §ors},
+ {"size", 2, log_uint64, §ors},
+ {"spares", 2, log_uint, &spares},
+ {"status", 3, log_string,
+ (void *) check_null(get_status(lc, rs->status))},
+ {"stride", 3, log_uint, &rs->stride},
+ {"subsets", 2, log_uint, &subsets},
+ {"type", 1, log_string,
+ (void *) check_null(get_set_type(lc, rs))},
};
log_fields(lc, log_handlers, ARRAY_SIZE(log_handlers));
- } else {
+ }
+ else {
const char *fmt[] = {
"name : %s\n"
- "size : %" PRIu64 "\n"
- "stride : %u\n"
- "type : %s\n"
- "status : %s\n"
- "subsets: %u\n"
- "devs : %u\n"
- "spares : %u",
+ "size : %" PRIu64 "\n"
+ "stride : %u\n"
+ "type : %s\n"
+ "status : %s\n"
+ "subsets: %u\n" "devs : %u\n" "spares : %u",
"%s",
"%s:%" PRIu64 ":%u:%s:%s:%u:%u:%u",
};
unsigned int o = ARRAY_LIMIT(fmt, lc_opt(lc, LC_COLUMN));
-
+
log_print(lc, fmt[o],
rs->name, sectors, rs->stride,
check_null(get_set_type(lc, rs)),
check_null(get_status(lc, rs->status)),
subsets, devs, spares);
-
+
}
if (OPT_COLUMN(lc) > 2) {
struct raid_dev *rd;
-
+
list_for_each_entry(rd, &rs->devs, devs)
log_rd(lc, &rd->list);
}
}
-static int group_active(struct lib_context *lc, struct raid_set *rs)
+static int
+group_active(struct lib_context *lc, struct raid_set *rs)
{
struct raid_set *r;
@@ -312,8 +330,8 @@
}
/* FIXME: Spock, do something better (neater). */
-void display_set(struct lib_context *lc, void *v,
- enum active_type active, int top)
+void
+display_set(struct lib_context *lc, void *v, enum active_type active, int top)
{
struct raid_set *rs = v;
struct raid_set *r;
@@ -328,20 +346,19 @@
log_print(lc, "*** Group superset %s", rs->name);
else {
log_print(lc, "%s %s%s%set",
- top ? "-->" : "***",
- S_INCONSISTENT(rs->status) ?
- "*Inconsistent* " : "",
- dm_status(lc, rs) ? "Active " : "",
- SETS(rs) ? "Supers" : (top ? "Subs" : "S"));
+ top ? "-->" : "***",
+ S_INCONSISTENT(rs->status) ?
+ "*Inconsistent* " : "",
+ dm_status(lc, rs) ? "Active " : "",
+ SETS(rs) ? "Supers" : (top ? "Subs" : "S"));
}
}
log_rs(lc, rs);
/* Optionally display subsets. */
- if (T_GROUP(rs) || /* Always display for GROUP sets. */
- OPT_SETS(lc) > 1 ||
- OPT_COLUMN(lc) > 2) {
+ if (T_GROUP(rs) || /* Always display for GROUP sets. */
+ OPT_SETS(lc) > 1 || OPT_COLUMN(lc) > 2) {
list_for_each_entry(r, &rs->sets, list)
display_set(lc, r, active, ++top);
}
@@ -351,7 +368,8 @@
* Display information about supported RAID metadata formats
* (ie. registered format handlers)
*/
-static void _list_formats(struct lib_context *lc, enum fmt_type type)
+static void
+_list_formats(struct lib_context *lc, enum fmt_type type)
{
struct format_list *fmt_list;
@@ -361,7 +379,8 @@
}
}
-int list_formats(struct lib_context *lc, int arg)
+int
+list_formats(struct lib_context *lc, int arg)
{
log_info(lc, "supported metadata formats:");
_list_formats(lc, FMT_RAID);
--- dmraid/lib/format/format.c 2008/04/02 13:35:31 1.4
+++ dmraid/lib/format/format.c 2008/06/20 21:52:17 1.5
@@ -1,7 +1,10 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
@@ -46,30 +49,39 @@
{ "name", offset(name), FMT_ALL },
{ "description", offset(descr), FMT_ALL },
{ "capabilities", offset(caps), 0 },
- { "read", offset(read), FMT_ALL|FMT_METHOD },
+ { "read", offset(read), FMT_ALL | FMT_METHOD },
{ "write", offset(write), FMT_METHOD },
- { "group", offset(group), FMT_ALL|FMT_METHOD },
- { "check", offset(check), FMT_ALL|FMT_METHOD },
+ { "create", offset(create), FMT_METHOD },
+ { "delete", offset(delete), FMT_METHOD },
+ { "group", offset(group), FMT_ALL | FMT_METHOD },
+ { "check", offset(check), FMT_ALL | FMT_METHOD },
{ "events array", offset(events), 0 },
#ifdef NATIVE_LOG
{ "log", offset(log), FMT_METHOD },
#endif
};
+
#undef offset
-static int check_member(struct lib_context *lc, struct dmraid_format *fmt,
- struct format_member *member)
+static int
+check_member(struct lib_context *lc, struct dmraid_format *fmt,
+ struct format_member *member)
{
if ((!IS_FMT_ALL(member) && fmt->format != FMT_RAID) ||
- *((unsigned long*) (((unsigned char*) fmt) + member->offset)))
+ *((unsigned long *) (((unsigned char *) fmt) + member->offset)))
return 0;
- LOG_ERR(lc, 1, "%s: missing metadata format handler %s%s",
- fmt->name, member->msg, IS_FMT_METHOD(member) ? " method" : "");
+ /* show error in case method is required for all handlers */
+ if (IS_FMT_ALL(member))
+ LOG_ERR(lc, 1, "%s: missing metadata format handler %s%s",
+ fmt->name, member->msg,
+ IS_FMT_METHOD(member) ? " method" : "");
+
+ return 0;
}
-static int check_format_handler(struct lib_context *lc,
- struct dmraid_format *fmt)
+static int
+check_format_handler(struct lib_context *lc, struct dmraid_format *fmt)
{
unsigned int error = 0;
struct format_member *fm = format_member;
@@ -87,7 +99,8 @@
/*
* Register a RAID metadata format handler.
*/
-int register_format_handler(struct lib_context *lc, struct dmraid_format *fmt)
+int
+register_format_handler(struct lib_context *lc, struct dmraid_format *fmt)
{
struct format_list *fl;
@@ -99,7 +112,8 @@
if ((fl = dbg_malloc(sizeof(*fl)))) {
fl->fmt = fmt;
list_add_tail(&fl->list, LC_FMT(lc));
- }
+ } else
+ log_alloc_err(lc, __func__);
return fl ? 1 : 0;
}
@@ -110,13 +124,14 @@
* I use an array because of the growing number...
*/
static struct register_fh {
- int (*func)(struct lib_context *lc);
+ int (*func) (struct lib_context * lc);
} register_fh[] = {
#include "register.h"
{ NULL },
};
-void unregister_format_handlers(struct lib_context *lc)
+void
+unregister_format_handlers(struct lib_context *lc)
{
struct list_head *elem, *tmp;
@@ -126,7 +141,8 @@
}
}
-int register_format_handlers(struct lib_context *lc)
+int
+register_format_handlers(struct lib_context *lc)
{
int ret = 1;
struct register_fh *fh;
@@ -143,6 +159,7 @@
return ret;
}
+
/* END metadata format handler registry. */
@@ -151,7 +168,8 @@
*/
/* Allocate private space in format handlers (eg, for on-disk metadata). */
-void *alloc_private(struct lib_context *lc, const char *who, size_t size)
+void *
+alloc_private(struct lib_context *lc, const char *who, size_t size)
{
void *ret;
@@ -162,8 +180,9 @@
}
/* Allocate private space in format handlers and read data off device. */
-void *alloc_private_and_read(struct lib_context *lc, const char *who,
- size_t size, char *path, loff_t offset)
+void *
+alloc_private_and_read(struct lib_context *lc, const char *who,
+ size_t size, char *path, loff_t offset)
{
void *ret;
@@ -179,8 +198,9 @@
/* Allocate metadata sector array in format handlers. */
-void *alloc_meta_areas(struct lib_context *lc, struct raid_dev *rd,
- const char *who, unsigned int n)
+void *
+alloc_meta_areas(struct lib_context *lc, struct raid_dev *rd,
+ const char *who, unsigned int n)
{
void *ret;
@@ -191,8 +211,9 @@
}
/* Simple metadata write function for format handlers. */
-static int _write_metadata(struct lib_context *lc, const char *handler,
- struct raid_dev *rd, int idx, int erase)
+static int
+_write_metadata(struct lib_context *lc, const char *handler,
+ struct raid_dev *rd, int idx, int erase)
{
int ret = 0;
void *p, *tmp;
@@ -205,25 +226,26 @@
!(p = alloc_private(lc, handler, rd->meta_areas[idx].size)))
goto out;
- ret = write_file(lc, handler, rd->di->path, (void*) p,
+ ret = write_file(lc, handler, rd->di->path, (void *) p,
rd->meta_areas[idx].size,
rd->meta_areas[idx].offset << 9);
- log_level(lc, ret ? _PLOG_DEBUG : _PLOG_ERR,
+ log_level(lc, ret ? _PLOG_DEBUG : _PLOG_ERR,
"writing metadata to %s, offset %" PRIu64 " sectors, "
"size %zu bytes returned %d",
rd->di->path, rd->meta_areas[idx].offset,
- rd->meta_areas[idx].size, ret);
+ rd->meta_areas[idx].size, ret);
if (p != tmp)
dbg_free(p);
- out:
+ out:
return ret;
}
-int write_metadata(struct lib_context *lc, const char *handler,
- struct raid_dev *rd, int idx, int erase)
+int
+write_metadata(struct lib_context *lc, const char *handler,
+ struct raid_dev *rd, int idx, int erase)
{
unsigned int i;
@@ -244,16 +266,16 @@
* a. spares in a mirror set need to be large enough.
* b. # of devices correct.
*/
-static void _check_raid_set(struct lib_context *lc, struct raid_set *rs,
- unsigned int (*f_devices)(struct raid_dev *rd,
- void *context),
- void *f_devices_context,
- int (*f_check)(struct lib_context *lc,
- struct raid_set *rs,
- struct raid_dev *rd,
- void *context),
- void *f_check_context,
- const char *handler)
+static void
+_check_raid_set(struct lib_context *lc, struct raid_set *rs,
+ unsigned int (*f_devices) (struct raid_dev * rd,
+ void *context),
+ void *f_devices_context,
+ int (*f_check) (struct lib_context * lc,
+ struct raid_set * rs,
+ struct raid_dev * rd,
+ void *context),
+ void *f_check_context, const char *handler)
{
unsigned int devs;
uint64_t sectors;
@@ -270,8 +292,7 @@
rs->found_devs = devices;
log_dbg(lc, "checking %s device \"%s\"", handler, rd->di->path);
- if (T_SPARE(rd) &&
- rs->type == t_raid1 && /* FIXME: rs->type check ? */
+ if (T_SPARE(rd) && rs->type == t_raid1 && /* FIXME: rs->type check ? */
rd->sectors != sectors) {
rd->status = s_inconsistent;
log_err(lc, "%s: size mismatch in set \"%s\", spare "
@@ -280,12 +301,11 @@
}
if (devs != devices &&
- f_check &&
- !f_check(lc, rs, rd, f_check_context)) {
+ f_check && !f_check(lc, rs, rd, f_check_context)) {
rd->status = s_broken;
log_err(lc, "%s: wrong # of devices in RAID "
"set \"%s\" [%u/%u] on %s",
- handler, rs->name, devs, devices, rd->di->path);
+ handler, rs->name, devs, devices, rd->di->path);
} else
rd->status = s_ok;
}
@@ -301,8 +321,9 @@
* In case of lowest level RAID sets, check consistence of devices
* and make the above decision at the device level.
*/
-static void _set_rs_status(struct lib_context *lc, struct raid_set *rs,
- unsigned int i, unsigned int operational)
+static void
+_set_rs_status(struct lib_context *lc, struct raid_set *rs,
+ unsigned int i, unsigned int operational)
{
if (operational == i)
rs->status = s_ok;
@@ -314,7 +335,8 @@
log_dbg(lc, "set status of set \"%s\" to %u", rs->name, rs->status);
}
-static int set_rs_status(struct lib_context *lc, struct raid_set *rs)
+static int
+set_rs_status(struct lib_context *lc, struct raid_set *rs)
{
unsigned int i = 0, operational = 0;
struct raid_set *r;
@@ -327,16 +349,15 @@
if (S_OK(r->status) || S_INCONSISTENT(r->status))
operational++;
}
-
+
/* Check status of devices... */
list_for_each_entry(rd, &rs->devs, devs) {
i++;
if (S_OK(rd->status))
operational++;
}
-
- _set_rs_status(lc, rs, i, operational);
+ _set_rs_status(lc, rs, i, operational);
return S_BROKEN(rs->status) ? 0 : 1;
}
@@ -346,14 +367,14 @@
* This tiny helper function avoids coding recursive
* RAID set stack unrolling in every metadata format handler.
*/
-int check_raid_set(struct lib_context *lc, struct raid_set *rs,
- unsigned int (*f_devices)(struct raid_dev *rd,
- void *context),
- void *f_devices_context,
- int (*f_check)(struct lib_context *lc, struct raid_set *r,
- struct raid_dev *rd, void *context),
- void *f_check_context,
- const char *handler)
+int
+check_raid_set(struct lib_context *lc, struct raid_set *rs,
+ unsigned int (*f_devices) (struct raid_dev * rd,
+ void *context),
+ void *f_devices_context,
+ int (*f_check) (struct lib_context * lc, struct raid_set * r,
+ struct raid_dev * rd, void *context),
+ void *f_check_context, const char *handler)
{
struct raid_set *r;
@@ -370,9 +391,10 @@
}
/* Initialize a RAID sets type and stride. */
-int init_raid_set(struct lib_context *lc, struct raid_set *rs,
- struct raid_dev *rd, unsigned int stride,
- unsigned int type, const char *handler)
+int
+init_raid_set(struct lib_context *lc, struct raid_set *rs,
+ struct raid_dev *rd, unsigned int stride,
+ unsigned int type, const char *handler)
{
if (T_UNDEF(rd))
LOG_ERR(lc, 0, "%s: RAID type %u not supported", handler, type);
@@ -395,22 +417,21 @@
}
/* Discover RAID metadata and setup RAID device. */
-struct raid_dev *read_raid_dev(
- struct lib_context *lc,
- struct dev_info *di,
- void* (*f_read_metadata)(struct lib_context *lc, struct dev_info *di,
- size_t *size, uint64_t *offset,
- union read_info *info),
- size_t size, uint64_t offset,
- void (*f_to_cpu)(void *meta),
- int (*f_is_meta)(struct lib_context *lc, struct dev_info *di,
- void *meta),
- void (*f_file_metadata)(struct lib_context *lc, struct dev_info *di,
+struct raid_dev *
+read_raid_dev(struct lib_context *lc,
+ struct dev_info *di,
+ void *(*f_read_metadata) (struct lib_context * lc,
+ struct dev_info * di, size_t * size,
+ uint64_t * offset,
+ union read_info * info), size_t size,
+ uint64_t offset, void (*f_to_cpu) (void *meta),
+ int (*f_is_meta) (struct lib_context * lc, struct dev_info * di,
void *meta),
- int (*f_setup_rd)(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta,
- union read_info *info),
- const char *handler)
+ void (*f_file_metadata) (struct lib_context * lc,
+ struct dev_info * di, void *meta),
+ int (*f_setup_rd) (struct lib_context * lc, struct raid_dev * rd,
+ struct dev_info * di, void *meta,
+ union read_info * info), const char *handler)
{
struct raid_dev *rd = NULL;
void *meta;
@@ -421,10 +442,9 @@
* metadata read function, use that. If not, allocate and
* read size from offset.
*/
- meta = f_read_metadata ? f_read_metadata(lc, di, &size, &offset,
- &info) :
- alloc_private_and_read(lc, handler, size,
- di->path, offset);
+ meta = f_read_metadata ?
+ f_read_metadata(lc, di, &size, &offset, &info) :
+ alloc_private_and_read(lc, handler, size, di->path, offset);
if (!meta)
goto out;
@@ -456,14 +476,15 @@
free_raid_dev(lc, &rd);
goto out;
- bad:
+ bad:
dbg_free(meta);
- out:
+ out:
return rd;
}
/* Check if format identifier is valid. */
-int check_valid_format(struct lib_context *lc, char *name)
+int
+check_valid_format(struct lib_context *lc, char *name)
{
struct format_list *fl;
@@ -479,13 +500,14 @@
/*
* Set up a format capabilities (ie, RAID levels) string array.
*/
-const char **get_format_caps(struct lib_context *lc, struct dmraid_format *fmt)
+const char **
+get_format_caps(struct lib_context *lc, struct dmraid_format *fmt)
{
int i;
char *caps, *p;
const char **ret = NULL, delim = ',';
- if (fmt->caps && (caps = dbg_strdup((char*) fmt->caps))) {
+ if (fmt->caps && (caps = dbg_strdup((char *) fmt->caps))) {
/* Count capabilities delimiters. */
for (i = 0, p = caps; (p = remove_delimiter(p, delim)); i++)
add_delimiter(&p, delim);
@@ -494,17 +516,20 @@
for (i = 0, p = caps - 1; p;
(p = remove_delimiter(p, delim)))
ret[i++] = ++p;
- } else
+ } else {
+ log_alloc_err(lc, __func__);
dbg_free(caps);
+ }
}
return ret;
}
-void free_format_caps(struct lib_context *lc, const char **caps)
+void
+free_format_caps(struct lib_context *lc, const char **caps)
{
if (caps) {
- dbg_free((char*) *caps);
+ dbg_free((char *) *caps);
dbg_free(caps);
}
}
@@ -512,16 +537,16 @@
/*
* Allocate a RAID superset and link the subset to it.
*/
-struct raid_set *join_superset(struct lib_context *lc,
- char *(*f_name)(struct lib_context *lc,
- struct raid_dev *rd,
- unsigned int subset),
- void (*f_create)(struct raid_set *super,
- void *private),
- int (*f_set_sort)(struct list_head *pos,
- struct list_head *new),
- struct raid_set *rs,
- struct raid_dev *rd)
+struct raid_set *
+join_superset(struct lib_context *lc,
+ char *(*f_name) (struct lib_context * lc,
+ struct raid_dev * rd,
+ unsigned int subset),
+ void (*f_create) (struct raid_set * super,
+ void *private),
+ int (*f_set_sort) (struct list_head * pos,
+ struct list_head * new),
+ struct raid_set *rs, struct raid_dev *rd)
{
char *n;
struct raid_set *ret = NULL;
@@ -539,7 +564,8 @@
}
/* Display 'zero sectors on RAID' device error. */
-int log_zero_sectors(struct lib_context *lc, char *path, const char *handler)
+int
+log_zero_sectors(struct lib_context *lc, char *path, const char *handler)
{
LOG_ERR(lc, 0, "%s: zero sectors on %s", handler, path);
}
--- dmraid/lib/format/register.h 2008/02/22 17:04:35 1.2
+++ dmraid/lib/format/register.h 2008/06/20 21:52:17 1.3
@@ -15,7 +15,7 @@
#define xx(type) { register_ ## type },
/* Metadata format handlers. */
- xx(asr)
+xx(asr)
xx(ddf1)
xx(hpt37x)
xx(hpt45x)
@@ -29,6 +29,5 @@
/* DOS partition type handler. */
xx(dos)
-
#undef xx
#endif
--- dmraid/lib/format/ataraid/asr.c 2008/04/02 13:35:31 1.4
+++ dmraid/lib/format/ataraid/asr.c 2008/06/20 21:52:17 1.5
@@ -30,7 +30,9 @@
static const char *spare_array = ".asr_spares";
/* Map ASR disk status to dmraid status */
-static enum status disk_status(struct asr_raid_configline *disk) {
+static enum status
+disk_status(struct asr_raid_configline *disk)
+{
static struct states states[] = {
{ LSU_COMPONENT_STATE_OPTIMAL, s_ok },
{ LSU_COMPONENT_STATE_DEGRADED, s_broken },
@@ -45,13 +47,14 @@
return rd_status(states, disk->raidstate, EQUAL);
}
-
+
/* Extract config line from metadata */
-static struct asr_raid_configline *get_config(struct asr *asr, uint32_t magic)
+static struct asr_raid_configline *
+get_config(struct asr *asr, uint32_t magic)
{
struct asr_raidtable *rt = asr->rt;
struct asr_raid_configline *cl = rt->ent + rt->elmcnt;
-
+
while (cl-- > rt->ent) {
if (cl->raidmagic == magic)
return cl;
@@ -61,14 +64,15 @@
}
/* Get this disk's configuration */
-static struct asr_raid_configline *this_disk(struct asr *asr)
+static struct asr_raid_configline *
+this_disk(struct asr *asr)
{
return get_config(asr, asr->rb.drivemagic);
}
/* Make up RAID device name. */
-static size_t _name(struct lib_context *lc, struct asr *asr, char *str,
- size_t len)
+static size_t
+_name(struct lib_context *lc, struct asr *asr, char *str, size_t len)
{
struct asr_raid_configline *cl = this_disk(asr);
@@ -79,7 +83,8 @@
}
/* Figure out a name for the RAID device. */
-static char *name(struct lib_context *lc, struct asr *asr)
+static char *
+name(struct lib_context *lc, struct asr *asr)
{
size_t len;
char *ret;
@@ -93,9 +98,10 @@
}
/* Stride size */
-static inline unsigned stride(struct asr_raid_configline *cl)
+static inline unsigned
+stride(struct asr_raid_configline *cl)
{
- return cl ? cl->strpsize: 0;
+ return cl ? cl->strpsize : 0;
}
/*
@@ -105,14 +111,15 @@
* do any of those right now (RAID4 and RAID5 are in the works).
*/
/* Map the ASR raid type codes into dmraid type codes. */
-static enum type type(struct asr_raid_configline *cl)
+static enum type
+type(struct asr_raid_configline *cl)
{
/* Mapping of template types to generic types */
static struct types types[] = {
- { ASR_RAID0, t_raid0 },
- { ASR_RAID1, t_raid1 },
+ { ASR_RAID0, t_raid0 },
+ { ASR_RAID1, t_raid1 },
{ ASR_RAIDSPR, t_spare },
- { 0, t_undef},
+ { 0, t_undef },
};
return cl ? rd_type(types, (unsigned) cl->raidtype) : t_undef;
@@ -122,10 +129,11 @@
* Read an ASR RAID device. Fields are big endian, so
* need to convert them if we're on a LE machine (i386, etc).
*/
-enum { ASR_BLOCK = 0x01, ASR_TABLE = 0x02, ASR_EXTTABLE = 0x04 };
+enum { ASR_BLOCK = 0x01, ASR_TABLE = 0x02, ASR_EXTTABLE = 0x04 };
#if BYTE_ORDER == LITTLE_ENDIAN
-static void cvt_configline(struct asr_raid_configline *cl)
+static void
+cvt_configline(struct asr_raid_configline *cl)
{
CVT16(cl->raidcnt);
CVT16(cl->raidseq);
@@ -141,12 +149,13 @@
CVT32(cl->appBurstCount);
}
-static void to_cpu(void *meta, unsigned cvt)
+static void
+to_cpu(void *meta, unsigned cvt)
{
struct asr *asr = meta;
struct asr_raidtable *rt = asr->rt;
unsigned i, elmcnt = rt->elmcnt,
- use_old_elmcnt = (rt->ridcode == RVALID2);
+ use_old_elmcnt = (rt->ridcode == RVALID2);
if (cvt & ASR_BLOCK) {
CVT32(asr->rb.b0idcode);
@@ -179,7 +188,7 @@
CVT32(rt->recreateDate);
/* Convert the first seven config lines */
- for (i = 0; i < (min(elmcnt, ASR_TBLELMCNT)); i++)
+ for (i = 0; i < (min(elmcnt, ASR_TBLELMCNT)); i++)
cvt_configline(rt->ent + i);
}
@@ -194,10 +203,11 @@
#endif
/* Compute the checksum of RAID metadata */
-static unsigned compute_checksum(struct asr *asr)
+static unsigned
+compute_checksum(struct asr *asr)
{
struct asr_raidtable *rt = asr->rt;
- uint8_t *ptr = (uint8_t*) rt->ent;
+ uint8_t *ptr = (uint8_t *) rt->ent;
unsigned checksum = 0, end = sizeof(*rt->ent) * rt->elmcnt;
/* Compute checksum. */
@@ -209,7 +219,8 @@
/* (Un)truncate white space at the end of a name */
enum truncate { TRUNCATE, UNTRUNCATE };
-static void handle_white_space(uint8_t *p, enum truncate truncate)
+static void
+handle_white_space(uint8_t * p, enum truncate truncate)
{
unsigned j = ASR_NAMELEN;
uint8_t c = truncate == TRUNCATE ? 0 : ' ';
@@ -219,14 +230,14 @@
}
/* Read extended metadata areas */
-static int read_extended(struct lib_context *lc, struct dev_info *di,
- struct asr *asr)
+static int
+read_extended(struct lib_context *lc, struct dev_info *di, struct asr *asr)
{
unsigned remaining, i, chk;
struct asr_raidtable *rt = asr->rt;
log_notice(lc, "%s: reading extended data on %s", handler, di->path);
-
+
/* Read the RAID table. */
if (!read_file(lc, handler, di->path, rt, ASR_DISK_BLOCK_SIZE,
(uint64_t) asr->rb.raidtbl * ASR_DISK_BLOCK_SIZE))
@@ -235,7 +246,7 @@
/* Convert it */
to_cpu(asr, ASR_TABLE);
-
+
/* Is this ok? */
if (rt->ridcode != RVALID2)
LOG_ERR(lc, 0, "%s: Invalid magic number in RAID table; "
@@ -256,7 +267,7 @@
if (rt->elmcnt > ASR_TBLELMCNT) {
remaining = rt->elmsize * (rt->elmcnt - 7);
if (!read_file(lc, handler, di->path, rt->ent + 7,
- remaining, (uint64_t)(asr->rb.raidtbl + 1) *
+ remaining, (uint64_t) (asr->rb.raidtbl + 1) *
ASR_DISK_BLOCK_SIZE))
return 0;
@@ -267,10 +278,10 @@
if (rt->rversion < 2) {
if ((chk = compute_checksum(asr)) != rt->rchksum)
log_err(lc, "%s: Invalid RAID config table checksum "
- "(0x%X vs. 0x%X) on %s",
+ "(0x%X vs. 0x%X) on %s",
handler, chk, rt->rchksum, di->path);
}
-
+
/* Process the name of each line of the config line. */
for (i = 0; i < rt->elmcnt; i++) {
/*
@@ -296,9 +307,8 @@
* This is nuts.
*/
if (!*rt->ent[i].name)
- strncpy((char*) rt->ent[i].name,
- (char*) rt->ent->name,
- ASR_NAMELEN);
+ strncpy((char *) rt->ent[i].name,
+ (char *) rt->ent->name, ASR_NAMELEN);
/* Now truncate trailing whitespace in the name. */
handle_white_space(rt->ent[i].name, TRUNCATE);
@@ -307,7 +317,8 @@
return 1;
}
-static int is_asr(struct lib_context *lc, struct dev_info *di, void *meta)
+static int
+is_asr(struct lib_context *lc, struct dev_info *di, void *meta)
{
struct asr *asr = meta;
@@ -315,11 +326,10 @@
* Check our magic numbers and that the version == v8.
* We don't support anything other than that right now.
*/
- if (asr->rb.b0idcode == B0RESRVD &&
- asr->rb.smagic == SVALID) {
+ if (asr->rb.b0idcode == B0RESRVD && asr->rb.smagic == SVALID) {
if (asr->rb.resver == RBLOCK_VER)
return 1;
-
+
log_err(lc, "%s: ASR v%d detected, but we only support v8",
handler, asr->rb.resver);
}
@@ -340,9 +350,9 @@
* lacks this sort of visibility as to where its block devices come from.
* This is EXTREMELY DANGEROUS if you aren't careful!
*/
-static void *read_metadata_areas(struct lib_context *lc, struct dev_info *di,
- size_t *sz, uint64_t *offset,
- union read_info *info)
+static void *
+read_metadata_areas(struct lib_context *lc, struct dev_info *di,
+ size_t * sz, uint64_t * offset, union read_info *info)
{
size_t size = ASR_DISK_BLOCK_SIZE;
uint64_t asr_sboffset = ASR_CONFIGOFFSET;
@@ -357,7 +367,7 @@
*/
if (!(asr = alloc_private(lc, handler, sizeof(*asr))))
goto bad0;
-
+
if (!(asr->rt = alloc_private(lc, handler, sizeof(*asr->rt))))
goto bad1;
@@ -370,8 +380,7 @@
to_cpu(asr, ASR_BLOCK);
/* Check Signature and read optional extended metadata. */
- if (!is_asr(lc, di, asr) ||
- !read_extended(lc, di, asr))
+ if (!is_asr(lc, di, asr) || !read_extended(lc, di, asr))
goto bad2;
/*
@@ -383,21 +392,21 @@
goto out;
- bad2:
+ bad2:
dbg_free(asr->rt);
- bad1:
+ bad1:
asr->rt = NULL;
dbg_free(asr);
- bad0:
+ bad0:
asr = NULL;
- out:
+ out:
return asr;
}
/* Read the whole metadata chunk at once */
-static uint8_t *read_metadata_chunk(struct lib_context *lc, struct dev_info *di,
- uint64_t start)
+static uint8_t *
+read_metadata_chunk(struct lib_context *lc, struct dev_info *di, uint64_t start)
{
uint8_t *ret;
size_t size = (di->sectors - start) * ASR_DISK_BLOCK_SIZE;
@@ -420,8 +429,8 @@
* "File the metadata areas" -- I think this function is supposed to declare
* which parts of the drive are metadata and thus off-limits to dmraid.
*/
-static void file_metadata_areas(struct lib_context *lc, struct dev_info *di,
- void *meta)
+static void
+file_metadata_areas(struct lib_context *lc, struct dev_info *di, void *meta)
{
uint8_t *buf;
struct asr *asr = meta;
@@ -432,19 +441,18 @@
/* Register the raid tables. */
file_metadata(lc, handler, di->path, buf,
- ASR_DISK_BLOCK_SIZE * 17,
- start * ASR_DISK_BLOCK_SIZE);
-
+ ASR_DISK_BLOCK_SIZE * 17, start * ASR_DISK_BLOCK_SIZE);
+
dbg_free(buf);
-
+
/* Record the device size if -D was specified. */
file_dev_size(lc, handler, di);
}
static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
struct dev_info *di, void *meta, union read_info *info);
-static struct raid_dev *asr_read(struct lib_context *lc,
- struct dev_info *di)
+static struct raid_dev *
+asr_read(struct lib_context *lc, struct dev_info *di)
{
/*
* NOTE: Everything called after read_metadata_areas assumes that
@@ -455,7 +463,8 @@
file_metadata_areas, setup_rd, handler);
}
-static int set_sort(struct list_head *dont, struct list_head *care)
+static int
+set_sort(struct list_head *dont, struct list_head *care)
{
return 0;
}
@@ -465,16 +474,18 @@
* Is hba:ch:lun:id ok?
* It seems to be the way the binary driver does it...
*/
-static inline uint64_t compose_id(struct asr_raid_configline *cl)
+static inline uint64_t
+compose_id(struct asr_raid_configline *cl)
{
- return ((uint64_t) cl->raidhba << 48)
+ return ((uint64_t) cl->raidhba << 48)
| ((uint64_t) cl->raidchnl << 40)
- | ((uint64_t) cl->raidlun << 32)
+ | ((uint64_t) cl->raidlun << 32)
| (uint64_t) cl->raidid;
}
/* Sort ASR devices by for a RAID set. */
-static int dev_sort(struct list_head *pos, struct list_head *new)
+static int
+dev_sort(struct list_head *pos, struct list_head *new)
{
return compose_id(this_disk(META(RD(new), asr))) <
compose_id(this_disk(META(RD(pos), asr)));
@@ -483,7 +494,8 @@
/*
* Find the top-level RAID set for an ASR context.
*/
-static int find_toplevel(struct lib_context *lc, struct asr *asr)
+static int
+find_toplevel(struct lib_context *lc, struct asr *asr)
{
int i, toplevel = -1;
struct asr_raidtable *rt = asr->rt;
@@ -496,7 +508,7 @@
break;
}
}
-
+
return toplevel;
}
@@ -504,7 +516,8 @@
* Find the logical drive configuration that goes with this
* physical disk configuration.
*/
-static struct asr_raid_configline *find_logical(struct asr *asr)
+static struct asr_raid_configline *
+find_logical(struct asr *asr)
{
int i, j;
struct asr_raidtable *rt = asr->rt;
@@ -522,11 +535,13 @@
return NULL;
}
-static struct raid_dev *find_spare(struct lib_context *lc) {
+static struct raid_dev *
+find_spare(struct lib_context *lc)
+{
struct raid_dev *spare;
-
+
list_for_each_entry(spare, LC_RD(lc), list) {
- if (spare->type == t_spare)
+ if (spare->type == t_spare)
return spare;
}
@@ -534,8 +549,8 @@
}
/* Wrapper for name() */
-static char *js_name(struct lib_context *lc, struct raid_dev *rd,
- unsigned subset)
+static char *
+js_name(struct lib_context *lc, struct raid_dev *rd, unsigned subset)
{
return name(lc, META(rd, asr));
}
@@ -543,7 +558,8 @@
/*
* IO error event handler.
*/
-static int event_io(struct lib_context *lc, struct event_io *e_io)
+static int
+event_io(struct lib_context *lc, struct event_io *e_io)
{
struct raid_dev *rd = e_io->rd;
struct asr *asr = META(rd, asr);
@@ -553,7 +569,7 @@
/* Ignore if we've already marked this disk broken(?) */
if (rd->status & s_broken)
return 0;
-
+
log_err(lc, "%s: I/O error on device %s at sector %lu",
handler, e_io->rd->di->path, e_io->sector);
@@ -563,13 +579,14 @@
fwl->raidstate = LSU_COMPONENT_STATE_DEGRADED;
/* FIXME: Do we have to mark a parent too? */
- return 1; /* Indicate that this is indeed a failure. */
+ return 1; /* Indicate that this is indeed a failure. */
}
/*
* Helper routines for asr_group()
*/
-static struct raid_set *do_spare(struct lib_context *lc, struct raid_dev *rd)
+static struct raid_set *
+do_spare(struct lib_context *lc, struct raid_dev *rd)
{
struct raid_set *rs;
@@ -585,11 +602,11 @@
* it.
*
* rs = find_set(lc, name(lc, asr), FIND_TOP, rd, LC_RS(lc),
- * NO_CREATE, NO_CREATE_ARG);
+ * NO_CREATE, NO_CREATE_ARG);
*/
/* Otherwise, make a global spare pool. */
- rs = find_or_alloc_raid_set(lc, (char*)spare_array, FIND_TOP, rd,
+ rs = find_or_alloc_raid_set(lc, (char *) spare_array, FIND_TOP, rd,
LC_RS(lc), NO_CREATE, NO_CREATE_ARG);
/*
@@ -604,8 +621,9 @@
}
#define BUFSIZE 128
-static struct raid_set *do_stacked(struct lib_context *lc, struct raid_dev *rd,
- struct asr_raid_configline *cl)
+static struct raid_set *
+do_stacked(struct lib_context *lc, struct raid_dev *rd,
+ struct asr_raid_configline *cl)
{
char buf[BUFSIZE], *path = rd->di->path;
struct raid_set *rs, *ss;
@@ -616,12 +634,11 @@
fwl = find_logical(asr);
if (!fwl)
LOG_ERR(lc, NULL, "%s: Failed to find RAID configuration "
- "line on %s",
- handler, path);
+ "line on %s", handler, path);
snprintf(buf, BUFSIZE, ".asr_%s_%x_donotuse",
fwl->name, fwl->raidmagic);
-
+
/* Now find said parent. */
rs = find_or_alloc_raid_set(lc, buf, FIND_ALL, rd, NO_LIST,
NO_CREATE, NO_CREATE_ARG);
@@ -635,7 +652,7 @@
/* Add the disk to the set. */
list_add_sorted(lc, &rs->devs, &rd->devs, dev_sort);
-
+
/* Find the top level set. */
ss = join_superset(lc, js_name, NO_CREATE, set_sort, rs, rd);
if (!ss)
@@ -645,7 +662,7 @@
ss->stride = stride(cl);
ss->status = s_ok;
/* FIXME: correct type (this crashed in stacked set code) */
- ss->type = t_raid1; // type(&asr->rt->ent[top_idx]);
+ ss->type = t_raid1; // type(&asr->rt->ent[top_idx]);
return ss;
}
@@ -654,7 +671,8 @@
* which this disk belongs, and then attaching it. Note that there are other
* complications, such as two-layer arrays (RAID10).
*/
-static struct raid_set *asr_group(struct lib_context *lc, struct raid_dev *rd)
+static struct raid_set *
+asr_group(struct lib_context *lc, struct raid_dev *rd)
{
int top_idx;
struct asr *asr = META(rd, asr);
@@ -668,8 +686,7 @@
top_idx = find_toplevel(lc, asr);
if (top_idx < 0)
LOG_ERR(lc, NULL, "%s: Can't find a logical array config "
- "for disk %x",
- handler, asr->rb.drivemagic);
+ "for disk %x", handler, asr->rb.drivemagic);
/* This is a simple RAID0/1 array. Find the set. */
if (asr->rt->ent[top_idx].raidlevel == FWL) {
@@ -700,7 +717,8 @@
}
/* deletes configline from metadata of given asr, by index. */
-static void delete_configline(struct asr *asr, int index)
+static void
+delete_configline(struct asr *asr, int index)
{
struct asr_raid_configline *cl, *end;
struct asr_raidtable *rt = asr->rt;
@@ -715,13 +733,14 @@
}
/* Find the newest configline entry in raid set and return a pointer to it. */
-static struct raid_dev *find_newest_drive(struct raid_set *rs)
+static struct raid_dev *
+find_newest_drive(struct raid_set *rs)
{
struct asr_raidtable *rt;
struct raid_dev *device, *newest = NULL;
uint16_t newest_raidseq = 0;
- int i;
-
+ int i;
+
list_for_each_entry(device, &rs->devs, devs) {
rt = META(device, asr)->rt;
// FIXME: We should be able to assume each configline
@@ -734,19 +753,21 @@
}
}
}
-
+
return newest;
}
/* Creates a random integer for a drive magic section */
-static uint32_t create_drivemagic() {
+static uint32_t
+create_drivemagic()
+{
srand(time(NULL));
return rand() + rand();
}
-static int spare(struct lib_context *lc, struct raid_dev *rd,
- struct asr *asr)
+static int
+spare(struct lib_context *lc, struct raid_dev *rd, struct asr *asr)
{
struct asr_raid_configline *cl;
@@ -781,13 +802,13 @@
cl->raidtype = ASR_RAIDSPR;
cl->lcapcty = rd->di->sectors;
cl->raidlevel = FWP;
-
return 1;
}
/* Returns (boolean) whether or not the drive described by the given configline
* is in the given raid_set. */
-static int in_raid_set(struct asr_raid_configline *cl, struct raid_set *rs)
+static int
+in_raid_set(struct asr_raid_configline *cl, struct raid_set *rs)
{
struct asr *asr;
struct raid_dev *d;
@@ -797,11 +818,13 @@
if (cl->raidmagic == asr->rb.drivemagic)
return 1;
}
+
return 0;
}
/* Delete extra configlines which would otherwise trip us up. */
-static int cleanup_configlines(struct raid_dev *rd, struct raid_set *rs)
+static int
+cleanup_configlines(struct raid_dev *rd, struct raid_set *rs)
{
struct asr *a;
struct raid_dev *d;
@@ -810,7 +833,7 @@
list_for_each_entry(d, &rs->devs, devs) {
a = META(d, asr);
-
+
cl = a->rt->ent;
for (clcnt = 0; clcnt < a->rt->elmcnt; /* done in loop */ ) {
/* If it's in the seen list, or is a logical drive,
@@ -833,19 +856,21 @@
}
}
}
+
return 1;
}
/* Add a CL entry */
-static int create_configline(struct raid_set *rs, struct asr *asr,
- struct asr *a, struct raid_dev* newest)
+static int
+create_configline(struct raid_set *rs, struct asr *asr,
+ struct asr *a, struct raid_dev *newest)
{
struct asr *newest_asr = META(newest, asr);
struct asr_raid_configline *cl;
-
+
if (asr->rt->elmcnt >= RCTBL_MAX_ENTRIES)
return 0;
-
+
cl = asr->rt->ent + asr->rt->elmcnt;
asr->rt->elmcnt++;
@@ -858,7 +883,7 @@
cl->strpsize = newest_asr->rt->ent[0].strpsize;
/* Starts after "asr_" */
- strcpy((char*) cl->name, &rs->name[sizeof(HANDLER)]);
+ strcpy((char *) cl->name, &rs->name[sizeof(HANDLER)]);
cl->raidcnt = 0;
/* Convert rs->type to an ASR_RAID type for the CL */
@@ -872,6 +897,7 @@
default:
return 0;
}
+
cl->lcapcty = newest_asr->rt->ent[0].lcapcty;
cl->raidlevel = FWP;
return 1;
@@ -879,8 +905,8 @@
/* Update metadata to reflect the current raid set configuration.
* Returns boolean success. */
-static int update_metadata(struct lib_context *lc, struct raid_dev *rd,
- struct asr *asr)
+static int
+update_metadata(struct lib_context *lc, struct raid_dev *rd, struct asr *asr)
{
struct raid_set *rs;
struct asr_raid_configline *cl;
@@ -895,7 +921,7 @@
rt->elmcnt = 0;
return 1;
}
-
+
/* If this is the spare array... */
if (!strcmp(spare_array, rs->name))
return spare(lc, rd, asr);
@@ -911,11 +937,11 @@
/* Make sure the raid type agrees with the metadata */
if (type(this_disk(asr)) == t_spare) {
struct asr *newest_asr = META(newest, asr);
-
- /* copy entire table from newest drive */
+
+ /* copy entire table from newest drive */
rt->elmcnt = newest_asr->rt->elmcnt;
memcpy(rt->ent, newest_asr->rt->ent,
- rt->elmcnt * sizeof(*rt->ent));
+ rt->elmcnt * sizeof(*rt->ent));
}
/* Increment the top level CL's raid count */
@@ -935,26 +961,25 @@
}
/* If the magic is 0xFFFFFFFF, assign a random one */
- if (a->rb.drivemagic == 0xFFFFFFFF) {
+ if (a->rb.drivemagic == 0xFFFFFFFF)
a->rb.drivemagic = create_drivemagic();
- }
-
+
if (!(newest = find_newest_drive(rs)))
return 0;
-
+
create_configline(rs, asr, a, newest);
}
cleanup_configlines(rd, rs);
-
return 1;
}
/* Write metadata. */
-static int asr_write(struct lib_context *lc, struct raid_dev *rd, int erase)
+static int
+asr_write(struct lib_context *lc, struct raid_dev *rd, int erase)
{
- struct asr *asr = META(rd, asr);
+ struct asr *asr = META(rd, asr);
int elmcnt = asr->rt->elmcnt, i, ret;
/* Update the metadata if we're not erasing it. */
@@ -969,19 +994,19 @@
asr->rt->rchksum = compute_checksum(asr);
/* Convert back to disk format */
- to_disk(asr, ASR_BLOCK | ASR_TABLE | ASR_EXTTABLE);
+ to_disk(asr, ASR_BLOCK | ASR_TABLE | ASR_EXTTABLE);
/* Write data */
- ret = write_metadata(lc, handler, rd, -1, erase);
-
+ ret = write_metadata(lc, handler, rd, -1, erase);
+
/* Go back to CPU format */
- to_cpu(asr, ASR_BLOCK | ASR_TABLE | ASR_EXTTABLE);
-
+ to_cpu(asr, ASR_BLOCK | ASR_TABLE | ASR_EXTTABLE);
+
/* Truncate trailing whitespace in the name. */
for (i = 0; i < elmcnt; i++)
handle_white_space(asr->rt->ent[i].name, TRUNCATE);
- return ret;
+ return ret;
}
/*
@@ -989,7 +1014,8 @@
*/
/* Retrieve the number of devices that should be in this set. */
-static unsigned device_count(struct raid_dev *rd, void *context)
+static unsigned
+device_count(struct raid_dev *rd, void *context)
{
/* Get the logical drive */
struct asr_raid_configline *cl = find_logical(META(rd, asr));
@@ -998,15 +1024,17 @@
}
/* Check a RAID device */
-static int check_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_dev *rd, void *context)
+static int
+check_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_dev *rd, void *context)
{
/* FIXME: Assume non-broken means ok. */
return rd->type != s_broken;
}
/* Start the recursive RAID set check. */
-static int asr_check(struct lib_context *lc, struct raid_set *rs)
+static int
+asr_check(struct lib_context *lc, struct raid_set *rs)
{
return check_raid_set(lc, rs, device_count, NULL, check_rd,
NULL, handler);
@@ -1018,7 +1046,8 @@
};
/* Dump a reserved block */
-static void dump_rb(struct lib_context *lc, struct asr_reservedblock *rb)
+static void
+dump_rb(struct lib_context *lc, struct asr_reservedblock *rb)
{
DP("block magic:\t\t0x%X", rb, rb->b0idcode);
DP("sb0flags:\t\t\t0x%X", rb, rb->sb0flags);
@@ -1033,7 +1062,8 @@
}
/* Dump a raid config line */
-static void dump_cl(struct lib_context *lc, struct asr_raid_configline *cl)
+static void
+dump_cl(struct lib_context *lc, struct asr_raid_configline *cl)
{
DP("config ID:\t\t0x%X", cl, cl->raidmagic);
DP(" name:\t\t\t\"%s\"", cl, cl->name);
@@ -1062,7 +1092,8 @@
}
/* Dump a raid config table */
-static void dump_rt(struct lib_context *lc, struct asr_raidtable *rt)
+static void
+dump_rt(struct lib_context *lc, struct asr_raidtable *rt)
{
unsigned i;
@@ -1093,7 +1124,8 @@
/*
* Log native information about the RAID device.
*/
-static void asr_log(struct lib_context *lc, struct raid_dev *rd)
+static void
+asr_log(struct lib_context *lc, struct raid_dev *rd)
{
struct asr *asr = META(rd, asr);
@@ -1104,22 +1136,23 @@
#endif
static struct dmraid_format asr_format = {
- .name = HANDLER,
- .descr = "Adaptec HostRAID ASR",
- .caps = "0,1,10",
+ .name = HANDLER,
+ .descr = "Adaptec HostRAID ASR",
+ .caps = "0,1,10",
.format = FMT_RAID,
- .read = asr_read,
- .write = asr_write,
- .group = asr_group,
- .check = asr_check,
- .events = &asr_event_handlers,
+ .read = asr_read,
+ .write = asr_write,
+ .group = asr_group,
+ .check = asr_check,
+ .events = &asr_event_handlers,
#ifdef DMRAID_NATIVE_LOG
- .log = asr_log,
+ .log = asr_log,
#endif
};
/* Register this format handler with the format core */
-int register_asr(struct lib_context *lc)
+int
+register_asr(struct lib_context *lc)
{
return register_format_handler(lc, &asr_format);
}
@@ -1127,15 +1160,17 @@
/*
* Set up a RAID device from what we've assembled out of the metadata.
*/
-static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta, union read_info *info)
+static int
+setup_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct dev_info *di, void *meta, union read_info *info)
{
struct asr *asr = meta;
struct meta_areas *ma;
struct asr_raid_configline *cl = this_disk(asr);
if (!cl)
- LOG_ERR(lc, 0, "%s: Could not find current disk!", handler);
+ LOG_ERR(lc, 0, "%s: Could not find current disk!", handler);
+
/* We need two metadata areas */
if (!(ma = rd->meta_areas = alloc_meta_areas(lc, rd, handler, 2)))
return 0;
@@ -1151,11 +1186,12 @@
ma->area = asr->rt;
/* Now set up the rest of the metadata info */
- rd->di = di;
+ rd->di = di;
rd->fmt = &asr_format;
rd->status = disk_status(cl);
- rd->type = type(cl);
+ rd->type = type(cl);
rd->offset = ASR_DATAOFFSET;
+
if (!(rd->sectors = cl->lcapcty))
return log_zero_sectors(lc, di->path, handler);
--- dmraid/lib/format/ataraid/asr.h 2008/02/22 17:04:35 1.2
+++ dmraid/lib/format/ataraid/asr.h 2008/06/20 21:52:17 1.3
@@ -89,12 +89,12 @@
/*** RAID CONFIGURATION TABLE STRUCTURE ***/
-#define RVALID2 0x900765C4 /* Version 2+ RAID table ID code
- signature */
+#define RVALID2 0x900765C4 /* Version 2+ RAID table ID code
+ signature */
#define RCTBL_MAX_ENTRIES 127
#define HBA_RCTBL_MAX_ENTRIES 255
-#define RTBLBLOCKS 16 /* Size of drive's raid table
- in blocks */
+#define RTBLBLOCKS 16 /* Size of drive's raid table
+ in blocks */
/* flag bits */
#define RCTBLCHNG 0x80 /* Set on comp OR log (NOT AND) if tbl updates needed */
@@ -106,185 +106,182 @@
#define PREDICTIVE_ENABLE 0x02
#define RAID_ENTRY_FLAGS_ALARM_OFF_M 0x01
-struct asr_raid_configline
-{
- uint16_t raidcnt; /* Component count of an OSL/FWL array */
- uint16_t raidseq; /* Sequence # of component to look for */
- uint32_t raidmagic; /* Magic # of component to look for */
- uint8_t raidlevel; /* Array level = OSL/FWL/OSI/FWP */
- uint8_t raidtype; /* Array type = RAID0/1/3/5, RAIDRED,
- RAIDSPR */
- uint8_t raidstate; /* State of logical or physical drive */
-
- uint8_t flags; /* misc flags set bit positions above */
-
- uint8_t refcnt; /* Number of references to this log entry */
- uint8_t raidhba; /* -- not used -- Host bus adapter number
- or RAIDID */
- uint8_t raidchnl; /* Channel number */
- uint8_t raidlun; /* SCSI LUN of log/phys drv */
- uint32_t raidid; /* SCSI ID of log/phys drv */
- uint32_t loffset; /* Offset of data for this comp in the
- array */
- uint32_t lcapcty; /* Capacity of log drv or space used on
- phys */
- uint16_t strpsize; /* Stripe size in blocks of this drive */
- uint16_t biosInfo; /* bios info - set by
- I2O_EXEC_BIOS_INFO_SET */
- uint32_t lsu; /* Pointer to phys/log lun of this entry */
- uint8_t addedDrives;
- uint8_t appSleepRate;
- uint16_t blockStorageTid;
- uint32_t curAppBlock;
- uint32_t appBurstCount;
+struct asr_raid_configline {
+ uint16_t raidcnt; /* Component count of an OSL/FWL array */
+ uint16_t raidseq; /* Sequence # of component to look for */
+ uint32_t raidmagic; /* Magic # of component to look for */
+ uint8_t raidlevel; /* Array level = OSL/FWL/OSI/FWP */
+ uint8_t raidtype; /* Array type = RAID0/1/3/5, RAIDRED,
+ RAIDSPR */
+ uint8_t raidstate; /* State of logical or physical drive */
+
+ uint8_t flags; /* misc flags set bit positions above */
+
+ uint8_t refcnt; /* Number of references to this log entry */
+ uint8_t raidhba; /* -- not used -- Host bus adapter number
+ or RAIDID */
+ uint8_t raidchnl; /* Channel number */
+ uint8_t raidlun; /* SCSI LUN of log/phys drv */
+ uint32_t raidid; /* SCSI ID of log/phys drv */
+ uint32_t loffset; /* Offset of data for this comp in the
+ array */
+ uint32_t lcapcty; /* Capacity of log drv or space used on
+ phys */
+ uint16_t strpsize; /* Stripe size in blocks of this drive */
+ uint16_t biosInfo; /* bios info - set by
+ I2O_EXEC_BIOS_INFO_SET */
+ uint32_t lsu; /* Pointer to phys/log lun of this entry */
+ uint8_t addedDrives;
+ uint8_t appSleepRate;
+ uint16_t blockStorageTid;
+ uint32_t curAppBlock;
+ uint32_t appBurstCount;
#define ASR_NAMELEN 16
- uint8_t name[ASR_NAMELEN]; /* Full name of the array. */
+ uint8_t name[ASR_NAMELEN]; /* Full name of the array. */
} __attribute__ ((packed));
-struct asr_raidtable
-{
+struct asr_raidtable {
/* raid Flag defines 32 bits 0 - FFFFFFFF */
#define RAID_FLAGS_ALARM_OFF_M 0x00000001
- uint32_t ridcode; /* RAID table signature - 0x900765C4 */
- uint32_t rversion; /* Version of the RAID config table */
- uint16_t maxelm; /* Maximum number of elements */
- uint16_t elmcnt; /* Element Count (number used) */
+ uint32_t ridcode; /* RAID table signature - 0x900765C4 */
+ uint32_t rversion; /* Version of the RAID config table */
+ uint16_t maxelm; /* Maximum number of elements */
+ uint16_t elmcnt; /* Element Count (number used) */
#define ASR_TBLELMCNT 7
- uint16_t elmsize; /* Size of an individual raidCLine */
- uint16_t rchksum; /* RAID table check sum
- (no rconfTblV2)*/
- uint32_t res1; /* Reserved */
- uint16_t res2; /* was bldRate - Time in 1/10s
- between idle build bursts */
- uint16_t res3; /* was bldAmount - Block to build
- during a build burst */
- uint32_t raidFlags;
- uint32_t timestamp; /* used for iROC. A stamp to find
- which is latest */
- uint8_t irocFlags;
+ uint16_t elmsize; /* Size of an individual raidCLine */
+ uint16_t rchksum; /* RAID table check sum
+ (no rconfTblV2) */
+ uint32_t res1; /* Reserved */
+ uint16_t res2; /* was bldRate - Time in 1/10s
+ between idle build bursts */
+ uint16_t res3; /* was bldAmount - Block to build
+ during a build burst */
+ uint32_t raidFlags;
+ uint32_t timestamp; /* used for iROC. A stamp to find
+ which is latest */
+ uint8_t irocFlags;
#define ASR_IF_VERIFY_WITH_AUTOFIX 0x01
#define ASR_IF_BOOTABLE 0x80
- uint8_t dirty; /* Records "open state" for array */
+ uint8_t dirty; /* Records "open state" for array */
#define ARRAY_STATE_OK 0x00
#define ARRAY_STATE_DIRTY 0x03
- uint8_t actionPriority;
- uint8_t spareid; /* Stored in member disk meta data
- to declare the ID of dedicated
- spare to show up. */
- uint32_t sparedrivemagic;/* drivemagic (in RB) of the spare
+ uint8_t actionPriority;
+ uint8_t spareid; /* Stored in member disk meta data
+ to declare the ID of dedicated
+ spare to show up. */
+ uint32_t sparedrivemagic; /* drivemagic (in RB) of the spare
at above ID. */
- uint32_t raidmagic; /* used to identify spare drive with
- its mirror set. */
- uint32_t verifyDate; /* used by iomgr */
- uint32_t recreateDate; /* used by iomgr */
- uint8_t res4[12]; /* Reserved */
+ uint32_t raidmagic; /* used to identify spare drive with
+ its mirror set. */
+ uint32_t verifyDate; /* used by iomgr */
+ uint32_t recreateDate; /* used by iomgr */
+ uint8_t res4[12]; /* Reserved */
struct asr_raid_configline ent[RCTBL_MAX_ENTRIES];
} __attribute__ ((packed));
-#define RBLOCK_VER 8 /* Version of the reserved block */
-#define B0RESRVD 0x37FC4D1E /* Signature of the reserved block */
-#define SVALID 0x4450544D /* ASCII code for "DPTM" DPT Mirror */
-
-struct asr_reservedblock
-{
- uint32_t b0idcode; /* 0x00 - ID code signifying block 0
- reserved */
- uint8_t lunsave[8]; /* 0x04 - NOT USED - LUN mappings for
- all drives */
- uint16_t sdtype; /* 0x0C - NOT USED - drive type in
- boot prom */
- uint16_t ssavecyl; /* 0x0E - NOT USED - Set Parameters
- cylinders */
- uint8_t ssavehed; /* 0x10 - NOT USED - Set Parameters
- heads */
- uint8_t ssavesec; /* 0x11 - NOT USED - Set Parameters
- sectors */
- uint8_t sb0flags; /* 0x12 - flags saved in reserved
- block */
- uint8_t jbodEnable; /* 0x13 - jbod enable -- DEC drive
- hiding */
- uint8_t lundsave; /* 0x14 - NOT USED - LUNMAP disable
- flags */
- uint8_t svpdirty; /* 0x15 - NOT USED - saved percentage
- dirty */
- uint16_t biosInfo; /* 0x16 - bios info - set by
- I2O_EXEC_BIOS_INFO_SET */
- uint16_t svwbskip; /* 0x18 - NOT USED - saved write-back
- skip value */
- uint16_t svwbcln; /* 0x1A - NOT USED - saved maximum
- clean blocks in write-back */
- uint16_t svwbmax; /* 0x1C - NOT USED - saved maximum
- write-back length */
- uint16_t res3; /* 0x1E - unused (was write-back burst
- block count) */
- uint16_t svwbmin; /* 0x20 - NOT USED - saved minimum
- block count to write */
- uint16_t res4; /* 0x22 - unused (was minimum
- look-ahead length) */
- uint16_t svrcacth; /* 0x24 - NOT USED - saved read cache
- threshold */
- uint16_t svwcacth; /* 0x26 - NOT USED - saved write
- cache threshold */
- uint16_t svwbdly; /* 0x28 - NOT USED - saved write-back
- delay */
- uint8_t svsdtime; /* 0x2A - NOT USED - saved spin down
- time */
- uint8_t res5; /* 0x2B - unused */
- uint16_t firmval; /* 0x2C - NOT USED - firmware on
- drive (dw) */
- uint16_t firmbln; /* 0x2E - NOT USED - length in blocks
- for firmware */
- uint32_t firmblk; /* 0x30 - NOT USED - starting block
- for firmware */
- uint32_t fstrsvrb; /* 0x34 - 1st block reserved by
- Storage Manager */
- uint16_t svBlockStorageTid; /* 0x38 - */
- uint16_t svtid; /* 0x3A - */
- uint8_t svseccfl; /* 0x3C - NOT USED - reserved block
- scsi bus ecc flags */
- uint8_t res6; /* 0x3D - unused */
- uint8_t svhbanum; /* 0x3E - NOT USED - HBA's unique
- RAID number */
- uint8_t resver; /* 0x3F - reserved block version
- number */
- uint32_t drivemagic; /* 0x40 - Magic number of this drive -
- used w/ RCTBLs */
- uint8_t reserved[20]; /* 0x44 - unused */
- uint8_t testnum; /* 0x58 - NOT USED - diagnostic test
- number */
- uint8_t testflags; /* 0x59 - NOT USED - diagnostic test
- flags */
- uint16_t maxErrorCount; /* 0x5A - NOT USED - diagnostic test
- maximum error count */
- uint32_t count; /* 0x5C - NOT USED - diagnostic test
- cycles - # of iterations */
- uint32_t startTime; /* 0x60 - NOT USED - diagnostic test
- absolute test start time in
- seconds */
- uint32_t interval; /* 0x64 - NOT USED - diagnostic test
- interval in seconds */
- uint8_t tstxt0; /* 0x68 - not used - originally
- diagnostic test exclusion period
- start hour */
- uint8_t tstxt1; /* 0x69 - not used - originally
- diagnostic test exclusion period
- end hour */
- uint8_t serNum[32]; /* 0x6A - reserved */
- uint8_t res8[102]; /* 0x8A - reserved */
- uint32_t fwTestMagic; /* 0xF0 - test magic number - used by
- FW Test for automated tests */
- uint32_t fwTestSeqNum; /* 0xF4 - test sequence number - used
- by FW Test for automated tests */
- uint8_t fwTestRes[8]; /* 0xF6 - reserved by FW Test for
- automated tests */
- uint32_t smagic; /* 0x100 - magic value saying software
- half is valid */
- uint32_t raidtbl; /* 0x104 - pointer to first block of
- raid table */
- uint16_t raidline; /* 0x108 - line number of this raid
- table entry - only if version <7 */
- uint8_t res9[0xF6]; /* 0x10A - reserved for software stuff*/
+#define RBLOCK_VER 8 /* Version of the reserved block */
+#define B0RESRVD 0x37FC4D1E /* Signature of the reserved block */
+#define SVALID 0x4450544D /* ASCII code for "DPTM" DPT Mirror */
+
+struct asr_reservedblock {
+ uint32_t b0idcode; /* 0x00 - ID code signifying block 0
+ reserved */
+ uint8_t lunsave[8]; /* 0x04 - NOT USED - LUN mappings for
+ all drives */
+ uint16_t sdtype; /* 0x0C - NOT USED - drive type in
+ boot prom */
+ uint16_t ssavecyl; /* 0x0E - NOT USED - Set Parameters
+ cylinders */
+ uint8_t ssavehed; /* 0x10 - NOT USED - Set Parameters
+ heads */
+ uint8_t ssavesec; /* 0x11 - NOT USED - Set Parameters
+ sectors */
+ uint8_t sb0flags; /* 0x12 - flags saved in reserved
+ block */
+ uint8_t jbodEnable; /* 0x13 - jbod enable -- DEC drive
+ hiding */
+ uint8_t lundsave; /* 0x14 - NOT USED - LUNMAP disable
+ flags */
+ uint8_t svpdirty; /* 0x15 - NOT USED - saved percentage
+ dirty */
+ uint16_t biosInfo; /* 0x16 - bios info - set by
+ I2O_EXEC_BIOS_INFO_SET */
+ uint16_t svwbskip; /* 0x18 - NOT USED - saved write-back
+ skip value */
+ uint16_t svwbcln; /* 0x1A - NOT USED - saved maximum
+ clean blocks in write-back */
+ uint16_t svwbmax; /* 0x1C - NOT USED - saved maximum
+ write-back length */
+ uint16_t res3; /* 0x1E - unused (was write-back burst
+ block count) */
+ uint16_t svwbmin; /* 0x20 - NOT USED - saved minimum
+ block count to write */
+ uint16_t res4; /* 0x22 - unused (was minimum
+ look-ahead length) */
+ uint16_t svrcacth; /* 0x24 - NOT USED - saved read cache
+ threshold */
+ uint16_t svwcacth; /* 0x26 - NOT USED - saved write
+ cache threshold */
+ uint16_t svwbdly; /* 0x28 - NOT USED - saved write-back
+ delay */
+ uint8_t svsdtime; /* 0x2A - NOT USED - saved spin down
+ time */
+ uint8_t res5; /* 0x2B - unused */
+ uint16_t firmval; /* 0x2C - NOT USED - firmware on
+ drive (dw) */
+ uint16_t firmbln; /* 0x2E - NOT USED - length in blocks
+ for firmware */
+ uint32_t firmblk; /* 0x30 - NOT USED - starting block
+ for firmware */
+ uint32_t fstrsvrb; /* 0x34 - 1st block reserved by
+ Storage Manager */
+ uint16_t svBlockStorageTid; /* 0x38 - */
+ uint16_t svtid; /* 0x3A - */
+ uint8_t svseccfl; /* 0x3C - NOT USED - reserved block
+ scsi bus ecc flags */
+ uint8_t res6; /* 0x3D - unused */
+ uint8_t svhbanum; /* 0x3E - NOT USED - HBA's unique
+ RAID number */
+ uint8_t resver; /* 0x3F - reserved block version
+ number */
+ uint32_t drivemagic; /* 0x40 - Magic number of this drive -
+ used w/ RCTBLs */
+ uint8_t reserved[20]; /* 0x44 - unused */
+ uint8_t testnum; /* 0x58 - NOT USED - diagnostic test
+ number */
+ uint8_t testflags; /* 0x59 - NOT USED - diagnostic test
+ flags */
+ uint16_t maxErrorCount; /* 0x5A - NOT USED - diagnostic test
+ maximum error count */
+ uint32_t count; /* 0x5C - NOT USED - diagnostic test
+ cycles - # of iterations */
+ uint32_t startTime; /* 0x60 - NOT USED - diagnostic test
+ absolute test start time in
+ seconds */
+ uint32_t interval; /* 0x64 - NOT USED - diagnostic test
+ interval in seconds */
+ uint8_t tstxt0; /* 0x68 - not used - originally
+ diagnostic test exclusion period
+ start hour */
+ uint8_t tstxt1; /* 0x69 - not used - originally
+ diagnostic test exclusion period
+ end hour */
+ uint8_t serNum[32]; /* 0x6A - reserved */
+ uint8_t res8[102]; /* 0x8A - reserved */
+ uint32_t fwTestMagic; /* 0xF0 - test magic number - used by
+ FW Test for automated tests */
+ uint32_t fwTestSeqNum; /* 0xF4 - test sequence number - used
+ by FW Test for automated tests */
+ uint8_t fwTestRes[8]; /* 0xF6 - reserved by FW Test for
+ automated tests */
+ uint32_t smagic; /* 0x100 - magic value saying software
+ half is valid */
+ uint32_t raidtbl; /* 0x104 - pointer to first block of
+ raid table */
+ uint16_t raidline; /* 0x108 - line number of this raid
+ table entry - only if version <7 */
+ uint8_t res9[0xF6]; /* 0x10A - reserved for software stuff */
} __attribute__ ((packed));
@@ -310,7 +307,7 @@
#define ID_MAP_PHYSICAL_M 1 /* Logical Map Physical */
#define ID_MAP_LOGICAL_M 2 /* Either Dual Level or Single Level
- Logical*/
+ Logical */
#define MAX_LSU_COUNT 256
@@ -369,10 +366,10 @@
#define LSU_COMPONENT_STATE_REPLACED 0x04
#define LSU_COMPONENT_STATE_UNINITIALIZED 0x0A
-#define LSU_COMPONENT_SUBSTATE_BUILDING 0x10 /* drive is being built
- for first time */
-#define LSU_COMPONENT_SUBSTATE_REBUILDING 0x20 /* drive is being
- rebuilt */
+#define LSU_COMPONENT_SUBSTATE_BUILDING 0x10 /* drive is being built
+ for first time */
+#define LSU_COMPONENT_SUBSTATE_REBUILDING 0x20 /* drive is being
+ rebuilt */
#define LSU_ARRAY_SUBSTATE_AWAIT_FORMAT 0x50
/* etc. */
--- dmraid/lib/format/ataraid/hpt37x.c 2008/02/22 17:04:35 1.2
+++ dmraid/lib/format/ataraid/hpt37x.c 2008/06/20 21:52:17 1.3
@@ -1,7 +1,7 @@
/*
* Highpoint 37X ATARAID series metadata format handler.
*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
* See file LICENSE at the top of this source tree for license information.
@@ -26,16 +26,16 @@
/* Make up RAID set name from magic_[01] numbers */
/* FIXME: better name ? */
-static size_t _name(struct hpt37x *hpt, char *str, size_t len,
- unsigned int subset)
+static size_t
+_name(struct hpt37x *hpt, char *str, size_t len, unsigned int subset)
{
const char *fmt;
if (hpt->magic_0)
fmt = (subset &&
(hpt->type == HPT37X_T_RAID01_RAID0 ||
- hpt->type == HPT37X_T_RAID01_RAID1)) ?
- "hpt37x_%u-%u" : "hpt37x_%u";
+ hpt->type == HPT37X_T_RAID01_RAID1)) ?
+ "hpt37x_%u-%u" : "hpt37x_%u";
else
fmt = "hpt37x_SPARE";
@@ -44,8 +44,8 @@
hpt->magic_1 ? hpt->magic_1 : hpt->magic_0, hpt->order);
}
-static char *name(struct lib_context *lc, struct raid_dev *rd,
- unsigned int subset)
+static char *
+name(struct lib_context *lc, struct raid_dev *rd, unsigned int subset)
{
size_t len;
char *ret;
@@ -65,52 +65,57 @@
* Retrieve status of device.
* FIXME: is this sufficient to cover all state ?
*/
-static enum status status(struct hpt37x *hpt)
+static enum status
+status(struct hpt37x *hpt)
{
return hpt->magic == HPT37X_MAGIC_BAD ? s_broken : s_ok;
}
/* Neutralize disk type. */
-static enum type type(struct hpt37x *hpt)
+static enum type
+type(struct hpt37x *hpt)
{
/* Mapping of HPT 37X types to generic types. */
static struct types types[] = {
- { HPT37X_T_SINGLEDISK, t_linear},
- { HPT37X_T_SPAN, t_linear},
- { HPT37X_T_RAID0, t_raid0},
- { HPT37X_T_RAID1, t_raid1},
- { HPT37X_T_RAID01_RAID0, t_raid0},
- { HPT37X_T_RAID01_RAID1, t_raid1},
+ { HPT37X_T_SINGLEDISK, t_linear },
+ { HPT37X_T_SPAN, t_linear },
+ { HPT37X_T_RAID0, t_raid0 },
+ { HPT37X_T_RAID1, t_raid1 },
+ { HPT37X_T_RAID01_RAID0, t_raid0 },
+ { HPT37X_T_RAID01_RAID1, t_raid1 },
/* FIXME: support RAID 3+5 */
- { 0, t_undef},
+ { 0, t_undef },
};
return hpt->magic_0 ?
- rd_type(types, (unsigned int) hpt->type) : t_spare;
+ rd_type(types, (unsigned int) hpt->type) : t_spare;
}
/* Decide about ordering sequence of RAID device. */
-static int dev_sort(struct list_head *pos, struct list_head *new)
+static int
+dev_sort(struct list_head *pos, struct list_head *new)
{
- return (META(RD(new), hpt37x))->disk_number <
- (META(RD(pos), hpt37x))->disk_number;
+ return META(RD(new), hpt37x)->disk_number <
+ META(RD(pos), hpt37x)->disk_number;
}
/* Decide about ordering sequence of RAID subset. */
-static int set_sort(struct list_head *pos, struct list_head *new)
+static int
+set_sort(struct list_head *pos, struct list_head *new)
{
- return (META(RD_RS(RS(new)), hpt37x))->order <
- (META(RD_RS(RS(pos)), hpt37x))->order;
+ return META(RD_RS(RS(new)), hpt37x)->order <
+ META(RD_RS(RS(pos)), hpt37x)->order;
}
/* Magic check. */
-static int check_magic(void *meta)
+static int
+check_magic(void *meta)
{
struct hpt37x *hpt = meta;
return (hpt->magic == HPT37X_MAGIC_OK ||
hpt->magic == HPT37X_MAGIC_BAD) &&
- hpt->disk_number < 8;
+ hpt->disk_number < 8;
}
/*
@@ -120,7 +125,8 @@
#if BYTE_ORDER == LITTLE_ENDIAN
# define to_cpu NULL
#else
-static void to_cpu(void *meta)
+static void
+to_cpu(void *meta)
{
struct hpt37x *hpt = meta;
@@ -138,8 +144,7 @@
for (l = hpt->errorlog;
l < hpt->errorlog +
- min(hpt->error_log_entries, HPT37X_MAX_ERRORLOG);
- l++) {
+ min(hpt->error_log_entries, HPT37X_MAX_ERRORLOG); l++) {
CVT32(l->timestamp);
CVT32(l->lba);
}
@@ -148,14 +153,16 @@
#endif
/* Use magic check to tell, if this is Highpoint 37x */
-static int is_hpt37x(struct lib_context *lc, struct dev_info *di, void *meta)
+static int
+is_hpt37x(struct lib_context *lc, struct dev_info *di, void *meta)
{
return check_magic(meta);
}
static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
struct dev_info *di, void *meta, union read_info *info);
-static struct raid_dev *hpt37x_read(struct lib_context *lc, struct dev_info *di)
+static struct raid_dev *
+hpt37x_read(struct lib_context *lc, struct dev_info *di)
{
return read_raid_dev(lc, di, NULL,
sizeof(struct hpt37x), HPT37X_CONFIGOFFSET,
@@ -165,8 +172,8 @@
/*
* Write a Highpoint 37X RAID device.
*/
-static int hpt37x_write(struct lib_context *lc,
- struct raid_dev *rd, int erase)
+static int
+hpt37x_write(struct lib_context *lc, struct raid_dev *rd, int erase)
{
int ret;
#if BYTE_ORDER != LITTLE_ENDIAN
@@ -188,28 +195,32 @@
* Check device hierarchy and create sub sets appropriately.
*
*/
-static unsigned int stride(struct hpt37x *hpt)
+static unsigned int
+stride(struct hpt37x *hpt)
{
return hpt->raid0_shift ? 1 << hpt->raid0_shift : 0;
}
-static int mismatch(struct lib_context *lc, struct raid_dev *rd, char magic)
+static int
+mismatch(struct lib_context *lc, struct raid_dev *rd, char magic)
{
LOG_ERR(lc, 0, "%s: magic_%c mismatch on %s",
handler, magic, rd->di->path);
}
-static void super_created(struct raid_set *ss, void *private)
+static void
+super_created(struct raid_set *ss, void *private)
{
struct hpt37x *hpt = META(private, hpt37x);
- ss->type = hpt->type == HPT37X_T_RAID01_RAID0 ? t_raid1 : t_raid0;
+ ss->type = hpt->type == HPT37X_T_RAID01_RAID0 ? t_raid1 : t_raid0;
ss->stride = stride(hpt);
}
/* FIXME: handle spares in mirrors and check that types are correct. */
-static int group_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_set **ss, struct raid_dev *rd)
+static int
+group_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_set **ss, struct raid_dev *rd)
{
struct hpt37x *h, *hpt = META(rd, hpt37x);
@@ -248,8 +259,8 @@
/*
* Add a Highpoint RAID device to a set.
*/
-static struct raid_set *hpt37x_group(struct lib_context *lc,
- struct raid_dev *rd)
+static struct raid_set *
+hpt37x_group(struct lib_context *lc, struct raid_dev *rd)
{
struct raid_set *rs, *ss = NULL;
@@ -268,22 +279,25 @@
*
* FIXME: more sanity checks.
*/
-static unsigned int devices(struct raid_dev *rd, void *context)
+static unsigned int
+devices(struct raid_dev *rd, void *context)
{
- return (META(rd, hpt37x))->raid_disks;
+ return META(rd, hpt37x)->raid_disks;
}
-static int check_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_dev *rd, void *context)
+static int
+check_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_dev *rd, void *context)
{
/*
* FIXME: raid_disks member wrong ?
- * (eg, Peter Jonas RAID1 metadata, 2 disks and raid_disks = 1)
+ * (eg, Peter Jonas RAID1 metadata, 2 disks and raid_disks = 1)
*/
return T_RAID1(rd);
}
-static int hpt37x_check(struct lib_context *lc, struct raid_set *rs)
+static int
+hpt37x_check(struct lib_context *lc, struct raid_set *rs)
{
return check_raid_set(lc, rs, devices, NULL, check_rd, NULL, handler);
}
@@ -291,7 +305,8 @@
/*
* IO error event handler.
*/
-static int event_io(struct lib_context *lc, struct event_io *e_io)
+static int
+event_io(struct lib_context *lc, struct event_io *e_io)
{
struct raid_dev *rd = e_io->rd;
struct hpt37x *hpt = META(rd, hpt37x);
@@ -301,20 +316,20 @@
return 0;
hpt->magic = HPT37X_MAGIC_BAD;
-
return 1;
}
static struct event_handlers hpt37x_event_handlers = {
.io = event_io,
- .rd = NULL, /* FIXME: no device add/remove event handler yet. */
+ .rd = NULL, /* FIXME: no device add/remove event handler yet. */
};
#ifdef DMRAID_NATIVE_LOG
/*
* Log native information about an HPT37X RAID device.
*/
-static void hpt37x_log(struct lib_context *lc, struct raid_dev *rd)
+static void
+hpt37x_log(struct lib_context *lc, struct raid_dev *rd)
{
struct hpt37x *hpt = META(rd, hpt37x);
struct hpt37x_errorlog *el;
@@ -348,33 +363,35 @@
DP("status: %u", hpt, el->status);
DP("sectors: %u", hpt, el->sectors);
DP("lba: %u", hpt, el->lba);
- };
+ };
}
#endif
static struct dmraid_format hpt37x_format = {
- .name = HANDLER,
- .descr = "Highpoint HPT37X",
- .caps = "S,0,1,10,01",
+ .name = HANDLER,
+ .descr = "Highpoint HPT37X",
+ .caps = "S,0,1,10,01",
.format = FMT_RAID,
- .read = hpt37x_read,
- .write = hpt37x_write,
- .group = hpt37x_group,
- .check = hpt37x_check,
- .events = &hpt37x_event_handlers,
+ .read = hpt37x_read,
+ .write = hpt37x_write,
+ .group = hpt37x_group,
+ .check = hpt37x_check,
+ .events = &hpt37x_event_handlers,
#ifdef DMRAID_NATIVE_LOG
- .log = hpt37x_log,
+ .log = hpt37x_log,
#endif
};
/* Register this format handler with the format core. */
-int register_hpt37x(struct lib_context *lc)
+int
+register_hpt37x(struct lib_context *lc)
{
return register_format_handler(lc, &hpt37x_format);
}
/* Calculate RAID device size in sectors depending on RAID type. */
-static uint64_t sectors(struct raid_dev *rd, struct hpt37x *hpt)
+static uint64_t
+sectors(struct raid_dev *rd, struct hpt37x *hpt)
{
uint64_t ret = 0;
struct dev_info *di = rd->di;
@@ -397,8 +414,9 @@
}
/* Derive the RAID device contents from the Highpoint ones. */
-static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta, union read_info *info)
+static int
+setup_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct dev_info *di, void *meta, union read_info *info)
{
struct hpt37x *hpt = meta;
@@ -407,18 +425,18 @@
rd->meta_areas->offset = HPT37X_CONFIGOFFSET >> 9;
rd->meta_areas->size = sizeof(*hpt);
- rd->meta_areas->area = (void*) hpt;
+ rd->meta_areas->area = (void *) hpt;
- rd->di = di;
+ rd->di = di;
rd->fmt = &hpt37x_format;
rd->status = status(hpt);
- rd->type = type(hpt);
+ rd->type = type(hpt);
/* Data offset from start of device; first device is special */
- rd->offset = hpt->disk_number ? HPT37X_DATAOFFSET : 0;
- if (!(rd->sectors = sectors(rd, hpt)))
+ rd->offset = hpt->disk_number ? HPT37X_DATAOFFSET : 0;
+ if (!(rd->sectors = sectors(rd, hpt)))
return log_zero_sectors(lc, di->path, handler);
- return (rd->name = name(lc, rd, 1)) ? 1 : 0;
+ return (rd->name = name(lc, rd, 1)) ? 1 : 0;
}
--- dmraid/lib/format/ataraid/hpt37x.h 2008/02/22 17:04:35 1.2
+++ dmraid/lib/format/ataraid/hpt37x.h 2008/06/20 21:52:17 1.3
@@ -39,60 +39,59 @@
#include <stdint.h>
/* HPT 37x config data byte offset on disk */
-#define HPT37X_CONFIGOFFSET (9 << 9) /* 9 sectors */
+#define HPT37X_CONFIGOFFSET (9 << 9) /* 9 sectors */
#define HPT37X_DATAOFFSET 10 /* Data offset in sectors */
/* Ondisk metadata for Highpoint ATARAID */
struct hpt37x {
- uint8_t filler1[32];
+ uint8_t filler1[32];
- uint32_t magic;
+ uint32_t magic;
#define HPT37X_MAGIC_OK 0x5a7816f0
-#define HPT37X_MAGIC_BAD 0x5a7816fd
+#define HPT37X_MAGIC_BAD 0x5a7816fd
- uint32_t magic_0; /* Set identifier */
- uint32_t magic_1; /* Array identifier */
+ uint32_t magic_0; /* Set identifier */
+ uint32_t magic_1; /* Array identifier */
- uint32_t order;
-#define HPT_O_MIRROR 0x01
+ uint32_t order;
+#define HPT_O_MIRROR 0x01
#define HPT_O_STRIPE 0x02
#define HPT_O_OK 0x04
- uint8_t raid_disks;
- uint8_t raid0_shift;
+ uint8_t raid_disks;
+ uint8_t raid0_shift;
- uint8_t type;
-#define HPT37X_T_RAID0 0x00
+ uint8_t type;
+#define HPT37X_T_RAID0 0x00
#define HPT37X_T_RAID1 0x01
#define HPT37X_T_RAID01_RAID0 0x02
#define HPT37X_T_SPAN 0x03
-#define HPT37X_T_RAID_3 0x04
+#define HPT37X_T_RAID_3 0x04
#define HPT37X_T_RAID_5 0x05
#define HPT37X_T_SINGLEDISK 0x06
#define HPT37X_T_RAID01_RAID1 0x07
- uint8_t disk_number;
- uint32_t total_secs;
- uint32_t disk_mode;
- uint32_t boot_mode;
- uint8_t boot_disk;
- uint8_t boot_protect;
- uint8_t error_log_entries;
- uint8_t error_log_index;
+ uint8_t disk_number;
+ uint32_t total_secs;
+ uint32_t disk_mode;
+ uint32_t boot_mode;
+ uint8_t boot_disk;
+ uint8_t boot_protect;
+ uint8_t error_log_entries;
+ uint8_t error_log_index;
#define HPT37X_MAX_ERRORLOG 32
- struct hpt37x_errorlog
- {
- uint32_t timestamp;
- uint8_t reason;
-#define HPT_R_REMOVED 0xfe
-#define HPT_R_BROKEN 0xff
-
- uint8_t disk;
- uint8_t status;
- uint8_t sectors;
- uint32_t lba;
- } errorlog[HPT37X_MAX_ERRORLOG];
- uint8_t filler[60];
+ struct hpt37x_errorlog {
+ uint32_t timestamp;
+ uint8_t reason;
+#define HPT_R_REMOVED 0xfe
+#define HPT_R_BROKEN 0xff
+
+ uint8_t disk;
+ uint8_t status;
+ uint8_t sectors;
+ uint32_t lba;
+ } errorlog[HPT37X_MAX_ERRORLOG];
+ uint8_t filler[60];
} __attribute__ ((packed));
#endif
--- dmraid/lib/format/ataraid/hpt45x.c 2008/02/22 17:04:35 1.2
+++ dmraid/lib/format/ataraid/hpt45x.c 2008/06/20 21:52:17 1.3
@@ -1,7 +1,7 @@
/*
* Highpoint 45X ATARAID series metadata format handler.
*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
* See file LICENSE at the top of this source tree for license information.
@@ -26,8 +26,8 @@
/* Make up RAID set name from magic_0 number */
/* FIXME: better name ? */
-static size_t _name(struct hpt45x *hpt, char *str, size_t len,
- unsigned int subset)
+static size_t
+_name(struct hpt45x *hpt, char *str, size_t len, unsigned int subset)
{
const char *fmt;
@@ -39,8 +39,8 @@
return snprintf(str, len, fmt, hpt->magic_0, hpt->raid1_disk_number);
}
-static char *name(struct lib_context *lc, struct raid_dev *rd,
- unsigned int subset)
+static char *
+name(struct lib_context *lc, struct raid_dev *rd, unsigned int subset)
{
size_t len;
char *ret;
@@ -60,39 +60,43 @@
* Retrieve status of device.
* FIXME: is this sufficient to cover all state ?
*/
-static enum status status(struct hpt45x *hpt)
+static enum status
+status(struct hpt45x *hpt)
{
return hpt->magic == HPT45X_MAGIC_BAD ? s_broken : s_ok;
}
/* Neutralize disk type */
-static enum type type(struct hpt45x *hpt)
+static enum type
+type(struct hpt45x *hpt)
{
/* Mapping of HPT 45X types to generic types */
static struct types types[] = {
- { HPT45X_T_SPAN, t_linear},
- { HPT45X_T_RAID0, t_raid0},
- { HPT45X_T_RAID1, t_raid1},
+ { HPT45X_T_SPAN, t_linear },
+ { HPT45X_T_RAID0, t_raid0 },
+ { HPT45X_T_RAID1, t_raid1 },
/* FIXME: handle RAID 4+5 */
- { 0, t_undef},
+ { 0, t_undef },
};
return hpt->magic_0 ? rd_type(types, (unsigned int) hpt->type) :
- t_spare;
+ t_spare;
}
/* Decide about ordering sequence of RAID device. */
-static int dev_sort(struct list_head *pos, struct list_head *new)
+static int
+dev_sort(struct list_head *pos, struct list_head *new)
{
- return (META(RD(new), hpt45x))->disk_number <
- (META(RD(pos), hpt45x))->disk_number;
+ return META(RD(new), hpt45x)->disk_number <
+ META(RD(pos), hpt45x)->disk_number;
}
/* Decide about ordering sequence of RAID subset. */
-static int set_sort(struct list_head *pos, struct list_head *new)
+static int
+set_sort(struct list_head *pos, struct list_head *new)
{
- return (META(RD_RS(RS(new)), hpt45x))->raid1_disk_number <
- (META(RD_RS(RS(pos)), hpt45x))->raid1_disk_number;
+ return META(RD_RS(RS(new)), hpt45x)->raid1_disk_number <
+ META(RD_RS(RS(pos)), hpt45x)->raid1_disk_number;
}
/*
@@ -100,19 +104,22 @@
*
* Check device hierarchy and create super set appropriately.
*/
-static unsigned int stride(unsigned int shift)
+static unsigned int
+stride(unsigned int shift)
{
- return shift ? 1 << shift : 0;
+ return shift ? (1 << shift) : 0;
}
-static void super_created(struct raid_set *super, void *private)
+static void
+super_created(struct raid_set *super, void *private)
{
- super->type = t_raid1;
+ super->type = t_raid1;
super->stride = stride(META((private), hpt45x)->raid1_shift);
}
-static int group_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_set **ss, struct raid_dev *rd)
+static int
+group_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_set **ss, struct raid_dev *rd)
{
struct hpt45x *hpt = META(rd, hpt45x);
@@ -125,7 +132,7 @@
switch (hpt->type) {
case HPT45X_T_SPAN:
case HPT45X_T_RAID1:
- no_raid10:
+ no_raid10:
if (!find_set(lc, NULL, rs->name, FIND_TOP))
list_add_tail(&rs->list, LC_RS(lc));
@@ -152,8 +159,8 @@
/*
* Add a Highpoint RAID device to a set.
*/
-static struct raid_set *hpt45x_group(struct lib_context *lc,
- struct raid_dev *rd)
+static struct raid_set *
+hpt45x_group(struct lib_context *lc, struct raid_dev *rd)
{
struct raid_set *rs, *ss = NULL;
@@ -174,7 +181,8 @@
#if BYTE_ORDER == LITTLE_ENDIAN
# define to_cpu NULL
#else
-static void to_cpu(void *meta)
+static void
+to_cpu(void *meta)
{
struct hpt45x *hpt = meta;
@@ -186,19 +194,20 @@
#endif
/* Magic check. */
-static int is_hpt45x(struct lib_context *lc, struct dev_info *di, void *meta)
+static int
+is_hpt45x(struct lib_context *lc, struct dev_info *di, void *meta)
{
struct hpt45x *hpt = meta;
return (hpt->magic == HPT45X_MAGIC_OK ||
hpt->magic == HPT45X_MAGIC_BAD) &&
- hpt->disk_number < 8;
+ hpt->disk_number < 8;
}
static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
struct dev_info *di, void *meta, union read_info *info);
-static struct raid_dev *hpt45x_read(struct lib_context *lc,
- struct dev_info *di)
+static struct raid_dev *
+hpt45x_read(struct lib_context *lc, struct dev_info *di)
{
return read_raid_dev(lc, di, NULL,
sizeof(struct hpt45x), HPT45X_CONFIGOFFSET,
@@ -208,8 +217,8 @@
/*
* Write a Highpoint 45X RAID device.
*/
-static int hpt45x_write(struct lib_context *lc,
- struct raid_dev *rd, int erase)
+static int
+hpt45x_write(struct lib_context *lc, struct raid_dev *rd, int erase)
{
int ret;
#if BYTE_ORDER != LITTLE_ENDIAN
@@ -229,12 +238,14 @@
*
* FIXME: more sanity checks.
*/
-static unsigned int devices(struct raid_dev *rd, void *context)
+static unsigned int
+devices(struct raid_dev *rd, void *context)
{
- return (META(rd, hpt45x))->raid_disks;
+ return META(rd, hpt45x)->raid_disks;
}
-static int hpt45x_check(struct lib_context *lc, struct raid_set *rs)
+static int
+hpt45x_check(struct lib_context *lc, struct raid_set *rs)
{
return check_raid_set(lc, rs, devices, NULL,
NO_CHECK_RD, NULL, handler);
@@ -243,7 +254,8 @@
/*
* IO error event handler.
*/
-static int event_io(struct lib_context *lc, struct event_io *e_io)
+static int
+event_io(struct lib_context *lc, struct event_io *e_io)
{
struct raid_dev *rd = e_io->rd;
struct hpt45x *hpt = META(rd, hpt45x);
@@ -253,20 +265,20 @@
return 0;
hpt->magic = HPT45X_MAGIC_BAD;
-
return 1;
}
static struct event_handlers hpt45x_event_handlers = {
.io = event_io,
- .rd = NULL, /* FIXME: no device add/remove event handler yet. */
+ .rd = NULL, /* FIXME: no device add/remove event handler yet. */
};
#ifdef DMRAID_NATIVE_LOG
/*
* Log native information about an HPT45X RAID device.
*/
-static void hpt45x_log(struct lib_context *lc, struct raid_dev *rd)
+static void
+hpt45x_log(struct lib_context *lc, struct raid_dev *rd)
{
unsigned int i;
struct hpt45x *hpt = META(rd, hpt45x);
@@ -293,35 +305,37 @@
#endif
static struct dmraid_format hpt45x_format = {
- .name = HANDLER,
- .descr = "Highpoint HPT45X",
- .caps = "S,0,1,10",
+ .name = HANDLER,
+ .descr = "Highpoint HPT45X",
+ .caps = "S,0,1,10",
.format = FMT_RAID,
- .read = hpt45x_read,
- .write = hpt45x_write,
- .group = hpt45x_group,
- .check = hpt45x_check,
- .events = &hpt45x_event_handlers,
+ .read = hpt45x_read,
+ .write = hpt45x_write,
+ .group = hpt45x_group,
+ .check = hpt45x_check,
+ .events = &hpt45x_event_handlers,
#ifdef DMRAID_NATIVE_LOG
- .log = hpt45x_log,
+ .log = hpt45x_log,
#endif
};
/* Register this format handler with the format core. */
-int register_hpt45x(struct lib_context *lc)
+int
+register_hpt45x(struct lib_context *lc)
{
return register_format_handler(lc, &hpt45x_format);
}
/* Calculate RAID device size in sectors depending on RAID type. */
-static uint64_t sectors(struct raid_dev *rd, void *meta)
+static uint64_t
+sectors(struct raid_dev *rd, void *meta)
{
struct hpt45x *hpt = meta;
switch (rd->type) {
case t_raid0:
return hpt->total_secs /
- (hpt->raid_disks ? hpt->raid_disks : 1);
+ (hpt->raid_disks ? hpt->raid_disks : 1);
case t_raid1:
return hpt->total_secs;
@@ -332,8 +346,9 @@
}
/* Set the RAID device contents up derived from the Highpoint ones */
-static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta, union read_info *info)
+static int
+setup_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct dev_info *di, void *meta, union read_info *info)
{
struct hpt45x *hpt = meta;
@@ -342,18 +357,18 @@
rd->meta_areas->offset = HPT45X_CONFIGOFFSET >> 9;
rd->meta_areas->size = sizeof(*hpt);
- rd->meta_areas->area = (void*) hpt;
+ rd->meta_areas->area = (void *) hpt;
rd->di = di;
rd->fmt = &hpt45x_format;
rd->status = status(hpt);
- rd->type = type(hpt);
+ rd->type = type(hpt);
rd->offset = HPT45X_DATAOFFSET;
if (!(rd->sectors = sectors(rd, hpt)))
return log_zero_sectors(lc, di->path, handler);
return (rd->name = name(lc, rd, hpt->raid1_type == HPT45X_T_RAID1)) ?
- 1 : 0;
+ 1 : 0;
}
--- dmraid/lib/format/ataraid/hpt45x.h 2008/02/22 16:57:36 1.1
+++ dmraid/lib/format/ataraid/hpt45x.h 2008/06/20 21:52:17 1.2
@@ -15,36 +15,36 @@
/* Highpoint 45x config data sector offset off end of disk */
#define HPT45X_CONFIGOFFSET ((di->sectors - 11) << 9)
-#define HPT45X_DATAOFFSET 0 /* Data offset in sectors */
+#define HPT45X_DATAOFFSET 0 /* Data offset in sectors */
/* Ondisk metadata for Highpoint 45X ATARAID */
struct hpt45x {
- uint32_t magic; /* 0x0 - 0x03 */
+ uint32_t magic; /* 0x0 - 0x03 */
#define HPT45X_MAGIC_OK 0x5a7816f3
#define HPT45X_MAGIC_BAD 0x5a7816fd
- uint32_t magic_0; /* 0x04 - 0x07 Set identifier */
- uint32_t magic_1; /* 0x08 - 0x0A (Sub-)Array identifier */
+ uint32_t magic_0; /* 0x04 - 0x07 Set identifier */
+ uint32_t magic_1; /* 0x08 - 0x0A (Sub-)Array identifier */
- uint32_t total_secs; /* 0x0B - 0x0F */
+ uint32_t total_secs; /* 0x0B - 0x0F */
- uint8_t type; /* 0x10 */
+ uint8_t type; /* 0x10 */
#define HPT45X_T_SPAN 0x04
#define HPT45X_T_RAID0 0x05
#define HPT45X_T_RAID1 0x06
- uint8_t raid_disks; /* 0x11 */
- uint8_t disk_number; /* 0x12 */
- uint8_t raid0_shift; /* 0x13 */
-
- uint32_t dummy[3]; /* 0x14 - 0x1F */
-
- uint8_t raid1_type; /* 0x20 */
- uint8_t raid1_raid_disks; /* 0x21 */
- uint8_t raid1_disk_number; /* 0x22 */
- uint8_t raid1_shift; /* 0x23 */
+ uint8_t raid_disks; /* 0x11 */
+ uint8_t disk_number; /* 0x12 */
+ uint8_t raid0_shift; /* 0x13 */
+
+ uint32_t dummy[3]; /* 0x14 - 0x1F */
+
+ uint8_t raid1_type; /* 0x20 */
+ uint8_t raid1_raid_disks; /* 0x21 */
+ uint8_t raid1_disk_number; /* 0x22 */
+ uint8_t raid1_shift; /* 0x23 */
- uint32_t dummy1[3]; /* 0x24 - 0x2F */
+ uint32_t dummy1[3]; /* 0x24 - 0x2F */
} __attribute__ ((packed));
#endif
--- dmraid/lib/format/ataraid/isw.c 2008/04/02 13:35:31 1.3
+++ dmraid/lib/format/ataraid/isw.c 2008/06/20 21:52:17 1.4
@@ -1,9 +1,12 @@
/*
* Intel Software RAID metadata format handler.
*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007,2008 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
@@ -15,7 +18,9 @@
*/
#define HANDLER "isw"
+#include <time.h>
#include "internal.h"
+#include <device/scsi.h>
#define FORMAT_HANDLER
#include "isw.h"
@@ -24,74 +29,168 @@
# include <datastruct/byteorder.h>
#endif
+#define GB_DIV 1024/1024/2
+
static const char *handler = HANDLER;
-/*
- * Make up RAID set name from family_num and volume name.
- */
-static size_t _name(struct isw *isw, struct isw_dev *dev,
- char *str, size_t len)
-{
- return snprintf(str, len, dev ? "isw_%u_%s" : "isw_%u",
- isw->family_num, (char*) dev->volume);
+/* Return minimum/maximum disks for a given RAID level. */
+static uint16_t
+_num_disks(uint8_t raid_level, int max)
+{
+ struct mm {
+ uint8_t level;
+ uint16_t min, max;
+ };
+ static struct mm mm[] = {
+ {ISW_T_RAID0, 2, 6},
+ {ISW_T_RAID1, 2, 2},
+ {ISW_T_RAID10, 4, 4},
+ {ISW_T_RAID5, 3, 6},
+ };
+ struct mm *m = ARRAY_END(mm);
+
+ while (m-- > mm) {
+ if (raid_level == m->level)
+ return max ? m->max : m->min;
+ }
+
+ return 1;
}
-static char *name(struct lib_context *lc, struct isw *isw, struct isw_dev *dev)
+static inline uint16_t
+min_num_disks(uint8_t raid_level)
{
- size_t len;
- char *ret;
+ return _num_disks(raid_level, 0);
+}
- if ((ret = dbg_malloc((len = _name(isw, dev, NULL, 0) + 1)))) {
- _name(isw, dev, ret, len);
- mk_alpha(lc, ret + HANDLER_LEN, len - HANDLER_LEN -
- (dev ? strlen((char*) dev->volume) - 2 : 1));
- } else
- log_alloc_err(lc, handler);
+static inline uint16_t
+max_num_disks(uint8_t raid_level)
+{
+ return _num_disks(raid_level, 1);
+}
- return ret;
+/* Check if given device belongs to a RAID10 mapping. */
+static int
+is_raid10(struct isw_dev *dev)
+{
+ return dev ? (dev->vol.map.raid_level == ISW_T_RAID10 ||
+ (dev->vol.map.raid_level == ISW_T_RAID1 &&
+ dev->vol.map.num_members >=
+ min_num_disks(ISW_T_RAID10))) : 0;
}
/* Find a disk table slot by serial number. */
-static struct isw_disk *_get_disk(struct isw *isw, struct dev_info *di)
+static struct isw_disk *
+_get_disk(struct isw *isw, struct dev_info *di)
{
if (di->serial) {
+ int i = isw->num_disks;
struct isw_disk *disk = isw->disk;
- do {
- if (!strncmp(di->serial, (const char*) disk->serial,
+ while (i--) {
+ if (!strncmp(di->serial, (const char *) disk[i].serial,
MAX_RAID_SERIAL_LEN))
- return disk;
- } while (++disk < isw->disk + isw->num_disks);
+ return disk + i;
+ }
}
return NULL;
}
-static struct isw_disk *get_disk(struct lib_context *lc,
- struct dev_info *di, struct isw *isw)
+static struct isw_disk *
+get_disk(struct lib_context *lc, struct dev_info *di, struct isw *isw)
{
struct isw_disk *disk;
if ((disk = _get_disk(isw, di)))
return disk;
- LOG_ERR(lc, NULL, "%s: Error finding disk table slot for %s",
+ LOG_ERR(lc, NULL, "%s: Could not find disk %s in the metadata",
handler, di->path);
}
+
+enum name_type { N_PATH, N_NUMBER, N_VOLUME, N_VOLUME_FORCE };
+static size_t
+_name(struct lib_context *lc, struct isw *isw, char *str, size_t len,
+ enum name_type nt, int num, struct isw_dev *dev, struct raid_dev *rd)
+{
+ struct {
+ const char *fmt, *what;
+ } formats[] = {
+ {
+ "isw_%u_%s", rd->di->path}, {
+ "isw_%u", NULL}, {
+ "isw_%u_%s", (const char *) dev->volume}, {
+ "isw_%u_%s-%u", (const char *) dev->volume},}, *f = formats;
+
+ if (nt < 0 || nt > N_VOLUME_FORCE)
+ LOG_ERR(lc, 0, "unsupported name type");
+
+ if (nt == N_VOLUME_FORCE)
+ f += N_VOLUME;
+ else {
+ f += nt;
+ if (nt == N_VOLUME)
+ f += (is_raid10(dev) ? 1 : 0);
+ }
+
+ return snprintf(str, len, f->fmt, isw->family_num, f->what, num);
+}
+
+static char *
+name(struct lib_context *lc, struct raid_dev *rd,
+ struct isw_dev *dev, enum name_type nt)
+{
+ size_t len;
+ char *ret = NULL;
+ int id = 0;
+ struct isw *isw = META(rd, isw);
+ struct isw_disk *disk = isw->disk;
+
+ if (nt == N_VOLUME && is_raid10(dev)) {
+ if ((disk = _get_disk(isw, rd->di))) {
+ int i = max_num_disks(ISW_T_RAID10);
+
+ while (i--) {
+ if (disk == isw->disk + i) {
+ id = i % 2;
+ goto ok;
+ }
+ }
+
+ return NULL;
+ }
+ }
+
+ ok:
+ if ((ret = alloc_private(lc, handler,
+ (len = _name(lc, isw, ret, 0, nt, id,
+ dev, rd) + 1)))) {
+ _name(lc, isw, ret, len, nt, id, dev, rd);
+ len = snprintf(ret, 0, "%u", isw->family_num);
+ mk_alpha(lc, ret + HANDLER_LEN, len);
+ }
+ else
+ log_alloc_err(lc, handler);
+
+ return ret;
+}
+
/*
* Retrieve status of device.
*
* FIXME: is this sufficient to cover all state ?
*/
-static enum status __status(unsigned int status)
+static enum status
+__status(unsigned status)
{
- return ((status & (CONFIGURED_DISK|USABLE_DISK)) &&
- !(FAILED_DISK & status)) ?
- s_ok : s_broken;
+ return ((status & (CONFIGURED_DISK | USABLE_DISK)) &&
+ !(FAILED_DISK & status)) ? s_ok : s_broken;
}
-static enum status status(struct lib_context *lc, struct raid_dev *rd)
+static enum status
+status(struct lib_context *lc, struct raid_dev *rd)
{
struct isw_disk *disk;
@@ -101,30 +200,53 @@
return s_undef;
}
+/* Mapping of Intel types to generic types. */
+static struct types types[] = {
+ {ISW_T_RAID0, t_raid0},
+ {ISW_T_RAID1, t_raid1},
+ {ISW_T_RAID5, t_raid5_la},
+ /* Only left asymmetric supported now.
+ { ISW_T_RAID5, t_raid5_ls},
+ { ISW_T_RAID5, t_raid5_ra},
+ { ISW_T_RAID5, t_raid5_rs}, */
+ {ISW_T_RAID10, t_raid1},
+ {ISW_T_SPARE, t_spare},
+ {ISW_T_UNDEF, t_undef},
+};
+
+static uint8_t
+_get_raid_level(enum type raid_type)
+{
+ int i;
+
+ for (i = 0;
+ types[i].unified_type != t_undef &&
+ types[i].unified_type != raid_type; i++);
+
+ return types[i].type;
+}
+
/* Neutralize disk type. */
-static enum type type(struct raid_dev *rd)
+static enum type
+type(struct isw_dev *dev)
{
- /* Mapping of Intel types to generic types. */
- static struct types types[] = {
- { ISW_T_RAID0, t_raid0},
- { ISW_T_RAID1, t_raid1},
- { ISW_T_RAID5, t_raid5_la},
- { 0, t_undef},
- };
- struct isw_dev *dev = rd->private.ptr;
- return dev ? rd_type(types, (unsigned int) dev->vol.map.raid_level) :
- t_group;
+ if (is_raid10(dev))
+ return t_raid1;
+
+ return dev ? rd_type(types, (unsigned) dev->vol.map.raid_level) :
+ t_group;
}
/*
* Generate checksum of Raid metadata for mpb_size/sizeof(u32) words
* (checksum field itself ignored for this calculation).
*/
-static uint32_t _checksum(struct isw *isw)
+static uint32_t
+_checksum(struct isw *isw)
{
uint32_t end = isw->mpb_size / sizeof(end),
- *p = (uint32_t*) isw, ret = 0;
+ *p = (uint32_t *) isw, ret = 0;
while (end--)
ret += *p++;
@@ -133,16 +255,17 @@
}
/* Calculate next isw device offset. */
-static struct isw_dev *advance_dev(struct isw_dev *dev,
- struct isw_map *map, size_t add)
+static struct isw_dev *
+advance_dev(struct isw_dev *dev, struct isw_map *map, size_t add)
{
- return (struct isw_dev*) ((uint8_t*) dev +
- (map->num_members - 1) *
- sizeof(map->disk_ord_tbl) + add);
+ return (struct isw_dev *) ((uint8_t *) dev +
+ (map->num_members - 1) *
+ sizeof(map->disk_ord_tbl) + add);
}
/* Advance to the next isw_dev from a given one. */
-static struct isw_dev *advance_raiddev(struct isw_dev *dev)
+static struct isw_dev *
+advance_raiddev(struct isw_dev *dev)
{
struct isw_vol *vol = &dev->vol;
struct isw_map *map = &vol->map;
@@ -150,16 +273,18 @@
/* Correction: yes, it sits here! */
dev = advance_dev(dev, map, sizeof(*dev));
- if (vol->migr_state) /* need to add space for another map */
+ if (vol->migr_state)
+ /* Need to add space for another map. */
dev = advance_dev(dev, map, sizeof(*map));
return dev;
}
/* Return isw_dev by table index. */
-static struct isw_dev *raiddev(struct isw *isw, unsigned int i)
+static struct isw_dev *
+raiddev(struct isw *isw, unsigned i)
{
- struct isw_dev *dev = (struct isw_dev*) (isw->disk + isw->num_disks);
+ struct isw_dev *dev = (struct isw_dev *) (isw->disk + isw->num_disks);
while (i--)
dev = advance_raiddev(dev);
@@ -179,9 +304,10 @@
* We can differ from the read_raid_dev template here,
* because we don't get called from there.
*/
-static void to_cpu(struct isw *isw, enum convert cvt)
+static void
+to_cpu(struct isw *isw, enum convert cvt)
{
- unsigned int i, j;
+ unsigned i, j;
struct isw_disk *dsk;
struct isw_dev *dev;
@@ -211,7 +337,7 @@
CVT32(dev->reserved_blocks);
/* RAID volume has 8 bit members only. */
-
+
/* RAID map. */
CVT32(dev->vol.map.pba_of_lba0);
CVT32(dev->vol.map.blocks_per_member);
@@ -224,29 +350,45 @@
}
#endif
-static int is_isw(struct lib_context *lc, struct dev_info *di, struct isw *isw)
+/* Return sector rounded size of isw metadata. */
+static size_t
+isw_size(struct isw *isw)
+{
+ return round_up(isw->mpb_size, ISW_DISK_BLOCK_SIZE);
+}
+
+/* Set metadata area size in bytes and config offset in sectors. */
+static void
+set_metadata_sizoff(struct raid_dev *rd, size_t size)
+{
+ rd->meta_areas->size = size;
+ rd->meta_areas->offset = ISW_CONFIGSECTOR(rd->di) -
+ size / ISW_DISK_BLOCK_SIZE + 1;
+}
+
+/* Check for isw signature (magic) and version. */
+static int
+is_isw(struct lib_context *lc, struct dev_info *di, struct isw *isw)
{
- if (strncmp((const char *) isw->sig, MPB_SIGNATURE,
- sizeof(MPB_SIGNATURE) - 1))
+ if (strncmp((const char *) isw->sig, MPB_SIGNATURE, MPB_SIGNATURE_SIZE))
return 0;
- /* Check version info, older versions supported */
- if (strncmp((const char*) isw->sig + sizeof(MPB_SIGNATURE) - 1,
- MPB_VERSION_RAID2, sizeof(MPB_VERSION_RAID2) - 1) > 0)
- log_print(lc, "%s: untested metadata version %s found on %s",
- handler, isw->sig + sizeof(MPB_SIGNATURE) - 1,
- di->path);
+ /* Check version info; older versions supported. */
+ if (strncmp((const char *) isw->sig + MPB_SIGNATURE_SIZE,
+ MPB_VERSION_RAID2, MPB_VERSION_RAID2_SIZE) > 0)
+ log_print(lc,
+ "%s: untested metadata version %s found on %s",
+ handler, isw->sig + MPB_SIGNATURE_SIZE, di->path);
return 1;
}
-static void isw_file_metadata(struct lib_context *lc, struct dev_info *di,
- void *meta)
+static void
+isw_file_metadata(struct lib_context *lc, struct dev_info *di, void *meta)
{
struct isw *isw = meta;
-
/* Get the rounded up value for the metadata size */
- size_t size = round_up(isw->mpb_size, ISW_DISK_BLOCK_SIZE);
+ size_t size = isw_size(isw);
file_metadata(lc, handler, di->path,
meta + (size / ISW_DISK_BLOCK_SIZE > 1 ?
@@ -255,62 +397,54 @@
file_dev_size(lc, handler, di);
}
-static int isw_read_extended(struct lib_context *lc, struct dev_info *di,
- struct isw **isw,
- uint64_t *isw_sboffset, size_t *size)
+static int
+isw_read_extended(struct lib_context *lc, struct dev_info *di,
+ struct isw **isw, uint64_t * isw_sboffset, size_t * size)
{
struct isw *isw_tmp;
-
/* Get the rounded up value for the metadata blocks */
size_t blocks = div_up((*isw)->mpb_size, ISW_DISK_BLOCK_SIZE);
- /* No extended metadata to read ? */
- if (blocks < 2)
- return 1;
-
- /*
- * Allocate memory for the extended Intel superblock
- * and read it in. Reserve one more disk block in order
- * to be able to file the metadata in the proper sequence.
- * (ie, sectors 1, 2-n, 1 in core so that the filing can start at 2).
- */
+ /* Allocate memory for the extended Intel superblock and read it in. */
*size = blocks * ISW_DISK_BLOCK_SIZE;
*isw_sboffset -= *size - ISW_DISK_BLOCK_SIZE;
- if ((isw_tmp = alloc_private(lc, handler,
- *size + ISW_DISK_BLOCK_SIZE))) {
+ if ((isw_tmp = alloc_private(lc, handler, *size))) {
+ /* Copy in first metadata sector. */
+ memcpy(isw_tmp, *isw, ISW_DISK_BLOCK_SIZE);
+
/* Read extended metadata to offset ISW_DISK_BLOCK_SIZE */
- if (read_file(lc, handler, di->path,
- (void*) isw_tmp + ISW_DISK_BLOCK_SIZE,
- *size - ISW_DISK_BLOCK_SIZE, *isw_sboffset))
- /* Copy in first metadata sector. */
- memcpy(isw_tmp, *isw, ISW_DISK_BLOCK_SIZE);
- else {
+ if (blocks > 1 &&
+ !read_file(lc, handler, di->path,
+ (void *) isw_tmp + ISW_DISK_BLOCK_SIZE,
+ *size - ISW_DISK_BLOCK_SIZE, *isw_sboffset)) {
dbg_free(isw_tmp);
isw_tmp = NULL;
}
}
+ else
+ return 0;
dbg_free(*isw);
*isw = isw_tmp;
-
- return isw_tmp ? 1 : 0;
+ return *isw ? 1 : 0;
}
/* Check for RAID disk ok. */
-static int disk_ok(struct lib_context *lc, struct dev_info *di, struct isw *isw)
+static int
+disk_ok(struct lib_context *lc, struct dev_info *di, struct isw *isw)
{
struct isw_disk *disk = get_disk(lc, di, isw);
return disk && __status(disk->status) == s_ok;
}
-static void *isw_read_metadata(struct lib_context *lc, struct dev_info *di,
- size_t *sz, uint64_t *offset,
- union read_info *info)
+static void *
+isw_read_metadata(struct lib_context *lc, struct dev_info *di,
+ size_t * sz, uint64_t * offset, union read_info *info)
{
size_t size = ISW_DISK_BLOCK_SIZE;
- uint64_t isw_sboffset = ISW_CONFIGOFFSET;
+ uint64_t isw_sboffset = ISW_CONFIGOFFSET(di);
struct isw *isw;
if (!(isw = alloc_private_and_read(lc, handler, size,
@@ -336,57 +470,60 @@
if (disk_ok(lc, di, isw)) {
*sz = size;
- *offset = isw_sboffset;
- info->u64 = isw_sboffset;
+ *offset = info->u64 = isw_sboffset;
goto out;
}
-
- bad:
+
+ bad:
dbg_free(isw);
isw = NULL;
- out:
- return (void*) isw;
+ out:
+ return (void *) isw;
}
static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
struct dev_info *di, void *meta, union read_info *info);
-static struct raid_dev *isw_read(struct lib_context *lc, struct dev_info *di)
+static struct raid_dev *
+isw_read(struct lib_context *lc, struct dev_info *di)
{
return read_raid_dev(lc, di, isw_read_metadata, 0, 0, NULL, NULL,
isw_file_metadata, setup_rd, handler);
}
/*
- * Write an Intel Software RAID device.
+ * Write metadata to an Intel Software RAID device.
*/
-static int isw_write(struct lib_context *lc, struct raid_dev *rd, int erase)
+static int
+isw_write(struct lib_context *lc, struct raid_dev *rd, int erase)
{
int ret;
struct isw *isw = META(rd, isw);
- int large = div_up(isw->mpb_size, ISW_DISK_BLOCK_SIZE) > 1;
+ void *dst, *src = isw;
+ uint32_t size = isw->mpb_size;
to_disk(isw, FULL);
- if (large) {
- /*
- * Copy 1st metadata sector to after the extended ones
- * and increment metadata area pointer by one block, so
- * that the metadata is filed in the proper sequence.
- */
- memcpy((void*) isw + rd->meta_areas->size, isw,
- ISW_DISK_BLOCK_SIZE);
- rd->meta_areas->area += ISW_DISK_BLOCK_SIZE;
- }
+ /* Flip sectors for write_metadata() to work if extended metadata. */
+ if (size > ISW_DISK_BLOCK_SIZE) {
+ /* sunil */
+ dst = alloc_private(lc, handler, 2 * ISW_DISK_BLOCK_SIZE);
+ if (!dst)
+ return 0;
+ memcpy(dst, src + ISW_DISK_BLOCK_SIZE, ISW_DISK_BLOCK_SIZE);
+ memcpy(dst + ISW_DISK_BLOCK_SIZE, src, ISW_DISK_BLOCK_SIZE);
+ }
+ else
+ dst = isw;
+ rd->meta_areas->area = dst;
ret = write_metadata(lc, handler, rd, -1, erase);
+ rd->meta_areas->area = isw;
- /* Correct metadata area pointer. */
- if (large)
- rd->meta_areas->area -= ISW_DISK_BLOCK_SIZE;
+ if (dst != isw)
+ dbg_free(dst);
to_cpu(isw, FULL);
-
return ret;
}
@@ -395,137 +532,222 @@
* multiple RAID sets and RAID disks.
*/
/* Check state if isw device map. */
-static int _check_map_state(struct lib_context *lc, struct raid_dev *rd,
- struct isw_dev *dev)
+static int
+_check_map_state(struct lib_context *lc, struct raid_dev *rd,
+ struct isw_dev *dev)
{
/* FIXME: FAILED_MAP etc. */
switch (dev->vol.map.map_state) {
case ISW_T_STATE_NORMAL:
case ISW_T_STATE_UNINITIALIZED:
+ case ISW_T_STATE_DEGRADED:
+ case ISW_T_STATE_FAILED:
break;
default:
- LOG_ERR(lc, 0, "%s: unsupported map state 0x%x on %s for %s",
+ LOG_ERR(lc, 0,
+ "%s: unsupported map state 0x%x on %s for %s",
handler, dev->vol.map.map_state, rd->di->path,
- (char*) dev->volume);
+ (char *) dev->volume);
}
return 1;
}
/* Create a RAID device to map a volumes segment. */
-static struct raid_dev *_create_rd(struct lib_context *lc, struct raid_dev *rd,
- struct isw *isw, struct isw_dev *dev)
+static struct raid_dev *
+_create_rd(struct lib_context *lc,
+ struct raid_dev *rd, struct isw *isw, struct isw_dev *dev)
{
struct raid_dev *r;
- if (!_check_map_state(lc, rd, dev) ||
- !(r = alloc_raid_dev(lc, handler)))
+ if (!(r = alloc_raid_dev(lc, handler)))
return NULL;
+ if (!(r->meta_areas = alloc_meta_areas(lc, rd, handler, 1)))
+ goto free;
+
+ /* Configuration for spare disk. */
+ if (isw->disk[0].status & SPARE_DISK) {
+ r->meta_areas->offset = rd->meta_areas->offset;
+ r->meta_areas->size = rd->meta_areas->size;
+ r->meta_areas->area =
+ alloc_private(lc, handler, rd->meta_areas->size);
+ memcpy(r->meta_areas->area, rd->meta_areas->area,
+ rd->meta_areas->size);
+
+ r->type = t_spare;
+ if (!(r->name = name(lc, rd, NULL, N_PATH)))
+ goto free;
+
+ r->di = rd->di;
+ r->fmt = rd->fmt;
+ r->sectors = ISW_CONFIGSECTOR(r->di);
+ goto out;
+ }
+
+ if (!_check_map_state(lc, rd, dev))
+ goto free;
+
if (!(r->private.ptr = alloc_private(lc, handler, sizeof(*dev))))
goto free;
memcpy(r->private.ptr, dev, sizeof(*dev));
- if ((r->type = type(r)) == t_undef) {
+
+ r->meta_areas->offset = rd->meta_areas->offset;
+ r->meta_areas->size = rd->meta_areas->size;
+ r->meta_areas->area = alloc_private(lc, handler, rd->meta_areas->size);
+ memcpy(r->meta_areas->area, rd->meta_areas->area, rd->meta_areas->size);
+
+ if ((r->type = type(dev)) == t_undef) {
log_err(lc, "%s: RAID type %u not supported",
- handler, (unsigned int) dev->vol.map.raid_level);
+ handler, (unsigned) dev->vol.map.raid_level);
goto free;
}
- if (!(r->name = name(lc, isw, dev)))
+ if (!(r->name = name(lc, rd, dev, N_VOLUME)))
goto free;
r->di = rd->di;
r->fmt = rd->fmt;
-
- r->offset = dev->vol.map.pba_of_lba0;
+ r->offset = dev->vol.map.pba_of_lba0;
if ((r->sectors = dev->vol.map.blocks_per_member))
goto out;
log_zero_sectors(lc, rd->di->path, handler);
- free:
+ free:
free_raid_dev(lc, &r);
- out:
+ out:
return r;
}
/* Find an Intel RAID set or create it. */
-static void create_rs(struct raid_set *rs, void* private)
+static void
+create_rs(struct raid_set *rs, void *private)
{
- rs->stride = ((struct isw_dev*) private)->vol.map.blocks_per_strip;
+ rs->stride = ((struct isw_dev *) private)->vol.map.blocks_per_strip;
}
/* Decide about ordering sequence of RAID device. */
-static int dev_sort(struct list_head *pos, struct list_head *new)
+static int
+dev_sort(struct list_head *pos, struct list_head *new)
{
struct isw *isw = RD(new)->private.ptr;
-
+
return _get_disk(isw, RD(new)->di) < _get_disk(isw, RD(pos)->di);
}
+static void
+super_created(struct raid_set *super, void *private)
+{
+ super->type = t_raid0;
+ super->stride = ((struct isw_dev *) private)->vol.map.blocks_per_strip;
+}
+
/*
* rs_group contains the top-level group RAID set (type: t_group) on entry
* and shall be returned on success (or NULL on error).
*/
-static struct raid_set *group_rd(struct lib_context *lc,
- struct raid_set *rs_group,
- struct raid_dev *rd_meta)
+static struct raid_set *
+group_rd(struct lib_context *lc,
+ struct raid_set *rs_group, struct raid_dev *rd_meta)
{
- unsigned int d;
+ unsigned d;
void *private;
struct isw *isw = META(rd_meta, isw);
struct isw_dev *dev;
struct raid_dev *rd;
- struct raid_set *rs;
+ struct raid_set *rs, *ss;
+ char *ss_name = NULL;
- /* Loop the device/volume table. */
- for (d = 0; d < isw->num_raid_devs; d++) {
- dev = raiddev(isw, d);
+ /* Configuration for spare disk. */
+ if (isw->disk[0].status & SPARE_DISK) {
+
+ /* Spare disk has no device description. */
+ dev = NULL;
if (!(rd = _create_rd(lc, rd_meta, isw, dev)))
return NULL;
- if (!(rs = find_or_alloc_raid_set(lc, rd->name, FIND_ALL,
- rd, &rs_group->sets,
- create_rs, dev))) {
+ if (!(rs = find_or_alloc_raid_set(lc, rd->name,
+ FIND_ALL, rd,
+ &rs_group->sets, NULL,
+ NULL))) {
free_raid_dev(lc, &rd);
return NULL;
}
- /* Save and set to enable dev_sort(). */
- private = rd->private.ptr;
- rd->private.ptr = isw;
-
+ rs->status = s_ok;
list_add_sorted(lc, &rs->devs, &rd->devs, dev_sort);
+ }
+ else {
+ /* Loop the device/volume table. */
+ for (d = 0; d < isw->num_raid_devs; d++) {
+ dev = raiddev(isw, d);
+
+ if (!(rd = _create_rd(lc, rd_meta, isw, dev)))
+ return NULL;
+ if (is_raid10(dev)) {
+ ss_name = name(lc, rd, dev, N_VOLUME_FORCE);
+ ss = find_or_alloc_raid_set(lc, ss_name,
+ FIND_ALL, rd,
+ &rs_group->sets,
+ super_created, dev);
+
+ if (!ss) {
+ dbg_free(ss_name);
+ free_raid_dev(lc, &rd);
+ return NULL;
+ }
+ }
+ else
+ ss = rs_group;
+
+ if (!(rs = find_or_alloc_raid_set(lc, rd->name,
+ FIND_ALL, rd,
+ &ss->sets, create_rs,
+ dev))) {
+ free_raid_dev(lc, &rd);
+ return NULL;
+ }
+
+ rs->status = s_ok;
+
+ /* Save and set to enable dev_sort(). */
+ private = rd->private.ptr;
+ rd->private.ptr = isw;
+ list_add_sorted(lc, &rs->devs, &rd->devs, dev_sort);
+ /* Restore. */
+ rd->private.ptr = private;
- /* Restore. */
- rd->private.ptr = private;
+ }
}
return rs_group;
}
/* Add an Intel SW RAID device to a set */
-static struct raid_set *isw_group(struct lib_context *lc,
- struct raid_dev *rd_meta)
+static struct raid_set *
+isw_group(struct lib_context *lc, struct raid_dev *rd_meta)
{
- struct raid_set *rs_group;
+ struct raid_set *rs_group = NULL;
- if (T_SPARE(rd_meta))
- return NULL;
/*
* Once we get here, an Intel SW RAID disk containing a metadata area
- * with a volume table has been discovered by isw_read.
+ * with a volume table has been discovered by isw_read. There is one
+ * goup RAID set for each metadata configuration. The volume defined in
+ * the metadata is a subset of the group RAID set.
*/
+
/* Check if a top level group RAID set already exists. */
- if (!(rs_group = find_or_alloc_raid_set(lc, rd_meta->name, FIND_TOP,
- rd_meta, LC_RS(lc),
- NO_CREATE, NO_CREATE_ARG)))
+ if (!(rs_group =
+ find_or_alloc_raid_set(lc, rd_meta->name, FIND_TOP, rd_meta,
+ LC_RS(lc), NO_CREATE, NO_CREATE_ARG)))
return NULL;
+
/*
* Add the whole underlying (meta) RAID device to the group set.
* Sorting is no problem here, because RAID sets and devices will
@@ -535,6 +757,13 @@
list_add_sorted(lc, &rs_group->devs, &rd_meta->devs, dev_sort);
rd_meta->private.ptr = NULL;
+
+ /* mark spare set as group set */
+ if (T_SPARE(rs_group))
+ rs_group->type = t_group;
+
+
+
/*
* We need to run through the volume table and create a RAID set and
* RAID devices hanging off it for every volume,
@@ -543,264 +772,1894 @@
* A pointer to the top-level group RAID set
* gets returned or NULL on error.
*/
- return group_rd(lc, rs_group, rd_meta);
+ struct raid_set *ret = group_rd(lc, rs_group, rd_meta);
+
+ return ret;
}
-/*
- * Check an Intel SW RAID set.
- *
- * FIXME: more sanity checks.
- */
-static unsigned int devices(struct raid_dev *rd, void *context)
+static unsigned
+adjust_length(struct isw_dev *dev, struct isw_dev *dev_rebuilt,
+ unsigned map_size)
{
- return ((struct isw_dev*) rd->private.ptr)->vol.map.num_members;
+ return (dev == dev_rebuilt || !dev->vol.migr_state) ?
+ map_size : 2 * map_size;
}
-static int check_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_dev *rd, void *context)
+/*
+ * Find out index of a raid device in isw_dev array by name.
+ * The function returns -1 if no relevant device can be found.
+ */
+static int
+rd_idx_by_name(struct isw *isw, const char *name)
{
- struct isw_dev *dev = rd->private.ptr;
+ int i = isw->num_raid_devs;
- /* FIXME: more status checks ? */
- if (dev->status)
- LOG_ERR(lc, 0, "%s device for volume \"%s\" broken on %s "
- "in RAID set \"%s\"",
- handler, dev->volume, rd->di->path, rs->name);
+ while (i--) {
+ if (strstr(name, (const char *) raiddev(isw, i)->volume))
+ return i;
+ }
- return 1;
+ return -ENOENT;
}
-static int _isw_check(struct lib_context *lc, struct raid_set *rs)
+/* Return RAID device for serial string. */
+static struct raid_dev *
+rd_by_serial(struct raid_set *rs, const char *serial)
{
- return check_raid_set(lc, rs, devices, NULL, check_rd, NULL, handler);
-}
+ struct raid_dev *rd;
-static int isw_check(struct lib_context *lc, struct raid_set *rs)
-{
- return T_GROUP(rs) ? _isw_check(lc, rs) : 0;
+ list_for_each_entry(rd, &rs->devs, devs) {
+ if (rd->di &&
+ !strncmp(rd->di->serial, serial, MAX_RAID_SERIAL_LEN))
+ return rd;
+ }
+
+ return NULL;
}
-/*
- * IO error event handler.
- */
-static int event_io(struct lib_context *lc, struct event_io *e_io)
+static struct isw *
+update_metadata_after_rebuild(struct lib_context *lc, struct raid_set *rs)
{
- struct raid_dev *rd = e_io->rd;
- struct isw *isw = META(rd, isw);
- struct isw_disk *disk;
-
- if (!(disk = get_disk(lc, rd->di, isw)))
- LOG_ERR(lc, 0, "%s: disk", handler);
+ struct raid_dev *rd = list_entry(rs->devs.next, struct raid_dev, devs);
+ struct isw *old_isw = META(rd, isw), *new_isw;
+ struct isw_dev *old_vol0 = NULL, *old_vol1 = NULL, *vol_rebuilt = NULL;
+ int vol_rebuilt_idx;
+ int remove_disk;
+ unsigned map_size, new_isw_size;
+ unsigned old_isw_offs, new_isw_offs;
+ unsigned i;
+
+
+ old_vol0 = raiddev(old_isw, 0);
+ if (old_isw->num_raid_devs > 1)
+ old_vol1 = raiddev(old_isw, 1);
+
+ /* Determine the volume being rebuilt. */
+ vol_rebuilt_idx =
+ rd_idx_by_name(old_isw,
+ lc->options[LC_REBUILD_SET].arg.str +
+ strlen(rs->name) + 1);
+ if (vol_rebuilt_idx < 0)
+ return NULL;
- /* Avoid write trashing. */
- if (S_BROKEN(status(lc, rd)))
- return 0;
+ /* Modify metadata related to the volume being rebuilt. */
+ vol_rebuilt = vol_rebuilt_idx ? old_vol1 : old_vol0;
+ vol_rebuilt->vol.migr_type = 0; /* FIXME: replace magic numbers */
+ vol_rebuilt->vol.migr_state = 0; /* FIXME: replace magic number */
+ vol_rebuilt->vol.map.failed_disk_num = 255; /* FIXME: replace magic number */
+
+ /* Are we going to remove the failed disk from the metadata ? */
+ remove_disk = (!old_vol0->vol.migr_type && old_vol1) ?
+ !old_vol1->vol.migr_type : 1;
+
+ /* Calculate new metadata's size and allocate memory for it. */
+ map_size = sizeof(struct isw_map) +
+ (vol_rebuilt->vol.map.num_members - 1) *
+ sizeof(((struct isw_map *) NULL)->disk_ord_tbl);
+
+ /* If we remove a disk. */
+ new_isw_size = old_isw->mpb_size - /* old size */
+ remove_disk * sizeof(struct isw_disk) - map_size;
+ new_isw = alloc_private(lc, handler, new_isw_size);
+
+ /* Copy metadata structures: struct isw without disks' array. */
+ new_isw_offs = old_isw_offs = i =
+ sizeof(struct isw) - sizeof(struct isw_disk);
+ memcpy(new_isw, old_isw, i);
+
+ /* Copy metadata structures: disks' array. */
+ i = (old_isw->num_disks - remove_disk) * sizeof(struct isw_disk);
+ memcpy((void *) new_isw + new_isw_offs,
+ (void *) old_isw + old_isw_offs, i);
+ new_isw_offs += i;
+ old_isw_offs += i + remove_disk * sizeof(struct isw_disk);
+
+ /* Copy metadata structures: isw_dev record #0. */
+ i = sizeof(struct isw_dev) - sizeof(struct isw_map) +
+ adjust_length(old_vol0, vol_rebuilt, map_size);
+
+ memcpy((void *) new_isw + new_isw_offs,
+ (void *) old_isw + old_isw_offs, i);
+ new_isw_offs += i;
+ old_isw_offs += i;
+ if (old_vol0 == vol_rebuilt)
+ old_isw_offs += map_size;
+
+ /* Copy metadata structures: isw_dev record #1 (if present). */
+ if (old_vol1) {
+ i = sizeof(struct isw_dev) - sizeof(struct isw_map) +
+ adjust_length(old_vol1, vol_rebuilt, map_size);
+ memcpy((void *) new_isw + new_isw_offs,
+ (void *) old_isw + old_isw_offs, i);
+ new_isw_offs += i;
+ old_isw_offs += i;
- disk->status &= ~USABLE_DISK;
- disk->status |= FAILED_DISK;
+ if (old_vol1 == vol_rebuilt)
+ old_isw_offs += map_size;
+ }
- return 1;
+ /* finally update new metadata's fields */
+ new_isw->mpb_size = new_isw_size;
+ new_isw->num_disks -= remove_disk;
+ new_isw->generation_num++;
+ new_isw->check_sum = _checksum(new_isw);
+ return new_isw;
}
-static struct event_handlers isw_event_handlers = {
- .io = event_io,
- .rd = NULL, /* FIXME: no device add/remove event handler yet. */
-};
-#ifdef DMRAID_NATIVE_LOG
-/*
- * Log native information about an ISW RAID device.
- */
-static void isw_log(struct lib_context *lc, struct raid_dev *rd)
+/* Handle rebuild state. */
+static int
+get_rebuild_state(struct lib_context *lc,
+ struct raid_set *rs, struct raid_dev *rd)
{
- unsigned int d, i;
- struct isw *isw = META(rd, isw);
- struct isw_disk *disk;
+ int idx;
+ struct raid_dev *check_rd;
+ struct isw *isw;
struct isw_dev *dev;
+ struct isw_disk *disk;
- log_print(lc, "%s (%s):", rd->di->path, handler);
- P("sig: \"%*s\"", isw, isw->sig, MAX_SIGNATURE_LENGTH, isw->sig);
- DP("check_sum: %u", isw, isw->check_sum);
- DP("mpb_size: %u", isw, isw->mpb_size);
- DP("family_num: %u", isw, isw->family_num);
- DP("generation_num: %u", isw, isw->generation_num);
- DP("reserved[0]: %u", isw, isw->reserved[0]);
- DP("reserved[1]: %u", isw, isw->reserved[1]);
- DP("num_disks: %u", isw, isw->num_disks);
- DP("num_raid_devs: %u", isw, isw->num_raid_devs);
- DP("fill[0]: %u", isw, isw->fill[0]);
- DP("fill[1]: %u", isw, isw->fill[1]);
+ list_for_each_entry(check_rd, &rs->devs, devs) {
+ if (check_rd->meta_areas) {
+ isw = META(check_rd, isw);
+
+ idx = rd_idx_by_name(isw,
+ lc->options[LC_REBUILD_SET].
+ arg.str);
+ if (idx < 0)
+ return 0;
+
+ dev = raiddev(isw, idx);
+ disk = isw->disk;
+
+ if (dev->vol.migr_state &&
+ dev->vol.migr_type &&
+ dev->vol.map.failed_disk_num < isw->num_disks) {
+ /*
+ * If rd that belongs to RAID set is
+ * pointed at by failed disk number
+ * the RAID set state is migration.
+ */
+ rd = rd_by_serial(rs,
+ (const char *) disk[dev->
+ vol.map.failed_disk_num].serial);
+ if (rd)
+ /*
+ * Found RAID device that belongs to
+ * RAID set is marked as failed in
+ * metadata.
+ */
+ return s_nosync;
+ }
+ else if (dev->vol.map.map_state == ISW_T_STATE_DEGRADED)
+ return s_inconsistent;
+ }
+
+ /*
+ * Check only first metadata on the
+ * first rd that has a metadata.
+ */
+ return s_inconsistent;
- for (i = 0; i < ISW_FILLERS; i++) {
- if (isw->filler[i])
- P("filler[%i]: %u", isw,
- isw->filler[i], i, isw->filler[i]);
}
- /* Disk table. */
- for (d = 0, disk = isw->disk; d < isw->num_disks; d++, disk++) {
- if (!disk->totalBlocks)
- continue;
+ return s_inconsistent;
+}
- P("disk[%u].serial: \"%*s\"", isw,
- disk->serial, d, MAX_RAID_SERIAL_LEN, disk->serial);
- P("disk[%u].totalBlocks: %u", isw,
- disk->totalBlocks, d, disk->totalBlocks);
- P("disk[%u].scsiId: 0x%x", isw, disk->scsiId, d, disk->scsiId);
- P("disk[%u].status: 0x%x", isw, disk->status, d, disk->status);
- for (i = 0; i < ISW_DISK_FILLERS; i++) {
- if (disk->filler[i])
- P("disk[%u].filler[%u]: %u", isw,
- disk->filler[i], d, i, disk->filler[i]);
+/* isw metadata handler routine. */
+static int
+isw_metadata_handler(struct lib_context *lc, enum handler_commands command,
+ struct handler_info *info, void *context)
+{
+ int idx, ret = 0;
+ struct raid_set *rs = context;
+ struct raid_dev *rd = list_entry(rs->devs.next, struct raid_dev, devs);
+ struct isw *isw, *new_isw;
+ struct isw_dev *dev;
+ struct isw_disk *disk;
+
+ switch (command) {
+ case UPDATE_REBUILD_STATE:
+ new_isw = update_metadata_after_rebuild(lc, rs);
+ if (!new_isw)
+ return 0;
+
+ /* Embed the new metadata on disks. */
+ list_for_each_entry(rd, &rs->devs, devs) {
+ set_metadata_sizoff(rd, isw_size(new_isw));
+ memcpy(rd->meta_areas->area, new_isw,
+ new_isw->mpb_size);
+
+ /* FIXME: use fmt->write from metadata.c instead ? */
+ /* FIXME: log update. */
+ ret = isw_write(lc, rd, 0);
+ if (!ret)
+ break;
}
- }
- /* RAID device/volume table. */
- for (d = 0; d < isw->num_raid_devs; d++) {
- dev = raiddev(isw, d);
+ break;
- /* RAID device */
- P("isw_dev[%u].volume: \"%*s\"", isw,
- dev->volume, d, MAX_RAID_SERIAL_LEN, dev->volume);
- P("isw_dev[%u].SizeHigh: %u", isw,
- dev->SizeHigh, d, dev->SizeHigh);
- P("isw_dev[%u].SizeLow: %u", isw,
- dev->SizeLow, d, dev->SizeLow);
- P("isw_dev[%u].status: 0x%x", isw, dev->status, d, dev->status);
- P("isw_dev[%u].reserved_blocks: %u", isw,
- dev->reserved_blocks, d, dev->reserved_blocks);
+ case GET_REBUILD_STATE:
+ return get_rebuild_state(lc, rs, rd);
- for (i = 0; i < ISW_DEV_FILLERS; i++) {
- if (dev->filler[i])
- P("isw_dev[%u].filler[%u]: %u", isw,
- dev->filler[i], d, i, dev->filler[i]);
+ case GET_REBUILD_DRIVE:
+ isw = META(rd, isw);
+ dev = raiddev(isw, 0);
+ disk = isw->disk + dev->vol.map.failed_disk_num;
+
+ rd = rd_by_serial(rs, (const char *) disk->serial);
+ if (rd) {
+ if (info && info->data.str && info->size) {
+ strncpy(info->data.str, rd->di->path,
+ info->size);
+ log_print(lc,
+ "Rebuild Drive: %s Serial No: %s\n",
+ rd->di->path, rd->di->serial);
+ ret = 1;
+ }
+ else
+ log_err(lc,
+ "Can't provide rebuild drive path!");
}
- /* RAID volume */
- for (i = 0; i < 2; i++) {
- if (dev->vol.reserved[i])
- P("isw_dev[%u].vol.reserved[%u]: %u", isw,
- dev->vol.reserved[i], d, i,
- dev->vol.reserved[i]);
+ break;
+
+ case GET_REBUILD_DRIVE_NO:
+ rd = list_entry(rs->devs.next, typeof(*rd), devs);
+ isw = META(rd, isw);
+ idx = rd_idx_by_name(isw, lc->options[LC_REBUILD_SET].arg.str);
+ if (idx < 0)
+ return 0;
+
+ dev = raiddev(isw, idx);
+ disk = isw->disk;
+
+ if (info) {
+ if (dev->vol.map.failed_disk_num <
+ dev->vol.map.num_members) {
+ info->data.i32 = is_raid10(dev) ?
+ dev->vol.map.failed_disk_num /
+ dev->vol.map.num_domains :
+ dev->vol.map.failed_disk_num;
+
+ ret = 1;
+ }
+ else
+ info->data.i32 = -1;
}
- P("isw_dev[%u].vol.migr_state: %u", isw,
- dev->vol.migr_state, d, dev->vol.migr_state);
- P("isw_dev[%u].vol.migr_type: %u", isw,
- dev->vol.migr_type, d, dev->vol.migr_type);
- P("isw_dev[%u].vol.dirty: %u", isw,
- dev->vol.dirty, d, dev->vol.dirty);
- P("isw_dev[%u].vol.fill[0]: %u", isw,
- dev->vol.fill[0], d, dev->vol.fill[0]);
+ break; /* case GET_REBUILD_DRIVE_NO */
- for (i = 0; i < 5; i++) {
- if (dev->vol.filler[i])
- P("isw_dev[%u].vol.filler[%u]: %u", isw,
- dev->vol.filler[i], d, i,
- dev->vol.filler[i]);
- }
-
- /* RAID map */
- P("isw_dev[%u].vol.map.pba_of_lba0: %u", isw,
- dev->vol.map.pba_of_lba0, d,
- dev->vol.map.pba_of_lba0);
- P("isw_dev[%u].vol.map.blocks_per_member: %u", isw,
- dev->vol.map.blocks_per_member, d,
- dev->vol.map.blocks_per_member);
- P("isw_dev[%u].vol.map.num_data_stripes: %u", isw,
- dev->vol.map.num_data_stripes, d,
- dev->vol.map.num_data_stripes);
- P("isw_dev[%u].vol.map.blocks_per_strip: %u", isw,
- dev->vol.map.blocks_per_strip, d,
- dev->vol.map.blocks_per_strip);
- P("isw_dev[%u].vol.map.map_state: %u", isw,
- dev->vol.map.map_state, d,
- dev->vol.map.map_state);
- P("isw_dev[%u].vol.map.raid_level: %u", isw,
- dev->vol.map.raid_level, d,
- dev->vol.map.raid_level);
- P("isw_dev[%u].vol.map.num_members: %u", isw,
- dev->vol.map.num_members, d,
- dev->vol.map.num_members);
-
- for (i = 0; i < 3; i++) {
- if (dev->vol.map.reserved[i])
- P("isw_dev[%u].vol.map.reserved[%u]: %u", isw,
- dev->vol.map.reserved[i], d, i,
- dev->vol.map.reserved[i]);
- }
-
- for (i = 0; i < 7; i++) {
- if (dev->vol.map.filler[i])
- P("isw_dev[%u].vol.map.filler[%u]: %u", isw,
- dev->vol.map.filler[i], d, i,
- dev->vol.map.filler[i]);
- }
-
- for (i = 0; i < isw->num_disks; i++) {
- P("isw_dev[%u].vol.map.disk_ord_tbl[%u]: 0x%x", isw,
- dev->vol.map.disk_ord_tbl[i], d, i,
- dev->vol.map.disk_ord_tbl[i]);
- }
- }
-}
-#endif
+ default:
+ LOG_ERR(lc, 0, "%u not yet supported", command);
-static struct dmraid_format isw_format = {
- .name = HANDLER,
- .descr = "Intel Software RAID",
- .caps = "0,1,5",
- .format = FMT_RAID,
- .read = isw_read,
- .write = isw_write,
- .group = isw_group,
- .check = isw_check,
- .events = &isw_event_handlers,
-#ifdef DMRAID_NATIVE_LOG
- .log = isw_log,
-#endif
-};
+ }
-/* Register this format handler with the format core. */
-int register_isw(struct lib_context *lc)
-{
- return register_format_handler(lc, &isw_format);
+ return ret;
}
/*
- * Set the RAID device contents up derived from the Intel ones.
+ * Check an Intel SW RAID set.
*
- * This is the first one we get with here and we potentially need to
- * create many in isw_group() in case of multiple Intel SW RAID devices
- * on this RAID disk.
+ * FIXME: more sanity checks.
*/
-static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta, union read_info *info)
+static unsigned
+devices(struct raid_dev *rd, void *context)
{
- struct isw *isw = meta;
+ return rd->type != t_spare ?
+ ((struct isw_dev *) rd->private.ptr)->vol.map.num_members : 0;
+}
- /* Superblock checksum */
- if (isw->check_sum != _checksum(isw))
- LOG_ERR(lc, 0, "%s: extended superblock for %s "
- "has wrong checksum",
- handler, di->path);
+static unsigned
+devices_per_domain(struct raid_dev *rd, void *context)
+{
+ return ((struct isw_dev *) rd->private.ptr)->vol.map.num_members /
+ ((struct isw_dev *) rd->private.ptr)->vol.map.num_domains;
+}
- if (!(rd->meta_areas = alloc_meta_areas(lc, rd, handler, 1)))
- return 0;
+static int
+check_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_dev *rd, void *context)
+{
+ struct isw_dev *dev = rd->private.ptr;
- rd->meta_areas->offset = info->u64 >> 9;
- rd->meta_areas->size = round_up(isw->mpb_size, ISW_DISK_BLOCK_SIZE);
- rd->meta_areas->area = (void*) isw;
+ /* FIXME: more status checks ? */
+ if (dev->status) {
+ LOG_ERR(lc, 0, "%s device for volume \"%s\" broken on %s "
+ "in RAID set \"%s\"",
+ handler, dev->volume, rd->di->path, rs->name);
- rd->di = di;
- rd->fmt = &isw_format;
+ }
- rd->offset = ISW_DATAOFFSET;
- if (!(rd->sectors = info->u64 >> 9))
- return log_zero_sectors(lc, di->path, handler);
+ return 1;
+}
- rd->status = status(lc, rd);
- rd->type = t_group;
+static int
+_isw_check(struct lib_context *lc, struct raid_set *rs)
+{
+ struct raid_set *r;
+
+ list_for_each_entry(r, &rs->sets, list) {
+ if (SETS(r))
+ check_raid_set(lc, r, devices_per_domain, NULL,
+ check_rd, NULL, handler);
+ else
+ check_raid_set(lc, r, devices, NULL, check_rd,
+ NULL, handler);
+ }
+
+ return 1;
+}
+
+static char *
+get_rs_basename(char *str)
+{
+ char *ret, *end;
+
+ if (!(end = strchr(str, '_')))
+ return str;
+
+ if (!(end = strchr((++end), '_')))
+ return str;
+
+ if ((ret = strstr(str, "isw_")) == str && strlen(end) > 1)
+ return ++end;
+
+ return str;
+}
+
+/* Check that volume name is unique. */
+static int
+is_name_unique(struct lib_context *lc, struct raid_set *rs)
+{
+ struct raid_set *rs1, *rs2;
+ char *bn;
+
+ list_for_each_entry(rs1, LC_RS(lc), list) {
+ if (rs1->type == t_group) {
+ list_for_each_entry(rs2, &rs1->sets, list) {
+ bn = get_rs_basename(rs2->name);
+ if (!strcmp(bn, rs->name))
+ goto out_used;
+ }
+ }
+ else {
+ bn = get_rs_basename(rs1->name);
+ if (!strcmp(bn, rs->name))
+ goto out_used;
+ }
+ }
+
+ return 1;
+
+ out_used:
+ log_dbg(lc, "%s is being used", bn);
+ return 0;
+}
+
+static int
+check_capability(struct raid_set *rs)
+{
+ uint8_t raid_level = _get_raid_level(rs->type);
+
+ if (SETS(rs)) {
+ struct raid_set *rs1 =
+ list_entry(rs->sets.next, struct raid_set, list);
+
+ if (raid_level == ISW_T_RAID0 && rs1->type == t_raid1)
+ raid_level = ISW_T_RAID10;
+ else
+ raid_level = ISW_T_UNDEF;
+ }
+
+ return raid_level;
+}
+
+static int
+match_hd_array(struct raid_set *rs, struct isw *isw)
+{
+ int broken = 0, found = 0; // , i = isw->num_disks;
+// struct isw_disk *disk = isw->disk;
+ struct raid_dev *rd;
+
+/* FIXME: all disks broken in case of no SCSI IDs
+ while (i--) {
+ if (disk[i].scsiId == UNKNOWN_SCSI_ID)
+ broken++;
+ }
+*/
+
+ list_for_each_entry(rd, &rs->devs, devs) {
+ if (_get_disk(isw, rd->di))
+ found++;
+ }
+
+ return isw->num_disks == broken + found && found == rs->total_devs;
+}
+
+static int
+is_hd_array_available(struct lib_context *lc, struct raid_set *rs)
+{
+ struct raid_dev *rd1, *rd2;
+
+ list_for_each_entry(rd1, &rs->devs, devs) {
+ list_for_each_entry(rd2, LC_RD(lc), list) {
+ if (!strcmp(rd1->di->path, rd2->di->path) &&
+ rd1->fmt == rd2->fmt)
+ return match_hd_array(rs, META(rd2, isw));
+ }
+ }
+
+ return 0;
+}
+
+#define MIN_VOLUME_SIZE 204800
+static void
+enforce_size_limit(struct raid_set *rs)
+{
+ /* the min size is 100M bytes */
+ if (rs->size && rs->size < MIN_VOLUME_SIZE)
+ rs->size = MIN_VOLUME_SIZE;
+}
+
+static int
+is_first_volume(struct lib_context *lc, struct raid_set *rs)
+{
+ struct raid_dev *rd1, *rd2;
+
+ list_for_each_entry(rd1, &rs->devs, devs) {
+ list_for_each_entry(rd2, LC_RD(lc), list) {
+ if (!strcmp(rd1->di->path, rd2->di->path) &&
+ rd1->fmt == rd2->fmt) {
+ /* No choice for the 2nd volume. */
+ rs->size = 0;
+ return 0;
+ }
+ }
+ }
+
+ enforce_size_limit(rs);
+ return 1;
+}
+
+/* Retrieve and make up SCSI ID. */
+static unsigned
+get_scsiId(struct lib_context *lc, char *path)
+{
+ int fd;
+ Sg_scsi_id sg_id;
+
+ memset(&sg_id, 0, sizeof(sg_id));
+
+ if ((fd = open(path, O_RDONLY)) == -1)
+ return UNKNOWN_SCSI_ID;
+
+ if (!get_scsi_id(lc, fd, &sg_id)) {
+ close(fd);
+ return UNKNOWN_SCSI_ID;
+ }
+
+ close(fd);
+ return (sg_id.host_no << 16) | (sg_id.scsi_id << 8) | sg_id.lun;
+}
+
+static int
+isw_config_disks(struct lib_context *lc, struct isw_disk *disk,
+ struct raid_set *rs)
+{
+ int i = 0;
+ struct raid_dev *rd;
+
+ list_for_each_entry(rd, &rs->devs, devs) {
+ strncpy((char *) disk[i].serial, rd->di->serial,
+ MAX_RAID_SERIAL_LEN);
+ disk[i].totalBlocks = rd->di->sectors;
+
+ /* FIXME: when scsiID == UNKNOWN_SCSI_ID */
+ disk[i].scsiId = get_scsiId(lc, rd->di->path);
+ disk[i++].status = CLAIMED_DISK |
+ CONFIG_ON_DISK |
+ DETECTED_DISK | USABLE_DISK |
+ ((rs->type == ISW_T_SPARE) ?
+ SPARE_DISK : CONFIGURED_DISK);
+ }
+
+ return i;
+}
+
+static void
+isw_config_vol(struct raid_set *rs, struct isw_vol *vol)
+{
+ if (rs->status == s_init) {
+ vol->migr_state = 0;
+ vol->migr_type = 0;
+ }
+}
+
+static uint32_t
+_get_stride_size(struct raid_set *rs)
+{
+ /* In blocks (512-bytes). */
+ /* First member is default stride size. */
+ static const uint32_t s_raid0[] = { 256, 8, 16, 32, 64, 128, 256, 0 };
+ static const uint32_t s_raid1[] = { 128, 128, 0 };
+ static const uint32_t s_raid10[] = { 128, 8, 16, 32, 64, 128, 256, 0 };
+ static const uint32_t s_raid5[] = { 128, 32, 64, 128, 256, 0 };
+ struct strip_options {
+ const uint8_t level;
+ const uint32_t *options;
+ };
+ static struct strip_options strip_options[] = {
+ {ISW_T_RAID0, s_raid0},
+ {ISW_T_RAID1, s_raid1},
+ {ISW_T_RAID10, s_raid10},
+ {ISW_T_RAID5, s_raid5},
+ };
+ struct strip_options *so = ARRAY_END(strip_options);
+
+ while (so-- > strip_options) {
+ if (rs->type == so->level) {
+ int i;
+
+ if (rs->stride) {
+ i = 1;
+ while (so->options[i + 1] &&
+ rs->stride > so->options[i])
+ i++;
+ }
+ else
+ i = 0;
+
+ return so->options[i];
+ }
+ }
+
+ return 0;
+}
+
+static void
+_find_factors(struct raid_set *rs, uint8_t * div, uint8_t * sub)
+{
+ struct factors {
+ const uint8_t level;
+ const uint8_t div, sub;
+ };
+ static struct factors factors[] = {
+ {ISW_T_RAID0, 1, 0},
+ {ISW_T_RAID1, 2, 0},
+ {ISW_T_RAID10, 2, 0},
+ {ISW_T_RAID5, 1, 1},
+ };
+ struct factors *f = ARRAY_END(factors);
+
+ while (f-- > factors) {
+ if (rs->type == f->level) {
+ *div = f->div;
+ *sub = f->sub;
+ return;
+ }
+ }
+
+ *div = 1;
+ *sub = 0;
+}
+
+/* Configure an isw map. */
+static void
+isw_config_map(struct raid_set *rs, struct isw_map *map,
+ uint64_t size, uint32_t first)
+{
+ int i;
+ uint8_t div, sub;
+
+ _find_factors(rs, &div, &sub);
+ map->pba_of_lba0 = first;
+ map->blocks_per_strip = _get_stride_size(rs);
+ map->num_data_stripes = size / (map->blocks_per_strip) /
+ ((rs->total_devs - sub) / div);
+ map->blocks_per_member = map->blocks_per_strip * map->num_data_stripes +
+ RAID_DS_JOURNAL;
+
+ map->map_state = ISW_T_STATE_NORMAL;
+ map->raid_level = rs->type == ISW_T_RAID10 ? ISW_T_RAID1 : rs->type;
+ map->num_members = rs->found_devs;
+ map->num_domains = (rs->type == ISW_T_RAID1 ||
+ rs->type == ISW_T_RAID10) ? 2 : 1;
+
+/* FIXME */
+ for (i = 0; i < map->num_members; i++)
+ map->disk_ord_tbl[i] = i;
+}
+
+/* Calculate the (new) array size. */
+static uint64_t
+_cal_array_size(struct isw_disk *disk, struct raid_set *rs, struct isw_dev *dev)
+{
+ int n = 0;
+ uint8_t div, sub;
+ uint64_t min_ds = ~0, max_ds;
+ struct raid_dev *rd;
+
+ list_for_each_entry(rd, &rs->devs, devs) {
+ if (min_ds > rd->di->sectors)
+ min_ds = rd->di->sectors;
+ n++;
+ }
+
+ if (min_ds < DISK_RESERVED_BLOCKS)
+ return 0;
+
+ min_ds -= DISK_RESERVED_BLOCKS;
+
+ /* blank disks */
+ if (dev) {
+ /* One volume existed and started from the beginning */
+ if (!dev->vol.map.pba_of_lba0) {
+ max_ds = dev->vol.map.blocks_per_member +
+ DISK_RESERVED_BLOCKS;
+
+ if (min_ds > max_ds)
+ min_ds -= max_ds;
+ else
+ return 1;
+ /* An existing volume at the bottom */
+ }
+ else if (dev->vol.map.pba_of_lba0 >=
+ RAID_VOLUME_RESERVED_BLOCKS)
+ min_ds = dev->vol.map.pba_of_lba0 -
+ RAID_VOLUME_RESERVED_BLOCKS;
+ else
+ return 1;
+ }
+ else {
+ if (min_ds > DISK_RESERVED_BLOCKS)
+ min_ds -= DISK_RESERVED_BLOCKS;
+ else
+ return 1;
+ }
+
+ _find_factors(rs, &div, &sub);
+ max_ds = min_ds * (n - sub) / div;
+ return max_ds;
+}
+
+#define METADATA_BLOCKS 2
+static int
+isw_config_dev(struct lib_context *lc, struct raid_set *rs,
+ struct isw_dev *dev1, struct isw_dev *dev2, uint64_t max_size)
+{
+ uint64_t tmp = rs->size ? rs->size : max_size;
+
+ strncpy((char *) dev2->volume, rs->name, MAX_RAID_SERIAL_LEN);
+ dev2->SizeLow = (uint32_t) tmp;
+ dev2->SizeHigh = (uint32_t) (tmp >> 32);
+ /* FIXME: isi this status ok, Radoslaw ? */
+ dev2->status = ISW_DEV_READ_COALESCING | ISW_DEV_WRITE_COALESCING;
+ isw_config_vol(rs, &dev2->vol);
+
+ if (!dev1) {
+ isw_config_map(rs, &dev2->vol.map, tmp, 0);
+ return 1;
+ }
+
+ if (!dev1->vol.map.pba_of_lba0) /* Start at the begginning. */
+ isw_config_map(rs, &dev2->vol.map, tmp,
+ dev1->vol.map.blocks_per_member +
+ MIGR_OPT_SPACE);
+ else {
+ isw_config_map(rs, &dev2->vol.map, tmp, 0);
+
+ if (dev2->vol.map.blocks_per_member + MIGR_OPT_SPACE >
+ dev1->vol.map.pba_of_lba0)
+ LOG_ERR(lc, 0, "%s: not enough space to create "
+ "requested volume", handler);
+
+ }
+
+ return 1;
+}
+
+static void
+display_new_volume(struct raid_set *rs, struct isw *isw, struct isw_dev *dev)
+{
+ enum type rt;
+ const char *type_name = NULL;
+ struct raid_dev *r;
+
+ if (rs->type == ISW_T_SPARE) { /* Case if spare disk. */
+ printf("\n\n Create a SPARE DISK with ISW metadata "
+ "format \n\nDISK: ");
+ }
+ else {
+ rt = type(dev);
+ switch (rt) {
+ case t_raid0:
+ type_name = "RAID0";
+ break;
+
+ case t_raid1:
+ type_name = dev->vol.map.num_members ==
+ min_num_disks(ISW_T_RAID10) ?
+ "RAID01 (isw RAID10)" : "RAID1";
+ break;
+
+ case t_raid5_la:
+ type_name = "RAID5";
+ break;
+
+ default:
+ return;
+ }
+
+ printf("\n\n Create a RAID set with ISW "
+ "metadata format \n\n");
+ printf("RAID name: %s\n", dev->volume);
+ printf("RAID type: %s\n", type_name);
+ printf("RAID size: %lluG",
+ ((unsigned long long) dev->SizeLow +
+ ((unsigned long long) dev->SizeHigh << 32)) / GB_DIV);
+ printf("(%llublocks)\n",
+ ((unsigned long long) dev->SizeLow +
+ ((unsigned long long) dev->SizeHigh << 32)));
+
+ if (rt != t_raid1)
+ printf("RAID strip: %uk(%ublocks)\n",
+ dev->vol.map.blocks_per_strip / 2,
+ dev->vol.map.blocks_per_strip);
+
+ printf("DISKS: ");
+ }
+
+ list_for_each_entry(r, &rs->devs, devs) {
+ if (_get_disk(isw, r->di))
+ printf("%s%s ", r->di->path,
+ rs->type == ISW_T_SPARE ? "" : ",");
+ }
+
+ printf("\n\n\n");
+}
+
+static struct isw *
+_isw_create_first_volume(struct lib_context *lc, struct raid_set *rs)
+{
+
+ uint16_t isw_size;
+ uint64_t total_size;
+ struct isw *isw;
+ struct isw_dev *dev = NULL;
+ struct isw_disk *disk = NULL;
+
+ total_size = _cal_array_size(disk, rs, NULL);
+ if (rs->size > total_size)
+ LOG_ERR(lc, 0,
+ "%s: the size exceeds the max %lluG(%llublocks)",
+ handler, total_size / GB_DIV, total_size);
+
+ /* allocate min 2 sectors space for isw metadata. */
+ isw_size = METADATA_BLOCKS * ISW_DISK_BLOCK_SIZE;
+ if (!(isw = alloc_private(lc, handler, isw_size)))
+ LOG_ERR(lc, 0, "%s: failed to allocate memory", handler);
+
+ disk = isw->disk;
+ isw->num_disks = isw_config_disks(lc, disk, rs);
+ isw_size = sizeof(*isw) + sizeof(*disk) * (isw->num_disks - 1);
+
+ if (rs->type != ISW_T_SPARE) {
+ dev = (struct isw_dev *) (disk + isw->num_disks);
+ if (!isw_config_dev(lc, rs, NULL, dev, total_size)) {
+ dbg_free(isw);
+ return NULL;
+ }
+
+ isw_size += sizeof(*dev) + sizeof(dev->vol.map.disk_ord_tbl) *
+ (isw->num_disks - 1);
+ }
+
+ display_new_volume(rs, isw, dev);
+
+ strncpy((char *) isw->sig, MPB_SIGNATURE, MPB_SIGNATURE_SIZE);
+ strncpy((char *) isw->sig + MPB_SIGNATURE_SIZE,
+ MPB_VERSION_RAID2, MPB_VERSION_RAID2_SIZE);
+ isw->mpb_size = isw_size;
+ isw->generation_num = 0;
+ isw->num_raid_devs = (rs->type == ISW_T_SPARE) ? 0 : 1;
+ isw->family_num = isw->orig_family_num = _checksum(isw) + time(NULL);
+ isw->check_sum = 0;
+ isw->check_sum = _checksum(isw);
+ return isw;
+}
+
+static struct raid_set *
+_find_group(struct lib_context *lc, struct raid_set *rs)
+{
+ struct raid_set *r;
+ struct raid_dev *rd1, *rd2;
+ int match = 0;
+
+ list_for_each_entry(r, LC_RS(lc), list) {
+ if (r->type != t_group)
+ continue;
+
+ list_for_each_entry(rd2, &rs->devs, devs) {
+ list_for_each_entry(rd1, &r->devs, devs) {
+ if (!strcmp(rd1->di->path, rd2->di->path)) {
+ match++;
+ break;
+ }
+ }
+ }
+
+ if (match) {
+ if (match == rs->found_devs)
+ return r;
+
+ LOG_ERR(lc, NULL,
+ "%s: mismatch in the number of drives "
+ "found", handler);
+ }
+ }
+
+ return NULL;
+}
+
+static struct isw *
+_isw_create_second_volume(struct lib_context *lc, struct raid_set *rs)
+{
+ uint16_t isw_size;
+ uint64_t total_size;
+ struct raid_set *rs_group;
+ struct raid_dev *rd;
+ struct isw *isw, *isw_v1;
+ struct isw_dev *dev1, *dev2;
+
+ if (!(rs_group = _find_group(lc, rs)))
+ return NULL;
+
+ rd = list_entry(rs_group->devs.next, struct raid_dev, devs);
+ /* Note: size of a volume data structure is smaller than a sector. */
+
+ /* FIXME: >=2 ? */
+ isw_v1 = rd->meta_areas->area;
+ if (isw_v1->num_raid_devs >= 2)
+ LOG_ERR(lc, NULL, "%s: only two volumes allowed per array",
+ handler);
+
+ if (!(dev1 = raiddev(isw_v1, 0)))
+ LOG_ERR(lc, NULL, "%s: failed to get the first volume info",
+ handler);
+
+ total_size = _cal_array_size(isw_v1->disk, rs, dev1);
+ if (total_size < MIN_VOLUME_SIZE)
+ LOG_ERR(lc, NULL, "%s: either not enough disk space or the "
+ "requested volume size is too small", handler);
+
+ isw_size = rd->meta_areas->size + ISW_DISK_BLOCK_SIZE;
+ if (!(isw = alloc_private(lc, handler, isw_size)))
+ LOG_ERR(lc, NULL, "%s: failed to allocate memory", handler);
+
+ memcpy(isw, isw_v1, isw_size - ISW_DISK_BLOCK_SIZE);
+ isw_size = isw_v1->mpb_size;
+ dev2 = raiddev(isw, 1);
+ if (!isw_config_dev(lc, rs, dev1, dev2, total_size)) {
+ dbg_free(isw);
+ return NULL;
+ }
+
+ isw_size += sizeof(*dev2) + sizeof(dev2->vol.map.disk_ord_tbl) *
+ (isw->num_disks - 1);
+
+ display_new_volume(rs, isw, dev2);
+ isw->mpb_size = isw_size;
+ isw->generation_num++;
+ isw->num_raid_devs++;
+ isw->check_sum = 0;
+ isw->check_sum = _checksum(isw);
+ return isw;
+}
+
+static struct isw_dev *
+get_raiddev(struct isw *isw, char *name)
+{
+ struct isw_dev *dev;
+ int i;
+
+ for (i = 0; i < isw->num_raid_devs; i++) {
+ dev = raiddev(isw, i);
+ if (!strcmp((const char *) dev->volume, (const char *) name))
+ return dev;
+ }
+
+ return NULL;
+}
+
+/*
+ * Update the metadata attached to each raid
+ * device and the name of the RAID set.
+ */
+static int
+update_raidset(struct lib_context *lc, struct raid_set *rs, struct isw *isw)
+{
+ int blocks = div_up(isw->mpb_size, ISW_DISK_BLOCK_SIZE);
+ size_t size = blocks * ISW_DISK_BLOCK_SIZE;
+ struct raid_dev *rd;
+ struct isw_dev *dev;
+
+ list_for_each_entry(rd, &rs->devs, devs) {
+ if (rd->meta_areas) {
+ if (rd->meta_areas->area)
+ dbg_free(rd->meta_areas->area);
+
+ dbg_free(rd->meta_areas);
+ }
+
+ if (!(rd->meta_areas = alloc_meta_areas(lc, rd, handler, 1)))
+ return 0;
+
+ if (!(rd->meta_areas->area = alloc_private(lc, handler, size)))
+ return 0;
+
+ set_metadata_sizoff(rd, size);
+ memcpy(rd->meta_areas->area, isw, size);
+ rd->type = t_group;
+
+ dev = NULL;
+ if (rs->type != ISW_T_SPARE &&
+ !(dev = get_raiddev(isw, rs->name)))
+ return 0;
+
+ if (!(rd->name = name(lc, rd, dev, N_NUMBER)))
+ return 0;
+ }
+
+ if (rs->type != ISW_T_SPARE) {
+ if (!(dev = get_raiddev(isw, rs->name)))
+ return 0;
+
+ dbg_free(rs->name);
+ rd = list_entry(rs->devs.next, struct raid_dev, devs);
+ if (!(rs->name = name(lc, rd, dev, N_VOLUME)))
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Create a RAID set (i.e. an isw volume). */
+static int
+_isw_create_raidset(struct lib_context *lc, struct raid_set *rs)
+{
+ uint16_t min, max = 0;
+ struct isw *isw;
+
+ /* The type is changed into the ISW defination */
+ if ((rs->type = check_capability(rs)) == ISW_T_UNDEF)
+ LOG_ERR(lc, 0, "%s: unsupported raid level", handler);
+
+ if (rs->type != ISW_T_SPARE && rs->name) {
+ if (!is_name_unique(lc, rs))
+ LOG_ERR(lc, 0, "%s: the name %s is already in use, "
+ "please try another name", handler, rs->name);
+ }
+
+ if ((min = min_num_disks(rs->type)) > rs->found_devs ||
+ (max = max_num_disks(rs->type)) < rs->found_devs)
+ LOG_ERR(lc, 0, "%s: the RAID set cannot have %s "
+ "than %d hard drives",
+ handler, max ? "more" : "less", max ? max : min);
+
+ /*
+ * The size of the RAID set is set to 0 if there is one volume
+ * detected. Also, the mininum size is enforced to 0.1G.
+ */
+ if (is_first_volume(lc, rs))
+ isw = _isw_create_first_volume(lc, rs);
+ else if (rs->type == ISW_T_SPARE)
+ LOG_ERR(lc, 0, "%s: SPARE disk must use all space "
+ "on the disk", handler);
+ else if (is_hd_array_available(lc, rs))
+ isw = _isw_create_second_volume(lc, rs);
+ else
+ LOG_ERR(lc, 0,
+ "%s: second volume must use all drives on the "
+ "existing array", handler);
+
+ /* isw spare disk is created without own name. */
+ if (isw) {
+ static const char *fmts[] = {
+ "About to create a RAID set with the above settings. "
+ "Name <%s> will lost. Continue",
+ "About to create a RAID set with the above settings. "
+ "Continue",
+ };
+ const char *fmt = fmts[!(rs->type == ISW_T_SPARE && rs->name)];
+
+ if (yes_no_prompt(lc, fmt, rs->name)) {
+ if (!update_raidset(lc, rs, isw)) {
+ dbg_free(isw);
+ LOG_ERR(lc, 0, "%s: failed to update metadata "
+ "on the raid_dev data structure ",
+ handler);
+ }
+ }
+ else {
+ dbg_free(isw);
+ return 0;
+ }
+
+ dbg_free(isw);
+ rs->status = s_config;
+ return 1;
+ }
+
+ return 0;
+}
+
+static int update_metadata(struct lib_context *lc, struct raid_set *rs);
+static int
+isw_create(struct lib_context *lc, struct raid_set *rs)
+{
+
+ int ret = 0;
+
+ if (rs->status == s_init) {
+ enum type raid_type;
+
+ /*
+ * The field size and type get changed
+ * later to faciliate processing.
+ */
+ raid_type = rs->type;
+ ret = _isw_create_raidset(lc, rs);
+ rs->type = raid_type;
+ }
+ else if (rs->status == s_nosync)
+ ret = update_metadata(lc, rs);
+
+ return ret;
+}
+
+static int
+isw_check(struct lib_context *lc, struct raid_set *rs)
+{
+ if (rs->status == s_init)
+ return 1;
+ else
+ return T_GROUP(rs) ? _isw_check(lc, rs) : 0;
+}
+
+/*
+ * IO error event handler.
+ */
+static int
+event_io(struct lib_context *lc, struct event_io *e_io)
+{
+ struct raid_dev *rd = e_io->rd;
+ struct isw *isw = META(rd, isw);
+ struct isw_disk *disk;
+
+ if (!(disk = get_disk(lc, rd->di, isw)))
+ LOG_ERR(lc, 0, "%s: disk", handler);
+
+ /* Avoid write trashing. */
+ if (S_BROKEN(status(lc, rd)))
+ return 0;
+
+ disk->status &= ~USABLE_DISK;
+ disk->status |= FAILED_DISK;
+
+ return 1;
+}
+
+static struct event_handlers isw_event_handlers = {
+ .io = event_io,
+ .rd = NULL, /* FIXME: no device add/remove event handler yet. */
+};
+
+static void
+_isw_log(struct lib_context *lc, struct isw *isw)
+{
+ unsigned d, i, m;
+ struct isw_disk *disk;
+ struct isw_dev *dev;
+
+ P("sig: \"%*s\"", isw, isw->sig, MAX_SIGNATURE_LENGTH, isw->sig);
+ DP("check_sum: %u", isw, isw->check_sum);
+ DP("mpb_size: %u", isw, isw->mpb_size);
+ DP("family_num: %u", isw, isw->family_num);
+ DP("generation_num: %u", isw, isw->generation_num);
+ DP("error_log_size: %u", isw, isw->error_log_size);
+ DP("attributes: %u", isw, isw->attributes);
+ DP("num_disks: %u", isw, isw->num_disks);
+ DP("num_raid_devs: %u", isw, isw->num_raid_devs);
+ DP("error_log_pos: %u", isw, isw->error_log_pos);
+ DP("cache_size: %u", isw, isw->cache_size);
+ DP("orig_family_num: %u", isw, isw->orig_family_num);
+
+ for (i = 0; i < ISW_FILLERS; i++) {
+ if (isw->filler[i])
+ P("filler[%i]: %u", isw, isw->filler[i], i,
+ isw->filler[i]);
+ }
+
+ /* Disk table. */
+ for (d = 0, disk = isw->disk; d < isw->num_disks; d++, disk++) {
+ if (!disk->totalBlocks)
+ continue;
+
+ P("disk[%u].serial: \"%*s\"", isw,
+ disk->serial, d, MAX_RAID_SERIAL_LEN, disk->serial);
+ P("disk[%u].totalBlocks: %u", isw,
+ disk->totalBlocks, d, disk->totalBlocks);
+ P("disk[%u].scsiId: 0x%x", isw, disk->scsiId, d, disk->scsiId);
+ P("disk[%u].status: 0x%x", isw, disk->status, d, disk->status);
+ P("disk[%u].owner_cfg_num: 0x%x", isw, disk->owner_cfg_num,
+ d, disk->owner_cfg_num);
+ for (i = 0; i < ISW_DISK_FILLERS; i++) {
+ if (disk->filler[i])
+ P("disk[%u].filler[%u]: %u", isw,
+ disk->filler[i], d, i, disk->filler[i]);
+ }
+ }
+
+ /* RAID device/volume table. */
+ for (d = 0; d < isw->num_raid_devs; d++) {
+ dev = raiddev(isw, d);
+
+ /* RAID device */
+ P("isw_dev[%u].volume: \"%*s\"", isw,
+ dev->volume, d, MAX_RAID_SERIAL_LEN, dev->volume);
+ P("isw_dev[%u].SizeHigh: %u", isw, dev->SizeHigh, d,
+ dev->SizeHigh);
+ P("isw_dev[%u].SizeLow: %u", isw, dev->SizeLow, d,
+ dev->SizeLow);
+ P("isw_dev[%u].status: 0x%x", isw, dev->status, d, dev->status);
+ P("isw_dev[%u].reserved_blocks: %u", isw,
+ dev->reserved_blocks, d, dev->reserved_blocks);
+ P("isw_dev[%u].migr_priority: %u", isw, dev->migr_priority,
+ d, dev->migr_priority);
+ P("isw_dev[%u].num_sub_vol: %u", isw, dev->num_sub_vol, d,
+ dev->num_sub_vol);
+ P("isw_dev[%u].tid: %u", isw, dev->tid, d, dev->tid);
+ P("isw_dev[%u].cng_master_disk: %u", isw,
+ dev->cng_master_disk, d, dev->cng_master_disk);
+ P("isw_dev[%u].cache_policy: %u", isw,
+ dev->cache_policy, d, dev->cache_policy);
+ P("isw_dev[%u].cng_state: %u", isw, dev->cng_state, d,
+ dev->cng_state);
+ P("isw_dev[%u].cng_sub_state: %u", isw, dev->cng_sub_state,
+ d, dev->cng_sub_state);
+
+ for (i = 0; i < ISW_DEV_FILLERS; i++) {
+ if (dev->filler[i])
+ P("isw_dev[%u].filler[%u]: %u", isw,
+ dev->filler[i], d, i, dev->filler[i]);
+ }
+
+ /* RAID volume */
+ P("isw_dev[%u].vol.curr_migr_unit: %u", isw,
+ dev->vol.curr_migr_unit, d, dev->vol.curr_migr_unit);
+ P("isw_dev[%u].vol.check_point_id: %u", isw,
+ dev->vol.check_point_id, d, dev->vol.check_point_id);
+
+ P("isw_dev[%u].vol.migr_state: %u", isw,
+ dev->vol.migr_state, d, dev->vol.migr_state);
+ P("isw_dev[%u].vol.migr_type: %u", isw,
+ dev->vol.migr_type, d, dev->vol.migr_type);
+ P("isw_dev[%u].vol.dirty: %u", isw, dev->vol.dirty, d,
+ dev->vol.dirty);
+ P("isw_dev[%u].vol.fs_state: %u", isw, dev->vol.fs_state,
+ d, dev->vol.fs_state);
+ P("isw_dev[%u].vol.verify_errors: %u", isw,
+ dev->vol.verify_errors, d, dev->vol.verify_errors);
+ P("isw_dev[%u].vol.verify_bad_blocks: %u", isw,
+ dev->vol.verify_bad_blocks, d, dev->vol.verify_bad_blocks);
+
+ for (i = 0; i < ISW_RAID_VOL_FILLERS; i++) {
+ if (dev->vol.filler[i])
+ P("isw_dev[%u].vol.filler[%u]: %u", isw,
+ dev->vol.filler[i], d, i, dev->vol.filler[i]);
+ }
+
+
+ struct isw_map *map = &dev->vol.map;
+ for (m = 0; m < 2; m++) {
+ /* RAID map */
+
+ P("isw_dev[%u].vol.map[%d].pba_of_lba0: %u", isw,
+ map->pba_of_lba0, d, m, map->pba_of_lba0);
+ P("isw_dev[%u].vol.map[%d].blocks_per_member: %u",
+ isw, map->blocks_per_member, d, m,
+ map->blocks_per_member);
+ P("isw_dev[%u].vol.map[%d].num_data_stripes: %u",
+ isw, map->num_data_stripes, d, m,
+ map->num_data_stripes);
+ P("isw_dev[%u].vol.map[%d].blocks_per_strip: %u",
+ isw, map->blocks_per_strip, d, m,
+ map->blocks_per_strip);
+ P("isw_dev[%u].vol.map[%d].map_state: %u", isw,
+ map->map_state, d, m, map->map_state);
+ P("isw_dev[%u].vol.map[%d].raid_level: %u", isw,
+ map->raid_level, d, m, map->raid_level);
+ P("isw_dev[%u].vol.map[%d].num_members: %u", isw,
+ map->num_members, d, m, map->num_members);
+ P("isw_dev[%u].vol.map[%d].num_domains: %u", isw,
+ map->num_domains, d, m, map->num_domains);
+ P("isw_dev[%u].vol.map[%d].failed_disk_num: %u",
+ isw, map->failed_disk_num, d, m,
+ map->failed_disk_num);
+ P("isw_dev[%u].vol.map[%d].ddf: %u", isw, map->ddf,
+ d, m, map->ddf);
+
+ for (i = 0; i < 7; i++) {
+ if (map->filler[i])
+ P("isw_dev[%u].vol.map[%d].filler[%u]: %u", isw, map->filler[i], d, m, i, map->filler[i]);
+ }
+
+ for (i = 0; i < map->num_members; i++) {
+ P("isw_dev[%u].vol.map[%d].disk_ord_tbl[%u]: 0x%x", isw, map->disk_ord_tbl[i], d, m, i, map->disk_ord_tbl[i]);
+ }
+
+ if (!dev->vol.migr_state)
+ break;
+
+ map = (struct isw_map *) ((char *) map +
+ (map->num_members - 1) *
+ sizeof(map->disk_ord_tbl) +
+ sizeof(struct isw_map));
+ }
+ }
+}
+
+#ifdef DMRAID_NATIVE_LOG
+/*
+ * Log native information about an ISW RAID device.
+ */
+static void
+isw_log(struct lib_context *lc, struct raid_dev *rd)
+{
+ struct isw *isw = META(rd, isw);
+
+ log_print(lc, "%s (%s):", rd->di->path, handler);
+ _isw_log(lc, isw);
+}
+#endif
+
+static void
+isw_erase_metadata(struct lib_context *lc, struct raid_set *rs)
+{
+ struct raid_dev *rd;
+
+ list_for_each_entry(rd, &rs->devs, devs)
+ isw_write(lc, rd, 1);
+}
+
+/*
+ * Write an Intel Software RAID device.
+ */
+static int
+isw_write_all(struct lib_context *lc, struct raid_set *rs, struct isw *isw)
+{
+ struct raid_dev *rd, *r;
+ struct meta_areas ma = {
+ .size = isw_size(isw),
+ .area = isw,
+ };
+
+ if (!(rd = alloc_raid_dev(lc, handler)))
+ return 0;
+
+ rd->meta_areas = &ma;
+ rd->type = t_raid0; //dummy code
+ rd->areas = 1;
+
+ list_for_each_entry(r, &rs->devs, devs) {
+ rd->di = r->di;
+ set_metadata_sizoff(rd, ma.size);
+ rd->fmt = r->fmt;
+ isw_write(lc, rd, 0);
+ }
+
+ dbg_free(rd);
+ return 1;
+}
+
+/* Remove an isw device. */
+static void
+isw_remove_dev(struct lib_context *lc, struct raid_set *rs,
+ struct isw *isw, struct isw_dev *dev)
+{
+ struct isw *isw_tmp;
+ size_t size, dev_size;
+
+ size = div_up(isw->mpb_size, ISW_DISK_BLOCK_SIZE);
+ if (!(isw_tmp = alloc_private(lc, handler,
+ (size + 1) * ISW_DISK_BLOCK_SIZE)))
+ log_err(lc, "%s: failed to allocate memory", handler);
+
+ size = sizeof(*isw) + sizeof(struct isw_disk) * (isw->num_disks - 1);
+ memcpy(isw_tmp, isw, size);
+
+ dev_size = sizeof(*dev) +
+ sizeof(uint32_t) * (dev->vol.map.num_members - 1);
+ memcpy((char *) isw_tmp + size, dev, dev_size);
+
+ isw_tmp->mpb_size = size + dev_size;
+ isw_tmp->num_raid_devs--;
+ isw_tmp->check_sum = _checksum(isw_tmp);
+ isw_write_all(lc, rs, isw_tmp);
+ dbg_free(isw_tmp);
+}
+
+static int
+_isw_delete_all(struct lib_context *lc, struct raid_set *rs_group)
+{
+ struct raid_set *rs;
+ struct raid_dev *rd;
+ char *name;
+ struct isw *isw;
+ struct isw_dev *dev1, *dev2;
+ int num = 0;
+
+ if (!(rs = list_entry(rs_group->sets.next, struct raid_set, list)))
+ LOG_ERR(lc, 0, "%s: failed to find a RAID set in a group",
+ handler);
+
+ if (!(rd = list_entry(rs_group->devs.next, struct raid_dev, devs)))
+ LOG_ERR(lc, 0,
+ "%s: failed to find a raid device in RS %s",
+ handler, rs_group->name);
+
+ if (!(isw = (struct isw *) rd->meta_areas->area))
+ LOG_ERR(lc, 0, "%s: failed to locate metadata on drive %s",
+ handler, rd->di->path);
+
+ if (isw->num_raid_devs != 2)
+ LOG_ERR(lc, 0, "%s: the number of raid volumes is not 2",
+ handler);
+
+ if ((!(dev1 = raiddev(isw, 0))) || (!(dev2 = raiddev(isw, 1))))
+ LOG_ERR(lc, 0, "%s: failed to get two volume info", handler);
+
+ list_for_each_entry(rs, &rs_group->sets, list) {
+ if (!(name = get_rs_basename(rs->name)))
+ LOG_ERR(lc, 0,
+ "%s: could not find the volume to be "
+ "deleted", handler);
+
+ if (!strcmp((const char *) dev1->volume, (const char *) name))
+ num++;
+
+ if (!strcmp((const char *) dev2->volume, (const char *) name))
+ num++;
+ }
+ if (num != 2)
+ LOG_ERR(lc, 0,
+ "%s: failed to find all of the RAID sets to be "
+ "deleted", handler);
+
+ isw_erase_metadata(lc, rs_group);
+ return 1;
+}
+
+/* Delete metadata according to the RAID set. */
+static int
+isw_delete(struct lib_context *lc, struct raid_set *rs_group)
+{
+ struct raid_set *rs;
+ struct raid_dev *rd;
+ char *name;
+ struct isw *isw;
+ struct isw_dev *dev1, *dev2;
+ int num = 0;
+
+ if (rs_group->type != t_group)
+ LOG_ERR(lc, 0, "%s: RAID set is not a t-group type", handler);
+
+ list_for_each_entry(rs, &rs_group->sets, list)
+ num++;
+
+ if (num > 1)
+ return _isw_delete_all(lc, rs_group);
+
+ if (!(rs = list_entry(rs_group->sets.next, struct raid_set, list)))
+ LOG_ERR(lc, 0,
+ "%s: failed to find a RAID set in the group",
+ handler);
+
+ if (!(name = get_rs_basename(rs->name)))
+ LOG_ERR(lc, 0,
+ "%s: failed to find the volume to be deleted", handler);
+
+ if (!(rd = list_entry(rs_group->devs.next, struct raid_dev, devs)))
+ LOG_ERR(lc, 0,
+ "%s: failed to find a raid device in RS %s",
+ handler, rs_group->name);
+
+ if (!(isw = (struct isw *) rd->meta_areas->area))
+ LOG_ERR(lc, 0,
+ "%s: failed to locate metadata on device %s",
+ handler, rd->di->path);
+
+ /* case if metadata on spare disk is delete */
+ if (!isw->num_raid_devs && isw->num_disks == 1 &&
+ (isw->disk[0].status & SPARE_DISK)) {
+ isw_erase_metadata(lc, rs_group);
+ return 1;
+ }
+
+ if (!(dev1 = raiddev(isw, 0)))
+ LOG_ERR(lc, 0,
+ "%s: failed to find a RAID set in the group", handler);
+
+ if (isw->num_raid_devs == 1) {
+ if (!strcmp((const char *) dev1->volume, (const char *) name)) {
+ isw_erase_metadata(lc, rs_group);
+ return 1;
+ }
+ else
+ LOG_ERR(lc, 0, "%s: failed to find the volume %s",
+ handler, name);
+ }
+
+ if (!(dev2 = raiddev(isw, 1)))
+ LOG_ERR(lc, 0,
+ "%s: failed to find a RAID set in the group", handler);
+
+ if (!strcmp((const char *) dev1->volume, (const char *) name))
+ isw_remove_dev(lc, rs_group, isw, dev2);
+ else if (!strcmp((const char *) dev2->volume, (const char *) name))
+ isw_remove_dev(lc, rs_group, isw, dev1);
+ else
+ return 0;
+
+ return 1;
+}
+
+
+static struct dmraid_format isw_format = {
+ .name = HANDLER,
+ .descr = "Intel Software RAID",
+ .caps = "0,1,01",
+ .format = FMT_RAID,
+ .read = isw_read,
+ .write = isw_write,
+ .create = isw_create,
+ .delete = isw_delete,
+ .group = isw_group,
+ .check = isw_check,
+ .metadata_handler = isw_metadata_handler,
+ .events = &isw_event_handlers,
+ .scope = t_scope_global /* | t_scope_local */ ,
+#ifdef DMRAID_NATIVE_LOG
+ .log = isw_log,
+#endif
+};
+
+static struct raid_set *
+change_set_name(struct lib_context *lc, struct list_head *list,
+ char *o_name, char *n_name)
+{
+ struct raid_set *r, *ret = NULL;
+
+ list_for_each_entry(r, list, list) {
+ if (!strcmp(r->name, o_name)) {
+ ret = r;
+ r->name = n_name;
+ break;
+ }
+ }
+
+ list_for_each_entry(r, list, list) {
+ if ((ret = change_set_name(lc, &r->sets, o_name, n_name)))
+ r->name = n_name;
+ }
+
+ return ret;
+}
+
+
+/*
+ * Create part of metadata (struct isw_dev) in new_isw based on
+ * certain parameters.
+ *
+ * Note that new_isw must have its data preceedning isw_dev field already set.
+ * The function returns size of created isw_dev (including map(s)).
+ */
+static unsigned
+update_metadata_isw_dev(struct isw *new_isw,
+ int failed_disk_idx,
+ struct isw *old_isw,
+ int isw_dev_idx, unsigned isw_dev_offs)
+{
+ int i, map_size;
+ struct isw_dev *new_dev, *old_dev = raiddev(old_isw, isw_dev_idx);
+
+ /* Append old volume information record (the first one);
+ * note that at the moment there is only one isw_map record
+ * (as in the old isw_dev/isw_vol record/subrecord) and we
+ * need two of them till data transfer is finished.
+ */
+ memcpy((void *) (new_isw->disk + new_isw->num_disks) +
+ isw_dev_offs, old_dev, sizeof(struct isw_dev));
+
+ /* Update new volume information. */
+ new_dev = raiddev(new_isw, isw_dev_idx);
+ new_dev->vol.migr_state = 1; /* FIXME: replace magic numbers */
+ new_dev->vol.migr_type = 1; /* FIXME: replace magic numbers */
+
+ /* Update information in the first map. */
+ new_dev->vol.map.map_state = ISW_T_STATE_NORMAL;
+ new_dev->vol.map.failed_disk_num = failed_disk_idx;
+
+ /*
+ * FIXME: disk_ord_tbl should be updated too but at the moment
+ * we may leave it as it is coded below without any harm.
+ */
+ for (i = 0; i < new_isw->num_disks - 1; i++)
+ new_dev->vol.map.disk_ord_tbl[i] = i;
+
+ /*
+ * FIXME: code commented out
+ * new_isw->family_num = _checksum(new_isw) + time(NULL);
+ */
+
+ /* now let's proceed with the second, temporary map
+ FIXME: we just copy the first map and update it a bit */
+ map_size =
+ sizeof(struct isw_map) + (new_dev->vol.map.num_members -
+ 1) *
+ sizeof(((struct isw_map *) NULL)->disk_ord_tbl);
+ memcpy((void *) &new_dev->vol.map + map_size,
+ (void *) &new_dev->vol.map, map_size);
+
+ /*
+ * FIXME: the code below should be put into
+ * a new function 'raid_is_rebuildable()'.
+ */
+ ((struct isw_map *)
+ ((void *) &new_dev->vol.map + map_size))->map_state =
+ new_dev->vol.map.raid_level == ISW_T_RAID0 ?
+ ISW_T_STATE_FAILED : ISW_T_STATE_DEGRADED;
+
+ return (unsigned)
+ ((unsigned long) &new_dev->vol.map + 2 * map_size) -
+ ((unsigned long) new_isw->disk + new_isw->num_disks) -
+ isw_dev_offs;
+}
+
+/* Update metadata wit hdrive to rebuild. */
+static int
+update_metadata(struct lib_context *lc, struct raid_set *rs)
+{
+ int failed_disk_idx = -1; /* zero-based index of failed disk */
+ int i, idx, found = 0, failed_disks_num = 0, new_isw_size, ret = 0;
+ unsigned isw_dev_offs;
+ const char *rebuild_set_name = lc->options[LC_REBUILD_SET].arg.str;
+ struct raid_dev *rd = list_entry(rs->devs.next, struct raid_dev, devs);
+ struct raid_set *sub_rs = NULL;
+ struct dev_info *di = NULL;
+ struct isw *isw = META(rd, isw), *new_isw = NULL;
+ struct isw_disk *disk = isw->disk, *new_disk = NULL;
+ struct isw_dev *new_dev = NULL;
+
+
+ /*
+ * Find the index of the failed disk -
+ * at most we can handle 1 failed disk.
+ */
+ i = isw->num_disks;
+ while (i--) {
+ /* Check if the disk is listed. */
+ list_for_each_entry(di, LC_DI(lc), list) {
+ if (!strncmp(di->serial, (const char *) disk[i].serial,
+ MAX_RAID_SERIAL_LEN))
+ goto goon;
+ }
+
+ /* Disk not found in system, i.e. it's the failed one. */
+ failed_disk_idx = i;
+ failed_disks_num++;
+
+ /* Mark disk as not usable. */
+ disk[i].scsiId = UNKNOWN_SCSI_ID;
+ disk[i].status &= ~USABLE_DISK;
+ disk[i].status |= FAILED_DISK;
+ goon:
+ ;
+ }
+
+ /* We must have one failed disk */
+ if (failed_disks_num != 1)
+ LOG_ERR(lc, 0, "%s: only one failed disk supported", handler);
+
+ /* Now let's find the disk for rebuild. */
+ if (failed_disk_idx == -1)
+ /*
+ * Could not find failed disk... maybe this place can
+ * be used to search for and add a spare disk.
+ */
+ return 0;
+
+ /* Search for a raid_dev in s_init state. */
+ sub_rs = find_set(lc, NULL, rebuild_set_name, FIND_ALL);
+ found = 0;
+ list_for_each_entry(rd, &sub_rs->devs, devs) {
+ if (rd->status == s_init) {
+ di = rd->di;
+ DM_ASSERT(di);
+ log_print(lc, "%s: drive to rebuild: %s\n",
+ handler, di->path);
+ found = 1;
+ break;
+ }
+ }
+
+ /* FIXME: "TBD - remove later" */
+ if (!found && lc->options[LC_REBUILD_DISK].opt) {
+ list_for_each_entry(di, LC_DI(lc), list) {
+ if (!strncmp(di->path,
+ lc->options[LC_REBUILD_DISK].arg.str,
+ strlen(di->path))) {
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ if (!found) /* Error: no disk to rebuild found - exit. */
+ LOG_ERR(lc, 0, "%s: no drive to rebuild", handler);
+
+ /* Now let's start building the new metadata. */
+
+ /* MPB can have at most two block size. */
+ new_isw_size = 2 * ISW_DISK_BLOCK_SIZE;
+ new_isw = alloc_private(lc, handler, new_isw_size);
+ if (!new_isw)
+ return 0;
+
+ /* Copy a few first metadata bytes. */
+ memcpy(new_isw, isw, sizeof(struct isw) - sizeof(struct isw_disk));
+
+ /* some field will be updated later on; they are marked below:
+ * check_sum
+ * mpb_size
+ family_num
+ * generation_num
+ error_log_size
+ attributes
+ * num_disks
+ num_raid_devs
+ error_log_pos
+ cache_size
+ orig_family_num
+ FIXME: OROM changes some fields that are not marked above,
+ so we should too
+ */
+
+ /* Add the new disk. */
+ new_disk = alloc_private(lc, handler, sizeof(struct isw_disk));
+ if (!new_disk)
+ goto bad_free_new_isw;
+
+ new_disk->totalBlocks = di->sectors;
+ new_disk->scsiId = get_scsiId(lc, di->path);
+ /* FIXME: is this state ok, Radoslaw ? Was 0x53a */
+ new_disk->status = CONFIG_ON_DISK |
+ DISK_SMART_EVENT_SUPPORTED |
+ CLAIMED_DISK | DETECTED_DISK | USABLE_DISK | CONFIGURED_DISK;
+ strncpy((char *) new_disk->serial, di->serial, MAX_RAID_SERIAL_LEN);
+
+ /* build new isw_disk array */
+ for (i = 0; i < isw->num_disks; i++) {
+ /*
+ * Replace failed disk with the new one or
+ * Leave previous drives as they are.
+ */
+ memcpy(new_isw->disk + i,
+ i == failed_disk_idx ? new_disk : isw->disk + i,
+ sizeof(struct isw_disk));
+ }
+
+ /*
+ * Append the failed disk at the end of the disks array in
+ * the metadata; as designed in the intermediate rebuilding
+ * step we have 3 disks and two maps per isw_dev: the new one
+ * (at index 0) and the old one (at index 1).
+ */
+ memcpy(new_isw->disk + i, isw->disk + failed_disk_idx,
+ sizeof(struct isw_disk));
+ new_isw->disk[i].status = CONFIGURED_DISK;
+ new_isw->num_disks++;
+
+ /* Create isw_dev record for volume(s). */
+ isw_dev_offs = update_metadata_isw_dev(new_isw, failed_disk_idx,
+ isw, 0, 0);
+ if (isw->num_raid_devs > 1)
+ isw_dev_offs += update_metadata_isw_dev(new_isw,
+ failed_disk_idx, isw,
+ 1, isw_dev_offs);
+
+ /* now we may update new metadata's fields */
+ new_isw->mpb_size =
+ (unsigned long) (new_isw->disk + new_isw->num_disks) -
+ (unsigned long) (new_isw) + isw_dev_offs;
+ new_isw->generation_num++;
+ new_isw->check_sum = _checksum(new_isw);
+
+ /* embed new metadata on physical devices */
+ idx = rd_idx_by_name(new_isw, rebuild_set_name + strlen(rs->name) + 1);
+ if (idx < 0)
+ return 0;
+
+ new_dev = raiddev(new_isw, idx);
+ sub_rs = find_set(lc, NULL, rebuild_set_name, FIND_ALL);
+ list_for_each_entry(rd, &sub_rs->devs, devs) {
+ if (rd->meta_areas && rd->meta_areas->area) {
+
+ dbg_free(rd->meta_areas->area);
+ }
+ if (!rd->meta_areas || rd->status == s_init) {
+ if (rd->meta_areas)
+ dbg_free(rd->meta_areas);
+
+ rd->meta_areas = alloc_meta_areas(lc, rd, handler, 1);
+ if (!rd->meta_areas)
+ goto bad_free_new_disk;
+
+ rd->di = di;
+ rd->fmt = &isw_format;
+ rd->meta_areas->area =
+ alloc_private(lc, handler, new_isw_size);
+ memcpy(rd->meta_areas->area, new_isw, new_isw_size);
+ rd->offset = new_dev->vol.map.pba_of_lba0;
+ rd->sectors = new_dev->vol.map.blocks_per_member;
+ }
+ else {
+ rd->meta_areas->area =
+ alloc_private(lc, handler, new_isw_size);
+ if (!rd->meta_areas->area)
+ goto bad_free_new_disk;
+
+ memcpy(rd->meta_areas->area, new_isw, new_isw_size);
+ }
+
+ if (!rd->areas)
+ rd->areas++;
+ set_metadata_sizoff(rd, isw_size(new_isw));
+
+ if (rd->status == s_init) {
+ rd->status = s_ok;
+ if (rd->name)
+ dbg_free(rd->name);
+
+ if (!(rd->name = name(lc, rd, new_dev, N_VOLUME)))
+ goto bad_free_new_disk;
+ }
+
+ rd->status = s_ok;
+ }
+
+ list_for_each_entry(rd, &rs->devs, devs) {
+ if (rd->meta_areas && rd->meta_areas->area)
+ dbg_free(rd->meta_areas->area);
+
+ if (!rd->meta_areas || rd->status == s_init) {
+ if (rd->meta_areas && rd->meta_areas->area)
+ dbg_free(rd->meta_areas->area);
+
+ rd->meta_areas = alloc_meta_areas(lc, rd, handler, 1);
+ if (!rd->meta_areas)
+ goto bad_free_new_disk;
+
+ rd->di = di;
+ rd->fmt = &isw_format;
+ rd->offset = new_dev->vol.map.pba_of_lba0;
+ rd->sectors = new_dev->vol.map.blocks_per_member;
+ }
+ rd->meta_areas->area = alloc_private(lc, handler, new_isw_size);
+ if (!rd->meta_areas->area)
+ goto bad_free_new_disk;
+ set_metadata_sizoff(rd, isw_size(new_isw));
+ memcpy(rd->meta_areas->area, new_isw, new_isw_size);
+
+
+ if (rd->status == s_init) {
+
+ if (rd->name)
+ dbg_free(rd->name);
+
+ if (!(rd->name = name(lc, rd, new_dev, N_VOLUME)))
+ goto bad_free_new_disk;
+
+ /* FIXME: code commented out
+ new_name = name(lc, rd, new_dev, 0);
+ */
+ }
+
+ rd->status = s_ok;
+ }
+
+ /* FIXME: code commented out
+ change_set_name(lc, LC_RS(lc), rs->name, new_name);
+ */
+
+ ret = 1;
+ bad_free_new_disk:
+ dbg_free(new_disk);
+ bad_free_new_isw:
+ dbg_free(new_isw);
+ return ret;
+}
+
+/* Register this format handler with the format core. */
+int
+register_isw(struct lib_context *lc)
+{
+ return register_format_handler(lc, &isw_format);
+}
+
+/*
+ * Set the RAID device contents up derived from the Intel ones.
+ *
+ * This is the first one we get with here and we potentially need to
+ * create many in isw_group() in case of multiple Intel SW RAID devices
+ * on this RAID disk.
+ */
+static int
+setup_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct dev_info *di, void *meta, union read_info *info)
+{
+ struct isw *isw = meta;
+ struct isw_disk *disk;
+
+
+ /* Superblock checksum */
+ if (isw->check_sum != _checksum(isw))
+ LOG_ERR(lc, 0, "%s: extended superblock for %s "
+ "has wrong checksum", handler, di->path);
+
+ if (!(rd->meta_areas = alloc_meta_areas(lc, rd, handler, 1)))
+ return 0;
+
+ rd->meta_areas->offset = info->u64 >> 9;
+ rd->meta_areas->size = isw_size(isw);
+ rd->meta_areas->area = isw;
+
+ rd->di = di;
+ rd->fmt = &isw_format;
+
+ rd->offset = ISW_DATAOFFSET;
+ if (!(rd->sectors = info->u64 >> 9))
+ return log_zero_sectors(lc, di->path, handler);
+
+ rd->status = status(lc, rd);
+
+ /* Mark disk as spare disk. */
+ disk = get_disk(lc, di, isw);
+ if (disk->status & SPARE_DISK)
+ rd->type = t_spare;
+ else
+ rd->type = t_group;
- return (rd->name = name(lc, isw, NULL)) ? 1 : 0;
+ disk->scsiId = get_scsiId(lc, di->path);
+ return (rd->name = name(lc, rd, NULL, N_NUMBER)) ? 1 : 0;
}
--- dmraid/lib/format/ataraid/isw.h 2008/02/22 16:57:36 1.1
+++ dmraid/lib/format/ataraid/isw.h 2008/06/20 21:52:17 1.2
@@ -5,6 +5,9 @@
* Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2.1, or (at your option)
@@ -31,85 +34,156 @@
#undef FORMAT_HANDLER
/* Intel metadata offset in bytes */
-#define ISW_CONFIGOFFSET ((di->sectors - 2) << 9)
+#define ISW_CONFIGSECTOR(di) ((di)->sectors - 2)
+#define ISW_CONFIGOFFSET(di) (ISW_CONFIGSECTOR(di) << 9)
#define ISW_DATAOFFSET 0 /* Data offset in sectors */
#define MPB_SIGNATURE "Intel Raid ISM Cfg Sig. "
-#define MPB_VERSION_RAID2 "1.2.02"
+#define MPB_SIGNATURE_SIZE (sizeof(MPB_SIGNATURE) - 1)
+#define MPB_VERSION_RAID2 "1.2.02"
+#define MPB_VERSION_RAID2_SIZE (sizeof(MPB_VERSION_RAID2) - 1)
#define MAX_SIGNATURE_LENGTH 32
#define MAX_RAID_SERIAL_LEN 16
#define ISW_DISK_BLOCK_SIZE 512
#define TYPICAL_MPBSIZE 1024
+#define RAID_DS_JOURNAL 259
+#define MIGR_OPT_SPACE 4096
+#define RAID_VOLUME_RESERVED_BLOCKS (RAID_DS_JOURNAL+MIGR_OPT_SPACE)
+#define RAID_DISK_RESERVED_BLOCKS 417
+#define DISK_RESERVED_BLOCKS (RAID_DISK_RESERVED_BLOCKS+RAID_VOLUME_RESERVED_BLOCKS)
+#define UNKNOWN_SCSI_ID ((uint32_t)~0)
+
/* Disk configuration info. */
struct isw_disk {
- int8_t serial[MAX_RAID_SERIAL_LEN];/* 0xD8 - 0xE7 ascii serial number */
+ int8_t serial[MAX_RAID_SERIAL_LEN]; /* 0xD8 - 0xE7 ascii serial number */
uint32_t totalBlocks; /* 0xE8 - 0xEB total blocks */
uint32_t scsiId; /* 0xEC - 0xEF scsi ID */
uint32_t status; /* 0xF0 - 0xF3 */
-#define SPARE_DISK 0x01 /* Spare */
-#define CONFIGURED_DISK 0x02 /* Member of some RaidDev */
-#define FAILED_DISK 0x04 /* Permanent failure */
-#define USABLE_DISK 0x08 /* Fully usable unless FAILED_DISK is set */
-
-#define ISW_DISK_FILLERS 5
- uint32_t filler[ISW_DISK_FILLERS]; /* 0xF4 - 0x107 MPB_DISK_FILLERS for future expansion */
+#define SPARE_DISK 0x01 /* Spare */
+#define CONFIGURED_DISK 0x02 /* Member of some RaidDev */
+#define FAILED_DISK 0x04 /* Permanent failure */
+#define USABLE_DISK 0x08 /* Fully usable unless FAILED_DISK is set */
+#define DETECTED_DISK 0x10 /* Device attach received */
+#define CLAIMED_DISK 0X20 /* Device has been claimed ? */
+#define PASSTHRU_DISK 0X40 /* Device should be ignored */
+#define OFFLINE_DISK 0X80 /* Device has been marked offline by user */
+#define CONFIG_ON_DISK 0x100 /* Device currently has MPB stored on it */
+#define DISK_SMART_EVENT_TRIGGERED 0x200
+#define DISK_SMART_EVENT_SUPPORTED 0x400
+#define FORMATTING_DISK 0x800 /* Device is formatting */
+#define FORMAT_SUCCEEDED 0x1000 /* This bit is used with FORMATTING_DISK */
+#define FORMAT_FAILED 0x2000 /* This bit is used with FORMATTING_DISK */
+#define ELIGIBLE_FOR_SPARE 0x4000 /* Device may be used as a spare if needed. */
+#define READ_CONFIG_NEEDED 0x8000 /* Device needs to have its config read */
+#define CONFIG_IS_UPREV 0x10000 /* Config on device but cannot be handled */
+#define UNKNOW_DISK_FAILURE 0x40000 /* Any reading errors */
+#define DO_READ_CONFIG 0x80000 /* Device's config will be read and merged on nexted call */
+#define POWERED_OFF_DISK 0x100000 /* Device is spun down */
+#define PASSTHRU_CLAIMABLE 0x200000 /* Passthru device is claimable */
+#define CLONE_DISK_MODIFIED 0x400000
+#define PASSTHRU_DISK_WMPB 0X800000
+
+ uint32_t owner_cfg_num; /* 0xF4 - 0xF7 */
+#define ISW_DISK_FILLERS 4
+ uint32_t filler[ISW_DISK_FILLERS]; /* 0xF7 - 0x107 MPB_DISK_FILLERS for future expansion */
};
/* RAID map configuration infos. */
struct isw_map {
- uint32_t pba_of_lba0; // start address of partition
+ uint32_t pba_of_lba0; // start address of partition
uint32_t blocks_per_member; // blocks per member
uint32_t num_data_stripes; // number of data stripes
uint16_t blocks_per_strip;
- uint8_t map_state; // Normal, Uninitialized, Degraded, Failed
-#define ISW_T_STATE_NORMAL 0
-#define ISW_T_STATE_UNINITIALIZED 1
- uint8_t raid_level;
+ uint8_t map_state; // Normal, Uninitialized, Degraded, Failed
+#define ISW_T_STATE_NORMAL 0x00
+#define ISW_T_STATE_UNINITIALIZED 0X01
+#define ISW_T_STATE_DEGRADED 0x02
+#define ISW_T_STATE_FAILED 0x03
+
+ uint8_t raid_level;
#define ISW_T_RAID0 0
#define ISW_T_RAID1 1
-#define ISW_T_RAID5 5 // since metadata version 1.2.02 ?
- uint8_t num_members; // number of member disks
- uint8_t reserved[3];
- uint32_t filler[7]; // expansion area
+#define ISW_T_RAID10 2
+#define ISW_T_RAID5 5 // since metadata version 1.2.02 ?
+#define ISW_T_SPARE 8
+#define ISW_T_UNDEF 0xff
+ uint8_t num_members; // number of member disks
+ uint8_t num_domains;
+ uint8_t failed_disk_num;
+#define ISW_DEV_NONE_FAILED 255
+ uint8_t ddf;
+
+ uint32_t filler[7]; // expansion area
uint32_t disk_ord_tbl[1]; /* disk_ord_tbl[num_members],
top byte special */
} __attribute__ ((packed));
struct isw_vol {
- uint32_t reserved[2];
- uint8_t migr_state; // Normal or Migrating
- uint8_t migr_type; // Initializing, Rebuilding, ...
- uint8_t dirty;
- uint8_t fill[1];
- uint32_t filler[5];
+ uint32_t curr_migr_unit;
+ uint32_t check_point_id;
+ uint8_t migr_state; // Normal or Migrating
+ uint8_t migr_type; // Initializing, Rebuilding, ...
+ uint8_t dirty;
+ uint8_t fs_state;
+ uint16_t verify_errors;
+ uint16_t verify_bad_blocks;
+#define ISW_RAID_VOL_FILLERS 4
+ uint32_t filler[ISW_RAID_VOL_FILLERS];
struct isw_map map;
// here comes another one if migr_state
} __attribute__ ((packed));
struct isw_dev {
- uint8_t volume[MAX_RAID_SERIAL_LEN];
+ uint8_t volume[MAX_RAID_SERIAL_LEN];
uint32_t SizeLow;
uint32_t SizeHigh;
uint32_t status; /* Persistent RaidDev status */
- uint32_t reserved_blocks; /* Reserved blocks at beginning of volume */
-#define ISW_DEV_FILLERS 12
+#define ISW_DEV_BOOTABLE 0x01
+#define ISW_DEV_BOOT_DEVICE 0x02
+#define ISW_DEV_READ_COALESCING 0x04
+#define ISW_DEV_WRITE_COALESCING 0x08
+#define ISW_DEV_LAST_SHUTDOWN_DIRTY 0x10
+#define ISW_DEV_HIDDEN_AT_BOOT 0x20
+#define ISW_DEV_CURRENTLY_HIDDEN 0x40
+#define ISW_DEV_VERIFY_AND_FIX 0x80
+#define ISW_DEV_MAP_STATE_UNINIT 0x100
+#define ISW_DEV_NO_AUTO_RECOVERY 0x200
+#define ISW_DEV_CLONE_N_GO 0x400
+#define ISW_DEV_CLONE_MAN_SYNC 0x800
+#define ISW_DEV_CNG_MASTER_DISK_NUM 0x1000
+
+ uint32_t reserved_blocks; /* Reserved blocks at beginning of volume */
+ uint8_t migr_priority; /* Medium, Low, High */
+ uint8_t num_sub_vol; /* number of subvolumes */
+ uint8_t tid; /* target Id */
+ uint8_t cng_master_disk; /* */
+ uint16_t cache_policy; /* Persistent cache info */
+ uint8_t cng_state;
+ uint8_t cng_sub_state;
+
+#define ISW_DEV_FILLERS 10
uint32_t filler[ISW_DEV_FILLERS];
struct isw_vol vol;
} __attribute__ ((packed));
struct isw {
- int8_t sig[MAX_SIGNATURE_LENGTH];/* 0x0 - 0x1F */
- uint32_t check_sum; /* 0x20 - 0x23 MPB Checksum */
- uint32_t mpb_size; /* 0x24 - 0x27 Size of MPB */
- uint32_t family_num; /* 0x28 - 0x2B Checksum from first time this config was written */
+ int8_t sig[MAX_SIGNATURE_LENGTH]; /* 0x0 - 0x1F */
+ uint32_t check_sum; /* 0x20 - 0x23 MPB Checksum */
+ uint32_t mpb_size; /* 0x24 - 0x27 Size of MPB */
+ uint32_t family_num; /* 0x28 - 0x2B Checksum from first time this config was written */
/* 0x2C - 0x2F Incremented each time this array's MPB is written */
uint32_t generation_num;
- uint32_t reserved[2]; /* 0x30 - 0x37 */
- uint8_t num_disks; /* 0x38 Number of configured disks */
- uint8_t num_raid_devs; /* 0x39 Number of configured volumes */
- uint8_t fill[2]; /* 0x3A - 0x3B */
-#define ISW_FILLERS 39
+ uint32_t error_log_size; /* 0x30 - 0x33 in bytes */
+ uint32_t attributes; /* 0x34 - 0x37 */
+
+ uint8_t num_disks; /* 0x38 Number of configured disks */
+ uint8_t num_raid_devs; /* 0x39 Number of configured volumes */
+ uint8_t error_log_pos; /* 0x3A */
+ uint8_t fill[1]; /* 0x3B */
+ uint32_t cache_size; /* 0x3c - 0x40 in mb */
+ uint32_t orig_family_num; /* 0x40 - 0x43 original family num */
+#define ISW_FILLERS 37
uint32_t filler[ISW_FILLERS]; /* 0x3C - 0xD7 RAID_MPB_FILLERS */
struct isw_disk disk[1]; /* 0xD8 diskTbl[numDisks] */
// here comes isw_dev[num_raid_devs]
--- dmraid/lib/format/ataraid/jm.c 2008/04/02 13:35:31 1.3
+++ dmraid/lib/format/ataraid/jm.c 2008/06/20 21:52:17 1.4
@@ -1,7 +1,7 @@
/*
* JMicron metadata format handler.
*
- * Copyright (C) 2006,2007 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2006-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
* See file LICENSE at the top of this source tree for license information.
@@ -22,8 +22,8 @@
/* RAID set name */
static int member(struct jm *jm);
-static char *name(struct lib_context *lc, struct raid_dev *rd,
- unsigned int subset)
+static char *
+name(struct lib_context *lc, struct raid_dev *rd, unsigned int subset)
{
int i;
size_t len;
@@ -55,50 +55,57 @@
* Retrieve status of device.
* FIXME: is this sufficient to cover all state ?
*/
-static enum status status(struct jm *jm)
+static enum status
+status(struct jm *jm)
{
- return jm->attribute & ~(JM_MOUNT|JM_BOOTABLE|JM_BADSEC|JM_ACTIVE|JM_UNSYNC|JM_NEWEST) ? s_broken : s_ok;
+ return jm->attribute & ~(JM_MOUNT | JM_BOOTABLE | JM_BADSEC | JM_ACTIVE
+ | JM_UNSYNC | JM_NEWEST) ? s_broken : s_ok;
}
/* Neutralize disk type */
-static enum type type(struct jm *jm)
+static enum type
+type(struct jm *jm)
{
/* Mapping of JM types to generic types */
static struct types types[] = {
- { JM_T_JBOD, t_linear},
- { JM_T_RAID0, t_raid0},
- { JM_T_RAID01, t_raid1},
- { JM_T_RAID1, t_raid1},
- { 0, t_undef},
+ { JM_T_JBOD, t_linear },
+ { JM_T_RAID0, t_raid0 },
+ { JM_T_RAID01, t_raid1 },
+ { JM_T_RAID1, t_raid1 },
+ { 0, t_undef },
};
return rd_type(types, (unsigned int) jm->mode);
}
/* Calculate checksum on metadata */
-static int checksum(struct jm *jm)
+static int
+checksum(struct jm *jm)
{
int count = 64;
- uint16_t *p = (uint16_t*) jm, sum = 0;
+ uint16_t *p = (uint16_t *) jm, sum = 0;
- while (count--)
+ while (count--)
sum += *p++;
/* FIXME: shouldn't this be one value only ? */
- return sum == 0 || sum == 1;
+ return !sum || sum == 1;
}
-static inline unsigned int segment(uint32_t m)
+static inline unsigned int
+segment(uint32_t m)
{
return (unsigned int) (m & JM_SEG_MASK);
}
-static inline unsigned int disk(unsigned int m)
+static inline unsigned int
+disk(unsigned int m)
{
return (unsigned int) (m & JM_HDD_MASK);
}
-static int member(struct jm *jm)
+static int
+member(struct jm *jm)
{
unsigned int i = JM_MEMBERS;
@@ -111,25 +118,29 @@
}
/* Decide about ordering sequence of RAID device. */
-static int dev_sort(struct list_head *pos, struct list_head *new)
+static int
+dev_sort(struct list_head *pos, struct list_head *new)
{
return member(META(RD(new), jm)) < member(META(RD(pos), jm));
}
/* Decide about ordering sequence of RAID subset. */
-static int set_sort(struct list_head *pos, struct list_head *new)
+static int
+set_sort(struct list_head *pos, struct list_head *new)
{
return member(META(RD_RS(RS(pos)), jm)) > 1;
}
-static unsigned int stride(unsigned int shift)
+static unsigned int
+stride(unsigned int shift)
{
return 1 << (shift + 1);
}
-static void super_created(struct raid_set *super, void *private)
+static void
+super_created(struct raid_set *super, void *private)
{
- super->type = t_raid0;
+ super->type = t_raid0;
super->stride = stride(META((private), jm)->block);
}
@@ -138,8 +149,9 @@
*
* Check device hierarchy and create super set appropriately.
*/
-static int group_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_set **ss, struct raid_dev *rd)
+static int
+group_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_set **ss, struct raid_dev *rd)
{
struct jm *jm = META(rd, jm);
@@ -154,7 +166,6 @@
case JM_T_RAID1:
if (!find_set(lc, NULL, rs->name, FIND_TOP))
list_add_tail(&rs->list, LC_RS(lc));
-
break;
case JM_T_RAID01:
@@ -169,8 +180,8 @@
/*
* Add a JMicron RAID device to a set.
*/
-static struct raid_set *jm_group(struct lib_context *lc,
- struct raid_dev *rd)
+static struct raid_set *
+jm_group(struct lib_context *lc, struct raid_dev *rd)
{
struct raid_set *rs, *ss = NULL;
@@ -191,7 +202,8 @@
#if BYTE_ORDER == LITTLE_ENDIAN
# define to_cpu NULL
#else
-static void to_cpu(void *meta)
+static void
+to_cpu(void *meta)
{
unsigned int i;
struct jm *jm = meta;
@@ -215,19 +227,20 @@
#endif
/* Magic check. */
-static int is_jm(struct lib_context *lc, struct dev_info *di, void *meta)
+static int
+is_jm(struct lib_context *lc, struct dev_info *di, void *meta)
{
struct jm *jm = meta;
- return !strncmp((const char*) jm->signature,
- JM_SIGNATURE, JM_SIGNATURE_LEN)
- && checksum(jm);
+ return !strncmp((const char *) jm->signature,
+ JM_SIGNATURE, JM_SIGNATURE_LEN) &&
+ checksum(jm);
}
static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
struct dev_info *di, void *meta, union read_info *info);
-static struct raid_dev *jm_read(struct lib_context *lc,
- struct dev_info *di)
+static struct raid_dev *
+jm_read(struct lib_context *lc, struct dev_info *di)
{
return read_raid_dev(lc, di, NULL,
sizeof(struct jm), JM_CONFIGOFFSET,
@@ -237,8 +250,8 @@
/*
* Write a JMicron RAID device.
*/
-static int jm_write(struct lib_context *lc,
- struct raid_dev *rd, int erase)
+static int
+jm_write(struct lib_context *lc, struct raid_dev *rd, int erase)
{
int ret;
#if BYTE_ORDER != LITTLE_ENDIAN
@@ -258,17 +271,18 @@
*
* FIXME: more sanity checks.
*/
-static unsigned int devices(struct raid_dev *rd, void *context)
+static unsigned int
+devices(struct raid_dev *rd, void *context)
{
unsigned int r = JM_MEMBERS;
struct jm *jm = META(rd, jm);
while (r-- && !jm->member[r]);
-
return ++r;
}
-static int jm_check(struct lib_context *lc, struct raid_set *rs)
+static int
+jm_check(struct lib_context *lc, struct raid_set *rs)
{
return check_raid_set(lc, rs, devices, NULL,
NO_CHECK_RD, NULL, handler);
@@ -277,7 +291,8 @@
/*
* IO error event handler.
*/
-static int event_io(struct lib_context *lc, struct event_io *e_io)
+static int
+event_io(struct lib_context *lc, struct event_io *e_io)
{
struct raid_dev *rd = e_io->rd;
struct jm *jm = META(rd, jm);
@@ -286,21 +301,21 @@
if (S_BROKEN(status(jm)))
return 0;
- jm->checksum = 1; /* FIXME: how to flag a JMicron disk bad? */
-
+ jm->checksum = 1; /* FIXME: how to flag a JMicron disk bad? */
return 1;
}
static struct event_handlers jm_event_handlers = {
.io = event_io,
- .rd = NULL, /* FIXME: no device add/remove event handler yet. */
+ .rd = NULL, /* FIXME: no device add/remove event handler yet. */
};
#ifdef DMRAID_NATIVE_LOG
/*
* Log native information about an JM RAID device.
*/
-static void jm_log(struct lib_context *lc, struct raid_dev *rd)
+static void
+jm_log(struct lib_context *lc, struct raid_dev *rd)
{
unsigned int i;
struct jm *jm = META(rd, jm);
@@ -319,44 +334,49 @@
DP("name: %u", jm, jm->mode);
DP("block: %u", jm, jm->block);
DP("attribute: %u", jm, jm->attribute);
+
for (i = 0; i < JM_SPARES; i++)
P2("spare[%d]: 0x%x", jm, i, jm->spare[i]);
+
for (i = 0; i < JM_MEMBERS; i++)
P2("member[%d]: 0x%x", jm, i, jm->member[i]);
}
#endif
static struct dmraid_format jm_format = {
- .name = HANDLER,
- .descr = "JMicron ATARAID",
- .caps = "S,0,1",
+ .name = HANDLER,
+ .descr = "JMicron ATARAID",
+ .caps = "S,0,1",
.format = FMT_RAID,
- .read = jm_read,
- .write = jm_write,
- .group = jm_group,
- .check = jm_check,
- .events = &jm_event_handlers,
+ .read = jm_read,
+ .write = jm_write,
+ .group = jm_group,
+ .check = jm_check,
+ .events = &jm_event_handlers,
#ifdef DMRAID_NATIVE_LOG
- .log = jm_log,
+ .log = jm_log,
#endif
};
/* Register this format handler with the format core. */
-int register_jm(struct lib_context *lc)
+int
+register_jm(struct lib_context *lc)
{
return register_format_handler(lc, &jm_format);
}
/* Calculate RAID device size in sectors depending on RAID type. */
-static inline uint64_t sectors(struct jm *jm)
+static inline uint64_t
+sectors(struct jm *jm)
{
/* range * 32MB[sectors] + range2 */
- return jm->segment.range * 32*2048 + jm->segment.range2;
+ return jm->segment.range * 32 * 2048 + jm->segment.range2;
}
/* Set the RAID device contents up derived from the JMicron ones */
-static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta, union read_info *info)
+static int
+setup_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct dev_info *di, void *meta, union read_info *info)
{
struct jm *jm = meta;
@@ -365,13 +385,13 @@
rd->meta_areas->offset = JM_CONFIGOFFSET >> 9;
rd->meta_areas->size = sizeof(*jm);
- rd->meta_areas->area = (void*) jm;
+ rd->meta_areas->area = (void *) jm;
rd->di = di;
rd->fmt = &jm_format;
rd->status = status(jm);
- rd->type = type(jm);
+ rd->type = type(jm);
rd->offset = jm->segment.base;
if (!(rd->sectors = sectors(jm)))
--- dmraid/lib/format/ataraid/jm.h 2008/02/22 16:57:36 1.1
+++ dmraid/lib/format/ataraid/jm.h 2008/06/20 21:52:17 1.2
@@ -22,35 +22,35 @@
struct jm {
#define JM_SIGNATURE "JM"
#define JM_SIGNATURE_LEN 2
- int8_t signature[JM_SIGNATURE_LEN]; /* 0x0 - 0x01 */
+ int8_t signature[JM_SIGNATURE_LEN]; /* 0x0 - 0x01 */
- uint16_t version; /* 0x03 - 0x04 JMicron version */
+ uint16_t version; /* 0x03 - 0x04 JMicron version */
#define JM_MINOR_VERSION(jm) (jm->version & 0xFF)
#define JM_MAJOR_VERSION(jm) (jm->version >> 8)
- uint16_t checksum; /* 0x04 - 0x05 */
- uint8_t filler[10];
+ uint16_t checksum; /* 0x04 - 0x05 */
+ uint8_t filler[10];
- uint32_t identity; /* 0x10 - 0x13 */
+ uint32_t identity; /* 0x10 - 0x13 */
struct {
- uint32_t base; /* 0x14 - 0x17 */
- uint32_t range; /* 0x18 - 0x1B range */
- uint16_t range2; /* 0x1C - 0x1D range2 */
+ uint32_t base; /* 0x14 - 0x17 */
+ uint32_t range; /* 0x18 - 0x1B range */
+ uint16_t range2; /* 0x1C - 0x1D range2 */
} segment;
#define JM_NAME_LEN 16
- int8_t name[JM_NAME_LEN]; /* 0x20 - 0x2F */
+ int8_t name[JM_NAME_LEN]; /* 0x20 - 0x2F */
- uint8_t mode; /* 0x30 RAID level */
+ uint8_t mode; /* 0x30 RAID level */
#define JM_T_RAID0 0
#define JM_T_RAID1 1
#define JM_T_RAID01 2 /* RAID 0+1 (striped with mirrors underneath) */
#define JM_T_JBOD 3
#define JM_T_RAID5 5
- uint8_t block; /* 0x31 stride size (2=4K, 3=8K, ...) */
- uint16_t attribute; /* 0x32 - 0x33 */
+ uint8_t block; /* 0x31 stride size (2=4K, 3=8K, ...) */
+ uint16_t attribute; /* 0x32 - 0x33 */
#define JM_MOUNT 0x01
#define JM_BOOTABLE 0x02
#define JM_BADSEC 0x03
@@ -58,16 +58,16 @@
#define JM_UNSYNC 0x06
#define JM_NEWEST 0x07
- uint8_t filler1[4];
+ uint8_t filler1[4];
#define JM_SPARES 2
#define JM_MEMBERS 8
- uint32_t spare[JM_SPARES]; /* 0x38 - 0x3F */
- uint32_t member[JM_MEMBERS]; /* 0x40 - 0x5F */
+ uint32_t spare[JM_SPARES]; /* 0x38 - 0x3F */
+ uint32_t member[JM_MEMBERS]; /* 0x40 - 0x5F */
#define JM_HDD_MASK 0xFFFFFFF0
#define JM_SEG_MASK 0x0F
- uint8_t filler2[0x20];
+ uint8_t filler2[0x20];
} __attribute__ ((packed));
#endif
--- dmraid/lib/format/ataraid/lsi.c 2008/04/02 13:35:31 1.3
+++ dmraid/lib/format/ataraid/lsi.c 2008/06/20 21:52:17 1.4
@@ -1,7 +1,7 @@
/*
* LSI Logic MegaRAID (and MegaIDE ?) ATARAID metadata format handler.
*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
* See file LICENSE at the top of this source tree for license information.
@@ -26,26 +26,29 @@
/* Make up RAID device name. */
/* FIXME: senseful name ;) */
-static unsigned int get_disk_slot(struct lsi *lsi)
+static unsigned int
+get_disk_slot(struct lsi *lsi)
{
return lsi->set_number * 2 + lsi->disk_number;
}
-static struct lsi_disk *get_disk(struct lsi *lsi)
+static struct lsi_disk *
+get_disk(struct lsi *lsi)
{
return lsi->disks + get_disk_slot(lsi);
}
-static size_t _name(struct lsi *lsi, char *str, size_t len, unsigned int subset)
+static size_t
+_name(struct lsi *lsi, char *str, size_t len, unsigned int subset)
{
return snprintf(str, len,
subset ? "lsi_%u%u-%u" : "lsi_%u%u",
- lsi->set_id, lsi->set_number,
- (get_disk(lsi))->raid10_mirror);
+ lsi->set_id, lsi->set_number,
+ get_disk(lsi)->raid10_mirror);
}
-static char *name(struct lib_context *lc, struct raid_dev *rd,
- unsigned int subset)
+static char *
+name(struct lib_context *lc, struct raid_dev *rd, unsigned int subset)
{
size_t len;
char *ret;
@@ -63,14 +66,15 @@
}
/* Neutralize disk type */
-static enum type type(struct lsi *lsi)
+static enum type
+type(struct lsi *lsi)
{
/* Mapping of LSI Logic types to generic types */
static struct types types[] = {
{ LSI_T_RAID0, t_raid0 },
{ LSI_T_RAID1, t_raid1 },
{ LSI_T_RAID10, t_raid0 },
- { 0, t_undef}
+ { 0, t_undef }
};
return rd_type(types, (unsigned int) lsi->type);
@@ -78,28 +82,31 @@
/* LSI device status. */
/* FIXME: add flesh. */
-static int status(struct lsi *lsi)
+static int
+status(struct lsi *lsi)
{
return s_ok;
}
/* Decide about ordering sequence of RAID device. */
-static int dev_sort(struct list_head *pos, struct list_head *new)
+static int
+dev_sort(struct list_head *pos, struct list_head *new)
{
struct lsi *p = META(RD(pos), lsi), *n = META(RD(new), lsi);
switch (n->type) {
case LSI_T_RAID10:
- return (get_disk(n))->raid10_stripe <
- (get_disk(p))->raid10_stripe;
+ return (get_disk(n))->raid10_stripe <
+ (get_disk(p))->raid10_stripe;
- default: /* RAID0 + RAID01 */
+ default: /* RAID0 + RAID01 */
return get_disk_slot(n) < get_disk_slot(p);
}
}
/* Decide about ordering sequence of RAID subset. */
-static int set_sort(struct list_head *pos, struct list_head *new)
+static int
+set_sort(struct list_head *pos, struct list_head *new)
{
struct lsi *p = META(RD_RS(pos), lsi), *n = META(RD_RS(new), lsi);
@@ -114,7 +121,8 @@
#if BYTE_ORDER == LITTLE_ENDIAN
# define to_cpu NULL
#else
-static void to_cpu(void *meta)
+static void
+to_cpu(void *meta)
{
struct lsi *lsi = meta;
struct lsi_disk *disk;
@@ -130,25 +138,28 @@
}
#endif
-static int is_lsi(struct lib_context *lc, struct dev_info *di, void *meta)
+static int
+is_lsi(struct lib_context *lc, struct dev_info *di, void *meta)
{
- return !strncmp((const char*) ((struct lsi *) meta)->magic_name,
- LSI_MAGIC_NAME, LSI_MAGIC_NAME_LEN);
+ return !strncmp((const char *) ((struct lsi *) meta)->magic_name,
+ LSI_MAGIC_NAME, LSI_MAGIC_NAME_LEN);
}
static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
struct dev_info *di, void *meta, union read_info *info);
-static struct raid_dev *lsi_read(struct lib_context *lc, struct dev_info *di)
+static struct raid_dev *
+lsi_read(struct lib_context *lc, struct dev_info *di)
{
return read_raid_dev(lc, di, NULL,
- sizeof(struct lsi), LSI_CONFIGOFFSET,
+ sizeof(struct lsi), LSI_CONFIGOFFSET,
to_cpu, is_lsi, NULL, setup_rd, handler);
}
/*
* Write a LSI Logic RAID device.
*/
-static int lsi_write(struct lib_context *lc, struct raid_dev *rd, int erase)
+static int
+lsi_write(struct lib_context *lc, struct raid_dev *rd, int erase)
{
int ret;
#if BYTE_ORDER != LITTLE_ENDIAN
@@ -168,14 +179,16 @@
*
* FIXME: this needs more work together with the metadata reengineering.
*/
-static void super_created(struct raid_set *ss, void *private)
+static void
+super_created(struct raid_set *ss, void *private)
{
- ss->type = t_raid1;
+ ss->type = t_raid1;
ss->stride = META(private, lsi)->stride;
}
-static int group_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_set **ss, struct raid_dev *rd)
+static int
+group_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_set **ss, struct raid_dev *rd)
{
struct lsi *lsi = META(rd, lsi);
@@ -204,8 +217,8 @@
return 1;
}
-static struct raid_set *lsi_group(struct lib_context *lc,
- struct raid_dev *rd)
+static struct raid_set *
+lsi_group(struct lib_context *lc, struct raid_dev *rd)
{
struct raid_set *rs, *ss = NULL;
@@ -220,9 +233,10 @@
}
/* Figure total number of disks depending on RAID type. */
-static unsigned int devices(struct raid_dev *rd, void *context)
+static unsigned int
+devices(struct raid_dev *rd, void *context)
{
- switch ((META(rd, lsi))->type) {
+ switch (META(rd, lsi)->type) {
case LSI_T_RAID10:
return 4;
@@ -239,7 +253,8 @@
*
* FIXME: more sanity checks!!!
*/
-static int lsi_check(struct lib_context *lc, struct raid_set *rs)
+static int
+lsi_check(struct lib_context *lc, struct raid_set *rs)
{
return check_raid_set(lc, rs, devices, NULL,
NO_CHECK_RD, NULL, handler);
@@ -248,7 +263,8 @@
/*
* IO error event handler.
*/
-static int event_io(struct lib_context *lc, struct event_io *e_io)
+static int
+event_io(struct lib_context *lc, struct event_io *e_io)
{
struct raid_dev *rd = e_io->rd;
struct lsi *lsi = META(rd, lsi);
@@ -258,18 +274,18 @@
return 0;
// FIXME: lsi->? = BAD;
-
return 1;
}
static struct event_handlers lsi_event_handlers = {
.io = event_io,
- .rd = NULL, /* FIXME: no device add/remove event handler yet. */
+ .rd = NULL, /* FIXME: no device add/remove event handler yet. */
};
#ifdef DMRAID_NATIVE_LOG
/* Log native information about an LSI Logic RAID device. */
-static void lsi_log(struct lib_context *lc, struct raid_dev *rd)
+static void
+lsi_log(struct lib_context *lc, struct raid_dev *rd)
{
unsigned int i;
struct lsi *lsi = META(rd, lsi);
@@ -294,12 +310,12 @@
disk->unknown, disk->unknown);
P("disks[%u].magic_0: 0x%x, %x, %x", lsi,
disk->magic_0, i, disk->magic_0,
- (unsigned char) (((char*) &disk->magic_0)[0]),
- (unsigned char) (((char*) &disk->magic_0)[1]));
+ (unsigned char) (((char *) &disk->magic_0)[0]),
+ (unsigned char) (((char *) &disk->magic_0)[1]));
P("disks[%u].magic_1: 0x%x, %x, %x", lsi,
disk->magic_1, i, disk->magic_1,
- (unsigned char) (((char*) &disk->magic_1)[0]),
- (unsigned char) (((char*) &disk->magic_1)[1]));
+ (unsigned char) (((char *) &disk->magic_1)[0]),
+ (unsigned char) (((char *) &disk->magic_1)[1]));
P("disks[%u].disk_number: %u", lsi, disk->disk_number,
i, disk->disk_number);
P("disks[%u].set_number: %u", lsi, disk->set_number,
@@ -315,29 +331,31 @@
#endif
static struct dmraid_format lsi_format = {
- .name = HANDLER,
- .descr = "LSI Logic MegaRAID",
- .caps = "0,1,10",
+ .name = HANDLER,
+ .descr = "LSI Logic MegaRAID",
+ .caps = "0,1,10",
.format = FMT_RAID,
- .read = lsi_read,
- .write = lsi_write,
- .group = lsi_group,
- .check = lsi_check,
- .events = &lsi_event_handlers,
+ .read = lsi_read,
+ .write = lsi_write,
+ .group = lsi_group,
+ .check = lsi_check,
+ .events = &lsi_event_handlers,
#ifdef DMRAID_NATIVE_LOG
- .log = lsi_log,
+ .log = lsi_log,
#endif
};
/* Register this format handler with the format core. */
-int register_lsi(struct lib_context *lc)
+int
+register_lsi(struct lib_context *lc)
{
return register_format_handler(lc, &lsi_format);
}
/* Set the RAID device contents up derived from the LSI ones */
-static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta, union read_info *info)
+static int
+setup_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct dev_info *di, void *meta, union read_info *info)
{
struct lsi *lsi = meta;
@@ -345,19 +363,19 @@
return 0;
rd->meta_areas->offset = LSI_CONFIGOFFSET >> 9;
- rd->meta_areas->size = sizeof(*lsi);
- rd->meta_areas->area = (void*) lsi;
+ rd->meta_areas->size = sizeof(*lsi);
+ rd->meta_areas->area = (void *) lsi;
- rd->di = di;
+ rd->di = di;
rd->fmt = &lsi_format;
rd->status = status(lsi);
- rd->type = type(lsi);
+ rd->type = type(lsi);
rd->offset = LSI_DATAOFFSET;
/* FIXME: propper size ? */
if (!(rd->sectors = rd->meta_areas->offset))
return log_zero_sectors(lc, di->path, handler);
- return (rd->name = name(lc, rd, 1)) ? 1 : 0;
+ return (rd->name = name(lc, rd, 1)) ? 1 : 0;
}
--- dmraid/lib/format/ataraid/lsi.h 2008/04/02 13:35:31 1.2
+++ dmraid/lib/format/ataraid/lsi.h 2008/06/20 21:52:17 1.3
@@ -36,21 +36,21 @@
#define LSI_MAGIC_NAME "$XIDE$"
#define LSI_MAGIC_NAME_LEN (sizeof(LSI_MAGIC_NAME) - 1)
uint8_t magic_name[LSI_MAGIC_NAME_LEN]; /* 0x0 - 0x05 */
- uint8_t dummy; /* 0x06 */
- uint8_t seqno; /* 0x07 */
- uint32_t dummy2; /* 0x08 - 0x0B */
- uint32_t dummy3; /* 0x0C - 0x0F */
- uint8_t type; /* 0x10 */
+ uint8_t dummy; /* 0x06 */
+ uint8_t seqno; /* 0x07 */
+ uint32_t dummy2; /* 0x08 - 0x0B */
+ uint32_t dummy3; /* 0x0C - 0x0F */
+ uint8_t type; /* 0x10 */
#define LSI_T_RAID0 1
#define LSI_T_RAID1 2
#define LSI_T_RAID10 3
uint8_t dummy4; /* 0x11 */
- uint16_t stride; /* 0x12 - 0x13 */
- uint8_t filler[0x20-0x14]; /* 0x14 - 0x1F */
+ uint16_t stride; /* 0x12 - 0x13 */
+ uint8_t filler[0x20 - 0x14]; /* 0x14 - 0x1F */
#define LSI_MAX_DISKS 4
- struct lsi_disk disks[LSI_MAX_DISKS];/* 0x20 - 0x5F */
+ struct lsi_disk disks[LSI_MAX_DISKS]; /* 0x20 - 0x5F */
#define LSI_DISK(lsi) (lsi->set_number * 2 + lsi->disk_number)
#define LSI_MAGIC_0(lsi) (lsi->disks[LSI_DISK(lsi)].magic_0)
@@ -59,13 +59,13 @@
#define LSI_SET_NUMBER(lsi) (lsi->disks[LSI_DISK(lsi)].set_number)
#undef LSI_DISK
- uint8_t filler1[0x1F0-0x60]; /* 0x70 - 0x1EF */
+ uint8_t filler1[0x1F0 - 0x60]; /* 0x70 - 0x1EF */
- uint8_t disk_number; /* 0x1F0 */
- uint8_t set_number; /* 0x1F1 */
- uint32_t set_id; /* 0x1F2 - 0x1F5 */
+ uint8_t disk_number; /* 0x1F0 */
+ uint8_t set_number; /* 0x1F1 */
+ uint32_t set_id; /* 0x1F2 - 0x1F5 */
- uint8_t filler2[0x200-0x1F6]; /* 0x1F6 - 0x200 */
+ uint8_t filler2[0x200 - 0x1F6]; /* 0x1F6 - 0x200 */
} __attribute__ ((packed));
#endif
--- dmraid/lib/format/ataraid/nv.c 2008/04/02 13:35:31 1.3
+++ dmraid/lib/format/ataraid/nv.c 2008/06/20 21:52:17 1.4
@@ -2,7 +2,8 @@
* NVidia NVRAID metadata format handler.
*
* Copyright (C) 2004 NVidia Corporation. All rights reserved.
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ *
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
* See file LICENSE at the top of this source tree for license information.
@@ -27,12 +28,14 @@
* The subset parameter indicates the requirement to create
* name suffixes in case the RAID set is hierarchical.
*/
-static unsigned int _subset(struct nv *nv)
+static unsigned int
+_subset(struct nv *nv)
{
return nv->unitNumber >= nv->array.stripeWidth;
}
-static size_t _name(struct nv *nv, char *str, size_t len, unsigned int subset)
+static size_t
+_name(struct nv *nv, char *str, size_t len, unsigned int subset)
{
unsigned int i = NV_SIGNATURES;
uint32_t sum = 0;
@@ -44,8 +47,8 @@
handler, sum, _subset(nv));
}
-static char *name(struct lib_context *lc, struct raid_dev *rd,
- unsigned int subset)
+static char *
+name(struct lib_context *lc, struct raid_dev *rd, unsigned int subset)
{
size_t len;
char *ret;
@@ -61,7 +64,8 @@
return ret;
}
-static enum status status(struct nv *nv)
+static enum status
+status(struct nv *nv)
{
static struct states states[] = {
{ NV_IDLE, s_ok },
@@ -77,7 +81,8 @@
}
/* Neutralize disk type using generic metadata type mapping function. */
-static enum type type(struct nv *nv)
+static enum type
+type(struct nv *nv)
{
uint8_t stripeWidth = nv->array.stripeWidth;
/* Mapping of nv types to generic types */
@@ -89,17 +94,17 @@
{ NV_LEVEL_1_0, t_raid0 },
{ NV_LEVEL_3, t_raid4 },
{ NV_LEVEL_5_SYM, t_raid5_ls },
- { NV_LEVEL_UNKNOWN, t_spare}, /* FIXME: UNKNOWN = spare ? */
+ { NV_LEVEL_UNKNOWN, t_spare }, /* FIXME: UNKNOWN = spare ? */
/* FIXME: The ones below don't really map to anything ?? */
{ NV_LEVEL_10, t_undef },
- { NV_LEVEL_5, t_undef }, /* Asymmetric RAID 5 is not used */
+ { NV_LEVEL_5, t_undef }, /* Asymmetric RAID 5 is not used */
};
/*
* FIXME: is there a direct way to decide what
- * a spare is (eg, NV_LEVEL_UNKNOWN) ?
+ * a spare is (eg, NV_LEVEL_UNKNOWN) ?
*/
- switch(NV_RAIDLEVEL(nv)) {
+ switch (NV_RAIDLEVEL(nv)) {
case NV_LEVEL_1_0:
case NV_LEVEL_10:
case NV_LEVEL_1:
@@ -109,27 +114,29 @@
case NV_LEVEL_5_SYM:
stripeWidth += 1;
break;
-
- default:
+
+ default:
break;
}
if (nv->array.totalVolumes >= stripeWidth &&
- nv->unitNumber >= stripeWidth)
+ nv->unitNumber >= stripeWidth)
return t_spare;
return rd_type(types, (unsigned int) NV_RAIDLEVEL(nv));
}
/* Decide about ordering sequence of RAID device. */
-static int dev_sort(struct list_head *pos, struct list_head *new)
+static int
+dev_sort(struct list_head *pos, struct list_head *new)
{
- return (META(RD(new), nv))->unitNumber <
- (META(RD(pos), nv))->unitNumber;
+ return META(RD(new), nv)->unitNumber <
+ META(RD(pos), nv)->unitNumber;
}
/* Decide about ordering sequence of RAID subset. */
-static int set_sort(struct list_head *pos, struct list_head *new)
+static int
+set_sort(struct list_head *pos, struct list_head *new)
{
return _subset((META(RD_RS(RS(new)), nv))) <
_subset((META(RD_RS(RS(pos)), nv)));
@@ -141,7 +148,8 @@
#if BYTE_ORDER == LITTLE_ENDIAN
# define to_cpu NULL
#else
-static void to_cpu(void *meta)
+static void
+to_cpu(void *meta)
{
struct nv *nv = meta;
unsigned int i = NV_SIGNATURES;
@@ -173,7 +181,8 @@
#endif
/* Check the metadata checksum. */
-static int checksum(struct nv *nv)
+static int
+checksum(struct nv *nv)
{
uint32_t sum = 0;
unsigned int s = nv->size;
@@ -181,18 +190,19 @@
if (s != sizeof(*nv) / sizeof(sum))
return 0;
- while (s--)
- sum += ((uint32_t*) nv)[s];
+ while (s--)
+ sum += ((uint32_t *) nv)[s];
/* Ignore chksum member itself. */
return nv->chksum - sum == nv->chksum;
}
-static int is_nv(struct lib_context *lc, struct dev_info *di, void *meta)
+static int
+is_nv(struct lib_context *lc, struct dev_info *di, void *meta)
{
struct nv *nv = meta;
- if (strncmp((char*) nv->vendor, NV_ID_STRING, sizeof(NV_ID_STRING) - 1))
+ if (strncmp((char *) nv->vendor, NV_ID_STRING, sizeof(NV_ID_STRING) -1))
return 0;
if (checksum(nv))
@@ -200,10 +210,11 @@
LOG_ERR(lc, 0, "%s: bad checksum on %s", handler, di->path);
}
-
+
static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
struct dev_info *di, void *meta, union read_info *info);
-static struct raid_dev *nv_read(struct lib_context *lc, struct dev_info *di)
+static struct raid_dev *
+nv_read(struct lib_context *lc, struct dev_info *di)
{
return read_raid_dev(lc, di, NULL,
sizeof(struct nv), NV_CONFIGOFFSET,
@@ -211,7 +222,8 @@
}
/* Write private RAID metadata to device */
-static int nv_write(struct lib_context *lc, struct raid_dev *rd, int erase)
+static int
+nv_write(struct lib_context *lc, struct raid_dev *rd, int erase)
{
int ret;
#if BYTE_ORDER != LITTLE_ENDIAN
@@ -226,15 +238,17 @@
return ret;
}
-static void super_created(struct raid_set *ss, void *private)
+static void
+super_created(struct raid_set *ss, void *private)
{
- ss->type = t_raid1;
+ ss->type = t_raid1;
ss->stride = META(private, nv)->array.stripeBlockSize;
}
/* FIXME: handle spares in mirrors and check that types are correct. */
-static int group_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_set **ss, struct raid_dev *rd)
+static int
+group_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_set **ss, struct raid_dev *rd)
{
struct nv *nv = META(rd, nv);
@@ -251,7 +265,6 @@
case NV_LEVEL_5_SYM:
if (!find_set(lc, NULL, rs->name, FIND_TOP))
list_add_tail(&rs->list, LC_RS(lc));
-
break;
case NV_LEVEL_1_0:
@@ -264,8 +277,8 @@
}
/* Add an NVidia RAID device to a set. */
-static struct raid_set *nv_group(struct lib_context *lc,
- struct raid_dev *rd)
+static struct raid_set *
+nv_group(struct lib_context *lc, struct raid_dev *rd)
{
struct raid_set *rs, *ss = NULL;
@@ -282,14 +295,16 @@
*
* FIXME: more sanity checks.
*/
-static unsigned int devices(struct raid_dev *rd, void *context)
+static unsigned int
+devices(struct raid_dev *rd, void *context)
{
struct nv *nv = META(rd, nv);
return nv->array.totalVolumes / (NVRAID_1_0(nv) ? 2 : 1);
}
-static int nv_check(struct lib_context *lc, struct raid_set *rs)
+static int
+nv_check(struct lib_context *lc, struct raid_set *rs)
{
return check_raid_set(lc, rs, devices, NULL,
NO_CHECK_RD, NULL, handler);
@@ -298,7 +313,8 @@
/*
* IO error event handler.
*/
-static int event_io(struct lib_context *lc, struct event_io *e_io)
+static int
+event_io(struct lib_context *lc, struct event_io *e_io)
{
struct raid_dev *rd = e_io->rd;
struct nv *nv = META(rd, nv);
@@ -315,14 +331,15 @@
static struct event_handlers nv_event_handlers = {
.io = event_io,
- .rd = NULL, /* FIXME: no device add/remove event handler yet. */
+ .rd = NULL, /* FIXME: no device add/remove event handler yet. */
};
#ifdef DMRAID_NATIVE_LOG
/*
* Log native information about the RAID device.
*/
-static void nv_log(struct lib_context *lc, struct raid_dev *rd)
+static void
+nv_log(struct lib_context *lc, struct raid_dev *rd)
{
unsigned int i, j;
#define LEN NV_PRODUCTIDS + 1
@@ -379,29 +396,31 @@
#endif
static struct dmraid_format nv_format = {
- .name = HANDLER,
- .descr = "NVidia RAID",
- .caps = "S,0,1,10,5",
+ .name = HANDLER,
+ .descr = "NVidia RAID",
+ .caps = "S,0,1,10,5",
.format = FMT_RAID,
- .read = nv_read,
- .write = nv_write,
- .group = nv_group,
- .check = nv_check,
- .events = &nv_event_handlers,
+ .read = nv_read,
+ .write = nv_write,
+ .group = nv_group,
+ .check = nv_check,
+ .events = &nv_event_handlers,
#ifdef DMRAID_NATIVE_LOG
- .log = nv_log,
+ .log = nv_log,
#endif
};
/* Register this format handler with the format core. */
-int register_nv(struct lib_context *lc)
+int
+register_nv(struct lib_context *lc)
{
return register_format_handler(lc, &nv_format);
}
/* Set the RAID device contents up derived from the NV ones */
-static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta, union read_info *info)
+static int
+setup_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct dev_info *di, void *meta, union read_info *info)
{
struct nv *nv = meta;
@@ -410,17 +429,17 @@
rd->meta_areas->offset = NV_CONFIGOFFSET >> 9;
rd->meta_areas->size = sizeof(*nv);
- rd->meta_areas->area = (void*) nv;
+ rd->meta_areas->area = (void *) nv;
- rd->di = di;
+ rd->di = di;
rd->fmt = &nv_format;
rd->status = status(nv);
- rd->type = type(nv);
+ rd->type = type(nv);
rd->offset = NV_DATAOFFSET;
if (!(rd->sectors = rd->meta_areas->offset))
return log_zero_sectors(lc, di->path, handler);
- return (rd->name = name(lc, rd, 1)) ? 1 : 0;
+ return (rd->name = name(lc, rd, 1)) ? 1 : 0;
}
--- dmraid/lib/format/ataraid/nv.h 2008/02/22 16:57:36 1.1
+++ dmraid/lib/format/ataraid/nv.h 2008/06/20 21:52:17 1.2
@@ -28,29 +28,29 @@
#define NV_ID_LENGTH 8
#define NV_ID_STRING "NVIDIA"
-#define NV_VERSION 100
+#define NV_VERSION 100
#define NV_SECTOR_SIZE 512
-#define NV_PRODUCT_ID_LEN 16 /* Product ID size in bytes */
+#define NV_PRODUCT_ID_LEN 16 /* Product ID size in bytes */
typedef uint32_t lba_t;
/* Array info */
struct nv_array_base {
uint32_t version; /* Version of this struct */
- /* 0x640000 + sizeof(nv_array_base) */
+ /* 0x640000 + sizeof(nv_array_base) */
#define NV_SIGNATURES 4
- uint32_t signature[NV_SIGNATURES]; /* Unique signature for array */
+ uint32_t signature[NV_SIGNATURES]; /* Unique signature for array */
- uint8_t raidJobCode; /* State of array */
+ uint8_t raidJobCode; /* State of array */
#define NV_IDLE 0
#define NV_SCDB_INIT_RAID 2
#define NV_SCDB_REBUILD_RAID 3
#define NV_SCDB_UPGRADE_RAID 4
#define NV_SCDB_SYNC_RAID 5
- uint8_t stripeWidth; /* Array stripe width */
- uint8_t totalVolumes; /* Total # of disks in array, including spare */
- uint8_t originalWidth; /* Stripe width before morph */
+ uint8_t stripeWidth; /* Array stripe width */
+ uint8_t totalVolumes; /* Total # of disks in array, including spare */
+ uint8_t originalWidth; /* Stripe width before morph */
uint32_t raidLevel; /* Array RAID level */
#define NV_RAIDLEVEL(nv) ((nv)->array.raidLevel)
@@ -66,45 +66,45 @@
#define NV_LEVEL_5_SYM_FLAG 0x10
#define NV_LEVEL_5_SYM (NV_LEVEL_5|NV_LEVEL_5_SYM_FLAG)
- lba_t stripeBlockSize; /* Array stripe block size in sectors */
+ lba_t stripeBlockSize; /* Array stripe block size in sectors */
uint32_t stripeBlockByteSize; /* stripeBlockSize in bytes */
uint32_t stripeBlockPower; /* Array stripe block size in log2 */
- lba_t stripeMask; /* stripeBlockSize - 1 */
- lba_t stripeSize; /* stripeBlockSize * stripeWidth */
+ lba_t stripeMask; /* stripeBlockSize - 1 */
+ lba_t stripeSize; /* stripeBlockSize * stripeWidth */
uint32_t stripeByteSize; /* stripeSize in bytes */
- lba_t raidJobMark; /* Ignored if array is idle, otherwise the */
- /* LBA where job is finished */
+ lba_t raidJobMark; /* Ignored if array is idle, otherwise the */
+ /* LBA where job is finished */
uint32_t originalLevel; /* RAID level before morph */
- lba_t originalCapacity; /* Array capacity before morph */
+ lba_t originalCapacity; /* Array capacity before morph */
uint32_t flags; /* Flags for array */
-#define NV_ARRAY_FLAG_BOOT (0x00000001) /* BIOS use only */
-#define NV_ARRAY_FLAG_ERROR (0x00000002) /* Degraded or offling */
-#define NV_ARRAY_FLAG_PARITY_VALID (0x00000004) /* RAID-3/5 parity valid */
+#define NV_ARRAY_FLAG_BOOT (0x00000001) /* BIOS use only */
+#define NV_ARRAY_FLAG_ERROR (0x00000002) /* Degraded or offling */
+#define NV_ARRAY_FLAG_PARITY_VALID (0x00000004) /* RAID-3/5 parity valid */
#define NV_BROKEN(n) (n->array.flags & NV_ARRAY_FLAG_ERROR)
#define NV_SET_BROKEN(n) (n->array.flags |= NV_ARRAY_FLAG_ERROR)
} __attribute__ ((packed));
/* Ondisk metadata */
struct nv {
- uint8_t vendor[NV_ID_LENGTH]; /* 0x00 - 0x07 ID string */
+ uint8_t vendor[NV_ID_LENGTH]; /* 0x00 - 0x07 ID string */
uint32_t size; /* 0x08 - 0x0B Size of metadata in dwords */
uint32_t chksum; /* 0x0C - 0x0F Checksum of this struct */
uint16_t version; /* 0x10 - 0x11 NV version */
- uint8_t unitNumber; /* 0x12 Disk index in array */
- uint8_t reserved; /* 0x13 */
- lba_t capacity; /* 0x14 - 0x17 Array capacity in sectors */
+ uint8_t unitNumber; /* 0x12 Disk index in array */
+ uint8_t reserved; /* 0x13 */
+ lba_t capacity; /* 0x14 - 0x17 Array capacity in sectors */
uint32_t sectorSize; /* 0x18 - 0x1B Sector size */
#define NV_PRODUCTIDS 16
- /* 0x1C - 0x2B Array product ID */
- uint8_t productID[NV_PRODUCTIDS];
- /* Match INQUIRY data */
+ /* 0x1C - 0x2B Array product ID */
+ uint8_t productID[NV_PRODUCTIDS];
+ /* Match INQUIRY data */
#define NV_PRODUCTREVISIONS 4
- /* 0x2C - 0x2F Array product revision */
- uint8_t productRevision[NV_PRODUCTREVISIONS];
- /* Match INQUIRY data */
+ /* 0x2C - 0x2F Array product revision */
+ uint8_t productRevision[NV_PRODUCTREVISIONS];
+ /* Match INQUIRY data */
uint32_t unitFlags; /* 0x30 - 0x33 Flags for this disk */
- struct nv_array_base array; /* Array information */
+ struct nv_array_base array; /* Array information */
} __attribute__ ((packed));
#endif
--- dmraid/lib/format/ataraid/pdc.c 2008/04/02 13:35:31 1.4
+++ dmraid/lib/format/ataraid/pdc.c 2008/06/20 21:52:17 1.5
@@ -27,19 +27,21 @@
/*
* Make up Promise RAID device name.
*/
-static unsigned set_number(struct pdc *pdc)
+static unsigned
+set_number(struct pdc *pdc)
{
return pdc->raid.disk_number >= (pdc->raid.total_disks / 2);
}
-static size_t __name(struct pdc *pdc, char *str, size_t len, int subset)
+static size_t
+__name(struct pdc *pdc, char *str, size_t len, int subset)
{
return snprintf(str, len, subset ? "pdc_%u-%u" : "pdc_%u",
pdc->raid.magic_1, set_number(pdc));
}
-static char *_name(struct lib_context *lc, struct pdc *pdc,
- unsigned subset)
+static char *
+_name(struct lib_context *lc, struct pdc *pdc, unsigned subset)
{
size_t len;
char *ret = NULL;
@@ -54,8 +56,8 @@
return ret;
}
-static char *name(struct lib_context *lc, struct raid_dev *rd,
- unsigned subset)
+static char *
+name(struct lib_context *lc, struct raid_dev *rd, unsigned subset)
{
return _name(lc, META(rd, pdc), subset);
}
@@ -65,28 +67,31 @@
*
* FIXME: need to identify state definitions.
*/
-static enum status status(struct pdc *pdc)
+static enum status
+status(struct pdc *pdc)
{
return PDC_BROKEN(pdc) ? s_broken : s_ok;
}
#define PDC_T_RAID10 0x2 /* Not defind by Promise (yet). */
-static int is_raid10(struct pdc *pdc)
+static int
+is_raid10(struct pdc *pdc)
{
return pdc->raid.type == PDC_T_RAID10 ||
(pdc->raid.type == PDC_T_RAID1 && pdc->raid.total_disks > 3);
}
/* Neutralize disk type */
-static enum type type(struct pdc *pdc)
+static enum type
+type(struct pdc *pdc)
{
/* Mapping of Promise types to generic types. */
static struct types types[] = {
- { PDC_T_SPAN, t_linear},
- { PDC_T_RAID0, t_raid0},
- { PDC_T_RAID1, t_raid1},
- { PDC_T_RAID10, t_raid0},
- { 0, t_undef}
+ { PDC_T_SPAN, t_linear },
+ { PDC_T_RAID0, t_raid0 },
+ { PDC_T_RAID1, t_raid1 },
+ { PDC_T_RAID10, t_raid0 },
+ { 0, t_undef }
};
if (is_raid10(pdc))
@@ -96,10 +101,11 @@
}
/* Calculate checksum on Promise metadata. */
-static uint32_t checksum(struct pdc *pdc)
+static uint32_t
+checksum(struct pdc *pdc)
{
unsigned i = 511, sum = 0;
- uint32_t *p = (uint32_t*) pdc;
+ uint32_t *p = (uint32_t *) pdc;
while (i--)
sum += *p++;
@@ -115,7 +121,8 @@
#if BYTE_ORDER == LITTLE_ENDIAN
# define to_cpu NULL
#else
-static void to_cpu(void *meta)
+static void
+to_cpu(void *meta)
{
struct pdc *pdc = meta;
struct pdc_disk *disk;
@@ -130,8 +137,7 @@
CVT32(pdc->raid.magic_1);
for (disk = pdc->raid.disk;
- disk < pdc->raid.disk + pdc->raid.total_disks;
- disk++) {
+ disk < pdc->raid.disk + pdc->raid.total_disks; disk++) {
CVT32(disk->magic_0);
CVT32(disk->disk_number);
}
@@ -139,16 +145,17 @@
#endif
/* Check for Promis signature. */
-static int is_signature(struct pdc *pdc)
+static int
+is_signature(struct pdc *pdc)
{
- return !strncmp((const char*) pdc->promise_id,
+ return !strncmp((const char *) pdc->promise_id,
PDC_MAGIC, PDC_ID_LENGTH);
}
/* Read and try to discover Promise signature. */
-static void *pdc_read_metadata(struct lib_context *lc, struct dev_info *di,
- size_t *size, uint64_t *offset,
- union read_info *info)
+static void *
+pdc_read_metadata(struct lib_context *lc, struct dev_info *di,
+ size_t * size, uint64_t * offset, union read_info *info)
{
struct pdc *ret;
unsigned ma, sub;
@@ -175,7 +182,7 @@
/* Check all sector offsets for metadata signature. */
for (; *s && !info->u32; s++) {
sector = sub ? di->sectors - *s : *s;
-
+
/* ...and all possible optional metadata signatures. */
for (ma = 0;
ma < PDC_MAX_META_AREAS &&
@@ -203,7 +210,7 @@
s = begin_sectors;
} while (!info->u32 && sub--);
- out:
+ out:
/* No metadata signature(s) found. */
if (!info->u32) {
dbg_free(ret);
@@ -214,7 +221,8 @@
}
/* Magic check. */
-static int is_pdc(struct lib_context *lc, struct dev_info *di, void *meta)
+static int
+is_pdc(struct lib_context *lc, struct dev_info *di, void *meta)
{
struct pdc *pdc = meta;
@@ -226,7 +234,6 @@
pdc->raid.total_disks < PDC_MAXDISKS)
return 1;
-
LOG_ERR(lc, 0, "%s: identifying %s, magic_0: 0x%x/0x%x, "
"magic_1: 0x%x/0x%x, total_disks: %u",
handler, di->path,
@@ -236,8 +243,9 @@
static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
struct dev_info *di, void *meta, union read_info *info);
-static struct raid_dev *pdc_read(struct lib_context *lc, struct dev_info *di)
-{
+static struct raid_dev *
+pdc_read(struct lib_context *lc, struct dev_info *di)
+{
return read_raid_dev(lc, di, pdc_read_metadata, 0, 0, to_cpu, is_pdc,
NULL, setup_rd, handler);
}
@@ -245,7 +253,8 @@
/*
* Write a Promise FastTrak RAID device.
*/
-static int pdc_write(struct lib_context *lc, struct raid_dev *rd, int erase)
+static int
+pdc_write(struct lib_context *lc, struct raid_dev *rd, int erase)
{
int ret;
#if BYTE_ORDER != LITTLE_ENDIAN
@@ -261,14 +270,16 @@
}
/* Decide about ordering sequence of RAID device. */
-static int dev_sort(struct list_head *pos, struct list_head *new)
+static int
+dev_sort(struct list_head *pos, struct list_head *new)
{
- return (META(RD(new), pdc))->raid.disk_number <
- (META(RD(pos), pdc))->raid.disk_number;
+ return META(RD(new), pdc)->raid.disk_number <
+ META(RD(pos), pdc)->raid.disk_number;
}
/* Decide about ordering sequence of RAID subset. */
-static int set_sort(struct list_head *pos, struct list_head *new)
+static int
+set_sort(struct list_head *pos, struct list_head *new)
{
return !set_number(META(RD_RS(RS(new)), pdc));
}
@@ -276,46 +287,49 @@
/*
* Group the RAID disk into a Promise set.
*/
-static unsigned stride(struct pdc *pdc)
+static unsigned
+stride(struct pdc *pdc)
{
- return pdc->raid.raid0_shift ? 1 << pdc->raid.raid0_shift : 0;
+ return pdc->raid.raid0_shift ? (1 << pdc->raid.raid0_shift) : 0;
}
-static void super_created(struct raid_set *super, void *private)
+static void
+super_created(struct raid_set *super, void *private)
{
- super->type = t_raid1;
+ super->type = t_raid1;
super->stride = stride(META((private), pdc));
}
/* Calculate RAID device size in sectors depending on RAID type. */
-static uint64_t sectors(struct raid_dev *rd, unsigned meta_sector)
+static uint64_t
+sectors(struct raid_dev *rd, unsigned meta_sector)
{
struct pdc *pdc = META(rd, pdc);
switch (pdc->raid.type) {
case PDC_T_RAID10:
- return pdc->raid.total_secs / (pdc->raid.total_disks / 2);
+ return pdc->raid.total_secs / (pdc->raid.total_disks / 2);
case PDC_T_RAID1:
- return pdc->raid.total_secs;
+ return pdc->raid.total_secs;
case PDC_T_RAID0:
- return pdc->raid.total_secs / pdc->raid.total_disks;
+ return pdc->raid.total_secs / pdc->raid.total_disks;
case PDC_T_SPAN:
- return rd->di->sectors - meta_sector;
+ return rd->di->sectors - meta_sector;
}
return 0;
}
-static struct raid_dev *_create_rd(struct lib_context *lc, struct raid_dev *rd,
- struct pdc *pdc, unsigned idx)
+static struct raid_dev *
+_create_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct pdc *pdc, unsigned idx)
{
struct raid_dev *r;
- if (!is_pdc(lc, rd->di, pdc) ||
- !(r = alloc_raid_dev(lc, handler)))
+ if (!is_pdc(lc, rd->di, pdc) || !(r = alloc_raid_dev(lc, handler)))
return NULL;
if ((r->type = type(pdc)) == t_undef) {
@@ -324,7 +338,7 @@
goto bad_free;
}
- if (!(r->name = _name(lc, pdc, is_raid10(pdc))))
+ if (!(r->name = _name(lc, pdc, is_raid10(pdc))))
goto bad_free;
/* Allocate meta_areas for devices() to work. */
@@ -356,15 +370,16 @@
log_zero_sectors(lc, r->di->path, handler);
- bad_free:
+ bad_free:
free_raid_dev(lc, &r);
- out:
+ out:
return r;
}
/* Add a PDC RAID device to a set. */
-static int _group_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_set **ss, struct raid_dev *rd, struct pdc *pdc)
+static int
+_group_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_set **ss, struct raid_dev *rd, struct pdc *pdc)
{
if (!init_raid_set(lc, rs, rd, stride(pdc), pdc->raid.type, handler))
return 0;
@@ -396,7 +411,8 @@
return 1;
}
-static inline unsigned count_meta_areas(struct pdc *pdc)
+static inline unsigned
+count_meta_areas(struct pdc *pdc)
{
unsigned r;
@@ -410,8 +426,9 @@
}
/* FIXME: different super sets possible with multiple metadata areas ? */
-static int group_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_set **ss, struct raid_dev *rd)
+static int
+group_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_set **ss, struct raid_dev *rd)
{
int r;
struct pdc *pdc = META(rd, pdc);
@@ -442,7 +459,8 @@
return r;
}
-static struct raid_set *pdc_group(struct lib_context *lc, struct raid_dev *rd)
+static struct raid_set *
+pdc_group(struct lib_context *lc, struct raid_dev *rd)
{
struct raid_set *rs, *ss = NULL;
@@ -461,23 +479,26 @@
*
* FIXME: more sanity checks.
*/
-static unsigned devices(struct raid_dev *rd, void *context)
+static unsigned
+devices(struct raid_dev *rd, void *context)
{
struct pdc *pdc = META(rd, pdc);
if (context && pdc->raid.type != PDC_T_SPAN)
- *((uint64_t*) context) += rd->sectors;
+ *((uint64_t *) context) += rd->sectors;
return pdc->raid.total_disks;
}
-static int check_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_dev *rd, void *context)
+static int
+check_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_dev *rd, void *context)
{
- return *((uint64_t*) context) >= (META(rd, pdc))->raid.total_secs;
+ return *((uint64_t *) context) >= (META(rd, pdc))->raid.total_secs;
}
-static int pdc_check(struct lib_context *lc, struct raid_set *rs)
+static int
+pdc_check(struct lib_context *lc, struct raid_set *rs)
{
uint64_t total_secs = 0;
@@ -494,7 +515,8 @@
/*
* IO error event handler.
*/
-static int event_io(struct lib_context *lc, struct event_io *e_io)
+static int
+event_io(struct lib_context *lc, struct event_io *e_io)
{
struct raid_dev *rd = e_io->rd;
struct pdc *pdc = META(rd, pdc);
@@ -504,19 +526,18 @@
return 0;
PDC_SET_BROKEN(pdc);
-
return 1;
}
static struct event_handlers pdc_event_handlers = {
.io = event_io,
- .rd = NULL, /* FIXME: no device add/remove event handler yet. */
+ .rd = NULL, /* FIXME: no device add/remove event handler yet. */
};
#ifdef DMRAID_NATIVE_LOG
/* Log native information about a Promise RAID device. */
-static void _pdc_log(struct lib_context *lc, struct dev_info *di,
- struct pdc *pdc)
+static void
+_pdc_log(struct lib_context *lc, struct dev_info *di, struct pdc *pdc)
{
unsigned i;
struct pdc_disk *disk;
@@ -539,7 +560,7 @@
DP("raid.device: %u", pdc, pdc->raid.device);
DP("raid.magic_0: 0x%x", pdc, pdc->raid.magic_0);
P("raid.unknown_1: 0x%x %u",
- pdc, pdc->raid.unknown_1, pdc->raid.unknown_1, pdc->raid.unknown_1);
+ pdc, pdc->raid.unknown_1, pdc->raid.unknown_1, pdc->raid.unknown_1);
P("raid.start: 0x%x %u",
pdc, pdc->raid.start, pdc->raid.start, pdc->raid.start);
DP("raid.disk_secs: %u", pdc, pdc->raid.disk_secs);
@@ -562,8 +583,7 @@
pdc, pdc->raid.unknown_5, pdc->raid.unknown_5, pdc->raid.unknown_5);
for (disk = pdc->raid.disk, i = 0;
- i < pdc->raid.total_disks;
- disk++, i++) {
+ i < pdc->raid.total_disks; disk++, i++) {
P2("raid.disk[%d].unknown_0: 0x%x", pdc, i, disk->unknown_0);
P2("raid.disk[%d].channel: %u", pdc, i, disk->channel);
P2("raid.disk[%d].device: %u", pdc, i, disk->device);
@@ -572,39 +592,42 @@
}
P("checksum: 0x%x %s", pdc, pdc->checksum, pdc->checksum,
- checksum(pdc) ? "Ok" : "BAD");
+ checksum(pdc) ? "Ok" : "BAD");
}
-static void pdc_log(struct lib_context *lc, struct raid_dev *rd)
+static void
+pdc_log(struct lib_context *lc, struct raid_dev *rd)
{
_pdc_log(lc, rd->di, META(rd, pdc));
}
#endif
static struct dmraid_format pdc_format = {
- .name = HANDLER,
- .descr = "Promise FastTrack",
- .caps = "S,0,1,10",
+ .name = HANDLER,
+ .descr = "Promise FastTrack",
+ .caps = "S,0,1,10",
.format = FMT_RAID,
- .read = pdc_read,
- .write = pdc_write,
- .group = pdc_group,
- .check = pdc_check,
- .events = &pdc_event_handlers,
+ .read = pdc_read,
+ .write = pdc_write,
+ .group = pdc_group,
+ .check = pdc_check,
+ .events = &pdc_event_handlers,
#ifdef DMRAID_NATIVE_LOG
- .log = pdc_log,
+ .log = pdc_log,
#endif
};
/* Register this format handler with the format core. */
-int register_pdc(struct lib_context *lc)
+int
+register_pdc(struct lib_context *lc)
{
return register_format_handler(lc, &pdc_format);
}
/* Set the RAID device contents up derived from the PDC ones */
-static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta, union read_info *info)
+static int
+setup_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct dev_info *di, void *meta, union read_info *info)
{
unsigned meta_sector;
struct pdc *pdc = meta;
@@ -620,7 +643,7 @@
rd->meta_areas->size = sizeof(*pdc);
rd->meta_areas->area = pdc;
- rd->di = di;
+ rd->di = di;
rd->fmt = &pdc_format;
rd->status = status(pdc);
@@ -634,5 +657,5 @@
if (!(rd->sectors = sectors(rd, meta_sector)))
return log_zero_sectors(lc, di->path, handler);
- return (rd->name = _name(lc, pdc, is_raid10(pdc))) ? 1 : 0;
+ return (rd->name = _name(lc, pdc, is_raid10(pdc))) ? 1 : 0;
}
--- dmraid/lib/format/ataraid/pdc.h 2008/04/02 13:35:31 1.2
+++ dmraid/lib/format/ataraid/pdc.h 2008/06/20 21:52:17 1.3
@@ -29,54 +29,54 @@
uint8_t promise_id[PDC_ID_LENGTH]; /* 0x00 - 0x17 */
#define PDC_MAGIC "Promise Technology, Inc."
- uint32_t unknown_0; /* 0x18 - 0x1B */
- uint32_t magic_0; /* 0x1C - 0x1F */
- uint32_t unknown_1; /* 0x20 - 0x23 */
- uint32_t magic_1; /* 0x24 - 0x27 */
- uint16_t unknown_2; /* 0x28 - 0x2B */
- uint8_t filler1[470]; /* 0x2C - 0x1FF */
+ uint32_t unknown_0; /* 0x18 - 0x1B */
+ uint32_t magic_0; /* 0x1C - 0x1F */
+ uint32_t unknown_1; /* 0x20 - 0x23 */
+ uint32_t magic_1; /* 0x24 - 0x27 */
+ uint16_t unknown_2; /* 0x28 - 0x2B */
+ uint8_t filler1[470]; /* 0x2C - 0x1FF */
struct {
- uint32_t flags; /* 0x200 - 0x203 */
- uint8_t unknown_0; /* 0x204 */
- uint8_t disk_number; /* 0x205 */
- uint8_t channel; /* 0x206 */
- uint8_t device; /* 0x207 */
- uint32_t magic_0; /* 0x208 - 0x20B */
- uint32_t unknown_1; /* 0x20C - 0x20F */
- // uint32_t unknown_2; /* 0x210 - 0x213 */
- uint32_t start; /* 0x210 - 0x213 */
- uint32_t disk_secs; /* 0x214 - 0x217 */
- uint32_t unknown_3; /* 0x218 - 0x21B */
- uint16_t unknown_4; /* 0x21C - 0x21D */
- uint8_t status; /* 0x21E */
+ uint32_t flags; /* 0x200 - 0x203 */
+ uint8_t unknown_0; /* 0x204 */
+ uint8_t disk_number; /* 0x205 */
+ uint8_t channel; /* 0x206 */
+ uint8_t device; /* 0x207 */
+ uint32_t magic_0; /* 0x208 - 0x20B */
+ uint32_t unknown_1; /* 0x20C - 0x20F */
+ // uint32_t unknown_2; /* 0x210 - 0x213 */
+ uint32_t start; /* 0x210 - 0x213 */
+ uint32_t disk_secs; /* 0x214 - 0x217 */
+ uint32_t unknown_3; /* 0x218 - 0x21B */
+ uint16_t unknown_4; /* 0x21C - 0x21D */
+ uint8_t status; /* 0x21E */
/* FIXME: bit 0x80 doesn't seem to indicate error as previously assumed. */
-// #define PDC_BROKEN(pdc) ((pdc)->raid.status & 0x80)
+// #define PDC_BROKEN(pdc) ((pdc)->raid.status & 0x80)
#define PDC_BROKEN(pdc) ((pdc)->raid.status & 0x00)
#define PDC_SET_BROKEN(pdc) ((pdc)->raid.status |= 0x80)
- uint8_t type; /* 0x21F */
+ uint8_t type; /* 0x21F */
#define PDC_T_RAID0 0x0
#define PDC_T_RAID1 0x1
#define PDC_T_SPAN 0x8
- uint8_t total_disks; /* 0x220 */
- uint8_t raid0_shift; /* 0x221 */
- uint8_t raid0_disks; /* 0x222 */
- uint8_t array_number; /* 0x223 */
- uint32_t total_secs; /* 0x224 - 0x227 */
- uint16_t cylinders; /* 0x228 - 0x229 */
- uint8_t heads; /* 0x22A */
- uint8_t sectors; /* 0x22B */
- uint32_t magic_1; /* 0x22C - 0x2EF */
- uint32_t unknown_5; /* 0x230 - 0x233 */
+ uint8_t total_disks; /* 0x220 */
+ uint8_t raid0_shift; /* 0x221 */
+ uint8_t raid0_disks; /* 0x222 */
+ uint8_t array_number; /* 0x223 */
+ uint32_t total_secs; /* 0x224 - 0x227 */
+ uint16_t cylinders; /* 0x228 - 0x229 */
+ uint8_t heads; /* 0x22A */
+ uint8_t sectors; /* 0x22B */
+ uint32_t magic_1; /* 0x22C - 0x2EF */
+ uint32_t unknown_5; /* 0x230 - 0x233 */
struct pdc_disk {
uint16_t unknown_0; /* 0x234 - 0x235 */
uint8_t channel; /* 0x236 */
- uint8_t device; /* 0x237 */
+ uint8_t device; /* 0x237 */
uint32_t magic_0; /* 0x238 - 0x23B */
uint32_t disk_number; /* 0x23C - 0x23F */
} disk[8];
} raid;
- uint32_t filler2[346]; /* 0x294 - */
+ uint32_t filler2[346]; /* 0x294 - */
uint32_t checksum;
} __attribute__ ((packed));
--- dmraid/lib/format/ataraid/sil.c 2008/02/22 17:04:35 1.2
+++ dmraid/lib/format/ataraid/sil.c 2008/06/20 21:52:17 1.3
@@ -22,19 +22,20 @@
/* Make up RAID device name from some 'magic' numbers */
/* FIXME: better name ? */
-static size_t _name(struct sil *sil, char *str, size_t len, unsigned int subset)
+static size_t
+_name(struct sil *sil, char *str, size_t len, unsigned int subset)
{
return snprintf(str, len,
subset ? "sil_%02u%02u%02u%02u%02u%02u-%u" :
- "sil_%02u%02u%02u%02u%02u%02u",
+ "sil_%02u%02u%02u%02u%02u%02u",
sil->year, sil->month, sil->day,
sil->hour, sil->minutes % 60, sil->seconds % 60,
sil->type == SIL_T_RAID1 ? sil->mirrored_set_number :
- sil->striped_set_number);
+ sil->striped_set_number);
}
-static char *name(struct lib_context *lc, struct raid_dev *rd,
- unsigned int subset)
+static char *
+name(struct lib_context *lc, struct raid_dev *rd, unsigned int subset)
{
size_t len;
char *ret;
@@ -45,7 +46,8 @@
_name(sil, ret, len, subset);
mk_alpha(lc, ret + HANDLER_LEN, len - HANDLER_LEN -
(strrchr(ret, '-') ? 3 : 1));
- } else
+ }
+ else
log_alloc_err(lc, handler);
return ret;
@@ -55,43 +57,46 @@
* Retrieve status of device.
* FIXME: is this sufficient to cover all state ?
*/
-static enum status status(struct sil *sil)
+static enum status
+status(struct sil *sil)
{
struct states states[] = {
- { SIL_OK, s_ok },
- { SIL_MIRROR_SYNC, s_ok },
- { SIL_MIRROR_NOSYNC, s_nosync },
- { 0, s_broken },
+ {SIL_OK, s_ok},
+ {SIL_MIRROR_SYNC, s_ok},
+ {SIL_MIRROR_NOSYNC, s_nosync},
+ {0, s_broken},
};
return rd_status(states, sil->mirrored_set_state, EQUAL);
}
/* Neutralize disk type */
-static enum type type(struct sil *sil)
+static enum type
+type(struct sil *sil)
{
/* Mapping of SIL 680 types to generic types */
static struct types types[] = {
- { SIL_T_SPARE, t_spare},
- { SIL_T_JBOD, t_linear},
- { SIL_T_RAID0, t_raid0},
- { SIL_T_RAID5, t_raid5_ls},
- { SIL_T_RAID1, t_raid1},
- { SIL_T_RAID10, t_raid0},
- { 0, t_undef}
+ {SIL_T_SPARE, t_spare},
+ {SIL_T_JBOD, t_linear},
+ {SIL_T_RAID0, t_raid0},
+ {SIL_T_RAID5, t_raid5_ls},
+ {SIL_T_RAID1, t_raid1},
+ {SIL_T_RAID10, t_raid0},
+ {0, t_undef}
};
return rd_type(types, (unsigned int) sil->type);
}
/* Calculate checksum on metadata */
-static int checksum(struct sil *sil)
+static int
+checksum(struct sil *sil)
{
int sum = 0;
- unsigned int count = struct_offset(sil, checksum1) / 2;
- uint16_t *p = (uint16_t*) sil;
+ unsigned short count = struct_offset(sil, checksum1) / 2;
+ uint16_t *p = (uint16_t *) sil;
- while (count--)
+ while (count--)
sum += *p++;
return (-sum & 0xFFFF) == sil->checksum1;
@@ -104,7 +109,8 @@
#if BYTE_ORDER == LITTLE_ENDIAN
# define to_cpu NULL
#else
-static void to_cpu(void *meta)
+static void
+to_cpu(void *meta)
{
struct sil *sil = meta;
@@ -128,13 +134,15 @@
#define AREAS 4
#define SIL_META_AREA(i) (SIL_CONFIGOFFSET - (i * 512 << 9))
-static inline int is_sil(struct sil *sil)
+static inline int
+is_sil(struct sil *sil)
{
return SIL_MAGIC_OK(sil) && sil->disk_number < 8;
}
-static int sil_valid(struct lib_context *lc, struct dev_info *di,
- void *meta, unsigned int area)
+static int
+sil_valid(struct lib_context *lc, struct dev_info *di,
+ void *meta, unsigned int area)
{
struct sil *sil = meta;
@@ -158,7 +166,8 @@
return 1;
}
-static void free_sils(struct sil **sils, unsigned int i)
+static void
+free_sils(struct sil **sils, unsigned int i)
{
for (; i < AREAS; i++)
dbg_free(sils[i]);
@@ -166,9 +175,9 @@
dbg_free(sils);
}
-static void *sil_read_metadata(struct lib_context *lc, struct dev_info *di,
- size_t *size, uint64_t *offset,
- union read_info *info)
+static void *
+sil_read_metadata(struct lib_context *lc, struct dev_info *di,
+ size_t * size, uint64_t * offset, union read_info *info)
{
unsigned int i, valid;
char str[9] = { 0, };
@@ -190,8 +199,9 @@
if (sil_valid(lc, di, sil, i + 1)) {
sils[valid] = sil;
sprintf(&str[strlen(str)], "%s%u",
- valid++ ? "," : "", i + 1);
- } else
+ valid++ ? "," : "", i + 1);
+ }
+ else
dbg_free(sil);
}
@@ -201,21 +211,23 @@
valid == 1 ? "is" : "are");
goto out;
}
-
- bad:
+
+ bad:
free_sils(sils, 0);
sils = NULL;
- out:
- return (void*) sils;
+ out:
+ return (void *) sils;
}
-static int _file_name(char *str, size_t len, char *n, int i)
+static int
+_file_name(char *str, size_t len, char *n, int i)
{
return snprintf(str, len, "%s_%d", n, i) + 1;
}
-static char *file_name(struct lib_context *lc, char *n, int i)
+static char *
+file_name(struct lib_context *lc, char *n, int i)
{
size_t len;
char *ret;
@@ -229,13 +241,13 @@
}
/* File all metadata areas. */
-static void sil_file_metadata(struct lib_context *lc, struct dev_info *di,
- void *meta)
+static void
+sil_file_metadata(struct lib_context *lc, struct dev_info *di, void *meta)
{
unsigned int i;
char *n;
struct sil **sils = meta;
-
+
for (i = 0; i < AREAS; i++) {
if (!(n = file_name(lc, di->path, i)))
break;
@@ -250,7 +262,8 @@
static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
struct dev_info *di, void *meta, union read_info *info);
-static struct raid_dev *sil_read(struct lib_context *lc, struct dev_info *di)
+static struct raid_dev *
+sil_read(struct lib_context *lc, struct dev_info *di)
{
return read_raid_dev(lc, di, sil_read_metadata, 0, 0, NULL, NULL,
sil_file_metadata, setup_rd, handler);
@@ -260,7 +273,8 @@
/*
* Write a Silicon Image RAID device.
*/
-static int sil_write(struct lib_context *lc, struct raid_dev *rd, int erase)
+static int
+sil_write(struct lib_context *lc, struct raid_dev *rd, int erase)
{
int ret;
#if BYTE_ORDER != LITTLE_ENDIAN
@@ -276,17 +290,19 @@
}
/* Decide about ordering sequence of RAID device. */
-static int dev_sort(struct list_head *pos, struct list_head *new)
+static int
+dev_sort(struct list_head *pos, struct list_head *new)
{
return (META(RD(new), sil))->disk_number <
- (META(RD(pos), sil))->disk_number;
+ (META(RD(pos), sil))->disk_number;
}
/* Decide about ordering sequence of RAID subset. */
-static int set_sort(struct list_head *pos, struct list_head *new)
+static int
+set_sort(struct list_head *pos, struct list_head *new)
{
return (META(RD_RS(RS(new)), sil))->mirrored_set_number <
- (META(RD_RS(RS(pos)), sil))->mirrored_set_number;
+ (META(RD_RS(RS(pos)), sil))->mirrored_set_number;
}
/*
@@ -294,15 +310,17 @@
*
* Check device hierarchy and create super set appropriately.
*/
-static void super_created(struct raid_set *ss, void *private)
+static void
+super_created(struct raid_set *ss, void *private)
{
- ss->type = t_raid1;
+ ss->type = t_raid1;
ss->stride = META(private, sil)->raid0_stride;
}
/* FIXME: handle spares. */
-static int group_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_set **ss, struct raid_dev *rd)
+static int
+group_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_set **ss, struct raid_dev *rd)
{
struct sil *sil = META(rd, sil);
@@ -336,7 +354,8 @@
}
/* Add a SIL RAID device to a set */
-static struct raid_set *sil_group(struct lib_context *lc, struct raid_dev *rd)
+static struct raid_set *
+sil_group(struct lib_context *lc, struct raid_dev *rd)
{
struct raid_set *rs, *ss = NULL;
@@ -355,7 +374,8 @@
*
* FIXME: more sanity checks.
*/
-static unsigned int devices(struct raid_dev *rd, void *context)
+static unsigned int
+devices(struct raid_dev *rd, void *context)
{
int ret;
struct sil *sil = META(rd, sil);
@@ -377,7 +397,8 @@
return ret;
}
-static int sil_check(struct lib_context *lc, struct raid_set *rs)
+static int
+sil_check(struct lib_context *lc, struct raid_set *rs)
{
return check_raid_set(lc, rs, devices, NULL,
NO_CHECK_RD, NULL, handler);
@@ -386,7 +407,8 @@
/*
* IO error event handler.
*/
-static int event_io(struct lib_context *lc, struct event_io *e_io)
+static int
+event_io(struct lib_context *lc, struct event_io *e_io)
{
struct raid_dev *rd = e_io->rd;
struct sil *sil = META(rd, sil);
@@ -402,14 +424,15 @@
static struct event_handlers sil_event_handlers = {
.io = event_io,
- .rd = NULL, /* FIXME: no device add/remove event handler yet. */
+ .rd = NULL, /* FIXME: no device add/remove event handler yet. */
};
#ifdef DMRAID_NATIVE_LOG
/*
* Log native information about a Silicon Image RAID device.
*/
-static void sil_log(struct lib_context *lc, struct raid_dev *rd)
+static void
+sil_log(struct lib_context *lc, struct raid_dev *rd)
{
char *tt;
struct sil *sil = META(rd, sil);
@@ -464,46 +487,49 @@
#endif
static struct dmraid_format sil_format = {
- .name = HANDLER,
- .descr = "Silicon Image(tm) Medley(tm)",
- .caps = "0,1,10",
+ .name = HANDLER,
+ .descr = "Silicon Image(tm) Medley(tm)",
+ .caps = "0,1,10",
.format = FMT_RAID,
- .read = sil_read,
- .write = sil_write,
- .group = sil_group,
- .check = sil_check,
- .events = &sil_event_handlers,
+ .read = sil_read,
+ .write = sil_write,
+ .group = sil_group,
+ .check = sil_check,
+ .events = &sil_event_handlers,
#ifdef DMRAID_NATIVE_LOG
- .log = sil_log,
+ .log = sil_log,
#endif
};
/* Register this format handler with the format core. */
-int register_sil(struct lib_context *lc)
+int
+register_sil(struct lib_context *lc)
{
return register_format_handler(lc, &sil_format);
}
/* Set the RAID device contents up derived from the SIL ones. */
-static int stripes(struct sil *sil)
+static int
+stripes(struct sil *sil)
{
return sil->drives_per_striped_set > -1 &&
- sil->disk_number < sil->drives_per_striped_set;
+ sil->disk_number < sil->drives_per_striped_set;
}
-static uint64_t sectors(struct raid_dev *rd)
+static uint64_t
+sectors(struct raid_dev *rd)
{
uint64_t array_sectors, ret = 0;
struct sil *sil = META(rd, sil);
array_sectors = (((uint64_t) sil->array_sectors_high) << 32) +
- sil->array_sectors_low;
+ sil->array_sectors_low;
switch (sil->type) {
case SIL_T_SPARE:
/* Cook them up... */
ret = rd->di->sectors - (AREAS - 1) * 512 -
- ((rd->di->sectors & 1) ? 1 : 2);
+ ((rd->di->sectors & 1) ? 1 : 2);
break;
case SIL_T_RAID0:
@@ -519,7 +545,7 @@
default:
/* Cook them up... */
ret = rd->di->sectors - (AREAS - 1) * 512 -
- ((rd->di->sectors & 1) ? 1 : 2);
+ ((rd->di->sectors & 1) ? 1 : 2);
break;
}
@@ -527,19 +553,19 @@
}
/* Quorate SIL metadata copies. */
-static struct sil *quorate(struct lib_context *lc, struct dev_info *di,
- struct sil *sils[])
+static struct sil *
+quorate(struct lib_context *lc, struct dev_info *di, struct sil *sils[])
{
unsigned int areas = 0, i, ident = 0, j;
struct sil *sil = NULL, *tmp;
-
+
/* Count valid metadata areas. */
while (areas < AREAS && sils[areas])
areas++;
if (areas != AREAS)
log_err(lc, "%s: only %u/%u metadata areas found on "
- "%s, %sing...",
+ "%s, %sing...",
handler, areas, AREAS, di->path,
areas > 1 ? "elect" : "pick");
@@ -551,7 +577,7 @@
}
if (ident > areas / 2);
- break;
+ break;
}
if (ident) {
@@ -563,8 +589,9 @@
return sil;
}
-static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta, union read_info *info)
+static int
+setup_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct dev_info *di, void *meta, union read_info *info)
{
unsigned int i;
struct meta_areas *ma;
@@ -573,13 +600,13 @@
if (!(rd->meta_areas = alloc_meta_areas(lc, rd, handler, AREAS)))
goto bad;
- sil = quorate(lc, di, sils); /* Quorate one copy+save a pointer.*/
- free_sils(sils, 1); /* Free the other copies. */
+ sil = quorate(lc, di, sils); /* Quorate one copy+save a pointer. */
+ free_sils(sils, 1); /* Free the other copies. */
for (i = 0, ma = rd->meta_areas; i < rd->areas; i++, ma++) {
ma->offset = SIL_META_AREA(i) >> 9;
ma->size = sizeof(*sil);
- ma->area = (void*) sil;
+ ma->area = (void *) sil;
}
rd->di = di;
@@ -590,11 +617,11 @@
return log_zero_sectors(lc, di->path, handler);
rd->status = status(sil);
- rd->type = type(sil);
+ rd->type = type(sil);
- return (rd->name = name(lc, rd, sil->type == SIL_T_RAID10)) ? 1 : 0;
+ return (rd->name = name(lc, rd, sil->type == SIL_T_RAID10)) ? 1 : 0;
- bad:
+ bad:
free_sils(sils, 0);
return 0;
--- dmraid/lib/format/ataraid/sil.h 2008/02/22 17:04:35 1.2
+++ dmraid/lib/format/ataraid/sil.h 2008/06/20 21:52:17 1.3
@@ -14,64 +14,64 @@
#include <stdint.h>
#define SIL_CONFIGOFFSET ((di->sectors - 1) << 9)
-#define SIL_DATAOFFSET 0 /* Data offset in sectors */
+#define SIL_DATAOFFSET 0 /* Data offset in sectors */
struct sil {
- uint8_t unknown0[0x2E]; /* 0x4 - 0x2D */
- uint8_t ascii_version[0x36 - 0x2E];/* 0x2E - 0x35 */
- int8_t diskname[0x56 - 0x36]; /* 0x36 - 0x55 */
- int8_t unknown1[0x60 - 0x56]; /* 0x56 - 0x59 */
- uint32_t magic; /* 0x60 - 0x63 */
+ uint8_t unknown0[0x2E]; /* 0x4 - 0x2D */
+ uint8_t ascii_version[0x36 - 0x2E]; /* 0x2E - 0x35 */
+ int8_t diskname[0x56 - 0x36]; /* 0x36 - 0x55 */
+ int8_t unknown1[0x60 - 0x56]; /* 0x56 - 0x59 */
+ uint32_t magic; /* 0x60 - 0x63 */
#define SIL_MAGIC 0x3000000
#define SIL_MAGIC_OK(sil) ((sil->magic & 0x3ffffff) == SIL_MAGIC)
- int8_t unknown1a[0x6C - 0x64]; /* 0x64 - 0x6B */
- uint32_t array_sectors_low; /* 0x6C - 0x6F */
- uint32_t array_sectors_high; /* 0x70 - 0x73 */
- int8_t unknown2[0x78 - 0x74]; /* 0x74 - 0x77 */
- uint32_t thisdisk_sectors; /* 0x78 - 0x7B */
- int8_t unknown3[0x100 - 0x7C]; /* 0x7C - 0xFF */
- int8_t unknown4[0x104 - 0x100];/* 0x100 - 0x103 */
- uint16_t product_id; /* 0x104 + 0x105 */
- uint16_t vendor_id; /* 0x106 + 0x107 */
- uint16_t minor_ver; /* 0x108 + 0x109 */
- uint16_t major_ver; /* 0x10A + 0x10B */
- uint8_t seconds; /* 0x10C */
- uint8_t minutes; /* 0x10D */
- uint8_t hour; /* 0x10E */
- uint8_t day; /* 0x10F */
- uint8_t month; /* 0x110 */
- uint8_t year; /* 0x111 */
- uint16_t raid0_stride; /* 0x112 + 0x113 */
- int8_t unknown6[0x116 - 0x114];/* 0x114 + 0x115 */
- uint8_t disk_number; /* 0x116 */
- uint8_t type; /* 0x117 */
+ int8_t unknown1a[0x6C - 0x64]; /* 0x64 - 0x6B */
+ uint32_t array_sectors_low; /* 0x6C - 0x6F */
+ uint32_t array_sectors_high; /* 0x70 - 0x73 */
+ int8_t unknown2[0x78 - 0x74]; /* 0x74 - 0x77 */
+ uint32_t thisdisk_sectors; /* 0x78 - 0x7B */
+ int8_t unknown3[0x100 - 0x7C]; /* 0x7C - 0xFF */
+ int8_t unknown4[0x104 - 0x100]; /* 0x100 - 0x103 */
+ uint16_t product_id; /* 0x104 + 0x105 */
+ uint16_t vendor_id; /* 0x106 + 0x107 */
+ uint16_t minor_ver; /* 0x108 + 0x109 */
+ uint16_t major_ver; /* 0x10A + 0x10B */
+ uint8_t seconds; /* 0x10C */
+ uint8_t minutes; /* 0x10D */
+ uint8_t hour; /* 0x10E */
+ uint8_t day; /* 0x10F */
+ uint8_t month; /* 0x110 */
+ uint8_t year; /* 0x111 */
+ uint16_t raid0_stride; /* 0x112 + 0x113 */
+ int8_t unknown6[0x116 - 0x114]; /* 0x114 + 0x115 */
+ uint8_t disk_number; /* 0x116 */
+ uint8_t type; /* 0x117 */
#define SIL_T_RAID0 0
#define SIL_T_RAID1 1
#define SIL_T_RAID10 2
#define SIL_T_RAID5 16
#define SIL_T_SPARE 3
#define SIL_T_JBOD 255
- int8_t drives_per_striped_set; /* 0x118 */
- int8_t striped_set_number; /* 0x119 */
- int8_t drives_per_mirrored_set;/* 0x11A */
- int8_t mirrored_set_number; /* 0x11B */
- uint32_t rebuild_ptr_low; /* 0x11C - 0x12F */
- uint32_t rebuild_ptr_high; /* 0x120 - 0x123 */
- uint32_t incarnation_no; /* 0x124 - 0x127 */
- uint8_t member_status; /* 0x128 */
- uint8_t mirrored_set_state; /* 0x129 */
+ int8_t drives_per_striped_set; /* 0x118 */
+ int8_t striped_set_number; /* 0x119 */
+ int8_t drives_per_mirrored_set; /* 0x11A */
+ int8_t mirrored_set_number; /* 0x11B */
+ uint32_t rebuild_ptr_low; /* 0x11C - 0x12F */
+ uint32_t rebuild_ptr_high; /* 0x120 - 0x123 */
+ uint32_t incarnation_no; /* 0x124 - 0x127 */
+ uint8_t member_status; /* 0x128 */
+ uint8_t mirrored_set_state; /* 0x129 */
#define SIL_OK 0
#define SIL_MIRROR_NOSYNC 1
#define SIL_MIRROR_SYNC 2
- uint8_t reported_device_location;/* 0x12A */
- uint8_t idechannel; /* 0x12B */
- uint8_t auto_rebuild; /* 0x12C */
+ uint8_t reported_device_location; /* 0x12A */
+ uint8_t idechannel; /* 0x12B */
+ uint8_t auto_rebuild; /* 0x12C */
#define SIL_MIRROR_NOAUTOREBUILD 0
- uint8_t unknown8; /* 0x12D */
- uint8_t text_type[0x13E - 0x12E]; /* 0x12E - 0x13D */
- uint16_t checksum1; /* 0x13E + 0x13F */
- int8_t assumed_zeros[0x1FE - 0x140];/* 0x140 - 0x1FD */
- uint16_t checksum2; /* 0x1FE + 0x1FF */
+ uint8_t unknown8; /* 0x12D */
+ uint8_t text_type[0x13E - 0x12E]; /* 0x12E - 0x13D */
+ uint16_t checksum1; /* 0x13E + 0x13F */
+ int8_t assumed_zeros[0x1FE - 0x140]; /* 0x140 - 0x1FD */
+ uint16_t checksum2; /* 0x1FE + 0x1FF */
} __attribute__ ((packed));
#endif
--- dmraid/lib/format/ataraid/via.c 2008/02/22 17:04:35 1.2
+++ dmraid/lib/format/ataraid/via.c 2008/06/20 21:52:17 1.3
@@ -21,16 +21,18 @@
static const char *handler = HANDLER;
-static int _subset(struct via *via)
+static int
+_subset(struct via *via)
{
return VIA_T_RAID01_MIRROR(via);
}
/* Make up VIA RAID device name suffix from the serial_checksum array. */
-static uint32_t sum_serial(struct via *via)
+static uint32_t
+sum_serial(struct via *via)
{
unsigned int i = VIA_MAX_DISKS;
- uint32_t ret = via->array.disk_array_ex; /* FIXME: correct ? */
+ uint32_t ret = via->array.disk_array_ex; /* FIXME: correct ? */
while (i--)
ret += via->serial_checksum[i];
@@ -38,7 +40,8 @@
return ret;
}
-static char *_name_suffix(struct via *via)
+static char *
+_name_suffix(struct via *via)
{
size_t len;
uint32_t sum = sum_serial(via);
@@ -51,15 +54,16 @@
}
/* Make up RAID device name. */
-static size_t _name(struct lib_context *lc, struct via *via, char *str,
- size_t len, char *suffix, unsigned int subset)
+static size_t
+_name(struct lib_context *lc, struct via *via, char *str,
+ size_t len, char *suffix, unsigned int subset)
{
return snprintf(str, len,
subset ? "via_%s-%u" : "via_%s", suffix, _subset(via));
}
-static char *name(struct lib_context *lc, struct raid_dev *rd,
- unsigned int subset)
+static char *
+name(struct lib_context *lc, struct raid_dev *rd, unsigned int subset)
{
size_t len;
char *ret, *suffix;
@@ -74,7 +78,8 @@
_name(lc, via, ret, len, suffix, subset);
mk_alpha(lc, ret + HANDLER_LEN, len - HANDLER_LEN -
(subset ? 3 : 1));
- } else
+ }
+ else
log_alloc_err(lc, handler);
dbg_free(suffix);
@@ -86,7 +91,8 @@
* Retrieve status of device.
* FIXME: is this sufficient to cover all state ?
*/
-static enum status status(struct via *via)
+static enum status
+status(struct via *via)
{
if (via->array.disk.tolerance)
return s_broken;
@@ -95,15 +101,16 @@
}
/* Neutralize disk type using generic metadata type mapping function */
-static enum type type(struct via *via)
+static enum type
+type(struct via *via)
{
/* Mapping of via types to generic types */
static struct types types[] = {
- { VIA_T_SPAN, t_linear },
- { VIA_T_RAID0, t_raid0 },
- { VIA_T_RAID1, t_raid1 },
- { VIA_T_RAID01, t_raid0 },
- { 0, t_undef}
+ {VIA_T_SPAN, t_linear},
+ {VIA_T_RAID0, t_raid0},
+ {VIA_T_RAID1, t_raid1},
+ {VIA_T_RAID01, t_raid0},
+ {0, t_undef}
};
return rd_type(types, (unsigned int) VIA_RAID_TYPE(via));
@@ -116,7 +123,8 @@
#if BYTE_ORDER == LITTLE_ENDIAN
# define to_cpu NULL
#else
-static void to_cpu(void *meta)
+static void
+to_cpu(void *meta)
{
struct via *via = meta;
unsigned int i = VIA_MAX_DISKS;
@@ -134,17 +142,19 @@
#endif
/* 8 bit checksum on first 50 bytes of metadata. */
-static uint8_t checksum(struct via *via)
+static uint8_t
+checksum(struct via *via)
{
uint8_t i = 50, sum = 0;
-
+
while (i--)
- sum += ((uint8_t*) via)[i];
+ sum += ((uint8_t *) via)[i];
return sum == via->checksum;
}
-static int is_via(struct lib_context *lc, struct dev_info *di, void *meta)
+static int
+is_via(struct lib_context *lc, struct dev_info *di, void *meta)
{
struct via *via = meta;
@@ -157,13 +167,14 @@
if (via->version_number > 1)
log_info(lc, "%s: version %u; format handler specified for "
"version 0+1 only", handler, via->version_number);
-
+
return 1;
}
static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
struct dev_info *di, void *meta, union read_info *info);
-static struct raid_dev *via_read(struct lib_context *lc, struct dev_info *di)
+static struct raid_dev *
+via_read(struct lib_context *lc, struct dev_info *di)
{
return read_raid_dev(lc, di, NULL,
sizeof(struct via), VIA_CONFIGOFFSET,
@@ -171,7 +182,8 @@
}
/* Decide about ordering sequence of RAID device. */
-static int dev_sort(struct list_head *pos, struct list_head *new)
+static int
+dev_sort(struct list_head *pos, struct list_head *new)
{
struct via *p = META(RD(pos), via);
struct via *n = META(RD(new), via);
@@ -180,27 +192,30 @@
case VIA_T_RAID1:
return VIA_T_RAID1_SOURCE(n);
- default: /* span, RAID0 + RAID01 */
+ default: /* span, RAID0 + RAID01 */
return VIA_T_RAID_INDEX(n) < VIA_T_RAID_INDEX(p);
}
}
/* Decide about ordering sequence of RAID subset. */
-static int set_sort(struct list_head *pos, struct list_head *new)
+static int
+set_sort(struct list_head *pos, struct list_head *new)
{
return _subset(META(RD_RS(RS(new)), via)) <
- _subset(META(RD_RS(RS(pos)), via));
+ _subset(META(RD_RS(RS(pos)), via));
}
-static void super_created(struct raid_set *ss, void *private)
+static void
+super_created(struct raid_set *ss, void *private)
{
ss->type = t_raid1;
ss->stride = VIA_STRIDE(META(private, via));
}
/* FIXME: handle spares in mirrors and check that types are correct. */
-static int group_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_set **ss, struct raid_dev *rd)
+static int
+group_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_set **ss, struct raid_dev *rd)
{
struct via *via = META(rd, via);
@@ -230,8 +245,8 @@
}
/* Add a VIA RAID device to a set */
-static struct raid_set *via_group(struct lib_context *lc,
- struct raid_dev *rd)
+static struct raid_set *
+via_group(struct lib_context *lc, struct raid_dev *rd)
{
struct raid_set *rs, *ss = NULL;
@@ -245,7 +260,8 @@
return NULL;
}
-static int via_write(struct lib_context *lc, struct raid_dev *rd, int erase)
+static int
+via_write(struct lib_context *lc, struct raid_dev *rd, int erase)
{
int ret;
#if BYTE_ORDER != LITTLE_ENDIAN
@@ -267,15 +283,17 @@
* FIXME: more sanity checks.
*/
/* Figure total number of disks depending on RAID type. */
-static unsigned int devices(struct raid_dev *rd, void *context)
+static unsigned int
+devices(struct raid_dev *rd, void *context)
{
struct via *via = META(rd, via);
return VIA_RAID_TYPE(via) == VIA_T_RAID1 ? 2 : VIA_RAID_DISKS(via);
}
-static int check_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_dev *rd, void *context)
+static int
+check_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_dev *rd, void *context)
{
struct via *via = META(rd, via);
@@ -291,7 +309,8 @@
return 1;
}
-static int via_check(struct lib_context *lc, struct raid_set *rs)
+static int
+via_check(struct lib_context *lc, struct raid_set *rs)
{
return check_raid_set(lc, rs, devices, NULL, check_rd, NULL, handler);
}
@@ -299,7 +318,8 @@
/*
* IO error event handler.
*/
-static int event_io(struct lib_context *lc, struct event_io *e_io)
+static int
+event_io(struct lib_context *lc, struct event_io *e_io)
{
struct raid_dev *rd = e_io->rd;
struct via *via = META(rd, via);
@@ -315,7 +335,7 @@
static struct event_handlers via_event_handlers = {
.io = event_io,
- .rd = NULL, /* FIXME: no device add/remove event handler yet. */
+ .rd = NULL, /* FIXME: no device add/remove event handler yet. */
};
@@ -323,7 +343,8 @@
/*
* Log native information about the RAID device.
*/
-static void via_log(struct lib_context *lc, struct raid_dev *rd)
+static void
+via_log(struct lib_context *lc, struct raid_dev *rd)
{
unsigned int i;
struct via *via = META(rd, via);
@@ -337,8 +358,7 @@
via->array.disk.enable_enhanced);
P("array.disk.in_disk_array: %u", via, via->array.disk,
via->array.disk.in_disk_array);
- P("array.disk.raid_type: %u", via, via->array.disk,
- VIA_RAID_TYPE(via));
+ P("array.disk.raid_type: %u", via, via->array.disk, VIA_RAID_TYPE(via));
P("array.disk.array_index: %u", via, via->array.disk,
VIA_ARRAY_INDEX(via));
@@ -366,28 +386,30 @@
#endif
static struct dmraid_format via_format = {
- .name = HANDLER,
- .descr = "VIA Software RAID",
- .caps = "S,0,1,10",
+ .name = HANDLER,
+ .descr = "VIA Software RAID",
+ .caps = "S,0,1,10",
.format = FMT_RAID,
- .read = via_read,
- .write = via_write,
- .group = via_group,
- .check = via_check,
- .events = &via_event_handlers,
+ .read = via_read,
+ .write = via_write,
+ .group = via_group,
+ .check = via_check,
+ .events = &via_event_handlers,
#ifdef DMRAID_NATIVE_LOG
- .log = via_log,
+ .log = via_log,
#endif
};
/* Register this format handler with the format core. */
-int register_via(struct lib_context *lc)
+int
+register_via(struct lib_context *lc)
{
return register_format_handler(lc, &via_format);
}
-static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta, union read_info *info)
+static int
+setup_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct dev_info *di, void *meta, union read_info *info)
{
struct via *via = meta;
@@ -396,17 +418,17 @@
rd->meta_areas->offset = VIA_CONFIGOFFSET >> 9;
rd->meta_areas->size = sizeof(*via);
- rd->meta_areas->area = (void*) via;
+ rd->meta_areas->area = (void *) via;
- rd->di = di;
+ rd->di = di;
rd->fmt = &via_format;
rd->status = status(via);
- rd->type = type(via);
+ rd->type = type(via);
rd->offset = VIA_DATAOFFSET;
if (!(rd->sectors = rd->meta_areas->offset))
return log_zero_sectors(lc, di->path, handler);
- return (rd->name = name(lc, rd, 1)) ? 1 : 0;
+ return (rd->name = name(lc, rd, 1)) ? 1 : 0;
}
--- dmraid/lib/format/ataraid/via.h 2008/02/22 16:57:36 1.1
+++ dmraid/lib/format/ataraid/via.h 2008/06/20 21:52:17 1.2
@@ -19,18 +19,18 @@
#define VIA_MAX_DISKS 8
struct disk {
- uint16_t bootable:1; /* BIOS boot */
- uint16_t enable_enhanced:1; /* Unused */
- uint16_t in_disk_array:1; /* Used/Spare */
- uint16_t raid_type:4;
+ uint16_t bootable:1; /* BIOS boot */
+ uint16_t enable_enhanced:1; /* Unused */
+ uint16_t in_disk_array:1; /* Used/Spare */
+ uint16_t raid_type:4;
#define VIA_T_RAID0 0
#define VIA_T_RAID1 1
#define VIA_T_SPAN 8
#define VIA_T_RAID01 9
#define VIA_RAID_TYPE(x) ((x)->array.disk.raid_type)
- uint16_t array_index:3;
+ uint16_t array_index:3;
#define VIA_ARRAY_INDEX(x) ((x)->array.disk.array_index)
- uint16_t raid_type_info:5;
+ uint16_t raid_type_info:5;
/* SPAN + RAID 0 */
#define VIA_T_RAID_INDEX(x) ((x)->array.disk.raid_type_info & 0x7)
@@ -41,33 +41,33 @@
#define VIA_T_RAID1_DIRTY(x) (((x)->array.disk.raid_type_info & 0x4) >> 2)
/* RAID 0+1 */
-// #define VIA_T_RAID01_INDEX(x) VIA_T_RAID_INDEX(x)
+// #define VIA_T_RAID01_INDEX(x) VIA_T_RAID_INDEX(x)
#define VIA_T_RAID01_MIRROR(x) (((x)->array.disk.raid_type_info & 0x8) >> 3)
#define VIA_T_RAID01_DIRTY(x) (((x)->array.disk.raid_type_info & 0x10) >> 4)
/* SPAN */
#define VIA_T_SPAN_INDEX(x) ((x)->array.disk.raid_type_info & 0x7)
- uint16_t tolerance:1;
+ uint16_t tolerance:1;
} __attribute__ ((packed));
struct array {
- struct disk disk;
- uint8_t disk_array_ex;
+ struct disk disk;
+ uint8_t disk_array_ex;
#define VIA_RAID_DISKS(x) ((x)->array.disk_array_ex & 0x7)
#define VIA_BROKEN(x) (((x)->array.disk_array_ex & 0x8) >> 4)
#define VIA_STRIDE(x) (8 << (((x)->array.disk_array_ex & 0xF0) >> 4))
- uint32_t capacity_low;
- uint32_t capacity_high;
- uint32_t serial_checksum;
+ uint32_t capacity_low;
+ uint32_t capacity_high;
+ uint32_t serial_checksum;
} __attribute__ ((packed));
struct via {
- uint16_t signature;
+ uint16_t signature;
#define VIA_SIGNATURE 0xAA55
- uint8_t version_number;
- struct array array;
- uint32_t serial_checksum[8];
- uint8_t checksum;
+ uint8_t version_number;
+ struct array array;
+ uint32_t serial_checksum[8];
+ uint8_t checksum;
} __attribute__ ((packed));
#endif
--- dmraid/lib/format/ddf/ddf1.c 2008/04/02 13:35:31 1.3
+++ dmraid/lib/format/ddf/ddf1.c 2008/06/20 21:52:17 1.4
@@ -4,8 +4,8 @@
* Copyright (C) 2005-2006 IBM, All rights reserved.
* Written by Darrick Wong <djwong at us.ibm.com>
*
- * Copyright (C) 2006 Heinz Mauelshagen, Red Hat GmbH
- * All rights reserved.
+ * Copyright (C) 2006-2008 Heinz Mauelshagen, Red Hat GmbH
+ * All rights reserved.
*
* See file LICENSE at the top of this source tree for license information.
*/
@@ -37,17 +37,19 @@
#define DDF1_DISKS (char*) ".ddf1_disks"
/* PCI IDs for Adaptec */
-// #define PCI_VENDOR_ID_ADAPTEC 0x9004
+// #define PCI_VENDOR_ID_ADAPTEC 0x9004
#define PCI_VENDOR_ID_ADAPTEC2 0x9005
/* Map DDF1 disk status to dmraid status */
-static enum status disk_status(struct ddf1_phys_drive *disk) {
+static enum status
+disk_status(struct ddf1_phys_drive *disk)
+{
struct states states[] = {
- { 0x72, s_broken },
- { 0x04, s_nosync },
- { 0x08, s_setup },
- { 0x01, s_ok },
- { 0, s_undef },
+ {0x72, s_broken},
+ {0x04, s_nosync},
+ {0x08, s_setup},
+ {0x01, s_ok},
+ {0, s_undef},
};
return disk ? rd_status(states, disk->state, AND) : s_undef;
@@ -60,7 +62,8 @@
* both GUIDs don't have 0xFFFFFFFF in bytes 20-23. Gross.
*/
/* Find this drive's physical data */
-static struct ddf1_phys_drive *get_phys_drive(struct ddf1 *ddf1)
+static struct ddf1_phys_drive *
+get_phys_drive(struct ddf1 *ddf1)
{
unsigned int i = ddf1->pd_header->max_drives;
@@ -73,8 +76,8 @@
}
/* Find the virtual drive that goes with this config record */
-static struct ddf1_virt_drive *get_virt_drive(struct ddf1 *ddf1,
- struct ddf1_config_record *cr)
+static struct ddf1_virt_drive *
+get_virt_drive(struct ddf1 *ddf1, struct ddf1_config_record *cr)
{
int i = ddf1->vd_header->num_drives;
@@ -89,8 +92,9 @@
/*
* Find the index of the VD config record given a physical drive and offset.
*/
-static int get_config_byoffset(struct ddf1 *ddf1, struct ddf1_phys_drive *pd,
- uint64_t offset)
+static int
+get_config_byoffset(struct ddf1 *ddf1, struct ddf1_phys_drive *pd,
+ uint64_t offset)
{
int cfgs = NUM_CONFIG_ENTRIES(ddf1), i;
uint32_t *cfg_drive_ids, j;
@@ -114,8 +118,8 @@
}
/* Find the index of the nth VD config record for this physical drive. */
-static int get_config_index(struct ddf1 *ddf1, struct ddf1_phys_drive *pd,
- unsigned int *n)
+static int
+get_config_index(struct ddf1 *ddf1, struct ddf1_phys_drive *pd, unsigned int *n)
{
int cfgs = NUM_CONFIG_ENTRIES(ddf1), i, j, nn = *n;
uint32_t *ids;
@@ -127,7 +131,7 @@
ids = CR_IDS(ddf1, cr);
for (j = 0; j < cr->primary_element_count; j++) {
if (ids[j] == pd->reference && !nn--)
- return i;
+ return i;
}
}
}
@@ -139,18 +143,17 @@
/*
* Find the nth VD config record for this physical drive.
*/
-static inline struct ddf1_config_record *get_config(struct ddf1 *ddf1,
- struct ddf1_phys_drive *pd,
- unsigned int n)
+static inline struct ddf1_config_record *
+get_config(struct ddf1 *ddf1, struct ddf1_phys_drive *pd, unsigned int n)
{
int i = get_config_index(ddf1, pd, &n);
return i < 0 ? NULL : CR(ddf1, i);
}
-
+
/* Find a config record for this drive, given the offset of the array. */
-static inline struct ddf1_config_record *get_this_config(struct ddf1 *ddf1,
- uint64_t offset)
+static inline struct ddf1_config_record *
+get_this_config(struct ddf1 *ddf1, uint64_t offset)
{
struct ddf1_phys_drive *pd = get_phys_drive(ddf1);
int i = get_config_byoffset(ddf1, pd, offset);
@@ -159,8 +162,9 @@
}
/* Find the config record disk/offset entry for this config/drive. */
-static int get_offset_entry(struct ddf1 *ddf1, struct ddf1_config_record *cr,
- struct ddf1_phys_drive *pd)
+static int
+get_offset_entry(struct ddf1 *ddf1, struct ddf1_config_record *cr,
+ struct ddf1_phys_drive *pd)
{
int i;
uint32_t *ids;
@@ -177,8 +181,9 @@
}
/* Find the offset for this config/drive. */
-static uint64_t get_offset(struct ddf1 *ddf1, struct ddf1_config_record *cr,
- struct ddf1_phys_drive *pd)
+static uint64_t
+get_offset(struct ddf1 *ddf1, struct ddf1_config_record *cr,
+ struct ddf1_phys_drive *pd)
{
int i = get_offset_entry(ddf1, cr, pd);
@@ -186,33 +191,34 @@
}
/* Calculate the stripe size, in sectors */
-static inline unsigned int stride(struct ddf1_config_record *cr)
+static inline unsigned int
+stride(struct ddf1_config_record *cr)
{
return to_bytes(1) >> 9 << cr->stripe_size;
}
/* Map the DDF1 raid type codes into dmraid type codes. */
-static enum type type(struct lib_context *lc, struct ddf1 *ddf1,
- struct ddf1_config_record *cr)
+static enum type
+type(struct lib_context *lc, struct ddf1 *ddf1, struct ddf1_config_record *cr)
{
unsigned int l;
struct types *t;
/* Mapping of template types to generic types */
static struct types types[] = {
- { DDF1_RAID0, t_raid0 },
- { DDF1_RAID1, t_raid1 },
- { DDF1_RAID4, t_raid4 },
- { DDF1_CONCAT, t_linear },
- { DDF1_JBOD, t_linear },
- { 0, t_undef}
+ {DDF1_RAID0, t_raid0},
+ {DDF1_RAID1, t_raid1},
+ {DDF1_RAID4, t_raid4},
+ {DDF1_CONCAT, t_linear},
+ {DDF1_JBOD, t_linear},
+ {0, t_undef}
};
/* Seperate array for RAID5 qualifiers */
static struct types qualifier_types[] = {
/* FIXME: Is RLQ=0 really right symmetric? */
- { DDF1_RAID5_RS, t_raid5_rs },
- { DDF1_RAID5_LA, t_raid5_la },
- { DDF1_RAID5_LS, t_raid5_ls },
- { 0, t_undef}
+ {DDF1_RAID5_RS, t_raid5_rs},
+ {DDF1_RAID5_LA, t_raid5_la},
+ {DDF1_RAID5_LS, t_raid5_ls},
+ {0, t_undef}
};
if (!cr)
@@ -236,8 +242,8 @@
}
/* Read the whole metadata chunk at once */
-static uint8_t *read_metadata_chunk(struct lib_context *lc, struct dev_info *di,
- uint64_t start)
+static uint8_t *
+read_metadata_chunk(struct lib_context *lc, struct dev_info *di, uint64_t start)
{
uint8_t *ret;
size_t size = to_bytes(di->sectors - start);
@@ -254,26 +260,29 @@
return ret;
}
-static inline void cond_free(void *p)
+static inline void
+cond_free(void *p)
{
if (p)
dbg_free(p);
}
/* Reused error message */
-static inline void *err_drive(struct lib_context *lc, struct dev_info *di,
- const char *what)
+static inline void *
+err_drive(struct lib_context *lc, struct dev_info *di, const char *what)
{
LOG_ERR(lc, NULL, "%s: cannot find %s drive record on %s",
handler, what, di->path);
}
-static void *err_phys_drive(struct lib_context *lc, struct dev_info *di)
+static void *
+err_phys_drive(struct lib_context *lc, struct dev_info *di)
{
return err_drive(lc, di, "physical");
}
-static void *err_virt_drive(struct lib_context *lc, struct dev_info *di)
+static void *
+err_virt_drive(struct lib_context *lc, struct dev_info *di)
{
return err_drive(lc, di, "virtual");
}
@@ -282,8 +291,8 @@
* Read a DDF1 RAID device. Fields are little endian, so
* need to convert them if we're on a BE machine (ppc, etc).
*/
-static int read_extended(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1)
+static int
+read_extended(struct lib_context *lc, struct dev_info *di, struct ddf1 *ddf1)
{
int i;
uint64_t where;
@@ -319,7 +328,7 @@
cond_free(ddf1->primary);
ddf1->primary = NULL;
};
-
+
if (sec->signature == DDF1_HEADER) {
/* If we encounter an error, we use the secondary table */
if (!ddf1->primary) {
@@ -331,8 +340,7 @@
} else {
if (sec->signature)
log_warn(lc, "%s: bad secondary header signature %x "
- "on %s",
- handler, sec->signature, di->path);
+ "on %s", handler, sec->signature, di->path);
dbg_free(sec);
ddf1->secondary = NULL;
@@ -357,7 +365,7 @@
if (ddf1->adapter->signature != DDF1_ADAPTER_DATA) {
if (ddf1->adapter->signature)
log_warn(lc, "%s: incorrect adapter data signature %x "
- "on %s",
+ "on %s",
handler, ddf1->adapter->signature, di->path);
dbg_free(ddf1->adapter);
ddf1->adapter = NULL;
@@ -402,8 +410,8 @@
}
/* Now read the physical drive data */
- ddf1->pds = (struct ddf1_phys_drive *)(((uint8_t *)ddf1->pd_header) +
- sizeof (*pd));
+ ddf1->pds = (struct ddf1_phys_drive *) (((uint8_t *) ddf1->pd_header) +
+ sizeof(*pd));
for (i = 0; i < pd->num_drives; i++) {
ddf1_cvt_phys_drive(ddf1, &ddf1->pds[i]);
/*
@@ -428,7 +436,7 @@
}
/* Now read the virtual drive data */
- ddf1->vds = (struct ddf1_virt_drive*)(((uint8_t*) vd) + sizeof (*pd));
+ ddf1->vds = (struct ddf1_virt_drive *) (((uint8_t *) vd) + sizeof(*pd));
for (i = 0; i < vd->num_drives; i++)
ddf1_cvt_virt_drive(ddf1, &ddf1->vds[i]);
@@ -454,13 +462,12 @@
ddf1->in_cpu_format = 1;
/* FIXME: We should verify the checksums for all modes */
- if (ddf1->adaptec_mode &&
- !(ddf1_check_all_crcs(lc, di, ddf1)))
+ if (ddf1->adaptec_mode && !(ddf1_check_all_crcs(lc, di, ddf1)))
goto bad;
return 1;
-bad:
+ bad:
ddf1->vds = NULL;
ddf1->pds = NULL;
cond_free(ddf1->cfg);
@@ -473,18 +480,19 @@
}
/* Count the number of raid_devs we need to create for this drive */
-static unsigned int num_devs(struct lib_context *lc, void *meta)
+static unsigned int
+num_devs(struct lib_context *lc, void *meta)
{
struct ddf1 *ddf1 = meta;
unsigned int num_drives = ~0;
-
+
get_config_index(ddf1, get_phys_drive(ddf1), &num_drives);
return num_drives;
}
/* Is this DDF1 metadata? */
-static inline int is_ddf1(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1)
+static inline int
+is_ddf1(struct lib_context *lc, struct dev_info *di, struct ddf1 *ddf1)
{
/*
* Check our magic numbers and that the version == v2.
@@ -493,15 +501,15 @@
/* FIXME: We should examine the version headers... */
return ddf1->anchor.signature == DDF1_HEADER ||
- ddf1->anchor.signature == DDF1_HEADER_BACKWARDS;
+ ddf1->anchor.signature == DDF1_HEADER_BACKWARDS;
}
/* Try to find DDF1 metadata at a given offset (ddf1_sboffset) */
-static struct ddf1 *try_to_find_ddf1(struct lib_context *lc,
- struct dev_info *di,
- size_t *sz, uint64_t *offset,
- union read_info *info,
- uint64_t ddf1_sboffset)
+static struct ddf1 *
+try_to_find_ddf1(struct lib_context *lc,
+ struct dev_info *di,
+ size_t * sz, uint64_t * offset,
+ union read_info *info, uint64_t ddf1_sboffset)
{
struct ddf1 *ddf1;
@@ -515,8 +523,7 @@
goto err;
if (!read_file(lc, handler, di->path, &ddf1->anchor, to_bytes(1),
- ddf1_sboffset) ||
- !is_ddf1(lc, di, ddf1))
+ ddf1_sboffset) || !is_ddf1(lc, di, ddf1))
goto bad;
ddf1->anchor_offset = ddf1_sboffset;
@@ -531,9 +538,9 @@
if (read_extended(lc, di, ddf1))
return ddf1;
- bad:
+ bad:
dbg_free(ddf1);
- err:
+ err:
return NULL;
}
@@ -543,9 +550,9 @@
* Note that the struct should be fully converted to the correct endianness
* by the time this function returns.
*/
-static void *read_metadata_areas(struct lib_context *lc, struct dev_info *di,
- size_t *sz, uint64_t *offset,
- union read_info *info)
+static void *
+read_metadata_areas(struct lib_context *lc, struct dev_info *di,
+ size_t * sz, uint64_t * offset, union read_info *info)
{
struct ddf1 *ddf1;
@@ -560,8 +567,8 @@
}
/* This is all hogwash since file_metadata can only be called once... */
-static void file_metadata_areas(struct lib_context *lc, struct dev_info *di,
- void *meta)
+static void
+file_metadata_areas(struct lib_context *lc, struct dev_info *di, void *meta)
{
uint8_t *buf;
uint64_t start = ddf1_beginning(meta);
@@ -571,14 +578,14 @@
file_metadata(lc, handler, di->path, buf,
to_bytes(di->sectors - start), to_bytes(start));
dbg_free(buf);
- file_dev_size(lc, handler, di); /* Record the device size. */
+ file_dev_size(lc, handler, di); /* Record the device size. */
}
}
static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
struct dev_info *di, void *meta, union read_info *info);
-static struct raid_dev *ddf1_read(struct lib_context *lc,
- struct dev_info *di)
+static struct raid_dev *
+ddf1_read(struct lib_context *lc, struct dev_info *di)
{
/*
* NOTE: Everything called after read_metadata_areas assumes that
@@ -590,7 +597,8 @@
}
/* Compose an "identifier" for use as a sort key for raid sets. */
-static inline int compose_id(struct ddf1 *ddf1, struct raid_dev *rd)
+static inline int
+compose_id(struct ddf1 *ddf1, struct raid_dev *rd)
{
struct ddf1_phys_drive *pd = get_phys_drive(ddf1);
int i = get_config_byoffset(ddf1, pd, rd->offset);
@@ -599,24 +607,27 @@
}
/* No sort. */
-static int no_sort(struct list_head *pos, struct list_head *new)
+static int
+no_sort(struct list_head *pos, struct list_head *new)
{
return 0;
}
/* Sort DDF1 devices by offset entry within a RAID set. */
-static int dev_sort(struct list_head *pos, struct list_head *new)
+static int
+dev_sort(struct list_head *pos, struct list_head *new)
{
struct raid_dev *rd_pos = RD(pos), *rd_new = RD(new);
return compose_id(META(GRP_RD(rd_new), ddf1), rd_new) <
- compose_id(META(GRP_RD(rd_pos), ddf1), rd_pos);
+ compose_id(META(GRP_RD(rd_pos), ddf1), rd_pos);
}
/*
* IO error event handler.
*/
-static int event_io(struct lib_context *lc, struct event_io *e_io)
+static int
+event_io(struct lib_context *lc, struct event_io *e_io)
{
log_err(lc, "%s: I/O error on device %s at sector %lu.\n",
handler, e_io->rd->di->path, e_io->sector);
@@ -626,30 +637,30 @@
#if 0
/* FIXME: This should not use META() directly? */
- struct raid_dev *rd = e_io->rd;
- struct ddf1 *ddf1 = META(rd, ddf1);
- struct ddf1_raid_configline *cl = this_disk(ddf1);
- struct ddf1_raid_configline *fwl = find_logical(ddf1);
+struct raid_dev *rd = e_io->rd;
+struct ddf1 *ddf1 = META(rd, ddf1);
+struct ddf1_raid_configline *cl = this_disk(ddf1);
+struct ddf1_raid_configline *fwl = find_logical(ddf1);
/* Ignore if we've already marked this disk broken(?) */
- if (rd->status & s_broken)
- return 0;
-
+if (rd->status & s_broken)
+ return 0;
+
/* Mark the array as degraded and the disk as failed. */
- rd->status = s_broken;
- cl->raidstate = LSU_COMPONENT_STATE_FAILED;
- fwl->raidstate = LSU_COMPONENT_STATE_DEGRADED;
+rd->status = s_broken;
+cl->raidstate = LSU_COMPONENT_STATE_FAILED;
+fwl->raidstate = LSU_COMPONENT_STATE_DEGRADED;
/* FIXME: Do we have to mark a parent too? */
/* Indicate that this is indeed a failure. */
- return 1;
+return 1;
}
#endif
#define NAME_SIZE 64
/* Formulate a RAID set name for this disk. */
-static char *name(struct lib_context *lc, struct ddf1 *ddf1,
- struct raid_dev *rd)
+static char *
+name(struct lib_context *lc, struct ddf1 *ddf1, struct raid_dev *rd)
{
int i, prefix;
char buf[NAME_SIZE];
@@ -661,8 +672,8 @@
return err_phys_drive(lc, rd->di);
i = get_config_byoffset(ddf1, pd, rd->offset);
- cr = get_config(ddf1, pd, i);
- if (i < 0 || !cr) {
+ cr = get_config(ddf1, pd, i);
+ if (i < 0 || !cr) {
sprintf(buf, DDF1_SPARES);
goto out;
}
@@ -677,29 +688,29 @@
memcpy(buf + prefix, vd->name, 16);
i = prefix + 16;
while (!isgraph(buf[--i]));
- buf[i+1] = 0;
+ buf[i + 1] = 0;
} else {
char *b;
for (b = buf + prefix, i = 0; i < 24; b += 8, i += 4)
sprintf(b, "%02x%02x%02x%02x",
- vd->guid[i], vd->guid[i+1],
- vd->guid[i+2], vd->guid[i+3]);
+ vd->guid[i], vd->guid[i + 1],
+ vd->guid[i + 2], vd->guid[i + 3]);
}
- out:
- return dbg_strdup(buf); /* Only return the needed allocation */
+ out:
+ return dbg_strdup(buf); /* Only return the needed allocation */
}
/* Figure out the real size of a disk... */
-static uint64_t get_size(struct lib_context *lc, struct ddf1 *ddf1,
- struct ddf1_config_record *cr,
- struct ddf1_phys_drive *pd)
+static uint64_t
+get_size(struct lib_context *lc, struct ddf1 *ddf1,
+ struct ddf1_config_record *cr, struct ddf1_phys_drive *pd)
{
if (cr && cr->sectors)
/* Some Adaptec controllers need this clamping. */
return type(lc, ddf1, cr) == t_raid0 ?
- cr->sectors - cr->sectors % stride(cr) : cr->sectors;
+ cr->sectors - cr->sectors % stride(cr) : cr->sectors;
return pd->size;
}
@@ -710,9 +721,9 @@
* function is successful, NULL if not. rd_group is the raid device that
* represents the entire disk drive.
*/
-static struct raid_set *group_rd(struct lib_context *lc,
- struct raid_set *rs_group,
- struct raid_dev *rd_group)
+static struct raid_set *
+group_rd(struct lib_context *lc,
+ struct raid_set *rs_group, struct raid_dev *rd_group)
{
struct ddf1 *ddf1 = META(rd_group, ddf1);
struct raid_set *rs = NULL;
@@ -721,7 +732,7 @@
struct ddf1_phys_drive *pd;
struct ddf1_group_info *gi;
unsigned int devs, i;
-
+
if (!(pd = get_phys_drive(ddf1)))
return err_phys_drive(lc, rd_group->di);
@@ -747,7 +758,7 @@
* If we have a virtual drive config without an entry in the
* list of virtual drives, we ignore it. Weird bug seen on
* Adaptec 2410SA controller.
- */
+ */
if (!(rd->name = name(lc, ddf1, rd))) {
free_raid_dev(lc, &rd);
continue;
@@ -789,7 +800,8 @@
*
* FIXME: We haven't been able to set up a RAID10 for testing...
*/
-static struct raid_set *ddf1_group(struct lib_context *lc, struct raid_dev *rd)
+static struct raid_set *
+ddf1_group(struct lib_context *lc, struct raid_dev *rd)
{
struct ddf1 *ddf1 = META(rd, ddf1);
struct ddf1_phys_drive *pd;
@@ -810,8 +822,7 @@
* (Is this really necessary?)
*/
if (!(rs = find_or_alloc_raid_set(lc, rd->name, FIND_TOP, rd,
- LC_RS(lc), NO_CREATE,
- NO_CREATE_ARG)))
+ LC_RS(lc), NO_CREATE, NO_CREATE_ARG)))
return NULL;
rs->type = t_group;
@@ -822,19 +833,20 @@
}
/* Write metadata. */
-static int ddf1_write(struct lib_context *lc, struct raid_dev *rd, int erase)
+static int
+ddf1_write(struct lib_context *lc, struct raid_dev *rd, int erase)
{
int ret;
- struct ddf1 *ddf1 = META(rd, ddf1);
+ struct ddf1 *ddf1 = META(rd, ddf1);
if (ddf1->adaptec_mode)
ddf1_update_all_crcs(lc, rd->di, ddf1);
- ddf1_cvt_all(lc, ddf1, rd->di);
- ret = write_metadata(lc, handler, rd, -1, erase);
- ddf1_cvt_all(lc, ddf1, rd->di);
+ ddf1_cvt_all(lc, ddf1, rd->di);
+ ret = write_metadata(lc, handler, rd, -1, erase);
+ ddf1_cvt_all(lc, ddf1, rd->di);
- return ret;
+ return ret;
}
/*
@@ -842,7 +854,8 @@
*/
/* Retrieve the number of devices that should be in this set. */
-static unsigned int device_count(struct raid_dev *rd, void *context)
+static unsigned int
+device_count(struct raid_dev *rd, void *context)
{
/* Get the logical drive */
struct ddf1_config_record *cr =
@@ -852,8 +865,9 @@
}
/* Check a RAID device */
-static int check_rd(struct lib_context *lc, struct raid_set *rs,
- struct raid_dev *rd, void *context)
+static int
+check_rd(struct lib_context *lc, struct raid_set *rs,
+ struct raid_dev *rd, void *context)
{
/*
* FIXME: Should we do more checking for brokenness here?
@@ -863,7 +877,8 @@
}
/* Start the recursive RAID set check. */
-static int ddf1_check(struct lib_context *lc, struct raid_set *rs)
+static int
+ddf1_check(struct lib_context *lc, struct raid_set *rs)
{
return check_raid_set(lc, rs, device_count, NULL, check_rd,
NULL, handler);
@@ -871,36 +886,38 @@
static struct event_handlers ddf1_event_handlers = {
.io = event_io,
- .rd = NULL, /* FIXME: no device add/remove event handler yet. */
+ .rd = NULL, /* FIXME: no device add/remove event handler yet. */
};
#ifdef DMRAID_NATIVE_LOG
/*
* Log native information about the RAID device.
*/
-static void ddf1_log(struct lib_context *lc, struct raid_dev *rd)
+static void
+ddf1_log(struct lib_context *lc, struct raid_dev *rd)
{
ddf1_dump_all(lc, rd->di, META(rd, ddf1), handler);
}
#endif /* #ifdef DMRAID_NATIVE_LOG */
static struct dmraid_format ddf1_format = {
- .name = HANDLER,
- .descr = "SNIA DDF1",
- .caps = "0,1,4,5,linear",
+ .name = HANDLER,
+ .descr = "SNIA DDF1",
+ .caps = "0,1,4,5,linear",
.format = FMT_RAID,
- .read = ddf1_read,
- .write = ddf1_write,
- .group = ddf1_group,
- .check = ddf1_check,
- .events = &ddf1_event_handlers,
+ .read = ddf1_read,
+ .write = ddf1_write,
+ .group = ddf1_group,
+ .check = ddf1_check,
+ .events = &ddf1_event_handlers,
#ifdef DMRAID_NATIVE_LOG
- .log = ddf1_log,
+ .log = ddf1_log,
#endif
};
/* Register this format handler with the format core */
-int register_ddf1(struct lib_context *lc)
+int
+register_ddf1(struct lib_context *lc)
{
return register_format_handler(lc, &ddf1_format);
}
@@ -908,8 +925,9 @@
/*
* Set up a RAID device from what we've assembled out of the metadata.
*/
-static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta, union read_info *info)
+static int
+setup_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct dev_info *di, void *meta, union read_info *info)
{
unsigned int i, ma_count = 5;
struct ddf1 *ddf1 = meta;
@@ -918,7 +936,7 @@
if (!(pd = get_phys_drive(ddf1)))
LOG_ERR(lc, 0, "%s: Cannot find physical drive description "
- "on %s!", handler, di->path);
+ "on %s!", handler, di->path);
/* We need multiple metadata areas */
ma_count += ddf1->adapter ? 1 : 0;
@@ -969,7 +987,7 @@
ma->area = ddf1->cfg;
/* Now set up the rest of the metadata info */
- rd->di = di;
+ rd->di = di;
rd->fmt = &ddf1_format;
rd->status = disk_status(pd);
rd->type = t_group;
--- dmraid/lib/format/ddf/ddf1.h 2008/02/22 17:04:35 1.1
+++ dmraid/lib/format/ddf/ddf1.h 2008/06/20 21:52:17 1.2
@@ -91,160 +91,160 @@
/* The DDF1 header table */
struct ddf1_header {
- uint32_t signature;
- uint32_t crc;
- uint8_t guid[DDF1_GUID_LENGTH];
- uint8_t ddf_rev[DDF1_REV_LENGTH];
- uint32_t seqnum;
- uint32_t timestamp;
- uint8_t open_flag;
- uint8_t foreign_flag;
- uint8_t grouping_enforced;
- uint8_t reserved2[45];
- uint64_t primary_table_lba;
- uint64_t secondary_table_lba;
- uint8_t header_type;
- uint8_t reserved3[3];
- uint32_t workspace_length;
- uint64_t workspace_lba;
- uint16_t max_phys_drives;
- uint16_t max_virt_drives;
- uint16_t max_partitions;
- uint16_t vd_config_record_len;
- uint16_t max_primary_elements;
- uint8_t reserved4[54];
- uint32_t adapter_data_offset;
- uint32_t adapter_data_len;
- uint32_t phys_drive_offset;
- uint32_t phys_drive_len;
- uint32_t virt_drive_offset;
- uint32_t virt_drive_len;
- uint32_t config_record_offset;
- uint32_t config_record_len;
- uint32_t disk_data_offset;
- uint32_t disk_data_len;
- uint32_t badblock_offset;
- uint32_t badblock_len;
- uint32_t diag_offset;
- uint32_t diag_len;
- uint32_t vendor_offset;
- uint32_t vendor_len;
- uint8_t reserved5[256];
+ uint32_t signature;
+ uint32_t crc;
+ uint8_t guid[DDF1_GUID_LENGTH];
+ uint8_t ddf_rev[DDF1_REV_LENGTH];
+ uint32_t seqnum;
+ uint32_t timestamp;
+ uint8_t open_flag;
+ uint8_t foreign_flag;
+ uint8_t grouping_enforced;
+ uint8_t reserved2[45];
+ uint64_t primary_table_lba;
+ uint64_t secondary_table_lba;
+ uint8_t header_type;
+ uint8_t reserved3[3];
+ uint32_t workspace_length;
+ uint64_t workspace_lba;
+ uint16_t max_phys_drives;
+ uint16_t max_virt_drives;
+ uint16_t max_partitions;
+ uint16_t vd_config_record_len;
+ uint16_t max_primary_elements;
+ uint8_t reserved4[54];
+ uint32_t adapter_data_offset;
+ uint32_t adapter_data_len;
+ uint32_t phys_drive_offset;
+ uint32_t phys_drive_len;
+ uint32_t virt_drive_offset;
+ uint32_t virt_drive_len;
+ uint32_t config_record_offset;
+ uint32_t config_record_len;
+ uint32_t disk_data_offset;
+ uint32_t disk_data_len;
+ uint32_t badblock_offset;
+ uint32_t badblock_len;
+ uint32_t diag_offset;
+ uint32_t diag_len;
+ uint32_t vendor_offset;
+ uint32_t vendor_len;
+ uint8_t reserved5[256];
} __attribute__ ((packed));
/* The adapter data header */
struct ddf1_adapter {
- uint32_t signature;
- uint32_t crc;
- uint8_t guid[DDF1_GUID_LENGTH];
- uint16_t pci_vendor;
- uint16_t pci_device;
- uint16_t pci_subvendor;
- uint16_t pci_subdevice;
- uint8_t reserved2[24];
- uint8_t adapter_data[448];
+ uint32_t signature;
+ uint32_t crc;
+ uint8_t guid[DDF1_GUID_LENGTH];
+ uint16_t pci_vendor;
+ uint16_t pci_device;
+ uint16_t pci_subvendor;
+ uint16_t pci_subdevice;
+ uint8_t reserved2[24];
+ uint8_t adapter_data[448];
} __attribute__ ((packed));
/* Physical drive info */
struct ddf1_disk_data {
- uint32_t signature;
- uint32_t crc;
- uint8_t guid[DDF1_GUID_LENGTH];
- uint32_t reference;
- uint8_t forced_ref_flag;
- uint8_t forced_guid_flag;
- uint8_t scratch[32];
- uint8_t reserved[442];
+ uint32_t signature;
+ uint32_t crc;
+ uint8_t guid[DDF1_GUID_LENGTH];
+ uint32_t reference;
+ uint8_t forced_ref_flag;
+ uint8_t forced_guid_flag;
+ uint8_t scratch[32];
+ uint8_t reserved[442];
} __attribute__ ((packed));
/* Physical drive record header */
struct ddf1_phys_drives {
- uint32_t signature;
- uint32_t crc;
- uint16_t num_drives;
- uint16_t max_drives;
- uint8_t reserved2[52];
+ uint32_t signature;
+ uint32_t crc;
+ uint16_t num_drives;
+ uint16_t max_drives;
+ uint8_t reserved2[52];
/* 64 bytes */
/* Drive records follow */
} __attribute__ ((packed));
/* Physical drive record */
struct ddf1_phys_drive {
- uint8_t guid[DDF1_GUID_LENGTH];
- uint32_t reference;
- uint16_t type;
- uint16_t state;
- uint64_t size;
- uint8_t path_info[18];
- uint8_t reserved3[6];
+ uint8_t guid[DDF1_GUID_LENGTH];
+ uint32_t reference;
+ uint16_t type;
+ uint16_t state;
+ uint64_t size;
+ uint8_t path_info[18];
+ uint8_t reserved3[6];
} __attribute__ ((packed));
/* Virtual drive record header */
struct ddf1_virt_drives {
- uint32_t signature;
- uint32_t crc;
- uint16_t num_drives;
- uint16_t max_drives;
- uint8_t reserved2[52];
+ uint32_t signature;
+ uint32_t crc;
+ uint16_t num_drives;
+ uint16_t max_drives;
+ uint8_t reserved2[52];
/* Drive records follow */
} __attribute__ ((packed));
/* Virtual drive record */
struct ddf1_virt_drive {
- uint8_t guid[DDF1_GUID_LENGTH];
- uint16_t vd_num;
- uint16_t reserved2;
- uint32_t type;
- uint8_t state;
- uint8_t init_state;
- uint8_t reserved3[14];
- uint8_t name[16];
+ uint8_t guid[DDF1_GUID_LENGTH];
+ uint16_t vd_num;
+ uint16_t reserved2;
+ uint32_t type;
+ uint8_t state;
+ uint8_t init_state;
+ uint8_t reserved3[14];
+ uint8_t name[16];
} __attribute__ ((packed));
/* Virtual disk configuration record. */
struct ddf1_config_record {
- uint32_t signature;
- uint32_t crc;
- uint8_t guid[DDF1_GUID_LENGTH];
- uint32_t timestamp;
- uint32_t seqnum;
- uint8_t reserved[24];
- uint16_t primary_element_count;
- uint8_t stripe_size;
- uint8_t raid_level;
- uint8_t raid_qualifier;
- uint8_t secondary_element_count;
- uint8_t secondary_element_number;
- uint8_t secondary_element_raid_level;
- uint64_t sectors;
- uint64_t size;
- uint64_t reserved2;
- uint32_t spares[8];
- uint64_t cache_policy;
- uint8_t bg_task_rate;
+ uint32_t signature;
+ uint32_t crc;
+ uint8_t guid[DDF1_GUID_LENGTH];
+ uint32_t timestamp;
+ uint32_t seqnum;
+ uint8_t reserved[24];
+ uint16_t primary_element_count;
+ uint8_t stripe_size;
+ uint8_t raid_level;
+ uint8_t raid_qualifier;
+ uint8_t secondary_element_count;
+ uint8_t secondary_element_number;
+ uint8_t secondary_element_raid_level;
+ uint64_t sectors;
+ uint64_t size;
+ uint64_t reserved2;
+ uint32_t spares[8];
+ uint64_t cache_policy;
+ uint8_t bg_task_rate;
/* 137 bytes */
- uint8_t reserved3[3+52+192+32+32+16+16+32];
+ uint8_t reserved3[3 + 52 + 192 + 32 + 32 + 16 + 16 + 32];
/* 512 bytes */
} __attribute__ ((packed));
/* Spare disk record */
struct ddf1_spare {
- uint8_t guid[DDF1_GUID_LENGTH];
- uint16_t secondary_element;
- uint8_t reserved[6];
+ uint8_t guid[DDF1_GUID_LENGTH];
+ uint16_t secondary_element;
+ uint8_t reserved[6];
} __attribute__ ((packed));
/* Spare disk assignment record */
struct ddf1_spare_header {
- uint32_t signature;
- uint32_t crc;
- uint32_t timestamp;
- uint8_t reserved[7];
- uint8_t type;
- uint16_t num_spares;
- uint16_t max_spares;
- uint8_t reserved2[8];
- struct ddf1_spare spares[0];
+ uint32_t signature;
+ uint32_t crc;
+ uint32_t timestamp;
+ uint8_t reserved[7];
+ uint8_t type;
+ uint16_t num_spares;
+ uint16_t max_spares;
+ uint8_t reserved2[8];
+ struct ddf1_spare spares[0];
} __attribute__ ((packed));
/* Metadata owner */
--- dmraid/lib/format/ddf/ddf1_crc.c 2008/04/02 13:35:31 1.3
+++ dmraid/lib/format/ddf/ddf1_crc.c 2008/06/20 21:52:17 1.4
@@ -4,8 +4,8 @@
* Copyright (C) 2005-2006 IBM, All rights reserved.
* Written by James Simshaw <simshawj at us.ibm.com>
*
- * Copyright (C) 2006 Heinz Mauelshagen, Red Hat GmbH
- * All rights reserved.
+ * Copyright (C) 2006-2008 Heinz Mauelshagen, Red Hat GmbH
+ * All rights reserved.
*
* See file LICENSE at the top of this source tree for license information.
*/
@@ -28,9 +28,10 @@
/* Make the table for a fast CRC. */
#define CRC_TABLE_SIZE 256
-static inline void crc_table_init(uint32_t *crc_table)
+static inline void
+crc_table_init(uint32_t * crc_table)
{
- static int new = 1; /* Flag for table not yet computed. */
+ static int new = 1; /* Flag for table not yet computed. */
if (new) {
uint32_t c, n, k;
@@ -49,15 +50,16 @@
* crc() routine below).
*/
/* Return the CRC of the bytes buf[0..len-1]. */
-static uint32_t crc(uint32_t crc, unsigned char *buf, int len)
+static uint32_t
+crc(uint32_t crc, unsigned char *buf, int len)
{
int n;
- static uint32_t crc_table[CRC_TABLE_SIZE]; /* CRCs of 8-bit messages. */
+ static uint32_t crc_table[CRC_TABLE_SIZE]; /* CRCs of 8-bit messages. */
crc_table_init(crc_table);
for (n = 0; n < len; n++)
crc = crc_table[(crc ^ buf[n]) & (CRC_TABLE_SIZE - 1)] ^
- (crc >> 8);
+ (crc >> 8);
return crc ^ 0xFFFFFFFFL;
}
@@ -71,7 +73,8 @@
};
/* Compute the checksum of a table */
-static uint32_t do_crc32(struct lib_context *lc, struct crc_info *ci)
+static uint32_t
+do_crc32(struct lib_context *lc, struct crc_info *ci)
{
uint32_t old_csum = *ci->crc, ret = 0xFFFFFFFF;
@@ -82,7 +85,8 @@
}
/* Return VD record size. */
-static inline size_t record_size(struct ddf1 *ddf1)
+static inline size_t
+record_size(struct ddf1 *ddf1)
{
return ddf1->primary->vd_config_record_len * DDF1_BLKSIZE;
}
@@ -108,8 +112,8 @@
/* Process the configuration records to have their CRCs updated */
-static int update_cfg_crc(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1)
+static int
+update_cfg_crc(struct lib_context *lc, struct dev_info *di, struct ddf1 *ddf1)
{
static struct ddf1_record_handler handlers = {
.vd = crc32_vd,
@@ -121,17 +125,17 @@
}
/* Checks the CRC for a particular table */
-static int check_crc(struct lib_context *lc, struct dev_info *di,
- struct crc_info *ci)
+static int
+check_crc(struct lib_context *lc, struct dev_info *di, struct crc_info *ci)
{
uint32_t crc32;
crc32 = do_crc32(lc, ci);
if (*ci->crc != crc32)
log_print(lc, "%s: %s with CRC %X, expected %X on %s",
- HANDLER, ci->text, crc32, *ci->crc, di->path);
-
-
+ HANDLER, ci->text, crc32, *ci->crc, di->path);
+
+
return 1;
}
@@ -155,8 +159,8 @@
#undef CHECK_CRC
/* Process the configuration records to have their CRCs checked */
-static int check_cfg_crc(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1)
+static int
+check_cfg_crc(struct lib_context *lc, struct dev_info *di, struct ddf1 *ddf1)
{
struct ddf1_record_handler handlers = {
.vd = vd_check_crc,
@@ -169,27 +173,35 @@
/* Processes all of the DDF1 information for having their CRCs updated*/
enum all_type { CHECK, UPDATE };
-static int all_crcs(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1, enum all_type type)
+static int
+all_crcs(struct lib_context *lc, struct dev_info *di,
+ struct ddf1 *ddf1, enum all_type type)
{
int ret = 1;
uint32_t crc;
struct crc_info crcs[] = {
- { ddf1->primary, &ddf1->primary->crc,
- sizeof(*ddf1->primary), "primary header" },
- { ddf1->secondary, &ddf1->secondary->crc,
- sizeof(*ddf1->secondary), "secondary header" },
- { ddf1->adapter, &ddf1->adapter->crc,
- ddf1->primary->adapter_data_len * DDF1_BLKSIZE, "adapter" },
- { ddf1->disk_data, &ddf1->disk_data->crc,
- ddf1->primary->disk_data_len * DDF1_BLKSIZE, "disk data" },
- { ddf1->pd_header, &ddf1->pd_header->crc,
- ddf1->primary->phys_drive_len * DDF1_BLKSIZE,
- "physical drives" },
- { ddf1->vd_header, &ddf1->vd_header->crc,
- ddf1->primary->virt_drive_len * DDF1_BLKSIZE,
- "virtual drives" },
- }, *c = ARRAY_END(crcs);
+ {ddf1->primary, &ddf1->primary->crc,
+ sizeof(*ddf1->primary), "primary header"}
+ ,
+ {ddf1->secondary, &ddf1->secondary->crc,
+ sizeof(*ddf1->secondary), "secondary header"}
+ ,
+ {ddf1->adapter, &ddf1->adapter->crc,
+ ddf1->primary->adapter_data_len * DDF1_BLKSIZE, "adapter"}
+ ,
+ {ddf1->disk_data, &ddf1->disk_data->crc,
+ ddf1->primary->disk_data_len * DDF1_BLKSIZE, "disk data"}
+ ,
+ {ddf1->pd_header, &ddf1->pd_header->crc,
+ ddf1->primary->phys_drive_len * DDF1_BLKSIZE,
+ "physical drives"}
+ ,
+ {ddf1->vd_header, &ddf1->vd_header->crc,
+ ddf1->primary->virt_drive_len * DDF1_BLKSIZE,
+ "virtual drives"}
+ ,
+ }
+ , *c = ARRAY_END(crcs);
while (c-- > crcs) {
if (c->p) {
@@ -203,19 +215,21 @@
}
return type == CHECK ? (ret & check_cfg_crc(lc, di, ddf1)) :
- update_cfg_crc(lc, di, ddf1);
+ update_cfg_crc(lc, di, ddf1);
}
/* Processes the tables to check their CRCs */
-int ddf1_check_all_crcs(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1)
+int
+ddf1_check_all_crcs(struct lib_context *lc, struct dev_info *di,
+ struct ddf1 *ddf1)
{
return all_crcs(lc, di, ddf1, CHECK);
}
/* Processes all of the DDF1 information for having their CRCs updated */
-void ddf1_update_all_crcs(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1)
+void
+ddf1_update_all_crcs(struct lib_context *lc, struct dev_info *di,
+ struct ddf1 *ddf1)
{
all_crcs(lc, di, ddf1, UPDATE);
}
--- dmraid/lib/format/ddf/ddf1_cvt.c 2008/02/22 17:04:35 1.1
+++ dmraid/lib/format/ddf/ddf1_cvt.c 2008/06/20 21:52:17 1.2
@@ -20,7 +20,8 @@
#include <datastruct/byteorder.h>
/* Convert a DDF header */
-void ddf1_cvt_header(struct ddf1 *ddf1, struct ddf1_header *hdr)
+void
+ddf1_cvt_header(struct ddf1 *ddf1, struct ddf1_header *hdr)
{
if (BYTE_ORDER == ddf1->disk_format)
return;
@@ -57,7 +58,8 @@
}
/* Convert DDF adapter data */
-void ddf1_cvt_adapter(struct ddf1 *ddf1, struct ddf1_adapter *hdr)
+void
+ddf1_cvt_adapter(struct ddf1 *ddf1, struct ddf1_adapter *hdr)
{
if (BYTE_ORDER == ddf1->disk_format)
return;
@@ -71,7 +73,8 @@
}
/* Convert physical disk data */
-void ddf1_cvt_disk_data(struct ddf1 *ddf1, struct ddf1_disk_data *hdr)
+void
+ddf1_cvt_disk_data(struct ddf1 *ddf1, struct ddf1_disk_data *hdr)
{
if (BYTE_ORDER == ddf1->disk_format)
return;
@@ -82,7 +85,8 @@
}
/* Convert physical drive header data */
-void ddf1_cvt_phys_drive_header(struct ddf1 *ddf1, struct ddf1_phys_drives *hdr)
+void
+ddf1_cvt_phys_drive_header(struct ddf1 *ddf1, struct ddf1_phys_drives *hdr)
{
if (BYTE_ORDER == ddf1->disk_format)
return;
@@ -94,7 +98,8 @@
}
/* Convert physical drive data */
-void ddf1_cvt_phys_drive(struct ddf1 *ddf1, struct ddf1_phys_drive *hdr)
+void
+ddf1_cvt_phys_drive(struct ddf1 *ddf1, struct ddf1_phys_drive *hdr)
{
if (BYTE_ORDER == ddf1->disk_format)
return;
@@ -106,7 +111,8 @@
}
/* Convert virtual drive header data */
-void ddf1_cvt_virt_drive_header(struct ddf1 *ddf1, struct ddf1_virt_drives *hdr)
+void
+ddf1_cvt_virt_drive_header(struct ddf1 *ddf1, struct ddf1_virt_drives *hdr)
{
if (BYTE_ORDER == ddf1->disk_format)
return;
@@ -118,7 +124,8 @@
}
/* Convert virtual drive data */
-void ddf1_cvt_virt_drive(struct ddf1 *ddf1, struct ddf1_virt_drive *hdr)
+void
+ddf1_cvt_virt_drive(struct ddf1 *ddf1, struct ddf1_virt_drive *hdr)
{
if (BYTE_ORDER == ddf1->disk_format)
return;
@@ -128,8 +135,9 @@
}
/* Convert config record data */
-int ddf1_cvt_config_record(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1, int idx)
+int
+ddf1_cvt_config_record(struct lib_context *lc, struct dev_info *di,
+ struct ddf1 *ddf1, int idx)
{
unsigned int i;
uint16_t max_pds;
@@ -148,7 +156,8 @@
if (ddf1->primary->signature == DDF1_HEADER_BACKWARDS)
CVT32(x);
- off = ((uint64_t*) (((uint8_t*) hdr) + sizeof(*hdr) + (x * sizeof(x))));
+ off = ((uint64_t *) (((uint8_t *) hdr) + sizeof(*hdr) +
+ (x * sizeof(x))));
CVT32(hdr->signature);
CVT32(hdr->crc);
@@ -172,8 +181,9 @@
}
/* Convert spare records */
-int ddf1_cvt_spare_record(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1, int idx)
+int
+ddf1_cvt_spare_record(struct lib_context *lc, struct dev_info *di,
+ struct ddf1 *ddf1, int idx)
{
uint16_t x, i;
struct ddf1_spare_header *sh = SR(ddf1, idx);
@@ -196,7 +206,8 @@
return 1;
}
-void ddf1_cvt_records(struct lib_context *lc, struct dev_info *di,
+void
+ddf1_cvt_records(struct lib_context *lc, struct dev_info *di,
struct ddf1 *ddf1, int in_cpu_format)
{
static struct ddf1_record_handler handlers = {
@@ -208,8 +219,8 @@
}
/* Convert endianness of all metadata */
-void ddf1_cvt_all(struct lib_context *lc, struct ddf1 *ddf1,
- struct dev_info *di)
+void
+ddf1_cvt_all(struct lib_context *lc, struct ddf1 *ddf1, struct dev_info *di)
{
int i;
uint16_t pds = 0, vds = 0;
--- dmraid/lib/format/ddf/ddf1_cvt.h 2008/02/22 17:04:35 1.1
+++ dmraid/lib/format/ddf/ddf1_cvt.h 2008/06/20 21:52:17 1.2
@@ -29,7 +29,7 @@
int ddf1_cvt_spare_record(struct lib_context *lc, struct dev_info *di,
struct ddf1 *ddf1, int idx);
void ddf1_cvt_records(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1, int in_cpu_format);
+ struct ddf1 *ddf1, int in_cpu_format);
void ddf1_cvt_all(struct lib_context *lc, struct ddf1 *ddf1,
struct dev_info *di);
--- dmraid/lib/format/ddf/ddf1_dump.c 2008/02/22 17:04:35 1.1
+++ dmraid/lib/format/ddf/ddf1_dump.c 2008/06/20 21:52:17 1.2
@@ -28,8 +28,9 @@
_dp_guid(lc, name, P_OFF(x, basevar, x), DDF1_GUID_LENGTH);\
} while (0)
-static void _dp_guid(struct lib_context *lc, const char *name,
- unsigned int offset, void *data, unsigned int len)
+static void
+_dp_guid(struct lib_context *lc, const char *name,
+ unsigned int offset, void *data, unsigned int len)
{
char *p;
int i;
@@ -52,17 +53,19 @@
#endif
/* Dump top */
-static void dump_top(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1, const char *handler)
+static void
+dump_top(struct lib_context *lc, struct dev_info *di,
+ struct ddf1 *ddf1, const char *handler)
{
log_print(lc, "%s (%s):", di->path, handler);
log_print(lc, "DDF1 anchor at %llu with tables in %s-endian format.",
ddf1->anchor_offset / DDF1_BLKSIZE,
(ddf1->disk_format == LITTLE_ENDIAN ? "little" : "big"));
}
-
+
/* Dump DDF tables. */
-static void dump_header(struct lib_context *lc, struct ddf1_header *dh)
+static void
+dump_header(struct lib_context *lc, struct ddf1_header *dh)
{
if (!dh)
return;
@@ -105,7 +108,8 @@
DP("vendor_len:\t%d", dh, dh->vendor_len);
}
-static void dump_adapter(struct lib_context *lc, struct ddf1_adapter *da)
+static void
+dump_adapter(struct lib_context *lc, struct ddf1_adapter *da)
{
if (!da)
return;
@@ -120,7 +124,8 @@
DP("pci subdevice:\t0x%X", da, da->pci_subdevice);
}
-static void dump_disk_data(struct lib_context *lc, struct ddf1_disk_data *fg)
+static void
+dump_disk_data(struct lib_context *lc, struct ddf1_disk_data *fg)
{
log_print(lc, "Disk Data at %p", fg);
DP("signature:\t0x%X", fg, fg->signature);
@@ -131,8 +136,8 @@
DP("forced_guid_flag:\t%d", fg, fg->forced_guid_flag);
}
-static void dump_phys_drive_header(struct lib_context *lc,
- struct ddf1_phys_drives *pd)
+static void
+dump_phys_drive_header(struct lib_context *lc, struct ddf1_phys_drives *pd)
{
log_print(lc, "Physical Drive Header at %p", pd);
DP("signature:\t0x%X", pd, pd->signature);
@@ -141,7 +146,8 @@
DP("max drives:\t%d", pd, pd->max_drives);
}
-static void dump_phys_drive(struct lib_context *lc, struct ddf1_phys_drive *pd)
+static void
+dump_phys_drive(struct lib_context *lc, struct ddf1_phys_drive *pd)
{
log_print(lc, "Physical Drive at %p", pd);
DP_GUID("guid:\t\t", pd, pd->guid);
@@ -152,8 +158,8 @@
DP_BUF("path info:\t", pd, pd->path_info, 18);
}
-static void dump_virt_drive_header(struct lib_context *lc,
- struct ddf1_virt_drives *vd)
+static void
+dump_virt_drive_header(struct lib_context *lc, struct ddf1_virt_drives *vd)
{
log_print(lc, "Virtual Drive Header at %p", vd);
DP("signature:\t0x%X", vd, vd->signature);
@@ -162,7 +168,8 @@
DP("max drives:\t%d", vd, vd->max_drives);
}
-static void dump_virt_drive(struct lib_context *lc, struct ddf1_virt_drive *vd)
+static void
+dump_virt_drive(struct lib_context *lc, struct ddf1_virt_drive *vd)
{
log_print(lc, "Virtual Drive at %p", vd);
DP_GUID("guid:\t\t", vd, vd->guid);
@@ -173,8 +180,9 @@
DP_BUF("name:\t\t", vd, vd->name, 16);
}
-static int dump_config_record(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf, int idx)
+static int
+dump_config_record(struct lib_context *lc, struct dev_info *di,
+ struct ddf1 *ddf, int idx)
{
int i;
uint16_t x;
@@ -220,10 +228,11 @@
cfg_drive_offsets[i]);
}
return 1;
-}
+}
-static int dump_spares(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1, int idx)
+static int
+dump_spares(struct lib_context *lc, struct dev_info *di,
+ struct ddf1 *ddf1, int idx)
{
int i;
struct ddf1_spare_header *sh = SR(ddf1, idx);
@@ -244,8 +253,9 @@
return 1;
}
-static void dump_config_records(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1)
+static void
+dump_config_records(struct lib_context *lc, struct dev_info *di,
+ struct ddf1 *ddf1)
{
static struct ddf1_record_handler handlers = {
.vd = dump_config_record,
@@ -256,8 +266,9 @@
}
/* Dump the entire table */
-void ddf1_dump_all(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1, const char *handler)
+void
+ddf1_dump_all(struct lib_context *lc, struct dev_info *di,
+ struct ddf1 *ddf1, const char *handler)
{
int i;
--- dmraid/lib/format/ddf/ddf1_lib.c 2008/02/22 17:06:54 1.2
+++ dmraid/lib/format/ddf/ddf1_lib.c 2008/06/20 21:52:17 1.3
@@ -20,9 +20,10 @@
#include <datastruct/byteorder.h>
/* Figure out what endian conversions we need */
-int ddf1_endianness(struct lib_context *lc, struct ddf1 *ddf1)
+int
+ddf1_endianness(struct lib_context *lc, struct ddf1 *ddf1)
{
- uint8_t *ptr = (uint8_t*) &ddf1->anchor.signature;
+ uint8_t *ptr = (uint8_t *) & ddf1->anchor.signature;
if (ptr[0] == 0xDE && ptr[1] == 0x11)
return BIG_ENDIAN;
@@ -33,7 +34,8 @@
}
/* Find the beginning of all DDF metadata */
-uint64_t ddf1_beginning(struct ddf1 *ddf1)
+uint64_t
+ddf1_beginning(struct ddf1 *ddf1)
{
uint64_t start;
struct ddf1_header *h = &ddf1->anchor;
@@ -52,51 +54,52 @@
}
/* Helper for CR_OFF */
-uint16_t ddf1_cr_off_maxpds_helper(struct ddf1 *ddf1)
+uint16_t
+ddf1_cr_off_maxpds_helper(struct ddf1 * ddf1)
{
struct ddf1_header *h = ddf1->primary;
/* The 0xFFFF nonsense is a weird Adaptec quirk */
-// bz211016
-// return (h->max_primary_elements == 0xFFFF && ddf1->adaptec_mode) ?
+// bz211016
+// return (h->max_primary_elements == 0xFFFF && ddf1->adaptec_mode) ?
return (h->max_primary_elements == 0xFFFF) ?
h->max_phys_drives : h->max_primary_elements;
}
/* Process DDF1 records depending on type */
-int ddf1_process_records(struct lib_context *lc, struct dev_info *di,
- struct ddf1_record_handler *handler,
- struct ddf1 *ddf1, int in_cpu_format)
+int
+ddf1_process_records(struct lib_context *lc, struct dev_info *di,
+ struct ddf1_record_handler *handler,
+ struct ddf1 *ddf1, int in_cpu_format)
{
unsigned int i, cfgs = NUM_CONFIG_ENTRIES(ddf1);
uint32_t x;
for (i = 0; i < cfgs; i++) {
- x = *((uint32_t*) CR(ddf1, i));
- if (!in_cpu_format &&
- BYTE_ORDER != ddf1->disk_format)
+ x = *((uint32_t *) CR(ddf1, i));
+ if (!in_cpu_format && BYTE_ORDER != ddf1->disk_format)
CVT32(x);
switch (x) {
- case DDF1_VD_CONFIG_REC:
- if (!handler->vd(lc, di, ddf1, i))
- return 0;
+ case DDF1_VD_CONFIG_REC:
+ if (!handler->vd(lc, di, ddf1, i))
+ return 0;
- break;
+ break;
- case DDF1_SPARE_REC:
- if (!handler->spare(lc, di, ddf1, i))
- return 0;
+ case DDF1_SPARE_REC:
+ if (!handler->spare(lc, di, ddf1, i))
+ return 0;
- break;
+ break;
- case 0: /* Adaptec puts zero in this field??? */
- case DDF1_INVALID:
- break;
+ case 0: /* Adaptec puts zero in this field??? */
+ case DDF1_INVALID:
+ break;
- default:
- log_warn(lc, "%s: Unknown config record %d.",
- di->path, x);
+ default:
+ log_warn(lc, "%s: Unknown config record %d.",
+ di->path, x);
}
}
--- dmraid/lib/format/ddf/ddf1_lib.h 2008/02/22 17:04:35 1.1
+++ dmraid/lib/format/ddf/ddf1_lib.h 2008/06/20 21:52:17 1.2
@@ -14,12 +14,14 @@
#define _DDF1_LIB_H
/* Cpmpare two GUIDs */
-static inline uint8_t _and(uint8_t *p)
+static inline uint8_t
+_and(uint8_t * p)
{
return p[20] & p[21] & p[22] & p[23];
}
-static inline int guidcmp(uint8_t *one, uint8_t *two)
+static inline int
+guidcmp(uint8_t * one, uint8_t * two)
{
int x = memcmp(one, two, DDF1_GUID_LENGTH - 4);
@@ -30,20 +32,21 @@
}
/* Byte offset for sector */
-static inline uint64_t to_bytes(uint64_t sector)
+static inline uint64_t
+to_bytes(uint64_t sector)
{
return sector * DDF1_BLKSIZE;
}
-uint64_t ddf1_beginning(struct ddf1 *ddf1);
+uint64_t ddf1_beginning(struct ddf1 * ddf1);
uint16_t ddf1_cr_off_maxpds_helper(struct ddf1 *ddf1);
int ddf1_endianness(struct lib_context *lc, struct ddf1 *ddf1);
struct ddf1_record_handler {
- int (*vd)(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1, int idx);
- int (*spare)(struct lib_context *lc, struct dev_info *di,
- struct ddf1 *ddf1, int idx);
+ int (*vd) (struct lib_context * lc, struct dev_info * di,
+ struct ddf1 * ddf1, int idx);
+ int (*spare) (struct lib_context * lc, struct dev_info * di,
+ struct ddf1 * ddf1, int idx);
};
int ddf1_process_records(struct lib_context *lc, struct dev_info *di,
--- dmraid/lib/format/partition/dos.c 2008/04/02 13:35:31 1.3
+++ dmraid/lib/format/partition/dos.c 2008/06/20 21:52:18 1.4
@@ -25,19 +25,19 @@
static const char *handler = HANDLER;
/* Make up RAID device name. */
-static size_t _name(struct lib_context *lc, struct raid_dev *rd,
- unsigned short partition, char *str, size_t len,
- unsigned char type)
+static size_t
+_name(struct lib_context *lc, struct raid_dev *rd,
+ unsigned short partition, char *str, size_t len, unsigned char type)
{
const char *base = get_basename(lc, rd->di->path);
return type ? snprintf(str, len, "%s%s%u", base, OPT_STR_PARTCHAR(lc),
- partition) :
- snprintf(str, len, "%s", base);
+ partition) : snprintf(str, len, "%s", base);
}
-static char *name(struct lib_context *lc, struct raid_dev *rd,
- unsigned int part, unsigned char type)
+static char *
+name(struct lib_context *lc, struct raid_dev *rd,
+ unsigned int part, unsigned char type)
{
size_t len;
char *ret;
@@ -57,7 +57,8 @@
#if BYTE_ORDER == LITTLE_ENDIAN
# define to_cpu NULL
#else
-static void to_cpu(void *meta)
+static void
+to_cpu(void *meta)
{
struct dos *dos = meta;
struct dos_partition *part = dos->partitions;
@@ -71,7 +72,8 @@
}
#endif
-static int is_dos(struct lib_context *lc, struct dev_info *di, void *meta)
+static int
+is_dos(struct lib_context *lc, struct dev_info *di, void *meta)
{
struct dos *dos = meta;
struct dos_partition *part;
@@ -87,8 +89,8 @@
return 1;
}
-static void dos_file_metadata(struct lib_context *lc, struct dev_info *di,
- void *meta)
+static void
+dos_file_metadata(struct lib_context *lc, struct dev_info *di, void *meta)
{
if (OPT_DUMP(lc))
log_print(lc, "%s: filing metadata not supported (use fdisk "
@@ -98,7 +100,8 @@
/* Allocate a DOS partition sector struct and read the data. */
static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
struct dev_info *di, void *meta, union read_info *info);
-static struct raid_dev *dos_read(struct lib_context *lc, struct dev_info *di)
+static struct raid_dev *
+dos_read(struct lib_context *lc, struct dev_info *di)
{
return read_raid_dev(lc, di, NULL,
sizeof(struct dos), DOS_CONFIGOFFSET,
@@ -107,23 +110,24 @@
}
/* Support functions for dos_group to read the partition table(s). */
-static int part_is_extended (struct dos_partition *part)
+static int
+part_is_extended(struct dos_partition *part)
{
return part->type == PARTITION_EXT ||
- part->type == PARTITION_EXT_LBA ||
- part->type == PARTITION_LINUX_EXT;
+ part->type == PARTITION_EXT_LBA ||
+ part->type == PARTITION_LINUX_EXT;
}
/* Get a partition start offset relative to a base location. */
-static uint64_t get_part_start(const struct dos_partition *raw_part,
- uint64_t offset)
+static uint64_t
+get_part_start(const struct dos_partition *raw_part, uint64_t offset)
{
return (uint64_t) raw_part->start + offset;
}
/* RAID set allocation support function. */
-static struct raid_set *_alloc_raid_set(struct lib_context *lc,
- struct raid_dev *rd)
+static struct raid_set *
+_alloc_raid_set(struct lib_context *lc, struct raid_dev *rd)
{
struct raid_set *rs;
@@ -135,9 +139,9 @@
return NULL;
rs->status = rd->status;
- rs->type = rd->type;
+ rs->type = rd->type;
- if (!(rs->name = dbg_strdup(rd->name))) {
+ if (!(rs->name = dbg_strdup(rd->name))) {
dbg_free(rs);
rs = NULL;
log_alloc_err(lc, handler);
@@ -147,12 +151,12 @@
}
/* Check sector vs. RAID device end */
-static int rd_check_end(struct lib_context *lc,
- struct raid_dev *rd, uint64_t sector)
+static int
+rd_check_end(struct lib_context *lc, struct raid_dev *rd, uint64_t sector)
{
if (sector > rd->di->sectors)
LOG_ERR(lc, 1, "%s: partition address past end of RAID device",
- handler);
+ handler);
return 0;
}
@@ -161,9 +165,10 @@
* Allocate a DOS RAID device and a set.
* Set the device up and add it to the set.
*/
-static int _create_rs_and_rd(struct lib_context *lc, struct raid_dev *rd,
- struct dos_partition *raw_part, uint64_t sector,
- unsigned int part)
+static int
+_create_rs_and_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct dos_partition *raw_part, uint64_t sector,
+ unsigned int part)
{
struct raid_dev *r;
struct raid_set *rs;
@@ -174,7 +179,7 @@
if (!(r->di = alloc_dev_info(lc, rd->di->path)))
goto free_raid_dev;
- if (!(r->name = name(lc, rd, part, 1)))
+ if (!(r->name = name(lc, rd, part, 1)))
goto free_di;
r->fmt = rd->fmt;
@@ -197,9 +202,9 @@
return 1;
- free_di:
+ free_di:
free_dev_info(lc, r->di);
- free_raid_dev:
+ free_raid_dev:
free_raid_dev(lc, &r);
return 0;
@@ -215,14 +220,16 @@
* Partition code inspired by libparted and squeezed for this purpose (lemon).
*/
/* FIXME: Check for position of partition */
-static int is_partition(struct dos_partition *p, uint64_t start_sector)
+static int
+is_partition(struct dos_partition *p, uint64_t start_sector)
{
return p->type != PARTITION_EMPTY && p->length && p->start;
}
-static int group_rd_extended(struct lib_context *lc, struct raid_dev *rd,
- uint64_t start_sector, uint64_t *extended_root,
- unsigned int part)
+static int
+group_rd_extended(struct lib_context *lc, struct raid_dev *rd,
+ uint64_t start_sector, uint64_t * extended_root,
+ unsigned int part)
{
int ret = 0;
uint64_t new_start_sector;
@@ -240,7 +247,7 @@
#endif
if (dos->magic == PARTITION_MAGIC_MAGIC)
goto out;
-
+
/* Check magic to see if this is a real partition table. */
if (dos->magic != DOS_MAGIC)
goto out;
@@ -249,13 +256,13 @@
* Logical partition tables only have two entries,
* one for the partition and one for the next partition table.
*/
-
+
/*
* An entry pointing to the present logical partition.
* It is an offset from the present partition table location.
*/
p1 = dos->partitions;
-
+
/*
* An entry pointing to the next logical partition table.
* It is an offset from the main extended partition start.
@@ -276,25 +283,25 @@
if (!*extended_root)
*extended_root = start_sector;
new_start_sector = get_part_start(p2, *extended_root);
-
+
if (is_partition(p2, start_sector) &&
!group_rd_extended(lc, rd, new_start_sector, extended_root, part))
goto out;
ret = 1;
- out:
+ out:
dbg_free(dos);
return ret;
}
/* Handle primary partitions. */
-static int group_rd(struct lib_context *lc, struct raid_dev *rd,
- uint64_t start_sector)
+static int
+group_rd(struct lib_context *lc, struct raid_dev *rd, uint64_t start_sector)
{
unsigned int i;
uint64_t part_start, part_end,
- extended_part_start = 0, extended_root = 0;
+ extended_part_start = 0, extended_root = 0;
struct dos *dos = META(rd, dos);
struct dos_partition *raw_table_entry;
@@ -314,8 +321,8 @@
* start of drive.
*/
part_start = get_part_start(raw_table_entry, start_sector);
- part_end = part_start + raw_table_entry->length;
-
+ part_end = part_start + raw_table_entry->length;
+
/* Avoid infinite recursion (mostly). */
if (part_start == start_sector)
continue;
@@ -336,19 +343,19 @@
start_sector, i + 1))
return 0;
}
-
+
/* When we are finished with all the primary partitions,
* go do the extended partition if we have one.
* It always starts with partition 5.
*/
return extended_part_start ?
- group_rd_extended(lc, rd, extended_part_start,
- &extended_root, 5) : 1;
+ group_rd_extended(lc, rd, extended_part_start,
+ &extended_root, 5) : 1;
}
/* Add a DOS RAID device to a set */
-static struct raid_set *dos_group(struct lib_context *lc,
- struct raid_dev *rd)
+static struct raid_set *
+dos_group(struct lib_context *lc, struct raid_dev *rd)
{
/*
* Once we get here, a DOS partition table
@@ -363,34 +370,36 @@
* to something else for some strange partitioning scheme because the
* code will handle it.
*/
- return group_rd(lc, rd, 0) ? (struct raid_set*) 1 : NULL;
+ return group_rd(lc, rd, 0) ? (struct raid_set *) 1 : NULL;
}
/*
* Check integrity of a DOS RAID set.
*/
-static int dos_check(struct lib_context *lc, struct raid_set *rs)
+static int
+dos_check(struct lib_context *lc, struct raid_set *rs)
{
- return 1; /* Nice, eh ? */
+ return 1; /* Nice, eh ? */
}
static struct dmraid_format dos_format = {
- .name = HANDLER,
- .descr = "DOS partitions on SW RAIDs",
- .caps = NULL, /* Not supported */
+ .name = HANDLER,
+ .descr = "DOS partitions on SW RAIDs",
+ .caps = NULL, /* Not supported */
.format = FMT_PARTITION,
- .read = dos_read,
- .write = NULL, /* Not supported */
- .group = dos_group,
- .check = dos_check,
- .events = NULL, /* Not supported */
+ .read = dos_read,
+ .write = NULL, /* Not supported */
+ .group = dos_group,
+ .check = dos_check,
+ .events = NULL, /* Not supported */
#ifdef DMRAID_NATIVE_LOG
- .log = NULL, /* Not supported; use fdisk and friends */
+ .log = NULL, /* Not supported; use fdisk and friends */
#endif
};
/* Register this format handler with the format core. */
-int register_dos(struct lib_context *lc)
+int
+register_dos(struct lib_context *lc)
{
return register_format_handler(lc, &dos_format);
}
@@ -401,8 +410,9 @@
* For a DOS partition we essentially just save the
* partition table sector and let dos_group do the rest...
*/
-static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta, union read_info *info)
+static int
+setup_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct dev_info *di, void *meta, union read_info *info)
{
struct dos *dos = meta;
@@ -411,16 +421,16 @@
rd->meta_areas->offset = DOS_CONFIGOFFSET >> 9;
rd->meta_areas->size = sizeof(*dos);
- rd->meta_areas->area = (void*) dos;
+ rd->meta_areas->area = (void *) dos;
- rd->di = di;
+ rd->di = di;
rd->fmt = &dos_format;
- rd->status = s_ok; /* Always :-) */
- rd->type = t_partition;
+ rd->status = s_ok; /* Always :-) */
+ rd->type = t_partition;
- rd->offset = DOS_DATAOFFSET;
- rd->sectors = di->sectors;
+ rd->offset = DOS_DATAOFFSET;
+ rd->sectors = di->sectors;
- return (rd->name = name(lc, rd, 0, 0)) ? 1 : 0;
+ return (rd->name = name(lc, rd, 0, 0)) ? 1 : 0;
}
--- dmraid/lib/format/partition/dos.h 2008/02/22 16:57:36 1.1
+++ dmraid/lib/format/partition/dos.h 2008/06/20 21:52:18 1.2
@@ -23,29 +23,29 @@
#define DOS_DATAOFFSET 0
struct chs {
- uint8_t head;
- uint8_t sector;
- uint8_t cylinder;
+ uint8_t head;
+ uint8_t sector;
+ uint8_t cylinder;
} __attribute__ ((packed));
struct dos_partition {
- uint8_t boot_ind; /* 00: 0x80 - active */
- struct chs chs_start; /* 01: */
- uint8_t type; /* 04: partition type */
+ uint8_t boot_ind; /* 00: 0x80 - active */
+ struct chs chs_start; /* 01: */
+ uint8_t type; /* 04: partition type */
#define PARTITION_EMPTY 0x00
#define PARTITION_EXT 0x05
#define PARTITION_EXT_LBA 0x0f
#define PARTITION_LINUX_EXT 0x85
#define PARTITION_GPT 0xee
- struct chs chs_end; /* 05: */
- uint32_t start; /* 08: starting sector from 0 */
- uint32_t length; /* 0c: nr of sectors in partition */
+ struct chs chs_end; /* 05: */
+ uint32_t start; /* 08: starting sector from 0 */
+ uint32_t length; /* 0c: nr of sectors in partition */
} __attribute__ ((packed));
struct dos {
- uint8_t boot_code [446];
- struct dos_partition partitions [4];
- uint16_t magic;
+ uint8_t boot_code[446];
+ struct dos_partition partitions[4];
+ uint16_t magic;
#define DOS_MAGIC 0xAA55
#define PARTITION_MAGIC_MAGIC 0xF6F6
} __attribute__ ((packed));
--- dmraid/lib/format/template/template.c 2008/02/22 16:57:36 1.1
+++ dmraid/lib/format/template/template.c 2008/06/20 21:52:18 1.2
@@ -24,14 +24,14 @@
/* Make up RAID device name. */
/* CODEME: implement creation of senseful name for the RAID device */
-static size_t _name(struct template *template, char *str, size_t len,
- unsigned int subset)
+static size_t
+_name(struct template *template, char *str, size_t len, unsigned int subset)
{
return snprintf(str, len, "template");
}
-static char *name(struct lib_context *lc, struct raid_dev *rd,
- unsigned int subset)
+static char *
+name(struct lib_context *lc, struct raid_dev *rd, unsigned int subset)
{
size_t len;
char *ret;
@@ -40,7 +40,8 @@
if ((ret = dbg_malloc((len = _name(template, NULL, 0, subset) + 1)))) {
_name(template, ret, len, subset);
mk_alpha(lc, ret + HANDLER_LEN, len - HANDLER_LEN);
- } else
+ }
+ else
log_alloc_err(lc, handler);
return ret;
@@ -52,13 +53,14 @@
* (see metadata.h for generic ones)
*/
static struct types types[] = {
- { TEMPLATE_T_SPAN, t_linear },
- { TEMPLATE_T_RAID0, t_raid0 },
- { 0, t_undef}
+ {TEMPLATE_T_SPAN, t_linear},
+ {TEMPLATE_T_RAID0, t_raid0},
+ {0, t_undef}
};
/* Neutralize disk type using generic metadata type mapping function */
-static enum type template_type(struct lib_context *lc, struct raid_dev *rd)
+static enum type
+template_type(struct lib_context *lc, struct raid_dev *rd)
{
return rd_type(types, (unsigned int) (META(rd, template))->type);
}
@@ -70,17 +72,17 @@
#if BYTE_ORDER == LITTLE_ENDIAN
# define to_cpu(x)
#else
-static void to_cpu(struct template *template)
+static void
+to_cpu(struct template *template)
{
CVT32(template->something);
- ...
-}
+...}
#endif
static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
struct dev_info *di, void *meta, union read_info *info);
-static struct raid_dev *template_read(struct lib_context *lc,
- struct dev_info *di)
+static struct raid_dev *
+template_read(struct lib_context *lc, struct dev_info *di)
{
return read_raid_dev(lc, di, NULL,
sizeof(struct template), TEMPLATE_CONFIGOFFSET,
@@ -91,25 +93,27 @@
* Decide about ordering sequence of RAID device.
* (Called by list_add_sorted().
*/
-static int dev_sort(struct list_head *pos, struct list_head *new)
+static int
+dev_sort(struct list_head *pos, struct list_head *new)
{
return (META(RD(new), template))->disk_number <
- (META(RD(pos), template))->disk_number;
+ (META(RD(pos), template))->disk_number;
}
/*
* Decide about ordering sequence of RAID device.
* (Called by join_superset().
*/
-static int set_sort(struct list_head *pos, struct list_head *new)
+static int
+set_sort(struct list_head *pos, struct list_head *new)
{
return _subset(META(RD_RS(RS(new)), via)) <
- _subset(META(RD_RS(RS(pos)), via));
+ _subset(META(RD_RS(RS(pos)), via));
}
/* Add a Template RAID device to a set */
-static struct raid_set *template_group(struct lib_context *lc,
- struct raid_dev *rd)
+static struct raid_set *
+template_group(struct lib_context *lc, struct raid_dev *rd)
{
if (T_SPARE(rd))
return NULL;
@@ -124,8 +128,8 @@
}
/* CODEME: Write private RAID metadata to device */
-static int template_write(struct lib_context *lc,
- struct raid_dev *rd, int erase)
+static int
+template_write(struct lib_context *lc, struct raid_dev *rd, int erase)
{
int ret;
#if BYTE_ORDER != LITTLE_ENDIAN
@@ -142,7 +146,8 @@
/*
* Check integrity of a RAID set.
*/
-static unsigned int devices(struct raid_dev *rd, void *context)
+static unsigned int
+devices(struct raid_dev *rd, void *context)
{
LOG_ERR(lc, 0, "%s: implement RAID device # function", handler);
}
@@ -153,7 +158,8 @@
LOG_ERR(lc, 0, "%s: implement RAID device integrity checks", handler);
}
-static int template_check(struct lib_context *lc, struct raid_set *rs)
+static int
+template_check(struct lib_context *lc, struct raid_set *rs)
{
/* CODEME: implement */
return check_raid_set(lc, rs, devices, devices_context,
@@ -161,15 +167,16 @@
}
static struct event_handlers template_event_handlers = {
- .io = event_io, /* CODEME: */
- .rd = NULL, /* FIXME: no device add/remove event handler yet. */
+ .io = event_io, /* CODEME: */
+ .rd = NULL, /* FIXME: no device add/remove event handler yet. */
};
#ifdef DMRAID_NATIVE_LOG
/*
* Log native information about the RAID device.
*/
-static void template_log(struct lib_context *lc, struct raid_dev *rd)
+static void
+template_log(struct lib_context *lc, struct raid_dev *rd)
{
struct template *template = META(rd, template);
@@ -179,29 +186,31 @@
#endif
static struct dmraid_format template_format = {
- .name = HANDLER,
- .descr = "Template RAID",
- .caps = "(Insert RAID levels here)",
+ .name = HANDLER,
+ .descr = "Template RAID",
+ .caps = "(Insert RAID levels here)",
.format = FMT_RAID,
- .read = template_read,
- .write = template_write,
- .group = template_group,
- .check = template_check,
- .events = &template_event_handlers,
+ .read = template_read,
+ .write = template_write,
+ .group = template_group,
+ .check = template_check,
+ .events = &template_event_handlers,
#ifdef DMRAID_NATIVE_LOG
- .log = template_log,
+ .log = template_log,
#endif
};
/* Register this format handler with the format core */
-int register_template(struct lib_context *lc)
+int
+register_template(struct lib_context *lc)
{
return register_format_handler(lc, &template_format);
}
/* CODEME: Set the RAID device contents up derived from the TEMPLATE ones */
-static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
- struct dev_info *di, void *meta, union read_info *info)
+static int
+setup_rd(struct lib_context *lc, struct raid_dev *rd,
+ struct dev_info *di, void *meta, union read_info *info)
{
struct template *template = meta;
@@ -210,20 +219,20 @@
rd->meta_areas->offset = TEMPLATE_CONFIGOFFSET >> 9;
rd->meta_areas->size = sizeof(*template);
- rd->meta_areas->area = (void*) template;
+ rd->meta_areas->area = (void *) template;
- rd->di = di;
+ rd->di = di;
rd->fmt = &template_format;
- rd->status = s_ok; /* CODEME: derive from metadata. */
- rd->type = template_type(template);
+ rd->status = s_ok; /* CODEME: derive from metadata. */
+ rd->type = template_type(template);
rd->offset = TEMPLATE_DATAOFFSET;
/* CODEME: correct sectors. */
rd->sectors = rd->meta_areas->offset;
- if ((rd->name = name(lc, rd, 1)))
+ if ((rd->name = name(lc, rd, 1)))
return 1;
return 0;
--- dmraid/lib/format/template/template.h 2008/02/22 16:57:36 1.1
+++ dmraid/lib/format/template/template.h 2008/06/20 21:52:18 1.2
@@ -25,14 +25,14 @@
uint32_t magic; /* and/or metadata has a 'magic' number ? */
#define TEMPLATE_MAGIC_OK 0xABCDEF
- uint8_t type; /* RAID level */
+ uint8_t type; /* RAID level */
#define TEMPLATE_T_SPAN 0
#define TEMPLATE_T_RAID0 1
uint8_t disk_number; /* Absolute disk number in set. */
/* etc. */
- ....... /* members for numbers of disks, whatever... */
+ ... .... /* members for numbers of disks, whatever... */
} __attribute__ ((packed));
#endif
--- dmraid/lib/locking/locking.c 2008/02/22 17:04:36 1.2
+++ dmraid/lib/locking/locking.c 2008/06/20 21:52:18 1.3
@@ -16,7 +16,8 @@
static int lf = -1;
/* flock file. */
-static int lock(struct lib_context *lc, struct resource *res)
+static int
+lock(struct lib_context *lc, struct resource *res)
{
/* Already locked. */
if (lf > -1)
@@ -36,7 +37,8 @@
}
/* Unlock file. */
-static void unlock(struct lib_context *lc, struct resource *res)
+static void
+unlock(struct lib_context *lc, struct resource *res)
{
/* Not locked! */
if (lf == -1)
@@ -55,17 +57,18 @@
/* File base locking interface. */
static struct locking file_locking = {
- .name = "file",
- .lock = lock,
- .unlock = unlock,
+ .name = "file",
+ .lock = lock,
+ .unlock = unlock,
};
-static int init_file_locking(struct lib_context *lc)
+static int
+init_file_locking(struct lib_context *lc)
{
int ret = 0;
char *dir;
- if (!(dir = get_dirname(lc, (char*) lock_file)))
+ if (!(dir = get_dirname(lc, (char *) lock_file)))
return 0;
if (!mk_dir(lc, dir))
@@ -78,7 +81,7 @@
lc->lock = &file_locking;
ret = 1;
- out:
+ out:
dbg_free(dir);
return ret;
@@ -89,7 +92,8 @@
*/
/* Initialize locking. */
-int init_locking(struct lib_context *lc)
+int
+init_locking(struct lib_context *lc)
{
if (OPT_IGNORELOCKING(lc))
return 1;
@@ -101,13 +105,15 @@
}
/* Hide locking. */
-int lock_resource(struct lib_context *lc, struct resource *res)
+int
+lock_resource(struct lib_context *lc, struct resource *res)
{
return OPT_IGNORELOCKING(lc) ? 1 : lc->lock->lock(lc, res);
}
/* Hide unlocking. */
-void unlock_resource(struct lib_context *lc, struct resource *res)
+void
+unlock_resource(struct lib_context *lc, struct resource *res)
{
return OPT_IGNORELOCKING(lc) ? 1 : lc->lock->unlock(lc, res);
}
--- dmraid/lib/log/log.c 2008/02/22 16:57:36 1.1
+++ dmraid/lib/log/log.c 2008/06/20 21:52:18 1.2
@@ -18,19 +18,21 @@
"FATAL",
};
-static const char *_prefix(int level)
+static const char *
+_prefix(int level)
{
return level < ARRAY_SIZE(_prefixes) ? _prefixes[level] : "UNDEF";
}
-void plog(struct lib_context *lc, int level, int lf, const char *file,
- int line, const char *format, ...)
+void
+plog(struct lib_context *lc, int level, int lf, const char *file,
+ int line, const char *format, ...)
{
int o = LC_VERBOSE, l = level;
FILE *f = stdout;
va_list ap;
- if (level == _PLOG_DEBUG) {
+ if (level == _PLOG_DEBUG) {
o = LC_DEBUG;
l -= _PLOG_WARN;
}
@@ -53,7 +55,8 @@
}
/* This is used so often in the metadata format handlers and elsewhere. */
-int log_alloc_err(struct lib_context *lc, const char *who)
+int
+log_alloc_err(struct lib_context *lc, const char *who)
{
LOG_ERR(lc, 0, "%s: allocating", who);
}
--- dmraid/lib/metadata/log_ops.c 2008/02/22 17:04:36 1.1
+++ dmraid/lib/metadata/log_ops.c 2008/06/20 21:52:18 1.2
@@ -9,7 +9,8 @@
*/
#include "internal.h"
-void end_log(struct lib_context *lc, struct list_head *log)
+void
+end_log(struct lib_context *lc, struct list_head *log)
{
struct list_head *pos, *tmp;
@@ -19,7 +20,8 @@
}
}
-int revert_log(struct lib_context *lc, struct list_head *log)
+int
+revert_log(struct lib_context *lc, struct list_head *log)
{
int writes_started = 0, ret = 0;
struct change *entry;
@@ -37,13 +39,14 @@
rd = entry->rd;
rd->type = t_spare;
list_del_init(&entry->rd->devs);
- } else if (entry->type == WRITE_METADATA) {
+ }
+ else if (entry->type == WRITE_METADATA) {
writes_started = 1;
rd = entry->rd;
ret = write_dev(lc, rd, 0);
if (ret) {
log_err(lc, "%s: Error while reverting "
- "metadata.", __func__);
+ "metadata.", __func__);
break;
}
}
--- dmraid/lib/metadata/metadata.c 2008/04/02 13:35:31 1.4
+++ dmraid/lib/metadata/metadata.c 2008/06/20 21:52:18 1.5
@@ -1,10 +1,14 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
+#include <getopt.h>
#include "internal.h"
#include "activate/devmapper.h"
@@ -20,24 +24,24 @@
const char *dm_ascii;
} ascii_type[] = {
/* enum text dm-target id */
- { t_undef, NULL, NULL },
- { t_group, "GROUP", NULL },
- { t_partition, "partition", NULL },
- { t_spare, "spare", NULL },
- { t_linear, "linear", "linear" },
- { t_raid0, "stripe", "striped" },
- { t_raid1, "mirror", "mirror" },
- { t_raid4, "raid4", "raid45" },
- { t_raid5_ls, "raid5_ls", "raid45" },
- { t_raid5_rs, "raid5_rs", "raid45" },
- { t_raid5_la, "raid5_la", "raid45" },
- { t_raid5_ra, "raid5_ra", "raid45" },
- { t_raid6, "raid6", NULL },
+ { t_undef, NULL, NULL},
+ { t_group, "GROUP", NULL},
+ { t_partition, "partition", NULL},
+ { t_spare, "spare", NULL},
+ { t_linear, "linear", "linear"},
+ { t_raid0, "stripe", "striped"},
+ { t_raid1, "mirror", "mirror"},
+ { t_raid4, "raid4", "raid45"},
+ { t_raid5_ls, "raid5_ls", "raid45"},
+ { t_raid5_rs, "raid5_rs", "raid45"},
+ { t_raid5_la, "raid5_la", "raid45"},
+ { t_raid5_ra, "raid5_ra", "raid45"},
+ { t_raid6, "raid6", NULL},
};
static const char *stacked_ascii_type[][5] = {
- { "raid10", "raid30", "raid40", "raid50", "raid60" },
- { "raid01", "raid03", "raid04", "raid05", "raid06" },
+ {"raid10", "raid30", "raid40", "raid50", "raid60"},
+ {"raid01", "raid03", "raid04", "raid05", "raid06"},
};
/*
@@ -47,16 +51,47 @@
const enum status status;
const char *ascii;
} ascii_status[] = {
- { s_undef, NULL },
- { s_setup, "setup" },
- { s_broken, "broken" },
- { s_inconsistent, "inconsistent" },
- { s_nosync, "nosync" },
- { s_ok, "ok" },
+ {
+ s_undef, NULL}, {
+ s_setup, "setup"}, {
+ s_broken, "broken"}, {
+ s_inconsistent, "inconsistent"}, {
+ s_nosync, "nosync"}, {
+s_ok, "ok"},};
+
+/* type of spare set - string definition */
+#define SPARE_TYPE_STRING "8"
+
+/**************************/
+
+
+#define ALL_FLAGS ((enum action) -1)
+
+/*
+ * Action flag definitions for set_action().
+ *
+ * 'Early' options can be handled directly in set_action() by calling
+ * the functions registered here (f_set member) handing in arg.
+ */
+struct actions {
+ int option; /* Option character/value. */
+ enum action action; /* Action flag for this option or UNDEF. */
+ enum action needed; /* Mandatory options or UNDEF if alone */
+ enum action allowed; /* Allowed flags (ie, other options allowed) */
+
+ enum args args; /* Arguments allowed ? */
+
+ /* Function to call on hit or NULL */
+ int (*f_set) (struct lib_context * lc, int arg);
+ int arg; /* Argument for above function call */
};
+/*************************************/
+
+
/* Fetch the respective ASCII string off the types array. */
-static unsigned int get_type_index(enum type type)
+static unsigned int
+get_type_index(enum type type)
{
unsigned int ret = ARRAY_SIZE(ascii_type);
@@ -68,36 +103,39 @@
return 0;
}
-const char *get_type(struct lib_context *lc, enum type type)
+const char *
+get_type(struct lib_context *lc, enum type type)
{
return ascii_type[get_type_index(type)].dsp_ascii;
}
-const char *get_dm_type(struct lib_context *lc, enum type type)
+const char *
+get_dm_type(struct lib_context *lc, enum type type)
{
return ascii_type[get_type_index(type)].dm_ascii;
}
/* Return the RAID type of a stacked RAID set (eg, raid10). */
-static const char *get_stacked_type(void *v)
+static const char *
+get_stacked_type(void *v)
{
struct raid_set *rs = v;
unsigned int t = (T_RAID0(rs) ? get_type_index((RS_RS(rs))->type) :
- get_type_index(rs->type))
- - get_type_index(t_raid1);
+ get_type_index(rs->type)) - get_type_index(t_raid1);
- return stacked_ascii_type[T_RAID0(rs) ? 1 : 0]
- [t > t_raid0 ? t_undef : t];
+ return stacked_ascii_type[T_RAID0(rs) ? 1:0][t > t_raid0 ? t_undef:t];
}
/* Check, if a RAID set is stacked (ie, hierachical). */
-static inline int is_stacked(struct raid_set *rs)
+static inline int
+is_stacked(struct raid_set *rs)
{
return !T_GROUP(rs) && SETS(rs);
}
/* Return the ASCII type for a RAID set. */
-const char *get_set_type(struct lib_context *lc, void *v)
+const char *
+get_set_type(struct lib_context *lc, void *v)
{
struct raid_set *rs = v;
@@ -106,12 +144,12 @@
}
/* Fetch the respective ASCII string off the state array. */
-const char *get_status(struct lib_context *lc, enum status status)
+const char *
+get_status(struct lib_context *lc, enum status status)
{
unsigned int i = ARRAY_SIZE(ascii_status);
while (i-- && !(status & ascii_status[i].status));
-
return ascii_status[i].ascii;
}
@@ -121,8 +159,8 @@
*
* Pay attention to RAID > 0 types.
*/
-static uint64_t add_sectors(struct raid_set *rs, uint64_t sectors,
- uint64_t add)
+static uint64_t
+add_sectors(struct raid_set *rs, uint64_t sectors, uint64_t add)
{
add = rs->stride ? round_down(add, rs->stride) : add;
@@ -136,7 +174,8 @@
}
/* FIXME: proper calculation of unsymetric sets ? */
-static uint64_t smallest_disk(struct raid_set *rs)
+static uint64_t
+smallest_disk(struct raid_set *rs)
{
uint64_t ret = ~0;
struct raid_dev *rd;
@@ -148,26 +187,27 @@
}
/* Count subsets of a set. */
-static unsigned int count_subsets(struct lib_context *lc, struct raid_set *rs)
+static unsigned int
+count_subsets(struct lib_context *lc, struct raid_set *rs)
{
unsigned ret = 0;
struct raid_set *r;
- list_for_each_entry(r, &rs->sets, list)
- ret++;
+ list_for_each_entry(r, &rs->sets, list) ret++;
return ret;
}
/* Calculate total sectors of a (hierarchical) RAID set. */
-uint64_t total_sectors(struct lib_context *lc, struct raid_set *rs)
+uint64_t
+total_sectors(struct lib_context * lc, struct raid_set * rs)
{
- uint64_t sectors = 0;
- struct raid_dev *rd;
+ uint64_t sectors = 0;
+ struct raid_dev *rd;
/* Stacked RAID sets. */
if (!T_GROUP(rs)) {
- struct raid_set *r;
+ struct raid_set *r;
list_for_each_entry(r, &rs->sets, list)
sectors = add_sectors(rs, sectors,
@@ -186,6 +226,14 @@
}
}
+ /* Size for spare disk set */
+ if (T_SPARE(rs)) {
+ list_for_each_entry(rd, &rs->devs, devs) {
+ if (T_SPARE(rd))
+ sectors = add_sectors(rs, sectors, rd->sectors);
+ }
+ }
+
/* Size correction for higher RAID levels */
if (T_RAID4(rs) || T_RAID5(rs) || T_RAID6(rs)) {
unsigned int i = count_subsets(lc, rs);
@@ -196,20 +244,21 @@
sectors -= sub;
}
- return sectors;
+ return sectors;
}
/* Check if a RAID device should be counted. */
-static unsigned int _count_dev(struct raid_dev *rd, enum count_type type)
+static unsigned int
+_count_dev(struct raid_dev *rd, enum count_type type)
{
return ((type == ct_dev && !T_SPARE(rd)) ||
- (type == ct_spare && T_SPARE(rd)) ||
- type == ct_all) ? 1 : 0;
+ (type == ct_spare && T_SPARE(rd)) || type == ct_all) ? 1 : 0;
}
/* Count devices in a set recursively. */
-unsigned int count_devs(struct lib_context *lc, struct raid_set *rs,
- enum count_type count_type)
+unsigned int
+count_devs(struct lib_context *lc, struct raid_set *rs,
+ enum count_type count_type)
{
unsigned int ret = 0;
struct raid_set *r;
@@ -233,7 +282,8 @@
* format handlers so far. If life becomes more complex, I might need
* one though...
*/
-static void _free_dev_pointers(struct lib_context *lc, struct raid_dev *rd)
+static void
+_free_dev_pointers(struct lib_context *lc, struct raid_dev *rd)
{
int area, i, idx = 0;
void **p;
@@ -244,7 +294,7 @@
/* Allocate and initialize temporary pointer list. */
if (!(p = dbg_malloc(area * sizeof(*p))))
- LOG_ERR(lc, , "allocating pointer array");
+ LOG_ERR(lc,, "failed to allocate pointer array");
/* Add private pointer to list. */
if (rd->private.ptr)
@@ -257,7 +307,7 @@
if (p[i] == rd->meta_areas[area].area)
break;
}
-
+
if (i == idx)
p[idx++] = rd->meta_areas[area].area;
}
@@ -268,12 +318,13 @@
/* Free all RAID device pointers. */
while (idx--)
dbg_free(p[idx]);
-
+
dbg_free(p);
}
/* Allocate dev_info struct and keep the device path */
-struct dev_info *alloc_dev_info(struct lib_context *lc, char *path)
+struct dev_info *
+alloc_dev_info(struct lib_context *lc, char *path)
{
struct dev_info *di;
@@ -291,7 +342,8 @@
}
/* Free dev_info structure */
-static void _free_dev_info(struct lib_context *lc, struct dev_info *di)
+static void
+_free_dev_info(struct lib_context *lc, struct dev_info *di)
{
if (di->serial)
dbg_free(di->serial);
@@ -300,11 +352,15 @@
dbg_free(di);
}
-static inline void _free_dev_infos(struct lib_context *lc)
+static inline void
+_free_dev_infos(struct lib_context *lc)
{
struct list_head *elem, *tmp;
list_for_each_safe(elem, tmp, LC_DI(lc)) {
+ if (!elem)
+ printf("NULL pointer\n");
+
list_del(elem);
_free_dev_info(lc, list_entry(elem, struct dev_info, list));
}
@@ -314,13 +370,15 @@
* Free dev_info structure or all registered
* dev_info structures in case di = NULL.
*/
-void free_dev_info(struct lib_context *lc, struct dev_info *di)
+void
+free_dev_info(struct lib_context *lc, struct dev_info *di)
{
di ? _free_dev_info(lc, di) : _free_dev_infos(lc);
}
/* Allocate/Free RAID device (member of a RAID set). */
-struct raid_dev *alloc_raid_dev(struct lib_context *lc, const char *who)
+struct raid_dev *
+alloc_raid_dev(struct lib_context *lc, const char *who)
{
struct raid_dev *ret;
@@ -334,7 +392,8 @@
return ret;
}
-static void _free_raid_dev(struct lib_context *lc, struct raid_dev **rd)
+static void
+_free_raid_dev(struct lib_context *lc, struct raid_dev **rd)
{
struct raid_dev *r = *rd;
@@ -348,12 +407,15 @@
*/
_free_dev_pointers(lc, r);
- dbg_free(r->name);
+ if (r->name)
+ dbg_free(r->name);
+
dbg_free(r);
*rd = NULL;
}
-static inline void _free_raid_devs(struct lib_context *lc)
+static inline void
+_free_raid_devs(struct lib_context *lc)
{
struct list_head *elem, *tmp;
struct raid_dev *rd;
@@ -365,13 +427,15 @@
}
/* Free RAID device structure or all registered RAID devices if rd == NULL. */
-void free_raid_dev(struct lib_context *lc, struct raid_dev **rd)
+void
+free_raid_dev(struct lib_context *lc, struct raid_dev **rd)
{
rd ? _free_raid_dev(lc, rd) : _free_raid_devs(lc);
}
/* Allocate/Free RAID set. */
-struct raid_set *alloc_raid_set(struct lib_context *lc, const char *who)
+struct raid_set *
+alloc_raid_set(struct lib_context *lc, const char *who)
{
struct raid_set *ret;
@@ -380,7 +444,7 @@
INIT_LIST_HEAD(&ret->sets);
INIT_LIST_HEAD(&ret->devs);
ret->status = s_setup;
- ret->type = t_undef;
+ ret->type = t_undef;
} else
log_alloc_err(lc, who);
@@ -388,7 +452,8 @@
}
/* Free a single RAID set structure and its RAID devices. */
-static void _free_raid_set(struct lib_context *lc, struct raid_set *rs)
+static void
+_free_raid_set(struct lib_context *lc, struct raid_set *rs)
{
struct raid_dev *rd;
struct list_head *elem, *tmp;
@@ -399,7 +464,7 @@
rd = RD(elem);
log_dbg(lc, "freeing device \"%s\", path \"%s\"",
- rd->name, rd->di->path);
+ rd->name, (rd->di) ? rd->di->path : "?");
/* FIXME: remove partition code in favour of kpartx ? */
/*
@@ -425,7 +490,8 @@
}
/* Remove a set or all sets (in case rs = NULL) recursively. */
-void free_raid_set(struct lib_context *lc, struct raid_set *rs)
+void
+free_raid_set(struct lib_context *lc, struct raid_set *rs)
{
struct list_head *elem, *tmp;
@@ -439,21 +505,24 @@
}
/* Return != 0 in case of a partitioned RAID set type. */
-int partitioned_set(struct lib_context *lc, void *rs)
+int
+partitioned_set(struct lib_context *lc, void *rs)
{
- return T_PARTITION((struct raid_set*) rs);
+ return T_PARTITION((struct raid_set *) rs);
}
/* Return != 0 in case of a partitioned base RAID set. */
-int base_partitioned_set(struct lib_context *lc, void *rs)
+int
+base_partitioned_set(struct lib_context *lc, void *rs)
{
- return ((struct raid_set*) rs)->flags & f_partitions;
+ return ((struct raid_set *) rs)->flags & f_partitions;
}
/* Return RAID set name. */
-const char *get_set_name(struct lib_context *lc, void *rs)
+const char *
+get_set_name(struct lib_context *lc, void *rs)
{
- return ((struct raid_set*) rs)->name;
+ return ((struct raid_set *) rs)->name;
}
/*
@@ -462,9 +531,9 @@
* Search top level RAID set list only if where = FIND_TOP.
* Recursive if where = FIND_ALL.
*/
-static struct raid_set *_find_set(struct lib_context *lc,
- struct list_head *list,
- const char *name, enum find where)
+static struct raid_set *
+_find_set(struct lib_context *lc,
+ struct list_head *list, const char *name, enum find where)
{
struct raid_set *r, *ret = NULL;
@@ -483,26 +552,41 @@
}
}
- out:
+ out:
log_dbg(lc, "_find_set: %sfound %s", ret ? "" : "not ", name);
return ret;
}
-struct raid_set *find_set(struct lib_context *lc,
- struct list_head *list,
- const char *name, enum find where)
+struct raid_set *
+find_set(struct lib_context *lc,
+ struct list_head *list, const char *name, enum find where)
{
return _find_set(lc, list ? list : LC_RS(lc), name, where);
}
-struct raid_set *find_or_alloc_raid_set(struct lib_context *lc,
- char *name, enum find where,
- struct raid_dev *rd,
- struct list_head *list,
- void (*f_create) (struct raid_set *super,
- void *private),
- void *private)
+static int set_sort(struct list_head *pos, struct list_head *new);
+
+
+static int
+set_sort(struct list_head *pos, struct list_head *new)
+{
+ struct raid_set *new_rs = list_entry(new, struct raid_set, list);
+ struct raid_set *pos_rs = list_entry(pos, struct raid_set, list);
+
+ if ((new_rs->name) && (pos_rs->name))
+ return (strcmp(new_rs->name, pos_rs->name) < 0);
+ else
+ return -1;
+}
+
+struct raid_set *
+find_or_alloc_raid_set(struct lib_context *lc,
+ char *name, enum find where,
+ struct raid_dev *rd,
+ struct list_head *list,
+ void (*f_create) (struct raid_set *
+ super, void *private), void *private)
{
struct raid_set *rs;
@@ -515,35 +599,34 @@
if (!(rs->name = dbg_strdup(name)))
goto err;
- if (rd && ((rs->type = rd->type), T_SPARE(rd)))
- rs->type = t_undef;
+ rs->type = rd ? rd->type : t_undef;
/* If caller hands a list in, add to it. */
if (list)
- list_add_tail(&rs->list, list);
+ list_add_sorted(lc, list, &rs->list, set_sort);
/* Call any create callback. */
if (f_create)
f_create(rs, private);
- out:
+ out:
return rs;
- err:
+ err:
dbg_free(rs);
log_alloc_err(lc, __func__);
return NULL;
}
-/* Return # of raid sets build */
-unsigned int count_sets(struct lib_context *lc, struct list_head *list)
+/* Return # of RAID sets build */
+unsigned int
+count_sets(struct lib_context *lc, struct list_head *list)
{
int ret = 0;
struct list_head *elem;
- list_for_each(elem, list)
- ret++;
+ list_for_each(elem, list) ret++;
return ret;
}
@@ -551,44 +634,45 @@
/*
* Count devices found
*/
-static unsigned int _count_devices(struct lib_context *lc, enum dev_type type)
+static unsigned int
+_count_devices(struct lib_context *lc, enum dev_type type)
{
unsigned int ret = 0;
struct list_head *elem, *list;
if (DEVICE & type)
list = LC_DI(lc);
- else if (((RAID|NATIVE) & type))
+ else if (((RAID | NATIVE) & type))
list = LC_RD(lc);
else
return 0;
-
- list_for_each(elem, list)
- ret++;
+
+ list_for_each(elem, list) ret++;
return ret;
}
-unsigned int count_devices(struct lib_context *lc, enum dev_type type)
+unsigned int
+count_devices(struct lib_context *lc, enum dev_type type)
{
return type == SET ? count_sets(lc, LC_RS(lc)) :
- _count_devices(lc, type);
+ _count_devices(lc, type);
}
/*
* Read RAID metadata off a device by trying
* all/selected registered format handlers in turn.
*/
-static int _want_format(struct dmraid_format *fmt, const char *format,
- enum fmt_type type)
+static int
+_want_format(struct dmraid_format *fmt, const char *format, enum fmt_type type)
{
return fmt->format != type ||
- (format && strncmp(format, fmt->name, strlen(format))) ? 0 : 1;
+ (format && strncmp(format, fmt->name, strlen(format))) ? 0 : 1;
}
-static struct raid_dev *_dmraid_read(struct lib_context *lc,
- struct dev_info *di,
- struct dmraid_format *fmt)
+static struct raid_dev *
+_dmraid_read(struct lib_context *lc,
+ struct dev_info *di, struct dmraid_format *fmt)
{
struct raid_dev *rd;
@@ -602,9 +686,9 @@
return rd;
}
-static struct raid_dev *dmraid_read(struct lib_context *lc,
- struct dev_info *di, char const *format,
- enum fmt_type type)
+static struct raid_dev *
+dmraid_read(struct lib_context *lc,
+ struct dev_info *di, char const *format, enum fmt_type type)
{
struct format_list *fl;
struct raid_dev *rd = NULL, *rd_tmp;
@@ -614,7 +698,8 @@
if (_want_format(fl->fmt, format, type) &&
(rd_tmp = _dmraid_read(lc, di, fl->fmt))) {
if (rd) {
- log_print(lc, "%s: \"%s\" and \"%s\" formats "
+ log_print(lc,
+ "%s: \"%s\" and \"%s\" formats "
"discovered (using %s)!",
di->path, rd_tmp->fmt->name,
rd->fmt->name, rd->fmt->name);
@@ -630,7 +715,8 @@
/*
* Write RAID metadata to a device.
*/
-int write_dev(struct lib_context *lc, struct raid_dev *rd, int erase)
+int
+write_dev(struct lib_context *lc, struct raid_dev *rd, int erase)
{
int ret = 0;
struct dmraid_format *fmt = rd->fmt;
@@ -638,10 +724,10 @@
if (fmt->write) {
log_notice(lc, "%sing metadata %s %s",
erase ? "Eras" : "Writ",
- erase ? "on" : "to",
- rd->di->path);
+ erase ? "on" : "to", rd->di->path);
ret = fmt->write(lc, rd, erase);
- } else
+ }
+ else
log_err(lc, "format \"%s\" doesn't support writing metadata",
fmt->name);
@@ -651,14 +737,15 @@
/*
* Group RAID device into a RAID set.
*/
-static inline struct raid_set *dmraid_group(struct lib_context *lc,
- struct raid_dev *rd)
+static inline struct raid_set *
+dmraid_group(struct lib_context *lc, struct raid_dev *rd)
{
return rd->fmt->group(lc, rd);
}
/* Check that device names are members of the devices list. */
-static int _want_device(struct dev_info *di, char **devices)
+static int
+_want_device(struct dev_info *di, char **devices)
{
char **dev;
@@ -673,8 +760,29 @@
return 0;
}
+/* Discover RAID devices that are spares */
+void
+discover_raid_devices_spares(struct lib_context *lc, const char *format)
+{
+ struct dev_info *di;
+
+ /* Walk the list of discovered block devices. */
+ list_for_each_entry(di, LC_DI(lc), list) {
+ struct raid_dev *rd;
+
+ if ((rd = dmraid_read(lc, di, format, FMT_RAID))) {
+ /* FIXME: */
+ /*if (T_SPARE(rd)) */
+ list_add_tail(&rd->list, LC_RD(lc));
+
+ }
+
+ }
+}
+
/* Discover RAID devices. */
-void discover_raid_devices(struct lib_context *lc, char **devices)
+void
+discover_raid_devices(struct lib_context *lc, char **devices)
{
struct dev_info *di;
char *names = NULL;
@@ -682,7 +790,7 @@
/* In case we've got format identifiers -> duplicate string for loop. */
if (OPT_FORMAT(lc) &&
- (!(names = dbg_strdup((char*) OPT_STR_FORMAT(lc))))) {
+ (!(names = dbg_strdup((char *) OPT_STR_FORMAT(lc))))) {
log_alloc_err(lc, __func__);
return;
}
@@ -714,8 +822,8 @@
*
* FIXME: remove partition code in favour of kpartx ?
*/
-static void _discover_partitions(struct lib_context *lc,
- struct list_head *rs_list)
+static void
+_discover_partitions(struct lib_context *lc, struct list_head *rs_list)
{
char *path;
struct dev_info *di;
@@ -738,8 +846,7 @@
* Skip all "container" sets, which are not active.
*/
if (base_partitioned_set(lc, rs) ||
- partitioned_set(lc, rs) ||
- !dm_status(lc, rs))
+ partitioned_set(lc, rs) || !dm_status(lc, rs))
continue;
log_notice(lc, "discovering partitions on \"%s\"", rs->name);
@@ -766,7 +873,8 @@
* We don't want to access that 'pointer'!
*/
if ((r = dmraid_group(lc, rd))) {
- log_notice(lc, "created partitioned RAID set(s) for %s",
+ log_notice(lc,
+ "created partitioned RAID set(s) for %s",
di->path);
rs->flags |= f_partitions;
} else
@@ -781,7 +889,8 @@
}
}
-void discover_partitions(struct lib_context *lc)
+void
+discover_partitions(struct lib_context *lc)
{
_discover_partitions(lc, LC_RS(lc));
}
@@ -792,18 +901,25 @@
* name = NULL : build all sets
* name = String: build just the one set
*/
-static void want_set(struct lib_context *lc, struct raid_set *rs, char *name)
+static void
+want_set(struct lib_context *lc, struct raid_set *rs, char *name)
{
- if (name) {
+ struct raid_set *rs_sub, *rs_n;
+
+ if (rs->type == t_group) {
+ list_for_each_entry_safe(rs_sub, rs_n, &rs->sets, list)
+ want_set(lc, rs_sub, name);
+
+ if (list_empty(&rs->sets))
+ free_raid_set(lc, rs);
+ } else if (name) {
size_t len1 = strlen(rs->name), len2 = strlen(name);
- if (len2 > len1 ||
- strncmp(rs->name, name, min(len1, len2))) {
+ if (len2 != len1 || strncmp(rs->name, name, min(len1, len2))) {
struct dmraid_format *fmt = get_format(rs);
-
- log_notice(lc, "dropping unwanted RAID set \"%s\"",
+ log_notice(lc,
+ "dropping unwanted RAID set \"%s\"",
rs->name);
-
/*
* ddf1 carries a private pointer to it's contianing
* set which is cleared as part of the check. So we
@@ -820,7 +936,8 @@
}
/* Get format handler of RAID set. */
-struct dmraid_format *get_format(struct raid_set *rs)
+struct dmraid_format *
+get_format(struct raid_set *rs)
{
/* Decend RAID set hierarchy. */
while (SETS(rs))
@@ -830,21 +947,30 @@
}
/* Find the set associated with a device */
-struct raid_set *get_raid_set(struct lib_context *lc, struct raid_dev *dev)
+struct raid_set *
+get_raid_set(struct lib_context *lc, struct raid_dev *dev)
{
- struct raid_set *rs;
- struct raid_dev *rd;
+ struct raid_set *rs = NULL, *sub_rs = NULL;
+ struct raid_dev *rd = NULL;
- list_for_each_entry(rs, LC_RS(lc), list)
- list_for_each_entry(rd, &rs->devs, devs)
- if (dev == rd)
- return rs;
+ list_for_each_entry(rs, LC_RS(lc), list) {
+ list_for_each_entry(rd, &rs->devs, devs) if (dev == rd)
+ return rs;
+ if (T_GROUP(rs)) {
+ list_for_each_entry(sub_rs, &rs->sets, list) {
+ list_for_each_entry(rd, &rs->devs, devs)
+ if (dev == rd)
+ return rs;
+ }
+ }
+ }
return NULL;
}
-/* Check metadata consistency of raid sets. */
-static void check_raid_sets(struct lib_context *lc)
+/* Check metadata consistency of RAID sets. */
+static void
+check_raid_sets(struct lib_context *lc)
{
struct list_head *elem, *tmp;
struct raid_set *rs;
@@ -874,7 +1000,9 @@
return;
}
-int group_set(struct lib_context *lc, char *name)
+/* Build RAID sets from devices on global RD list. */
+static int
+build_set(struct lib_context *lc, char *name)
{
struct raid_dev *rd;
struct raid_set *rs;
@@ -906,14 +1034,571 @@
/* Check sanity of grouped RAID sets. */
check_raid_sets(lc);
+ return 1;
+}
+
+struct raid_set_descr {
+ char *name;
+ uint64_t size;
+ char *raid_level;
+ uint64_t stripe_size;
+ char *disks;
+ //uint8_t num_disks;
+ //struct list_head *disks;
+};
+
+/* RAID set creation options. */
+static struct option rs_lopts[] = {
+ { "size", required_argument, NULL, 's'},
+ { "type", required_argument, NULL, 'r'},
+ { "str", required_argument, NULL, 't'},
+ { "stri", required_argument, NULL, 't'},
+ { "strip", required_argument, NULL, 't'},
+ { "strid", required_argument, NULL, 't'},
+ { "disk", required_argument, NULL, 'd'},
+ { "disks", required_argument, NULL, 'd'},
+ { NULL, no_argument, NULL, 0},
+};
+
+#define RAIDLEVEL_INVALID 0xff
+#define MAX_STACK 16
+static enum type
+check_raid_level(char *raidlevel)
+{
+ int len, i;
+
+ if (raidlevel == NULL)
+ return t_undef;
+
+ for (i = 0, len = strlen(raidlevel); i < len; i++) {
+ if (!isdigit(raidlevel[i]))
+ return t_undef;
+ }
+
+ if (i > MAX_STACK)
+ return t_undef;
+
+ return t_raid0;
+}
+
+static int
+check_size(char *size)
+{
+ int c;
+ size_t len;
+ char *pEnd;
+
+ if (!size)
+ return 0;
+
+ len = strlen(size);
+ strtod(size, &pEnd);
+
+ /* No unit. */
+ if (size + len == pEnd)
+ return 1;
+
+ /* Check units. */
+ c = tolower(size[len - 1]);
+ if (c == 'b')
+ len--;
+
+ c = tolower(size[len - 1]);
+ if (c == 'k' || c == 'm' || c == 'g')
+ len--;
+
+ return size + len == pEnd ? 1 : 0;
+}
+
+/*
+ * The unit of a raid size can be byte(b) or block(B)(512 bytes)
+ * k=1024 and m=1024*1024 or g=1024*1024*1024.
+ *
+ * Return size in byte
+ */
+static uint64_t
+get_raid_size(char *rsp)
+{
+ char *pEnd, *pSizeUnit;
+ double dRsp;
+ uint64_t mul = 1;
+
+ if ((dRsp = strtod(rsp, &pEnd)) <= 0)
+ dRsp = 0;
+
+ if ((pSizeUnit = strpbrk(pEnd, "kKmMgG"))) {
+ switch (tolower(*pSizeUnit)) {
+ case 'g':
+ mul *= 1024;
+ case 'm':
+ mul *= 1024;
+ case 'k':
+ mul *= 1024;
+ }
+ }
+
+ if ((pSizeUnit = strpbrk(pEnd, "bB"))) {
+ if (*pSizeUnit == 'B')
+ mul *= 512;
+ }
+
+ return (uint64_t) (dRsp * mul);
+}
+
+/* Parse RAID set creation arguments. */
+int
+parse_rs_args(struct lib_context *lc, char **argv, struct raid_set_descr *rsd)
+{
+ int o, n, opt_idx;
+
+ optind = 0;
+ rsd->raid_level = NULL;
+ rsd->size = 0;
+ rsd->stripe_size = 0;
+ rsd->disks = NULL;
+
+ /* set rsd structure for spare disk set */
+ if (OPT_HOT_SPARE_SET(lc)) {
+ rsd->name = (char *) OPT_STR_HOT_SPARE_SET(lc);
+ rsd->raid_level = (char *) SPARE_TYPE_STRING;
+ rsd->disks = (char *) OPT_STR_REBUILD_DISK(lc);
+ } else {
+ if (!argv[0] || !*argv[0])
+ LOG_ERR(lc, 0,
+ "failed to provide a valid RAID set name");
+
+ /* Handle the case -Cname. */
+ rsd->name = strstr(argv[0], "-C") ? argv[0] + 2 : argv[0];
+
+ for (n = 0; *(argv + n); n++);
+ if (n < 4)
+ LOG_ERR(lc, 0, "too few arguments");
+
+ while ((o = getopt_long(n, argv, ":",
+ rs_lopts, &opt_idx)) != -1) {
+ switch (o) {
+ case 's':
+ if (!check_size(optarg))
+ LOG_ERR(lc, 0, "failed to config size");
+
+ if (!rsd->size)
+ rsd->size = get_raid_size(optarg);
+ break;
+
+ case 'r':
+ if (!rsd->raid_level)
+ rsd->raid_level = optarg;
+ break;
+
+ case 't':
+ if (!check_size(optarg))
+ LOG_ERR(lc, 0,
+ "failed to config stripe");
+
+ if (!rsd->stripe_size)
+ rsd->stripe_size =
+ get_raid_size(optarg);
+ break;
+
+ case 'd':
+ if (!rsd->disks)
+ rsd->disks = optarg;
+ break;
+
+ case '?':
+ LOG_ERR(lc, 0, "unknown option");
+ }
+ }
+ }
+
+ return 1;
+}
+
+struct dev_info *
+find_disk(struct lib_context *lc, char *dp)
+{
+ struct dev_info *di;
+
+ if ((dp == NULL) || (*dp == '\0'))
+ LOG_ERR(lc, 0, "failed to provide an array of disks");
+
+
+ list_for_each_entry(di, LC_DI(lc), list) {
+ if (!strcmp(di->path, dp))
+ return di;
+ }
+
+ return NULL;
+}
+
+static struct dmraid_format *
+find_format(struct lib_context *lc, const char *cp)
+{
+ struct format_list *fl;
+
+ if (cp == NULL)
+ LOG_ERR(lc, 0, "format handler string is NULL");
+
+
+ list_for_each_entry(fl, LC_FMT(lc), list) {
+ if (!(strcmp(fl->fmt->name, cp)))
+ return fl->fmt;
+ }
+ return NULL;
+}
+
+/*
+ * Remove the first digit and return a raid type according to the
+ * value of the first digit.
+ */
+static enum type
+get_raid_level(char **rl)
+{
+ char c;
+ struct raid_type {
+ char c;
+ enum type level;
+ };
+ static struct raid_type rts[] = {
+ { '0', t_raid0 },
+ { '1', t_raid1 },
+ { '4', t_raid4 },
+ { '5', t_raid5_la }, /* FIXME: other RAID5 algorithms? */
+ { '6', t_raid6 },
+ { '8', t_spare }, /* FIXME: Intel abuse of raid char. */
+ };
+ struct raid_type *rt = ARRAY_END(rts);
+
+ if (rl && *rl) {
+ c = **rl;
+ (*rl)++;
+
+ while (rt-- > rts) {
+ if (rt->c == c)
+ return rt->level;
+ }
+ }
+
+ return t_undef;
+}
+
+#define MAX_NAME_LEN 15
+static int
+check_rsd(struct lib_context *lc, struct raid_set_descr *rsd)
+{
+ uint16_t i, len;
+
+ if (!find_format(lc, OPT_STR_FORMAT(lc)))
+ LOG_ERR(lc, 0, "unknown format type: %s",
+ lc->options[LC_FORMAT].arg.str);
+
+ if (check_raid_level(rsd->raid_level) == t_undef)
+ LOG_ERR(lc, 0, "failed to provide a valid RAID type");
+
+ /* do not check name set, if it is spare set without name */
+ if (!((rsd->name == NULL) &&
+ !(strcmp(rsd->raid_level, SPARE_TYPE_STRING)))) {
+
+ if ((len = strlen(rsd->name)) > MAX_NAME_LEN)
+ LOG_ERR(lc, 0, "name %s is longer than %d chars",
+ rsd->name, MAX_NAME_LEN);
+
+ if (len == 0)
+ LOG_ERR(lc, 0, "no RAID set name provided");
+ else if (!isalnum(rsd->name[0]))
+ LOG_ERR(lc, 0, "first character of a name must "
+ "be an alphanumeric charater");
+
+ for (i = 1; i < len; i++) {
+ if ((!isalnum(rsd->name[i]))
+ && (rsd->name[i] != '_')
+ && (rsd->name[i] != '-'))
+ LOG_ERR(lc, 0, "name %s has non-alphanumeric "
+ "characters", rsd->name);
+ }
+ }
+
+ if ((rsd->disks == NULL) || (*(rsd->disks) == 0))
+ LOG_ERR(lc, 0, "no hard drives specified");
+
+ return 1;
+}
+
+static void
+free_raidset(struct lib_context *lc, struct raid_set *rs)
+{
+ struct raid_set *rs1;
+
+ if (SETS(rs)) {
+ rs1 = list_entry(rs->sets.next, struct raid_set, list);
+ free_raidset(lc, rs1);
+ }
+ if (rs)
+ _free_raid_set(lc, rs);
+}
+
+struct raid_dev *
+find_raiddev(struct lib_context *lc, struct raid_set *rs, struct dev_info *di)
+{
+ struct raid_dev *rd;
+
+ if (di == NULL)
+ LOG_ERR(lc, 0, "failed to provide dev info");
+
+ list_for_each_entry(rd, &rs->devs, devs) {
+ if (rd->di == di)
+ return rd;
+ }
+
+ return NULL;
+}
+
+struct raid_set *
+create_raidset(struct lib_context *lc, struct raid_set_descr *rsd)
+{
+ struct raid_set *rs, *rs_sub, *rs_tmp;
+ struct dev_info *di;
+ struct raid_dev *rd;
+ struct dmraid_format *fmt;
+ enum type rt;
+ int n = 0;
+ char *start, *end;
+
+ if (!check_rsd(lc, rsd))
+ return NULL;
+
+ if (!(rs = alloc_raid_set(lc, __func__)))
+ return NULL;
+
+ /* case if it is spare disk set without name */
+ if (!rsd->name
+ && !(strcmp(rsd->raid_level, SPARE_TYPE_STRING))) {
+ rs->name = NULL;
+ } else {
+ if (!(rs->name = dbg_strdup(rsd->name)))
+ goto err;
+ }
+
+ /* the format type has been checked by check_rsd */
+ fmt = find_format(lc, OPT_STR_FORMAT(lc));
+ /*
+ * The raid level has been checked at the function check_rsd.
+ * Use get_raid_level to remove the first digit from the string.
+ */
+ rt = get_raid_level(&rsd->raid_level);
+
+ if (rsd->size)
+ rs->size = (rsd->size - 1) / 512 + 1;
+
+ if (rsd->stripe_size)
+ rs->stride = (rsd->stripe_size - 1) / 512 + 1;
+
+ rs->type = rt;
+ rs->flags = 0;
+ rs->status = s_init;
+ end = rsd->disks;
+ replace_delimiter(end, ',', ' ');
+ remove_tail_space(end);
+
+ do {
+ start = end;
+ /* skip space */
+ for (; *start == ' '; start++);
+ end = remove_delimiter(start, ' ');
+
+ if (!(di = find_disk(lc, start))) {
+ log_err(lc, "failed to find disk %s", start);
+ goto err;
+ }
+
+ /* check if device is not duplicated on the raid dev list */
+ if (find_raiddev(lc, rs, di)) {
+ log_err(lc, "disk %s is duplicated on the disk list",
+ di->path);
+ goto err;
+ }
+
+ if (!(rd = alloc_raid_dev(lc, __func__))) {
+ log_err(lc, "failed to allocate space for a raid_dev");
+ goto err;
+ }
+
+ rd->name = NULL;
+ rd->di = di;
+ rd->fmt = fmt;
+ rd->status = s_init;
+ rd->type = t_undef;
+ rd->offset = 0;
+ rd->sectors = 0;
+ list_add_tail(&rd->devs, &rs->devs);
+ n++;
+ } while (end++ != '\0');
+
+ rs->total_devs = rs->found_devs = n;
+ rs_tmp = rs;
+
+ /*
+ * If there is a stacked RAID set, all sub sets are
+ * created and only the type is required to set
+ */
+ while (*rsd->raid_level) {
+ if ((!(rt = get_raid_level(&rsd->raid_level))) ||
+ !(rs_sub = alloc_raid_set(lc, __func__)))
+ goto err;
+
+ rs_sub->type = rt;
+ list_add_tail(&rs_sub->list, &rs_tmp->sets);
+ rs_tmp = rs_sub;
+ }
+
+ return rs;
+
+ err:
+ free_raidset(lc, rs);
+ return NULL;
+}
+
+
+int
+rebuild_config_raidset(struct lib_context *lc, struct raid_set *rs)
+{
+
+ struct raid_dev *rd;
+ struct raid_set *rs1 = NULL;
+ struct list_head *elem, *tmp;
+ struct dmraid_format *fmt;
+ int ret = 0;
+
+ if (!(fmt = (RD_RS(rs)->fmt)))
+ return 0;
+
+ if (!(fmt->create))
+ LOG_ERR(lc, 0,
+ "metadata creation isn't supported in \"%s\" format",
+ fmt->name);
+
+ if ((ret = fmt->create(lc, rs)) && (printf("no write_set\n"), 1)) { /* (ret=write_set(lc, rs)) */
+ /* free rebuilded RAID set and then reconstr */
+ free_raid_set(lc, rs);
+ list_for_each_safe(elem, tmp, LC_RD(lc)) {
+ //list_del(elem);
+ rd = RD(elem);
+ rd->status = s_ok;
+ if (!(rs1 = dmraid_group(lc, rd)))
+ LOG_ERR(lc, 0,
+ "failed to build the created RAID set");
+ want_set(lc, rs1, rs->name);
+ }
+ if (rs1)
+ fmt->check(lc, rs1);
+ }
return 1;
}
+static int
+config_raidset(struct lib_context *lc, struct raid_set *rs)
+{
+ struct raid_dev *rd;
+ struct raid_set *rs1 = NULL;
+ struct list_head *elem, *tmp;
+ struct dmraid_format *fmt;
+ int ret = 0;
+
+ if (!(fmt = RD_RS(rs)->fmt))
+ return 0;
+
+ if (!fmt->create)
+ LOG_ERR(lc, 0,
+ "metadata creation isn't supported in \"%s\" format",
+ fmt->name);
+
+ if ((ret = fmt->create(lc, rs)) && (ret = write_set(lc, rs))) {
+ free_raid_set(lc, NULL);
+
+ list_for_each_safe(elem, tmp, &rs->devs) {
+ list_del(elem);
+ rd = RD(elem);
+ rd->status = s_ok;
+
+ if (!(rs1 = dmraid_group(lc, rd)))
+ LOG_ERR(lc, 0,
+ "failed to build the created RAID set");
+
+ want_set(lc, rs1, rs->name);
+ }
+
+ if (rs1)
+ fmt->check(lc, rs1);
+ }
+
+ free_raidset(lc, rs);
+ return ret;
+}
+
+
+int
+group_set(struct lib_context *lc, char **argv)
+{
+ char **sets = argv;
+ int i = 0;
+ struct raid_set_descr rsd;
+ struct raid_set *rs;
+
+ /* This is valid if name of RAID set is required. */
+ if (!OPT_HOT_SPARE_SET(lc) && !OPT_STR_HOT_SPARE_SET(lc)) {
+ if (!build_set(lc, sets[i]))
+ LOG_ERR(lc, 0, "failed to build a RAID set");
+
+ /* The required RAID set is found. */
+ if (!list_empty(LC_RS(lc)))
+ return 1;
+
+ /* There is no way for add spare disk to RAID set. */
+ if (!OPT_FORMAT(lc) &&
+ OPT_REBUILD_DISK(lc) && OPT_HOT_SPARE_SET(lc))
+ return 0;
+
+ /*
+ * Since there are several arguments required for
+ * creating a RAID set, we know that the intented command is to list all RAID sets.
+ */
+ if (!sets[0])
+ LOG_ERR(lc, 0, "no RAID set found");
+
+ }
+
+ /* This is not argument for creating spare RAID set. */
+ if (!OPT_HOT_SPARE_SET(lc)) {
+ /*
+ * Make sure we have min arguments for creating a RAID set:
+ * a name and an option.
+ */
+ if (!sets[1])
+ LOG_ERR(lc, 0,
+ "either the required RAID set not found or more options required");
+
+ if (sets[1][0] != '-')
+ LOG_ERR(lc, 0,
+ "only one argument allowed for this option");
+ }
+
+ if (!parse_rs_args(lc, argv, &rsd))
+ return 0;
+
+ if (!build_set(lc, NULL))
+ LOG_ERR(lc, 0, "failed to get the existing RAID set info");
+
+ if (!(rs = create_raidset(lc, &rsd)))
+ return 0;
+
+ return config_raidset(lc, rs);
+}
+
/* Process function on RAID set(s) */
-static void process_set(struct lib_context *lc, void *rs,
- int (*func)(struct lib_context *lc, void *rs, int arg),
- int arg)
+static void
+process_set(struct lib_context *lc, void *rs,
+ int (*func) (struct lib_context * lc, void *rs, int arg), int arg)
{
if (!partitioned_set(lc, rs))
func(lc, rs, arg);
@@ -922,28 +1607,30 @@
/* FIXME: remove partition code in favour of kpartx ? */
static void
process_partitioned_set(struct lib_context *lc, void *rs,
- int (*func)(struct lib_context *lc, void *rs, int arg),
- int arg)
+ int (*func) (struct lib_context * lc, void *rs,
+ int arg), int arg)
{
if (partitioned_set(lc, rs) && !base_partitioned_set(lc, rs))
func(lc, rs, arg);
}
-void process_sets(struct lib_context *lc,
- int (*func)(struct lib_context *lc, void *rs, int arg),
- int arg, enum set_type type)
+void
+process_sets(struct lib_context *lc,
+ int (*func) (struct lib_context * lc, void *rs, int arg),
+ int arg, enum set_type type)
{
struct raid_set *rs;
- void (*p)(struct lib_context *l, void *r,
- int (*f)(struct lib_context *lc, void *rs, int arg), int a) =
+ void (*p) (struct lib_context * l, void *r,
+ int (*f) (struct lib_context * lc, void *rs, int arg),
+ int a) =
(type == PARTITIONS) ? process_partitioned_set : process_set;
- list_for_each_entry(rs, LC_RS(lc), list)
- p(lc, rs, func, arg);
+ list_for_each_entry(rs, LC_RS(lc), list) p(lc, rs, func, arg);
}
/* Write RAID set metadata to devices. */
-int write_set(struct lib_context *lc, void *v)
+int
+write_set(struct lib_context *lc, void *v)
{
int ret = 1;
struct raid_set *r, *rs = v;
@@ -953,10 +1640,11 @@
list_for_each_entry(r, &rs->sets, list) {
/*
* FIXME: does it make sense to try the rest of the subset
- * in case we fail writing one ?
+ * in case we fail writing one ?
*/
- if (!write_set(lc, (void*) r))
- log_err(lc, "writing RAID subset \"%s\", continuing",
+ if (!write_set(lc, (void *) r))
+ log_err(lc,
+ "writing RAID subset \"%s\", continuing",
r->name);
}
@@ -964,10 +1652,11 @@
list_for_each_entry(rd, &rs->devs, devs) {
/*
* FIXME: does it make sense to try the rest of the
- * devices in case we fail writing one ?
+ * devices in case we fail writing one ?
*/
if (!write_dev(lc, rd, 0)) {
- log_err(lc, "writing RAID device \"%s\", continuing",
+ log_err(lc,
+ "writing RAID device \"%s\", continuing",
rd->di->path);
ret = 0;
}
@@ -977,7 +1666,8 @@
}
/* Erase ondisk metadata. */
-int erase_metadata(struct lib_context *lc)
+int
+erase_metadata(struct lib_context *lc)
{
int ret = 1;
struct raid_dev *rd;
@@ -1001,7 +1691,8 @@
*
* Return neutralized RAID type for given mapping array (linear, raid0, ...)
*/
-enum type rd_type(struct types *t, unsigned int type)
+enum type
+rd_type(struct types *t, unsigned int type)
{
for (; t->unified_type != t_undef && t->type != type; t++);
return t->unified_type;
@@ -1012,9 +1703,13 @@
*
* Return neutralized RAID status for given metadata status
*/
-enum status rd_status(struct states *s, unsigned int status, enum compare cmp)
+enum status
+rd_status(struct states *s, unsigned int status, enum compare cmp)
{
- for (; s->status && (cmp == AND ? !(s->status & status) : (s->status != status)); s++);
+ for (;
+ s->status
+ && (cmp ==
+ AND ? !(s->status & status) : (s->status != status)); s++);
return s->unified_status;
}
@@ -1024,10 +1719,10 @@
* Sort an element into a list by optionally
* using a metadata format handler helper function.
*/
-void list_add_sorted(struct lib_context *lc,
- struct list_head *to, struct list_head *new,
- int (*f_sort)(struct list_head *pos,
- struct list_head *new))
+void
+list_add_sorted(struct lib_context *lc,
+ struct list_head *to, struct list_head *new,
+ int (*f_sort) (struct list_head * pos, struct list_head * new))
{
struct list_head *pos;
@@ -1055,14 +1750,16 @@
* File RAID metadata and offset on device for analysis.
*/
/* FIXME: all files into one directory ? */
-static size_t __name(struct lib_context *lc, char *str, size_t len,
- const char *path, const char *suffix)
+static size_t
+__name(struct lib_context *lc, char *str, size_t len,
+ const char *path, const char *suffix)
{
return snprintf(str, len, "%s.%s",
- get_basename(lc, (char*) path), suffix) + 1;
+ get_basename(lc, (char *) path), suffix) + 1;
}
-static char *_name(struct lib_context *lc, const char *path, const char *suffix)
+static char *
+_name(struct lib_context *lc, const char *path, const char *suffix)
{
size_t len;
char *ret;
@@ -1075,8 +1772,9 @@
return ret;
}
-static int file_data(struct lib_context *lc, const char *handler,
- char *path, void *data, size_t size)
+static int
+file_data(struct lib_context *lc, const char *handler,
+ char *path, void *data, size_t size)
{
int ret = 0;
char *name;
@@ -1090,21 +1788,23 @@
return ret;
}
-static void file_number(struct lib_context *lc, const char *handler,
- char *path, uint64_t number, const char *suffix)
+static void
+file_number(struct lib_context *lc, const char *handler,
+ char *path, uint64_t number, const char *suffix)
{
char *name, s_number[32];
-
+
if ((name = _name(lc, path, suffix))) {
log_notice(lc, "writing %s to file \"%s\"", suffix, name);
- write_file(lc, handler, name, (void*) s_number,
- snprintf(s_number, sizeof(s_number),
- "%" PRIu64 "\n", number), 0);
+ write_file(lc, handler, name, (void *) s_number,
+ snprintf(s_number, sizeof(s_number),
+ "%" PRIu64 "\n", number), 0);
dbg_free(name);
}
}
-static int _chdir(struct lib_context *lc, const char *dir)
+static int
+_chdir(struct lib_context *lc, const char *dir)
{
if (chdir(dir)) {
log_err(lc, "changing directory to %s", dir);
@@ -1114,7 +1814,8 @@
return 0;
}
-static char *_dir(struct lib_context *lc, const char *handler)
+static char *
+_dir(struct lib_context *lc, const char *handler)
{
char *dir = _name(lc, lc->cmd, handler);
@@ -1129,7 +1830,7 @@
if (!_chdir(lc, dir))
return dir;
- out:
+ out:
dbg_free(dir);
return NULL;
}
@@ -1137,8 +1838,9 @@
/*
* File vendor RAID metadata.
*/
-void file_metadata(struct lib_context *lc, const char *handler,
- char *path, void *data, size_t size, uint64_t offset)
+void
+file_metadata(struct lib_context *lc, const char *handler,
+ char *path, void *data, size_t size, uint64_t offset)
{
if (OPT_DUMP(lc)) {
char *dir = _dir(lc, handler);
@@ -1158,8 +1860,8 @@
/*
* File RAID device size.
*/
-void file_dev_size(struct lib_context *lc, const char *handler,
- struct dev_info *di)
+void
+file_dev_size(struct lib_context *lc, const char *handler, struct dev_info *di)
{
if (OPT_DUMP(lc)) {
char *dir = _dir(lc, handler);
@@ -1173,3 +1875,307 @@
_chdir(lc, "..");
}
}
+
+/* Delete RAID set(s) */
+int
+delete_raidsets(struct lib_context *lc)
+{
+ struct raid_set *rs, *rs1;
+ struct raid_dev *rd;
+ int n = 0, status;
+
+ if (list_empty(&(lc->lists[LC_RAID_SETS])))
+ LOG_ERR(lc, 0, "Cannot find a RAID set to delete");
+
+ list_for_each_entry(rs, LC_RS(lc), list) {
+ if (!(rd = list_entry(rs->devs.next, struct raid_dev, devs)))
+ LOG_ERR(lc, 0, "Failed to locate the raid device");
+
+ if (rs->type == t_group) {
+ list_for_each_entry(rs1, &rs->sets, list) {
+ status = dm_status(lc, rs1);
+ if (status == 1)
+ LOG_ERR(lc, 0,
+ "%s is active and cannot be deleted",
+ rs1->name);
+
+ n++;
+ }
+ if (n > 1) {
+ printf("\nAbout to delete the raid super-set \"%s\" with the following RAID sets\n", rs->name);
+ list_for_each_entry(rs1, &rs->sets, list)
+ printf("%s\n", rs1->name);
+ }
+ else if (n == 1) {
+ rs1 = list_entry(rs->sets.next,
+ struct raid_set, list);
+ printf("\nAbout to delete RAID set %s\n",
+ rs1->name);
+ }
+ else
+ LOG_ERR(lc, 0, "coding error");
+ }
+ else {
+ printf("\nAbout to delete RAID set %s\n", rs->name);
+ }
+ printf("\nWARNING: The metadata stored on the raidset(s) will not be accessible after deletion\n");
+ if (!yes_no_prompt(lc, "Do you want to continue"))
+ return 0;
+
+ if (!rd->fmt->delete)
+ LOG_ERR(lc, 0,
+ "Raid set deletion is not supported in \"%s\" format",
+ rd->fmt->name);
+
+ rd->fmt->delete(lc, rs);
+
+ }
+
+ return 1;
+}
+
+struct raid_set *find_set_inconsistent(struct lib_context *lc,
+ struct raid_set *rs);
+
+struct raid_dev *find_spare(struct lib_context *lc,
+ struct raid_set *rs2rebuild,
+ struct raid_set **spareRs);
+
+struct raid_set *
+find_set_inconsistent(struct lib_context *lc, struct raid_set *rs)
+{
+ struct raid_set *r, *rsb;
+
+ list_for_each_entry(r, &rs->sets, list) {
+ if (T_GROUP(r) && !(rsb = find_set_inconsistent(lc, r)))
+ return rsb;
+ }
+
+ return (DEVS(rs) &&
+ (S_BROKEN(rs->status) || S_INCONSISTENT(rs->status))) ?
+ rs : NULL;
+
+}
+
+
+/*
+ * Search for spare drive that can be used to fix given rs.
+ *
+ * Returns spare raid_dev and its spare RAID set.
+ * Based on format configuration searches:
+ * localy (in RAID set that shall be fixed)
+ * globaly (any spare drive that can be used to fix rs)
+ */
+struct raid_dev *
+find_spare(struct lib_context *lc, struct raid_set *rs,
+ struct raid_set **spare_rs)
+{
+ struct raid_dev *closest = NULL, *spare_rd, *rd = NULL;
+ struct raid_set *rs_failed = NULL, *tmp_spare_rs = NULL;
+ struct dmraid_format *fmt = get_format(rs);
+
+ /* Find rd that will be evaluated for replacement. */
+
+ /* Search the spare sets for eligible disk. */
+ if (!(rs_failed = find_set_inconsistent(lc, rs)) ||
+ !(rd = RD_RS(rs_failed)))
+ LOG_PRINT(lc, NULL,
+ "no failed subsets or no device in subset found");
+
+
+ /* Local search - based on fmt. */
+ if (fmt->scope & t_scope_local) {
+ struct raid_set *group_rs = find_group(lc, rs);
+
+ if (!group_rs)
+ return NULL;
+
+ list_for_each_entry(tmp_spare_rs, &group_rs->sets, list) {
+ if (DEVS(tmp_spare_rs) && T_SPARE(tmp_spare_rs)) {
+ list_for_each_entry(spare_rd,
+ &tmp_spare_rs->devs, devs) {
+ /* Simple check of size */
+ if (spare_rd->di->sectors >=
+ rd->di->sectors &&
+ (!closest ||
+ closest->di->sectors <
+ rd->di->sectors)) {
+ if (spare_rd->di->sectors ==
+ rd->di->sectors) {
+ /* Match */
+ closest = spare_rd;
+ break;
+ }
+
+ closest = spare_rd;
+ }
+ }
+ }
+ }
+ }
+
+ /* Global search - based on fmt */
+ if ((fmt->scope & t_scope_global) && !closest) {
+ struct raid_set *group_rs;
+
+ list_for_each_entry(group_rs, LC_RS(lc), list) {
+ if (T_GROUP(group_rs)
+ && (get_format(group_rs) == fmt)) {
+ list_for_each_entry(tmp_spare_rs,
+ &group_rs->sets, list) {
+ if ((DEVS(tmp_spare_rs)) &&
+ T_SPARE(tmp_spare_rs)) {
+ list_for_each_entry(spare_rd, &tmp_spare_rs->devs, devs) {
+ /* Simple check of size. */
+ if ((spare_rd->di->sectors >= rd->di->sectors) &&
+ (!closest == NULL ||
+ closest->di->sectors < rd->di->sectors)) {
+ if (spare_rd->di->sectors == rd->di->sectors) {
+ /* match */
+ closest = spare_rd;
+ break;
+ }
+
+ closest = spare_rd;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Global search. */
+ if (closest) {
+ *spare_rs = get_raid_set(lc, closest);
+ return closest;
+ }
+
+ /* spare not found */
+ return NULL;
+}
+
+
+void
+format_error(struct lib_context *lc, const char *error, char **argv)
+{
+ log_print_nnl(lc, "no raid %s", error);
+
+ if (OPT_FORMAT(lc))
+ log_print_nnl(lc, " with format: \"%s\"", OPT_STR_FORMAT(lc));
+
+
+ if (argv && *argv) {
+ log_print_nnl(lc, " and with names: \"");
+
+ while (*argv) {
+ log_print_nnl(lc, "%s", *argv++);
+ if (*argv)
+ log_print_nnl(lc, "%s", OPT_STR_SEPARATOR(lc));
+ else
+ log_print_nnl(lc, "\"");
+ }
+ }
+
+ log_print(lc, "");
+}
+
+/* Retrieve and build metadata. */
+static int
+get_metadata(struct lib_context *lc, enum action action,
+ struct prepost *p, char **argv)
+{
+ if (!(M_DEVICE & p->metadata))
+ return 1;
+
+ if (!discover_devices(lc, OPT_DEVICES(lc) ? argv : NULL))
+ LOG_ERR(lc, 0, "failed to discover devices");
+
+ if (!count_devices(lc, DEVICE)) {
+ log_print(lc, "no block devices found");
+ return 1;
+ }
+
+ if (!(M_RAID & p->metadata))
+ return 1;
+
+#ifndef DMRAID_MINI
+ /* Discover RAID disks and keep RAID metadata (eg, hpt45x) */
+ discover_raid_devices(lc,
+# ifdef DMRAID_NATIVE_LOG
+ ((NATIVE_LOG | RAID_DEVICES) & action) ? argv
+ : NULL);
+# else
+ (RAID_DEVICES & action) ? argv : NULL);
+# endif
+#else
+ discover_raid_devices(lc, NULL);
+#endif
+
+ if (!OPT_HOT_SPARE_SET(lc) && !OPT_CREATE(lc)
+ && !count_devices(lc, RAID)) {
+ format_error(lc, "disks", argv);
+ return 1;
+ }
+
+ if (M_SET & p->metadata) {
+ /* Group RAID sets. */
+ group_set(lc, argv);
+ if (!OPT_HOT_SPARE_SET(lc) && !OPT_CREATE(lc)
+ && !count_devices(lc, SET)) {
+ format_error(lc, "sets", argv);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+
+int
+lib_perform(struct lib_context *lc, enum action action,
+ struct prepost *p, char **argv)
+{
+ int ret = 0;
+
+ if (ROOT == p->id && geteuid())
+ LOG_ERR(lc, 0, "you must be root");
+
+ /* Lock against parallel runs. Resource NULL for now. */
+ if (LOCK == p->lock && !lock_resource(lc, NULL))
+ LOG_ERR(lc, 0, "lock failure");
+
+ if (get_metadata(lc, action, p, argv))
+ ret = p->post(lc, p->pre ? p->pre(p->arg) : p->arg);
+
+ if (LOCK == p->lock)
+ unlock_resource(lc, NULL);
+
+ return ret;
+}
+
+int
+dso_get_members(struct lib_context *lc, int arg)
+{
+ static char disks[100] = "\0";
+ const char *vol_name = lc->options[LC_REBUILD_SET].arg.str;
+ struct raid_set *sub_rs;
+ struct raid_dev *rd;
+
+ if ((sub_rs = find_set(lc, NULL, vol_name, FIND_ALL))) {
+ lc->options[LC_REBUILD_SET].opt = 0;
+
+ list_for_each_entry(rd, &sub_rs->devs, devs) {
+ strcat(disks, rd->di->path);
+ strcat(disks, " ");
+ lc->options[LC_REBUILD_SET].opt++;
+ }
+
+ dbg_free((char *) lc->options[LC_REBUILD_SET].arg.str);
+ lc->options[LC_REBUILD_SET].arg.str = dbg_strdup(disks);
+ return 0;
+ }
+ else
+ /* RAID set not found. */
+ return 1;
+}
--- dmraid/lib/metadata/reconfig.c 2008/02/22 17:04:36 1.1
+++ dmraid/lib/metadata/reconfig.c 2008/06/20 21:52:18 1.2
@@ -4,113 +4,354 @@
* James Simshaw <simshawj at us.ibm.com>, and
* Adam DiCarlo <bikko at us.ibm.com>
*
- * Copyright (C) 2006 Heinz Mauelshagen, Red Hat GmbH
- * All rights reserved
+ * Copyright (C) 2006-2008 Heinz Mauelshagen, Red Hat GmbH
+ * All rights reserved
+ *
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
*
* See file LICENSE at the top of this source tree for license information.
*/
#include "internal.h"
+int dso = 0;
#define add_to_log(entry, log) \
list_add_tail(&(entry)->changes, &(log));
-static inline int alloc_entry(struct change **entry)
+static inline int
+alloc_entry(struct change **entry, struct lib_context *lc)
{
- return (*entry = dbg_malloc(sizeof (*entry))) ? 0 : -ENOMEM;
+ return (*entry = dbg_malloc(sizeof(*entry))) ? 0 : -ENOMEM;
}
-static int nuke_spare(struct lib_context *lc, struct raid_dev *rd)
+static int
+nuke_spare(struct lib_context *lc, struct raid_dev *rd)
{
printf("Nuking Spare\n");
list_del_init(&rd->devs);
return 0;
}
-/* Add a device to a RAID1 set and start the resync */
-static int add_dev_to_raid1(struct lib_context *lc, struct raid_set *rs,
- struct raid_dev *rd)
+int
+dso_end_rebuild(struct lib_context *lc, int arg)
{
- int ret;
- struct raid_dev *tmp;
- struct change *entry;
- LIST_HEAD(log); /* playback log */
+ struct raid_set *sub_rs;
+ const char *vol_name = lc->options[LC_REBUILD_SET].arg.str;
- /* Add device to the raid set */
- ret = alloc_entry(&entry);
- if (ret)
- goto err;
+ sub_rs = find_set(lc, NULL, vol_name, FIND_ALL);
+ if (sub_rs) {
+ struct raid_set *rs = NULL;
+
+ rs = find_group(lc, sub_rs);
+ if ((rs) && S_OK(sub_rs->status)) {
+ struct raid_dev *check_rd = RD_RS(sub_rs);
+ enum status state = s_ok;
+
+ if (check_rd->fmt->metadata_handler)
+ state = check_rd->fmt->metadata_handler(lc,
+ GET_REBUILD_STATE,
+ NULL,
+ (void *)
+ sub_rs);
+
+ if (state != s_nosync) {
+ /* cannot rebuild */
+ log_print(lc,
+ "Volume \"%s\" is not in rebuild state (current: %u)\n",
+ sub_rs->name, state);
+ return 1;
+ }
+
+ if (check_rd->fmt->metadata_handler)
+ check_rd->fmt->metadata_handler(lc,
+ UPDATE_REBUILD_STATE,
+ NULL,
+ (void *) rs);
+ } else {
+ log_print(lc,
+ "Volume \"%s\" is not in rebuild state \n",
+ vol_name);
+ return 1;
+ }
+ } else
+ log_print(lc, "raid volume \"%s\" not found\n", vol_name);
- entry->type = ADD_TO_SET;
- entry->rs = rs;
- entry->rd = rd;
- add_to_log(entry, log);
- list_add_tail(&rd->devs, &rs->devs);
- rd->type = t_raid1;
+ return 0;
+}
- /* Check that this is a sane configuration */
- list_for_each_entry(tmp, &rs->devs, devs) {
- ret = tmp->fmt->check(lc, rs);
- if (ret)
- goto err;
+int rebuild_config_raidset(struct lib_context *lc, struct raid_set *rs);
+
+void
+show_raid_stack(struct lib_context *lc)
+{
+ struct raid_set *_rs;
+ log_dbg(lc, "RM: Discovered raid sets:");
+ list_for_each_entry(_rs, LC_RS(lc), list) {
+ struct raid_dev *_rd;
+ struct raid_set *_rss;
+ log_dbg(lc, "RM: GROUP name: \"%s\"", _rs->name);
+ list_for_each_entry(_rd, &_rs->devs, devs) {
+ log_dbg(lc, "RM: GROUP_DISK name: \"%s\"",
+ (_rd->di) ? _rd->di->path : "UNKNOWN");
+ }
+ list_for_each_entry(_rss, &_rs->sets, list) {
+ struct raid_dev *_rsd;
+ struct raid_set *_rsss;
+
+ log_dbg(lc, "RM: SUPERSET name: \"%s\"", _rss->name);
+
+ list_for_each_entry(_rsd, &_rss->devs, devs) {
+ log_dbg(lc, "RM: SUPERSET_DISK name: \"%s\"",
+ (_rsd->di) ? _rsd->
+ di->path : "UNKNOWN");
+ }
+
+ list_for_each_entry(_rsss, &_rss->sets, list) {
+ struct raid_dev *_rssd;
+ log_dbg(lc, "RM: SUBSET name: \"%s\"",
+ _rsss->name);
+ list_for_each_entry(_rssd, &_rsss->devs, devs) {
+ log_dbg(lc,
+ "RM: SUBSET_DISK name: \"%s\"",
+ (_rssd->di) ? _rssd->
+ di->path : "UNKNOWN");
+ }
+ }
+ }
}
+}
- /* Write the metadata of the drive we're adding _first_ */
- ret = alloc_entry(&entry);
- if (ret)
- goto err;
+/* Add a device to a RAID1 set and start the resync */
+static int
+add_dev_to_raid(struct lib_context *lc, struct raid_set *rs,
+ struct raid_dev *rd)
+{
+ int ret = 0;
+ const char *vol_name = lc->options[LC_REBUILD_SET].arg.str;
- entry->type = WRITE_METADATA;
- entry->rd = rd;
- add_to_log(entry, log);
- ret = write_dev(lc, rd, 0);
- if (!ret)
- goto err;
+ struct raid_set *sub_rs, *crs;
+ struct raid_dev *check_rd;
- /* Write metadatas of every device in the set */
- list_for_each_entry(tmp, &rs->devs, devs) {
- if (tmp != rd) {
- ret = alloc_entry(&entry);
- if (ret)
- goto err;
- entry->type = WRITE_METADATA;
- entry->rd = tmp;
- add_to_log(entry, log);
- ret = write_dev(lc, tmp, 0);
- if (!ret)
+ LIST_HEAD(log); /* playback log */
+ sub_rs = find_set(lc, NULL, vol_name, FIND_ALL);
+ check_rd = list_entry(rs->devs.next, typeof(*rd), devs);
+
+ if (rd) {
+ if (check_rd->fmt->create) {
+ struct raid_dev *tmp;
+ if ((ret = check_rd->fmt->create(lc, rs))) {
+
+ list_for_each_entry(tmp, &rs->devs, devs) {
+ write_dev(lc, tmp, 0);
+ }
+ } else {
+ log_print(lc, "metadata fmt update failed\n");
goto err;
+ }
+ } else {
+ log_print(lc, "create failed fmt handler missing\n");
+ goto err;
+ }
+
+ struct handler_info info;
+
+ if (lc->options[LC_REBUILD_SET].opt) {
+ if (check_rd->fmt->metadata_handler) {
+ if (!check_rd->
+ fmt->metadata_handler(lc,
+ GET_REBUILD_DRIVE_NO,
+ &info,
+ (void *) sub_rs)) {
+ LOG_ERR(lc, 0,
+ "can't get rebuild drive !");
+ }
+ }
}
+
+ if (info.data.i32 != -1) {
+ struct raid_dev *before_rd, *tmp_rd;
+ int idx = 0;
+ list_for_each_entry_safe(before_rd, tmp_rd,
+ &sub_rs->devs, devs) {
+ if ((idx == info.data.i32)
+ && (&rd->devs != &before_rd->devs)) {
+ list_del(&rd->devs)
+ list_add_tail(&rd->devs,
+ &before_rd->devs);
+ break;
+ }
+ idx++;
+ }
+ }
+ show_raid_stack(lc);
+ log_dbg(lc, "RM: REBUILD drivie #: \"%d\"", info.data);
+ show_raid_stack(lc);
}
/* Reconfigure device mapper */
// FIXME: is nosync enough? rs->status |= s_inconsistent;
- rs->status |= s_nosync;
+ rs->status = s_ok;
+ if ((sub_rs = find_set(lc, NULL, vol_name, FIND_ALL))) {
+ sub_rs->status = s_ok;
+
+ list_for_each_entry(crs, &sub_rs->sets, list)
+ crs->status = s_ok;
+ }
+
change_set(lc, A_ACTIVATE, rs);
+ rs->status |= s_nosync;
+
+ if ((sub_rs = find_set(lc, NULL, vol_name, FIND_ALL))) {
+ sub_rs->status |= s_nosync;
+ list_for_each_entry(crs, &sub_rs->sets, list) {
+ crs->status |= s_nosync;
+ }
+ }
+
ret = change_set(lc, A_RELOAD, rs);
// FIXME: might need this later: change_set(lc, A_DEACTIVATE,rs);
if (!ret)
goto err;
+ if (!dso) {
+#ifdef DMRAID_LED
+ struct raid_dev *_rd;
+ list_for_each_entry(_rd, &sub_rs->devs, devs)
+ led(strrchr(_rd->di->path, '/') + 1, LED_REBUILD);
+#endif
+
+ if (check_rd->fmt->metadata_handler)
+ check_rd->fmt->metadata_handler(lc,
+ UPDATE_REBUILD_STATE,
+ NULL, (void *) rs);
+ }
+
/* End transaction */
end_log(lc, &log);
return 0;
-err:
+ err:
revert_log(lc, &log);
return ret;
}
+struct dev_info *find_disk(struct lib_context *lc, char *dp);
+
+/* check if disk is under a raid set */
+int
+check_busy_disk(struct lib_context *lc, struct raid_dev *check_rd)
+{
+ struct raid_dev *rd;
+
+ if (!check_rd)
+ return 0;
+
+ if (!check_rd->di)
+ return 0;
+
+ list_for_each_entry(rd, LC_RD(lc), list) {
+ if (rd->di == check_rd->di)
+ return 0;
+ }
+
+ return 1;
+}
+
+int
+add_dev_to_array(struct lib_context *lc, struct raid_set *rs,
+ uint build_metadata, struct raid_dev *hot_spare_rd)
+{
+ const char *set_name = lc->options[LC_REBUILD_SET].arg.str;
+ struct raid_dev *rd = NULL;
+ struct raid_set *sub_rs;
+
+ if ((hot_spare_rd) || (build_metadata)) {
+ struct raid_dev tmp_rd;
+ struct raid_dev *new_rd = hot_spare_rd;
+ enum type type = t_raid1;
+
+ sub_rs = find_set(lc, NULL, set_name, FIND_ALL);
+ if (sub_rs == NULL) {
+ log_print(lc, "Volume \"%s\" not found\n", set_name);
+ return 1;
+ }
+
+
+ type = sub_rs->type;
+
+ if (new_rd == NULL) {
+ const char *disk_name =
+ lc->options[LC_REBUILD_DISK].arg.str;
+
+ new_rd = &tmp_rd;
+ /* for non-hot-spare */
+ if (!(new_rd->di = find_disk(lc, (char *) disk_name)))
+ LOG_ERR(lc, 0, "failed to find disk %s",
+ disk_name);
+
+ /* check if disk is a member of another raid set */
+ if (!(check_busy_disk(lc, new_rd)))
+ LOG_ERR(lc, 0,
+ "disk %s cannot be used to rebuilding",
+ disk_name);
+
+ new_rd->fmt = get_format(rs);
+ }
+
+ /* add a rd to group raid set */
+ if ((rd = alloc_raid_dev(lc, "rebuild")) == NULL)
+ LOG_ERR(lc, 1,
+ "failed to allocate space for a raid_dev");
+
+ memset(rd, 0, sizeof(*rd));
+ rd->name = NULL;
+
+ rd->di = new_rd->di;
+ rd->fmt = new_rd->fmt;
+
+ rd->status = s_init;
+ rd->type = type;
+ rd->offset = 0;
+ rd->sectors = 0;
+
+ list_add_tail(&rd->list, LC_RD(lc));
+ list_add_tail(&rd->devs, &rs->devs);
+
+ /* add a spare to raid set */
+ sub_rs = find_set(lc, NULL, set_name, FIND_ALL);
+
+ if (!(rd = alloc_raid_dev(lc, __func__)))
+ LOG_ERR(lc, 1,
+ "failed to allocate space for a raid_dev");
+
+ rd->name = NULL;
+ rd->di = new_rd->di;
+ rd->fmt = new_rd->fmt;
+ rd->status = s_init;
+ rd->type = type;
+ rd->offset = 0;
+ rd->sectors = 0;
+ list_add_tail(&rd->devs, &sub_rs->devs);
+ sub_rs->total_devs++;
+ }
+
+ add_dev_to_raid(lc, rs, rd);
+ return 0;
+}
+
/* Remove a disk from a raid1 */
-static int del_dev_in_raid1(struct lib_context *lc, struct raid_set *rs,
- struct raid_dev *rd)
+static int
+del_dev_in_raid1(struct lib_context *lc, struct raid_set *rs,
+ struct raid_dev *rd)
{
int ret;
struct raid_dev *tmp;
struct change *entry;
- LIST_HEAD(log); /* Playback log */
+ LIST_HEAD(log); /* Playback log */
/* Remove device from the raid set */
- ret = alloc_entry(&entry);
+ ret = alloc_entry(&entry, lc);
if (ret)
goto err;
@@ -129,7 +370,7 @@
}
/* Write the metadata of the drive we're removing _first_ */
- ret = alloc_entry(&entry);
+ ret = alloc_entry(&entry, lc);
if (ret)
goto err;
@@ -145,7 +386,7 @@
if (tmp == rd)
continue;
- ret = alloc_entry(&entry);
+ ret = alloc_entry(&entry, lc);
if (ret)
goto err;
@@ -168,7 +409,7 @@
end_log(lc, &log);
return 0;
-err:
+ err:
revert_log(lc, &log);
return ret;
}
@@ -176,13 +417,14 @@
/* Corelate type and function to handle addition/removel of RAID device */
struct handler {
enum change_type type;
- int (*func) (struct lib_context *lc, struct raid_set *rs,
- struct raid_dev *rd);
+ int (*func) (struct lib_context * lc, struct raid_set * rs,
+ struct raid_dev * rd);
};
/* Call the function to handle addition/removal of a RAID device */
-static int handle_dev(struct lib_context *lc, struct handler *h,
- struct raid_set *rs, struct raid_dev *rd)
+static int
+handle_dev(struct lib_context *lc, struct handler *h,
+ struct raid_set *rs, struct raid_dev *rd)
{
do {
if (h->type == rs->type)
@@ -193,11 +435,11 @@
}
/* Add a disk to an array. */
-int add_dev_to_set(struct lib_context *lc, struct raid_set *rs,
- struct raid_dev *rd)
+int
+add_dev_to_set(struct lib_context *lc, struct raid_set *rs, struct raid_dev *rd)
{
struct handler handlers[] = {
- {t_raid1, add_dev_to_raid1},
+ {t_raid1, add_dev_to_raid},
{t_undef, NULL},
};
@@ -216,8 +458,8 @@
}
/* Remove a disk from an array */
-int del_dev_in_set(struct lib_context *lc, struct raid_set *rs,
- struct raid_dev *rd)
+int
+del_dev_in_set(struct lib_context *lc, struct raid_set *rs, struct raid_dev *rd)
{
struct handler handlers[] = {
{t_raid1, del_dev_in_raid1},
@@ -235,3 +477,323 @@
return handle_dev(lc, handlers, rs, rd);
}
+
+/*
+ * Find group of raid_set to which sub_rs belongs
+ * Serves one level stacked raids.
+ */
+struct raid_set *
+find_group(struct lib_context *lc, struct raid_set *sub_rs)
+{
+ struct raid_set *tmp = NULL, *r = NULL, *r2 = NULL;
+
+ list_for_each_entry(tmp, LC_RS(lc), list) {
+ if (T_GROUP(tmp)) {
+ list_for_each_entry(r, &tmp->sets, list) {
+ if (r == sub_rs)
+ return tmp;
+ else if (SETS(r)) {
+ list_for_each_entry(r2, &r->sets, list) {
+ if (r2 == sub_rs)
+ return tmp;
+ }
+ }
+ }
+ }
+ }
+
+ /* Group not found. */
+ return NULL;
+}
+
+struct raid_dev *find_spare(struct lib_context *lc, struct raid_set *sub_rs,
+ struct raid_set **spare_set);
+
+int
+_rebuild_raidset(struct lib_context *lc, struct raid_set *sub_rs,
+ char *set_name)
+{
+ struct raid_set *spare_set = NULL, *rs = NULL;
+ struct raid_dev *rd = NULL;
+ int driveRebuild = 1;
+
+ rs = find_group(lc, sub_rs);
+
+ /* raid 0 cannot be rebuild - exit */
+ if (T_RAID0(sub_rs) && (!SETS(sub_rs))) {
+ log_print(lc, "Rebuild: raid0 cannot be rebuild\n");
+ return 1;
+ }
+ /* FIXME - work-aroud for status reporting */
+ if (S_BROKEN(sub_rs->status) ||
+ S_INCONSISTENT(sub_rs->status)) {
+ if (lc->options[LC_REBUILD_DISK].opt == 0) {
+ /* find the spare drive */
+ if ((rd = find_spare(lc, sub_rs, &spare_set)) == NULL) {
+ log_print(lc,
+ "Rebuild: a hot-spare drive not found for a volume: \"%s\"."
+ " Need a drive to rebuild a volume.\n",
+ sub_rs->name);
+ return 1;
+ }
+
+ }
+ } else if (S_OK(sub_rs->status)) {
+ struct raid_dev *check_rd = RD_RS(sub_rs);
+ enum status state = s_ok;
+
+ if (check_rd && (check_rd->fmt->metadata_handler))
+ state = check_rd->fmt->metadata_handler(lc,
+ GET_REBUILD_STATE,
+ NULL, (void *)
+ sub_rs);
+
+ if (state != s_nosync) {
+ /* cannot rebuild */
+ log_print(lc,
+ "Volume \"%s\" is not in rebuild state (current: %u)",
+ sub_rs->name, state);
+ log_print(lc,
+ "Rebuild: cannot rebuild from current state!\n");
+ return 1;
+ }
+ driveRebuild = 0;
+ } else if (!(S_NOSYNC(sub_rs->status))) {
+ /* cannot rebuild */
+ log_print(lc, "Rebuild: cannot rebuild from current state!\n");
+ return 1;
+ }
+
+
+ sub_rs->status = s_nosync;
+ rs->status = s_nosync;
+
+ /* set the name for rebuild set (function down the path are using this variable to
+ * retrive the raid set that is rebuild
+ */
+
+
+ dbg_free((char *) lc->options[LC_REBUILD_SET].arg.str);
+ lc->options[LC_REBUILD_SET].arg.str =
+ (const char *) dbg_malloc(strlen(sub_rs->name) + 1);
+ strcpy((char *) lc->options[LC_REBUILD_SET].arg.str, sub_rs->name);
+
+ if (!(add_dev_to_array(lc, rs,
+ (driveRebuild
+ && lc->options[LC_REBUILD_DISK].opt)
+ || rd, rd))) {
+ log_dbg(lc, "rebuild: raid \"%s\" rebuild finished\n",
+ set_name);
+ } else {
+ /* error - raid failed to be rebuilded */
+ log_print(lc, "Rebuild: raid \"%s\" rebuild failed\n",
+ set_name);
+ return 1;
+ }
+ return 0;
+}
+
+
+int
+rebuild_raidset(struct lib_context *lc, char *set_name)
+{
+ struct raid_set *sub_rs = NULL;
+ int ret = 0;
+
+ sub_rs = find_set(lc, NULL, set_name, FIND_ALL);
+ if (sub_rs) {
+ /* for stacked subsets go throu the stack to retrive the subsets that:
+ - do not contain subsets
+ - are eligible for rebuild
+ */
+ if (SETS(sub_rs)) {
+ enum status curr_state = s_ok;
+ struct raid_set *r = NULL;
+
+ /* check sub-set that are in Ok state */
+ curr_state = s_ok;
+
+ /* check for all subsets that have state equal curr_state */
+ list_for_each_entry(r, &sub_rs->sets, list) {
+ if (r->status & curr_state) {
+ ret |= _rebuild_raidset(lc, r,
+ set_name);
+ }
+ }
+
+ /* TBD change to s_inconsisten when the states are reported in right way */
+ curr_state = s_broken | s_inconsistent;
+ list_for_each_entry(r, &sub_rs->sets, list) {
+ if (r->status & curr_state) {
+ ret |= _rebuild_raidset(lc, r,
+ set_name);
+ }
+ }
+ } else
+ ret |= _rebuild_raidset(lc, sub_rs, set_name);
+
+ } else
+ log_print(lc, "raid volume \"%s\" not found\n", set_name);
+
+ return ret;
+}
+
+
+int
+write_set_spare(struct lib_context *lc, void *v)
+{
+ int ret = 1;
+ struct raid_set *r, *rs = v;
+ struct raid_dev *rd;
+
+ /* Decend hierarchy */
+ list_for_each_entry(r, &rs->sets, list) {
+ /*
+ * FIXME: does it make sense to try the rest of the subset
+ * in case we fail writing one ?
+ */
+ if (!write_set_spare(lc, (void *) r))
+ log_err(lc, "writing RAID subset \"%s\", continuing",
+ r->name);
+ }
+
+ /* Write metadata to the RAID devices of a set */
+ list_for_each_entry(rd, &rs->devs, devs) {
+ /*
+ * FIXME: does it make sense to try the rest of the
+ * devices in case we fail writing one ?
+ */
+ if (!(T_GROUP(rs))) {
+ if (!write_dev(lc, rd, 0)) {
+ log_err(lc,
+ "writing RAID device \"%s\", continuing",
+ rd->di->path);
+ ret = 0;
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+
+static int
+add_spare_dev_to_raid(struct lib_context *lc, struct raid_set *rs)
+{
+ int ret = 0;
+ struct dmraid_format *fmt_hand;
+
+
+ /* find format handler */
+ fmt_hand = get_format(rs);
+
+ if (!(fmt_hand->create)) {
+ LOG_ERR(lc, 0,
+ "metadata creation is not supported in \"%s\" format",
+ fmt_hand->name);
+ } else {
+ if ((ret = fmt_hand->create(lc, rs)))
+ ret = write_set_spare(lc, rs);
+
+ if (!ret)
+ log_print(lc, "metadata fmt update failed\n");
+ }
+
+ return ret;
+}
+
+int
+add_spare_dev_to_array(struct lib_context *lc, struct raid_set *rs)
+{
+ struct dev_info *di;
+ struct dmraid_format *fmt_hand;
+ struct raid_dev *rd;
+ struct raid_set *rs_sub;
+
+ const char *disk_name = lc->options[LC_REBUILD_DISK].arg.str;
+
+
+ /* find format handler */
+ fmt_hand = get_format(rs);
+
+ /* add a spare rs to raid set */
+ if (!(rs_sub = alloc_raid_set(lc, "rebuild")))
+ return 0;
+
+ rs_sub->name = NULL;
+ rs_sub->size = 0;
+ rs_sub->stride = 0;
+ rs_sub->type = t_spare;
+ rs_sub->flags = 0;
+ rs_sub->status = s_init;
+ list_add_tail(&rs_sub->list, &rs->sets);
+
+ /* Find disk by name. */
+ if (!(di = find_disk(lc, (char *) disk_name)))
+ LOG_ERR(lc, 0, "failed to find disk %s", disk_name);
+
+ /* Add a rd to group raid set. */
+ if ((rd = alloc_raid_dev(lc, "rebuild")) == NULL)
+ LOG_ERR(lc, 0, "failed to allocate space for a raid_dev");
+
+ rd->name = NULL;
+ rd->di = di;
+ rd->fmt = fmt_hand;
+ rd->status = s_init;
+ rd->type = t_spare;
+ rd->offset = 0;
+ rd->sectors = 0;
+
+ /* add dev to lc list and to group rs */
+ list_add_tail(&rd->list, LC_RD(lc));
+ list_add_tail(&rd->devs, &rs->devs);
+
+ if (!(rd = alloc_raid_dev(lc, "rebuild")))
+ LOG_ERR(lc, 0, "failed to allocate space for a raid_dev");
+
+ rd->name = NULL;
+ rd->di = di;
+ rd->fmt = fmt_hand;
+ rd->status = s_init;
+ rd->type = t_spare;
+ rd->offset = 0;
+ rd->sectors = 0;
+ list_add_tail(&rd->devs, &rs_sub->devs);
+ return add_spare_dev_to_raid(lc, rs);
+}
+
+
+/* Add a disk to raid set as spare disk. */
+int
+hot_spare_add(struct lib_context *lc, struct raid_set *rs)
+{
+ const char *vol_name = lc->options[LC_HOT_SPARE_SET].arg.str;
+ int ret_func;
+ struct dmraid_format *fmt_hand;
+
+
+ if (!(!OPT_FORMAT(lc) &&
+ OPT_REBUILD_DISK(lc) &&
+ OPT_HOT_SPARE_SET(lc)))
+ return 0;
+
+ if (!(fmt_hand = get_format(rs)))
+ LOG_ERR(lc, 0, "unknown metadata format");
+
+ if (!(fmt_hand->metadata_handler))
+ LOG_ERR(lc, 0,
+ "metadata_handler() is not supported in \"%s\" format",
+ fmt_hand->name);
+
+ ret_func = fmt_hand->metadata_handler(lc, CHECK_HOT_SPARE, NULL,
+ (void *) rs);
+
+ if (!ret_func)
+ LOG_ERR(lc, 0,
+ "hot-spare cannot be added to existing raid "
+ "set \"%s\" in \"%s\" format",
+ vol_name, fmt_hand->name);
+
+ return add_spare_dev_to_array(lc, rs);
+}
--- dmraid/lib/misc/file.c 2008/02/22 17:04:36 1.2
+++ dmraid/lib/misc/file.c 2008/06/20 21:52:18 1.3
@@ -8,17 +8,18 @@
#include "internal.h"
/* Create directory recusively. */
-static int mk_dir_recursive(struct lib_context *lc, const char *dir)
+static int
+mk_dir_recursive(struct lib_context *lc, const char *dir)
{
int ret = 1;
- char *orig, *s;
+ char *orig, *s;
const char delim = '/';
- if (!(orig = s = dbg_strdup((char*) dir)))
+ if (!(orig = s = dbg_strdup((char *) dir)))
return log_alloc_err(lc, __func__);
- /* Create parent directories */
- log_notice(lc, "creating directory %s", dir);
+ /* Create parent directories */
+ log_notice(lc, "creating directory %s", dir);
do {
s = remove_delimiter(s + 1, delim);
if (mkdir(orig, 0777) && errno != EEXIST) {
@@ -32,11 +33,12 @@
dbg_free(orig);
- return ret;
+ return ret;
}
/* Create directory. */
-int mk_dir(struct lib_context *lc, const char *dir)
+int
+mk_dir(struct lib_context *lc, const char *dir)
{
struct stat info;
@@ -50,18 +52,19 @@
LOG_ERR(lc, 0, "directory %s not found", dir);
}
-static int rw_file(struct lib_context *lc, const char *who, int flags,
- char *path, void *buffer, size_t size, loff_t offset)
+static int
+rw_file(struct lib_context *lc, const char *who, int flags,
+ char *path, void *buffer, size_t size, loff_t offset)
{
int fd, ret = 0;
loff_t o;
struct {
- ssize_t (*func)();
+ ssize_t(*func) ();
const char *what;
} rw_spec[] = {
- { read, "read" },
- { write, "writ" },
- }, *rw = rw_spec + ((flags & O_WRONLY) ? 1 : 0);
+ {
+ read, "read"}, {
+ write, "writ"},}, *rw = rw_spec + ((flags & O_WRONLY) ? 1 : 0);
if ((fd = open(path, flags, lc->mode)) == -1)
LOG_ERR(lc, 0, "opening \"%s\"", path);
@@ -71,7 +74,7 @@
#else
#define DMRAID_LSEEK lseek64
#endif
- if (offset && (o = DMRAID_LSEEK(fd, offset, SEEK_SET)) == (loff_t) -1)
+ if (offset && (o = DMRAID_LSEEK(fd, offset, SEEK_SET)) == (loff_t) - 1)
log_err(lc, "%s: seeking device \"%s\" to %" PRIu64,
who, path, offset);
else if (rw->func(fd, buffer, size) != size)
@@ -85,16 +88,18 @@
return ret;
}
-int read_file(struct lib_context *lc, const char *who, char *path,
- void *buffer, size_t size, loff_t offset)
+int
+read_file(struct lib_context *lc, const char *who, char *path,
+ void *buffer, size_t size, loff_t offset)
{
return rw_file(lc, who, O_RDONLY, path, buffer, size, offset);
}
-int write_file(struct lib_context *lc, const char *who, char *path,
- void *buffer, size_t size, loff_t offset)
+int
+write_file(struct lib_context *lc, const char *who, char *path,
+ void *buffer, size_t size, loff_t offset)
{
/* O_CREAT|O_TRUNC are noops on a devnode. */
- return rw_file(lc, who, O_WRONLY|O_CREAT|O_TRUNC, path,
+ return rw_file(lc, who, O_WRONLY | O_CREAT | O_TRUNC, path,
buffer, size, offset);
}
--- dmraid/lib/misc/init.c 2008/02/22 16:57:36 1.1
+++ dmraid/lib/misc/init.c 2008/06/20 21:52:18 1.2
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
* See file LICENSE at the top of this source tree for license information.
@@ -7,11 +7,16 @@
#include "internal.h"
+extern int dso;
+
/* Library initialization. */
-struct lib_context *libdmraid_init(int argc, char **argv)
+struct lib_context *
+libdmraid_init(int argc, char **argv)
{
struct lib_context *lc;
+ dso = (argv[0] && strcmp(argv[0], "dso")) ? 1 : 0;
+
if ((lc = alloc_lib_context(argv))) {
if (!register_format_handlers(lc)) {
libdmraid_exit(lc);
@@ -25,11 +30,12 @@
}
/* Library exit processing. */
-void libdmraid_exit(struct lib_context *lc)
+void
+libdmraid_exit(struct lib_context *lc)
{
free_raid_set(lc, NULL); /* Free all RAID sets. */
free_raid_dev(lc, NULL); /* Free all RAID devices. */
free_dev_info(lc, NULL); /* Free all disk infos. */
unregister_format_handlers(lc); /* Unregister all format handlers. */
- free_lib_context(lc); /* Release library context. */
+ free_lib_context(lc); /* Release library context. */
}
--- dmraid/lib/misc/lib_context.c 2008/04/02 13:35:32 1.2
+++ dmraid/lib/misc/lib_context.c 2008/06/20 21:52:18 1.3
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
* See file LICENSE at the top of this source tree for license information.
@@ -10,34 +10,39 @@
#include "version.h"
/* Options access functions. */
-static inline int lc_opt_ok(enum lc_options o)
+static inline int
+lc_opt_ok(enum lc_options o)
{
return o < LC_OPTIONS_SIZE;
}
-int lc_opt(struct lib_context *lc, enum lc_options o)
+int
+lc_opt(struct lib_context *lc, enum lc_options o)
{
return lc_opt_ok(o) ? lc->options[o].opt : 0;
}
-static int _inc_opt(struct lib_context *lc, int o)
+static int
+_inc_opt(struct lib_context *lc, int o)
{
- return lc->options[o].opt < UCHAR_MAX ? ++lc->options[o].opt :
- lc->options[o].opt;
+ return lc->options[o].opt < UCHAR_MAX ?
+ ++lc->options[o].opt : lc->options[o].opt;
}
-int lc_inc_opt(struct lib_context *lc, int o)
+int
+lc_inc_opt(struct lib_context *lc, int o)
{
return lc_opt_ok(o) ? _inc_opt(lc, o) : 0;
}
-const char *lc_strcat_opt(struct lib_context *lc, enum lc_options o,
- char *arg, const char delim)
+const char *
+lc_strcat_opt(struct lib_context *lc, enum lc_options o,
+ char *arg, const char delim)
{
char *ret = NULL;
if (lc_opt_ok(o)) {
- char *a = (char*) OPT_STR(lc, o);
+ char *a = (char *) OPT_STR(lc, o);
size_t end = (a ? strlen(a) : 0),
len = end + strlen(arg) + ((delim && end) ? 1 : 0) + 1;
@@ -50,7 +55,7 @@
strcat(ret, arg);
OPT_STR(lc, o) = ret;
} else {
- dbg_free((char*) OPT_STR(lc, o));
+ dbg_free((char *) OPT_STR(lc, o));
OPT_STR(lc, o) = ret;
log_alloc_err(lc, __func__);
}
@@ -59,13 +64,13 @@
return ret;
}
-const char *lc_stralloc_opt(struct lib_context *lc, enum lc_options o,
- char *arg)
+const char *
+lc_stralloc_opt(struct lib_context *lc, enum lc_options o, char *arg)
{
if (lc_opt_ok(o)) {
/* Free any already allocated one. */
if (OPT_STR(lc, o))
- dbg_free((char*) OPT_STR(lc, o));
+ dbg_free((char *) OPT_STR(lc, o));
/* Dup new one. */
if ((OPT_STR(lc, o) = dbg_strdup(arg)))
@@ -77,12 +82,14 @@
return NULL;
}
-const char *lc_opt_arg(struct lib_context *lc, enum lc_options o)
+const char *
+lc_opt_arg(struct lib_context *lc, enum lc_options o)
{
return lc_opt_ok(o) ? lc->options[o].arg.str : NULL;
}
-struct list_head *lc_list(struct lib_context *lc, int l)
+struct list_head *
+lc_list(struct lib_context *lc, int l)
{
return l < ARRAY_SIZE(lc->lists) ? lc->lists + l : NULL;
}
@@ -90,21 +97,24 @@
/*
* Library context initialization functions.
*/
-static void init_options(struct lib_context *lc, void *arg)
+static void
+init_options(struct lib_context *lc, void *arg)
{
lc_inc_opt(lc, LC_SEPARATOR);
- lc->options[LC_SEPARATOR].arg.str = dbg_strdup((char*) ",");
+ lc->options[LC_SEPARATOR].arg.str = dbg_strdup((char *) ",");
lc_inc_opt(lc, LC_PARTCHAR);
- lc->options[LC_PARTCHAR].arg.str = dbg_strdup((char*) "p");
+ lc->options[LC_PARTCHAR].arg.str = dbg_strdup((char *) "p");
}
-static void init_cmd(struct lib_context *lc, void *arg)
+static void
+init_cmd(struct lib_context *lc, void *arg)
{
- lc->cmd = get_basename(lc, ((char**) arg)[0]);
+ lc->cmd = get_basename(lc, ((char **) arg)[0]);
}
-static void init_lists(struct lib_context *lc, void *arg)
+static void
+init_lists(struct lib_context *lc, void *arg)
{
unsigned int i = LC_LISTS_SIZE;
@@ -112,40 +122,44 @@
INIT_LIST_HEAD(lc->lists + i);
}
-static void init_mode(struct lib_context *lc, void *arg)
+static void
+init_mode(struct lib_context *lc, void *arg)
{
lc->mode = 0600;
}
-static void init_paths(struct lib_context *lc, void *arg)
+static void
+init_paths(struct lib_context *lc, void *arg)
{
lc->path.error = "/dev/zero";
}
/* FIXME: add lib flavour info (e.g., DEBUG). */
-static void init_version(struct lib_context *lc, void *arg)
+static void
+init_version(struct lib_context *lc, void *arg)
{
- lc->version.text = DMRAID_LIB_VERSION;
- lc->version.date = DMRAID_LIB_DATE;
- lc->version.v.major = DMRAID_LIB_MAJOR_VERSION;
- lc->version.v.minor = DMRAID_LIB_MINOR_VERSION;
- lc->version.v.sub_minor = DMRAID_LIB_SUBMINOR_VERSION;
- lc->version.v.suffix = DMRAID_LIB_VERSION_SUFFIX;
+ lc->version.text = DMRAID_LIB_VERSION;
+ lc->version.date = DMRAID_LIB_DATE;
+ lc->version.v.major = DMRAID_LIB_MAJOR_VERSION;
+ lc->version.v.minor = DMRAID_LIB_MINOR_VERSION;
+ lc->version.v.sub_minor = DMRAID_LIB_SUBMINOR_VERSION;
+ lc->version.v.suffix = DMRAID_LIB_VERSION_SUFFIX;
}
/* Put init functions into an array because of the potentially growing list. */
struct init_fn {
- void (*func)(struct lib_context *lc, void *arg);
+ void (*func) (struct lib_context * lc, void *arg);
} init_fn[] = {
- { init_options },
- { init_cmd },
- { init_lists },
- { init_mode },
- { init_paths },
- { init_version },
-};
+ {
+ init_options}, {
+ init_cmd}, {
+ init_lists}, {
+ init_mode}, {
+ init_paths}, {
+init_version},};
-struct lib_context *alloc_lib_context(char **argv)
+struct lib_context *
+alloc_lib_context(char **argv)
{
struct lib_context *lc;
struct init_fn *f;
@@ -167,26 +181,29 @@
return lc;
}
-void free_lib_context(struct lib_context *lc)
+void
+free_lib_context(struct lib_context *lc)
{
int o;
for (o = 0; o < LC_OPTIONS_SIZE; o++) {
if (lc->options[o].arg.str)
- dbg_free ((char*) lc->options[o].arg.str);
+ dbg_free((char *) lc->options[o].arg.str);
}
dbg_free(lc);
}
/* Return library date (ASCII). */
-const char *libdmraid_date(struct lib_context *lc)
+const char *
+libdmraid_date(struct lib_context *lc)
{
return lc->version.date;
}
/* Return library version (ASCII). */
-const char *libdmraid_version(struct lib_context *lc)
+const char *
+libdmraid_version(struct lib_context *lc)
{
return lc->version.text;
}
--- dmraid/lib/misc/misc.c 2008/02/22 16:57:36 1.1
+++ dmraid/lib/misc/misc.c 2008/06/20 21:52:18 1.2
@@ -2,6 +2,9 @@
* Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
@@ -9,7 +12,8 @@
#include "internal.h"
/* Prompt for a yes/no answer */
-int yes_no_prompt(struct lib_context *lc, const char *prompt, ...)
+int
+yes_no_prompt(struct lib_context *lc, const char *prompt, ...)
{
int c = '\n';
va_list ap;
@@ -31,7 +35,8 @@
}
/* Return the basename of a path. */
-char *get_basename(struct lib_context *lc, char *str)
+char *
+get_basename(struct lib_context *lc, char *str)
{
char *ret = strrchr(str, '/');
@@ -39,7 +44,8 @@
}
/* Return the dirname of a path. */
-char *get_dirname(struct lib_context *lc, char *str)
+char *
+get_dirname(struct lib_context *lc, char *str)
{
char *ret = strrchr(str, '/');
size_t len = ret ? ret - str : strlen(str);
@@ -51,7 +57,8 @@
}
/* Convert a numeric string to alpha. */
-void mk_alpha(struct lib_context *lc, char *str, size_t len)
+void
+mk_alpha(struct lib_context *lc, char *str, size_t len)
{
for (; len && *str; len--, str++) {
if (isdigit(*str))
@@ -60,7 +67,8 @@
}
/* Remove any whitespace from a string. */
-char *remove_white_space(struct lib_context *lc, char *str, size_t size)
+char *
+remove_white_space(struct lib_context *lc, char *str, size_t size)
{
int c;
char *in = str, *out = str;
@@ -70,24 +78,36 @@
if (!isspace(c))
*out++ = c;
}
- *out = 0;
+ *out = 0;
return str;
}
+/* Remove any whitespace at the tail of a string */
+void
+remove_tail_space(char *str)
+{
+ char *s = str + strlen(str);
+
+ while (s-- > str && isspace(*s))
+ *s = 0;
+}
+
/* Remove/add a delimiter character. */
-char *remove_delimiter(char *ptr, char c)
+char *
+remove_delimiter(char *ptr, char c)
{
char *ret = NULL;
if (ptr && (ret = strchr(ptr, (int) c)))
*ret = 0;
- return ret;
+ return ret;
}
-void add_delimiter(char **ptr, char c)
+void
+add_delimiter(char **ptr, char c)
{
if (ptr && *ptr) {
**ptr = c;
@@ -95,24 +115,38 @@
}
}
+char *
+replace_delimiter(char *str, char delim, char c)
+{
+ char *s = str;
+
+ while ((s = remove_delimiter(s, delim)))
+ add_delimiter(&s, c);
+
+ return str;
+}
+
/* Grow a string. */
-static int grow_string(struct lib_context *lc, char **string, const char *s)
+static int
+grow_string(struct lib_context *lc, char **string, const char *s)
{
size_t len;
char *tmp = *string;
- len = strlen(s) + (tmp ? strlen(tmp) + 1 : 1);
+ len = strlen(s) + (tmp ? strlen(tmp) + 1 : 1);
if ((*string = dbg_realloc(tmp, len))) {
if (!tmp)
**string = '\0';
- } else if (tmp)
+ }
+ else if (tmp)
dbg_free(tmp);
-
+
return *string ? 1 : 0;
}
/* Free a string. */
-void free_string(struct lib_context *lc, char **string)
+void
+free_string(struct lib_context *lc, char **string)
{
if (*string) {
dbg_free(*string);
@@ -121,46 +155,48 @@
}
/* Push a string onto the end of another. */
-static int p_str(struct lib_context *lc, char **string, const char *s)
+static int
+p_str(struct lib_context *lc, char **string, const char *s)
{
int ret;
if ((ret = grow_string(lc, string, s)))
- strcat (*string, s);
+ strcat(*string, s);
return ret;
}
/* Push a string defined by a start and end pointer onto the end of another. */
-static int p_str_str(struct lib_context *lc, char **string,
- char *begin, char *end)
+static int
+p_str_str(struct lib_context *lc, char **string, char *begin, char *end)
{
if (end == begin)
return 1;
*end = 0;
-
return p_str(lc, string, begin);
}
/* Push an uint64_t in ascii onto the end of a string. */
-static int p_u64(struct lib_context *lc, char **string, const uint64_t u)
+static int
+p_u64(struct lib_context *lc, char **string, const uint64_t u)
{
char buffer[22];
sprintf(buffer, "%" PRIu64, u);
-
return p_str(lc, string, buffer);
}
/* Push an uint_t in ascii onto the end of a string. */
-static int p_u(struct lib_context *lc, char **string, const unsigned int u)
+static int
+p_u(struct lib_context *lc, char **string, const unsigned int u)
{
return p_u64(lc, string, (uint64_t) u);
}
/* Push an uint_t in ascii onto the end of a string. */
-static int p_d(struct lib_context *lc, char **string, const int d)
+static int
+p_d(struct lib_context *lc, char **string, const int d)
{
char buffer[12];
@@ -170,12 +206,13 @@
}
/* Push a format string defined list of arguments onto a string. */
-int p_fmt(struct lib_context *lc, char **string, const char *fmt, ...)
+int
+p_fmt(struct lib_context *lc, char **string, const char *fmt, ...)
{
int ret = 1;
char *b, *f, *f_sav;
va_list ap;
-
+
if (!(f = f_sav = dbg_strdup((char *) fmt)))
return 0;
@@ -198,7 +235,7 @@
case 's':
ret = p_str(lc, string, va_arg(ap, char *));
break;
-
+
case 'u':
ret = p_u(lc, string, va_arg(ap, unsigned int));
break;
@@ -222,3 +259,49 @@
return ret;
}
+
+#ifdef DMRAID_LED
+int
+led(const char *path, int status)
+{
+
+#ifdef DMRAID_INTEL_LED
+ FILE *fd;
+ int sgpio = 0;
+ static char com[100];
+
+ /* Check if sgpio app is installed. */
+ if ((fd = popen("which sgpio", "r"))) {
+ sgpio = fscanf(fd, "%s", com);
+ close(fd);
+ }
+
+ if (sgpio != 1) {
+ printf("sgpio app not found\n");
+ return 1;
+ }
+
+ switch (status) {
+ case LED_REBUILD:
+ sprintf(com, "sgpio -d %s -s rebuild", path);
+ break;
+
+ case LED_OFF:
+ sprintf(com, "sgpio -d %s -s off", path);
+ break;
+
+ default:
+ printf("Unknown LED status\n");
+ return 2;
+ }
+
+ if (system(com) == -1) {
+ printf("Call to sgpio app (%s) failed\n", com);
+ return 4;
+ }
+#endif
+
+ return 0;
+
+}
+#endif
--- dmraid/lib/misc/workaround.c 2008/02/22 16:57:36 1.1
+++ dmraid/lib/misc/workaround.c 2008/06/20 21:52:18 1.2
@@ -15,22 +15,23 @@
* populate /sys/block in case of IDE module
* load because of asynchronuous registration !?
*/
-void sysfs_workaround(struct lib_context *lc)
+void
+sysfs_workaround(struct lib_context *lc)
{
int d, fd;
size_t len;
char *dev;
if (!(dev = dbg_malloc(sizeof(_PATH_DEV) + 4)))
- LOG_ERR(lc, , "sysfs workaround");
+ LOG_ERR(lc,, "sysfs workaround");
sprintf(dev, "%shd?", _PATH_DEV);
for (len = strlen(dev) - 1, d = 'a'; d <= 'z'; d++) {
dev[len] = (char) d;
if (!removable_device(lc, dev) &&
- (fd = open (dev, O_RDONLY)) != -1)
- close (fd);
+ (fd = open(dev, O_RDONLY)) != -1)
+ close(fd);
}
dbg_free(dev);
--- dmraid/lib/mm/dbg_malloc.c 2008/02/22 16:57:37 1.1
+++ dmraid/lib/mm/dbg_malloc.c 2008/06/20 21:52:18 1.2
@@ -12,7 +12,8 @@
#include "dbg_malloc.h"
#include "log/log.h"
-static void *__dbg_malloc(size_t size, int init)
+static void *
+__dbg_malloc(size_t size, int init)
{
void *ret = malloc(size);
@@ -24,31 +25,34 @@
#ifdef DEBUG_MALLOC
-void *_dbg_malloc(size_t size, struct lib_context *lc,
- const char *who, unsigned int line)
+void *
+_dbg_malloc(size_t size, struct lib_context *lc,
+ const char *who, unsigned int line)
{
void *ret = __dbg_malloc(size, 1);
log_dbg(lc, "%s: dbg_malloc(%zu) at line %u returned 0x%x",
- (char*) who, size, line, (unsigned long) ret);
+ (char *) who, size, line, (unsigned long) ret);
return ret;
}
-void *_dbg_realloc(void *ptr, size_t size, struct lib_context *lc,
- const char *who, unsigned int line)
+void *
+_dbg_realloc(void *ptr, size_t size, struct lib_context *lc,
+ const char *who, unsigned int line)
{
void *ret = realloc(ptr, size);
log_dbg(lc, "%s: dbg_realloc(0x%x, %zu) at line %u returned 0x%x",
- (char*) who, (unsigned long) ptr, size, line,
+ (char *) who, (unsigned long) ptr, size, line,
(unsigned long) ret);
return ret;
}
-void *_dbg_strndup(void *ptr, size_t len, struct lib_context *lc,
- const char *who, unsigned int line)
+void *
+_dbg_strndup(void *ptr, size_t len, struct lib_context *lc,
+ const char *who, unsigned int line)
{
char *ret;
@@ -58,40 +62,44 @@
}
log_dbg(lc, "%s: dbg_strndup(0x%x) at line %u returned 0x%x",
- (char*) who, (unsigned long) ptr, line, (unsigned long) ret);
+ (char *) who, (unsigned long) ptr, line, (unsigned long) ret);
return ret;
}
-void *_dbg_strdup(void *ptr, struct lib_context *lc,
- const char *who, unsigned int line)
+void *
+_dbg_strdup(void *ptr, struct lib_context *lc,
+ const char *who, unsigned int line)
{
return _dbg_strndup(ptr, strlen(ptr), lc, who, line);
}
-void _dbg_free(void *ptr, struct lib_context *lc,
- const char *who, unsigned int line)
+void
+_dbg_free(void *ptr, struct lib_context *lc, const char *who, unsigned int line)
{
log_dbg(lc, "%s: dbg_free(0x%x) at line %u",
- (char*) who, (unsigned long) ptr, line);
+ (char *) who, (unsigned long) ptr, line);
free(ptr);
}
#else
-void *_dbg_malloc(size_t size)
+void *
+_dbg_malloc(size_t size)
{
return __dbg_malloc(size, 1);
}
-void *_dbg_realloc(void *ptr, size_t size)
+void *
+_dbg_realloc(void *ptr, size_t size)
{
return realloc(ptr, size);
}
-void *_dbg_strndup(void *ptr, size_t len)
+void *
+_dbg_strndup(void *ptr, size_t len)
{
char *ret;
@@ -103,12 +111,14 @@
return ret;
}
-void *_dbg_strdup(void *ptr)
+void *
+_dbg_strdup(void *ptr)
{
return _dbg_strndup(ptr, strlen(ptr));
}
-void _dbg_free(void *ptr)
+void
+_dbg_free(void *ptr)
{
free(ptr);
}
--- dmraid/man/dmraid.8 2008/04/02 13:35:32 1.2
+++ dmraid/man/dmraid.8 2008/06/20 21:52:18 1.3
@@ -1,420 +1,533 @@
-.TH DMRAID 8 "DMRAID TOOL" "Heinz Mauelshagen" \" -*- nroff -*-
-.SH NAME
-dmraid \- discover and activate software (ATA)RAID
-.SH SYNOPSIS
-.B dmraid
- {-a|--activate} {y|n|yes|no}
- [-d|--debug]... [-v|--verbose]... [-i|--ignorelocking]
- [-f|--format FORMAT[,FORMAT...]]
- [{-P|--partchar} CHAR]
- [-p|--no_partitions]
- [--separator SEPARATOR]
- [-t|--test]
- [RAID-set...]
-
-.B dmraid
- {-b|--block_devices}
- [-c|--display_columns][FIELD[,FIELD...]]...
- [-d|--debug]... [-v|--verbose]...
- [--separator SEPARATOR]
- [device-path...]
-
-.B dmraid
- {-h|--help}
-
-.B dmraid
- {-l|--list_formats}
- [-d|--debug]... [-v|--verbose]...
-
-.B dmraid
- {-n|--native_log}
- [-d|--debug]... [-v|--verbose]... [-i|--ignorelocking]
- [-f|--format FORMAT[,FORMAT...]]
- [--separator SEPARATOR]
- [device-path...]
-
-.B dmraid
- {-r|--raid_devices}
- [-c|--display_columns][FIELD[,FIELD...]]...
- [-d|--debug]... [-v|--verbose]... [-i|--ignorelocking]
- [-D|--dump_metadata]
- [-f|--format FORMAT[,FORMAT...]]
- [--separator SEPARATOR]
- [device-path...]
-
-.B dmraid
- {-r|--raid_devices}
- [-d|--debug]... [-v|--verbose]... [-i|--ignorelocking]
- [-E|--erase_metadata]
- [-f|--format FORMAT[,FORMAT...]]
- [--separator SEPARATOR]
- [device-path...]
-
-.B dmraid
- {-s|--sets}...[a|i|active|inactive]
- [-c|--display_columns][FIELD[,FIELD...]]...
- [-d|--debug]... [-v|--verbose]... [-i|--ignorelocking]
- [-f|--format FORMAT[,FORMAT...]]
- [-g|--display_group]
- [--separator SEPARATOR]
- [RAID-set...]
-
-.B dmraid
- {-V/--version}
-
-.SH DESCRIPTION
-dmraid discovers block and software RAID devices (eg, ATARAID)
-by using multiple different metadata format handlers which
-support various formats (eg, Highpoint 37x series).
-It offers activating RAID sets made up by 2 or more
-discovered RAID devices, display properties of devices and sets (see option
-.B -l
-for supported metadata formats).
-Block device access to activated RAID sets occurs via device-mapper nodes
-/dev/mapper/RaidSetName.
-RaidSetName starts with the format name (see
-.B -l
-option) which can be used to access all RAID sets of a specific format
-easily with certain options (eg,
-.B -a
-below).
-
-.SS OPTIONS
-.TP
-.I \-a, \-\-activate {y|n} [RAID set...]
-Activates or deactivates all or particular software RAID set.
-In case metadata format handlers are chosen with
-.B -f
-, only RAID sets with such format(s) can be activated or deactivated.
-Useful if devices have multiple metadata signatures.
-When activating RAID sets,
-.B -p
-disables the activation of partitions on them.
-RAID set names given on command line don't need to be fully specified
-(eg, "dmraid -ay sil" would activate all discovered Silicon Image Medley
-RAID sets).
-
-.TP
-.I {-b|--block_devices} [device-path...]
-List all or particular discovered block devices with their
-properties (size, serial number).
-Add
-.B -c
-to display block device names only and
-.B -cc
-for CSV column output of block device properties.
-See description of
-.B -c
-below for FIELD identifiers.
-
-.TP
-.I [-d|--debug]...
-Enable debugging output. Opion can be given multiple times
-increasing the debug output level.
-
-.TP
-.I [-c|--display_columns][FIELD[,FIELD...]]...
-Display properties of block devices, RAID sets and devices in column(s).
-Optional list specifying which FIELDs to display.
-.br
-For
-.B -b:
-.br
-d[evpath]|p[ath], sec[tors]|si[ze], ser[ialnumber].
-.br
-For
-.B -r:
-.br
-de[vpath]|p[ath], f[ormat], r[aidname], t[ype], st[atus], se[ctors]|si[ze], da[taoffset]|o[ffset].
-.br
-For
-.B -s:
-.br
-f[ormat], r[aidname], t[ype], sta[tus], str[ide], se[ctors]|si[ze], su[bsets], d[evices], sp[ares].
-.br
-.TP
-.I [-f|--format FORMAT[,FORMAT...]]
-Use metadata format handler(s) to discover RAID devices.
-See
-.B -l
-for a list of supported format handler names. This is useful to
-select particular formats in case multiple metadata signatures are found
-on a device. A comma seperated list of format names can be specified which
-may not contain white space.
-
-.TP
-.I {-h|--help}
-Display help text.
-
-.TP
-.I {-i|--ignorelocking}
-Don't take out any locks. Useful in early boot where no read/write
-access to /var is available.
-
-.TP
-.I {-l|--list_formats}
-List all available metadata format handlers with their names and
-descriptions. Supported RAID levels are listed in parenthesis:
-.br
-
-S: Span (concatination)
-.br
-0: RAID0 (stripe)
-.br
-1: RAID1 (mirror)
-.br
-10: RAID10 (mirror on top of stripes)
-.br
-01: RAID10 (stripe on top of mirrors)
-
-.TP
-.I {-n|--native_log} [device-path...]
-Display metadata in native, vendor-specific format.
-In case a metadata format handler is chosen with
-.B -f
-only RAID devices with such format will be displayed in native format.
-If device-path(s) is/are given on the command line, native metadata output
-is restricted to those listed.
-
-.TP
-.I [{-P|--partchar} CHAR]
-Use CHAR as the separator between the device name and the partition number.
-
-.TP
-.I {-r|--raid_devices} [device-path...]
-List all discovered RAID devices with format, RAID level, sectors used
-and data offset into the device.
-In case a metadata format handler is chosen with
-.B -f
-, only RAID devices with such format can be discovered. Useful if devices
-have multiple metadata signatures.
-If
-.B -D
-is added to
-.B -r
-the RAID metadata gets dumped into a subdirectory named dmraid.format_name
-(eg. format_name = isw) in files named devicename.dat.
-The byte offset where the metadata is located on the device is written
-into files named devicename.offset and the size of the device in sectors
-into files named devicename.size.
-
-If
-.B -E
-is added to
-.B -r
-the RAID metadata on the devices gets conditionally erased.
-Useful to erase old metadata after new one of different type has been
-stored on a device in order to avoid discovering both. If you enter
-.B -E
-option
-.B -D
-will be enforced in order to have a fallback in case the wrong metadata
-got erased.
-Manual copying back onto the device is needed to recover from erasing
-the wrong metadata using the dumped files devicename_formatname.dat
-and devicename_formatname.offset.
-Eg, to restore all *.dat files in the working directory to the respective devices:
-
-.br
-for f in *.dat
-.br
-do
-.br
- dd if=$f of=/dev/${f%%.dat} \\
-.br
- seek=`cat ${f%%dat}offset` bs=1
-.br
-done
-.br
-
-If device-path(s) is/are given on the command line, the above actions
-are restricted to those listed.
-Add
-.B -c
-to display RAID device names only and
-.B -cc
-for CSV column output of RAID device properties.
-See description of
-.B -c
-above for FIELD identifiers.
-
-.TP
-.I --separator SEPARATOR
-Use SEPARATOR as a delimiter for all options taking or displaying lists.
-
-.TP
-.I -s... [a|i] [RAID-set...]
-Display properties of RAID sets. Multiple RAID set names can be given
-on the command line which don't need to be fully specified (eg, "dmraid -s hpt"
-would display all discovered Highpoint RAID sets). Enter
-.B -s
-twice to display RAID subsets too.
-Add
-.B -c
-to display names of RAID sets only,
-.B -cc
-for CSV column output of RAID set properties and
-.B -ccc
-for inclusion of block devices in the listing. Doesn't imply
-.B -s -s
-to show RAID subsets (implied for group sets, e.g. isw).
-Add
-.B -g
-to include information about group RAID sets (as with Intel Software
-RAID) in the listing.
-See description of
-.B -c
-above for FIELD identifiers.
-
-.TP
-.I [-v|--verbose]...
-Enable verbose runtime information output. Opion can be given multiple times
-increasing the verbosity level.
-
-.SH EXAMPLES
-"dmraid -l" lists all supported metadata formats with their names along with
-some descriptive information, eg:
-.br
-hpt37x : (+) Highpoint HPT37X
-.br
-hpt45x : (+) Highpoint HPT45X
-.br
-isw : (+) Intel Software RAID
-.br
-lsi : (0) LSI Logic MegaRAID
-.br
-nvidia : (+) NVidia RAID
-.br
-pdc : (+) Promise FastTrack
-.br
-sil : (+) Silicon Image(tm) Medley(tm)
-.br
-via : (+) VIA Software RAID
-.br
-dos : (+) DOS partitions on SW RAIDs
-.br
-(0): Discover, (+): Discover+Activate
-
-"dmraid -ay" activates all software RAID sets discovered.
-
-"dmraid -an" deactivates all active software RAID sets which are not open
-(eg, mounted filesystem on them).
-
-"dmraid -ay -f pdc" (pdc looked up from "dmraid -l") activates all
-software RAID sets with Promise format discovered and ignores all other
-supported formats.
-
-"dmraid -r" discovers all software RAID devices supported on your system, eg:
-.br
-/dev/dm-46: hpt45x, "hpt45x_chidjhaiaa-0", striped, ok, 320172928 sectors, data@ 0
-.br
-/dev/dm-50: hpt45x, "hpt45x_chidjhaiaa-0", striped, ok, 320172928 sectors, data@ 0
-.br
-/dev/dm-54: hpt45x, "hpt45x_chidjhaiaa-1", striped, ok, 320172928 sectors, data@ 0
-.br
-/dev/dm-58: hpt45x, "hpt45x_chidjhaiaa-1", striped, ok, 320172928 sectors, data@ 0
-
-
-"dmraid -s -s hpt45x_chidjhaiaa" displays properties of
-set "hpt45x_chidjhaiaa", eg:
-.br
-*** Superset
-.br
-name : hpt45x_chidjhaiaa
-.br
-size : 640345856
-.br
-stride : 128
-.br
-type : raid10
-.br
-status : ok
-.br
-subsets: 2
-.br
-dev : 4
-.br
-spare : 0
-.br
----> Subset
-.br
-name : hpt45x_chidjhaiaa-0
-.br
-size : 640345856
-.br
-stride : 128
-.br
-type : stripe
-.br
-status : ok
-.br
-subsets: 0
-.br
-dev : 2
-.br
-spare : 0
-.br
----> Subset
-.br
-name : hpt45x_chidjhaiaa-1
-.br
-size : 640345856
-.br
-stride : 128
-.br
-type : stripe
-.br
-status : ok
-.br
-subsets: 0
-.br
-dev : 2
-.br
-spare : 0
-.br
-
-"dmraid -s -ccs hpt45" displays properties in column format of all sets
-and subsets with hpt45* format, eg:
-.br
-hpt45x_chidjhaiaa,640345856,128,raid10,ok,4,0
-.br
-hpt45x_chidjhaiaa-a,640345856,128,stripe,ok,2,0
-.br
-hpt45x_chidjhaiaa-b,640345856,128,stripe,ok,2,0
-
-"dmraid -r --sep : -cpath:size" display paths and sizes in sectors for
-RAID devices in column format using ':' as a delimiter, eg:
-.br
-/dev/dm-8:320173055
-.br
-/dev/dm-12:320173055
-.br
-/dev/dm-22:320173055
-.br
-/dev/dm-26:320173055
-.br
-/dev/dm-30:586114703
-.br
-/dev/dm-34:586114703
-.br
-/dev/dm-38:586114703
-.br
-/dev/dm-42:586114703
-.br
-/dev/dm-46:156301487
-.br
-/dev/dm-50:156301487
-.br
-/dev/dm-54:390624896
-.br
-/dev/dm-58:390624896
-.br
-/dev/dm-62:390624896
-.br
-/dev/dm-66:390624896
-
-.SH DIAGNOSTICS
-dmraid returns an exit code of 0 for success or 1 for error.
-
-.SH AUTHOR
-Heinz Mauelshagen <Mauelshagen at RedHat.com>
+.TH DMRAID 8 "DMRAID TOOL" "Heinz Mauelshagen" \" -*- nroff -*-
+.SH NAME
+dmraid \- discover, configure and activate software (ATA)RAID
+.SH SYNOPSIS
+.B dmraid
+ {-a|--activate} {y|n|yes|no}
+ [-d|--debug]... [-v|--verbose]... [-i|--ignorelocking]
+ [-f|--format FORMAT[,FORMAT...]]
+ [{-P|--partchar} CHAR]
+ [-p|--no_partitions]
+ [--separator SEPARATOR]
+ [-t|--test]
+ [RAID-set...]
+
+.B dmraid
+ {-b|--block_devices}
+ [-c|--display_columns][FIELD[,FIELD...]]...
+ [-d|--debug]... [-v|--verbose]...
+ [--separator SEPARATOR]
+ [device-path...]
+
+.B dmraid
+ {-h|--help}
+
+.B dmraid
+ {-l|--list_formats}
+ [-d|--debug]... [-v|--verbose]...
+
+.B dmraid
+ {-n|--native_log}
+ [-d|--debug]... [-v|--verbose]... [-i|--ignorelocking]
+ [-f|--format FORMAT[,FORMAT...]]
+ [--separator SEPARATOR]
+ [device-path...]
+
+.B dmraid
+ {-R| --rebuild}
+ RAID-set
+ [device-path]
+
+.B dmraid
+ {-x| --remove}
+ [RAID-set]
+
+.B dmraid
+ -f FORMAT-handler
+{-C| --create} set
+ --type raidlevel
+ [--size=setsize --strip stridesize]
+ --disk "device-path, device-path [, device-path ...]"
+
+.B dmraid
+[ -f|--format FORMAT-handler]
+-S|--spare [RAID-set]
+-M|--media "device-path"
+
+.B dmraid
+ {-r|--raid_devices}
+ [-c|--display_columns][FIELD[,FIELD...]]...
+ [-d|--debug]... [-v|--verbose]... [-i|--ignorelocking]
+ [-D|--dump_metadata]
+ [-f|--format FORMAT[,FORMAT...]]
+ [--separator SEPARATOR]
+ [device-path...]
+
+.B dmraid
+ {-r|--raid_devices}
+ [-d|--debug]... [-v|--verbose]... [-i|--ignorelocking]
+ [-E|--erase_metadata]
+ [-f|--format FORMAT[,FORMAT...]]
+ [--separator SEPARATOR]
+ [device-path...]
+
+.B dmraid
+ {-s|--sets}...[a|i|active|inactive]
+ [-c|--display_columns][FIELD[,FIELD...]]...
+ [-d|--debug]... [-v|--verbose]... [-i|--ignorelocking]
+ [-f|--format FORMAT[,FORMAT...]]
+ [-g|--display_group]
+ [--separator SEPARATOR]
+ [RAID-set...]
+
+.B dmraid
+ {-V/--version}
+
+.SH DESCRIPTION
+dmraid discovers block and software RAID devices (eg, ATARAID)
+by using multiple different metadata format handlers which
+support various formats (eg, Highpoint 37x series).
+It offers activating RAID sets made up by 2 or more
+discovered RAID devices, display properties of devices and sets (see option
+.B -l
+for supported metadata formats).
+Block device access to activated RAID sets occurs via device-mapper nodes
+/dev/mapper/RaidSetName.
+RaidSetName starts with the format name (see
+.B -l
+option) which can be used to access all RAID sets of a specific format
+easily with certain options (eg,
+.B -a
+below).
+
+.SS OPTIONS
+.TP
+.I \-a, \-\-activate {y|n} [RAID set...]
+Activates or deactivates all or particular software RAID set.
+In case metadata format handlers are chosen with
+.B -f
+, only RAID sets with such format(s) can be activated or deactivated.
+Useful if devices have multiple metadata signatures.
+When activating RAID sets,
+.B -p
+disables the activation of partitions on them.
+RAID set names given on command line don't need to be fully specified
+(eg, "dmraid -ay sil" would activate all discovered Silicon Image Medley
+RAID sets).
+
+.TP
+.I {-b|--block_devices} [device-path...]
+List all or particular discovered block devices with their
+properties (size, serial number).
+Add
+.B -c
+to display block device names only and
+.B -cc
+for CSV column output of block device properties.
+See description of
+.B -c
+below for FIELD identifiers.
+
+.TP
+.I [-d|--debug]...
+Enable debugging output. Opion can be given multiple times
+increasing the debug output level.
+
+.TP
+.I [-c|--display_columns][FIELD[,FIELD...]]...
+Display properties of block devices, RAID sets and devices in column(s).
+Optional list specifying which FIELDs to display.
+.br
+For
+.B -b:
+.br
+d[evpath]|p[ath], sec[tors]|si[ze], ser[ialnumber].
+.br
+For
+.B -r:
+.br
+de[vpath]|p[ath], f[ormat], r[aidname], t[ype], st[atus], se[ctors]|si[ze], da[taoffset]|o[ffset].
+.br
+For
+.B -s:
+.br
+f[ormat], r[aidname], t[ype], sta[tus], str[ide], se[ctors]|si[ze], su[bsets], d[evices], sp[ares].
+.br
+.TP
+.I [-f|--format FORMAT[,FORMAT...]]
+Use metadata format handler(s) to discover RAID devices.
+See
+.B -l
+for a list of supported format handler names. This is useful to
+select particular formats in case multiple metadata signatures are found
+on a device. A comma seperated list of format names can be specified which
+may not contain white space.
+
+.TP
+.I {-h|--help}
+Display help text.
+
+.TP
+.I {-i|--ignorelocking}
+Don't take out any locks. Useful in early boot where no read/write
+access to /var is available.
+
+.TP
+.I {-l|--list_formats}
+List all available metadata format handlers with their names and
+descriptions. Supported RAID levels are listed in parenthesis:
+.br
+
+S: Span (concatination)
+.br
+0: RAID0 (stripe)
+.br
+1: RAID1 (mirror)
+.br
+10: RAID10 (mirror on top of stripes)
+.br
+01: RAID10 (stripe on top of mirrors) Note: Intel OROM displays this as RAID10
+
+.TP
+.I {-n|--native_log} [device-path...]
+Display metadata in native, vendor-specific format.
+In case a metadata format handler is chosen with
+.B -f
+only RAID devices with such format will be displayed in native format.
+If device-path(s) is/are given on the command line, native metadata output
+is restricted to those listed.
+.TP
+.I [{-P|--partchar} CHAR]
+Use CHAR as the separator between the device name and the partition number.
+.TP
+.I {-R| --rebuild} RAID-set [device-path]
+Rebuild raid array after a drive has failed and a new drive is added.
+For Intel chipset based systems, there are two methods in which a new drive
+is added to the system.
+
+1. Using OROM to identify a new drive
+ During system reboot, enter OROM and mark the new drive as the rebuild drive.
+ After booting to the OS, use the dmraid command to rebuild.
+
+ Example: dmraid -R raid_set
+
+2. Using dmraid to identify a new drive
+ Boot to the OS and use the dmraid command with the new drive as
+the second parameter.
+
+ Example: dmraid -R raid_set /dev/sdc
+
+3. Using hot spare drive
+ Mark a drive as hot spare using the "dmraid -f isw -S" command. Then use the dmraid command to start the rebuild.
+
+ Example: dmraid -R raid_set
+
+.TP
+.I {-x|--remove} [RAID-set]
+Delete one or all existing software RAID devices from the metadata.
+
+.TP
+.I -f FORMAT-handler {-C|--create} --type raidlevel [--size=setsize --strip stripsize] --disk "device-path, device-path [,device-path]"
+Delete one or all existing Configure a software RAID device and store the configuration data in a group of hard drive devices consisting of this array. This command requires the following options:
+
+-f FORMAT-handler
+.br
+ metadata format (see "dmraid -l")
+.br
+--type digit[digit...]
+.br
+ specify the raid level of the software RAID set.
+.br
+ 0: raid0
+.br
+ 1: raid1
+.br
+ 5: raid5
+.br
+ 01: raid01 (isw raid10)
+.br
+--size: [digits[k|K|m|M|g|G][b|B]]
+.br
+ specify the size of the RAID set.The number is an integer followed by [kKmMgG] and/or [bB].
+.br
+ b: byte (default)
+.br
+ B: block (512 bytes)
+.br
+ K or K: on the base of 1024
+.br
+ m or M: on the base of 1024*1024
+.br
+ g or G: on the base of 1024*1024*1024
+.br
+If this option is missing, it's set to the default value pre-configured by the vendor. Note that different vendors may apply different constraints on the granularity of the size or the minimal value.
+.br
+--strip: [digits[k|K|m|M|g|G][b|B]]
+.br
+ specify the strip size of a RAID1, RAID5, and RAID10 RAID set (as above)
+.br
+--disk: device-path[{,| }device-path...]
+.br
+ specify the array of the hard drives, e.g. /dev/sda.
+
+.TP
+.I -f FORMAT-handler -S -M device-path
+.I -S -M device-path
+
+This command adds hot spare support for one or more RAID sets.
+
+1. When used with a format handler, which supports hot spare sets (e.g. isw), a hot spare is marked to be used when rebuilding any RAID set of that format.
+2. When used when specifying a RAID set, the drive is added to that RAID set and will be used only to rebuild that set. Note: If the specified name does not match an existing RAID-set, a set with the new name will be created.
+
+.TP
+.I {-r|--raid_devices} [device-path...]
+List all discovered RAID devices with format, RAID level, sectors used
+and data offset into the device.
+In case a metadata format handler is chosen with
+.B -f
+, only RAID devices with such format can be discovered. Useful if devices
+have multiple metadata signatures.
+If
+.B -D
+is added to
+.B -r
+the RAID metadata gets dumped into a subdirectory named dmraid.format_name
+(eg. format_name = isw) in files named devicename.dat.
+The byte offset where the metadata is located on the device is written
+into files named devicename.offset and the size of the device in sectors
+into files named devicename.size.
+
+If
+.B -E
+is added to
+.B -r
+the RAID metadata on the devices gets conditionally erased.
+Useful to erase old metadata after new one of different type has been
+stored on a device in order to avoid discovering both. If you enter
+.B -E
+option
+.B -D
+will be enforced in order to have a fallback in case the wrong metadata
+got erased.
+Manual copying back onto the device is needed to recover from erasing
+the wrong metadata using the dumped files devicename_formatname.dat
+and devicename_formatname.offset.
+Eg, to restore all *.dat files in the working directory to the respective devices:
+
+.br
+for f in *.dat
+.br
+do
+.br
+ dd if=$f of=/dev/${f%%.dat} \\
+.br
+ seek=`cat ${f%%dat}offset` bs=1
+.br
+done
+.br
+
+If device-path(s) is/are given on the command line, the above actions
+are restricted to those listed.
+Add
+.B -c
+to display RAID device names only and
+.B -cc
+for CSV column output of RAID device properties.
+See description of
+.B -c
+above for FIELD identifiers.
+
+.TP
+.I --separator SEPARATOR
+Use SEPARATOR as a delimiter for all options taking or displaying lists.
+
+.TP
+.I -s... [a|i] [RAID-set...]
+Display properties of RAID sets. Multiple RAID set names can be given
+on the command line which don't need to be fully specified (eg, "dmraid -s hpt"
+would display all discovered Highpoint RAID sets). Enter
+.B -s
+twice to display RAID subsets too.
+Add
+.B -c
+to display names of RAID sets only,
+.B -cc
+for CSV column output of RAID set properties and
+.B -ccc
+for inclusion of block devices in the listing. Doesn't imply
+.B -s -s
+to show RAID subsets (implied for group sets, e.g. isw).
+Add
+.B -g
+to include information about group RAID sets (as with Intel Software
+RAID) in the listing.
+See description of
+.B -c
+above for FIELD identifiers.
+Note: Size is given in sectors (not bytes).
+
+.TP
+.I [-v|--verbose]...
+Enable verbose runtime information output. Opion can be given multiple times
+increasing the verbosity level.
+
+.SH EXAMPLES
+"dmraid -l" lists all supported metadata formats with their names along with
+some descriptive information, eg:
+.br
+hpt37x : (+) Highpoint HPT37X
+.br
+hpt45x : (+) Highpoint HPT45X
+.br
+isw : (+) Intel Software RAID
+.br
+lsi : (0) LSI Logic MegaRAID
+.br
+nvidia : (+) NVidia RAID
+.br
+pdc : (+) Promise FastTrack
+.br
+sil : (+) Silicon Image(tm) Medley(tm)
+.br
+via : (+) VIA Software RAID
+.br
+dos : (+) DOS partitions on SW RAIDs
+.br
+(0): Discover, (+): Discover+Activate
+
+"dmraid -ay" activates all software RAID sets discovered.
+
+"dmraid -an" deactivates all active software RAID sets which are not open
+(eg, mounted filesystem on them).
+
+"dmraid -ay -f pdc" (pdc looked up from "dmraid -l") activates all
+software RAID sets with Promise format discovered and ignores all other
+supported formats.
+
+"dmraid -r" discovers all software RAID devices supported on your system, eg:
+.br
+/dev/dm-46: hpt45x, "hpt45x_chidjhaiaa-0", striped, ok, 320172928 sectors, data@ 0
+.br
+/dev/dm-50: hpt45x, "hpt45x_chidjhaiaa-0", striped, ok, 320172928 sectors, data@ 0
+.br
+/dev/dm-54: hpt45x, "hpt45x_chidjhaiaa-1", striped, ok, 320172928 sectors, data@ 0
+.br
+/dev/dm-58: hpt45x, "hpt45x_chidjhaiaa-1", striped, ok, 320172928 sectors, data@ 0
+
+
+"dmraid -s -s hpt45x_chidjhaiaa" displays properties of
+set "hpt45x_chidjhaiaa", eg:
+.br
+*** Superset
+.br
+name : hpt45x_chidjhaiaa
+.br
+size : 640345856
+.br
+stride : 128
+.br
+type : raid10
+.br
+status : ok
+.br
+subsets: 2
+.br
+dev : 4
+.br
+spare : 0
+.br
+---> Subset
+.br
+name : hpt45x_chidjhaiaa-0
+.br
+size : 640345856
+.br
+stride : 128
+.br
+type : stripe
+.br
+status : ok
+.br
+subsets: 0
+.br
+dev : 2
+.br
+spare : 0
+.br
+---> Subset
+.br
+name : hpt45x_chidjhaiaa-1
+.br
+size : 640345856
+.br
+stride : 128
+.br
+type : stripe
+.br
+status : ok
+.br
+subsets: 0
+.br
+dev : 2
+.br
+spare : 0
+.br
+
+"dmraid -s -ccs hpt45" displays properties in column format of all sets
+and subsets with hpt45* format, eg:
+.br
+hpt45x_chidjhaiaa,640345856,128,raid10,ok,4,0
+.br
+hpt45x_chidjhaiaa-a,640345856,128,stripe,ok,2,0
+.br
+hpt45x_chidjhaiaa-b,640345856,128,stripe,ok,2,0
+
+"dmraid -r --sep : -cpath:size" display paths and sizes in sectors for
+RAID devices in column format using ':' as a delimiter, eg:
+.br
+/dev/dm-8:320173055
+.br
+/dev/dm-12:320173055
+.br
+/dev/dm-22:320173055
+.br
+/dev/dm-26:320173055
+.br
+/dev/dm-30:586114703
+.br
+/dev/dm-34:586114703
+.br
+/dev/dm-38:586114703
+.br
+/dev/dm-42:586114703
+.br
+/dev/dm-46:156301487
+.br
+/dev/dm-50:156301487
+.br
+/dev/dm-54:390624896
+.br
+/dev/dm-58:390624896
+.br
+/dev/dm-62:390624896
+.br
+/dev/dm-66:390624896
+
+"dmraid -f isw -C Raid0 --type 0 --strip 8k --size 20g --disk "/dev/sdb /dev/sdc"" creates an ISW volume with
+a name of "Raid0", 20Gig bytes in total, and 8kilo bytes strip size on two disks.
+
+"dmraid -f isw -C Test0 --type 0 --disk "/dev/sdd /dev/sde"" creates an ISW volume with the default size and strip size.
+
+"dmraid -f isw -C Test10 --type 01 --strip 128B --disk "/dev/sda /dev/sdb /dev/sdc /dev/sdd" creates a stacked
+RAID device, RAID10 (isw format), with a name of "Test10", 128 blocks (512bytes) strip size , and the default volume size on
+4 disks.
+
+"dmraid -f isw -S -M /dev/sde" marks the device /dev/sde as a hot spare for rebuild
+
+"dmraid -R isw_djaggchdde_RAID1 /dev/sde" starts rebuild of the RAID volume on device /dev/sde
+
+.SH DIAGNOSTICS
+dmraid returns an exit code of 0 for success or 1 for error.
+
+.SH AUTHOR
+Heinz Mauelshagen <Mauelshagen at RedHat.com>
--- dmraid/tools/VERSION 2008/04/02 13:35:32 1.5
+++ dmraid/tools/VERSION 2008/06/20 21:52:19 1.6
@@ -1 +1 @@
-1.0.0.rc15 (2008.04.02)
+1.0.0.rc15 (2008-06-20)
--- dmraid/tools/commands.c 2008/04/02 13:35:32 1.2
+++ dmraid/tools/commands.c 2008/06/20 21:52:19 1.3
@@ -1,7 +1,10 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
@@ -21,18 +24,21 @@
/* Action flags */
enum action action = UNDEF;
+int add_dev_to_array(struct lib_context *lc, struct raid_set *rs,
+ uint build_metadata, struct raid_dev *hot_spare_rd);
+
/*
* Command line options.
*/
static char const *short_opts = "a:hipP:"
#ifndef DMRAID_MINI
- "bc::dDEf:gl"
+ "bc::dDEf:glxM:"
#ifdef DMRAID_NATIVE_LOG
- "n"
+ "n"
#endif
- "rs::tv"
+ "rR:s::tv"
#endif
- "V";
+ "VC:S::";
#ifdef HAVE_GETOPTLONG
static struct option long_opts[] = {
@@ -52,16 +58,21 @@
{"ignorelocking", no_argument, NULL, 'i'},
# ifndef DMRAID_MINI
{"list_formats", no_argument, NULL, 'l'},
+ {"media", required_argument, NULL, 'M'},
# ifdef DMRAID_NATIVE_LOG
{"native_log", no_argument, NULL, 'n'},
# endif
{"raid_devices", no_argument, NULL, 'r'},
+ {"rebuild", required_argument, NULL, 'R'},
{"sets", optional_argument, NULL, 's'},
- {"separator", required_argument, NULL, SEPARATOR}, /* long only. */
+ {"remove", no_argument, NULL, 'x'},
+ {"separator", required_argument, NULL, SEPARATOR}, /* long only. */
{"test", no_argument, NULL, 't'},
{"verbose", no_argument, NULL, 'v'},
# endif
{"version", no_argument, NULL, 'V'},
+ {"create", required_argument, NULL, 'C'},
+ {"spare", optional_argument, NULL, 'S'},
{NULL, no_argument, NULL, 0}
};
#endif /* #ifdef HAVE_GETOPTLONG */
@@ -73,8 +84,8 @@
};
/* Check option argument. */
-static int check_optarg(struct lib_context *lc, const char option,
- struct optarg_def *def)
+static int
+check_optarg(struct lib_context *lc, const char option, struct optarg_def *def)
{
size_t len;
struct optarg_def *d;
@@ -91,16 +102,17 @@
}
}
- LOG_ERR(lc, 0, "Invalid option argument for -%c", option);
+ LOG_ERR(lc, 0, "invalid option argument for -%c", option);
}
/* Check activate/deactivate option arguments. */
-static int check_activate(struct lib_context *lc, int arg)
+static int
+check_activate(struct lib_context *lc, int arg)
{
struct optarg_def def[] = {
- { "yes", ACTIVATE },
- { "no", DEACTIVATE },
- { NULL, UNDEF },
+ { "yes", ACTIVATE},
+ { "no", DEACTIVATE},
+ { NULL, UNDEF},
};
return check_optarg(lc, 'a', def);
@@ -108,21 +120,22 @@
#ifndef DMRAID_MINI
/* Check active/inactive option arguments. */
-static int check_active(struct lib_context *lc, int arg)
+static int
+check_active(struct lib_context *lc, int arg)
{
struct optarg_def def[] = {
- { "active", ACTIVE },
- { "inactive", INACTIVE },
- { NULL, UNDEF },
+ { "active", ACTIVE},
+ { "inactive", INACTIVE},
+ { NULL, UNDEF},
};
lc_inc_opt(lc, LC_SETS);
-
return check_optarg(lc, 's', def);
}
/* Check and store option arguments. */
-static int check_identifiers(struct lib_context *lc, int o)
+static int
+check_identifiers(struct lib_context *lc, int o)
{
if (optarg) {
const char delim = *OPT_STR_SEPARATOR(lc);
@@ -135,22 +148,48 @@
}
lc_inc_opt(lc, o);
-
return 1;
}
/* Check and store option argument/output field separator. */
-static int check_separator(struct lib_context *lc, int arg)
+static int
+check_separator(struct lib_context *lc, int arg)
{
if (strlen(optarg) != 1)
- LOG_ERR(lc, 0, "Invalid separator \"%s\"", optarg);
+ LOG_ERR(lc, 0, "invalid separator \"%s\"", optarg);
return lc_stralloc_opt(lc, LC_SEPARATOR, optarg) ? 1 : 0;
}
+
+/* Check create option arguments. */
+static int
+check_create_argument(struct lib_context *lc, int arg)
+{
+ size_t len;
+
+ len = strlen(optarg);
+ if (len < 1)
+ LOG_ERR(lc, 0, "arguments missing");
+
+ if (*optarg == '-')
+ LOG_ERR(lc, 0, "the raid set name is missing");
+
+ lc_inc_opt(lc, arg);
+ return 1;
+}
+
+/* 'Check' spare option argument. */
+static int
+check_spare_argument(struct lib_context *lc, int arg)
+{
+ lc_inc_opt(lc, arg);
+ return 1;
+}
#endif
/* Check and store option for partition separator. */
-static int check_part_separator(struct lib_context *lc, int arg)
+static int
+check_part_separator(struct lib_context *lc, int arg)
{
/* We're not actually checking that it's only one character... if
somebody wants to use more, it shouldn't hurt anything. */
@@ -158,7 +197,8 @@
}
/* Display help information */
-static int help(struct lib_context *lc, int arg)
+static int
+help(struct lib_context *lc, int arg)
{
char *c = lc->cmd;
@@ -169,21 +209,21 @@
"\t[-f|--format FORMAT[,FORMAT...]]\n"
"\t[-P|--partchar CHAR]\n"
"\t[-p|--no_partitions]\n"
- "\t[--separator SEPARATOR]\n"
- "\t[RAID-set...]\n", c);
+ "\t[--separator SEPARATOR]\n" "\t[RAID-set...]\n", c);
log_print(lc, "%s\t{-h|--help}\n", c);
log_print(lc, "%s\t{-V/--version}\n", c);
#else
log_print(lc, "%s: Device-Mapper Software RAID tool\n", c);
- log_print(lc, "* = [-d|--debug]... [-v|--verbose]... [-i|--ignorelocking]\n");
- log_print(lc, "%s\t{-a|--activate} {y|n|yes|no} *\n"
+ log_print(lc,
+ "* = [-d|--debug]... [-v|--verbose]... [-i|--ignorelocking]\n");
+ log_print(lc,
+ "%s\t{-a|--activate} {y|n|yes|no} *\n"
"\t[-f|--format FORMAT[,FORMAT...]]\n"
- "\t[-P|--partchar CHAR]\n"
- "\t[-p|--no_partitions]\n"
- "\t[--separator SEPARATOR]\n"
- "\t[-t|--test]\n"
+ "\t[-P|--partchar CHAR]\n" "\t[-p|--no_partitions]\n"
+ "\t[--separator SEPARATOR]\n" "\t[-t|--test]\n"
"\t[RAID-set...]\n", c);
- log_print(lc, "%s\t{-b|--block_devices} *\n"
+ log_print(lc,
+ "%s\t{-b|--block_devices} *\n"
"\t[-c|--display_columns][FIELD[,FIELD...]]...\n"
"\t[device-path...]\n", c);
log_print(lc, "%s\t{-h|--help}\n", c);
@@ -191,29 +231,34 @@
# ifdef DMRAID_NATIVE_LOG
log_print(lc, "%s\t{-n|--native_log} *\n"
"\t[-f|--format FORMAT[,FORMAT...]]\n"
- "\t[--separator SEPARATOR]\n"
- "\t[device-path...]\n", c);
+ "\t[--separator SEPARATOR]\n" "\t[device-path...]\n", c);
# endif
log_print(lc, "%s\t{-r|--raid_devices} *\n"
"\t[-c|--display_columns][FIELD[,FIELD...]]...\n"
"\t[-D|--dump_metadata]\n"
"\t[-f|--format FORMAT[,FORMAT...]]\n"
- "\t[--separator SEPARATOR]\n"
- "\t[device-path...]\n", c);
+ "\t[--separator SEPARATOR]\n" "\t[device-path...]\n", c);
log_print(lc, "%s\t{-r|--raid_devices} *\n"
"\t{-E|--erase_metadata}\n"
"\t[-f|--format FORMAT[,FORMAT...]]\n"
- "\t[--separator SEPARATOR]\n"
- "\t[device-path...]\n", c);
+ "\t[--separator SEPARATOR]\n" "\t[device-path...]\n", c);
log_print(lc, "%s\t{-s|--sets}...[a|i|active|inactive] *\n"
"\t[-c|--display_columns][FIELD[,FIELD...]]...\n"
"\t[-f|--format FORMAT[,FORMAT...]]\n"
"\t[-g|--display_group]\n"
- "\t[--separator SEPARATOR]\n"
- "\t[RAID-set...]\n", c);
+ "\t[--separator SEPARATOR]\n" "\t[RAID-set...]\n", c);
+ log_print(lc, "%s\t{-f|--format FORMAT}\n \t{-C|--create RAID-set} \n"
+ "\t{--type RAID-level}\n"
+ "\t[--size [0-9]...[kKgG][bB]]\n"
+ "\t[--str[i[de]] [0-9]...[kK][bB]]\n"
+ "\t{--disk[s] \"device-path[, device-path...\"}\n", c);
+ log_print(lc, "%s\t{-x|--remove RAID-set} \n");
+ log_print(lc, "%s\t{-R|--rebuild} RAID-set [drive_name]\n", c);
+ log_print(lc, "%s\t[{-f|--format FORMAT}]\n"
+ "\t{-S|--spare [RAID-set]} \n"
+ "\t{-M|--media \"device-path\"}\n", c);
log_print(lc, "%s\t{-V/--version}\n", c);
#endif
-
return 1;
}
@@ -225,247 +270,316 @@
*/
static struct actions actions[] = {
/* [De]activate option. */
- { 'a',
- UNDEF, /* Set in check_activate() by mandatory option argument. */
- UNDEF,
- ACTIVATE|DEACTIVATE|FORMAT|HELP|IGNORELOCKING|NOPARTITIONS|SEPARATOR
+ {'a',
+ UNDEF, /* Set in check_activate() by mandatory option argument. */
+ UNDEF,
+ ACTIVATE | DEACTIVATE | FORMAT | HELP | IGNORELOCKING | NOPARTITIONS |
+ SEPARATOR
#ifndef DMRAID_MINI
- |DBG|TEST|VERBOSE
+ | DBG | TEST | VERBOSE
#endif
- , ARGS,
- check_activate,
- 0,
- },
+ , ARGS,
+ check_activate,
+ 0,
+ },
/* Format option. */
- { 'f',
- FORMAT,
- ACTIVATE|DEACTIVATE
+ {'f',
+ FORMAT,
+ ACTIVATE | DEACTIVATE
#ifndef DMRAID_MINI
# ifdef DMRAID_NATIVE_LOG
- |NATIVE_LOG
+ | NATIVE_LOG
# endif
- |RAID_DEVICES|RAID_SETS,
- ACTIVE|INACTIVE|COLUMN|DBG|DUMP|ERASE|GROUP|HELP|
- IGNORELOCKING|NOPARTITIONS|SEPARATOR|TEST|VERBOSE
+ | RAID_DEVICES | RAID_SETS,
+ ACTIVE | INACTIVE | COLUMN | DBG | DUMP | DMERASE | GROUP | HELP |
+ IGNORELOCKING | NOPARTITIONS | SEPARATOR | TEST | VERBOSE
#else
- , UNDEF
+ , UNDEF
#endif
- , ARGS,
+ , ARGS,
#ifndef DMRAID_MINI
- check_identifiers,
+ check_identifiers,
#else
- NULL,
+ NULL,
#endif
- LC_FORMAT,
- },
+ LC_FORMAT,
+ },
/* Partition separator. */
- { 'P',
- PARTCHAR,
- ACTIVATE|DEACTIVATE,
- FORMAT|HELP|IGNORELOCKING|SEPARATOR
+ {'P',
+ PARTCHAR,
+ ACTIVATE | DEACTIVATE,
+ FORMAT | HELP | IGNORELOCKING | SEPARATOR
#ifndef DMRAID_MINI
- |DBG|TEST|VERBOSE
+ | DBG | TEST | VERBOSE
#endif
- , ARGS,
- check_part_separator,
- 0,
- },
+ , ARGS,
+ check_part_separator,
+ 0,
+ },
/* Partition option. */
- { 'p',
- NOPARTITIONS,
- ACTIVATE|DEACTIVATE,
- FORMAT|HELP|IGNORELOCKING|SEPARATOR
+ {'p',
+ NOPARTITIONS,
+ ACTIVATE | DEACTIVATE,
+ FORMAT | HELP | IGNORELOCKING | SEPARATOR
#ifndef DMRAID_MINI
- |DBG|TEST|VERBOSE
+ | DBG | TEST | VERBOSE
#endif
- , ARGS,
- NULL,
- 0,
- },
+ , ARGS,
+ NULL,
+ 0,
+ },
#ifndef DMRAID_MINI
/* Block devices option. */
- { 'b',
- BLOCK_DEVICES,
- UNDEF,
- COLUMN|DBG|HELP|IGNORELOCKING|SEPARATOR|VERBOSE,
- ARGS,
- lc_inc_opt,
- LC_DEVICES,
- },
+ {'b',
+ BLOCK_DEVICES,
+ UNDEF,
+ COLUMN | DBG | HELP | IGNORELOCKING | SEPARATOR | VERBOSE,
+ ARGS,
+ lc_inc_opt,
+ LC_DEVICES,
+ },
/* Columns display option. */
- { 'c',
- COLUMN,
- BLOCK_DEVICES|RAID_DEVICES|RAID_SETS,
- ACTIVE|INACTIVE|DBG|DUMP|FORMAT|GROUP|HELP|IGNORELOCKING
- |SEPARATOR|VERBOSE,
- ARGS,
- check_identifiers,
- LC_COLUMN,
- },
+ {'c',
+ COLUMN,
+ BLOCK_DEVICES | RAID_DEVICES | RAID_SETS,
+ ACTIVE | INACTIVE | DBG | DUMP | FORMAT | GROUP | HELP | IGNORELOCKING
+ | SEPARATOR | VERBOSE,
+ ARGS,
+ check_identifiers,
+ LC_COLUMN,
+ },
/* Debug option. */
- { 'd',
- DBG,
- ALL_FLAGS,
- ALL_FLAGS,
- ARGS,
- lc_inc_opt,
- LC_DEBUG,
- },
+ {'d',
+ DBG,
+ ALL_FLAGS,
+ ALL_FLAGS,
+ ARGS,
+ lc_inc_opt,
+ LC_DEBUG,
+ },
/* Dump metadata option. */
- { 'D',
- DUMP,
- RAID_DEVICES,
- COLUMN|DBG|FORMAT|HELP|IGNORELOCKING|SEPARATOR|VERBOSE,
- ARGS,
- lc_inc_opt,
- LC_DUMP,
- },
+ {'D',
+ DUMP,
+ RAID_DEVICES,
+ COLUMN | DBG | FORMAT | HELP | IGNORELOCKING | SEPARATOR | VERBOSE,
+ ARGS,
+ lc_inc_opt,
+ LC_DUMP,
+ },
/* Erase metadata option. */
- { 'E',
- ERASE,
- RAID_DEVICES,
- COLUMN|DBG|FORMAT|HELP|IGNORELOCKING|SEPARATOR|VERBOSE,
- ARGS,
- NULL,
- 0,
- },
+ {'E',
+ DMERASE,
+ RAID_DEVICES,
+ COLUMN | DBG | FORMAT | HELP | IGNORELOCKING | SEPARATOR | VERBOSE,
+ ARGS,
+ NULL,
+ 0,
+ },
/* RAID groups option. */
- { 'g',
- GROUP,
- RAID_SETS,
- ACTIVE|INACTIVE|DBG|COLUMN|FORMAT|HELP|IGNORELOCKING
- |SEPARATOR|VERBOSE,
- ARGS,
- lc_inc_opt,
- LC_GROUP,
- },
+ {'g',
+ GROUP,
+ RAID_SETS,
+ ACTIVE | INACTIVE | DBG | COLUMN | FORMAT | HELP | IGNORELOCKING
+ | SEPARATOR | VERBOSE,
+ ARGS,
+ lc_inc_opt,
+ LC_GROUP,
+ },
#endif
/* Help option. */
- { 'h',
- HELP,
- UNDEF,
- ALL_FLAGS,
- ARGS,
- help,
- 0,
- },
+ {'h',
+ HELP,
+ UNDEF,
+ ALL_FLAGS,
+ ARGS,
+ help,
+ 0,
+ },
/* ignorelocking option. */
- { 'i',
- IGNORELOCKING,
- UNDEF,
- ALL_FLAGS,
- ARGS,
- lc_inc_opt,
- LC_IGNORELOCKING,
- },
+ {'i',
+ IGNORELOCKING,
+ UNDEF,
+ ALL_FLAGS,
+ ARGS,
+ lc_inc_opt,
+ LC_IGNORELOCKING,
+ },
#ifndef DMRAID_MINI
/* List metadata format handlers option. */
- { 'l',
- LIST_FORMATS,
- UNDEF,
- DBG|HELP|IGNORELOCKING|VERBOSE,
- NO_ARGS,
- NULL,
- 0,
- },
+ {'l',
+ LIST_FORMATS,
+ UNDEF,
+ DBG | HELP | IGNORELOCKING | VERBOSE,
+ NO_ARGS,
+ NULL,
+ 0,
+ },
+
+ /* Delete a RAID set option. */
+ {'x',
+ DEL_SETS,
+ UNDEF, //RAID_SETS,
+ RAID_SETS | INACTIVE | COLUMN | DBG | FORMAT | GROUP | HELP |
+ IGNORELOCKING | SEPARATOR | VERBOSE,
+ ARGS,
+ NULL,
+ 0,
+ },
# ifdef DMRAID_NATIVE_LOG
/* Native log option. */
- { 'n',
- NATIVE_LOG,
- UNDEF,
- DBG|FORMAT|HELP|IGNORELOCKING|SEPARATOR|VERBOSE,
- ARGS,
- NULL,
- 0,
- },
+ {'n',
+ NATIVE_LOG,
+ UNDEF,
+ DBG | FORMAT | HELP | IGNORELOCKING | SEPARATOR | VERBOSE,
+ ARGS,
+ NULL,
+ 0,
+ },
# endif
/* Display RAID devices option. */
- { 'r',
- RAID_DEVICES,
- UNDEF,
- COLUMN|DBG|DUMP|ERASE|FORMAT|HELP|IGNORELOCKING|SEPARATOR|VERBOSE,
- ARGS,
- NULL,
- 0,
- },
+ {'r',
+ RAID_DEVICES,
+ UNDEF,
+ COLUMN | DBG | DUMP | DMERASE | FORMAT | HELP | IGNORELOCKING |
+ SEPARATOR | VERBOSE,
+ ARGS,
+ NULL,
+ 0,
+ },
+
+ /* rebuild option */
+ {'R',
+ REBUILD,
+ UNDEF,
+#ifdef DMRAID_MINI
+ HELP, IGNORELOCKING,
+#else
+ DBG | HELP | IGNORELOCKING | VERBOSE,
+#endif
+ ARGS,
+#ifndef DMRAID_MINI
+ check_identifiers,
+#else
+ NULL,
+#endif
+ LC_REBUILD_SET,
+ },
+
+ /* Media/drive option */
+ {'M',
+ MEDIA,
+ UNDEF,
+#ifdef DMRAID_MINI
+ HELP, IGNORELOCKING,
+#else
+ DBG | HELP | IGNORELOCKING | VERBOSE | REBUILD,
+#endif
+ ARGS,
+#ifndef DMRAID_MINI
+ check_identifiers,
+#else
+ NULL,
+#endif
+ LC_REBUILD_DISK,
+ },
/* Display RAID sets option. */
- { 's',
- RAID_SETS,
- UNDEF,
- ACTIVE|INACTIVE|COLUMN|DBG|FORMAT|GROUP|HELP|IGNORELOCKING
- |SEPARATOR|VERBOSE,
- ARGS,
- check_active,
- 0,
- },
+ {'s',
+ RAID_SETS,
+ UNDEF,
+ ACTIVE | INACTIVE | COLUMN | DBG | FORMAT | GROUP | HELP |
+ IGNORELOCKING | DEL_SETS | SEPARATOR | VERBOSE,
+ ARGS,
+ check_active,
+ 0,
+ },
/* Display RAID sets option. */
- { SEPARATOR,
- SEPARATOR,
- COLUMN|FORMAT,
- ALL_FLAGS,
- ARGS,
- check_separator,
- 0,
- },
+ {SEPARATOR,
+ SEPARATOR,
+ COLUMN | FORMAT,
+ ALL_FLAGS,
+ ARGS,
+ check_separator,
+ 0,
+ },
/* Test run option. */
- { 't',
- TEST,
- ACTIVATE|DEACTIVATE,
- ACTIVATE|DEACTIVATE|DBG|FORMAT|HELP|IGNORELOCKING|
- NOPARTITIONS|VERBOSE,
- ARGS,
- lc_inc_opt,
- LC_TEST,
- },
+ {'t',
+ TEST,
+ ACTIVATE | DEACTIVATE,
+ ACTIVATE | DEACTIVATE | DBG | FORMAT | HELP | IGNORELOCKING |
+ NOPARTITIONS | VERBOSE,
+ ARGS,
+ lc_inc_opt,
+ LC_TEST,
+ },
/* Verbose option. */
- { 'v',
- VERBOSE,
- ALL_FLAGS,
- ALL_FLAGS,
- ARGS,
- lc_inc_opt,
- LC_VERBOSE,
- },
+ {'v',
+ VERBOSE,
+ ALL_FLAGS,
+ ALL_FLAGS,
+ ARGS,
+ lc_inc_opt,
+ LC_VERBOSE,
+ },
#endif /* #ifndef DMRAID_MINI */
/* Version option. */
- { 'V',
- VERSION,
- UNDEF,
+ {'V',
+ VERSION,
+ UNDEF,
#ifdef DMRAID_MINI
- HELP,IGNORELOCKING,
+ HELP, IGNORELOCKING,
#else
- DBG|HELP|IGNORELOCKING|VERBOSE,
+ DBG | HELP | IGNORELOCKING | VERBOSE,
#endif
- NO_ARGS,
- NULL,
- 0,
- },
+ NO_ARGS,
+ NULL,
+ 0,
+ },
+
+ /* RAID set creation. */
+ {'C',
+ CREATE,
+ UNDEF,
+ DBG | HELP | IGNORELOCKING | VERBOSE,
+ NO_ARGS,
+ check_create_argument,
+ LC_CREATE,
+ },
+ /* Spare disk creation. */
+ {'S',
+ SPARE,
+ UNDEF,
+ DBG | HELP | IGNORELOCKING | VERBOSE,
+ NO_ARGS,
+ check_spare_argument,
+ LC_HOT_SPARE_SET,
+ },
};
/*
* Set action flag and call optional function.
*/
-static int set_action(struct lib_context *lc, int o)
+static int
+set_action(struct lib_context *lc, int o)
{
struct actions *a;
@@ -474,6 +588,7 @@
action |= a->action; /* Set action flag. */
a->allowed |= a->action;/* Merge to allowed flags. */
a->allowed |= a->needed;
+
if (a->f_set) /* Optionally call function. */
return a->f_set(lc, a->arg);
@@ -485,38 +600,37 @@
}
/* Check for invalid option combinations */
-static int check_actions(struct lib_context *lc, char **argv)
+static int
+check_actions(struct lib_context *lc, char **argv)
{
struct actions *a;
for (a = actions; a < ARRAY_END(actions); a++) {
if (a->action & action) {
- if (a->needed != UNDEF &&
- !(a->needed & action))
+ if (a->needed != UNDEF && !(a->needed & action))
LOG_ERR(lc, 0,
"option missing/invalid option "
- "combination with -%c",
- a->option);
+ "combination with -%c", a->option);
if (~a->allowed & action)
- LOG_ERR(lc, 0, "Invalid option combination"
- " (-h for help)");
+ LOG_ERR(lc, 0, "invalid option combination"
+ " (-h for help)");
if (a->args == NO_ARGS && argv[optind])
LOG_ERR(lc, 0,
- "No arguments allowed with -%c\n",
+ "no arguments allowed with -%c\n",
a->option);
}
}
if (!action)
- LOG_ERR(lc, 0, "Options missing\n");
+ LOG_ERR(lc, 0, "options missing\n");
#ifndef DMRAID_MINI
- if ((action & (DBG|VERBOSE)) == action)
- LOG_ERR(lc, 0, "More options needed with -d/-v");
+ if ((action & (DBG | VERBOSE)) == action)
+ LOG_ERR(lc, 0, "more options needed with -d/-v");
- if (action & ERASE) {
+ if (action & DMERASE) {
action |= DUMP;
lc_inc_opt(lc, LC_DUMP);
}
@@ -526,16 +640,42 @@
}
/* Check for invalid option argumengts. */
-static int check_actions_arguments(struct lib_context *lc)
+static int
+check_actions_arguments(struct lib_context *lc)
{
if (valid_format(lc, OPT_STR_FORMAT(lc)))
return 1;
- LOG_ERR(lc, 0, "Invalid format for -f at (see -l)");
+ LOG_ERR(lc, 0, "invalid format for -f at (see -l)");
}
+int
+save_drive_name(struct lib_context *lc, char *drive)
+{
+ lc->options[LC_REBUILD_DISK].opt++;
+ return lc_strcat_opt(lc, LC_REBUILD_DISK, drive, ',') ? 1 : 0;
+}
+
+static int
+save_spare_name(struct lib_context *lc, char **argv)
+{
+ char *p = argv[optind];
+
+ lc->options[LC_HOT_SPARE_SET].arg.str = NULL;
+
+ if (p && strlen(p) && *p != '-') {
+ lc->options[LC_HOT_SPARE_SET].arg.str = dbg_strdup(p);
+ if (!lc->options[LC_HOT_SPARE_SET].arg.str)
+ return log_alloc_err(lc, __func__);
+ }
+
+ return 1;
+}
+
+
/* Parse and handle the command line arguments */
-int handle_args(struct lib_context *lc, int argc, char ***argv)
+int
+handle_args(struct lib_context *lc, int argc, char ***argv)
{
int o, ret = 0;
#ifdef HAVE_GETOPTLONG
@@ -543,7 +683,7 @@
#endif
if (argc < 2)
- LOG_ERR(lc, 0, "No arguments/options given (-h for help)\n");
+ LOG_ERR(lc, 0, "no arguments/options given (-h for help)\n");
#ifdef HAVE_GETOPTLONG
/* Walk the options (and option arguments) */
@@ -556,6 +696,29 @@
if ((ret = set_action(lc, o)) && (HELP & action))
return 1;
+ /* Handle arguments for option -S */
+ if (o == 'S') {
+ if (!save_spare_name(lc, *argv))
+ return 0;
+ }
+
+ /* to create spare disk/set */
+ if (o == 'M' &&
+ OPT_HOT_SPARE_SET(lc) &&
+ OPT_REBUILD_DISK(lc)) {
+ *argv += optind - 3;
+ return 1;
+ }
+
+ /* To create a new RAID set; arguments are handled later */
+ if (o == 'C') {
+ *argv += optind - 1;
+ return 1;
+ } else if (o == 'R' && argc == 4) {
+ if (*(*argv + optind))
+ save_drive_name(lc, *(*argv + optind));
+ }
+
if (!ret || o == ':' || o == '?')
return 0;
}
@@ -569,107 +732,103 @@
ret = check_actions_arguments(lc);
*argv += optind;
+ if (argc == 4 && lc->options[LC_REBUILD_SET].opt)
+ *argv += 1;
return ret;
}
-static int version(struct lib_context *lc, int arg)
+static int
+version(struct lib_context *lc, int arg)
{
char v[80];
dm_version(lc, v, sizeof(v));
log_print(lc, "%s version:\t\t%s\n"
- "%s library version:\t%s %s\n"
- "device-mapper version:\t%s",
- lc->cmd, DMRAID_VERSION,
- lc->cmd, libdmraid_version(lc), libdmraid_date(lc), v);
+ "%s library version:\t%s %s\n"
+ "device-mapper version:\t%s",
+ lc->cmd, DMRAID_VERSION,
+ lc->cmd, libdmraid_version(lc), libdmraid_date(lc), v);
return 1;
}
+static int
+rebuild(struct lib_context *lc, int arg)
+{
+ return rebuild_raidset(lc,
+ (char *) lc->options[LC_REBUILD_SET].arg.str);
+}
+
/*********************************************************************
* Perform pre/post functions for requested actions.
*/
/* Post Activate/Deactivate RAID set. */
#ifndef DMRAID_MINI
/* Pre and post display_set() functions. */
-static int _display_sets_arg(int arg)
+static int
+_display_sets_arg(int arg)
{
return (action & ACTIVE) ?
- D_ACTIVE : ((action & INACTIVE) ? D_INACTIVE : D_ALL);
+ D_ACTIVE : ((action & INACTIVE) ? D_INACTIVE : D_ALL);
}
-static int _display_set(struct lib_context *lc, void *rs, int type)
+static int
+_display_set(struct lib_context *lc, void *rs, int type)
{
display_set(lc, rs, type, 0);
-
return 1;
}
-static int _display_sets(struct lib_context *lc, int type)
+static int
+_display_sets(struct lib_context *lc, int type)
{
process_sets(lc, _display_set, type, SETS);
+ return 1;
+}
+static int
+_delete_sets(struct lib_context *lc, int arg)
+{
+ delete_raidsets(lc);
return 1;
}
-static int _display_devices(struct lib_context *lc, int type)
+static int
+_create_sets(struct lib_context *lc, int arg)
{
- display_devices(lc, type);
+ return 1;
+}
+static int
+_display_devices(struct lib_context *lc, int type)
+{
+ display_devices(lc, type);
return 1;
}
-static int _erase(struct lib_context *lc, int arg)
+static int
+_erase(struct lib_context *lc, int arg)
{
return erase_metadata(lc);
}
-#endif
-/* Retrieve and build metadata. */
-static int get_metadata(struct lib_context *lc, struct prepost *p, char **argv)
+/* Post hot_spare_add function */
+static int
+_hot_spare_add_set(struct lib_context *lc, void *r, int type)
{
- if (!(M_DEVICE & p->metadata))
- return 1;
-
- if (!discover_devices(lc, OPT_DEVICES(lc) ? argv : NULL))
- LOG_ERR(lc, 0, "failed to discover devices");
-
- if(!count_devices(lc, DEVICE)) {
- log_print(lc, "no block devices found");
- return 1;
- }
+ return hot_spare_add(lc, (struct raid_set*) r);
+}
- if (!(M_RAID & p->metadata))
- return 1;
+static int
+_hot_spare_add(struct lib_context *lc, int type)
+{
+ process_sets(lc, _hot_spare_add_set, type, SETS);
+ return 1;
+}
-#ifndef DMRAID_MINI
- /* Discover RAID disks and keep RAID metadata (eg, hpt45x) */
- discover_raid_devices(lc,
-# ifdef DMRAID_NATIVE_LOG
- ((NATIVE_LOG|RAID_DEVICES) & action) ? argv : NULL);
-# else
- (RAID_DEVICES & action) ? argv : NULL);
-# endif
-#else
- discover_raid_devices(lc, NULL);
#endif
- if (!count_devices(lc, RAID)) {
- format_error(lc, "disks", argv);
- return 1;
- }
- if (M_SET & p->metadata) {
- /* Group RAID sets. */
- build_sets(lc, argv);
- if (!count_devices(lc, SET)) {
- format_error(lc, "sets", argv);
- return 0;
- }
- }
-
- return 1;
-}
/*
* Function abstraction which takes pre- and post-function calls
@@ -692,112 +851,136 @@
*/
struct prepost prepost[] = {
/* (De)activate RAID set. */
- { ACTIVATE|DEACTIVATE,
- M_DEVICE|M_RAID|M_SET,
- ROOT,
- LOCK,
- NULL,
- 0,
- activate_or_deactivate_sets,
- },
+ {ACTIVATE | DEACTIVATE,
+ M_DEVICE | M_RAID | M_SET,
+ ROOT,
+ LOCK,
+ NULL,
+ 0,
+ activate_or_deactivate_sets,
+ },
#ifndef DMRAID_MINI
/* Display block devices. */
- { BLOCK_DEVICES,
- M_DEVICE,
- ROOT,
- NO_LOCK,
- NULL,
- DEVICE,
- _display_devices,
- },
+ {BLOCK_DEVICES,
+ M_DEVICE,
+ ROOT,
+ NO_LOCK,
+ NULL,
+ DEVICE,
+ _display_devices,
+ },
/* Erase metadata. */
- { ERASE,
- M_DEVICE|M_RAID,
- ROOT,
- LOCK,
- NULL,
- 0,
- _erase,
- },
+ {DMERASE,
+ M_DEVICE | M_RAID,
+ ROOT,
+ LOCK,
+ NULL,
+ 0,
+ _erase,
+ },
/* List metadata format handlers. */
- { LIST_FORMATS,
- M_NONE,
- ANY_ID,
- NO_LOCK,
- NULL,
- 0,
- list_formats,
- },
+ {LIST_FORMATS,
+ M_NONE,
+ ANY_ID,
+ NO_LOCK,
+ NULL,
+ 0,
+ list_formats,
+ },
# ifdef DMRAID_NATIVE_LOG
/* Native metadata log. */
- { NATIVE_LOG,
- M_DEVICE|M_RAID,
- ROOT,
- LOCK,
- NULL,
- NATIVE,
- _display_devices,
- },
+ {NATIVE_LOG,
+ M_DEVICE | M_RAID,
+ ROOT,
+ LOCK,
+ NULL,
+ NATIVE,
+ _display_devices,
+ },
# endif
/* Display RAID devices. */
- { RAID_DEVICES,
- M_DEVICE|M_RAID,
- ROOT,
- LOCK,
- NULL,
- RAID,
- _display_devices,
- },
+ {RAID_DEVICES,
+ M_DEVICE | M_RAID,
+ ROOT,
+ LOCK,
+ NULL,
+ RAID,
+ _display_devices,
+ },
+
+ /* Delete RAID sets. */
+ {DEL_SETS,
+ M_DEVICE | M_RAID | M_SET,
+ ROOT,
+ LOCK,
+ NULL,
+ 0,
+ _delete_sets,
+ },
/* Display RAID sets. */
- { RAID_SETS,
- M_DEVICE|M_RAID|M_SET,
- ROOT,
- LOCK,
- _display_sets_arg,
- 0,
- _display_sets,
- },
+ {RAID_SETS,
+ M_DEVICE | M_RAID | M_SET,
+ ROOT,
+ LOCK,
+ _display_sets_arg,
+ 0,
+ _display_sets,
+ },
+
#endif
/* Display version. */
- { VERSION,
- M_NONE,
- ANY_ID,
- NO_LOCK,
- NULL,
- 0,
- version,
- },
-};
+ {VERSION,
+ M_NONE,
+ ANY_ID,
+ NO_LOCK,
+ NULL,
+ 0,
+ version,
+ },
+
+ /* Create a RAID set. */
+ {CREATE,
+ M_DEVICE | M_RAID | M_SET,
+ ROOT,
+ LOCK,
+ NULL,
+ 0,
+ _create_sets,
+ },
+
+ /* Add spare disk to a RAID set. */
+ {SPARE,
+ M_DEVICE | M_RAID | M_SET,
+ ROOT,
+ LOCK,
+ NULL,
+ 0,
+ _hot_spare_add,
+ },
+
+
+ /* Rebuild */
+ {REBUILD,
+ M_DEVICE | M_RAID | M_SET,
+ ROOT,
+ LOCK,
+ NULL,
+ 0,
+ rebuild,
+ },
-static int _perform(struct lib_context *lc, struct prepost *p,
- char **argv)
-{
- int ret = 0;
-
- if (ROOT == p->id && geteuid())
- LOG_ERR(lc, 0, "you must be root");
-
- /* Lock against parallel runs. Resource NULL for now. */
- if (LOCK == p->lock && !lock_resource(lc, NULL))
- LOG_ERR(lc, 0, "lock failure");
-
- if (get_metadata(lc, p, argv))
- ret = p->post(lc, p->pre ? p->pre(p->arg) : p->arg);
-
- if (LOCK == p->lock)
- unlock_resource(lc, NULL);
-
- return ret;
-}
+};
-int perform(struct lib_context *lc, char **argv)
+/* Perform pre/post actions for options. */
+int
+perform(struct lib_context *lc, char **argv)
{
struct prepost *p;
@@ -808,7 +991,8 @@
/* Find appropriate action. */
for (p = prepost; p < ARRAY_END(prepost); p++) {
if (p->action & action)
- return _perform(lc, p, argv);
+ return lib_perform(lc, action, p, argv);
+
}
return 0;
--- dmraid/tools/commands.h 2008/04/02 13:35:32 1.2
+++ dmraid/tools/commands.h 2008/06/20 21:52:19 1.3
@@ -2,6 +2,9 @@
* Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
@@ -13,50 +16,8 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
#define ARRAY_END(a) (a + ARRAY_SIZE(a))
-/* Options actions dmraid performs. */
-enum action {
- UNDEF = 0x0,
- ACTIVATE = 0x1,
- DEACTIVATE = 0x2,
- FORMAT = 0x4,
-#ifndef DMRAID_MINI
- BLOCK_DEVICES = 0x8,
- COLUMN = 0x10,
- DBG = 0x20,
- DUMP = 0x40,
- ERASE = 0x80,
- GROUP = 0x100,
-#endif
- HELP = 0x200,
-#ifndef DMRAID_MINI
- LIST_FORMATS = 0x400,
-# ifdef DMRAID_NATIVE_LOG
- NATIVE_LOG = 0x800,
-# endif
-#endif
- NOPARTITIONS = 0x1000,
-#ifndef DMRAID_MINI
- RAID_DEVICES = 0x2000,
- RAID_SETS = 0x4000,
- TEST = 0x8000,
- VERBOSE = 0x10000,
- ACTIVE = 0x20000,
- INACTIVE = 0x40000,
- SEPARATOR = 0x80000,
-#endif
- VERSION = 0x100000,
- IGNORELOCKING = 0x200000,
- PARTCHAR = 0x400000,
-};
-
#define ALL_FLAGS ((enum action) -1)
-/* Arguments allowed ? */
-enum args {
- NO_ARGS,
- ARGS,
-};
-
/*
* Action flag definitions for set_action().
*
@@ -72,41 +33,10 @@
enum args args; /* Arguments allowed ? */
/* Function to call on hit or NULL */
- int (*f_set)(struct lib_context *lc, int arg);
+ int (*f_set) (struct lib_context * lc, int arg);
int arg; /* Argument for above function call */
};
-/* Define which metadata is needed before we can call post functions. */
-enum metadata_need {
- M_NONE = 0x00,
- M_DEVICE = 0x01,
- M_RAID = 0x02,
- M_SET = 0x04,
-};
-
-enum id {
- ROOT,
- ANY_ID,
-};
-
-enum lock {
- LOCK,
- NO_LOCK,
-};
-
-/*
- * Pre and Post functions to perform for an option.
- */
-struct prepost {
- enum action action;
- enum metadata_need metadata;
- enum id id;
- enum lock lock;
- int (*pre)(int arg);
- int arg;
- int (*post)(struct lib_context *lc, int arg);
-};
-
int handle_args(struct lib_context *lc, int argc, char ***argv);
int perform(struct lib_context *lc, char **argv);
--- dmraid/tools/dmraid.c 2008/02/22 16:57:37 1.1
+++ dmraid/tools/dmraid.c 2008/06/20 21:52:19 1.2
@@ -14,7 +14,8 @@
#include "toollib.h"
#include "version.h"
-int main(int argc, char **argv)
+int
+main(int argc, char **argv)
{
int ret = 0;
struct lib_context *lc;
@@ -32,13 +33,12 @@
* If both are ok -> perform the required action.
*/
ret = handle_args(lc, argc, &argv) &&
- init_locking(lc) &&
- perform(lc, argv);
+ init_locking(lc) && perform(lc, argv);
/* Cleanup the library context. */
libdmraid_exit(lc);
}
/* Set standard exit code. */
- exit (ret ? EXIT_SUCCESS : EXIT_FAILURE);
+ exit(ret ? EXIT_SUCCESS : EXIT_FAILURE);
}
--- dmraid/tools/toollib.c 2008/02/22 16:57:37 1.1
+++ dmraid/tools/toollib.c 2008/06/20 21:52:19 1.2
@@ -1,7 +1,10 @@
/*
- * Copyright (C) 2004,2005 Heinz Mauelshagen, Red Hat GmbH.
+ * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH.
* All rights reserved.
*
+ * Copyright (C) 2007 Intel Corporation. All rights reserved.
+ * November, 2007 - additions for Create, Delete, Rebuild & Raid 10.
+ *
* See file LICENSE at the top of this source tree for license information.
*/
@@ -23,13 +26,13 @@
#include "toollib.h"
/* [De]activate a RAID set. */
-static int _change_set(struct lib_context *lc, void *rs, int arg)
+static int
+_change_set(struct lib_context *lc, void *rs, int arg)
{
- if (change_set(lc,
- (ACTIVATE & action) ? A_ACTIVATE : A_DEACTIVATE,
+ if (change_set(lc, (ACTIVATE & action) ? A_ACTIVATE : A_DEACTIVATE,
rs)) {
- log_info(lc, "%sctivating %s RAID set \"%s\"",
- action & ACTIVATE ? "A": "Dea",
+ log_info(lc, "%sctivating %s raid set \"%s\"",
+ action & ACTIVATE ? "A" : "Dea",
get_set_type(lc, rs), get_set_name(lc, rs));
return 1;
}
@@ -39,13 +42,15 @@
/* [De]activate RAID sets. */
/* FIXME: remove partition code in favour of kpartx ? */
-static void process_partitions(struct lib_context *lc)
+static void
+process_partitions(struct lib_context *lc)
{
discover_partitions(lc);
process_sets(lc, _change_set, 0, PARTITIONS);
}
-int activate_or_deactivate_sets(struct lib_context *lc, int arg)
+int
+activate_or_deactivate_sets(struct lib_context *lc, int arg)
{
/* Discover partitions to deactivate RAID sets for and work on them. */
if (DEACTIVATE & action)
@@ -61,21 +66,15 @@
}
/* Build all sets or the ones given. */
-void build_sets(struct lib_context *lc, char **sets)
+void
+build_sets(struct lib_context *lc, char **sets)
{
- int o = 0;
-
- do {
- if (!group_set(lc, sets[o]))
- log_err(lc, "building set");
-
- if (!sets[o])
- break;
- } while (sets[++o]);
+ group_set(lc, sets);
}
/* Convert a character string to lower case. */
-void str_tolower(char *s)
+void
+str_tolower(char *s)
{
for (; *s; s++)
*s = tolower(*s);
@@ -85,8 +84,9 @@
* Check if selected or all formats shall be used to read the metadata.
*/
/* Collapse a delimiter into one. */
-char *collapse_delimiter(struct lib_context *lc, char *str,
- size_t size, const char delim)
+char *
+collapse_delimiter(struct lib_context *lc, char *str,
+ size_t size, const char delim)
{
size_t len;
char *p = str;
@@ -101,13 +101,14 @@
return str;
}
-int valid_format(struct lib_context *lc, const char *fmt)
+int
+valid_format(struct lib_context *lc, const char *fmt)
{
int ret = 1;
char *p, *p_sav, *sep;
const char delim = *OPT_STR_SEPARATOR(lc);
- if (!(p_sav = dbg_strdup((char*) fmt)))
+ if (!(p_sav = dbg_strdup((char *) fmt)))
return log_alloc_err(lc, __func__);
sep = p_sav;
@@ -122,29 +123,5 @@
} while (sep);
dbg_free(p_sav);
-
return ret;
}
-
-void format_error(struct lib_context *lc, const char *error, char **argv)
-{
- log_print_nnl(lc, "No RAID %s", error);
-
- if (OPT_FORMAT(lc))
- log_print_nnl(lc, " with format: \"%s\"",
- OPT_STR_FORMAT(lc));
-
-
- if (argv && *argv) {
- log_print_nnl(lc, " and with names: \"");
- while (*argv) {
- log_print_nnl(lc, "%s", *argv++);
- if (*argv)
- log_print_nnl(lc, "%s", OPT_STR_SEPARATOR(lc));
- else
- log_print_nnl(lc, "\"");
- }
- }
-
- log_print(lc, "");
-}
--- dmraid/tools/toollib.h 2008/02/22 16:57:37 1.1
+++ dmraid/tools/toollib.h 2008/06/20 21:52:19 1.2
@@ -10,12 +10,12 @@
extern enum action action;
-int activate_or_deactivate_sets(struct lib_context *lc, int arg);
+int activate_or_deactivate_sets(struct lib_context *lc, int arg);
void build_sets(struct lib_context *lc, char **sets);
void format_error(struct lib_context *lc, const char *error, char **argv);
void str_tolower(char *s);
char *collapse_delimiter(struct lib_context *lc, char *str,
size_t size, const char delim);
-int valid_format(struct lib_context *lc, const char *fmt);
+int valid_format(struct lib_context *lc, const char *fmt);
#endif
More information about the dm-devel
mailing list