[dm-devel] dmraid ./CHANGELOG ./KNOWN_BUGS ./README ./dmr ...
heinzm at sourceware.org
heinzm at sourceware.org
Wed Apr 2 13:35:36 UTC 2008
CVSROOT: /cvs/dm
Module name: dmraid
Changes by: heinzm at sourceware.org 2008-04-02 13:35:32
Modified files:
. : CHANGELOG KNOWN_BUGS README dmraid.spec
include/dmraid : lib_context.h
lib : internal.h version.h
lib/activate : activate.c devmapper.c
lib/format : format.c
lib/format/ataraid: asr.c isw.c jm.c lsi.c lsi.h nv.c pdc.c
pdc.h
lib/format/ddf : ddf1.c ddf1_crc.c
lib/format/partition: dos.c
lib/metadata : metadata.c
lib/misc : lib_context.c
man : dmraid.8
tools : VERSION commands.c commands.h
Log message:
1.0.0.rc15-pre checkin
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/CHANGELOG.diff?cvsroot=dm&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/KNOWN_BUGS.diff?cvsroot=dm&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/README.diff?cvsroot=dm&r1=1.5&r2=1.6
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/dmraid.spec.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.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/internal.h.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/version.h.diff?cvsroot=dm&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/activate/activate.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/activate/devmapper.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/format.c.diff?cvsroot=dm&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/asr.c.diff?cvsroot=dm&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/isw.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/jm.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/lsi.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/lsi.h.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/nv.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/pdc.c.diff?cvsroot=dm&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ataraid/pdc.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.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/ddf/ddf1_crc.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/format/partition/dos.c.diff?cvsroot=dm&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/metadata/metadata.c.diff?cvsroot=dm&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/lib/misc/lib_context.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.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/tools/VERSION.diff?cvsroot=dm&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/tools/commands.c.diff?cvsroot=dm&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/dmraid/tools/commands.h.diff?cvsroot=dm&r1=1.1&r2=1.2
--- dmraid/CHANGELOG 2008/02/22 17:06:54 1.4
+++ dmraid/CHANGELOG 2008/04/02 13:35:30 1.5
@@ -1,4 +1,21 @@
+Changelog from dmraid 1.0.0.rc14 to 1.0.0.rc15 2007.08.22
+
+FIXES:
+------
+o jm.c: fixed name handling, when whitespace added to end of name
+o nv.c: fixed endian bug (Bryn Reeves)
+
+
+FEATURES:
+---------
+
+
+MISCELANIOUS:
+-------------
+
+
+
Changelog from dmraid 1.0.0.rc13 to 1.0.0.rc14 2006.11.08
FIXES:
--- dmraid/KNOWN_BUGS 2008/02/22 17:06:54 1.3
+++ dmraid/KNOWN_BUGS 2008/04/02 13:35:30 1.4
@@ -1,4 +1,4 @@
-KNOWN_BUGS in dmraid 1.0.0.rc14 2005.11.08
+KNOWN_BUGS in dmraid 1.0.0.rc15 2008.04.02
o "dmraid --sets[a/i]" doesn't work properly. Use the short option -s.
--- dmraid/README 2008/02/22 17:06:54 1.5
+++ dmraid/README 2008/04/02 13:35:30 1.6
@@ -1,8 +1,8 @@
********************************************************************************
* *
-* dmraid (Device-Mapper Software RAID support tool) 1.0.0.rc14 2006.11.08 *
+* dmraid (Device-Mapper Software RAID tool) 1.0.0.rc15-pre 2008.04.02 *
* *
-* (C)opyright 2004-2006 Heinz Mauelshagen, Red Hat GmbH. *
+* (C)opyright 2004-2008 Heinz Mauelshagen, Red Hat GmbH. *
* All rights reserved. *
* *
********************************************************************************
@@ -66,13 +66,13 @@
--------------
To install the rpm
-rpm -i [--nodeps] dmraid-1.0.0.rc10.i386.rpm
+rpm -i [--nodeps] dmraid-1.0.0.rc15.i386.rpm
- or -
to build in an empty directory and install from source
-tar jxvf dmraid-1.0.0.rc10.tar.bz2
+tar jxvf dmraid-1.0.0.rc15.tar.bz2
./configure # see ./configure --help for options
make
make install
--- dmraid/dmraid.spec 2008/02/22 16:50:38 1.1
+++ dmraid/dmraid.spec 2008/04/02 13:35:30 1.2
@@ -6,7 +6,7 @@
Summary: dmraid (Device-mapper RAID tool and library)
Name: dmraid
-Version: 1.0.0.rc11
+Version: 1.0.0.rc15-pre
Release: 1
License: GPL
Group: System Environment/Base
--- dmraid/include/dmraid/lib_context.h 2008/02/22 16:57:35 1.1
+++ dmraid/include/dmraid/lib_context.h 2008/04/02 13:35:31 1.2
@@ -38,7 +38,8 @@
LC_VERBOSE,
LC_IGNORELOCKING,
LC_SEPARATOR,
- LC_DEVICES, /* Add new options below this one ! */
+ LC_DEVICES,
+ LC_PARTCHAR, /* Add new options below this one ! */
LC_OPTIONS_SIZE, /* Must be the last enumerator. */
};
@@ -55,12 +56,14 @@
#define OPT_SETS(lc) (lc_opt(lc, LC_SETS))
#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))
/* Return option value. */
#define OPT_STR(lc, o) (lc->options[o].arg.str)
#define OPT_STR_COLUMN(lc) OPT_STR(lc, LC_COLUMN)
#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)
struct lib_version {
const char *text;
--- dmraid/lib/internal.h 2008/02/22 17:04:35 1.2
+++ dmraid/lib/internal.h 2008/04/02 13:35:31 1.3
@@ -49,8 +49,8 @@
#define u_int64_t uint64_t
#endif
-#define min(a, b) a < b ? a : b
-#define max(a, b) a > b ? a : b
+#define min(a, b) (a) < (b) ? (a) : (b)
+#define max(a, b) (a) > (b) ? (a) : (b)
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
#define ARRAY_END(a) (a + ARRAY_SIZE(a))
--- dmraid/lib/version.h 2008/02/22 17:06:54 1.4
+++ dmraid/lib/version.h 2008/04/02 13:35:31 1.5
@@ -1,12 +1,12 @@
#ifndef DMRAID_LIB_VERSION
-#define DMRAID_LIB_VERSION "1.0.0.rc14"
+#define DMRAID_LIB_VERSION "1.0.0.rc15"
#define DMRAID_LIB_MAJOR_VERSION 1
#define DMRAID_LIB_MINOR_VERSION 0
#define DMRAID_LIB_SUBMINOR_VERSION 0
-#define DMRAID_LIB_VERSION_SUFFIX "rc14"
+#define DMRAID_LIB_VERSION_SUFFIX "rc15"
-#define DMRAID_LIB_DATE "(2006.11.08)"
+#define DMRAID_LIB_DATE "(2008.04.02)"
#endif
--- dmraid/lib/activate/activate.c 2008/02/22 17:04:35 1.2
+++ dmraid/lib/activate/activate.c 2008/04/02 13:35:31 1.3
@@ -398,7 +398,11 @@
goto err;
}
- return 1;
+ /* Append the flag/feature required for dmraid1
+ * event handling in the kernel driver
+ */
+ if(p_fmt(lc, table, " 1 handle_errors"))
+ return 1;
err:
return log_alloc_err(lc, __func__);
--- dmraid/lib/activate/devmapper.c 2008/02/22 17:04:35 1.2
+++ dmraid/lib/activate/devmapper.c 2008/04/02 13:35:31 1.3
@@ -21,6 +21,8 @@
#include "internal.h"
#include "devmapper.h"
+#include <linux/dm-ioctl.h>
+
/* Make up a dm path. */
char *mkdm_path(struct lib_context *lc, const char *name)
{
@@ -147,24 +149,48 @@
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) {
+ int r;
+
+ /* Clear garbage data from uuid string */
+ memset(uuid, 0, uuid_len);
+
+ /* Create UUID string from subsystem prefix and RAID set name. */
+ r = snprintf(uuid, uuid_len, "DMRAID-%s", rs->name) < uuid_len;
+ return r < 0 ? 0 : (r < uuid_len);
+}
+
/* 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)
{
+ /* 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)*/
+ 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)
- ret = dm_task_run(dmt);
+ 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);
_exit_dm(dmt);
return ret;
}
+
/* Create a mapped device. */
int dm_create(struct lib_context *lc, struct raid_set *rs, char *table)
{
--- dmraid/lib/format/format.c 2008/02/22 17:06:54 1.3
+++ dmraid/lib/format/format.c 2008/04/02 13:35:31 1.4
@@ -18,7 +18,7 @@
* Comment next line out to avoid pre-registration
* checks on metadata format handlers.
*/
-// #define CHECK_FORMAT_HANDLER
+#define CHECK_FORMAT_HANDLER
#ifdef CHECK_FORMAT_HANDLER
/*
* Check that mandatory members of a metadata form handler are present.
@@ -34,25 +34,25 @@
#define offset(member) struct_offset(dmraid_format, member)
struct format_member {
- const unsigned short offset;
- const unsigned char flags;
const char *msg;
+ const unsigned short offset;
+ const unsigned short flags;
} __attribute__ ((packed));
enum { FMT_ALL = 0x01, FMT_METHOD = 0x02 } format_flags;
#define IS_FMT_ALL(member) (member->flags & FMT_ALL)
#define IS_FMT_METHOD(member) (member->flags & FMT_METHOD)
static struct format_member format_member[] = {
- { offset(name), FMT_ALL, "name" },
- { offset(descr), FMT_ALL, "description" },
- { offset(caps), 0, "capabilities" },
- { offset(read), FMT_ALL|FMT_METHOD, "read" },
- { offset(write), FMT_METHOD, "write" },
- { offset(group), FMT_ALL|FMT_METHOD, "group" },
- { offset(check), FMT_ALL|FMT_METHOD, "check" },
- { offset(events), 0, "events array" },
+ { "name", offset(name), FMT_ALL },
+ { "description", offset(descr), FMT_ALL },
+ { "capabilities", offset(caps), 0 },
+ { "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 },
+ { "events array", offset(events), 0 },
#ifdef NATIVE_LOG
- { offset(log), FMT_METHOD, "log" },
+ { "log", offset(log), FMT_METHOD },
#endif
};
#undef offset
--- dmraid/lib/format/ataraid/asr.c 2008/02/22 17:06:00 1.3
+++ dmraid/lib/format/ataraid/asr.c 2008/04/02 13:35:31 1.4
@@ -49,11 +49,12 @@
/* Extract config line from metadata */
static struct asr_raid_configline *get_config(struct asr *asr, uint32_t magic)
{
- unsigned int i = asr->rt->elmcnt;
+ struct asr_raidtable *rt = asr->rt;
+ struct asr_raid_configline *cl = rt->ent + rt->elmcnt;
- while (i--) {
- if (asr->rt->ent[i].raidmagic == magic)
- return asr->rt->ent + i;
+ while (cl-- > rt->ent) {
+ if (cl->raidmagic == magic)
+ return cl;
}
return NULL;
@@ -92,7 +93,7 @@
}
/* Stride size */
-static inline unsigned int stride(struct asr_raid_configline *cl)
+static inline unsigned stride(struct asr_raid_configline *cl)
{
return cl ? cl->strpsize: 0;
}
@@ -114,8 +115,7 @@
{ 0, t_undef},
};
-printf("cl->raidtype=%d rd_type=%d\n", cl->raidtype, rd_type(types, (unsigned int) cl->raidtype));
- return cl ? rd_type(types, (unsigned int) cl->raidtype) : t_undef;
+ return cl ? rd_type(types, (unsigned) cl->raidtype) : t_undef;
}
/*
@@ -141,11 +141,12 @@
CVT32(cl->appBurstCount);
}
-static void to_cpu(void *meta, unsigned int cvt)
+static void to_cpu(void *meta, unsigned cvt)
{
struct asr *asr = meta;
- unsigned int i, elmcnt = asr->rt->elmcnt,
- use_old_elmcnt = (asr->rt->ridcode == RVALID2);
+ struct asr_raidtable *rt = asr->rt;
+ unsigned i, elmcnt = rt->elmcnt,
+ use_old_elmcnt = (rt->ridcode == RVALID2);
if (cvt & ASR_BLOCK) {
CVT32(asr->rb.b0idcode);
@@ -161,29 +162,30 @@
}
if (cvt & ASR_TABLE) {
- CVT32(asr->rt->ridcode);
- CVT32(asr->rt->rversion);
- CVT16(asr->rt->maxelm);
- CVT16(asr->rt->elmcnt);
+ CVT32(rt->ridcode);
+ CVT32(rt->rversion);
+ CVT16(rt->maxelm);
+ CVT16(rt->elmcnt);
if (!use_old_elmcnt)
- elmcnt = asr->rt->elmcnt;
- CVT16(asr->rt->elmsize);
- CVT32(asr->rt->raidFlags);
- CVT32(asr->rt->timestamp);
- CVT16(asr->rt->rchksum);
- CVT32(asr->rt->sparedrivemagic);
- CVT32(asr->rt->raidmagic);
- CVT32(asr->rt->verifyDate);
- CVT32(asr->rt->recreateDate);
+ elmcnt = rt->elmcnt;
+
+ CVT16(rt->elmsize);
+ CVT32(rt->raidFlags);
+ CVT32(rt->timestamp);
+ CVT16(rt->rchksum);
+ CVT32(rt->sparedrivemagic);
+ CVT32(rt->raidmagic);
+ CVT32(rt->verifyDate);
+ CVT32(rt->recreateDate);
/* Convert the first seven config lines */
for (i = 0; i < (min(elmcnt, ASR_TBLELMCNT)); i++)
- cvt_configline(asr->rt->ent + i);
+ cvt_configline(rt->ent + i);
}
if (cvt & ASR_EXTTABLE) {
for (i = ASR_TBLELMCNT; i < elmcnt; i++)
- cvt_configline(asr->rt->ent + i);
+ cvt_configline(rt->ent + i);
}
}
@@ -192,11 +194,11 @@
#endif
/* Compute the checksum of RAID metadata */
-static unsigned int compute_checksum(struct asr *asr)
+static unsigned compute_checksum(struct asr *asr)
{
- uint8_t *ptr = (uint8_t*) asr->rt->ent;
- unsigned int checksum = 0,
- end = sizeof(*asr->rt->ent) * asr->rt->elmcnt;
+ struct asr_raidtable *rt = asr->rt;
+ uint8_t *ptr = (uint8_t*) rt->ent;
+ unsigned checksum = 0, end = sizeof(*rt->ent) * rt->elmcnt;
/* Compute checksum. */
while (end--)
@@ -209,7 +211,7 @@
enum truncate { TRUNCATE, UNTRUNCATE };
static void handle_white_space(uint8_t *p, enum truncate truncate)
{
- unsigned int j = ASR_NAMELEN;
+ unsigned j = ASR_NAMELEN;
uint8_t c = truncate == TRUNCATE ? 0 : ' ';
while (j-- && (truncate == TRUNCATE ? isspace(p[j]) : !p[j]))
@@ -220,12 +222,13 @@
static int read_extended(struct lib_context *lc, struct dev_info *di,
struct asr *asr)
{
- unsigned int remaining, i, chk;
+ 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, asr->rt, ASR_DISK_BLOCK_SIZE,
+ if (!read_file(lc, handler, di->path, rt, ASR_DISK_BLOCK_SIZE,
(uint64_t) asr->rb.raidtbl * ASR_DISK_BLOCK_SIZE))
LOG_ERR(lc, 0, "%s: Could not read metadata off %s",
handler, di->path);
@@ -234,25 +237,25 @@
to_cpu(asr, ASR_TABLE);
/* Is this ok? */
- if (asr->rt->ridcode != RVALID2)
+ if (rt->ridcode != RVALID2)
LOG_ERR(lc, 0, "%s: Invalid magic number in RAID table; "
"saw 0x%X, expected 0x%X on %s",
- handler, asr->rt->ridcode, RVALID2, di->path);
+ handler, rt->ridcode, RVALID2, di->path);
/* Have we a valid element count? */
- if (asr->rt->elmcnt >= asr->rt->maxelm || asr->rt->elmcnt == 0)
+ if (rt->elmcnt >= rt->maxelm || rt->elmcnt == 0)
LOG_ERR(lc, 0, "%s: Invalid RAID config table count on %s",
handler, di->path);
/* Is each element the right size? */
- if (asr->rt->elmsize != sizeof(*asr->rt->ent))
+ if (rt->elmsize != sizeof(*rt->ent))
LOG_ERR(lc, 0, "%s: Wrong RAID config line size on %s",
handler, di->path);
/* Figure out how much else we need to read. */
- if (asr->rt->elmcnt > ASR_TBLELMCNT) {
- remaining = asr->rt->elmsize * (asr->rt->elmcnt - 7);
- if (!read_file(lc, handler, di->path, asr->rt->ent + 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) *
ASR_DISK_BLOCK_SIZE))
return 0;
@@ -260,14 +263,16 @@
to_cpu(asr, ASR_EXTTABLE);
}
- chk = compute_checksum(asr);
- if (chk != asr->rt->rchksum)
- LOG_ERR(lc, 0,"%s: Invalid RAID config table checksum "
- "(0x%X vs. 0x%X) on %s",
- handler, chk, asr->rt->rchksum, di->path);
+ /* Checksum only valid for raid table version 1. */
+ 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",
+ handler, chk, rt->rchksum, di->path);
+ }
/* Process the name of each line of the config line. */
- for (i = 0; i < asr->rt->elmcnt; i++) {
+ for (i = 0; i < rt->elmcnt; i++) {
/*
* Weird quirks of the name field of the config line:
*
@@ -290,11 +295,13 @@
*
* This is nuts.
*/
- if (!asr->rt->ent[i].name)
- memcpy(asr->rt->ent[i].name, asr->rt->ent[0].name, 16);
+ if (!*rt->ent[i].name)
+ strncpy((char*) rt->ent[i].name,
+ (char*) rt->ent->name,
+ ASR_NAMELEN);
/* Now truncate trailing whitespace in the name. */
- handle_white_space(asr->rt->ent[i].name, TRUNCATE);
+ handle_white_space(rt->ent[i].name, TRUNCATE);
}
return 1;
@@ -479,11 +486,12 @@
static int find_toplevel(struct lib_context *lc, struct asr *asr)
{
int i, toplevel = -1;
+ struct asr_raidtable *rt = asr->rt;
- for (i = 0; i < asr->rt->elmcnt; i++) {
- if (asr->rt->ent[i].raidlevel == FWL)
+ for (i = 0; i < rt->elmcnt; i++) {
+ if (rt->ent[i].raidlevel == FWL)
toplevel = i;
- else if (asr->rt->ent[i].raidlevel == FWL_2) {
+ else if (rt->ent[i].raidlevel == FWL_2) {
toplevel = i;
break;
}
@@ -499,13 +507,14 @@
static struct asr_raid_configline *find_logical(struct asr *asr)
{
int i, j;
+ struct asr_raidtable *rt = asr->rt;
/* This MUST be done backwards! */
- for (i = asr->rt->elmcnt - 1; i > -1; i--) {
- if (asr->rt->ent[i].raidmagic == asr->rb.drivemagic) {
+ for (i = rt->elmcnt - 1; i > -1; i--) {
+ if (rt->ent[i].raidmagic == asr->rb.drivemagic) {
for (j = i - 1; j > -1; j--) {
- if (asr->rt->ent[j].raidlevel == FWL)
- return asr->rt->ent + j;
+ if (rt->ent[j].raidlevel == FWL)
+ return rt->ent + j;
}
}
}
@@ -526,7 +535,7 @@
/* Wrapper for name() */
static char *js_name(struct lib_context *lc, struct raid_dev *rd,
- unsigned int subset)
+ unsigned subset)
{
return name(lc, META(rd, asr));
}
@@ -694,10 +703,11 @@
static void delete_configline(struct asr *asr, int index)
{
struct asr_raid_configline *cl, *end;
+ struct asr_raidtable *rt = asr->rt;
- asr->rt->elmcnt--;
- cl = asr->rt->ent + index;
- end = asr->rt->ent + asr->rt->elmcnt;
+ rt->elmcnt--;
+ cl = rt->ent + index;
+ end = rt->ent + rt->elmcnt;
while (cl < end) {
memcpy(cl, cl + 1, sizeof(*cl));
++cl;
@@ -707,19 +717,19 @@
/* 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)
{
- struct asr *asr;
+ struct asr_raidtable *rt;
struct raid_dev *device, *newest = NULL;
uint16_t newest_raidseq = 0;
int i;
list_for_each_entry(device, &rs->devs, devs) {
- asr = META(device, asr);
+ rt = META(device, asr)->rt;
// FIXME: We should be able to assume each configline
// in a single drive has the same raidseq as the rest
// in that drive. We're doing too much work here.
- for (i = 0; i < asr->rt->elmcnt; ++i) {
- if (asr->rt->ent[i].raidseq >= newest_raidseq) {
- newest_raidseq = asr->rt->ent[i].raidseq;
+ for (i = 0; i < rt->elmcnt; i++) {
+ if (rt->ent[i].raidseq >= newest_raidseq) {
+ newest_raidseq = rt->ent[i].raidseq;
newest = device;
}
}
@@ -830,24 +840,25 @@
static int create_configline(struct raid_set *rs, struct asr *asr,
struct asr *a, struct raid_dev* newest)
{
- if (asr->rt->elmcnt >= RCTBL_MAX_ENTRIES) {
- return 0;
- }
-
- struct asr *newest_asr;
+ struct asr *newest_asr = META(newest, asr);
struct asr_raid_configline *cl;
- newest_asr = META(newest, asr);
+ if (asr->rt->elmcnt >= RCTBL_MAX_ENTRIES)
+ return 0;
cl = asr->rt->ent + asr->rt->elmcnt;
asr->rt->elmcnt++;
- /* Use first raidseq, below: FIXME - don't assume all CLS are
- * consistent */
+ /*
+ * Use first raidseq, below: FIXME - don't
+ * assume all CLS are consistent.
+ */
cl->raidmagic = a->rb.drivemagic;
cl->raidseq = newest_asr->rt->ent[0].raidseq;
cl->strpsize = newest_asr->rt->ent[0].strpsize;
- strcpy((char*) cl->name, &rs->name[4]); /* starts after "asr_" */
+
+ /* Starts after "asr_" */
+ strcpy((char*) cl->name, &rs->name[sizeof(HANDLER)]);
cl->raidcnt = 0;
/* Convert rs->type to an ASR_RAID type for the CL */
@@ -875,12 +886,13 @@
struct asr_raid_configline *cl;
struct raid_dev *d, *newest;
struct asr *a;
+ struct asr_raidtable *rt = asr->rt;
/* Find the raid set */
rs = get_raid_set(lc, rd);
if (!rs) {
/* Array-less disks ... have no CLs ? */
- asr->rt->elmcnt = 0;
+ rt->elmcnt = 0;
return 1;
}
@@ -901,14 +913,14 @@
struct asr *newest_asr = META(newest, asr);
/* copy entire table from newest drive */
- asr->rt->elmcnt = newest_asr->rt->elmcnt;
- memcpy(asr->rt->ent, newest_asr->rt->ent,
- asr->rt->elmcnt * sizeof(*asr->rt->ent));
+ rt->elmcnt = newest_asr->rt->elmcnt;
+ memcpy(rt->ent, newest_asr->rt->ent,
+ rt->elmcnt * sizeof(*rt->ent));
}
/* Increment the top level CL's raid count */
/* Fixme: What about the the FWLs in a FWL2 setting? */
- cl = asr->rt->ent + find_toplevel(lc, asr);
+ cl = rt->ent + find_toplevel(lc, asr);
cl->raidseq++;
/* For each disk in the rs */
@@ -977,7 +989,7 @@
*/
/* Retrieve the number of devices that should be in this set. */
-static unsigned int 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));
@@ -1052,10 +1064,10 @@
/* Dump a raid config table */
static void dump_rt(struct lib_context *lc, struct asr_raidtable *rt)
{
- unsigned int i;
+ unsigned i;
DP("ridcode:\t\t\t0x%X", rt, rt->ridcode);
- DP("table ver:\t\t%d", rt, rt->rversion);
+ DP("rversion:\t\t%d", rt, rt->rversion);
DP("max configs:\t\t%d", rt, rt->maxelm);
DP("configs:\t\t\t%d", rt, rt->elmcnt);
DP("config sz:\t\t%d", rt, rt->elmsize);
@@ -1124,7 +1136,6 @@
if (!cl)
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;
--- dmraid/lib/format/ataraid/isw.c 2008/02/22 17:04:35 1.2
+++ dmraid/lib/format/ataraid/isw.c 2008/04/02 13:35:31 1.3
@@ -364,21 +364,26 @@
{
int ret;
struct isw *isw = META(rd, isw);
+ int large = div_up(isw->mpb_size, ISW_DISK_BLOCK_SIZE) > 1;
to_disk(isw, FULL);
- /*
- * 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;
+ 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;
+ }
ret = write_metadata(lc, handler, rd, -1, erase);
/* Correct metadata area pointer. */
- rd->meta_areas->area -= ISW_DISK_BLOCK_SIZE;
+ if (large)
+ rd->meta_areas->area -= ISW_DISK_BLOCK_SIZE;
to_cpu(isw, FULL);
@@ -504,7 +509,7 @@
/* Add an Intel SW RAID device to a set */
static struct raid_set *isw_group(struct lib_context *lc,
- struct raid_dev *rd_meta)
+ struct raid_dev *rd_meta)
{
struct raid_set *rs_group;
@@ -744,7 +749,7 @@
static struct dmraid_format isw_format = {
.name = HANDLER,
.descr = "Intel Software RAID",
- .caps = "0,1",
+ .caps = "0,1,5",
.format = FMT_RAID,
.read = isw_read,
.write = isw_write,
--- dmraid/lib/format/ataraid/jm.c 2008/02/22 17:04:35 1.2
+++ dmraid/lib/format/ataraid/jm.c 2008/04/02 13:35:31 1.3
@@ -1,8 +1,8 @@
/*
* JMicron metadata format handler.
*
- * Copyright (C) 2006 Heinz Mauelshagen, Red Hat GmbH.
- * All rights reserved.
+ * Copyright (C) 2006,2007 Heinz Mauelshagen, Red Hat GmbH.
+ * All rights reserved.
*
* See file LICENSE at the top of this source tree for license information.
*/
@@ -25,25 +25,27 @@
static char *name(struct lib_context *lc, struct raid_dev *rd,
unsigned int subset)
{
+ int i;
size_t len;
struct jm *jm = META(rd, jm);
- char buf[2], *ret, *name = (char *) jm->name;
+ char buf[JM_NAME_LEN + 1], *ret, *name = (char *) jm->name;
- /* Name always 0 terminated ? */
- if ((len = strlen(name)) > JM_NAME_LEN)
- len = JM_NAME_LEN;
-
- len += sizeof(HANDLER) + 2;
- if (jm->mode == JM_T_RAID01)
- len++;
+ /* Name always 0 terminated or whitespace at end ? */
+ strncpy(buf, name, JM_NAME_LEN);
+ len = strlen(buf);
+ i = len < JM_NAME_LEN ? len : JM_NAME_LEN;
+ buf[i] = 0;
+ while (i-- && isspace(buf[i]))
+ buf[i] = 0;
+ len = strlen(buf) + sizeof(HANDLER) + (jm->mode == JM_T_RAID01 ? 3 : 2);
if ((ret = dbg_malloc(len))) {
if (jm->mode == JM_T_RAID01 && subset)
sprintf(buf, "-%u", member(jm) / 2);
else
*buf = 0;
- sprintf(ret, "%s_%s%s", HANDLER, name, buf);
+ sprintf(ret, "%s_%s%s", handler, name, buf);
}
return ret;
--- dmraid/lib/format/ataraid/lsi.c 2008/02/22 17:04:35 1.2
+++ dmraid/lib/format/ataraid/lsi.c 2008/04/02 13:35:31 1.3
@@ -179,6 +179,10 @@
{
struct lsi *lsi = META(rd, lsi);
+ /* Refuse to add drives that are not online */
+ if (get_disk(lsi)->offline)
+ return 0;
+
if (!init_raid_set(lc, rs, rd, lsi->stride, type(lsi), handler))
return 0;
@@ -300,8 +304,8 @@
i, disk->disk_number);
P("disks[%u].set_number: %u", lsi, disk->set_number,
i, disk->set_number);
- P("disks[%u].unknown1: %u, 0x%u", lsi, disk->unknown1,
- i, disk->unknown1, disk->unknown1);
+ P("disks[%u].unknown1: %lu, 0x%lX", lsi, disk->unknown1,
+ i, (uint64_t) disk->unknown1, (uint64_t) disk->unknown1);
}
DP("disk_number: %u", lsi, lsi->disk_number);
--- dmraid/lib/format/ataraid/lsi.h 2008/02/22 16:57:36 1.1
+++ dmraid/lib/format/ataraid/lsi.h 2008/04/02 13:35:31 1.2
@@ -28,7 +28,8 @@
uint16_t magic_1;
uint8_t disk_number;
uint8_t set_number;
- uint8_t unknown1[8];
+ uint8_t offline;
+ uint8_t unknown1[7];
} __attribute__ ((packed));
struct lsi {
@@ -47,8 +48,10 @@
uint8_t dummy4; /* 0x11 */
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 */
+
#define LSI_DISK(lsi) (lsi->set_number * 2 + lsi->disk_number)
#define LSI_MAGIC_0(lsi) (lsi->disks[LSI_DISK(lsi)].magic_0)
#define LSI_MAGIC_1(lsi) (lsi->disks[LSI_DISK(lsi)].magic_1)
--- dmraid/lib/format/ataraid/nv.c 2008/02/22 17:04:35 1.2
+++ dmraid/lib/format/ataraid/nv.c 2008/04/02 13:35:31 1.3
@@ -155,7 +155,7 @@
CVT32(nv->unitFlags);
CVT32(array->version);
- while (i--);
+ while (i--)
CVT32(array->signature[i]);
CVT32(array->raidLevel);
--- dmraid/lib/format/ataraid/pdc.c 2008/02/22 17:06:00 1.3
+++ dmraid/lib/format/ataraid/pdc.c 2008/04/02 13:35:31 1.4
@@ -1,7 +1,7 @@
/*
* Promise FastTrak 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.
@@ -27,26 +27,25 @@
/*
* Make up Promise RAID device name.
*/
-static unsigned int 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 raid_dev *rd,
- unsigned int subset)
+static char *_name(struct lib_context *lc, struct pdc *pdc,
+ unsigned subset)
{
- struct pdc *pdc = META(rd, pdc);
size_t len;
char *ret = NULL;
- if ((ret = dbg_malloc((len = _name(pdc, ret, 0, subset) + 1)))) {
- _name(pdc, ret, len, subset);
+ if ((ret = dbg_malloc((len = __name(pdc, ret, 0, subset) + 1)))) {
+ __name(pdc, ret, len, subset);
mk_alpha(lc, ret + HANDLER_LEN,
len - HANDLER_LEN - (subset ? 2 : 0));
} else
@@ -55,6 +54,12 @@
return ret;
}
+static char *name(struct lib_context *lc, struct raid_dev *rd,
+ unsigned subset)
+{
+ return _name(lc, META(rd, pdc), subset);
+}
+
/*
* Retrieve status of device.
*
@@ -87,13 +92,13 @@
if (is_raid10(pdc))
pdc->raid.type = PDC_T_RAID10;
- return rd_type(types, (unsigned int) pdc->raid.type);
+ return rd_type(types, (unsigned) pdc->raid.type);
}
/* Calculate checksum on Promise metadata. */
static uint32_t checksum(struct pdc *pdc)
{
- unsigned int i = 511, sum = 0;
+ unsigned i = 511, sum = 0;
uint32_t *p = (uint32_t*) pdc;
while (i--)
@@ -133,32 +138,79 @@
}
#endif
+/* Check for Promis signature. */
+static int is_signature(struct pdc *pdc)
+{
+ 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)
{
+ struct pdc *ret;
+ unsigned ma, sub;
+ unsigned pdc_sectors_max = di->sectors - div_up(sizeof(*ret), 512);
+
/* Assume certain sectors off the end of the RAID device. */
- static unsigned int *s, sectors[] = {
+ static unsigned end_sectors[] = {
PDC_CONFIGOFFSETS, 0,
};
- struct pdc *ret;
+ /* ...or beginning of large RAID device. */
+ static unsigned begin_sectors[] = {
+ 268435377, 0,
+ };
+ unsigned *s = end_sectors;
+ uint64_t sector;
- if ((ret = alloc_private(lc, handler, sizeof(*ret)))) {
- for (s = sectors; *s; s++) {
- if (read_file(lc, handler, di->path, ret, sizeof(*ret),
- (di->sectors - *s) << 9) &&
- !strncmp((const char*) ret->promise_id, PDC_MAGIC,
- PDC_ID_LENGTH)) {
- info->u32 = *s;
- return (void*) ret;
+ if (!(ret = alloc_private(lc, handler,
+ PDC_MAX_META_AREAS * sizeof(*ret))))
+ return NULL;
+
+ info->u32 = 0;
+ sub = 1;
+ do {
+ /* 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 &&
+ sector <= pdc_sectors_max;
+ ma++, sector += PDC_META_OFFSET) {
+ if (read_file(lc, handler, di->path,
+ ret + ma, sizeof(*ret),
+ sector << 9)) {
+ /* No signature? */
+ if (!is_signature(ret + ma)) {
+ if (info->u32)
+ goto out;
+ else
+ break;
+
+ /* Memorize main metadata sector. */
+ } else if (!info->u32)
+ info->u32 = *s;
+ }
}
}
+ /* Retry relative to beginning of device if none... */
+ if (!info->u32)
+ s = begin_sectors;
+ } while (!info->u32 && sub--);
+
+ out:
+ /* No metadata signature(s) found. */
+ if (!info->u32) {
dbg_free(ret);
+ ret = NULL;
}
- return NULL;
+ return ret;
}
/* Magic check. */
@@ -224,7 +276,7 @@
/*
* Group the RAID disk into a Promise set.
*/
-static unsigned int stride(struct pdc *pdc)
+static unsigned stride(struct pdc *pdc)
{
return pdc->raid.raid0_shift ? 1 << pdc->raid.raid0_shift : 0;
}
@@ -235,12 +287,85 @@
super->stride = stride(META((private), pdc));
}
-/* 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)
+/* Calculate RAID device size in sectors depending on RAID type. */
+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);
+
+ case PDC_T_RAID1:
+ return pdc->raid.total_secs;
+
+ case PDC_T_RAID0:
+ return pdc->raid.total_secs / pdc->raid.total_disks;
+
+ case PDC_T_SPAN:
+ 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)
+{
+ struct raid_dev *r;
+
+ if (!is_pdc(lc, rd->di, pdc) ||
+ !(r = alloc_raid_dev(lc, handler)))
+ return NULL;
+
+ if ((r->type = type(pdc)) == t_undef) {
+ log_err(lc, "%s: RAID type %u not supported",
+ handler, (unsigned) pdc->raid.type);
+ goto bad_free;
+ }
+
+ if (!(r->name = _name(lc, pdc, is_raid10(pdc))))
+ goto bad_free;
+
+ /* Allocate meta_areas for devices() to work. */
+ if (!(r->meta_areas = alloc_meta_areas(lc, r, handler, 1)))
+ goto bad_free;
+
+ /* Allocate private metadata area so that free_raid_dev() succeeds. */
+ r->meta_areas->area = alloc_private(lc, handler, sizeof(*pdc));
+ if (!r->meta_areas->area)
+ goto bad_free;
+
+ memcpy(r->meta_areas->area, pdc, sizeof(*pdc));
+ r->meta_areas->size = sizeof(*pdc);
+ r->meta_areas->offset = rd->meta_areas->offset + idx * PDC_META_OFFSET;
+
+ r->di = rd->di;
+ r->fmt = rd->fmt;
+ r->status = status(pdc);
+
+ /*
+ * Type needs to be set before sectors(), because we need
+ * to set the RAID10 type used there!
+ */
+ r->type = type(pdc);
+
+ r->offset = pdc->raid.start;
+ if ((r->sectors = sectors(r, 0)))
+ goto out;
+
+ log_zero_sectors(lc, r->di->path, handler);
+
+ bad_free:
+ free_raid_dev(lc, &r);
+ 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)
+{
if (!init_raid_set(lc, rs, rd, stride(pdc), pdc->raid.type, handler))
return 0;
@@ -271,6 +396,52 @@
return 1;
}
+static inline unsigned count_meta_areas(struct pdc *pdc)
+{
+ unsigned r;
+
+ /* Count metadata signatures discovered by pdc_read_metadata(). */
+ for (r = 0; r < PDC_MAX_META_AREAS; r++) {
+ if (!is_signature(pdc + r))
+ break;
+ }
+
+ return r;
+}
+
+/* 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)
+{
+ int r;
+ struct pdc *pdc = META(rd, pdc);
+ unsigned idx = 0, ma = count_meta_areas(pdc);
+ struct raid_dev *rd_tmp;
+ struct raid_set *rs_tmp;
+
+
+ /* Group the one we already have. */
+ r = _group_rd(lc, rs, ss, rd, META(rd, pdc));
+
+ /* Group any additional ones. */
+ while (r && --ma) {
+ if (!(rd_tmp = _create_rd(lc, rd, ++pdc, ++idx)))
+ return 0;
+
+ if (!(rs_tmp = find_or_alloc_raid_set(lc, rd_tmp->name,
+ FIND_ALL, rd_tmp,
+ NO_LIST, NO_CREATE,
+ NO_CREATE_ARG))) {
+ free_raid_dev(lc, &rd_tmp);
+ return 0;
+ }
+
+ r = _group_rd(lc, rs_tmp, ss, rd_tmp, pdc);
+ }
+
+ return r;
+}
+
static struct raid_set *pdc_group(struct lib_context *lc, struct raid_dev *rd)
{
struct raid_set *rs, *ss = NULL;
@@ -290,7 +461,7 @@
*
* FIXME: more sanity checks.
*/
-static unsigned int devices(struct raid_dev *rd, void *context)
+static unsigned devices(struct raid_dev *rd, void *context)
{
struct pdc *pdc = META(rd, pdc);
@@ -344,30 +515,38 @@
#ifdef DMRAID_NATIVE_LOG
/* Log native information about a Promise RAID device. */
-static void pdc_log(struct lib_context *lc, struct raid_dev *rd)
+static void _pdc_log(struct lib_context *lc, struct dev_info *di,
+ struct pdc *pdc)
{
- unsigned int i;
- struct pdc *pdc = META(rd, pdc);
+ unsigned i;
struct pdc_disk *disk;
- log_print(lc, "%s (%s):", rd->di->path, handler);
+ log_print(lc, "%s (%s):", di->path, handler);
DP("promise_id: \"%s\"", pdc, pdc->promise_id);
- DP("unknown_0: 0x%x", pdc, pdc->unknown_0);
+ P("unknown_0: 0x%x %u",
+ pdc, pdc->unknown_0, pdc->unknown_0, pdc->unknown_0);
DP("magic_0: 0x%x", pdc, pdc->magic_0);
- DP("unknown_1: 0x%x", pdc, pdc->unknown_1);
+ P("unknown_1: 0x%x %u",
+ pdc, pdc->unknown_1, pdc->unknown_1, pdc->unknown_1);
DP("magic_1: 0x%x", pdc, pdc->magic_1);
- DP("unknown_2: 0x%x", pdc, pdc->unknown_2);
+ P("unknown_2: 0x%x %u",
+ pdc, pdc->unknown_2, pdc->unknown_2, pdc->unknown_2);
DP("raid.flags: 0x%x", pdc, pdc->raid.flags);
- DP("raid.unknown_0: 0x%x", pdc, pdc->raid.unknown_0);
+ P("raid.unknown_0: 0x%x %d",
+ pdc, pdc->raid.unknown_0, pdc->raid.unknown_0, pdc->raid.unknown_0);
DP("raid.disk_number: %u", pdc, pdc->raid.disk_number);
DP("raid.channel: %u", pdc, pdc->raid.channel);
DP("raid.device: %u", pdc, pdc->raid.device);
DP("raid.magic_0: 0x%x", pdc, pdc->raid.magic_0);
- DP("raid.unknown_1: 0x%x", pdc, pdc->raid.unknown_1);
- DP("raid.unknown_2: 0x%x", pdc, pdc->raid.unknown_2);
+ P("raid.unknown_1: 0x%x %u",
+ 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);
- DP("raid.unknown_3: 0x%x", pdc, pdc->raid.unknown_3);
- DP("raid.unknown_4: 0x%x", pdc, pdc->raid.unknown_4);
+ P("raid.unknown_3: 0x%x %u",
+ pdc, pdc->raid.unknown_3, pdc->raid.unknown_3, pdc->raid.unknown_3);
+ P("raid.unknown_4: 0x%x %u",
+ pdc, pdc->raid.unknown_4, pdc->raid.unknown_4, pdc->raid.unknown_4);
DP("raid.status: 0x%x", pdc, pdc->raid.status);
DP("raid.type: 0x%x", pdc, pdc->raid.type);
DP("raid.total_disks: %u", pdc, pdc->raid.total_disks);
@@ -379,7 +558,8 @@
DP("raid.heads: %u", pdc, pdc->raid.heads);
DP("raid.sectors: %u", pdc, pdc->raid.sectors);
DP("raid.magic_1: 0x%x", pdc, pdc->raid.magic_1);
- DP("raid.unknown_5: 0x%x", pdc, pdc->raid.unknown_5);
+ P("raid.unknown_5: 0x%x %u",
+ 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;
@@ -394,6 +574,11 @@
P("checksum: 0x%x %s", pdc, pdc->checksum, pdc->checksum,
checksum(pdc) ? "Ok" : "BAD");
}
+
+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 = {
@@ -417,33 +602,11 @@
return register_format_handler(lc, &pdc_format);
}
-/* Calculate RAID device size in sectors depending on RAID type. */
-static uint64_t sectors(struct raid_dev *rd, unsigned int 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);
-
- case PDC_T_RAID1:
- return pdc->raid.total_secs;
-
- case PDC_T_RAID0:
- return pdc->raid.total_secs / pdc->raid.total_disks;
-
- case PDC_T_SPAN:
- return rd->di->sectors - meta_sector;
- }
-
- return 0;
-}
-
/* 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)
{
- unsigned int meta_sector;
+ unsigned meta_sector;
struct pdc *pdc = meta;
if (!checksum(pdc))
@@ -455,21 +618,21 @@
meta_sector = info->u32;
rd->meta_areas->offset = di->sectors - meta_sector;
rd->meta_areas->size = sizeof(*pdc);
- rd->meta_areas->area = (void*) pdc;
+ rd->meta_areas->area = pdc;
rd->di = di;
rd->fmt = &pdc_format;
-
rd->status = status(pdc);
+
/*
* Type needs to be set before sectors(), because we need
* to set the RAID10 type used there!
*/
- rd->type = type(pdc);
+ rd->type = type(pdc);
rd->offset = PDC_DATAOFFSET;
if (!(rd->sectors = sectors(rd, meta_sector)))
return log_zero_sectors(lc, di->path, handler);
- return (rd->name = name(lc, rd, is_raid10(pdc))) ? 1 : 0;
+ return (rd->name = _name(lc, pdc, is_raid10(pdc))) ? 1 : 0;
}
--- dmraid/lib/format/ataraid/pdc.h 2008/02/22 16:57:36 1.1
+++ dmraid/lib/format/ataraid/pdc.h 2008/04/02 13:35:31 1.2
@@ -13,9 +13,16 @@
#include <stdint.h>
-#define PDC_CONFIGOFFSETS 63,255,256,16,399,735
+#define PDC_CONFIGOFFSETS 63,255,256,16,399,675,735,974,991
#define PDC_DATAOFFSET 0
+/*
+ * Maximum metadata areas checked for and offset of
+ * those relative to PDC_CONFIGOFFSETS value in sectors.
+ */
+#define PDC_MAX_META_AREAS 4
+#define PDC_META_OFFSET 14
+
/* Ondisk metadata for Promise Fastrack */
struct pdc {
#define PDC_ID_LENGTH 24
@@ -36,7 +43,8 @@
uint8_t device; /* 0x207 */
uint32_t magic_0; /* 0x208 - 0x20B */
uint32_t unknown_1; /* 0x20C - 0x20F */
- uint32_t unknown_2; /* 0x210 - 0x213 */
+ // 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 */
--- dmraid/lib/format/ddf/ddf1.c 2008/02/22 17:06:54 1.2
+++ dmraid/lib/format/ddf/ddf1.c 2008/04/02 13:35:31 1.3
@@ -19,6 +19,18 @@
#include "ddf1_cvt.h"
#include "ddf1_dump.h"
+#define GRP_RD(rd) \
+ (((struct ddf1_group_info *) (rd)->private.ptr)->rd_group)
+
+/*
+ * Helper struct to squirrel a group set reference to the check method
+ * in order to avoid, that premature deallocation in metadata.c
+ * removes the group set.
+ */
+struct ddf1_group_info {
+ struct raid_dev *rd_group;
+};
+
static const char *handler = HANDLER;
#define DDF1_SPARES ".ddf1_spares"
@@ -595,8 +607,10 @@
/* Sort DDF1 devices by offset entry within a RAID set. */
static int dev_sort(struct list_head *pos, struct list_head *new)
{
- return compose_id(META(RD(new)->private.ptr, ddf1), RD(new)) <
- compose_id(META(RD(pos)->private.ptr, ddf1), RD(pos));
+ 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);
}
/*
@@ -705,6 +719,7 @@
struct raid_dev *rd;
struct ddf1_config_record *cr;
struct ddf1_phys_drive *pd;
+ struct ddf1_group_info *gi;
unsigned int devs, i;
if (!(pd = get_phys_drive(ddf1)))
@@ -746,8 +761,14 @@
return NULL;
}
+ if (!(gi = alloc_private(lc, handler, sizeof(*gi)))) {
+ free_raid_dev(lc, &rd);
+ return NULL;
+ }
+
/* Keep reference to the entire device for ddf1_check() */
- rd->private.ptr = rd_group;
+ rd->private.ptr = gi;
+ GRP_RD(rd) = rd_group;
/* Add rest of subset state */
rs->stride = stride(cr);
@@ -825,13 +846,8 @@
{
/* Get the logical drive */
struct ddf1_config_record *cr =
- get_this_config(META(rd->private.ptr, ddf1), rd->offset);
+ get_this_config(META(GRP_RD(rd), ddf1), rd->offset);
- /*
- * Release reference after check, so that core
- * doesn't try to free it multiple times.
- */
- rd->private.ptr = NULL;
return cr ? cr->primary_element_count : 0;
}
--- dmraid/lib/format/ddf/ddf1_crc.c 2008/02/22 17:06:54 1.2
+++ dmraid/lib/format/ddf/ddf1_crc.c 2008/04/02 13:35:31 1.3
@@ -16,6 +16,7 @@
#include "ddf1.h"
#include "ddf1_crc.h"
#include "ddf1_lib.h"
+#include "zlib.h"
#define DM_BYTEORDER_SWAB
#include <datastruct/byteorder.h>
--- dmraid/lib/format/partition/dos.c 2008/02/22 17:04:36 1.2
+++ dmraid/lib/format/partition/dos.c 2008/04/02 13:35:31 1.3
@@ -29,8 +29,11 @@
unsigned short partition, char *str, size_t len,
unsigned char type)
{
- return snprintf(str, len, type ? "%s%u" : "%s",
- get_basename(lc, rd->di->path), partition);
+ 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);
}
static char *name(struct lib_context *lc, struct raid_dev *rd,
--- dmraid/lib/metadata/metadata.c 2008/02/22 17:06:00 1.3
+++ dmraid/lib/metadata/metadata.c 2008/04/02 13:35:31 1.4
@@ -799,8 +799,21 @@
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\"",
rs->name);
+
+ /*
+ * ddf1 carries a private pointer to it's contianing
+ * set which is cleared as part of the check. So we
+ * must call it's check method before freeing the
+ * set. Whats more, it looks like ddf1 check can
+ * only be called once, yoweee !!!!
+ */
+ if (fmt)
+ fmt->check(lc, rs);
+
free_raid_set(lc, rs);
}
}
@@ -838,6 +851,7 @@
struct dmraid_format *fmt;
list_for_each_safe(elem, tmp, LC_RS(lc)) {
+ /* Some metadata format handlers may not have a check method. */
if (!(fmt = get_format((rs = RS(elem)))))
continue;
@@ -864,11 +878,13 @@
{
struct raid_dev *rd;
struct raid_set *rs;
+ struct list_head *elem, *tmp;
if (name && find_set(lc, NULL, name, FIND_TOP))
LOG_ERR(lc, 0, "RAID set %s already exists", name);
- list_for_each_entry(rd, LC_RD(lc), list) {
+ list_for_each_safe(elem, tmp, LC_RD(lc)) {
+ rd = list_entry(elem, struct raid_dev, list);
/* FIXME: optimize dropping of unwanted RAID sets. */
if ((rs = dmraid_group(lc, rd))) {
log_notice(lc, "added %s to RAID set \"%s\"",
@@ -1039,22 +1055,20 @@
* 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, char *path,
- const char *suffix, const char *handler)
+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.%s",
- get_basename(lc, path), handler, suffix) + 1;
+ return snprintf(str, len, "%s.%s",
+ get_basename(lc, (char*) path), suffix) + 1;
}
-static char *_name(struct lib_context *lc, char *path,
- const char *suffix, const char *handler)
+static char *_name(struct lib_context *lc, const char *path, const char *suffix)
{
size_t len;
char *ret;
- if ((ret = dbg_malloc((len = __name(lc, NULL, 0, path,
- suffix, handler)))))
- __name(lc, ret, len, path, suffix, handler);
+ if ((ret = dbg_malloc((len = __name(lc, NULL, 0, path, suffix)))))
+ __name(lc, ret, len, path, suffix);
else
log_alloc_err(lc, __func__);
@@ -1067,7 +1081,7 @@
int ret = 0;
char *name;
- if ((name = _name(lc, path, "dat", handler))) {
+ if ((name = _name(lc, path, "dat"))) {
log_notice(lc, "writing metadata file \"%s\"", name);
ret = write_file(lc, handler, name, data, size, 0);
dbg_free(name);
@@ -1081,25 +1095,64 @@
{
char *name, s_number[32];
- if ((name = _name(lc, path, suffix, handler))) {
+ 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);
+ "%" PRIu64 "\n", number), 0);
dbg_free(name);
}
}
+static int _chdir(struct lib_context *lc, const char *dir)
+{
+ if (chdir(dir)) {
+ log_err(lc, "changing directory to %s", dir);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static char *_dir(struct lib_context *lc, const char *handler)
+{
+ char *dir = _name(lc, lc->cmd, handler);
+
+ if (!dir) {
+ log_err(lc, "allocating directory name for %s", handler);
+ return NULL;
+ }
+
+ if (!mk_dir(lc, dir))
+ goto out;
+
+ if (!_chdir(lc, dir))
+ return dir;
+
+ out:
+ dbg_free(dir);
+ return NULL;
+}
+
/*
* File vendor RAID metadata.
*/
void file_metadata(struct lib_context *lc, const char *handler,
char *path, void *data, size_t size, uint64_t offset)
{
- if (OPT_DUMP(lc) &&
- file_data(lc, handler, path, data, size))
- file_number(lc, handler, path, offset, "offset");
+ if (OPT_DUMP(lc)) {
+ char *dir = _dir(lc, handler);
+
+ if (dir)
+ dbg_free(dir);
+ else
+ return;
+
+ if (file_data(lc, handler, path, data, size))
+ file_number(lc, handler, path, offset, "offset");
+
+ _chdir(lc, "..");
+ }
}
/*
@@ -1108,6 +1161,15 @@
void file_dev_size(struct lib_context *lc, const char *handler,
struct dev_info *di)
{
- if (OPT_DUMP(lc))
+ if (OPT_DUMP(lc)) {
+ char *dir = _dir(lc, handler);
+
+ if (dir)
+ dbg_free(dir);
+ else
+ return;
+
file_number(lc, handler, di->path, di->sectors, "size");
+ _chdir(lc, "..");
+ }
}
--- dmraid/lib/misc/lib_context.c 2008/02/22 16:57:36 1.1
+++ dmraid/lib/misc/lib_context.c 2008/04/02 13:35:32 1.2
@@ -94,6 +94,9 @@
{
lc_inc_opt(lc, LC_SEPARATOR);
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");
}
static void init_cmd(struct lib_context *lc, void *arg)
--- dmraid/man/dmraid.8 2008/02/22 16:57:37 1.1
+++ dmraid/man/dmraid.8 2008/04/02 13:35:32 1.2
@@ -6,6 +6,7 @@
{-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]
@@ -176,6 +177,10 @@
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.
@@ -187,10 +192,11 @@
.B -D
is added to
.B -r
-the RAID metadata gets dumped into files named devicename_formatname.dat.
-The offset in sectors where the metadata is located on the device is written
-into files named devicename_formatname.offset and the size of the device
-into files named devicename_formatname.size.
+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
@@ -214,7 +220,7 @@
.br
do
.br
- dd if=$f of=/dev/${f%%_*} \\
+ dd if=$f of=/dev/${f%%.dat} \\
.br
seek=`cat ${f%%dat}offset` bs=1
.br
--- dmraid/tools/VERSION 2008/02/22 17:06:54 1.4
+++ dmraid/tools/VERSION 2008/04/02 13:35:32 1.5
@@ -1 +1 @@
-1.0.0.rc14 (2006.11.08)
+1.0.0.rc15 (2008.04.02)
--- dmraid/tools/commands.c 2008/02/22 16:57:37 1.1
+++ dmraid/tools/commands.c 2008/04/02 13:35:32 1.2
@@ -24,7 +24,7 @@
/*
* Command line options.
*/
-static char const *short_opts = "a:hip"
+static char const *short_opts = "a:hipP:"
#ifndef DMRAID_MINI
"bc::dDEf:gl"
#ifdef DMRAID_NATIVE_LOG
@@ -38,6 +38,7 @@
static struct option long_opts[] = {
{"activate", required_argument, NULL, 'a'},
{"format", required_argument, NULL, 'f'},
+ {"partchar", required_argument, NULL, 'P'},
{"no_partitions", no_argument, NULL, 'p'},
# ifndef DMRAID_MINI
{"block_devices", no_argument, NULL, 'b'},
@@ -148,6 +149,14 @@
}
#endif
+/* Check and store option for partition separator. */
+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. */
+ return lc_stralloc_opt(lc, LC_PARTCHAR, optarg) ? 1 : 0;
+}
+
/* Display help information */
static int help(struct lib_context *lc, int arg)
{
@@ -158,6 +167,7 @@
"[Early Boot Version]\n", c);
log_print(lc, "%s\t{-a|--activate} {y|n|yes|no} [-i|--ignorelocking]\n"
"\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);
@@ -168,6 +178,7 @@
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"
@@ -249,6 +260,19 @@
LC_FORMAT,
},
+ /* Partition separator. */
+ { 'P',
+ PARTCHAR,
+ ACTIVATE|DEACTIVATE,
+ FORMAT|HELP|IGNORELOCKING|SEPARATOR
+#ifndef DMRAID_MINI
+ |DBG|TEST|VERBOSE
+#endif
+ , ARGS,
+ check_part_separator,
+ 0,
+ },
+
/* Partition option. */
{ 'p',
NOPARTITIONS,
--- dmraid/tools/commands.h 2008/02/22 16:57:37 1.1
+++ dmraid/tools/commands.h 2008/04/02 13:35:32 1.2
@@ -46,6 +46,7 @@
#endif
VERSION = 0x100000,
IGNORELOCKING = 0x200000,
+ PARTCHAR = 0x400000,
};
#define ALL_FLAGS ((enum action) -1)
More information about the dm-devel
mailing list