X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=udev%2Fudev-rules.c;h=663a6d4f047ec8a22d0e9341bdc477b3a0f56072;hp=7ba52208fb243daafaf971d82befe26cbb15d451;hb=977f6f4b3dfbdd32d7df5a774a4ed761d5d4b98f;hpb=3d7b2831cd661afd7d946791110b6ad5a7156d7f diff --git a/udev/udev-rules.c b/udev/udev-rules.c index 7ba52208f..663a6d4f0 100644 --- a/udev/udev-rules.c +++ b/udev/udev-rules.c @@ -140,6 +140,7 @@ enum token_type { TK_A_IGNORE_DEVICE, TK_A_STRING_ESCAPE_NONE, TK_A_STRING_ESCAPE_REPLACE, + TK_A_INOTIFY_WATCH, /* int */ TK_A_NUM_FAKE_PART, /* int */ TK_A_DEVLINK_PRIO, /* int */ TK_A_OWNER, /* val */ @@ -182,7 +183,6 @@ struct token { union { unsigned int attr_off; int ignore_error; - int i; unsigned int rule_goto; mode_t mode; uid_t uid; @@ -190,6 +190,7 @@ struct token { int num_fake_part; int devlink_prio; int event_timeout; + int watch; }; } key; }; @@ -270,6 +271,7 @@ static const char *token_str(enum token_type type) [TK_A_IGNORE_DEVICE] = "A IGNORE_DEVICE", [TK_A_STRING_ESCAPE_NONE] = "A STRING_ESCAPE_NONE", [TK_A_STRING_ESCAPE_REPLACE] = "A STRING_ESCAPE_REPLACE", + [TK_A_INOTIFY_WATCH] = "A INOTIFY_WATCH", [TK_A_NUM_FAKE_PART] = "A NUM_FAKE_PART", [TK_A_DEVLINK_PRIO] = "A DEVLINK_PRIO", [TK_A_OWNER] = "A OWNER", @@ -360,6 +362,9 @@ static void dump_token(struct udev_rules *rules, struct token *token) dbg(rules->udev, "%s %s '%s'(%s) %#o\n", token_str(type), operation_str(op), value, string_glob_str(glob), token->key.mode); break; + case TK_A_INOTIFY_WATCH: + dbg(rules->udev, "%s %u\n", token_str(type), token->key.watch); + break; case TK_A_NUM_FAKE_PART: dbg(rules->udev, "%s %u\n", token_str(type), token->key.num_fake_part); break; @@ -1027,9 +1032,8 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, token->key.value_off = add_string(rule_tmp->rules, value); token->key.ignore_error = *(int *)data; break; + case TK_A_INOTIFY_WATCH: case TK_A_NUM_FAKE_PART: - token->key.num_fake_part = *(int *)data; - break; case TK_A_DEVLINK_PRIO: token->key.devlink_prio = *(int *)data; break; @@ -1131,7 +1135,6 @@ static int sort_token(struct udev_rules *rules, struct rule_tmp *rule_tmp) static int add_rule(struct udev_rules *rules, char *line, const char *filename, unsigned int filename_off, unsigned int lineno) { - int valid = 0; char *linepos; char *attr; int physdev = 0; @@ -1159,7 +1162,6 @@ static int add_rule(struct udev_rules *rules, char *line, goto invalid; } rule_add_key(&rule_tmp, TK_M_ACTION, op, value, NULL); - valid = 1; continue; } @@ -1169,7 +1171,6 @@ static int add_rule(struct udev_rules *rules, char *line, goto invalid; } rule_add_key(&rule_tmp, TK_M_DEVPATH, op, value, NULL); - valid = 1; continue; } @@ -1179,7 +1180,6 @@ static int add_rule(struct udev_rules *rules, char *line, goto invalid; } rule_add_key(&rule_tmp, TK_M_KERNEL, op, value, NULL); - valid = 1; continue; } @@ -1198,7 +1198,6 @@ static int add_rule(struct udev_rules *rules, char *line, rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, "subsystem|class|bus", NULL); } else rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, value, NULL); - valid = 1; continue; } @@ -1208,7 +1207,6 @@ static int add_rule(struct udev_rules *rules, char *line, goto invalid; } rule_add_key(&rule_tmp, TK_M_DRIVER, op, value, NULL); - valid = 1; continue; } @@ -1223,7 +1221,6 @@ static int add_rule(struct udev_rules *rules, char *line, } else { rule_add_key(&rule_tmp, TK_A_ATTR, op, value, attr); } - valid = 1; continue; } @@ -1234,7 +1231,6 @@ static int add_rule(struct udev_rules *rules, char *line, goto invalid; } rule_add_key(&rule_tmp, TK_M_KERNELS, op, value, NULL); - valid = 1; continue; } @@ -1245,7 +1241,6 @@ static int add_rule(struct udev_rules *rules, char *line, goto invalid; } rule_add_key(&rule_tmp, TK_M_SUBSYSTEMS, op, value, NULL); - valid = 1; continue; } @@ -1255,7 +1250,6 @@ static int add_rule(struct udev_rules *rules, char *line, goto invalid; } rule_add_key(&rule_tmp, TK_M_DRIVERS, op, value, NULL); - valid = 1; continue; } @@ -1277,7 +1271,6 @@ static int add_rule(struct udev_rules *rules, char *line, err(rules->udev, "do not reference parent sysfs directories directly, " "it may break with a future kernel, please fix it in %s:%u", filename, lineno); rule_add_key(&rule_tmp, TK_M_ATTRS, op, value, attr); - valid = 1; continue; } @@ -1296,13 +1289,11 @@ static int add_rule(struct udev_rules *rules, char *line, if (rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr) != 0) goto invalid; } - valid = 1; continue; } if (strcasecmp(key, "PROGRAM") == 0) { rule_add_key(&rule_tmp, TK_M_PROGRAM, op, value, NULL); - valid = 1; continue; } @@ -1312,7 +1303,6 @@ static int add_rule(struct udev_rules *rules, char *line, goto invalid; } rule_add_key(&rule_tmp, TK_M_RESULT, op, value, NULL); - valid = 1; continue; } @@ -1321,15 +1311,12 @@ static int add_rule(struct udev_rules *rules, char *line, if (attr != NULL && strstr(attr, "program")) { dbg(rules->udev, "IMPORT will be executed\n"); rule_add_key(&rule_tmp, TK_M_IMPORT_PROG, op, value, NULL); - valid = 1; } else if (attr != NULL && strstr(attr, "file")) { dbg(rules->udev, "IMPORT will be included as file\n"); rule_add_key(&rule_tmp, TK_M_IMPORT_FILE, op, value, NULL); - valid = 1; } else if (attr != NULL && strstr(attr, "parent")) { dbg(rules->udev, "IMPORT will include the parent values\n"); rule_add_key(&rule_tmp, TK_M_IMPORT_PARENT, op, value, NULL); - valid = 1; } else { /* figure it out if it is executable */ char file[UTIL_PATH_SIZE]; @@ -1354,11 +1341,9 @@ static int add_rule(struct udev_rules *rules, char *line, if (!lstat(file, &statbuf) && (statbuf.st_mode & S_IXUSR)) { dbg(rules->udev, "IMPORT will be executed (autotype)\n"); rule_add_key(&rule_tmp, TK_M_IMPORT_PROG, op, value, NULL); - valid = 1; } else { dbg(rules->udev, "IMPORT will be included as file (autotype)\n"); rule_add_key(&rule_tmp, TK_M_IMPORT_FILE, op, value, NULL); - valid = 1; } } continue; @@ -1378,7 +1363,6 @@ static int add_rule(struct udev_rules *rules, char *line, } else { rule_add_key(&rule_tmp, TK_M_TEST, op, value, NULL); } - valid = 1; continue; } @@ -1389,26 +1373,22 @@ static int add_rule(struct udev_rules *rules, char *line, if (attr != NULL && strstr(attr, "ignore_error")) flag = 1; rule_add_key(&rule_tmp, TK_A_RUN, op, value, &flag); - valid = 1; continue; } if (strcasecmp(key, "WAIT_FOR") == 0 || strcasecmp(key, "WAIT_FOR_SYSFS") == 0) { rule_add_key(&rule_tmp, TK_M_WAITFOR, 0, value, NULL); - valid = 1; waitfor = 1; continue; } if (strcasecmp(key, "LABEL") == 0) { rule_tmp.rule.rule.label_off = add_string(rules, value); - valid = 1; continue; } if (strcasecmp(key, "GOTO") == 0) { rule_add_key(&rule_tmp, TK_A_GOTO, 0, value, NULL); - valid = 1; continue; } @@ -1417,7 +1397,7 @@ static int add_rule(struct udev_rules *rules, char *line, rule_add_key(&rule_tmp, TK_M_NAME, op, value, NULL); } else { if (value[0] == '\0') - dbg(rules->udev, "name empty, node creation suppressed\n"); + info(rules->udev, "name empty, node creation suppressed\n"); rule_add_key(&rule_tmp, TK_A_NAME, op, value, NULL); attr = get_key_attribute(rules->udev, key + sizeof("NAME")-1); if (attr != NULL) { @@ -1443,7 +1423,6 @@ static int add_rule(struct udev_rules *rules, char *line, else rule_add_key(&rule_tmp, TK_A_DEVLINK, op, value, NULL); rule_tmp.rule.rule.flags = 1; - valid = 1; continue; } @@ -1454,14 +1433,13 @@ static int add_rule(struct udev_rules *rules, char *line, uid = strtoul(value, &endptr, 10); if (endptr[0] == '\0') { rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid); - } else if (rules->resolve_names && strchr("$%", value[0]) == NULL) { + } else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) { uid = add_uid(rules, value); rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid); - } else { + } else if (rules->resolve_names == 0) { rule_add_key(&rule_tmp, TK_A_OWNER, op, value, NULL); } rule_tmp.rule.rule.flags = 1; - valid = 1; continue; } @@ -1472,14 +1450,13 @@ static int add_rule(struct udev_rules *rules, char *line, gid = strtoul(value, &endptr, 10); if (endptr[0] == '\0') { rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid); - } else if (rules->resolve_names && strchr("$%", value[0]) == NULL) { + } else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) { gid = add_gid(rules, value); rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid); - } else { + } else if (rules->resolve_names == 0) { rule_add_key(&rule_tmp, TK_A_GROUP, op, value, NULL); } rule_tmp.rule.rule.flags = 1; - valid = 1; continue; } @@ -1493,7 +1470,6 @@ static int add_rule(struct udev_rules *rules, char *line, else rule_add_key(&rule_tmp, TK_A_MODE, op, value, NULL); rule_tmp.rule.rule.flags = 1; - valid = 1; continue; } @@ -1540,7 +1516,21 @@ static int add_rule(struct udev_rules *rules, char *line, rule_add_key(&rule_tmp, TK_A_NUM_FAKE_PART, 0, NULL, &num); dbg(rules->udev, "creation of partition nodes requested\n"); } - valid = 1; + pos = strstr(value, "nowatch"); + if (pos != NULL) { + const int off = 0; + + rule_add_key(&rule_tmp, TK_A_INOTIFY_WATCH, 0, NULL, &off); + dbg(rules->udev, "inotify watch of device disabled\n"); + } else { + pos = strstr(value, "watch"); + if (pos != NULL) { + const int on = 1; + + rule_add_key(&rule_tmp, TK_A_INOTIFY_WATCH, 0, NULL, &on); + dbg(rules->udev, "inotify watch of device requested\n"); + } + } continue; } err(rules->udev, "unknown key '%s' in %s:%u\n", key, filename, lineno); @@ -1550,10 +1540,6 @@ static int add_rule(struct udev_rules *rules, char *line, err(rules->udev, "PHYSDEV* values are deprecated and not available on recent kernels, " "please fix it in %s:%u\n", filename, lineno); - /* skip line if no valid key was found */ - if (!valid) - goto invalid; - /* add rule token */ rule_tmp.rule.rule.token_count = 1 + rule_tmp.token_cur; if (add_token(rules, &rule_tmp.rule) != 0) @@ -1649,7 +1635,7 @@ static int add_matching_files(struct udev *udev, struct udev_list_node *file_lis dbg(udev, "open directory '%s'\n", dirname); dir = opendir(dirname); if (dir == NULL) { - err(udev, "unable to open '%s': %m\n", dirname); + info(udev, "unable to open '%s': %m\n", dirname); return -1; } @@ -2277,6 +2263,9 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event break; udev_device_set_num_fake_partitions(event->dev, cur->key.num_fake_part); break; + case TK_A_INOTIFY_WATCH: + event->inotify_watch = cur->key.watch; + break; case TK_A_DEVLINK_PRIO: udev_device_set_devlink_priority(event->dev, cur->key.devlink_prio); break; @@ -2398,24 +2387,19 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event break; if (cur->key.op == OP_ASSIGN_FINAL) event->name_final = 1; - if (name[0] == '\0') { - free(event->name); - event->name = NULL; - break; - } util_strlcpy(name_str, name, sizeof(name_str)); udev_event_apply_format(event, name_str, sizeof(name_str)); if (esc == ESCAPE_UNSET || esc == ESCAPE_REPLACE) { count = udev_util_replace_chars(name_str, "/"); if (count > 0) info(event->udev, "%i character(s) replaced\n", count); - free(event->name); - event->name = strdup(name_str); - info(event->udev, "NAME '%s' %s:%u\n", - event->name, - &rules->buf[rule->rule.filename_off], - rule->rule.filename_line); } + free(event->name); + event->name = strdup(name_str); + info(event->udev, "NAME '%s' %s:%u\n", + event->name, + &rules->buf[rule->rule.filename_off], + rule->rule.filename_line); break; } case TK_A_DEVLINK: @@ -2504,9 +2488,8 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event rule->rule.filename_line); f = fopen(attr, "w"); if (f != NULL) { - if (!event->test) - if (fprintf(f, "%s", value) <= 0) - err(event->udev, "error writing ATTR{%s}: %m\n", attr); + if (fprintf(f, "%s", value) <= 0) + err(event->udev, "error writing ATTR{%s}: %m\n", attr); fclose(f); } else { err(event->udev, "error opening ATTR{%s} for writing: %m\n", attr);