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); }
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); }