udev-node.c revision b7e2b7641e2b7242fd1df717bccf5908f731eeab
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering * Copyright (C) 2003-2013 Kay Sievers <kay@vrfy.org>
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering * This program is free software: you can redistribute it and/or modify
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering * it under the terms of the GNU General Public License as published by
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering * the Free Software Foundation, either version 2 of the License, or
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering * (at your option) any later version.
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering * This program is distributed in the hope that it will be useful,
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering * but WITHOUT ANY WARRANTY; without even the implied warranty of
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering * GNU General Public License for more details.
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering * You should have received a copy of the GNU General Public License
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering * along with this program. If not, see <http://www.gnu.org/licenses/>.
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poetteringstatic int node_symlink(struct udev_device *dev, const char *node, const char *slink)
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering /* use relative link */
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering while (node[i] && (node[i] == slink[i])) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering /* preserve link with correct target, do not replace node of other device */
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering if (S_ISBLK(stats.st_mode) || S_ISCHR(stats.st_mode)) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering log_error("conflicting device node '%s' found, link to '%s' will not be created\n", slink, node);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering log_debug("preserve already existing symlink '%s' to '%s'\n", slink, target);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering utimensat(AT_FDCWD, slink, NULL, AT_SYMLINK_NOFOLLOW);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering log_debug("creating symlink '%s' to '%s'\n", slink, target);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering log_debug("atomically replace '%s'\n", slink);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering strscpyl(slink_tmp, sizeof(slink_tmp), slink, ".tmp-", udev_device_get_id_filename(dev), NULL);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering err = mkdir_parents_label(slink_tmp, 0755);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering log_error("symlink '%s' '%s' failed: %m\n", target, slink_tmp);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering log_error("rename '%s' '%s' failed: %m\n", slink_tmp, slink);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering/* find device node of device with highest priority */
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poetteringstatic const char *link_find_prioritized(struct udev_device *dev, bool add, const char *stackdir, char *buf, size_t bufsize)
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering struct udev *udev = udev_device_get_udev(dev);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering priority = udev_device_get_devlink_priority(dev);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering strscpy(buf, bufsize, udev_device_get_devnode(dev));
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering if (dent == NULL || dent->d_name[0] == '\0')
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering log_debug("found '%s' claiming '%s'\n", dent->d_name, stackdir);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering /* did we find ourself? */
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering if (streq(dent->d_name, udev_device_get_id_filename(dev)))
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering dev_db = udev_device_new_from_device_id(udev, dent->d_name);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering devnode = udev_device_get_devnode(dev_db);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering if (target == NULL || udev_device_get_devlink_priority(dev_db) > priority) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering log_debug("'%s' claims priority %i for '%s'\n",
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering udev_device_get_syspath(dev_db), udev_device_get_devlink_priority(dev_db), stackdir);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering priority = udev_device_get_devlink_priority(dev_db);
return target;
const char *target;
if (add) {
int err;
int fd;
if (fd >= 0)
int found;
found = 0;
if (found)
int err = 0;
goto out;
goto out;
if (apply) {
bool selinux = false;
#ifdef HAVE_SMACK
bool smack = false;
selinux = true;
#ifdef HAVE_SMACK
smack = true;
if (!selinux)
#ifdef HAVE_SMACK
if (!smack)
out:
return err;