Пример #1
0
void
activate(qelem *q, int so)
{
	struct portal_cred pcred;
	char key[MAXPATHLEN+1];
	int error;
	char **v;
	int fd = -1;

	/*
	 * Read the key from the socket
	 */
	error = get_request(so, &pcred, key, sizeof(key));
	if (error) {
		syslog(LOG_ERR, "activate: recvmsg: %s", strerror(error));
		goto drop;
	}

#ifdef DEBUG
	fprintf(stderr, "lookup key %s\n", key);
#endif

	/*
	 * Find a match in the configuration file
	 */
	v = conf_match(q, key);

	/*
	 * If a match existed, then find an appropriate portal
	 * otherwise simply return ENOENT.
	 */
	if (v) {
		error = activate_argv(&pcred, key, v, so, &fd);
		if (error)
			fd = -1;
		else if (fd < 0)
			error = -1;
	} else {
		error = ENOENT;
	}

	if (error >= 0)
		send_reply(so, fd, error);

drop:;
	close(so);
}
Пример #2
0
void RebuildMap(void)
{
	struct mdstat_ent *mdstat = mdstat_read(0, 0);
	struct mdstat_ent *md;
	struct map_ent *map = NULL;
	int require_homehost;
	char sys_hostname[256];
	char *homehost = conf_get_homehost(&require_homehost);

	if (homehost == NULL || strcmp(homehost, "<system>")==0) {
		if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) {
			sys_hostname[sizeof(sys_hostname)-1] = 0;
			homehost = sys_hostname;
		}
	}

	for (md = mdstat ; md ; md = md->next) {
		struct mdinfo *sra = sysfs_read(-1, md->devnm, GET_DEVS);
		struct mdinfo *sd;

		if (!sra)
			continue;

		for (sd = sra->devs ; sd ; sd = sd->next) {
			char namebuf[100];
			char dn[30];
			int dfd;
			int ok;
			int devid;
			struct supertype *st;
			char *subarray = NULL;
			char *path;
			struct mdinfo *info;

			sprintf(dn, "%d:%d", sd->disk.major, sd->disk.minor);
			dfd = dev_open(dn, O_RDONLY);
			if (dfd < 0)
				continue;
			st = guess_super(dfd);
			if ( st == NULL)
				ok = -1;
			else {
				subarray = get_member_info(md);
				ok = st->ss->load_super(st, dfd, NULL);
			}
			close(dfd);
			if (ok != 0)
				continue;
			if (subarray)
				info = st->ss->container_content(st, subarray);
			else {
				info = xmalloc(sizeof(*info));
				st->ss->getinfo_super(st, info, NULL);
			}
			if (!info)
				continue;

			devid = devnm2devid(md->devnm);
			path = map_dev(major(devid), minor(devid), 0);
			if (path == NULL ||
			    strncmp(path, "/dev/md/", 8) != 0) {
				/* We would really like a name that provides
				 * an MD_DEVNAME for udev.
				 * The name needs to be unique both in /dev/md/
				 * and in this mapfile.
				 * It needs to match what -I or -As would come
				 * up with.
				 * That means:
				 *   Check if array is in mdadm.conf
				 *        - if so use that.
				 *   determine trustworthy from homehost etc
				 *   find a unique name based on metadata name.
				 *
				 */
				struct mddev_ident *match = conf_match(st, info,
								       NULL, 0,
								       NULL);
				struct stat stb;
				if (match && match->devname && match->devname[0] == '/') {
					path = match->devname;
					if (path[0] != '/') {
						strcpy(namebuf, "/dev/md/");
						strcat(namebuf, path);
						path = namebuf;
					}
				} else {
					int unum = 0;
					char *sep = "_";
					const char *name;
					int conflict = 1;
					if ((homehost == NULL ||
					     st->ss->match_home(st, homehost) != 1) &&
					    st->ss->match_home(st, "any") != 1 &&
					    (require_homehost
					     || ! conf_name_is_free(info->name)))
						/* require a numeric suffix */
						unum = 0;
					else
						/* allow name to be used as-is if no conflict */
						unum = -1;
					name = info->name;
					if (!*name) {
						name = st->ss->name;
						if (!isdigit(name[strlen(name)-1]) &&
						    unum == -1) {
							unum = 0;
							sep = "";
						}
					}
					if (strchr(name, ':')) {
						/* Probably a uniquifying
						 * hostname prefix.  Allow
						 * without a suffix, and strip
						 * hostname if it is us.
						 */
						if (homehost && unum == -1 &&
						    strncmp(name, homehost,
							    strlen(homehost)) == 0 &&
						    name[strlen(homehost)] == ':')
							name += strlen(homehost)+1;
						unum = -1;
					}

					while (conflict) {
						if (unum >= 0)
							sprintf(namebuf, "/dev/md/%s%s%d",
								name, sep, unum);
						else
							sprintf(namebuf, "/dev/md/%s",
								name);
						unum++;
						if (lstat(namebuf, &stb) != 0 &&
						    (map == NULL ||
						     !map_by_name(&map, namebuf+8)))
							conflict = 0;
					}
					path = namebuf;
				}
			}
			map_add(&map, md->devnm,
				info->text_version,
				info->uuid, path);
			st->ss->free_super(st);
			free(info);
			break;
		}
		sysfs_free(sra);
	}
	/* Only trigger a change if we wrote a new map file */
	if (map_write(map))
		for (md = mdstat ; md ; md = md->next) {
			struct mdinfo *sra = sysfs_read(-1, md->devnm,
							GET_VERSION);
			if (sra)
				sysfs_uevent(sra, "change");
			sysfs_free(sra);
		}
	map_free(map);
	free_mdstat(mdstat);
}