now. Non-systemd systems need to ship their own rule if they
need these filesystems auto-mounted.
+The long deprecated keys: SYSFS, ID, BUS have been removed.
+
+The support for 'udevadm trigger --type=failed, and the
+RUN{fail_event_on_error} attribute was removed.
+
udev 173
========
Bugfixes.
+ - validate the two hex chars in replace_chars \x
+
- test (now fixed) /dev/tape/ links
- /run/udev/control socket
- move udevadm -> --bindir
- - remove deprecated trigger --type=failed logic
-
- - remove deprecated BUS=, SYSFS{}=, ID= keys
-
- kill tabs?
- warn about RUN+="socket:"
udev_queue_get_seqnum_is_finished
udev_queue_get_seqnum_sequence_is_finished
udev_queue_get_queued_list_entry
-udev_queue_get_failed_list_entry
udev_queue_get_kernel_seqnum
udev_queue_get_udev_seqnum
</SECTION>
void udev_queue_export_cleanup(struct udev_queue_export *udev_queue_export);
int udev_queue_export_device_queued(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device);
int udev_queue_export_device_finished(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device);
-int udev_queue_export_device_failed(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device);
/* libudev-util.c */
#define UTIL_PATH_SIZE 1024
struct udev_queue_export {
struct udev *udev;
- int failed_count; /* number of failed events exported */
int queued_count; /* number of unfinished events exported in queue file */
FILE *queue_file;
unsigned long long int seqnum_max; /* earliest sequence number in queue file */
enum device_state {
DEVICE_QUEUED,
DEVICE_FINISHED,
- DEVICE_FAILED,
};
static inline size_t queue_record_size(size_t devpath_len)
return err;
}
-static void update_failed(struct udev_queue_export *udev_queue_export,
- struct udev_device *udev_device, enum device_state state)
-{
- struct udev *udev = udev_device_get_udev(udev_device);
- char filename[UTIL_PATH_SIZE];
-
- if (state != DEVICE_FAILED && udev_queue_export->failed_count == 0)
- return;
-
- /* location of failed file */
- util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/failed/",
- udev_device_get_subsystem(udev_device), ":", udev_device_get_sysname(udev_device), NULL);
-
- switch (state) {
- case DEVICE_FAILED:
- /* record event in the failed directory */
- udev_queue_export->failed_count++;
- util_create_path(udev, filename);
- symlink(udev_device_get_devpath(udev_device), filename);
- break;
-
- case DEVICE_QUEUED:
- /* delete failed file */
- if (unlink(filename) == 0) {
- util_delete_path(udev, filename);
- udev_queue_export->failed_count--;
- }
- break;
-
- case DEVICE_FINISHED:
- break;
- }
-
- return;
-}
-
static int update(struct udev_queue_export *udev_queue_export,
struct udev_device *udev_device, enum device_state state)
{
- update_failed(udev_queue_export, udev_device, state);
-
if (update_queue(udev_queue_export, udev_device, state) != 0)
return -1;
{
return update(udev_queue_export, udev_device, DEVICE_FINISHED);
}
-
-int udev_queue_export_device_failed(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device)
-{
- return update(udev_queue_export, udev_device, DEVICE_FAILED);
-}
struct udev *udev;
int refcount;
struct udev_list queue_list;
- struct udev_list failed_list;
};
/**
udev_queue->refcount = 1;
udev_queue->udev = udev;
udev_list_init(udev, &udev_queue->queue_list, false);
- udev_list_init(udev, &udev_queue->failed_list, false);
return udev_queue;
}
if (udev_queue->refcount > 0)
return;
udev_list_cleanup(&udev_queue->queue_list);
- udev_list_cleanup(&udev_queue->failed_list);
free(udev_queue);
}
return udev_list_get_entry(&udev_queue->queue_list);
}
-/**
- * udev_queue_get_failed_list_entry:
- * @udev_queue: udev queue context
- *
- * Returns: the first entry of the list of recorded failed events.
- **/
+struct udev_list_entry *udev_queue_get_failed_list_entry(struct udev_queue *udev_queue);
UDEV_EXPORT struct udev_list_entry *udev_queue_get_failed_list_entry(struct udev_queue *udev_queue)
{
- char path[UTIL_PATH_SIZE];
- DIR *dir;
- struct dirent *dent;
-
- if (udev_queue == NULL)
- return NULL;
- udev_list_cleanup(&udev_queue->failed_list);
- util_strscpyl(path, sizeof(path), udev_get_run_path(udev_queue->udev), "/failed", NULL);
- dir = opendir(path);
- if (dir == NULL)
- return NULL;
- for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
- char filename[UTIL_PATH_SIZE];
- char syspath[UTIL_PATH_SIZE];
- char *s;
- size_t l;
- ssize_t len;
- struct stat statbuf;
-
- if (dent->d_name[0] == '.')
- continue;
- s = syspath;
- l = util_strpcpyl(&s, sizeof(syspath), udev_get_sys_path(udev_queue->udev), NULL);
- len = readlinkat(dirfd(dir), dent->d_name, s, l);
- if (len <= 0 || (size_t)len == l)
- continue;
- s[len] = '\0';
- dbg(udev_queue->udev, "found '%s' [%s]\n", syspath, dent->d_name);
- util_strscpyl(filename, sizeof(filename), syspath, "/uevent", NULL);
- if (stat(filename, &statbuf) != 0)
- continue;
- udev_list_entry_add(&udev_queue->failed_list, syspath, NULL);
- }
- closedir(dir);
- return udev_list_get_entry(&udev_queue->failed_list);
+ errno = ENOSYS;
+ return NULL;
}
int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue,
unsigned long long int start, unsigned long long int end);
struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue);
-struct udev_list_entry *udev_queue_get_failed_list_entry(struct udev_queue *udev_queue);
#ifdef __cplusplus
} /* extern "C" */
udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue))
printf("queued: '%s' [%s]\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
printf("\n");
- printf("get failed list\n");
- udev_list_entry_foreach(list_entry, udev_queue_get_failed_list_entry(udev_queue))
- printf("failed: '%s'\n", udev_list_entry_get_name(list_entry));
- printf("\n");
list_entry = udev_queue_get_queued_list_entry(udev_queue);
if (list_entry != NULL) {
# After creation and removal the result is checked against the
# expected value and the result is printed.
#
-# Copyright (C) 2004-2008 Kay Sievers <kay.sievers@vrfy.org>
+# Copyright (C) 2004-2011 Kay Sievers <kay.sievers@vrfy.org>
# Copyright (C) 2004 Leann Ogasawara <ogasawara@osdl.org>
use warnings;
union {
unsigned int attr_off;
int devlink_unique;
- int fail_on_error;
unsigned int rule_goto;
mode_t mode;
uid_t uid;
break;
case TK_A_RUN:
token->key.value_off = add_string(rule_tmp->rules, value);
- token->key.fail_on_error = *(int *)data;
break;
case TK_A_INOTIFY_WATCH:
case TK_A_DEVLINK_PRIO:
char *linepos;
char *attr;
struct rule_tmp rule_tmp;
- bool bus_warn = false;
- bool sysfs_warn = false;
- bool id_warn = false;
memset(&rule_tmp, 0x00, sizeof(struct rule_tmp));
rule_tmp.rules = rules;
continue;
}
- if (strcmp(key, "ID") == 0) {
- if (!id_warn) {
- id_warn = true;
- err(rules->udev, "ID= will be removed in a future udev version, "
- "please use KERNEL= to match the event device, or KERNELS= "
- "to match a parent device, in %s:%u\n", filename, lineno);
- }
- if (op > OP_MATCH_MAX) {
- err(rules->udev, "invalid KERNELS operation\n");
- goto invalid;
- }
- rule_add_key(&rule_tmp, TK_M_KERNELS, op, value, NULL);
- continue;
- }
-
if (strcmp(key, "SUBSYSTEMS") == 0) {
if (op > OP_MATCH_MAX) {
err(rules->udev, "invalid SUBSYSTEMS operation\n");
continue;
}
- if (strcmp(key, "BUS") == 0) {
- if (!bus_warn) {
- bus_warn = true;
- err(rules->udev, "BUS= will be removed in a future udev version, "
- "please use SUBSYSTEM= to match the event device, or SUBSYSTEMS= "
- "to match a parent device, in %s:%u\n", filename, lineno);
- }
- if (op > OP_MATCH_MAX) {
- err(rules->udev, "invalid SUBSYSTEMS operation\n");
- goto invalid;
- }
- rule_add_key(&rule_tmp, TK_M_SUBSYSTEMS, op, value, NULL);
- continue;
- }
-
if (strcmp(key, "DRIVERS") == 0) {
if (op > OP_MATCH_MAX) {
err(rules->udev, "invalid DRIVERS operation\n");
continue;
}
- if (strncmp(key, "SYSFS{", sizeof("SYSFS{")-1) == 0) {
- if (!sysfs_warn) {
- sysfs_warn = true;
- err(rules->udev, "SYSFS{}= will be removed in a future udev version, "
- "please use ATTR{}= to match the event device, or ATTRS{}= "
- "to match a parent device, in %s:%u\n", filename, lineno);
- }
- if (op > OP_MATCH_MAX) {
- err(rules->udev, "invalid ATTRS operation\n");
- goto invalid;
- }
- attr = get_key_attribute(rules->udev, key + sizeof("ATTRS")-1);
- if (attr == NULL) {
- err(rules->udev, "error parsing ATTRS attribute\n");
- goto invalid;
- }
- rule_add_key(&rule_tmp, TK_M_ATTRS, op, value, attr);
- continue;
- }
-
if (strncmp(key, "ENV{", sizeof("ENV{")-1) == 0) {
attr = get_key_attribute(rules->udev, key + sizeof("ENV")-1);
if (attr == NULL) {
continue;
}
- if (strncmp(key, "RUN", sizeof("RUN")-1) == 0) {
- int flag = 0;
-
- attr = get_key_attribute(rules->udev, key + sizeof("RUN")-1);
- if (attr != NULL && strstr(attr, "fail_event_on_error"))
- flag = 1;
- rule_add_key(&rule_tmp, TK_A_RUN, op, value, &flag);
+ if (strcmp(key, "RUN") == 0) {
+ rule_add_key(&rule_tmp, TK_A_RUN, op, value, NULL);
continue;
}
break;
}
case TK_A_RUN: {
- struct udev_list_entry *list_entry;
-
if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL)
udev_list_cleanup(&event->run_list);
info(event->udev, "RUN '%s' %s:%u\n",
&rules->buf[cur->key.value_off],
&rules->buf[rule->rule.filename_off],
rule->rule.filename_line);
- list_entry = udev_list_entry_add(&event->run_list, &rules->buf[cur->key.value_off], NULL);
- if (cur->key.fail_on_error)
- udev_list_entry_set_num(list_entry, true);
+ udev_list_entry_add(&event->run_list, &rules->buf[cur->key.value_off], NULL);
break;
}
case TK_A_GOTO:
}
}
-static int scan_failed(struct udev_enumerate *udev_enumerate)
-{
- struct udev *udev = udev_enumerate_get_udev(udev_enumerate);
- struct udev_queue *udev_queue;
- struct udev_list_entry *list_entry;
-
- udev_queue = udev_queue_new(udev);
- if (udev_queue == NULL)
- return -1;
- udev_list_entry_foreach(list_entry, udev_queue_get_failed_list_entry(udev_queue))
- udev_enumerate_add_syspath(udev_enumerate, udev_list_entry_get_name(list_entry));
- return 0;
-}
-
static const char *keyval(const char *str, const char **val, char *buf, size_t size)
{
char *pos;
enum {
TYPE_DEVICES,
TYPE_SUBSYSTEMS,
- TYPE_FAILED,
} device_type = TYPE_DEVICES;
const char *action = "change";
struct udev_enumerate *udev_enumerate;
device_type = TYPE_DEVICES;
} else if (strcmp(optarg, "subsystems") == 0) {
device_type = TYPE_SUBSYSTEMS;
- } else if (strcmp(optarg, "failed") == 0) {
- device_type = TYPE_FAILED;
} else {
err(udev, "unknown type --type=%s\n", optarg);
rc = 2;
" --type= type of events to trigger\n"
" devices sys devices (default)\n"
" subsystems sys subsystems and drivers\n"
- " failed trigger only the events which have been\n"
- " marked as failed during a previous run\n"
" --action=<action> event action value, default is \"change\"\n"
" --subsystem-match=<subsystem> trigger devices from a matching subsystem\n"
" --subsystem-nomatch=<subsystem> exclude devices from a matching subsystem\n"
}
switch (device_type) {
- case TYPE_FAILED:
- err(udev, "--type=failed is deprecated and will be removed from a future udev release.\n");
- scan_failed(udev_enumerate);
- exec_list(udev_enumerate, action);
- goto exit;
case TYPE_SUBSYSTEMS:
udev_enumerate_scan_subsystems(udev_enumerate);
exec_list(udev_enumerate, action);
udev_list_node_remove(&event->node);
if (export) {
- /* mark as failed, if "add" event returns non-zero */
- if (event->exitcode != 0 && strcmp(udev_device_get_action(event->dev), "remove") != 0)
- udev_queue_export_device_failed(udev_queue_export, event->dev);
- else
- udev_queue_export_device_finished(udev_queue_export, event->dev);
+ udev_queue_export_device_finished(udev_queue_export, event->dev);
info(event->udev, "seq %llu done with %i\n", udev_device_get_seqnum(event->dev), event->exitcode);
}
udev_device_unref(event->dev);
for (;;) {
struct udev_event *udev_event;
struct worker_message msg;
- int failed = 0;
int err;
info(udev, "seq %llu running\n", udev_device_get_seqnum(dev));
err = udev_event_execute_rules(udev_event, rules, &sigmask_orig);
if (err == 0)
- failed = udev_event_execute_run(udev_event, &sigmask_orig);
+ udev_event_execute_run(udev_event, &sigmask_orig);
/* apply/restore inotify watch */
if (err == 0 && udev_event->inotify_watch) {
memset(&msg, 0, sizeof(struct worker_message));
if (err != 0)
msg.exitcode = err;
- else if (failed != 0)
- msg.exitcode = failed;
msg.pid = getpid();
send(worker_watch[WRITE_END], &msg, sizeof(struct worker_message), 0);