⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arytst.c

📁 create raid tool at linux
💻 C
字号:
/* * Array Test * * Regression test utility for raidreconf * (C) 2000, by Jakob Oestergaard * * This software is licensed under the GNU Public License. * * Usage: *     arytst {-w|-r} -l <raid level, {0,1,4,5,20,30}> -c <chunksize (blocks)> -s <array size (blocks)> <dev0> <dev1> ... * A block is 1024 bytes * Array level 20 :  linear * Array level 30 : single disk * * arrays are filled with 64-bit words holding *   [gblock number : 32 bit] *   [origin level : 8 bit] *   [origin disk-chunk : 16 bit] *   [padding : 8 bit] */#define BLOCK_SIZE 1024#include "common.h"#include <popt.h>#include <stdio.h>#include <errno.h>#include <string.h>long array_size = 0;long chunk_size = 0;int array_level = -1;char opt_write = 0, opt_read = 0;char ** args = 0;struct fillword {  unsigned int block_num;  char org_level;  unsigned short org_dchunk;  char padding;};#define GBLK_SIZE 1024#define PADNUM 42void print_fillword(const struct fillword*);void init_fillword(struct fillword*, unsigned gblock, unsigned dchunk);void init_block_buf(char*, unsigned gblock, unsigned dchunk);int check_fillword(const struct fillword*, unsigned gblock, unsigned dchunk);int check_block_buf(const char*, unsigned gblock, unsigned dchunk);static void ary_progress(const char*, unsigned now, unsigned total);static void endary_progress(const char*);int write_single(void);int read_single(void);int write_raid0(void);int read_raid0(void);int main(int argc, const char** argv){    poptContext optCon;  int i;  struct poptOption optionsTable[] = {    {"write", 'w', POPT_ARG_NONE, &opt_write, 0},    {"read", 'r', POPT_ARG_NONE, &opt_read, 0},    {"level", 'l', POPT_ARG_INT, &array_level, 0},    {"chunksize", 'c', POPT_ARG_LONG, &chunk_size, 0},    {"arraysize", 's', POPT_ARG_LONG, &array_size, 0},    {0, 0, 0, 0, 0}   } ;    /*   * Parse options   */  optCon = poptGetContext("arytst", argc, argv, optionsTable, 0);  if ((i = poptGetNextOpt(optCon)) < -1) {    fprintf(stderr, "%s: %s\n", 	    poptBadOption(optCon, POPT_BADOPTION_NOALIAS),	    poptStrerror(i));    return -1;  }  args = (char **)poptGetArgs(optCon);  if(!args) {    fprintf(stderr, "No devices given\n");    return -1;  }  /*    * Make sure mandatory arguments are given   */  if(!opt_read && !opt_write) {    fprintf(stderr, "Must either read or write\n");    return -1;  }  if(opt_read && opt_write) {    fprintf(stderr, "Cannot both read and write\n");    return -1;  }  if(array_level != 0 && array_level != 30) {    fprintf(stderr, "We only know raid level 0 and 30 (single disk) for now\n");    return -1;  }  if(chunk_size <= 0) {    fprintf(stderr, "Chunk size must be specified\n");    return -1;  }  if(array_size <= 0) {    fprintf(stderr, "Array size must be specified\n");    return -1;  }  /*   * Choose action   */  if(opt_write) {    switch(array_level) {    case 0:      return write_raid0();     case 30:      return write_single();    default:      fprintf(stderr, "Unknown level\n");      return -1;    }  }  if(opt_read) {    switch(array_level) {    case 0:      return read_raid0();    case 30:      return read_single();    default:      fprintf(stderr, "Unknown level\n");      return -1;    }  }  return 0;}void print_fillword(const struct fillword* fw){  fprintf(stderr, 	  "block_num   = %u\n"	  "org_level   = %i\n"	  "org_dchunk  = %u\n"	  "padding     = %i\n",	  fw->block_num, fw->org_level,	  fw->org_dchunk, fw->padding);}void init_fillword(struct fillword* fw, unsigned gblock, unsigned dchunk){  fw->block_num = gblock;  fw->org_level = array_level;  fw->org_dchunk = dchunk;  fw->padding = PADNUM;}void init_block_buf(char* buf, unsigned gblock, unsigned dchunk){  int pos;  for(pos = 0; pos != GBLK_SIZE / sizeof(struct fillword); pos++)    init_fillword((struct fillword*)(buf + sizeof(struct fillword) * pos), gblock, dchunk);}int check_fillword(const struct fillword* fw, unsigned gblock, unsigned dchunk){  if(fw->block_num != gblock) {    fprintf(stderr, "\n*** Mismatch at gblock = %u, dchunk = %u\n", gblock, dchunk);    print_fillword(fw);    return 1;  } else if(fw->padding != PADNUM) {    fprintf(stderr, "\n*** Bad padding at gblock = %u, dchunk = %u\n", gblock, dchunk);    print_fillword(fw);    return 1;  }  return 0;}int check_block_buf(const char* buf, unsigned gblock, unsigned dchunk){  int pos;  int rc;  for(pos = 0; pos != GBLK_SIZE / sizeof(struct fillword); pos++)     if((rc = check_fillword((const struct fillword*)(buf + sizeof(struct fillword) * pos), gblock, dchunk)))      return rc;  return 0;}void ary_progress(const char* dev, unsigned now, unsigned total){  fprintf(stderr, "\r%s:  %9u/%-9u  ~%3i%%", dev, now, total, now * 100 / total);  fflush(stderr);}void endary_progress(const char* dev){  fprintf(stderr, "\r%s:  all done.                  \n", dev);}int write_single(void){  FILE * fp = 0;  unsigned blocks;  if(!args[0] || args[1]) {    fprintf(stderr, "Must have precisely one device\n");    return -1;  }  if(!(fp = fopen(args[0], "w"))) {    fprintf(stderr, "Cannot open %s for writing\n", args[0]);    return -1;  }  for(blocks = 0; blocks != array_size; blocks++) {    char buf[GBLK_SIZE];    init_block_buf(buf, blocks, blocks / chunk_size);    fwrite(buf, GBLK_SIZE, 1, fp);    ary_progress(args[0], blocks, array_size);  }  endary_progress(args[0]);  fclose(fp);  return 0;}int read_single(void){  FILE * fp = 0;  unsigned blocks;  if(!args[0] || args[1]) {    fprintf(stderr, "Must have precisely one device\n");    return -1;  }  if(!(fp = fopen(args[0], "r"))) {    fprintf(stderr, "Cannot open %s for writing\n", args[0]);    return -1;  }  for(blocks = 0; blocks != array_size; blocks++) {    char buf[GBLK_SIZE];    int rc;    if(1 != fread(buf, GBLK_SIZE, 1, fp)) {      fprintf(stderr, "\nCannot read\n");      return -1;    }    if((rc = check_block_buf(buf, blocks, blocks / chunk_size)))      return rc;    ary_progress(args[0], blocks, array_size);  }  endary_progress(args[0]);  fclose(fp);  return 0;}int write_raid0(void){  FILE * fp = 0;  unsigned blocks;  char ** cur_dev;  mdp_super_t sb;  int ndisks = 0;  int curdisk = 0;  if(!args[0]) {    fprintf(stderr, "Must have one or more devices\n");    return -1;  }  for(cur_dev = args; *cur_dev; cur_dev++)    ndisks ++;  for(cur_dev = args; *cur_dev; cur_dev++,curdisk++) {    if(!(fp = fopen(*cur_dev, "w"))) {      fprintf(stderr, "Cannot open %s for writing\n", *cur_dev);      return -1;    }        for(blocks = curdisk; blocks-curdisk < array_size; blocks += ndisks) {      char buf[GBLK_SIZE];      init_block_buf(buf, blocks, (blocks-curdisk) / chunk_size);      fwrite(buf, GBLK_SIZE, 1, fp);      ary_progress(*cur_dev, blocks, array_size);    }    endary_progress(*cur_dev);    /* Put a superblock in there too */    if(fseek(fp, 1024 * MD_NEW_SIZE_BLOCKS(array_size/ndisks), SEEK_SET)) {      fprintf(stderr, "Cannot seek to superblock position: %s\n", strerror(errno));      return -1;    } else fprintf(stderr, "Pos: %lu\n", MD_NEW_SIZE_BLOCKS(array_size/ndisks));    memset(&sb, 0, sizeof(sb));    sb.md_magic = MD_SB_MAGIC;    sb.state = (1 << MD_SB_CLEAN);    fwrite(&sb, sizeof(sb), 1, fp);    fclose(fp);  }  return 0;}int read_raid0(void){  FILE * fp = 0;  unsigned blocks;  char ** cur_dev;  int ndisks = 0;  int curdisk = 0;  if(!args[0]) {    fprintf(stderr, "Must have one or more devices\n");    return -1;  }  for(cur_dev = args; *cur_dev; cur_dev++)    ndisks ++;  for(cur_dev = args; *cur_dev; cur_dev++,curdisk++) {    unsigned dblocks_read = 0;    if(!(fp = fopen(*cur_dev, "r"))) {      fprintf(stderr, "Cannot open %s for writing\n", *cur_dev);      return -1;    }        for(blocks = curdisk; blocks-curdisk < array_size; blocks += ndisks) {      char buf[GBLK_SIZE];      int rc;      fread(buf, GBLK_SIZE, 1, fp);      dblocks_read ++;      if(dblocks_read == MD_NEW_SIZE_BLOCKS(array_size/ndisks))	break;      if((rc = check_block_buf(buf, blocks, (blocks-curdisk) / chunk_size)))	return rc;      ary_progress(*cur_dev, blocks, array_size);    }    endary_progress(*cur_dev);    fclose(fp);  }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -