Example #1
0
void load_conffile(void)
{
	FILE *f;
	char *confdir = NULL;
	char *head;

	if (loaded)
		return;
	if (conffile == NULL) {
		conffile = DefaultConfFile;
		confdir = DefaultConfDir;
	}

	if (strcmp(conffile, "partitions")==0) {
		char *list = dl_strdup("DEV");
		dl_init(list);
		dl_add(list, dl_strdup("partitions"));
		devline(list);
		free_line(list);
	} else if (strcmp(conffile, "none") != 0) {
		f = fopen(conffile, "r");
		/* Debian chose to relocate mdadm.conf into /etc/mdadm/.
		 * To allow Debian users to compile from clean source and still
		 * have a working mdadm, we read /etc/mdadm/mdadm.conf
		 * if /etc/mdadm.conf doesn't exist
		 */
		if (f == NULL &&
		    conffile == DefaultConfFile) {
			f = fopen(DefaultAltConfFile, "r");
			if (f) {
				conffile = DefaultAltConfFile;
				confdir = DefaultAltConfDir;
			}
		}
		if (f) {
			conf_file_or_dir(f);
			fclose(f);
		}
		if (confdir) {
			f = fopen(confdir, "r");
			if (f) {
				conf_file_or_dir(f);
				fclose(f);
			}
		}
	}
	/* If there was no AUTO line, process an empty line
	 * now so that the MDADM_CONF_AUTO env var gets processed.
	 */
	head = dl_strdup("AUTO");
	dl_init(head);
	autoline(head);
	free_line(head);

	loaded = 1;
}
Example #2
0
char *conf_line(FILE *file)
{
	char *w;
	char *list;

	w = conf_word(file, 1);
	if (w == NULL) return NULL;

	list = dl_strdup(w);
	free(w);
	dl_init(list);

	while ((w = conf_word(file,0))){
		char *w2 = dl_strdup(w);
		free(w);
		dl_add(list, w2);
	}
/*    printf("got a line\n");*/
	return list;
}
Example #3
0
int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust, struct supertype *forcest)
{

	/* Read the raid superblock from a device and
	 * display important content.
	 *
	 * If cannot be found, print reason: too small, bad magic
	 *
	 * Print:
	 *   version, ctime, level, size, raid+spare+
	 *   prefered minor
	 *   uuid
	 *
	 *   utime, state etc
	 *
	 * If (brief) gather devices for same array and just print a mdadm.conf line including devices=
	 * if devlist==NULL, use conf_get_devs()
	 */
	int fd; 
	void *super = NULL;
	int rv = 0;
	int err = 0;

	struct array {
		void *super;
		struct supertype *st;
		struct mdinfo info;
		struct mddev_ident_s ident;
		void *devs;
		struct array *next;
		int spares;
	} *arrays = NULL;

	for (; devlist ; devlist=devlist->next) {
		struct supertype *st = forcest;

		fd = dev_open(devlist->devname, O_RDONLY);
		if (fd < 0) {
			if (!scan)
				fprintf(stderr,Name ": cannot open %s: %s\n",
					devlist->devname, strerror(errno));
			err = 1;
		}
		else {
			if (!st)
				st = guess_super(fd);
			if (st)
				err = st->ss->load_super(st, fd, &super, (brief||scan)?NULL:devlist->devname);
			else {
				if (!brief)
					fprintf(stderr, Name ": No md superblock detected on %s.\n", devlist->devname);
				err = 1;
			}
			close(fd);
		}
		if (err) {
			rv = 1;
			continue;
		}

		if (SparcAdjust)
			st->ss->update_super(NULL, super, "sparc2.2", devlist->devname,  0);
		/* Ok, its good enough to try, though the checksum could be wrong */
		if (brief) {
			struct array *ap;
			char *d;
			for (ap=arrays; ap; ap=ap->next) {
				if (st->ss == ap->st->ss && st->ss->compare_super(&ap->super, super)==0)
					break;
			}
			if (!ap) {
				ap = malloc(sizeof(*ap));
				ap->super = super;
				ap->devs = dl_head();
				ap->next = arrays;
				ap->spares = 0;
				ap->st = st;
				arrays = ap;
				st->ss->getinfo_super(&ap->info, &ap->ident, super);
			} else {
				st->ss->getinfo_super(&ap->info, &ap->ident, super);
				free(super);
			}
			if (!(ap->info.disk.state & MD_DISK_SYNC))
				ap->spares++;
			d = dl_strdup(devlist->devname);
			dl_add(ap->devs, d);
		} else {
			printf("%s:\n",devlist->devname);
			st->ss->examine_super(super);
			free(super);
		}
	}
	if (brief) {
		struct array *ap;
		for (ap=arrays; ap; ap=ap->next) {
			char sep='=';
			char *d;
			ap->st->ss->brief_examine_super(ap->super);
			if (ap->spares) printf("   spares=%d", ap->spares);
			if (brief > 1) {
				printf("   devices");
				for (d=dl_next(ap->devs); d!= ap->devs; d=dl_next(d)) {
					printf("%c%s", sep, d);
					sep=',';
				}
			}
			free(ap->super);
			/* FIXME free ap */
			if (ap->spares || brief > 1)
				printf("\n");
		}
	}
	return rv;
}
Example #4
0
void load_conffile(char *conffile)
{
	FILE *f;
	char *line;

	if (loaded) return;
	if (conffile == NULL)
		conffile = DefaultConfFile;

	if (strcmp(conffile, "none") == 0) {
		loaded = 1;
		return;
	}
	if (strcmp(conffile, "partitions")==0) {
		char *list = dl_strdup("DEV");
		dl_init(list);
		dl_add(list, dl_strdup("partitions"));
		devline(list);
		free_line(list);
		loaded = 1;
		return;
	}
	f = fopen(conffile, "r");
	/* Debian chose to relocate mdadm.conf into /etc/mdadm/.
	 * To allow Debian users to compile from clean source and still
	 * have a working mdadm, we read /etc/mdadm/mdadm.conf
	 * if /etc/mdadm.conf doesn't exist
	 */
	if (f == NULL &&
	    conffile == DefaultConfFile) {
		f = fopen(DefaultAltConfFile, "r");
		if (f)
			conffile = DefaultAltConfFile;
	}
	if (f == NULL)
		return;

	loaded = 1;
	while ((line=conf_line(f))) {
		switch(match_keyword(line)) {
		case 0: /* DEVICE */
			devline(line);
			break;
		case 1: /* ARRAY */
			arrayline(line);
			break;
		case 2: /* MAIL */
			mailline(line);
			break;
		case 3: /* PROGRAM */
			programline(line);
			break;
		default:
			fprintf(stderr, Name ": Unknown keyword %s\n", line);
		}
		free_line(line);
	}
    
	fclose(f);

/*    printf("got file\n"); */
}
Example #5
0
void autoline(char *line)
{
	char *w;
	char *seen;
	int super_cnt;
	char *dflt = auto_yes;
	int homehost = 0;
	int i;

	if (auto_seen)
		return;
	auto_seen = 1;

	/* Parse the 'auto' line creating policy statements for the 'auto' policy.
	 *
	 * The default is 'yes' but the 'auto' line might over-ride that.
	 * Words in the line are processed in order with the first
	 * match winning.
	 * word can be:
	 *   +version   - that version can be assembled
	 *   -version   - that version cannot be auto-assembled
	 *   yes or +all - any other version can be assembled
	 *   no or -all  - no other version can be assembled.
	 *   homehost   - any array associated by 'homehost' to this
	 *                host can be assembled.
	 *
	 * Thus:
	 *   +ddf -0.90 homehost -all
	 * will auto-assemble any ddf array, no 0.90 array, and
	 * any other array (imsm, 1.x) if and only if it is identified
	 * as belonging to this host.
	 *
	 * We translate that to policy by creating 'auto=yes' when we see
	 * a '+version' line, 'auto=no' if we see '-version' before 'homehost',
	 * or 'auto=homehost' if we see '-version' after 'homehost'.
	 * When we see yes, no, +all or -all we stop and any version that hasn't
	 * been seen gets an appropriate auto= entry.
	 */

	/* If environment variable MDADM_CONF_AUTO is defined, then
	 * it is prepended to the auto line.  This allow a script
	 * to easily disable some metadata types.
	 */
	w = getenv("MDADM_CONF_AUTO");
	if (w && *w) {
		char *l = xstrdup(w);
		char *head = line;
		w = strtok(l, " \t");
		while (w) {
			char *nw = dl_strdup(w);
			dl_insert(head, nw);
			head = nw;
			w = strtok(NULL, " \t");
		}
		free(l);
	}

	for (super_cnt = 0; superlist[super_cnt]; super_cnt++)
		;
	seen = xcalloc(super_cnt, 1);

	for (w = dl_next(line); w != line ; w = dl_next(w)) {
		char *val;

		if (strcasecmp(w, "yes") == 0) {
			dflt = auto_yes;
			break;
		}
		if (strcasecmp(w, "no") == 0) {
			if (homehost)
				dflt = auto_homehost;
			else
				dflt = auto_no;
			break;
		}
		if (strcasecmp(w, "homehost") == 0) {
			homehost = 1;
			continue;
		}
		if (w[0] == '+')
			val = auto_yes;
		else if (w[0] == '-') {
			if (homehost)
				val = auto_homehost;
			else
				val = auto_no;
		} else
			continue;

		if (strcasecmp(w+1, "all") == 0) {
			dflt = val;
			break;
		}
		for (i = 0; superlist[i]; i++) {
			const char *version = superlist[i]->name;
			if (strcasecmp(w+1, version) == 0)
				break;
			/* 1 matches 1.x, 0 matches 0.90 */
			if (version[1] == '.' &&
			    strlen(w+1) == 1 &&
			    w[1] == version[0])
				break;
			/* 1.anything matches 1.x */
			if (strcmp(version, "1.x") == 0 &&
			    strncmp(w+1, "1.", 2) == 0)
				break;
		}
		if (superlist[i] == NULL)
			/* ignore this word */
			continue;
		if (seen[i])
			/* already know about this metadata */
			continue;
		policy_add(rule_policy, pol_auto, val, pol_metadata, superlist[i]->name, NULL);
		seen[i] = 1;
	}
	for (i = 0; i < super_cnt; i++)
		if (!seen[i])
			policy_add(rule_policy, pol_auto, dflt, pol_metadata, superlist[i]->name, NULL);

	free(seen);
}
Example #6
0
void load_conffile(void)
{
	FILE *f;
	char *line;

	if (loaded) return;
	if (conffile == NULL)
		conffile = DefaultConfFile;

	if (strcmp(conffile, "none") == 0) {
		loaded = 1;
		return;
	}
	if (strcmp(conffile, "partitions")==0) {
		char *list = dl_strdup("DEV");
		dl_init(list);
		dl_add(list, dl_strdup("partitions"));
		devline(list);
		free_line(list);
		loaded = 1;
		return;
	}
	f = fopen(conffile, "r");
	/* Debian chose to relocate mdadm.conf into /etc/mdadm/.
	 * To allow Debian users to compile from clean source and still
	 * have a working mdadm, we read /etc/mdadm/mdadm.conf
	 * if /etc/mdadm.conf doesn't exist
	 */
	if (f == NULL &&
	    conffile == DefaultConfFile) {
		f = fopen(DefaultAltConfFile, "r");
		if (f)
			conffile = DefaultAltConfFile;
	}
	if (f == NULL)
		return;

	loaded = 1;
	while ((line=conf_line(f))) {
		switch(match_keyword(line)) {
		case Devices:
			devline(line);
			break;
		case Array:
			arrayline(line);
			break;
		case Mailaddr:
			mailline(line);
			break;
		case Mailfrom:
			mailfromline(line);
			break;
		case Program:
			programline(line);
			break;
		case CreateDev:
			createline(line);
			break;
		case Homehost:
			homehostline(line);
			break;
		default:
			fprintf(stderr, Name ": Unknown keyword %s\n", line);
		}
		free_line(line);
	}
    
	fclose(f);

/*    printf("got file\n"); */
}