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

📄 raidreconf.c

📁 create raid tool at linux
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * raidreconf.c: RAID Reconfiguration Utility, for resizing and reconfiguration *               of RAID sets. *               (C) 1999,2000 by Jakob Oestergaard * * This code is based on the mkraid.c program by Ingo Molnar and others. * * This source is covered by the GNU GPL, the same as all Linux kernel * sources. */#include "raidreconf.h"/* * The strategy is: * * 1)  Read the raidtabs * 2)  Read the superblocks, and perform some consistency checks... * 3)  Find the difference(s) between the two, and decide what to do * 4)  If possible, convert array * * TOFIX: *          Add linear and raid-5 * *          Test this on large arrays (100+GB) * *          Checkpoint file (to allow continuation without data loss *          after eg. power-surge) * */void printcfg (md_cfg_entry_t * cfg);level_driver_t *source_driver = 0, *sink_driver = 0;static int raid_reconfigure (mdu_version_t *);voidusage (void){	printf	    ("usage: raidreconf [--version] [--test] {-o <old_raidtab>|-i <import_device>}  {-n <new_raidtab>| -e<export device>} [-m <md device>]\n"	     "examples:\n" "  Resize an existing array:\n"	     "    raidreconf -o /etc/raidtab.old -n /etc/raidtab.new -m /dev/md3\n"	     "  Import data on a disk into an array:\n"	     "    raidreconf -i /dev/sda3 -n /etc/raidtab -m /dev/md3\n");}intmain (int argc, const char *argv[]){	FILE *fp = 0;	md_cfg_entry_t *p = 0;	int exit_status = 0;	int version = 0, help = 0;	char *old_raidtab = 0, *import_device = 0,	    *new_raidtab = 0, *export_device = 0, *md_device = 0;	poptContext optCon;	int i;	struct poptOption optionsTable[] = {		{"help", 'h', POPT_ARG_NONE, &help, 0},		{"version", 'V', POPT_ARG_NONE, &version, 0},		{"test", 't', POPT_ARG_NONE, &test, 0},		{"old", 'o', POPT_ARG_STRING, &old_raidtab, 0},		{"import", 'i', POPT_ARG_STRING, &import_device, 0},		{"new", 'n', POPT_ARG_STRING, &new_raidtab, 0},		{"export", 'e', POPT_ARG_STRING, &export_device, 0},		{"mddev", 'm', POPT_ARG_STRING, &md_device, 0},		{0, 0, 0, 0, 0}	};	optCon =	    poptGetContext ("raidreconf", argc, argv, optionsTable, 0);	if ((i = poptGetNextOpt (optCon)) < -1) {		fprintf (stderr, "%s: %s\n",			 poptBadOption (optCon, POPT_BADOPTION_NOALIAS),			 poptStrerror (i));		usage ();		return EXIT_FAILURE;	}	if (i != -1) {		fprintf (stderr, "Extra arguments given - giving up.\n");		usage ();		return EXIT_FAILURE;	}	if (!test && prepare_raidlib ())		return EXIT_FAILURE;	if (help) {		usage ();		return EXIT_FAILURE;	}	if (version) {		printf ("raidreconf 0.1.2 for mkraid version %d.%d.%d\n",			MKRAID_MAJOR_VERSION, MKRAID_MINOR_VERSION,			MKRAID_PATCHLEVEL_VERSION);		return EXIT_VERSION;	}	if (test) {		printf		    ("test mode - plain files are used, no kernel RAID interaction\n");	}	if (!test && getMdVersion (&ver))		return EXIT_FAILURE;	/*	 * Check that mandatory arguments are given	 */	if (!md_device) {		fprintf (stderr, "no md device given\n");		usage();		return EXIT_FAILURE;	}	/*	 * Check for mutually exclusive arguments	 */	if (import_device && export_device) {		fprintf (stderr, "cannot both import and export\n");		return EXIT_FAILURE;	}	if (old_raidtab && import_device) {		fprintf (stderr,			 "cannot both have an import device and an old raidtab\n");		return EXIT_FAILURE;	}	if (new_raidtab && export_device) {		fprintf (stderr,			 "cannot both have an export device and a new raidtab\n");		return EXIT_FAILURE;	}	/*	 * Check source -> destination path	 */	if (old_raidtab && !(new_raidtab || export_device)) {		fprintf (stderr,			 "old raidtab given, but no new raidtab and no export device\n");		return EXIT_FAILURE;	}	if (import_device && !new_raidtab) {		fprintf (stderr,			 "import device given, but no new raidtab\n");		return EXIT_FAILURE;	}	/*	 * Good, now let's move on	 */	printf ("Working with device %s\n", md_device);	/* 	 * Treat import setup	 */	if (import_device) {		printf ("I assume %s is a device you want to import\n",			import_device);		old_md_cfg = setup_single_config (import_device);		if (!old_md_cfg) {			fprintf (stderr, "Import of device failed!\n");			return EXIT_FAILURE;		}	}	if (old_raidtab) {		fp = fopen (old_raidtab, "r");		if (!fp) {			fprintf (stderr, "Couldn't open %s -- %s\n",				 old_raidtab, strerror (errno));			return EXIT_FAILURE;		}		fprintf (stderr, "Parsing %s\n", old_raidtab);		if (parse_config (fp)) {			fprintf (stderr,				 "Cannot parse old-array configuration file");			return EXIT_FAILURE;		}		for (p = cfg_head; p; p = p->next) {			if (strcmp (p->md_name, md_device))				continue;			old_md_cfg = p;			break;		}		if (!p) {			fprintf (stderr,				 "device %s is not described in config file\n",				 md_device);			exit_status++;		}		fclose (fp);	}	/*	 * Read the NEW configuration file 	 */	if (export_device) {		printf ("I assume %s is a device you want to export to\n",			export_device);		new_md_cfg = setup_single_config (export_device);		if (!new_md_cfg) {			fprintf (stderr, "Export to device failed!\n");			return EXIT_FAILURE;		}	}	if (new_raidtab) {		fp = fopen (new_raidtab, "r");		if (!fp) {			fprintf (stderr, "Couldn't open %s -- %s\n",				 new_raidtab, strerror (errno));			return EXIT_FAILURE;		}		fprintf (stderr, "Parsing %s\n", new_raidtab);		if (parse_config (fp)) {			fprintf (stderr,				 "Cannot parse new-array configuration file.\n");			return EXIT_FAILURE;		}		/* Seek from where we left. */		for (p = (p ? p->next : cfg_head); p; p = p->next) {			if (strcmp (p->md_name, md_device))				continue;			new_md_cfg = p;			break;		}		if (!p) {			fprintf (stderr,				 "device %s is not described in config file\n",				 md_device);			exit_status++;			return EXIT_FAILURE;		}	}	if (raid_reconfigure (&ver)) {		fprintf (stderr, "reconfiguration failed\n");		return EXIT_FAILURE;	}	return 0;}#define P(x) printf("%18s: \t %d\n",#x,cfg->array.param.x)#define DP(x) printf("%18s: \t %d\n",#x,cfg->array.disks[i].x)voidprintcfg (md_cfg_entry_t * cfg){	int i;	P (major_version);	P (minor_version);	P (patch_version);	P (ctime);	P (level);	P (size);	P (nr_disks);	P (raid_disks);	P (md_minor);	P (utime);	P (state);	P (active_disks);	P (working_disks);	P (failed_disks);	P (spare_disks);	P (layout);	P (chunk_size);	for (i = 0; i < cfg->array.param.nr_disks; i++) {		printf ("\n");		DP (number);		DP (major);		DP (minor);		DP (raid_disk);		DP (state);	}}static intread_needed_entries (md_cfg_entry_t * cfg){	int i;	for (i = 0; i != cfg->array.param.nr_disks; i++) {		int disk_num = cfg->array.disks[i].raid_disk;		char *devname = cfg->device_name[disk_num];		int fd = open (devname, O_RDWR);		int nr_blocks;		/* sb_block_offset code */		if (fd == -1) {			fprintf (stderr, "Cannot open %s for read/write\n",				 devname);			return 1;		}		if (test) {			struct stat sbuf;			if (fstat (fd, &sbuf)) {				fprintf (stderr,					 "Couldn't stat device %s -- %s\n",					 devname, strerror (errno));				return 1;			}			if (((sbuf.st_size >> 10) << 10) != sbuf.st_size) {				fprintf (stderr,					 "Sorry, device %s size %lu is bad\n",					 devname, sbuf.st_size);				return 1;			}			nr_blocks = sbuf.st_size >> 10;		}		else {			if (ioctl			    (fd, BLKGETSIZE,			     (unsigned long) &nr_blocks) == -1) {				fprintf (stderr,					 "couldn't get device size for %s -- %s\n",					 devname, strerror (errno));				return 1;			}			nr_blocks >>= 1;		}		if (nr_blocks < MD_RESERVED_BLOCKS * 2) {			fprintf (stderr, "%s: device too small (%dkB)\n",				 devname, nr_blocks);			return 1;		}		cfg->sb_block_offset[i] = MD_NEW_SIZE_BLOCKS (nr_blocks);		close (fd);	}	return 0;}intraid_get_size (md_cfg_entry_t * cfg, unsigned long *sum){	int i;	*sum = 0;	for (i = 0; i != cfg->array.param.nr_disks; i++) {		int dnum = cfg->array.disks[i].raid_disk;		char *devname = cfg->device_name[dnum];		int fd = open (devname, O_RDONLY);		unsigned long nr_blocks;		if (fd == -1) {			fprintf (stderr, "Cannot open %s for read/write\n",				 devname);			return 1;

⌨️ 快捷键说明

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