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

📄 rf_ctrl.c

📁 RAIDFrame是个非常好的磁盘阵列RAID仿真工具
💻 C
字号:
/* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. * * Author: Mark Holland * * Permission to use, copy, modify and distribute this software and * its documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU *  School of Computer Science *  Carnegie Mellon University *  Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. *//* $Locker:  $ * $Log: rf_ctrl.c,v $ * Revision 1.7  1996/07/19  16:11:05  jimz * fix typing problems with access test * * Revision 1.6  1996/06/14  14:21:24  jimz * dfstrace stuff only compiled in if RF_DFSTRACE > 0 * * Revision 1.5  1996/06/05  18:06:02  jimz * Major code cleanup. The Great Renaming is now done. * Better modularity. Better typing. Fixed a bunch of * synchronization bugs. Made a lot of global stuff * per-desc or per-array. Removed dead code. * * Revision 1.4  1996/05/24  01:59:45  jimz * another checkpoint in code cleanup for release * time to sync kernel tree * * Revision 1.3  1996/05/23  21:46:35  jimz * checkpoint in code cleanup (release prep) * lots of types, function names have been fixed * * Revision 1.2  1995/12/01  15:15:03  root * added copyright info * * Revision 1.1  1995/11/29  21:55:22  wvcii * Initial revision * *//* rf_ctrl.c * * controls the kernelized raidframe by poking at it with ioctls. */#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/ioctl.h>#if RF_DFSTRACE > 0#include <sys/dfstracebuf.h>#endif /* RF_DFSTRACE > 0 */#include "rf_raidframe.h"static void DoIoctl(int fd, unsigned long which, void *arg, char *cmdstring);static void DoConfigure(int fd, char *configfile);static void bad_line(char *s);static void usage(void);static int raidID;#define RF_DEV2RAIDID(_dev)  (minor(_dev)>>6)     /* convert dev_t to raid id */#define SECTOR_SHIFT 9main(argc,argv)  int     argc;  char  **argv;{  int fd, nscanned, pctg, nomenu, nbytes;  char *devfile = "/dev/raidframe_c";  char filen[100], cmdbuf[200], hostname[256];  struct stat buf;  dev_t dev;  unsigned long devno_long;  struct rf_test_acc testacc;  struct rf_recon_req fdisk_desc;  nomenu = 0;  argc--; argv++;  while (argc && argv[0][0] == '-') {    switch(argv[0][1]) {      case 'M':        nomenu = 1;        break;      default:  fprintf(stderr,"Unknown option '%s'\n",argv[0]); usage(); exit(1);    }    argc--; argv++;  }  if (argc == 1) devfile = argv[0];  if (stat(devfile, &buf) < 0) {fprintf(stderr,"stat failure on %s\n",devfile); exit(1);}  dev = buf.st_rdev;    raidID = RF_DEV2RAIDID(dev);  printf("Working with raid device number %d\n\n",raidID);    fd = open(devfile, O_RDWR, 0644);  if (fd < 0) {    fprintf(stderr,"Unable to open raidframe device file\n");    perror("open");    exit(1);  }  while (1) {    if (!nomenu) {    printf("c [cfgfile]-- Configure from cfgfile (/dev/.rfconfigN if none)\n");    printf("s          -- Shutdown\n");    printf("r          -- Rewrite (initialize) parity\n");    printf("t dev      -- TUR through raidframe on devno 'd'\n");    printf("a r/w s n  -- Do a test read/write to sector s, numsector n\n");    printf("f r c flag -- Fail the disk at row r col c, init recon if flag non-zero\n");    printf("C          -- Do a copyback after a reconstruction\n");    printf("R r        -- Check reconstruction status on row r (default 0)\n");    printf("S d        -- Fork a sparemap daemon using sparemap directory d\n");    printf("A          -- Cause the sparemap daemon to wake up and exit\n");#if RF_DFSTRACE > 0    printf("d          -- Start the dfstrace agent and collector\n");    printf("K          -- Shutdown the dfstrace agent and collector\n");    printf("F          -- Do a dfstrace flush operation\n");    printf("n          -- Do a dfstrace newFile operation\n");    printf("T 1/0      -- Start/Stop DFS tracing of accesses\n");#endif /* RF_DFSTRACE > 0 */    printf("o          -- Reset acc_totals\n");    printf("O 1/0      -- Toggle acc_total capture\n");    printf("q          -- quit\n");    printf("\nCommand? ");    }    if (!gets(cmdbuf)) break;    switch (*cmdbuf) {    case 'o':      DoIoctl(fd, RAIDFRAME_RESET_ACCTOTALS, NULL, "reset_acctotals");      break;    case 'O':      {		char *str;		int keep;		str = strtok(cmdbuf, " \t");		str = strtok(NULL, " \t");		if (str == NULL) {			fprintf(stderr, "Must specify 1 or 0 (on or off)\n");			fflush(stderr);			break;		}		if (sscanf(str, "%d", &keep) != 1) {			fprintf(stderr, "Cannot parse \"%s\" to an integer\n", str);			fflush(stderr);			break;		}		DoIoctl(fd, RAIDFRAME_KEEP_ACCTOTALS, &keep, "keep_acctotals");      }      break;    case 'T':      nscanned = sscanf(cmdbuf,"T %d",&pctg);      if (nscanned != 1) {bad_line(cmdbuf); break;}      DoIoctl(fd, (unsigned long) ((pctg == 1) ? RAIDFRAME_START_ATRACE : RAIDFRAME_STOP_ATRACE), NULL, "atrace");      break;          case 'c':      nscanned = sscanf(cmdbuf,"c %s",filen);      /* sscanf returns EOF "if the input ends before the first conflict or conversion" */      if (nscanned == EOF) sprintf(filen,"/dev/.rfconfig%d",raidID);      else if (nscanned != 1) {bad_line(cmdbuf); break;}      DoConfigure(fd, filen);      break;          case 's':      DoIoctl(fd, (unsigned long) RAIDFRAME_SHUTDOWN, NULL, "shutdown");      break;          case 'r':      DoIoctl(fd, (unsigned long) RAIDFRAME_REWRITEPARITY, NULL, "rewrite");      break;          case 't':      if (sscanf(cmdbuf, "t 0x%lx",&devno_long) != 1) {	if (sscanf(cmdbuf, "t %ld",&devno_long) != 1) {bad_line(cmdbuf); break;}      }      DoIoctl(fd, (unsigned long) RAIDFRAME_TUR, (void *) devno_long, "TUR");      break;          case 'a': {      if (sscanf(cmdbuf, "a %c 0x%lx 0x%x",&testacc.type, &testacc.startSector, &testacc.numSector) != 3) {        if (sscanf(cmdbuf, "a %c %ld 0x%x",&testacc.type, &testacc.startSector, &testacc.numSector) != 3) {          if (sscanf(cmdbuf, "a %c 0x%lx %d",&testacc.type, &testacc.startSector, &testacc.numSector) != 3) {            if (sscanf(cmdbuf, "a %c %ld %d",&testacc.type, &testacc.startSector, &testacc.numSector) != 3) {              bad_line(cmdbuf);              break;            }          }        }      }      nbytes = testacc.numSector<<SECTOR_SHIFT;      testacc.buf = malloc(nbytes);      if (testacc.buf == NULL) {        printf("Unable to malloc %d bytes\n", nbytes);        break;      }      DoIoctl(fd, (unsigned long) RAIDFRAME_TEST_ACC, (void *) &testacc, "testacc");      free(testacc.buf);      }      break;          case 'f':      nscanned = sscanf(cmdbuf, "f %d %d %d",&fdisk_desc.row,&fdisk_desc.col,&fdisk_desc.flags);      if (nscanned != 2 && nscanned != 3) {bad_line(cmdbuf); break;}      if (nscanned == 3 && fdisk_desc.flags) fdisk_desc.flags = RF_FDFLAGS_RECON;      else fdisk_desc.flags = RF_FDFLAGS_NONE;      DoIoctl(fd, (unsigned long) RAIDFRAME_FAIL_DISK, (void *) &fdisk_desc, "fail disk");      break;    case 'R':      nscanned = sscanf(cmdbuf, "R %d", &pctg);      if (nscanned != 1 && nscanned != -1 && nscanned != 0) {bad_line(cmdbuf); break;}      if (nscanned == 0 || nscanned == -1) pctg = 0;      DoIoctl(fd, (unsigned long) RAIDFRAME_CHECKRECON, (void *) &pctg, "checkrecon");      printf("Reconstruction is %d %% complete\n",pctg);      break;	          case 'C':      DoIoctl(fd, (unsigned long) RAIDFRAME_COPYBACK, NULL, "copyback");      break;    case 'S':      nscanned = sscanf(cmdbuf,"S %s",filen);      if (nscanned <= 0) sprintf(filen,"/afs/cs/project/pdl-1/Mark/Reconstruction/lib/sparemaps");      nscanned = fork();      if (nscanned < 0) {	perror("rfctrl: fork failed\n");      } else if (nscanned == 0) {	if (execl("smd", "smd", filen, NULL)) {	  perror("rfctrl child process: exec failed");	  exit(1);	}      }      break;    case 'A':      DoIoctl(fd, (unsigned long) RAIDFRAME_ABORT_SPARET_WAIT, NULL, "spare wait abort");      break;      #if RF_DFSTRACE > 0    /* we first check the user's path for agent & collector, and if not found,     * we default to /usr/dfstrace/bin     */#define STRINGIFY(string) "string"#define DFSDIR /usr16/jimz/rfcfgs/#define DFSCONCAT(file) DFSDIR/**/file	case 'd':	  printf("starting agent and collector\n");	  nscanned = fork();	  if (nscanned < 0) {		  perror("rfctrl: fork failed\n");	  } else if (nscanned == 0) {		  if (execlp("collector", "collector", "-d", ".", "-g", "/dev/null", "-n", "-c", "0", NULL)) {			  if (execlp("DFSCONCAT(collector)", "collector", "-d", ".", "-g", "/dev/null", "-n", "-c", "0", NULL)) {				  perror("rfctrl child process: exec failed for collector");				  exit(1);			  }			  printf("started collector from %s\n", STRINGIFY(DFSDIR));		  }		  else {			  printf("started collector\n");		  }	  }	  else {		  printf("collector is pid %d\n", nscanned);	  }	  sleep(3);            /* give the collector a chance to get started */	  nscanned = fork();	  if (nscanned < 0) {		  perror("rfctrl: fork failed\n");	  } else if (nscanned == 0) {		  char dfs_traceon_val[256];		  if (gethostname(hostname, 256)) {			  perror("Unable to get host name for agent fork");			  exit(1);		  }		  sprintf(dfs_traceon_val, "%ld", (DFS_TRACE_RAIDFRAME|DFS_TRACE_SCSI|DFS_TRACE_IO|DFS_TRACE_BASIC));		  if (execlp("agent", "agent", "-l", "256", "-b3", "-h", hostname, "-c", "0", "-g", "/dev/null", NULL)) {			  if (execlp("DFSCONCAT(agent)", "agent", "-l", dfs_traceon_val, "-b3", "-h", hostname, "-c", "0", "-g", "/dev/null", NULL)) {				  perror("rfctrl child process: exec failed for agent");				  exit(1);			  }			  printf("started agent from %s\n", STRINGIFY(DFSDIR));		  }		  else {			  printf("started agent\n");		  }	  }	  else {		  printf("agent is pid %d\n", nscanned);	  }	  printf("done starting agent and collector\n");	  break;	case 'K':	  nscanned = fork();	  if (nscanned < 0) {		  perror("rfctrl: fork failed\n");	  } else if (nscanned == 0) {		  if (execlp("shutAgent", "shutAgent", NULL)) {			  if (execlp("DFSCONCAT(shutAgent)", "shutAgent", NULL)) {				  perror("rfctrl child process: exec failed for agent shutdown");				  exit(1);			  }		  }	  }	  sleep(3);            /* give the agent a chance to shut down */	  nscanned = fork();	  if (nscanned < 0) {		  perror("rfctrl: fork failed\n");	  } else if (nscanned == 0) {		  if (gethostname(hostname, 256)) {			  perror("Unable to get host name for agent fork");			  exit(1);		  }		  if (execlp("shutCollector", "shutCollector", NULL)) {			  if (execlp("DFSCONCAT(shutCollector)", "shutCollector", NULL)) {				  perror("rfctrl child process: exec failed for collector shutdown");				  exit(1);			  }		  }	  }	  break;    case 'n':      nscanned = fork();      if (nscanned < 0) {	perror("rfctrl: fork failed\n");      } else if (nscanned == 0) {	if (execlp("newFile", "newFile", NULL)) {	  if (execlp("DFSCONCAT(newFile)", "newFile", NULL)) {	    perror("rfctrl child process: exec failed for newFile");	    exit(1);	  }	}      }      break;    case 'F':      nscanned = fork();      if (nscanned < 0) {	perror("rfctrl: fork failed\n");      } else if (nscanned == 0) {	if (execlp("trflush", "trflush", NULL)) {	  if (execlp("DFSCONCAT(trflush)", "trflush", NULL)) {	    perror("rfctrl child process: exec failed for dfsflush");	    exit(1);	  }	}      }      break;#endif /* RF_DFSTRACE > 0 */    case 'q':      exit(0);    default: bad_line(cmdbuf); break;    }  }  }static void usage(){  fprintf(stderr,"Usage: rfctrl [device_file]\n");}static void bad_line(char *s){  printf("Unparse-able line: %s\n",s);}static void DoConfigure(int fd, char *configfile){  void *p;  char cmdbuf[256], namebuf[256];  int status;  RF_Config_t cfg;  if (rf_MakeConfig(configfile, &cfg) < 0) {    fprintf(stderr,"Unable to create configuration structure\n");    return;  }  /* the argument to ioctl is a pointer to the data to be copied in.   * I want only the pointer to the configuration info to be copied in,   * so I use p as an extra level of indirection   */  p = (void *) &cfg;  if (ioctl(fd, (unsigned long) RAIDFRAME_CONFIGURE, (void *) &p) < 0) {    perror("config ioctl");  } else {    sprintf(namebuf, "/dev/.rfconfig%d",raidID);    if (strcmp(configfile, namebuf)) {                        /* don't try to copy if the input file is /dev/.rfconfigX */      sprintf(cmdbuf, "cp %s /dev/.rfconfig%d",configfile,raidID);      if (system(cmdbuf)) printf("Copy to /dev/.rfconfig%d failed\n",raidID);      else printf("File %s copied to /dev/.rfconfig%d\n",configfile,raidID);    }  }}static void DoIoctl(int fd, unsigned long which, void *arg, char *cmdstring){  char errbuf[100];  if (ioctl(fd, which, arg) < 0) {    sprintf(errbuf,"%s ioctl",cmdstring);    perror(errbuf);  }}

⌨️ 快捷键说明

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