mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
udevadm: info --cleanup-db
Most of the udev database from initramfs should be deleted before starting udev in the real root. udevadm: info --cleanup-db deletes all database entries in /run/udev. Events that processed IMPORT{db}, or mark devices explicitely as persistent, will be excluded.
This commit is contained in:
parent
09913ced8c
commit
9ead662791
6
NEWS
6
NEWS
@ -2,6 +2,12 @@ udev 168
|
||||
========
|
||||
Bugfixes.
|
||||
|
||||
warning if /run is not writable.
|
||||
|
||||
udevadm control --exit
|
||||
|
||||
udevadm info --cleanup-db
|
||||
|
||||
udev 167
|
||||
========
|
||||
Bugfixes.
|
||||
|
2
TODO
2
TODO
@ -1,5 +1,3 @@
|
||||
- do not write age/configured in initramfs
|
||||
|
||||
- remove deprecated trigger --type=failed logic
|
||||
|
||||
- remove deprecated BUS=, SYSFS{}=, ID= keys
|
||||
|
@ -134,6 +134,13 @@ int udev_device_update_db(struct udev_device *udev_device)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* set 'sticky' bit to indicate that we should not clean the
|
||||
* database when we transition from initramfs to the real root
|
||||
*/
|
||||
if (udev_device_get_db_persist(udev_device))
|
||||
fchmod(fileno(f), 01644);
|
||||
|
||||
if (has_info) {
|
||||
size_t devlen = strlen(udev_get_dev_path(udev))+1;
|
||||
struct udev_list_entry *list_entry;
|
||||
|
@ -89,6 +89,7 @@ struct udev_device {
|
||||
bool uevent_loaded;
|
||||
bool is_initialized;
|
||||
bool sysattr_list_read;
|
||||
bool db_persist;
|
||||
};
|
||||
|
||||
struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value)
|
||||
@ -1774,3 +1775,13 @@ int udev_device_set_ifindex(struct udev_device *udev_device, int ifindex)
|
||||
udev_device_add_property(udev_device, "IFINDEX", num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool udev_device_get_db_persist(struct udev_device *udev_device)
|
||||
{
|
||||
return udev_device->db_persist;
|
||||
}
|
||||
|
||||
void udev_device_set_db_persist(struct udev_device *udev_device)
|
||||
{
|
||||
udev_device->db_persist = true;
|
||||
}
|
||||
|
@ -109,6 +109,8 @@ int udev_device_set_watch_handle(struct udev_device *udev_device, int handle);
|
||||
int udev_device_get_ifindex(struct udev_device *udev_device);
|
||||
int udev_device_set_ifindex(struct udev_device *udev_device, int ifindex);
|
||||
void udev_device_set_info_loaded(struct udev_device *device);
|
||||
bool udev_device_get_db_persist(struct udev_device *udev_device);
|
||||
void udev_device_set_db_persist(struct udev_device *udev_device);
|
||||
|
||||
/* libudev-device-private.c */
|
||||
int udev_device_update_db(struct udev_device *udev_device);
|
||||
|
@ -150,6 +150,7 @@ enum token_type {
|
||||
|
||||
TK_A_STRING_ESCAPE_NONE,
|
||||
TK_A_STRING_ESCAPE_REPLACE,
|
||||
TK_A_DB_PERSIST,
|
||||
TK_A_INOTIFY_WATCH, /* int */
|
||||
TK_A_DEVLINK_PRIO, /* int */
|
||||
TK_A_OWNER, /* val */
|
||||
@ -284,6 +285,7 @@ static const char *token_str(enum token_type type)
|
||||
|
||||
[TK_A_STRING_ESCAPE_NONE] = "A STRING_ESCAPE_NONE",
|
||||
[TK_A_STRING_ESCAPE_REPLACE] = "A STRING_ESCAPE_REPLACE",
|
||||
[TK_A_DB_PERSIST] = "A DB_PERSIST",
|
||||
[TK_A_INOTIFY_WATCH] = "A INOTIFY_WATCH",
|
||||
[TK_A_DEVLINK_PRIO] = "A DEVLINK_PRIO",
|
||||
[TK_A_OWNER] = "A OWNER",
|
||||
@ -370,6 +372,7 @@ static void dump_token(struct udev_rules *rules, struct token *token)
|
||||
break;
|
||||
case TK_A_STRING_ESCAPE_NONE:
|
||||
case TK_A_STRING_ESCAPE_REPLACE:
|
||||
case TK_A_DB_PERSIST:
|
||||
dbg(rules->udev, "%s\n", token_str(type));
|
||||
break;
|
||||
case TK_M_TEST:
|
||||
@ -1045,6 +1048,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
|
||||
break;
|
||||
case TK_A_STRING_ESCAPE_NONE:
|
||||
case TK_A_STRING_ESCAPE_REPLACE:
|
||||
case TK_A_DB_PERSIST:
|
||||
break;
|
||||
case TK_A_RUN:
|
||||
token->key.value_off = add_string(rule_tmp->rules, value);
|
||||
@ -1572,6 +1576,7 @@ static int add_rule(struct udev_rules *rules, char *line,
|
||||
rule_add_key(&rule_tmp, TK_A_DEVLINK_PRIO, op, NULL, &prio);
|
||||
dbg(rules->udev, "link priority=%i\n", prio);
|
||||
}
|
||||
|
||||
pos = strstr(value, "event_timeout=");
|
||||
if (pos != NULL) {
|
||||
int tout = atoi(&pos[strlen("event_timeout=")]);
|
||||
@ -1579,6 +1584,7 @@ static int add_rule(struct udev_rules *rules, char *line,
|
||||
rule_add_key(&rule_tmp, TK_A_EVENT_TIMEOUT, op, NULL, &tout);
|
||||
dbg(rules->udev, "event timeout=%i\n", tout);
|
||||
}
|
||||
|
||||
pos = strstr(value, "string_escape=");
|
||||
if (pos != NULL) {
|
||||
pos = &pos[strlen("string_escape=")];
|
||||
@ -1587,6 +1593,11 @@ static int add_rule(struct udev_rules *rules, char *line,
|
||||
else if (strncmp(pos, "replace", strlen("replace")) == 0)
|
||||
rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_REPLACE, op, NULL, NULL);
|
||||
}
|
||||
|
||||
pos = strstr(value, "db_persist=");
|
||||
if (pos != NULL)
|
||||
rule_add_key(&rule_tmp, TK_A_DB_PERSIST, op, NULL, NULL);
|
||||
|
||||
pos = strstr(value, "nowatch");
|
||||
if (pos != NULL) {
|
||||
const int off = 0;
|
||||
@ -1602,11 +1613,13 @@ static int add_rule(struct udev_rules *rules, char *line,
|
||||
dbg(rules->udev, "inotify watch of device requested\n");
|
||||
}
|
||||
}
|
||||
|
||||
pos = strstr(value, "static_node=");
|
||||
if (pos != NULL) {
|
||||
rule_add_key(&rule_tmp, TK_A_STATIC_NODE, op, &pos[strlen("static_node=")], NULL);
|
||||
rule_tmp.rule.rule.has_static_node = true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
err(rules->udev, "unknown key '%s' in %s:%u\n", key, filename, lineno);
|
||||
@ -2332,6 +2345,9 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
|
||||
const char *key = &rules->buf[cur->key.value_off];
|
||||
const char *value;
|
||||
|
||||
/* implicitely mark database as persistent across initramfs transition */
|
||||
udev_device_set_db_persist(event->dev);
|
||||
|
||||
value = udev_device_get_property_value(event->dev_db, key);
|
||||
if (value != NULL) {
|
||||
struct udev_list_entry *entry;
|
||||
@ -2407,6 +2423,9 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
|
||||
case TK_A_STRING_ESCAPE_REPLACE:
|
||||
esc = ESCAPE_REPLACE;
|
||||
break;
|
||||
case TK_A_DB_PERSIST:
|
||||
udev_device_set_db_persist(event->dev);
|
||||
break;
|
||||
case TK_A_INOTIFY_WATCH:
|
||||
if (event->inotify_watch_final)
|
||||
break;
|
||||
|
@ -200,6 +200,81 @@ static int export_devices(struct udev *udev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cleanup_dir(DIR *dir, mode_t mask, int depth)
|
||||
{
|
||||
struct dirent *dent;
|
||||
|
||||
if (depth <= 0)
|
||||
return;
|
||||
|
||||
for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
|
||||
struct stat stats;
|
||||
|
||||
if (dent->d_name[0] == '.')
|
||||
continue;
|
||||
if (fstatat(dirfd(dir), dent->d_name, &stats, AT_SYMLINK_NOFOLLOW) != 0)
|
||||
continue;
|
||||
if ((stats.st_mode & mask) != 0)
|
||||
continue;
|
||||
if (S_ISDIR(stats.st_mode)) {
|
||||
DIR *dir2;
|
||||
|
||||
dir2 = fdopendir(openat(dirfd(dir), dent->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC));
|
||||
if (dir2 != NULL) {
|
||||
cleanup_dir(dir2, mask, depth-1);
|
||||
closedir(dir2);
|
||||
}
|
||||
unlinkat(dirfd(dir), dent->d_name, AT_REMOVEDIR);
|
||||
} else {
|
||||
unlinkat(dirfd(dir), dent->d_name, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cleanup_db(struct udev *udev)
|
||||
{
|
||||
char filename[UTIL_PATH_SIZE];
|
||||
DIR *dir;
|
||||
|
||||
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/queue.bin", NULL);
|
||||
unlink(filename);
|
||||
|
||||
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/data", NULL);
|
||||
dir = opendir(filename);
|
||||
if (dir != NULL) {
|
||||
cleanup_dir(dir, S_ISVTX, 1);
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/links", NULL);
|
||||
dir = opendir(filename);
|
||||
if (dir != NULL) {
|
||||
cleanup_dir(dir, 0, 2);
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/tags", NULL);
|
||||
dir = opendir(filename);
|
||||
if (dir != NULL) {
|
||||
cleanup_dir(dir, 0, 2);
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/watch", NULL);
|
||||
dir = opendir(filename);
|
||||
if (dir != NULL) {
|
||||
cleanup_dir(dir, 0, 1);
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/firmware-missing", NULL);
|
||||
dir = opendir(filename);
|
||||
if (dir != NULL) {
|
||||
cleanup_dir(dir, 0, 1);
|
||||
closedir(dir);
|
||||
}
|
||||
}
|
||||
|
||||
int udevadm_info(struct udev *udev, int argc, char *argv[])
|
||||
{
|
||||
struct udev_device *device = NULL;
|
||||
@ -216,6 +291,7 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
|
||||
{ "path", required_argument, NULL, 'p' },
|
||||
{ "query", required_argument, NULL, 'q' },
|
||||
{ "attribute-walk", no_argument, NULL, 'a' },
|
||||
{ "cleanup-db", no_argument, NULL, 'c' },
|
||||
{ "export-db", no_argument, NULL, 'e' },
|
||||
{ "root", no_argument, NULL, 'r' },
|
||||
{ "run", no_argument, NULL, 'R' },
|
||||
@ -248,7 +324,7 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
|
||||
int option;
|
||||
struct stat statbuf;
|
||||
|
||||
option = getopt_long(argc, argv, "aed:n:p:q:rxP:RVh", options, NULL);
|
||||
option = getopt_long(argc, argv, "aced:n:p:q:rxP:RVh", options, NULL);
|
||||
if (option == -1)
|
||||
break;
|
||||
|
||||
@ -345,6 +421,9 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
|
||||
case 'e':
|
||||
export_devices(udev);
|
||||
goto exit;
|
||||
case 'c':
|
||||
cleanup_db(udev);
|
||||
goto exit;
|
||||
case 'x':
|
||||
export = true;
|
||||
break;
|
||||
@ -371,6 +450,7 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
|
||||
" --export export key/value pairs\n"
|
||||
" --export-prefix export the key name with a prefix\n"
|
||||
" --export-db export the content of the udev database\n"
|
||||
" --cleanup-db cleanup the udev database\n"
|
||||
" --help\n\n");
|
||||
goto exit;
|
||||
default:
|
||||
|
@ -149,6 +149,12 @@
|
||||
<para>Export the content of the udev database.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--cleanup-db</option></term>
|
||||
<listitem>
|
||||
<para>Cleanup the udev database.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--version</option></term>
|
||||
<listitem>
|
||||
|
Loading…
Reference in New Issue
Block a user