"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "policy.c" between
mdadm-4.1.tar.gz and mdadm-4.2.tar.gz

About: mdadm is a tool for creating, managing and monitoring device arrays using the "md" driver in Linux, also known as Software RAID arrays.

policy.c  (mdadm-4.1):policy.c  (mdadm-4.2)
skipping to change at line 192 skipping to change at line 192
struct dev_policy *pol_find(struct dev_policy *pol, char *name) struct dev_policy *pol_find(struct dev_policy *pol, char *name)
{ {
while (pol && pol->name < name) while (pol && pol->name < name)
pol = pol->next; pol = pol->next;
if (!pol || pol->name != name) if (!pol || pol->name != name)
return NULL; return NULL;
return pol; return pol;
} }
static char *disk_path(struct mdinfo *disk) static char **disk_paths(struct mdinfo *disk)
{ {
struct stat stb; struct stat stb;
int prefix_len; int prefix_len;
DIR *by_path; DIR *by_path;
char symlink[PATH_MAX] = "/dev/disk/by-path/"; char symlink[PATH_MAX] = "/dev/disk/by-path/";
char nm[PATH_MAX]; char **paths;
int cnt = 0;
struct dirent *ent; struct dirent *ent;
int rv;
paths = xmalloc(sizeof(*paths) * (cnt+1));
by_path = opendir(symlink); by_path = opendir(symlink);
if (by_path) { if (by_path) {
prefix_len = strlen(symlink); prefix_len = strlen(symlink);
while ((ent = readdir(by_path)) != NULL) { while ((ent = readdir(by_path)) != NULL) {
if (ent->d_type != DT_LNK) if (ent->d_type != DT_LNK)
continue; continue;
strncpy(symlink + prefix_len, strncpy(symlink + prefix_len,
ent->d_name, ent->d_name,
sizeof(symlink) - prefix_len); sizeof(symlink) - prefix_len);
if (stat(symlink, &stb) < 0) if (stat(symlink, &stb) < 0)
continue; continue;
if ((stb.st_mode & S_IFMT) != S_IFBLK) if ((stb.st_mode & S_IFMT) != S_IFBLK)
continue; continue;
if (stb.st_rdev != makedev(disk->disk.major, disk->disk.m inor)) if (stb.st_rdev != makedev(disk->disk.major, disk->disk.m inor))
continue; continue;
closedir(by_path); paths[cnt++] = xstrdup(ent->d_name);
return xstrdup(ent->d_name); paths = xrealloc(paths, sizeof(*paths) * (cnt+1));
} }
closedir(by_path); closedir(by_path);
} }
/* A NULL path isn't really acceptable - use the devname.. */ paths[cnt] = NULL;
sprintf(symlink, "/sys/dev/block/%d:%d", disk->disk.major, disk->disk.min return paths;
or);
rv = readlink(symlink, nm, sizeof(nm)-1);
if (rv > 0) {
char *dname;
nm[rv] = 0;
dname = strrchr(nm, '/');
if (dname)
return xstrdup(dname + 1);
}
return xstrdup("unknown");
} }
char type_part[] = "part"; char type_part[] = "part";
char type_disk[] = "disk"; char type_disk[] = "disk";
static char *disk_type(struct mdinfo *disk) static char *disk_type(struct mdinfo *disk)
{ {
char buf[30+20+20]; char buf[30+20+20];
struct stat stb; struct stat stb;
sprintf(buf, "/sys/dev/block/%d:%d/partition", sprintf(buf, "/sys/dev/block/%d:%d/partition",
disk->disk.major, disk->disk.minor); disk->disk.major, disk->disk.minor);
if (stat(buf, &stb) == 0) if (stat(buf, &stb) == 0)
return type_part; return type_part;
else else
return type_disk; return type_disk;
} }
static int pol_match(struct rule *rule, char *path, char *type) static int path_has_part(char *path, char **part)
{
/* check if path ends with "-partNN" and
* if it does, place a pointer to "-pathNN"
* in 'part'.
*/
int l;
if (!path)
return 0;
l = strlen(path);
while (l > 1 && isdigit(path[l-1]))
l--;
if (l < 5 || strncmp(path+l-5, "-part", 5) != 0)
return 0;
*part = path+l-5;
return 1;
}
static int pol_match(struct rule *rule, char **paths, char *type, char **part)
{ {
/* check if this rule matches on path and type */ /* Check if this rule matches on any path and type.
* If 'part' is not NULL, then 'path' must end in -partN, which
* we ignore for matching, and return in *part on success.
*/
int pathok = 0; /* 0 == no path, 1 == match, -1 == no match yet */ int pathok = 0; /* 0 == no path, 1 == match, -1 == no match yet */
int typeok = 0; int typeok = 0;
while (rule) { for (; rule; rule = rule->next) {
if (rule->name == rule_path) { if (rule->name == rule_path) {
char *p = NULL;
int i;
if (pathok == 0) if (pathok == 0)
pathok = -1; pathok = -1;
if (path && fnmatch(rule->value, path, 0) == 0) if (!paths)
pathok = 1; continue;
for (i = 0; paths[i]; i++) {
if (part) {
if (!path_has_part(paths[i], &p))
continue;
*p = '\0';
*part = p+1;
}
if (fnmatch(rule->value, paths[i], 0) == 0)
pathok = 1;
if (part)
*p = '-';
}
} }
if (rule->name == rule_type) { if (rule->name == rule_type) {
if (typeok == 0) if (typeok == 0)
typeok = -1; typeok = -1;
if (type && strcmp(rule->value, type) == 0) if (type && strcmp(rule->value, type) == 0)
typeok = 1; typeok = 1;
} }
rule = rule->next;
} }
return pathok >= 0 && typeok >= 0; return pathok >= 0 && typeok >= 0;
} }
static void pol_merge(struct dev_policy **pol, struct rule *rule) static void pol_merge(struct dev_policy **pol, struct rule *rule)
{ {
/* copy any name assignments from rule into pol */ /* copy any name assignments from rule into pol */
struct rule *r; struct rule *r;
char *metadata = NULL; char *metadata = NULL;
for (r = rule; r ; r = r->next) for (r = rule; r ; r = r->next)
if (r->name == pol_metadata) if (r->name == pol_metadata)
metadata = r->value; metadata = r->value;
for (r = rule; r ; r = r->next) for (r = rule; r ; r = r->next)
if (r->name == pol_act || if (r->name == pol_act ||
r->name == pol_domain || r->name == pol_domain ||
r->name == pol_auto) r->name == pol_auto)
pol_new(pol, r->name, r->value, metadata); pol_new(pol, r->name, r->value, metadata);
} }
static int path_has_part(char *path, char **part)
{
/* check if path ends with "-partNN" and
* if it does, place a pointer to "-pathNN"
* in 'part'.
*/
int l;
if (!path)
return 0;
l = strlen(path);
while (l > 1 && isdigit(path[l-1]))
l--;
if (l < 5 || strncmp(path+l-5, "-part", 5) != 0)
return 0;
*part = path+l-4;
return 1;
}
static void pol_merge_part(struct dev_policy **pol, struct rule *rule, char *par t) static void pol_merge_part(struct dev_policy **pol, struct rule *rule, char *par t)
{ {
/* copy any name assignments from rule into pol, appending /* copy any name assignments from rule into pol, appending
* -part to any domain. The string with -part appended is * -part to any domain. The string with -part appended is
* stored with the rule so it has a lifetime to match * stored with the rule so it has a lifetime to match
* the rule. * the rule.
*/ */
struct rule *r; struct rule *r;
char *metadata = NULL; char *metadata = NULL;
for (r = rule; r ; r = r->next) for (r = rule; r ; r = r->next)
skipping to change at line 355 skipping to change at line 364
static struct pol_rule *config_rules = NULL; static struct pol_rule *config_rules = NULL;
static struct pol_rule **config_rules_end = NULL; static struct pol_rule **config_rules_end = NULL;
static int config_rules_has_path = 0; static int config_rules_has_path = 0;
/* /*
* most policy comes from a set policy rules that are * most policy comes from a set policy rules that are
* read from the config file. * read from the config file.
* path_policy() gathers policy information for the * path_policy() gathers policy information for the
* disk described in the given a 'path' and a 'type'. * disk described in the given a 'path' and a 'type'.
*/ */
struct dev_policy *path_policy(char *path, char *type) struct dev_policy *path_policy(char **paths, char *type)
{ {
struct pol_rule *rules; struct pol_rule *rules;
struct dev_policy *pol = NULL; struct dev_policy *pol = NULL;
int i; int i;
rules = config_rules; rules = config_rules;
while (rules) { while (rules) {
char *part; char *part = NULL;
if (rules->type == rule_policy) if (rules->type == rule_policy)
if (pol_match(rules->rule, path, type)) if (pol_match(rules->rule, paths, type, NULL))
pol_merge(&pol, rules->rule); pol_merge(&pol, rules->rule);
if (rules->type == rule_part && strcmp(type, type_part) == 0) if (rules->type == rule_part && strcmp(type, type_part) == 0)
if (path_has_part(path, &part)) { if (pol_match(rules->rule, paths, type_disk, &part))
*part = 0; pol_merge_part(&pol, rules->rule, part);
if (pol_match(rules->rule, path, type_disk))
pol_merge_part(&pol, rules->rule, part+1)
;
*part = '-';
}
rules = rules->next; rules = rules->next;
} }
/* Now add any metadata-specific internal knowledge /* Now add any metadata-specific internal knowledge
* about this path * about this path
*/ */
for (i=0; path && superlist[i]; i++) for (i=0; paths && paths[0] && superlist[i]; i++)
if (superlist[i]->get_disk_controller_domain) { if (superlist[i]->get_disk_controller_domain) {
const char *d = const char *d =
superlist[i]->get_disk_controller_domain(path); superlist[i]->get_disk_controller_domain(
paths[0]);
if (d) if (d)
pol_new(&pol, pol_domain, d, superlist[i]->name); pol_new(&pol, pol_domain, d, superlist[i]->name);
} }
pol_sort(&pol); pol_sort(&pol);
pol_dedup(pol); pol_dedup(pol);
return pol; return pol;
} }
void pol_add(struct dev_policy **pol, void pol_add(struct dev_policy **pol,
char *name, char *val, char *name, char *val,
char *metadata) char *metadata)
{ {
pol_new(pol, name, val, metadata); pol_new(pol, name, val, metadata);
pol_sort(pol); pol_sort(pol);
pol_dedup(*pol); pol_dedup(*pol);
} }
static void free_paths(char **paths)
{
int i;
if (!paths)
return;
for (i = 0; paths[i]; i++)
free(paths[i]);
free(paths);
}
/* /*
* disk_policy() gathers policy information for the * disk_policy() gathers policy information for the
* disk described in the given mdinfo (disk.{major,minor}). * disk described in the given mdinfo (disk.{major,minor}).
*/ */
struct dev_policy *disk_policy(struct mdinfo *disk) struct dev_policy *disk_policy(struct mdinfo *disk)
{ {
char *path = NULL; char **paths = NULL;
char *type = disk_type(disk); char *type = disk_type(disk);
struct dev_policy *pol = NULL; struct dev_policy *pol = NULL;
if (config_rules_has_path) if (config_rules_has_path)
path = disk_path(disk); paths = disk_paths(disk);
pol = path_policy(path, type); pol = path_policy(paths, type);
free(path); free_paths(paths);
return pol; return pol;
} }
struct dev_policy *devid_policy(int dev) struct dev_policy *devid_policy(int dev)
{ {
struct mdinfo disk; struct mdinfo disk;
disk.disk.major = major(dev); disk.disk.major = major(dev);
disk.disk.minor = minor(dev); disk.disk.minor = minor(dev);
return disk_policy(&disk); return disk_policy(&disk);
} }
skipping to change at line 746 skipping to change at line 764
} }
snprintf(path, PATH_MAX, FAILED_SLOTS_DIR "/%s", id_path); snprintf(path, PATH_MAX, FAILED_SLOTS_DIR "/%s", id_path);
f = fopen(path, "w"); f = fopen(path, "w");
if (!f) { if (!f) {
pr_err("can't create file to save path to old disk: %s\n", pr_err("can't create file to save path to old disk: %s\n",
strerror(errno)); strerror(errno));
return; return;
} }
if (fprintf(f, "%s %08x:%08x:%08x:%08x\n", if (fprintf(f, "%20s %08x:%08x:%08x:%08x\n",
array->metadata, array->metadata,
array->uuid[0], array->uuid[1], array->uuid[0], array->uuid[1],
array->uuid[2], array->uuid[3]) <= 0) array->uuid[2], array->uuid[3]) <= 0)
pr_err("Failed to write to <id_path> cookie\n"); pr_err("Failed to write to <id_path> cookie\n");
fclose(f); fclose(f);
} }
int policy_check_path(struct mdinfo *disk, struct map_ent *array) int policy_check_path(struct mdinfo *disk, struct map_ent *array)
{ {
char path[PATH_MAX]; char path[PATH_MAX];
FILE *f = NULL; FILE *f = NULL;
char *id_path = disk_path(disk); char **id_paths = disk_paths(disk);
int rv; int i;
int rv = 0;
if (!id_path)
return 0;
snprintf(path, PATH_MAX, FAILED_SLOTS_DIR "/%s", id_path); for (i = 0; id_paths[i]; i++) {
f = fopen(path, "r"); snprintf(path, PATH_MAX, FAILED_SLOTS_DIR "/%s", id_paths[i]);
if (!f) { f = fopen(path, "r");
free(id_path); if (!f)
return 0; continue;
rv = fscanf(f, " %20s %x:%x:%x:%x\n",
array->metadata,
array->uuid,
array->uuid+1,
array->uuid+2,
array->uuid+3);
fclose(f);
break;
} }
free_paths(id_paths);
rv = fscanf(f, " %s %x:%x:%x:%x\n",
array->metadata,
array->uuid,
array->uuid+1,
array->uuid+2,
array->uuid+3);
fclose(f);
free(id_path);
return rv == 5; return rv == 5;
} }
/* invocation of udev rule file */ /* invocation of udev rule file */
char udev_template_start[] = char udev_template_start[] =
"# do not edit this file, it is automatically generated by mdadm\n" "# do not edit this file, it is automatically generated by mdadm\n"
"\n"; "\n";
/* find rule named rule_type and return its value */ /* find rule named rule_type and return its value */
char *find_rule(struct rule *rule, char *rule_type) char *find_rule(struct rule *rule, char *rule_type)
 End of changes. 27 change blocks. 
77 lines changed or deleted 92 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)