use /run/udev/ if possible and fall back to /dev/.udev/

This commit is contained in:
Kay Sievers 2011-03-23 02:31:09 +01:00
parent 3c6ee19027
commit 4ec9c3e797
20 changed files with 188 additions and 80 deletions

25
NEWS
View File

@ -2,20 +2,27 @@ udev 167
========
Bugfixes.
The udev runtime data moved from /dev/.udev/ to /dev/.run/udev/.
On systemd systems the tmpfs mountpoint /var/run/ will have a
permanent "early-boot alias" /dev/.run/, where udev and a couple
of other early-boot tools will put their runtime data.
The udev runtime data moved from /dev/.udev/ to /run/udev/. The
/run mountpoint is supposed to be a tmpfs mounted during early boot,
available and writable to for all tools at any time during bootup,
it replaces /var/run/, which should become a symlink some day.
On systemd systems with LVM used, packagers must make sure, that
the systemd and initramfs version match. The initramfs needs to
create the /dev/.run/ mountpoint for udev to store the data, so
that systemd will not overmount it, which would make the udev
data from initramfs invisible.
If /run does not exist, or is not writable, udev will fall back using
/dev/.udev/.
On systemd systems with initramfs and LVM used, packagers must
make sure, that the systemd and initramfs versions match. The initramfs
needs to create the /run/ mountpoint for udev to store the data, and
mount this tmpfs to /run in the rootfs, so the that the udev database
is preserved for the udev version started in the rootfs.
The command 'udevadm info --convert-db' is gone. The udev daemon
itself, at startup, converts any old database version if necessary.
The fstab_import callout is no longer built or installed. Udev
should not be used to mount, does not watch changes to fstab, and
should not mirror fstab values in the udev database.
udev 166
========
Bugfixes.

View File

@ -34,7 +34,6 @@
#include "libudev.h"
#include "libudev-private.h"
#define TMPFILE "/dev/.run/udev/collect"
#define BUFSIZE 16
#define UDEV_ALARM_TIMEOUT 180
@ -338,6 +337,7 @@ static void everybody(void)
int main(int argc, char **argv)
{
struct udev *udev;
static const struct option options[] = {
{ "add", no_argument, NULL, 'a' },
{ "remove", no_argument, NULL, 'r' },
@ -349,8 +349,15 @@ int main(int argc, char **argv)
char *checkpoint, *us;
int fd;
int i;
int ret = 0;
int ret = EXIT_SUCCESS;
int prune = 0;
char tmpdir[UTIL_PATH_SIZE];
udev = udev_new();
if (udev == NULL) {
ret = EXIT_FAILURE;
goto exit;
}
while (1) {
int option;
@ -398,7 +405,8 @@ int main(int argc, char **argv)
if (debug)
fprintf(stderr, "Using checkpoint '%s'\n", checkpoint);
fd = prepare(TMPFILE, checkpoint);
util_strscpyl(tmpdir, sizeof(tmpdir), udev_get_run_path(udev), "/collect", NULL);
fd = prepare(tmpdir, checkpoint);
if (fd < 0) {
ret = 3;
goto out;
@ -454,11 +462,12 @@ int main(int argc, char **argv)
lockf(fd, F_ULOCK, 0);
close(fd);
out:
out:
if (debug)
everybody();
if (ret >= 0)
printf("COLLECT_%s=%d\n", checkpoint, ret);
exit:
exit:
udev_unref(udev);
return ret;
}

View File

@ -147,7 +147,7 @@ int main(int argc, char **argv)
}
util_path_encode(firmware, fwencpath, sizeof(fwencpath));
util_strscpyl(misspath, sizeof(misspath), udev_get_dev_path(udev), "/.run/udev/firmware-missing/", fwencpath, NULL);
util_strscpyl(misspath, sizeof(misspath), udev_get_run_path(udev), "/firmware-missing/", fwencpath, NULL);
util_strscpyl(loadpath, sizeof(loadpath), udev_get_sys_path(udev), devpath, "/loading", NULL);
if (fwfile == NULL) {

View File

@ -48,9 +48,10 @@ writeable() {
# Create a lock file for the current rules file.
lock_rules_file() {
[ -e /dev/.udev/ ] || return 0
RUNDIR=$(udevadm info --run)
[ -e "$RUNDIR" ] || return 0
RULES_LOCK="/dev/.udev/.lock-${RULES_FILE##*/}"
RULES_LOCK="$RUNDIR/.lock-${RULES_FILE##*/}"
retry=30
while ! mkdir $RULES_LOCK 2> /dev/null; do
@ -71,7 +72,8 @@ unlock_rules_file() {
# Choose the real rules file if it is writeable or a temporary file if not.
# Both files should be checked later when looking for existing rules.
choose_rules_file() {
local tmp_rules_file="/dev/.udev/tmp-rules--${RULES_FILE##*/}"
RUNDIR=$(udevadm info --run)
local tmp_rules_file="$RUNDIR/tmp-rules--${RULES_FILE##*/}"
[ -e "$RULES_FILE" -o -e "$tmp_rules_file" ] || PRINT_HEADER=1
if writeable ${RULES_FILE%/*}; then

View File

@ -31,7 +31,7 @@ static void udev_device_tag(struct udev_device *dev, const char *tag, bool add)
id = udev_device_get_id_filename(dev);
if (id == NULL)
return;
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/tags/", tag, "/", id, NULL);
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/tags/", tag, "/", id, NULL);
if (add) {
int fd;
@ -115,7 +115,7 @@ int udev_device_update_db(struct udev_device *udev_device)
return -1;
has_info = device_has_info(udev_device);
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/db3/", id, NULL);
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/data/", id, NULL);
/* do not store anything for otherwise empty devices */
if (!has_info &&
@ -176,7 +176,7 @@ int udev_device_delete_db(struct udev_device *udev_device)
id = udev_device_get_id_filename(udev_device);
if (id == NULL)
return -1;
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/db3/", id, NULL);
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/data/", id, NULL);
unlink(filename);
return 0;
}

View File

@ -254,7 +254,7 @@ int udev_device_read_db(struct udev_device *udev_device, const char *dbfile)
id = udev_device_get_id_filename(udev_device);
if (id == NULL)
return -1;
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/.run/udev/db3/", id, NULL);
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev_device->udev), "/data/", id, NULL);
dbfile = filename;
}

View File

@ -751,7 +751,7 @@ int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate)
struct dirent *dent;
char path[UTIL_PATH_SIZE];
util_strscpyl(path, sizeof(path), udev_get_dev_path(udev), "/.run/udev/tags/",
util_strscpyl(path, sizeof(path), udev_get_run_path(udev), "/tags/",
udev_list_entry_get_name(list_entry), NULL);
dir = opendir(path);
if (dir == NULL)

View File

@ -61,6 +61,9 @@ void udev_log(struct udev *udev,
const char *format, ...)
__attribute__((format(printf, 6, 7)));
const char *udev_get_rules_path(struct udev *udev);
const char *udev_get_run_config_path(struct udev *udev);
const char *udev_get_run_path(struct udev *udev);
const char *udev_set_run_path(struct udev *udev, const char *path);
struct udev_list_entry *udev_add_property(struct udev *udev, const char *key, const char *value);
struct udev_list_entry *udev_get_properties_list_entry(struct udev *udev);

View File

@ -103,10 +103,10 @@ void udev_queue_export_cleanup(struct udev_queue_export *udev_queue_export)
{
char filename[UTIL_PATH_SIZE];
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_queue_export->udev), "/.run/udev/queue.tmp", NULL);
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev_queue_export->udev), "/queue.tmp", NULL);
unlink(filename);
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_queue_export->udev), "/.run/udev/queue.bin", NULL);
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev_queue_export->udev), "/queue.bin", NULL);
unlink(filename);
}
@ -221,7 +221,7 @@ static int rebuild_queue_file(struct udev_queue_export *udev_queue_export)
}
/* create new queue file */
util_strscpyl(filename_tmp, sizeof(filename_tmp), udev_get_dev_path(udev_queue_export->udev), "/.run/udev/queue.tmp", NULL);
util_strscpyl(filename_tmp, sizeof(filename_tmp), udev_get_run_path(udev_queue_export->udev), "/queue.tmp", NULL);
new_queue_file = fopen(filename_tmp, "w+");
if (new_queue_file == NULL)
goto error;
@ -255,7 +255,7 @@ static int rebuild_queue_file(struct udev_queue_export *udev_queue_export)
goto error;
/* rename the new file on top of the old one */
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_queue_export->udev), "/.run/udev/queue.bin", NULL);
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev_queue_export->udev), "/queue.bin", NULL);
if (rename(filename_tmp, filename) != 0)
goto error;
@ -401,7 +401,7 @@ static void update_failed(struct udev_queue_export *udev_queue_export,
return;
/* location of failed file */
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/failed/",
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) {

View File

@ -214,7 +214,7 @@ static FILE *open_queue_file(struct udev_queue *udev_queue, unsigned long long i
char filename[UTIL_PATH_SIZE];
FILE *queue_file;
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_queue->udev), "/.run/udev/queue.bin", NULL);
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev_queue->udev), "/queue.bin", NULL);
queue_file = fopen(filename, "re");
if (queue_file == NULL)
return NULL;
@ -484,7 +484,7 @@ struct udev_list_entry *udev_queue_get_failed_list_entry(struct udev_queue *udev
if (udev_queue == NULL)
return NULL;
udev_list_cleanup_entries(udev_queue->udev, &udev_queue->failed_list);
util_strscpyl(path, sizeof(path), udev_get_dev_path(udev_queue->udev), "/.run/udev/failed", NULL);
util_strscpyl(path, sizeof(path), udev_get_run_path(udev_queue->udev), "/failed", NULL);
dir = opendir(path);
if (dir == NULL)
return NULL;

View File

@ -43,6 +43,8 @@ struct udev {
char *sys_path;
char *dev_path;
char *rules_path;
char *run_config_path;
char *run_path;
struct udev_list_node properties_list;
int log_priority;
};
@ -96,6 +98,14 @@ void udev_set_userdata(struct udev *udev, void *userdata)
udev->userdata = userdata;
}
static char *set_value(char **s, const char *v)
{
free(*s);
*s = strdup(v);
util_remove_trailing_chars(*s, '/');
return *s;
}
/**
* udev_new:
*
@ -111,7 +121,7 @@ struct udev *udev_new(void)
{
struct udev *udev;
const char *env;
char *config_file;
char *config_file = NULL;
FILE *f;
udev = calloc(1, sizeof(struct udev));
@ -121,31 +131,21 @@ struct udev *udev_new(void)
udev->log_fn = log_stderr;
udev->log_priority = LOG_ERR;
udev_list_init(&udev->properties_list);
udev->dev_path = strdup("/dev");
udev->sys_path = strdup("/sys");
config_file = strdup(SYSCONFDIR "/udev/udev.conf");
if (udev->dev_path == NULL ||
udev->sys_path == NULL ||
config_file == NULL)
goto err;
/* settings by environment and config file */
env = getenv("SYSFS_PATH");
if (env != NULL) {
free(udev->sys_path);
udev->sys_path = strdup(env);
util_remove_trailing_chars(udev->sys_path, '/');
udev_add_property(udev, "SYSFS_PATH", udev->sys_path);
}
/* custom config file */
env = getenv("UDEV_CONFIG_FILE");
if (env != NULL) {
free(config_file);
config_file = strdup(env);
util_remove_trailing_chars(config_file, '/');
udev_add_property(udev, "UDEV_CONFIG_FILE", udev->dev_path);
if (set_value(&config_file, env) == NULL)
goto err;
}
/* default config file */
if (config_file == NULL)
config_file = strdup(SYSCONFDIR "/udev/udev.conf");
if (config_file == NULL)
goto err;
f = fopen(config_file, "re");
if (f != NULL) {
char line[UTIL_LINE_SIZE];
@ -214,40 +214,57 @@ struct udev *udev_new(void)
continue;
}
if (strcmp(key, "udev_root") == 0) {
free(udev->dev_path);
udev->dev_path = strdup(val);
util_remove_trailing_chars(udev->dev_path, '/');
set_value(&udev->dev_path, val);
continue;
}
if (strcmp(key, "udev_run") == 0) {
set_value(&udev->run_config_path, val);
continue;
}
if (strcmp(key, "udev_rules") == 0) {
free(udev->rules_path);
udev->rules_path = strdup(val);
util_remove_trailing_chars(udev->rules_path, '/');
set_value(&udev->rules_path, val);
continue;
}
}
fclose(f);
}
env = getenv("UDEV_ROOT");
if (env != NULL) {
free(udev->dev_path);
udev->dev_path = strdup(env);
util_remove_trailing_chars(udev->dev_path, '/');
udev_add_property(udev, "UDEV_ROOT", udev->dev_path);
}
/* environment overwrites config */
env = getenv("UDEV_LOG");
if (env != NULL)
udev_set_log_priority(udev, util_log_priority(env));
if (udev->dev_path == NULL || udev->sys_path == NULL)
goto err;
env = getenv("UDEV_ROOT");
if (env != NULL) {
set_value(&udev->dev_path, env);
udev_add_property(udev, "UDEV_ROOT", udev->dev_path);
}
env = getenv("SYSFS_PATH");
if (env != NULL) {
set_value(&udev->sys_path, env);
udev_add_property(udev, "SYSFS_PATH", udev->sys_path);
}
/* set defaults */
if (udev->dev_path == NULL)
if (set_value(&udev->dev_path, "/dev") == NULL)
goto err;
if (udev->sys_path == NULL)
if (set_value(&udev->sys_path, "/sys") == NULL)
goto err;
if (udev->run_config_path == NULL)
if (set_value(&udev->run_config_path, "/run/udev") == NULL)
goto err;
dbg(udev, "context %p created\n", udev);
dbg(udev, "log_priority=%d\n", udev->log_priority);
dbg(udev, "config_file='%s'\n", config_file);
dbg(udev, "dev_path='%s'\n", udev->dev_path);
dbg(udev, "sys_path='%s'\n", udev->sys_path);
dbg(udev, "run_path='%s'\n", udev->run_config_path);
if (udev->rules_path != NULL)
dbg(udev, "rules_path='%s'\n", udev->rules_path);
free(config_file);
@ -294,6 +311,8 @@ void udev_unref(struct udev *udev)
free(udev->dev_path);
free(udev->sys_path);
free(udev->rules_path);
free(udev->run_path);
free(udev->run_config_path);
dbg(udev, "context %p released\n", udev);
free(udev);
}
@ -387,6 +406,39 @@ const char *udev_get_dev_path(struct udev *udev)
return udev->dev_path;
}
const char *udev_get_run_config_path(struct udev *udev)
{
return udev->run_config_path;
}
const char *udev_get_run_path(struct udev *udev)
{
if (udev->run_path != NULL)
return udev->run_path;
/* check if configured path exists */
if (access(udev->run_config_path, F_OK) < 0) {
char filename[UTIL_PATH_SIZE];
/* fall back to /dev/.udev if that exists */
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev", NULL);
if (access(filename, F_OK) >= 0)
if (set_value(&udev->run_path, filename) != NULL)
return udev->run_path;
}
/* use default path */
set_value(&udev->run_path, udev->run_config_path);
if (udev->run_path == NULL)
return udev->run_config_path;
return udev->run_path;
}
const char *udev_set_run_path(struct udev *udev, const char *path)
{
return set_value(&udev->run_path, path);
}
struct udev_list_entry *udev_add_property(struct udev *udev, const char *key, const char *value)
{
if (value == NULL) {

View File

@ -1732,6 +1732,7 @@ make_udev_root();
# create config file
open CONF, ">$udev_conf" || die "unable to create config file: $udev_conf";
print CONF "udev_root=\"$udev_root\"\n";
print CONF "udev_run=\"$udev_root/.udev\"\n";
print CONF "udev_rules=\"$PWD\"\n";
print CONF "udev_log=\"err\"\n";
close CONF;

View File

@ -292,7 +292,7 @@ static void link_update(struct udev_device *dev, const char *slink, bool add)
dbg(udev, "update symlink '%s' of '%s'\n", slink, udev_device_get_syspath(dev));
util_path_encode(&slink[strlen(udev_get_dev_path(udev))+1], name_enc, sizeof(name_enc));
util_strscpyl(dirname, sizeof(dirname), udev_get_dev_path(udev), "/.run/udev/links/", name_enc, NULL);
util_strscpyl(dirname, sizeof(dirname), udev_get_run_path(udev), "/links/", name_enc, NULL);
util_strscpyl(filename, sizeof(filename), dirname, "/", udev_device_get_id_filename(dev), NULL);
if (!add) {

View File

@ -1803,7 +1803,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
add_matching_files(udev, &file_list, SYSCONFDIR "/udev/rules.d", ".rules");
/* read dynamic/temporary rules */
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/rules.d", NULL);
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/rules.d", NULL);
udev_list_init(&sort_list);
add_matching_files(udev, &sort_list, filename, ".rules");

View File

@ -54,8 +54,8 @@ void udev_watch_restore(struct udev *udev)
if (inotify_fd < 0)
return;
util_strscpyl(oldname, sizeof(oldname), udev_get_dev_path(udev), "/.run/udev/watch.old", NULL);
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/watch", NULL);
util_strscpyl(oldname, sizeof(oldname), udev_get_run_path(udev), "/watch.old", NULL);
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/watch", NULL);
if (rename(filename, oldname) == 0) {
DIR *dir;
struct dirent *ent;
@ -118,7 +118,7 @@ void udev_watch_begin(struct udev *udev, struct udev_device *dev)
return;
}
snprintf(filename, sizeof(filename), "%s/.run/udev/watch/%d", udev_get_dev_path(udev), wd);
snprintf(filename, sizeof(filename), "%s/watch/%d", udev_get_run_path(udev), wd);
util_create_path(udev, filename);
unlink(filename);
symlink(udev_device_get_id_filename(dev), filename);
@ -141,7 +141,7 @@ void udev_watch_end(struct udev *udev, struct udev_device *dev)
info(udev, "removing watch on '%s'\n", udev_device_get_devnode(dev));
inotify_rm_watch(inotify_fd, wd);
snprintf(filename, sizeof(filename), "%s/.run/udev/watch/%d", udev_get_dev_path(udev), wd);
snprintf(filename, sizeof(filename), "%s/watch/%d", udev_get_run_path(udev), wd);
unlink(filename);
udev_device_set_watch_handle(dev, -1);
@ -158,7 +158,7 @@ struct udev_device *udev_watch_lookup(struct udev *udev, int wd)
if (inotify_fd < 0 || wd < 0)
return NULL;
snprintf(filename, sizeof(filename), "%s/.run/udev/watch/%d", udev_get_dev_path(udev), wd);
snprintf(filename, sizeof(filename), "%s/watch/%d", udev_get_run_path(udev), wd);
s = majmin;
l = util_strpcpy(&s, sizeof(majmin), udev_get_sys_path(udev));
len = readlink(filename, s, l);

View File

@ -73,7 +73,7 @@
<para>The udev rules are read from the files located in the
default rules directory <filename>/lib/udev/rules.d/</filename>,
the custom rules directory <filename>/etc/udev/rules.d/</filename>
and the temporary rules directory <filename>/var/run/udev/rules.d/</filename>.
and the temporary rules directory <filename>/run/udev/rules.d/</filename>.
All rule files are sorted and processed in lexical order, regardless
in which of these directories they live. Files in
<filename>/etc/udev/rules.d/</filename> have precedence over files with

View File

@ -218,6 +218,7 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
{ "attribute-walk", no_argument, NULL, 'a' },
{ "export-db", no_argument, NULL, 'e' },
{ "root", no_argument, NULL, 'r' },
{ "run", no_argument, NULL, 'R' },
{ "device-id-of-file", required_argument, NULL, 'd' },
{ "export", no_argument, NULL, 'x' },
{ "export-prefix", required_argument, NULL, 'P' },
@ -247,7 +248,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:Vh", options, NULL);
option = getopt_long(argc, argv, "aed:n:p:q:rxP:RVh", options, NULL);
if (option == -1)
break;
@ -331,6 +332,9 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
action = ACTION_ROOT;
root = true;
break;
case 'R':
printf("%s\n", udev_get_run_path(udev));
goto exit;
case 'd':
action = ACTION_DEVICE_ID_FILE;
util_strscpy(name, sizeof(name), optarg);

View File

@ -171,6 +171,8 @@ int main(int argc, char *argv[])
}
command = argv[optind];
info(udev, "runtime dir '%s'\n", udev_get_run_path(udev));
if (command != NULL)
for (i = 0; cmds[i].cmd != NULL; i++) {
if (strcmp(cmds[i].name, command) == 0) {

View File

@ -110,6 +110,12 @@
query returns the absolute path including the root directory.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--run</option></term>
<listitem>
<para>The udev runtime directory: <filename>/run/udev</filename>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--attribute-walk</option></term>
<listitem>

View File

@ -979,13 +979,15 @@ static int convert_db(struct udev *udev)
struct udev_list_entry *list_entry;
/* current database */
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/db3", NULL);
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/data", NULL);
if (access(filename, F_OK) >= 0)
return 0;
/* make sure we do not get here again */
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/db3/", NULL);
util_create_path(udev, filename);
udev_selinux_setfscreatecon(udev, udev_get_run_path(udev), S_IFDIR|0755);
mkdir(filename, 0755);
udev_selinux_resetfscreatecon(udev);
/* old database */
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/db", NULL);
@ -1044,8 +1046,7 @@ static int convert_db(struct udev *udev)
/* find old database with the encoded devpath name */
util_path_encode(udev_device_get_devpath(device), devpath, sizeof(devpath));
util_strscpyl(from, sizeof(from), udev_get_dev_path(udev),
"/.udev/db/", devpath, NULL);
util_strscpyl(from, sizeof(from), udev_get_dev_path(udev), "/.udev/db/", devpath, NULL);
if (lstat(from, &stats) == 0) {
if (!have_db) {
udev_device_read_db(device, from);
@ -1093,6 +1094,27 @@ int main(int argc, char *argv[])
info(udev, "version %s\n", VERSION);
udev_selinux_init(udev);
/* make sure, that our runtime dir exists and is writable */
if (utimensat(AT_FDCWD, udev_get_run_config_path(udev), NULL, 0) < 0) {
/* try to create our own subdirectory, do not create parent directories */
udev_selinux_setfscreatecon(udev, udev_get_run_config_path(udev), S_IFDIR|0755);
mkdir(udev_get_run_config_path(udev), 0755);
udev_selinux_resetfscreatecon(udev);
if (utimensat(AT_FDCWD, udev_get_run_config_path(udev), NULL, 0) >= 0) {
/* directory seems writable now */
udev_set_run_path(udev, udev_get_run_config_path(udev));
} else {
/* fall back to /dev/.udev */
char filename[UTIL_PATH_SIZE];
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev", NULL);
if (udev_set_run_path(udev, filename) == NULL)
goto exit;
}
}
info(udev, "runtime dir '%s'\n", udev_get_run_path(udev));
for (;;) {
int option;
@ -1252,7 +1274,7 @@ int main(int argc, char *argv[])
IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
/* watch dynamic rules directory */
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/rules.d", NULL);
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/rules.d", NULL);
if (stat(filename, &statbuf) != 0) {
util_create_path(udev, filename);
udev_selinux_setfscreatecon(udev, filename, S_IFDIR|0755);