示例#1
0
/* Not really Monitor but ... */
int Wait(char *dev)
{
	struct stat stb;
	char devnm[32];
	int rv = 1;
	int frozen_remaining = 3;

	if (stat(dev, &stb) != 0) {
		pr_err("Cannot find %s: %s\n", dev,
			strerror(errno));
		return 2;
	}
	strcpy(devnm, stat2devnm(&stb));

	while(1) {
		struct mdstat_ent *ms = mdstat_read(1, 0);
		struct mdstat_ent *e;

		for (e=ms ; e; e=e->next)
			if (strcmp(e->devnm, devnm) == 0)
				break;

		if (e && e->percent == RESYNC_NONE) {
			/* We could be in the brief pause before something
			 * starts. /proc/mdstat doesn't show that, but
			 * sync_action does.
			 */
			struct mdinfo mdi;
			char buf[21];
			sysfs_init(&mdi, -1, devnm);
			if (sysfs_get_str(&mdi, NULL, "sync_action",
					  buf, 20) > 0 &&
			    strcmp(buf,"idle\n") != 0) {
				e->percent = RESYNC_UNKNOWN;
				if (strcmp(buf, "frozen\n") == 0) {
					if (frozen_remaining == 0)
						e->percent = RESYNC_NONE;
					else
						frozen_remaining -= 1;
				}
			}
		}
		if (!e || e->percent == RESYNC_NONE) {
			if (e && e->metadata_version &&
			    strncmp(e->metadata_version, "external:", 9) == 0) {
				if (is_subarray(&e->metadata_version[9]))
					ping_monitor(&e->metadata_version[9]);
				else
					ping_monitor(devnm);
			}
			free_mdstat(ms);
			return rv;
		}
		free_mdstat(ms);
		rv = 0;
		mdstat_wait(5);
	}
}
示例#2
0
int main(int argc, char *argv[])
{
	char *container_name = NULL;
	char *devnm = NULL;
	int status = 0;
	int opt;
	int all = 0;
	int takeover = 0;
	int dofork = 1;
	static struct option options[] = {
		{"all", 0, NULL, 'a'},
		{"takeover", 0, NULL, 't'},
		{"help", 0, NULL, 'h'},
		{"offroot", 0, NULL, OffRootOpt},
		{"foreground", 0, NULL, 'F'},
		{NULL, 0, NULL, 0}
	};

	if (in_initrd()) {
		/*
		 * set first char of argv[0] to @. This is used by
		 * systemd to signal that the task was launched from
		 * initrd/initramfs and should be preserved during shutdown
		 */
		argv[0][0] = '@';
	}

	while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) {
		switch (opt) {
		case 'a':
			container_name = argv[optind-1];
			all = 1;
			break;
		case 't':
			takeover = 1;
			break;
		case 'F':
			dofork = 0;
			break;
		case OffRootOpt:
			argv[0][0] = '@';
			break;
		case 'h':
		default:
			usage();
			break;
		}
	}

	if (all == 0 && container_name == NULL) {
		if (argv[optind])
			container_name = argv[optind];
	}

	if (container_name == NULL)
		usage();

	if (argc - optind > 1)
		usage();

	if (strcmp(container_name, "/proc/mdstat") == 0)
		all = 1;

	if (all) {
		struct mdstat_ent *mdstat, *e;
		int container_len = strlen(container_name);

		/* launch an mdmon instance for each container found */
		mdstat = mdstat_read(0, 0);
		for (e = mdstat; e; e = e->next) {
			if (e->metadata_version &&
			    strncmp(e->metadata_version, "external:", 9) == 0 &&
			    !is_subarray(&e->metadata_version[9])) {
				/* update cmdline so this mdmon instance can be
				 * distinguished from others in a call to ps(1)
				 */
				if (strlen(e->devnm) <= (unsigned)container_len) {
					memset(container_name, 0, container_len);
					sprintf(container_name, "%s", e->devnm);
				}
				status |= mdmon(e->devnm, 1, takeover);
			}
		}
		free_mdstat(mdstat);

		return status;
	} else if (strncmp(container_name, "md", 2) == 0) {
		int id = devnm2devid(container_name);
		if (id)
			devnm = container_name;
	} else {
		struct stat st;

		if (stat(container_name, &st) == 0)
			devnm = xstrdup(stat2devnm(&st));
	}

	if (!devnm) {
		pr_err("%s is not a valid md device name\n",
			container_name);
		exit(1);
	}
	return mdmon(devnm, dofork && do_fork(), takeover);
}