#include "alloc-util.h"
#include "architecture.h"
#include "conf-files.h"
+#include "conf-parser.h"
#include "def.h"
#include "device-private.h"
#include "device-util.h"
};
struct UdevRules {
- usec_t dirs_ts_usec;
ResolveNameTiming resolve_name_timing;
Hashmap *known_users;
Hashmap *known_groups;
+ Hashmap *stats_by_path;
UdevRuleFile *current_file;
LIST_HEAD(UdevRuleFile, rule_files);
};
hashmap_free_free_key(rules->known_users);
hashmap_free_free_key(rules->known_groups);
+ hashmap_free(rules->stats_by_path);
return mfree(rules);
}
UdevRuleFile *rule_file;
bool ignore_line = false;
unsigned line_nr = 0;
+ struct stat st;
int r;
f = fopen(filename, "re");
if (errno == ENOENT)
return 0;
- return -errno;
+ return log_warning_errno(errno, "Failed to open %s, ignoring: %m", filename);
}
- (void) fd_warn_permissions(filename, fileno(f));
+ if (fstat(fileno(f), &st) < 0)
+ return log_warning_errno(errno, "Failed to stat %s, ignoring: %m", filename);
- if (null_or_empty_fd(fileno(f))) {
+ if (null_or_empty(&st)) {
log_debug("Skipping empty file: %s", filename);
return 0;
}
+ r = hashmap_put_stats_by_path(&rules->stats_by_path, filename, &st);
+ if (r < 0)
+ return log_warning_errno(errno, "Failed to save stat for %s, ignoring: %m", filename);
+
+ (void) fd_warn_permissions(filename, fileno(f));
+
log_debug("Reading rules file: %s", filename);
name = strdup(filename);
if (!rules)
return -ENOMEM;
- (void) udev_rules_check_timestamp(rules);
-
r = conf_files_list_strv(&files, ".rules", NULL, 0, RULES_DIRS);
if (r < 0)
return log_debug_errno(r, "Failed to enumerate rules files: %m");
return 0;
}
-bool udev_rules_check_timestamp(UdevRules *rules) {
+bool udev_rules_should_reload(UdevRules *rules) {
+ _cleanup_hashmap_free_ Hashmap *stats_by_path = NULL;
+ int r;
+
if (!rules)
- return false;
+ return true;
+
+ r = config_get_stats_by_path(".rules", NULL, 0, RULES_DIRS, /* check_dropins = */ false, &stats_by_path);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to get stats of udev rules, ignoring: %m");
+ return true;
+ }
+
+ if (!stats_by_path_equal(rules->stats_by_path, stats_by_path)) {
+ log_debug("Udev rules need reloading");
+ return true;
+ }
- return paths_check_timestamp(RULES_DIRS, &rules->dirs_ts_usec, true);
+ return false;
}
static bool token_match_string(UdevRuleToken *token, const char *str) {