Logo Search packages:      
Sourcecode: dmraid version File versions


 * SNIA DDF1 v1.0 metadata format handler.
 * Copyright (C) 2005-2006 IBM, All rights reserved.
 * Written by Darrick Wong <djwong@us.ibm.com>
 * Copyright (C) 2006 Heinz Mauelshagen, Red Hat GmbH
 *                    All rights reserved.
 * See file LICENSE at the top of this source tree for license information.


#include "internal.h"
#include "ddf1.h"
#include "ddf1_lib.h"

/* Print DDF GUIDs. */

#define DP_BUF(name, basevar, x, len) do { \
      _dp_guid(lc, name, P_OFF(x, basevar, x), len);\
} while (0)

#define DP_GUID(name, basevar, x) do {\
_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)
      char *p;
      int i;

      p = data;
      log_print_nnl(lc, "0x%03x %s\"", offset, name);
      for (i = 0; i < len; i++)
            log_print_nnl(lc, "%c",
                        (isgraph(p[i]) || p[i] == ' ' ? p[i] : '.'));

      log_print_nnl(lc, "\" [");
      for (i = 0; i < len; i++)
            log_print_nnl(lc, "%s%02x", (i != 0 ? " " : ""), p[i] & 0xFF);

      log_print_nnl(lc, "]\n");
#define DP_BUF(name, basevar, x, len)
#define DP_GUID(name, basevar, x)

/* Dump top */
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)
      if (!dh)

      log_print(lc, "DDF1 Header at %p", dh);
      DP("signature:\t0x%X", dh, dh->signature);
      DP("crc:\t\t0x%X", dh, dh->crc);
      DP_GUID("guid:\t\t", dh, dh->guid);
      DP_BUF("rev:\t\t", dh, dh->ddf_rev, DDF1_REV_LENGTH);
      DP("seqnum:\t\t%d", dh, dh->seqnum);
      DP("timestamp:\t0x%X", dh, dh->timestamp);
      DP("open:\t\t0x%X", dh, dh->open_flag);
      DP("foreign:\t\t0x%X", dh, dh->foreign_flag);
      DP("grouping:\t\t0x%X", dh, dh->grouping_enforced);
      DP("primary header:\t%lu", dh, dh->primary_table_lba);
      DP("secondary header:\t%lu", dh, dh->secondary_table_lba);
      DP("header type:\t0x%X", dh, dh->header_type);
      DP("workspace len:\t%d", dh, dh->workspace_length);
      DP("workspace lba:\t%lu", dh, dh->workspace_lba);
      DP("max pd:\t\t%d", dh, dh->max_phys_drives);
      DP("max vd:\t\t%d", dh, dh->max_virt_drives);
      DP("max part:\t\t%d", dh, dh->max_partitions);
      DP("vd_config len:\t%d", dh, dh->vd_config_record_len);
      DP("max_primary_elts:\t%d", dh, dh->max_primary_elements);
      DP("adapter_offset:\t%d", dh, dh->adapter_data_offset);
      DP("adapter_len:\t%d", dh, dh->adapter_data_len);
      DP("pd_offset:\t%d", dh, dh->phys_drive_offset);
      DP("pd_len:\t\t%d", dh, dh->phys_drive_len);
      DP("vd_offset:\t%d", dh, dh->virt_drive_offset);
      DP("vd_len:\t\t%d", dh, dh->virt_drive_len);
      DP("config_offset:\t%d", dh, dh->config_record_offset);
      DP("config_len:\t%d", dh, dh->config_record_len);
      DP("disk_data_offset:\t%d", dh, dh->disk_data_offset);
      DP("disk_data_len:\t%d", dh, dh->disk_data_len);
      DP("badblock_offset:\t%d", dh, dh->badblock_offset);
      DP("badblock_len:\t%d", dh, dh->badblock_len);
      DP("diag_offset:\t%d", dh, dh->diag_offset);
      DP("diag_len:\t\t%d", dh, dh->diag_len);
      DP("vendor_offset:\t%d", dh, dh->vendor_offset);
      DP("vendor_len:\t%d", dh, dh->vendor_len);

static void dump_adapter(struct lib_context *lc, struct ddf1_adapter *da)
      if (!da)

      log_print(lc, "Adapter Data at %p", da);
      DP("signature:\t0x%X", da, da->signature);
      DP("crc:\t\t0x%X", da, da->crc);
      DP_GUID("guid:\t\t", da, da->guid);
      DP("pci vendor:\t0x%X", da, da->pci_vendor);
      DP("pci device:\t0x%X", da, da->pci_device);
      DP("pci subvendor:\t0x%X", da, da->pci_subvendor);
      DP("pci subdevice:\t0x%X", da, da->pci_subdevice);

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);
      DP("crc:\t\t0x%X", fg, fg->crc);
      DP_GUID("guid:\t\t", fg, fg->guid);
      DP("reference:\t\t0x%X", fg, fg->reference);
      DP("forced_ref_flag:\t%d", fg, fg->forced_ref_flag);
      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)
      log_print(lc, "Physical Drive Header at %p", pd);
      DP("signature:\t0x%X", pd, pd->signature);
      DP("crc:\t\t0x%X", pd, pd->crc);
      DP("num drives:\t%d", pd, pd->num_drives);
      DP("max drives:\t%d", pd, pd->max_drives);

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);
      DP("reference #:\t0x%X", pd, pd->reference);
      DP("type:\t\t0x%X", pd, pd->type);
      DP("state:\t\t0x%X", pd, pd->state);
      DP("size:\t\t%llu", pd, pd->size);
      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)
      log_print(lc, "Virtual Drive Header at %p", vd);
      DP("signature:\t0x%X", vd, vd->signature);
      DP("crc:\t\t0x%X", vd, vd->crc);
      DP("num drives:\t%d", vd, vd->num_drives);
      DP("max drives:\t%d", vd, vd->max_drives);

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);
      DP("vd #:\t\t0x%X", vd, vd->vd_num);
      DP("type:\t\t0x%X", vd, vd->type);
      DP("state:\t\t0x%X", vd, vd->state);
      DP("init state:\t0x%X", vd, vd->init_state);
      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)
      int i;
      uint16_t x;
      uint32_t *cfg_drive_ids;
      uint64_t *cfg_drive_offsets;
      struct ddf1_config_record *cfg = CR(ddf, idx);

      if (cfg->signature != DDF1_VD_CONFIG_REC)
            return 1;

      log_print(lc, "Virtual Drive Config Record at %p", cfg);
      DP("signature:\t0x%X", cfg, cfg->signature);
      DP("crc:\t\t0x%X", cfg, cfg->crc);
      DP_GUID("guid:\t\t", cfg, cfg->guid);
      DP("timestamp:\t0x%X", cfg, cfg->timestamp);
      DP("seqnum:\t\t%d", cfg, cfg->seqnum);
      DP("primary count:\t%d", cfg, cfg->primary_element_count);
      DP("stripe size:\t%dKiB", cfg, cfg->stripe_size);
      DP("raid level:\t%d", cfg, cfg->raid_level);
      DP("raid qualifier:\t%d", cfg, cfg->raid_qualifier);
      DP("secondary count:\t%d", cfg, cfg->secondary_element_count);
      DP("secondary number:\t%d", cfg, cfg->secondary_element_number);
      DP("secondary level:\t%d", cfg, cfg->secondary_element_raid_level);
      DP("spare 0:\t\t0x%X", cfg, cfg->spares[0]);
      DP("spare 1:\t\t0x%X", cfg, cfg->spares[1]);
      DP("spare 2:\t\t0x%X", cfg, cfg->spares[2]);
      DP("spare 3:\t\t0x%X", cfg, cfg->spares[3]);
      DP("spare 4:\t\t0x%X", cfg, cfg->spares[4]);
      DP("spare 5:\t\t0x%X", cfg, cfg->spares[5]);
      DP("spare 6:\t\t0x%X", cfg, cfg->spares[6]);
      DP("spare 7:\t\t0x%X", cfg, cfg->spares[7]);
      DP("cache policy:\t0x%X", cfg, cfg->cache_policy);
      DP("bg task rate:\t%d", cfg, cfg->bg_task_rate);
      DP("sector count:\t%llu", cfg, cfg->sectors);
      DP("size:\t\t%llu", cfg, cfg->size);
      cfg_drive_ids = CR_IDS(ddf, cfg);
      cfg_drive_offsets = CR_OFF(ddf, cfg);

      x = cfg->primary_element_count;
      log_print(lc, "Drive map:");
      for (i = 0; i < x; i++) {
            log_print(lc, "%d: %X @ %lu", i, cfg_drive_ids[i],
      return 1;

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);

      log_print(lc, "Spare Config Record at %p", sh);
      DP("signature:\t0x%X", sh, sh->signature);
      DP("crc:\t\t0x%X", sh, sh->crc);
      DP("timestamp:\t0x%X", sh, sh->timestamp);
      DP("type:\t\t0x%X", sh, sh->type);
      DP("num drives:\t%d", sh, sh->num_spares);
      DP("max drives:\t%d", sh, sh->max_spares);

      for (i = 0; i < sh->num_spares; i++) {
            log_print(lc, "Spare %d:", i);
            DP_GUID("guid:\t\t", sh, sh->spares[i].guid);
            DP("secondary:\t%d", sh, sh->spares[i].secondary_element);
      return 1;

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,
            .spare = dump_spares,

      ddf1_process_records(lc, di, &handlers, ddf1, 1);

/* Dump the entire table */
void ddf1_dump_all(struct lib_context *lc, struct dev_info *di,
               struct ddf1 *ddf1, const char *handler)
      int i;

      dump_top(lc, di, ddf1, handler);
      dump_header(lc, &ddf1->anchor);
      dump_header(lc, ddf1->primary);
      dump_header(lc, ddf1->secondary);
      dump_adapter(lc, ddf1->adapter);
      dump_disk_data(lc, ddf1->disk_data);
      dump_phys_drive_header(lc, ddf1->pd_header);
      for (i = 0; i < ddf1->pd_header->num_drives; i++)
            dump_phys_drive(lc, ddf1->pds + i);

      dump_virt_drive_header(lc, ddf1->vd_header);
      for (i = 0; i < ddf1->vd_header->num_drives; i++)
            dump_virt_drive(lc, ddf1->vds + i);

      dump_config_records(lc, di, ddf1);

#endif /* DMRAID_NATIVE_LOG */

Generated by  Doxygen 1.6.0   Back to index