Codebase list mdadm / 79f25f7d-ee9e-46d5-a893-fdd6521c4afd/main Examine.c
79f25f7d-ee9e-46d5-a893-fdd6521c4afd/main

Tree @79f25f7d-ee9e-46d5-a893-fdd6521c4afd/main (Download .tar.gz)

Examine.c @79f25f7d-ee9e-46d5-a893-fdd6521c4afd/main

64c4757
9a9dab3
64c4757
6f02172
64c4757
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e736b62
64c4757
 
9a9dab3
cd29a5c
64c4757
82b2761
 
 
64c4757
 
eec3f88
 
 
64c4757
 
 
 
 
 
 
 
 
 
 
 
 
 
ca3b669
 
8b0dabe
64c4757
aba6914
cd29a5c
64c4757
cd29a5c
82d9eba
4b1ac34
cd29a5c
 
4b1ac34
cd29a5c
 
ca3b669
0ea2b5e
1f49fb3
36352fc
 
f9ce90b
8b0dabe
cd29a5c
eec3f88
e7b84f9
 
e52f8e2
751406f
36352fc
cd29a5c
36352fc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6baf9a8
36352fc
 
 
 
 
 
 
cd29a5c
36352fc
 
 
 
 
cd29a5c
36352fc
4b1ac34
eec3f88
3da92f2
68c7d6d
cd29a5c
0d726f1
eec3f88
 
e7b84f9
36352fc
eec3f88
cd29a5c
 
ca3b669
68c7d6d
c7b8547
cd29a5c
 
 
503975b
cd29a5c
 
4b1ac34
82d9eba
cd29a5c
a5d85af
37424f1
a5d85af
1f49fb3
ed57a7e
4b1ac34
cd29a5c
 
eec3f88
bceedee
 
1cc7f4f
cd29a5c
 
eec3f88
3da92f2
bd526ce
82b2761
eec3f88
cd29a5c
ca3b669
cd29a5c
 
ee836c3
 
eec3f88
601ffa7
ee836c3
eec3f88
ee836c3
ca3b669
 
 
22892d5
 
 
cd29a5c
ee836c3
 
 
eec3f88
ee836c3
3da92f2
4b1ac34
eec3f88
d9d4e46
cd29a5c
64c4757
cd29a5c
64c4757
6d388a8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/*
 * mdadm - manage Linux "md" devices aka RAID arrays.
 *
 * Copyright (C) 2001-2013 Neil Brown <neilb@suse.de>
 *
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *    Author: Neil Brown
 *    Email: <neilb@suse.de>
 */

#include	"mdadm.h"
#include	"dlink.h"

#if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN)
#error no endian defined
#endif
#include	"md_u.h"
#include	"md_p.h"
int Examine(struct mddev_dev *devlist,
	    struct context *c,
	    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;
	int rv = 0;

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

	for (; devlist ; devlist = devlist->next) {
		struct supertype *st;
		int have_container = 0;
		int err = 0;
		int container = 0;

		fd = dev_open(devlist->devname, O_RDONLY);
		if (fd < 0) {
			if (!c->scan) {
				pr_err("cannot open %s: %s\n",
				       devlist->devname, strerror(errno));
				rv = 1;
			}
			continue;
		}

		if (forcest)
			st = dup_super(forcest);
		else if (must_be_container(fd)) {
			/* might be a container */
			st = super_by_fd(fd, NULL);
			container = 1;
		} else
			st = guess_super(fd);
		if (st) {
			err = 1;
			st->ignore_hw_compat = 1;
			if (!container)
				err = st->ss->load_super(st, fd,
							 (c->brief||c->scan) ? NULL
							 :devlist->devname);
			if (err && st->ss->load_container) {
				err = st->ss->load_container(st, fd,
							     (c->brief||c->scan) ? NULL
							     :devlist->devname);
				if (!err)
					have_container = 1;
			}
			st->ignore_hw_compat = 0;
		} else {
			if (!c->brief) {
				pr_err("No md superblock detected on %s.\n", devlist->devname);
				rv = 1;
			}
			err = 1;
		}
		close(fd);

		if (err) {
			if (st)
				st->ss->free_super(st);
			continue;
		}

		if (c->SparcAdjust)
			st->ss->update_super(st, NULL, "sparc2.2",
					     devlist->devname, 0, 0, NULL);
		/* Ok, its good enough to try, though the checksum could be wrong */

		if (c->brief && st->ss->brief_examine_super == NULL) {
			if (!c->scan)
				pr_err("No brief listing for %s on %s\n",
				       st->ss->name, devlist->devname);
		} else if (c->brief) {
			struct array *ap;
			char *d;
			for (ap = arrays; ap; ap = ap->next) {
				if (st->ss == ap->st->ss &&
				    st->ss->compare_super(ap->st, st, 0) == 0)
					break;
			}
			if (!ap) {
				ap = xmalloc(sizeof(*ap));
				ap->devs = dl_head();
				ap->next = arrays;
				ap->spares = 0;
				ap->st = st;
				arrays = ap;
				st->ss->getinfo_super(st, &ap->info, NULL);
			} else
				st->ss->getinfo_super(st, &ap->info, NULL);
			if (!have_container &&
			    !(ap->info.disk.state & (1<<MD_DISK_SYNC)))
				ap->spares++;
			d = dl_strdup(devlist->devname);
			dl_add(ap->devs, d);
		} else if (c->export) {
			if (st->ss->export_examine_super)
				st->ss->export_examine_super(st);
			st->ss->free_super(st);
		} else {
			printf("%s:\n",devlist->devname);
			st->ss->examine_super(st, c->homehost);
			st->ss->free_super(st);
		}
	}
	if (c->brief) {
		struct array *ap;
		for (ap = arrays; ap; ap = ap->next) {
			char sep='=';
			char *d;
			int newline = 0;

			ap->st->ss->brief_examine_super(ap->st, c->verbose > 0);
			if (ap->spares && !ap->st->ss->external)
				newline += printf("   spares=%d", ap->spares);
			if (c->verbose > 0) {
				newline += printf("   devices");
				for (d = dl_next(ap->devs);
				     d != ap->devs;
				     d=dl_next(d)) {
					printf("%c%s", sep, d);
					sep=',';
				}
			}
			if (ap->st->ss->brief_examine_subarrays) {
				if (newline)
					printf("\n");
				ap->st->ss->brief_examine_subarrays(ap->st, c->verbose);
			}
			ap->st->ss->free_super(ap->st);
			/* FIXME free ap */
			if (ap->spares || c->verbose > 0)
				printf("\n");
		}
	}
	return rv;
}

int ExamineBadblocks(char *devname, int brief, struct supertype *forcest)
{
	int fd = dev_open(devname, O_RDONLY);
	struct supertype *st = forcest;
	int err = 1;

	if (fd < 0) {
		pr_err("cannot open %s: %s\n", devname, strerror(errno));
		return 1;
	}
	if (!st)
		st = guess_super(fd);
	if (!st) {
		if (!brief)
			pr_err("No md superblock detected on %s\n", devname);
		goto out;
	}
	if (!st->ss->examine_badblocks) {
		pr_err("%s metadata does not support badblocks\n", st->ss->name);
		goto out;
	}
	err = st->ss->load_super(st, fd, brief ? NULL : devname);
	if (err)
		goto out;
	err = st->ss->examine_badblocks(st, fd, devname);

out:
	if (fd >= 0)
		close(fd);
	if (st) {
		st->ss->free_super(st);
		free(st);
	}
	return err;
}