/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <ctype.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/types.h>

#include "sd-device.h"

#include "alloc-util.h"
#include "chase-symlinks.h"
#include "device-internal.h"
#include "device-private.h"
#include "device-util.h"
#include "devnum-util.h"
#include "dirent-util.h"
#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
#include "fs-util.h"
#include "hashmap.h"
#include "id128-util.h"
#include "macro.h"
#include "missing_magic.h"
#include "netlink-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "set.h"
#include "socket-util.h"
#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
#include "strxcpyx.h"
#include "user-util.h"

int device_new_aux(sd_device **ret) {
        sd_device *device;

        assert(ret);

        device = new(sd_device, 1);
        if (!device)
                return -ENOMEM;

        *device = (sd_device) {
                .n_ref = 1,
                .devmode = MODE_INVALID,
                .devuid = UID_INVALID,
                .devgid = GID_INVALID,
                .action = _SD_DEVICE_ACTION_INVALID,
        };

        *ret = device;
        return 0;
}

static sd_device *device_free(sd_device *device) {
        assert(device);

        sd_device_unref(device->parent);
        free(device->syspath);
        free(device->sysname);
        free(device->devtype);
        free(device->devname);
        free(device->subsystem);
        free(device->driver_subsystem);
        free(device->driver);
        free(device->device_id);
        free(device->properties_strv);
        free(device->properties_nulstr);

        ordered_hashmap_free(device->properties);
        ordered_hashmap_free(device->properties_db);
        hashmap_free(device->sysattr_values);
        set_free(device->sysattrs);
        set_free(device->all_tags);
        set_free(device->current_tags);
        set_free(device->devlinks);
        hashmap_free(device->children);

        return mfree(device);
}

DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_device, sd_device, device_free);

int device_add_property_aux(sd_device *device, const char *key, const char *value, bool db) {
        OrderedHashmap **properties;

        assert(device);
        assert(key);

        if (db)
                properties = &device->properties_db;
        else
                properties = &device->properties;

        if (value) {
                _unused_ _cleanup_free_ char *old_value = NULL;
                _cleanup_free_ char *new_key = NULL, *new_value = NULL, *old_key = NULL;
                int r;

                r = ordered_hashmap_ensure_allocated(properties, &string_hash_ops_free_free);
                if (r < 0)
                        return r;

                new_key = strdup(key);
                if (!new_key)
                        return -ENOMEM;

                new_value = strdup(value);
                if (!new_value)
                        return -ENOMEM;

                old_value = ordered_hashmap_get2(*properties, key, (void**) &old_key);

                /* ordered_hashmap_replace() does not fail when the hashmap already has the entry. */
                r = ordered_hashmap_replace(*properties, new_key, new_value);
                if (r < 0)
                        return r;

                TAKE_PTR(new_key);
                TAKE_PTR(new_value);
        } else {
                _unused_ _cleanup_free_ char *old_value = NULL;
                _cleanup_free_ char *old_key = NULL;

                old_value = ordered_hashmap_remove2(*properties, key, (void**) &old_key);
        }

        if (!db) {
                device->properties_generation++;
                device->properties_buf_outdated = true;
        }

        return 0;
}

int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
        _cleanup_free_ char *syspath = NULL;
        const char *devpath;
        int r;

        assert(device);
        assert(_syspath);

        if (verify) {
                _cleanup_close_ int fd = -EBADF;

                /* The input path maybe a symlink located outside of /sys. Let's try to chase the symlink at first.
                 * The primary usecase is that e.g. /proc/device-tree is a symlink to /sys/firmware/devicetree/base.
                 * By chasing symlinks in the path at first, we can call sd_device_new_from_path() with such path. */
                r = chase_symlinks(_syspath, NULL, 0, &syspath, &fd);
                if (r == -ENOENT)
                         /* the device does not exist (any more?) */
                        return log_debug_errno(SYNTHETIC_ERRNO(ENODEV),
                                               "sd-device: Failed to chase symlinks in \"%s\".", _syspath);
                if (r < 0)
                        return log_debug_errno(r, "sd-device: Failed to get target of '%s': %m", _syspath);

                if (!path_startswith(syspath, "/sys")) {
                        _cleanup_free_ char *real_sys = NULL, *new_syspath = NULL;
                        char *p;

                        /* /sys is a symlink to somewhere sysfs is mounted on? In that case, we convert the path to real sysfs to "/sys". */
                        r = chase_symlinks("/sys", NULL, 0, &real_sys, NULL);
                        if (r < 0)
                                return log_debug_errno(r, "sd-device: Failed to chase symlink /sys: %m");

                        p = path_startswith(syspath, real_sys);
                        if (!p)
                                return log_debug_errno(SYNTHETIC_ERRNO(ENODEV),
                                                       "sd-device: Canonicalized path '%s' does not starts with sysfs mount point '%s'",
                                                       syspath, real_sys);

                        new_syspath = path_join("/sys", p);
                        if (!new_syspath)
                                return log_oom_debug();

                        free_and_replace(syspath, new_syspath);
                        path_simplify(syspath);
                }

                if (path_startswith(syspath, "/sys/devices/")) {
                        /* For proper devices, stricter rules apply: they must have a 'uevent' file,
                         * otherwise we won't allow them */

                        if (faccessat(fd, "uevent", F_OK, 0) < 0) {
                                if (errno == ENOENT)
                                        /* This is not a valid device.  Note, this condition is quite often
                                         * satisfied when enumerating devices or finding a parent device.
                                         * Hence, use log_trace_errno() here. */
                                        return log_trace_errno(SYNTHETIC_ERRNO(ENODEV),
                                                               "sd-device: the uevent file \"%s/uevent\" does not exist.", syspath);
                                if (errno == ENOTDIR)
                                        /* Not actually a directory. */
                                        return log_debug_errno(SYNTHETIC_ERRNO(ENODEV),
                                                               "sd-device: the syspath \"%s\" is not a directory.", syspath);

                                return log_debug_errno(errno, "sd-device: cannot find uevent file for %s: %m", syspath);
                        }
                } else {
                        struct stat st;

                        /* For everything else lax rules apply: they just need to be a directory */

                        if (fstat(fd, &st) < 0)
                                return log_debug_errno(errno, "sd-device: failed to check if syspath \"%s\" is a directory: %m", syspath);
                        if (!S_ISDIR(st.st_mode))
                                return log_debug_errno(SYNTHETIC_ERRNO(ENODEV),
                                                       "sd-device: the syspath \"%s\" is not a directory.", syspath);
                }

                /* Only operate on sysfs, i.e. refuse going down into /sys/fs/cgroup/ or similar places where
                 * things are not arranged as kobjects in kernel, and hence don't necessarily have
                 * kobject/attribute structure. */
                r = getenv_bool_secure("SYSTEMD_DEVICE_VERIFY_SYSFS");
                if (r < 0 && r != -ENXIO)
                        log_debug_errno(r, "Failed to parse $SYSTEMD_DEVICE_VERIFY_SYSFS value: %m");
                if (r != 0) {
                        r = fd_is_fs_type(fd, SYSFS_MAGIC);
                        if (r < 0)
                                return log_debug_errno(r, "sd-device: failed to check if syspath \"%s\" is backed by sysfs.", syspath);
                        if (r == 0)
                                return log_debug_errno(SYNTHETIC_ERRNO(ENODEV),
                                                       "sd-device: the syspath \"%s\" is outside of sysfs, refusing.", syspath);
                }
        } else {
                /* must be a subdirectory of /sys */
                if (!path_startswith(_syspath, "/sys/"))
                        return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
                                               "sd-device: Syspath '%s' is not a subdirectory of /sys",
                                               _syspath);

                syspath = strdup(_syspath);
                if (!syspath)
                        return log_oom_debug();

                path_simplify(syspath);
        }

        assert_se(devpath = startswith(syspath, "/sys"));
        if (devpath[0] != '/')
                return log_debug_errno(SYNTHETIC_ERRNO(ENODEV), "sd-device: \"/sys\" alone is not a valid device path.");

        r = device_add_property_internal(device, "DEVPATH", devpath);
        if (r < 0)
                return log_debug_errno(r, "sd-device: Failed to add \"DEVPATH\" property for device \"%s\": %m", syspath);

        free_and_replace(device->syspath, syspath);
        device->devpath = devpath;

        /* Unset sysname and sysnum, they will be assigned when requested. */
        device->sysnum = NULL;
        device->sysname = mfree(device->sysname);
        return 0;
}

static int device_new_from_syspath(sd_device **ret, const char *syspath, bool strict) {
        _cleanup_(sd_device_unrefp) sd_device *device = NULL;
        int r;

        assert_return(ret, -EINVAL);
        assert_return(syspath, -EINVAL);

        if (strict && !path_startswith(syspath, "/sys/"))
                return -EINVAL;

        r = device_new_aux(&device);
        if (r < 0)
                return r;

        r = device_set_syspath(device, syspath, /* verify= */ true);
        if (r < 0)
                return r;

        *ret = TAKE_PTR(device);
        return 0;
}

_public_ int sd_device_new_from_syspath(sd_device **ret, const char *syspath) {
        return device_new_from_syspath(ret, syspath, /* strict = */ true);
}

int device_new_from_mode_and_devnum(sd_device **ret, mode_t mode, dev_t devnum) {
        _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
        _cleanup_free_ char *syspath = NULL;
        const char *t, *subsystem = NULL;
        dev_t n;
        int r;

        assert(ret);

        if (S_ISCHR(mode))
                t = "char";
        else if (S_ISBLK(mode))
                t = "block";
        else
                return -ENOTTY;

        if (major(devnum) == 0)
                return -ENODEV;

        if (asprintf(&syspath, "/sys/dev/%s/%u:%u", t, major(devnum), minor(devnum)) < 0)
                return -ENOMEM;

        r = sd_device_new_from_syspath(&dev, syspath);
        if (r < 0)
                return r;

        r = sd_device_get_devnum(dev, &n);
        if (r == -ENOENT)
                return -ENXIO;
        if (r < 0)
                return r;
        if (n != devnum)
                return -ENXIO;

        r = sd_device_get_subsystem(dev, &subsystem);
        if (r < 0 && r != -ENOENT)
                return r;
        if (streq_ptr(subsystem, "block") != !!S_ISBLK(mode))
                return -ENXIO;

        *ret = TAKE_PTR(dev);
        return 0;
}

_public_ int sd_device_new_from_devnum(sd_device **ret, char type, dev_t devnum) {
        assert_return(ret, -EINVAL);
        assert_return(IN_SET(type, 'b', 'c'), -EINVAL);

        return device_new_from_mode_and_devnum(ret, type == 'b' ? S_IFBLK : S_IFCHR, devnum);
}

static int device_new_from_main_ifname(sd_device **ret, const char *ifname) {
        const char *syspath;

        assert(ret);
        assert(ifname);

        syspath = strjoina("/sys/class/net/", ifname);
        return sd_device_new_from_syspath(ret, syspath);
}

_public_ int sd_device_new_from_ifname(sd_device **ret, const char *ifname) {
        _cleanup_free_ char *main_name = NULL;
        int r;

        assert_return(ret, -EINVAL);
        assert_return(ifname, -EINVAL);

        r = parse_ifindex(ifname);
        if (r > 0)
                return sd_device_new_from_ifindex(ret, r);

        if (ifname_valid(ifname)) {
                r = device_new_from_main_ifname(ret, ifname);
                if (r >= 0)
                        return r;
        }

        r = rtnl_resolve_link_alternative_name(NULL, ifname, &main_name);
        if (r < 0)
                return r;

        return device_new_from_main_ifname(ret, main_name);
}

_public_ int sd_device_new_from_ifindex(sd_device **ret, int ifindex) {
        _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
        char ifname[IF_NAMESIZE];
        int r, i;

        assert_return(ret, -EINVAL);
        assert_return(ifindex > 0, -EINVAL);

        if (format_ifname(ifindex, ifname) < 0)
                return -ENODEV;

        r = device_new_from_main_ifname(&dev, ifname);
        if (r < 0)
                return r;

        r = sd_device_get_ifindex(dev, &i);
        if (r == -ENOENT)
                return -ENXIO;
        if (r < 0)
                return r;
        if (i != ifindex)
                return -ENXIO;

        *ret = TAKE_PTR(dev);
        return 0;
}

static int device_strjoin_new(
                const char *a,
                const char *b,
                const char *c,
                const char *d,
                sd_device **ret) {

        const char *p;
        int r;

        p = strjoina(a, b, c, d);
        if (access(p, F_OK) < 0)
                return IN_SET(errno, ENOENT, ENAMETOOLONG) ? 0 : -errno; /* If this sysfs is too long then it doesn't exist either */

        r = sd_device_new_from_syspath(ret, p);
        if (r < 0)
                return r;

        return 1;
}

_public_ int sd_device_new_from_subsystem_sysname(
                sd_device **ret,
                const char *subsystem,
                const char *sysname) {

        char *name;
        int r;

        assert_return(ret, -EINVAL);
        assert_return(path_is_normalized(subsystem), -EINVAL);
        assert_return(path_is_normalized(sysname), -EINVAL);

        /* translate sysname back to sysfs filename */
        name = strdupa_safe(sysname);
        string_replace_char(name, '/', '!');

        if (streq(subsystem, "subsystem")) {
                FOREACH_STRING(s, "/sys/bus/", "/sys/class/") {
                        r = device_strjoin_new(s, name, NULL, NULL, ret);
                        if (r < 0)
                                return r;
                        if (r > 0)
                                return 0;
                }

        } else if (streq(subsystem, "module")) {
                r = device_strjoin_new("/sys/module/", name, NULL, NULL, ret);
                if (r < 0)
                        return r;
                if (r > 0)
                        return 0;

        } else if (streq(subsystem, "drivers")) {
                const char *sep;

                sep = strchr(name, ':');
                if (sep && sep[1] != '\0') { /* Require ":" and something non-empty after that. */

                        const char *subsys = memdupa_suffix0(name, sep - name);
                        sep++;

                        if (streq(sep, "drivers")) /* If the sysname is "drivers", then it's the drivers directory itself that is meant. */
                                r = device_strjoin_new("/sys/bus/", subsys, "/drivers", NULL, ret);
                        else
                                r = device_strjoin_new("/sys/bus/", subsys, "/drivers/", sep, ret);
                        if (r < 0)
                                return r;
                        if (r > 0)
                                return 0;
                }
        }

        r = device_strjoin_new("/sys/bus/", subsystem, "/devices/", name, ret);
        if (r < 0)
                return r;
        if (r > 0)
                return 0;

        r = device_strjoin_new("/sys/class/", subsystem, "/", name, ret);
        if (r < 0)
                return r;
        if (r > 0)
                return 0;

        r = device_strjoin_new("/sys/firmware/", subsystem, "/", name, ret);
        if (r < 0)
                return r;
        if (r > 0)
                return 0;

        return -ENODEV;
}

_public_ int sd_device_new_from_stat_rdev(sd_device **ret, const struct stat *st) {
        assert_return(ret, -EINVAL);
        assert_return(st, -EINVAL);

        return device_new_from_mode_and_devnum(ret, st->st_mode, st->st_rdev);
}

_public_ int sd_device_new_from_devname(sd_device **ret, const char *devname) {
        struct stat st;
        dev_t devnum;
        mode_t mode;

        assert_return(ret, -EINVAL);
        assert_return(devname, -EINVAL);

        /* This function actually accepts both devlinks and devnames, i.e. both symlinks and device
         * nodes below /dev/. */

        /* Also ignore when the specified path is "/dev". */
        if (isempty(path_startswith(devname, "/dev")))
                return -EINVAL;

        if (device_path_parse_major_minor(devname, &mode, &devnum) >= 0)
                /* Let's shortcut when "/dev/block/maj:min" or "/dev/char/maj:min" is specified.
                 * In that case, we can directly convert the path to syspath, hence it is not necessary
                 * that the specified path exists. So, this works fine without udevd being running. */
                return device_new_from_mode_and_devnum(ret, mode, devnum);

        if (stat(devname, &st) < 0)
                return ERRNO_IS_DEVICE_ABSENT(errno) ? -ENODEV : -errno;

        return sd_device_new_from_stat_rdev(ret, &st);
}

_public_ int sd_device_new_from_path(sd_device **ret, const char *path) {
        assert_return(ret, -EINVAL);
        assert_return(path, -EINVAL);

        if (path_startswith(path, "/dev"))
                return sd_device_new_from_devname(ret, path);

        return device_new_from_syspath(ret, path, /* strict = */ false);
}

int device_set_devtype(sd_device *device, const char *devtype) {
        _cleanup_free_ char *t = NULL;
        int r;

        assert(device);
        assert(devtype);

        t = strdup(devtype);
        if (!t)
                return -ENOMEM;

        r = device_add_property_internal(device, "DEVTYPE", t);
        if (r < 0)
                return r;

        return free_and_replace(device->devtype, t);
}

int device_set_ifindex(sd_device *device, const char *name) {
        int r, ifindex;

        assert(device);
        assert(name);

        ifindex = parse_ifindex(name);
        if (ifindex < 0)
                return ifindex;

        r = device_add_property_internal(device, "IFINDEX", name);
        if (r < 0)
                return r;

        device->ifindex = ifindex;

        return 0;
}

int device_set_devname(sd_device *device, const char *devname) {
        _cleanup_free_ char *t = NULL;
        int r;

        assert(device);
        assert(devname);

        if (devname[0] != '/')
                t = strjoin("/dev/", devname);
        else
                t = strdup(devname);
        if (!t)
                return -ENOMEM;

        r = device_add_property_internal(device, "DEVNAME", t);
        if (r < 0)
                return r;

        return free_and_replace(device->devname, t);
}

int device_set_devmode(sd_device *device, const char *_devmode) {
        unsigned devmode;
        int r;

        assert(device);
        assert(_devmode);

        r = safe_atou(_devmode, &devmode);
        if (r < 0)
                return r;

        if (devmode > 07777)
                return -EINVAL;

        r = device_add_property_internal(device, "DEVMODE", _devmode);
        if (r < 0)
                return r;

        device->devmode = devmode;

        return 0;
}

int device_set_devnum(sd_device *device, const char *major, const char *minor) {
        unsigned maj, min = 0;
        int r;

        assert(device);
        assert(major);

        r = safe_atou(major, &maj);
        if (r < 0)
                return r;
        if (maj == 0)
                return 0;
        if (!DEVICE_MAJOR_VALID(maj))
                return -EINVAL;

        if (minor) {
                r = safe_atou(minor, &min);
                if (r < 0)
                        return r;
                if (!DEVICE_MINOR_VALID(min))
                        return -EINVAL;
        }

        r = device_add_property_internal(device, "MAJOR", major);
        if (r < 0)
                return r;

        if (minor) {
                r = device_add_property_internal(device, "MINOR", minor);
                if (r < 0)
                        return r;
        }

        device->devnum = makedev(maj, min);

        return 0;
}

int device_set_diskseq(sd_device *device, const char *str) {
        uint64_t diskseq;
        int r;

        assert(device);
        assert(str);

        r = safe_atou64(str, &diskseq);
        if (r < 0)
                return r;
        if (diskseq == 0)
                return -EINVAL;

        r = device_add_property_internal(device, "DISKSEQ", str);
        if (r < 0)
                return r;

        device->diskseq = diskseq;

        return 0;
}

static int handle_uevent_line(
                sd_device *device,
                const char *key,
                const char *value,
                const char **major,
                const char **minor) {

        assert(device);
        assert(key);
        assert(value);
        assert(major);
        assert(minor);

        if (streq(key, "DEVTYPE"))
                return device_set_devtype(device, value);
        if (streq(key, "IFINDEX"))
                return device_set_ifindex(device, value);
        if (streq(key, "DEVNAME"))
                return device_set_devname(device, value);
        if (streq(key, "DEVMODE"))
                return device_set_devmode(device, value);
        if (streq(key, "DISKSEQ"))
                return device_set_diskseq(device, value);
        if (streq(key, "MAJOR"))
                *major = value;
        else if (streq(key, "MINOR"))
                *minor = value;
        else
                return device_add_property_internal(device, key, value);

        return 0;
}

int device_read_uevent_file(sd_device *device) {
        _cleanup_free_ char *uevent = NULL;
        const char *syspath, *key = NULL, *value = NULL, *major = NULL, *minor = NULL;
        char *path;
        size_t uevent_len;
        int r;

        enum {
                PRE_KEY,
                KEY,
                PRE_VALUE,
                VALUE,
                INVALID_LINE,
        } state = PRE_KEY;

        assert(device);

        if (device->uevent_loaded || device->sealed)
                return 0;

        r = sd_device_get_syspath(device, &syspath);
        if (r < 0)
                return r;

        device->uevent_loaded = true;

        path = strjoina(syspath, "/uevent");

        r = read_full_virtual_file(path, &uevent, &uevent_len);
        if (r < 0) {
                /* The uevent files may be write-only, the device may be already removed, or the device
                 * may not have the uevent file. */
                if (r == -EACCES || ERRNO_IS_DEVICE_ABSENT(r))
                        return 0;

                return log_device_debug_errno(device, r, "sd-device: Failed to read uevent file '%s': %m", path);
        }

        for (size_t i = 0; i < uevent_len; i++)
                switch (state) {
                case PRE_KEY:
                        if (!strchr(NEWLINE, uevent[i])) {
                                key = &uevent[i];

                                state = KEY;
                        }

                        break;
                case KEY:
                        if (uevent[i] == '=') {
                                uevent[i] = '\0';

                                state = PRE_VALUE;
                        } else if (strchr(NEWLINE, uevent[i])) {
                                uevent[i] = '\0';
                                log_device_debug(device, "sd-device: Invalid uevent line '%s', ignoring", key);

                                state = PRE_KEY;
                        }

                        break;
                case PRE_VALUE:
                        value = &uevent[i];
                        state = VALUE;

                        _fallthrough_; /* to handle empty property */
                case VALUE:
                        if (strchr(NEWLINE, uevent[i])) {
                                uevent[i] = '\0';

                                r = handle_uevent_line(device, key, value, &major, &minor);
                                if (r < 0)
                                        log_device_debug_errno(device, r, "sd-device: Failed to handle uevent entry '%s=%s', ignoring: %m", key, value);

                                state = PRE_KEY;
                        }

                        break;
                default:
                        assert_not_reached();
                }

        if (major) {
                r = device_set_devnum(device, major, minor);
                if (r < 0)
                        log_device_debug_errno(device, r, "sd-device: Failed to set 'MAJOR=%s' or 'MINOR=%s' from '%s', ignoring: %m", major, strna(minor), path);
        }

        return 0;
}

_public_ int sd_device_get_ifindex(sd_device *device, int *ifindex) {
        int r;

        assert_return(device, -EINVAL);

        r = device_read_uevent_file(device);
        if (r < 0)
                return r;

        if (device->ifindex <= 0)
                return -ENOENT;

        if (ifindex)
                *ifindex = device->ifindex;

        return 0;
}

_public_ int sd_device_new_from_device_id(sd_device **ret, const char *id) {
        int r;

        assert_return(ret, -EINVAL);
        assert_return(id, -EINVAL);

        switch (id[0]) {
        case 'b':
        case 'c': {
                dev_t devt;

                if (isempty(id))
                        return -EINVAL;

                r = parse_devnum(id + 1, &devt);
                if (r < 0)
                        return r;

                return sd_device_new_from_devnum(ret, id[0], devt);
        }

        case 'n': {
                int ifindex;

                ifindex = parse_ifindex(id + 1);
                if (ifindex < 0)
                        return ifindex;

                return sd_device_new_from_ifindex(ret, ifindex);
        }

        case '+': {
                const char *subsys, *sep;

                sep = strchr(id + 1, ':');
                if (!sep || sep - id - 1 > NAME_MAX)
                        return -EINVAL;

                subsys = memdupa_suffix0(id + 1, sep - id - 1);

                return sd_device_new_from_subsystem_sysname(ret, subsys, sep + 1);
        }

        default:
                return -EINVAL;
        }
}

_public_ int sd_device_get_syspath(sd_device *device, const char **ret) {
        assert_return(device, -EINVAL);

        assert(path_startswith(device->syspath, "/sys/"));

        if (ret)
                *ret = device->syspath;

        return 0;
}

DEFINE_PRIVATE_HASH_OPS_FULL(
        device_by_path_hash_ops,
        char, path_hash_func, path_compare, free,
        sd_device, sd_device_unref);

static int device_enumerate_children_internal(sd_device *device, const char *subdir, Set **stack, Hashmap **children) {
        _cleanup_closedir_ DIR *dir = NULL;
        int r;

        assert(device);
        assert(stack);
        assert(children);

        r = device_opendir(device, subdir, &dir);
        if (r < 0)
                return r;

        FOREACH_DIRENT_ALL(de, dir, return -errno) {
                _cleanup_(sd_device_unrefp) sd_device *child = NULL;
                _cleanup_free_ char *p = NULL;

                if (dot_or_dot_dot(de->d_name))
                        continue;

                if (!IN_SET(de->d_type, DT_LNK, DT_DIR))
                        continue;

                if (subdir)
                        p = path_join(subdir, de->d_name);
                else
                        p = strdup(de->d_name);
                if (!p)
                        return -ENOMEM;

                /* Try to create child device. */
                r = sd_device_new_child(&child, device, p);
                if (r >= 0) {
                        /* OK, this is a child device, saving it. */
                        r = hashmap_ensure_put(children, &device_by_path_hash_ops, p, child);
                        if (r < 0)
                                return r;

                        TAKE_PTR(p);
                        TAKE_PTR(child);
                } else if (r == -ENODEV) {
                        /* This is not a child device. Push the sub-directory into stack, and read it later. */

                        if (de->d_type == DT_LNK)
                                /* Do not follow symlinks, otherwise, we will enter an infinite loop, e.g.,
                                 * /sys/class/block/nvme0n1/subsystem/nvme0n1/subsystem/nvme0n1/subsystem/… */
                                continue;

                        r = set_ensure_consume(stack, &path_hash_ops_free, TAKE_PTR(p));
                        if (r < 0)
                                return r;
                } else
                        return r;
        }

        return 0;
}

static int device_enumerate_children(sd_device *device) {
        _cleanup_hashmap_free_ Hashmap *children = NULL;
        _cleanup_set_free_ Set *stack = NULL;
        int r;

        assert(device);

        if (device->children_enumerated)
                return 0; /* Already enumerated. */

        r = device_enumerate_children_internal(device, NULL, &stack, &children);
        if (r < 0)
                return r;

        for (;;) {
                _cleanup_free_ char *subdir = NULL;

                subdir = set_steal_first(stack);
                if (!subdir)
                        break;

                r = device_enumerate_children_internal(device, subdir, &stack, &children);
                if (r < 0)
                        return r;
        }

        device->children_enumerated = true;
        device->children = TAKE_PTR(children);
        return 1; /* Enumerated. */
}

_public_ sd_device *sd_device_get_child_first(sd_device *device, const char **ret_suffix) {
        int r;

        assert(device);

        r = device_enumerate_children(device);
        if (r < 0) {
                log_device_debug_errno(device, r, "sd-device: failed to enumerate child devices: %m");
                if (ret_suffix)
                        *ret_suffix = NULL;
                return NULL;
        }

        device->children_iterator = ITERATOR_FIRST;

        return sd_device_get_child_next(device, ret_suffix);
}

_public_ sd_device *sd_device_get_child_next(sd_device *device, const char **ret_suffix) {
        sd_device *child;

        assert(device);

        hashmap_iterate(device->children, &device->children_iterator, (void**) &child, (const void**) ret_suffix);
        return child;
}

_public_ int sd_device_new_child(sd_device **ret, sd_device *device, const char *suffix) {
        _cleanup_free_ char *path = NULL;
        sd_device *child;
        const char *s;
        int r;

        assert_return(ret, -EINVAL);
        assert_return(device, -EINVAL);
        assert_return(suffix, -EINVAL);

        if (!path_is_safe(suffix))
                return -EINVAL;

        /* If we have already enumerated children, try to find the child from the cache. */
        child = hashmap_get(device->children, suffix);
        if (child) {
                *ret = sd_device_ref(child);
                return 0;
        }

        r = sd_device_get_syspath(device, &s);
        if (r < 0)
                return r;

        path = path_join(s, suffix);
        if (!path)
                return -ENOMEM;

        return sd_device_new_from_syspath(ret, path);
}

static int device_new_from_child(sd_device **ret, sd_device *child) {
        _cleanup_free_ char *path = NULL;
        const char *syspath;
        int r;

        assert(ret);
        assert(child);

        r = sd_device_get_syspath(child, &syspath);
        if (r < 0)
                return r;

        for (;;) {
                _cleanup_free_ char *p = NULL;

                r = path_extract_directory(path ?: syspath, &p);
                if (r < 0)
                        return r;

                if (path_equal(p, "/sys"))
                        return -ENODEV;

                r = sd_device_new_from_syspath(ret, p);
                if (r != -ENODEV)
                        return r;

                free_and_replace(path, p);
        }
}

_public_ int sd_device_get_parent(sd_device *child, sd_device **ret) {
        int r;

        assert_return(child, -EINVAL);

        if (!child->parent_set) {
                r = device_new_from_child(&child->parent, child);
                if (r < 0 && r != -ENODEV)
                        return r;

                child->parent_set = true;
        }

        if (!child->parent)
                return -ENOENT;

        if (ret)
                *ret = child->parent;
        return 0;
}

int device_set_subsystem(sd_device *device, const char *subsystem) {
        _cleanup_free_ char *s = NULL;
        int r;

        assert(device);

        if (subsystem) {
                s = strdup(subsystem);
                if (!s)
                        return -ENOMEM;
        }

        r = device_add_property_internal(device, "SUBSYSTEM", s);
        if (r < 0)
                return r;

        device->subsystem_set = true;
        return free_and_replace(device->subsystem, s);
}

int device_set_drivers_subsystem(sd_device *device) {
        _cleanup_free_ char *subsystem = NULL;
        const char *devpath, *drivers, *p;
        int r;

        assert(device);

        r = sd_device_get_devpath(device, &devpath);
        if (r < 0)
                return r;

        drivers = strstr(devpath, "/drivers/");
        if (!drivers)
                drivers = endswith(devpath, "/drivers");
        if (!drivers)
                return -EINVAL;

        /* Find the path component immediately before the "/drivers/" string */
        r = path_find_last_component(devpath, /* accept_dot_dot= */ false, &drivers, &p);
        if (r < 0)
                return r;
        if (r == 0)
                return -EINVAL;

        subsystem = strndup(p, r);
        if (!subsystem)
                return -ENOMEM;

        r = device_set_subsystem(device, "drivers");
        if (r < 0)
                return r;

        return free_and_replace(device->driver_subsystem, subsystem);
}

_public_ int sd_device_get_subsystem(sd_device *device, const char **ret) {
        int r;

        assert_return(device, -EINVAL);

        if (!device->subsystem_set) {
                _cleanup_free_ char *subsystem = NULL;
                const char *syspath;
                char *path;

                r = sd_device_get_syspath(device, &syspath);
                if (r < 0)
                        return r;

                /* read 'subsystem' link */
                path = strjoina(syspath, "/subsystem");
                r = readlink_value(path, &subsystem);
                if (r < 0 && r != -ENOENT)
                        return log_device_debug_errno(device, r,
                                                      "sd-device: Failed to read subsystem for %s: %m",
                                                      device->devpath);

                if (subsystem)
                        r = device_set_subsystem(device, subsystem);
                /* use implicit names */
                else if (!isempty(path_startswith(device->devpath, "/module/")))
                        r = device_set_subsystem(device, "module");
                else if (strstr(syspath, "/drivers/") || endswith(syspath, "/drivers"))
                        r = device_set_drivers_subsystem(device);
                else if (!isempty(PATH_STARTSWITH_SET(device->devpath, "/class/", "/bus/")))
                        r = device_set_subsystem(device, "subsystem");
                else {
                        device->subsystem_set = true;
                        r = 0;
                }
                if (r < 0)
                        return log_device_debug_errno(device, r,
                                                      "sd-device: Failed to set subsystem for %s: %m",
                                                      device->devpath);
        }

        if (!device->subsystem)
                return -ENOENT;

        if (ret)
                *ret = device->subsystem;
        return 0;
}

_public_ int sd_device_get_devtype(sd_device *device, const char **devtype) {
        int r;

        assert_return(device, -EINVAL);

        r = device_read_uevent_file(device);
        if (r < 0)
                return r;

        if (!device->devtype)
                return -ENOENT;

        if (devtype)
                *devtype = device->devtype;

        return !!device->devtype;
}

_public_ int sd_device_get_parent_with_subsystem_devtype(sd_device *child, const char *subsystem, const char *devtype, sd_device **ret) {
        sd_device *parent = NULL;
        int r;

        assert_return(child, -EINVAL);
        assert_return(subsystem, -EINVAL);

        r = sd_device_get_parent(child, &parent);
        while (r >= 0) {
                const char *parent_subsystem = NULL;

                (void) sd_device_get_subsystem(parent, &parent_subsystem);
                if (streq_ptr(parent_subsystem, subsystem)) {
                        const char *parent_devtype = NULL;

                        if (!devtype)
                                break;

                        (void) sd_device_get_devtype(parent, &parent_devtype);
                        if (streq_ptr(parent_devtype, devtype))
                                break;
                }
                r = sd_device_get_parent(parent, &parent);
        }

        if (r < 0)
                return r;

        if (ret)
                *ret = parent;
        return 0;
}

_public_ int sd_device_get_devnum(sd_device *device, dev_t *devnum) {
        int r;

        assert_return(device, -EINVAL);

        r = device_read_uevent_file(device);
        if (r < 0)
                return r;

        if (major(device->devnum) <= 0)
                return -ENOENT;

        if (devnum)
                *devnum = device->devnum;

        return 0;
}

int device_set_driver(sd_device *device, const char *driver) {
        _cleanup_free_ char *d = NULL;
        int r;

        assert(device);

        if (driver) {
                d = strdup(driver);
                if (!d)
                        return -ENOMEM;
        }

        r = device_add_property_internal(device, "DRIVER", d);
        if (r < 0)
                return r;

        device->driver_set = true;
        return free_and_replace(device->driver, d);
}

_public_ int sd_device_get_driver(sd_device *device, const char **ret) {
        assert_return(device, -EINVAL);

        if (!device->driver_set) {
                _cleanup_free_ char *driver = NULL;
                const char *syspath;
                char *path;
                int r;

                r = sd_device_get_syspath(device, &syspath);
                if (r < 0)
                        return r;

                path = strjoina(syspath, "/driver");
                r = readlink_value(path, &driver);
                if (r < 0 && r != -ENOENT)
                        return log_device_debug_errno(device, r,
                                                      "sd-device: readlink(\"%s\") failed: %m", path);

                r = device_set_driver(device, driver);
                if (r < 0)
                        return log_device_debug_errno(device, r,
                                                      "sd-device: Failed to set driver \"%s\": %m", driver);
        }

        if (!device->driver)
                return -ENOENT;

        if (ret)
                *ret = device->driver;
        return 0;
}

_public_ int sd_device_get_devpath(sd_device *device, const char **ret) {
        assert_return(device, -EINVAL);

        assert(device->devpath);
        assert(device->devpath[0] == '/');

        if (ret)
                *ret = device->devpath;

        return 0;
}

_public_ int sd_device_get_devname(sd_device *device, const char **devname) {
        int r;

        assert_return(device, -EINVAL);

        r = device_read_uevent_file(device);
        if (r < 0)
                return r;

        if (!device->devname)
                return -ENOENT;

        assert(path_startswith(device->devname, "/dev/"));

        if (devname)
                *devname = device->devname;
        return 0;
}

static int device_set_sysname_and_sysnum(sd_device *device) {
        _cleanup_free_ char *sysname = NULL;
        size_t len, n;
        int r;

        assert(device);

        r = path_extract_filename(device->devpath, &sysname);
        if (r < 0)
                return r;
        if (r == O_DIRECTORY)
                return -EINVAL;

        /* some devices have '!' in their name, change that to '/' */
        string_replace_char(sysname, '!', '/');

        n = strspn_from_end(sysname, DIGITS);
        len = strlen(sysname);
        assert(n <= len);
        if (n == len)
                n = 0; /* Do not set sysnum for number only sysname. */

        device->sysnum = n > 0 ? sysname + len - n : NULL;
        return free_and_replace(device->sysname, sysname);
}

_public_ int sd_device_get_sysname(sd_device *device, const char **ret) {
        int r;

        assert_return(device, -EINVAL);

        if (!device->sysname) {
                r = device_set_sysname_and_sysnum(device);
                if (r < 0)
                        return r;
        }

        if (ret)
                *ret = device->sysname;
        return 0;
}

_public_ int sd_device_get_sysnum(sd_device *device, const char **ret) {
        int r;

        assert_return(device, -EINVAL);

        if (!device->sysname) {
                r = device_set_sysname_and_sysnum(device);
                if (r < 0)
                        return r;
        }

        if (!device->sysnum)
                return -ENOENT;

        if (ret)
                *ret = device->sysnum;
        return 0;
}

_public_ int sd_device_get_action(sd_device *device, sd_device_action_t *ret) {
        assert_return(device, -EINVAL);

        if (device->action < 0)
                return -ENOENT;

        if (ret)
                *ret = device->action;

        return 0;
}

_public_ int sd_device_get_seqnum(sd_device *device, uint64_t *ret) {
        assert_return(device, -EINVAL);

        if (device->seqnum == 0)
                return -ENOENT;

        if (ret)
                *ret = device->seqnum;

        return 0;
}

_public_ int sd_device_get_diskseq(sd_device *device, uint64_t *ret) {
        int r;

        assert_return(device, -EINVAL);

        r = device_read_uevent_file(device);
        if (r < 0)
                return r;

        if (device->diskseq == 0)
                return -ENOENT;

        if (ret)
                *ret = device->diskseq;

        return 0;
}

static bool is_valid_tag(const char *tag) {
        assert(tag);

        return !strchr(tag, ':') && !strchr(tag, ' ');
}

int device_add_tag(sd_device *device, const char *tag, bool both) {
        int r, added;

        assert(device);
        assert(tag);

        if (!is_valid_tag(tag))
                return -EINVAL;

        /* Definitely add to the "all" list of tags (i.e. the sticky list) */
        added = set_put_strdup(&device->all_tags, tag);
        if (added < 0)
                return added;

        /* And optionally, also add it to the current list of tags */
        if (both) {
                r = set_put_strdup(&device->current_tags, tag);
                if (r < 0) {
                        if (added > 0)
                                (void) set_remove(device->all_tags, tag);

                        return r;
                }
        }

        device->tags_generation++;
        device->property_tags_outdated = true;

        return 0;
}

int device_add_devlink(sd_device *device, const char *devlink) {
        int r;

        assert(device);
        assert(devlink);

        r = set_put_strdup(&device->devlinks, devlink);
        if (r < 0)
                return r;

        device->devlinks_generation++;
        device->property_devlinks_outdated = true;

        return 0;
}

void device_remove_devlink(sd_device *device, const char *devlink) {
        _cleanup_free_ char *s = NULL;

        assert(device);
        assert(devlink);

        s = set_remove(device->devlinks, devlink);
        if (!s)
                return;

        device->devlinks_generation++;
        device->property_devlinks_outdated = true;
}

bool device_has_devlink(sd_device *device, const char *devlink) {
        assert(device);
        assert(devlink);

        return set_contains(device->devlinks, devlink);
}

static int device_add_property_internal_from_string(sd_device *device, const char *str) {
        _cleanup_free_ char *key = NULL;
        char *value;
        int r;

        assert(device);
        assert(str);

        key = strdup(str);
        if (!key)
                return -ENOMEM;

        value = strchr(key, '=');
        if (!value)
                return -EINVAL;

        *value = '\0';

        if (isempty(++value))
                value = NULL;

        /* Add the property to both sd_device::properties and sd_device::properties_db,
         * as this is called by only handle_db_line(). */
        r = device_add_property_aux(device, key, value, false);
        if (r < 0)
                return r;

        return device_add_property_aux(device, key, value, true);
}

int device_set_usec_initialized(sd_device *device, usec_t when) {
        char s[DECIMAL_STR_MAX(usec_t)];
        int r;

        assert(device);

        xsprintf(s, USEC_FMT, when);

        r = device_add_property_internal(device, "USEC_INITIALIZED", s);
        if (r < 0)
                return r;

        device->usec_initialized = when;
        return 0;
}

static int handle_db_line(sd_device *device, char key, const char *value) {
        int r;

        assert(device);
        assert(value);

        switch (key) {
        case 'G': /* Any tag */
        case 'Q': /* Current tag */
                return device_add_tag(device, value, key == 'Q');

        case 'S': {
                const char *path;

                path = strjoina("/dev/", value);
                return device_add_devlink(device, path);
        }
        case 'E':
                return device_add_property_internal_from_string(device, value);

        case 'I': {
                usec_t t;

                r = safe_atou64(value, &t);
                if (r < 0)
                        return r;

                return device_set_usec_initialized(device, t);
        }
        case 'L':
                return safe_atoi(value, &device->devlink_priority);

        case 'W':
                /* Deprecated. Previously, watch handle is both saved in database and /run/udev/watch.
                 * However, the handle saved in database may not be updated when the handle is updated
                 * or removed. Moreover, it is not necessary to store the handle within the database,
                 * as its value becomes meaningless when udevd is restarted. */
                return 0;

        case 'V':
                return safe_atou(value, &device->database_version);

        default:
                log_device_debug(device, "sd-device: Unknown key '%c' in device db, ignoring", key);
                return 0;
        }
}

int device_get_device_id(sd_device *device, const char **ret) {
        assert(device);
        assert(ret);

        if (!device->device_id) {
                _cleanup_free_ char *id = NULL;
                const char *subsystem;
                dev_t devnum;
                int ifindex, r;

                r = sd_device_get_subsystem(device, &subsystem);
                if (r < 0)
                        return r;

                if (sd_device_get_devnum(device, &devnum) >= 0) {
                        /* use dev_t — b259:131072, c254:0 */
                        if (asprintf(&id, "%c%u:%u",
                                     streq(subsystem, "block") ? 'b' : 'c',
                                     major(devnum), minor(devnum)) < 0)
                                return -ENOMEM;
                } else if (sd_device_get_ifindex(device, &ifindex) >= 0) {
                        /* use netdev ifindex — n3 */
                        if (asprintf(&id, "n%u", (unsigned) ifindex) < 0)
                                return -ENOMEM;
                } else {
                        _cleanup_free_ char *sysname = NULL;

                        /* use $subsys:$sysname — pci:0000:00:1f.2
                         * sd_device_get_sysname() has '!' translated, get it from devpath */
                        r = path_extract_filename(device->devpath, &sysname);
                        if (r < 0)
                                return r;
                        if (r == O_DIRECTORY)
                                return -EINVAL;

                        if (streq(subsystem, "drivers")) {
                                /* the 'drivers' pseudo-subsystem is special, and needs the real
                                 * subsystem encoded as well */
                                assert(device->driver_subsystem);
                                id = strjoin("+drivers:", device->driver_subsystem, ":", sysname);
                        } else
                                id = strjoin("+", subsystem, ":", sysname);
                        if (!id)
                                return -ENOMEM;
                }

                if (!filename_is_valid(id))
                        return -EINVAL;

                device->device_id = TAKE_PTR(id);
        }

        *ret = device->device_id;
        return 0;
}

int device_read_db_internal_filename(sd_device *device, const char *filename) {
        _cleanup_free_ char *db = NULL;
        const char *value;
        size_t db_len;
        char key = '\0';  /* Unnecessary initialization to appease gcc-12.0.0-0.4.fc36 */
        int r;

        enum {
                PRE_KEY,
                KEY,
                PRE_VALUE,
                VALUE,
                INVALID_LINE,
        } state = PRE_KEY;

        assert(device);
        assert(filename);

        r = read_full_file(filename, &db, &db_len);
        if (r < 0) {
                if (r == -ENOENT)
                        return 0;

                return log_device_debug_errno(device, r, "sd-device: Failed to read db '%s': %m", filename);
        }

        /* devices with a database entry are initialized */
        device->is_initialized = true;

        device->db_loaded = true;

        for (size_t i = 0; i < db_len; i++)
                switch (state) {
                case PRE_KEY:
                        if (!strchr(NEWLINE, db[i])) {
                                key = db[i];

                                state = KEY;
                        }

                        break;
                case KEY:
                        if (db[i] != ':') {
                                log_device_debug(device, "sd-device: Invalid db entry with key '%c', ignoring", key);

                                state = INVALID_LINE;
                        } else {
                                db[i] = '\0';

                                state = PRE_VALUE;
                        }

                        break;
                case PRE_VALUE:
                        value = &db[i];

                        state = VALUE;

                        break;
                case INVALID_LINE:
                        if (strchr(NEWLINE, db[i]))
                                state = PRE_KEY;

                        break;
                case VALUE:
                        if (strchr(NEWLINE, db[i])) {
                                db[i] = '\0';
                                r = handle_db_line(device, key, value);
                                if (r < 0)
                                        log_device_debug_errno(device, r, "sd-device: Failed to handle db entry '%c:%s', ignoring: %m",
                                                               key, value);

                                state = PRE_KEY;
                        }

                        break;
                default:
                        return log_device_debug_errno(device, SYNTHETIC_ERRNO(EINVAL), "sd-device: invalid db syntax.");
                }

        return 0;
}

int device_read_db_internal(sd_device *device, bool force) {
        const char *id, *path;
        int r;

        assert(device);

        if (device->db_loaded || (!force && device->sealed))
                return 0;

        r = device_get_device_id(device, &id);
        if (r < 0)
                return r;

        path = strjoina("/run/udev/data/", id);

        return device_read_db_internal_filename(device, path);
}

_public_ int sd_device_get_is_initialized(sd_device *device) {
        int r;

        assert_return(device, -EINVAL);

        r = device_read_db(device);
        if (r == -ENOENT)
                /* The device may be already removed or renamed. */
                return false;
        if (r < 0)
                return r;

        return device->is_initialized;
}

_public_ int sd_device_get_usec_initialized(sd_device *device, uint64_t *ret) {
        int r;

        assert_return(device, -EINVAL);

        r = sd_device_get_is_initialized(device);
        if (r < 0)
                return r;
        if (r == 0)
                return -EBUSY;

        if (device->usec_initialized == 0)
                return -ENODATA;

        if (ret)
                *ret = device->usec_initialized;

        return 0;
}

_public_ int sd_device_get_usec_since_initialized(sd_device *device, uint64_t *ret) {
        usec_t now_ts, ts;
        int r;

        assert_return(device, -EINVAL);

        r = sd_device_get_usec_initialized(device, &ts);
        if (r < 0)
                return r;

        now_ts = now(CLOCK_MONOTONIC);

        if (now_ts < ts)
                return -EIO;

        if (ret)
                *ret = usec_sub_unsigned(now_ts, ts);

        return 0;
}

_public_ const char *sd_device_get_tag_first(sd_device *device) {
        void *v;

        assert_return(device, NULL);

        (void) device_read_db(device);

        device->all_tags_iterator_generation = device->tags_generation;
        device->all_tags_iterator = ITERATOR_FIRST;

        (void) set_iterate(device->all_tags, &device->all_tags_iterator, &v);
        return v;
}

_public_ const char *sd_device_get_tag_next(sd_device *device) {
        void *v;

        assert_return(device, NULL);

        (void) device_read_db(device);

        if (device->all_tags_iterator_generation != device->tags_generation)
                return NULL;

        (void) set_iterate(device->all_tags, &device->all_tags_iterator, &v);
        return v;
}

static bool device_database_supports_current_tags(sd_device *device) {
        assert(device);

        (void) device_read_db(device);

        /* The current tags (saved in Q field) feature is implemented in database version 1.
         * If the database version is 0, then the tags (NOT current tags, saved in G field) are not
         * sticky. Thus, we can safely bypass the operations for the current tags (Q) to tags (G). */

        return device->database_version >= 1;
}

_public_ const char *sd_device_get_current_tag_first(sd_device *device) {
        void *v;

        assert_return(device, NULL);

        if (!device_database_supports_current_tags(device))
                return sd_device_get_tag_first(device);

        (void) device_read_db(device);

        device->current_tags_iterator_generation = device->tags_generation;
        device->current_tags_iterator = ITERATOR_FIRST;

        (void) set_iterate(device->current_tags, &device->current_tags_iterator, &v);
        return v;
}

_public_ const char *sd_device_get_current_tag_next(sd_device *device) {
        void *v;

        assert_return(device, NULL);

        if (!device_database_supports_current_tags(device))
                return sd_device_get_tag_next(device);

        (void) device_read_db(device);

        if (device->current_tags_iterator_generation != device->tags_generation)
                return NULL;

        (void) set_iterate(device->current_tags, &device->current_tags_iterator, &v);
        return v;
}

_public_ const char *sd_device_get_devlink_first(sd_device *device) {
        void *v;

        assert_return(device, NULL);

        (void) device_read_db(device);

        device->devlinks_iterator_generation = device->devlinks_generation;
        device->devlinks_iterator = ITERATOR_FIRST;

        (void) set_iterate(device->devlinks, &device->devlinks_iterator, &v);
        return v;
}

_public_ const char *sd_device_get_devlink_next(sd_device *device) {
        void *v;

        assert_return(device, NULL);

        (void) device_read_db(device);

        if (device->devlinks_iterator_generation != device->devlinks_generation)
                return NULL;

        (void) set_iterate(device->devlinks, &device->devlinks_iterator, &v);
        return v;
}

int device_properties_prepare(sd_device *device) {
        int r;

        assert(device);

        r = device_read_uevent_file(device);
        if (r < 0)
                return r;

        r = device_read_db(device);
        if (r < 0)
                return r;

        if (device->property_devlinks_outdated) {
                _cleanup_free_ char *devlinks = NULL;

                r = set_strjoin(device->devlinks, " ", false, &devlinks);
                if (r < 0)
                        return r;

                if (!isempty(devlinks)) {
                        r = device_add_property_internal(device, "DEVLINKS", devlinks);
                        if (r < 0)
                                return r;
                }

                device->property_devlinks_outdated = false;
        }

        if (device->property_tags_outdated) {
                _cleanup_free_ char *tags = NULL;

                r = set_strjoin(device->all_tags, ":", true, &tags);
                if (r < 0)
                        return r;

                if (!isempty(tags)) {
                        r = device_add_property_internal(device, "TAGS", tags);
                        if (r < 0)
                                return r;
                }

                tags = mfree(tags);
                r = set_strjoin(device->current_tags, ":", true, &tags);
                if (r < 0)
                        return r;

                if (!isempty(tags)) {
                        r = device_add_property_internal(device, "CURRENT_TAGS", tags);
                        if (r < 0)
                                return r;
                }

                device->property_tags_outdated = false;
        }

        return 0;
}

_public_ const char *sd_device_get_property_first(sd_device *device, const char **_value) {
        const char *key;
        int r;

        assert_return(device, NULL);

        r = device_properties_prepare(device);
        if (r < 0)
                return NULL;

        device->properties_iterator_generation = device->properties_generation;
        device->properties_iterator = ITERATOR_FIRST;

        (void) ordered_hashmap_iterate(device->properties, &device->properties_iterator, (void**)_value, (const void**)&key);
        return key;
}

_public_ const char *sd_device_get_property_next(sd_device *device, const char **_value) {
        const char *key;
        int r;

        assert_return(device, NULL);

        r = device_properties_prepare(device);
        if (r < 0)
                return NULL;

        if (device->properties_iterator_generation != device->properties_generation)
                return NULL;

        (void) ordered_hashmap_iterate(device->properties, &device->properties_iterator, (void**)_value, (const void**)&key);
        return key;
}

static int device_sysattrs_read_all_internal(sd_device *device, const char *subdir, Set **stack) {
        _cleanup_closedir_ DIR *dir = NULL;
        int r;

        assert(device);
        assert(stack);

        r = device_opendir(device, subdir, &dir);
        if (r == -ENOENT && subdir)
                return 0; /* Maybe, this is a child device, and is already removed. */
        if (r < 0)
                return r;

        if (subdir) {
                if (faccessat(dirfd(dir), "uevent", F_OK, 0) >= 0)
                        return 0; /* this is a child device, skipping */
                if (errno != ENOENT) {
                        log_device_debug_errno(device, errno,
                                               "sd-device: Failed to access %s/uevent, ignoring sub-directory %s: %m",
                                               subdir, subdir);
                        return 0;
                }
        }

        FOREACH_DIRENT_ALL(de, dir, return -errno) {
                _cleanup_free_ char *p = NULL;
                struct stat statbuf;

                if (dot_or_dot_dot(de->d_name))
                        continue;

                /* only handle symlinks, regular files, and directories */
                if (!IN_SET(de->d_type, DT_LNK, DT_REG, DT_DIR))
                        continue;

                if (subdir) {
                        p = path_join(subdir, de->d_name);
                        if (!p)
                                return -ENOMEM;
                }

                if (de->d_type == DT_DIR) {
                        /* push the sub-directory into the stack, and read it later. */
                        if (p)
                                r = set_ensure_consume(stack, &path_hash_ops_free, TAKE_PTR(p));
                        else
                                r = set_put_strdup_full(stack, &path_hash_ops_free, de->d_name);
                        if (r < 0)
                                return r;

                        continue;
                }

                if (fstatat(dirfd(dir), de->d_name, &statbuf, AT_SYMLINK_NOFOLLOW) < 0)
                        continue;

                if ((statbuf.st_mode & (S_IRUSR | S_IWUSR)) == 0)
                        continue;

                if (p)
                        r = set_ensure_consume(&device->sysattrs, &path_hash_ops_free, TAKE_PTR(p));
                else
                        r = set_put_strdup_full(&device->sysattrs, &path_hash_ops_free, de->d_name);
                if (r < 0)
                        return r;
        }

        return 0;
}

static int device_sysattrs_read_all(sd_device *device) {
        _cleanup_set_free_ Set *stack = NULL;
        int r;

        assert(device);

        if (device->sysattrs_read)
                return 0;

        r = device_sysattrs_read_all_internal(device, NULL, &stack);
        if (r < 0)
                return r;

        for (;;) {
                _cleanup_free_ char *subdir = NULL;

                subdir = set_steal_first(stack);
                if (!subdir)
                        break;

                r = device_sysattrs_read_all_internal(device, subdir, &stack);
                if (r < 0)
                        return r;
        }

        device->sysattrs_read = true;

        return 0;
}

_public_ const char *sd_device_get_sysattr_first(sd_device *device) {
        void *v;
        int r;

        assert_return(device, NULL);

        if (!device->sysattrs_read) {
                r = device_sysattrs_read_all(device);
                if (r < 0) {
                        errno = -r;
                        return NULL;
                }
        }

        device->sysattrs_iterator = ITERATOR_FIRST;

        (void) set_iterate(device->sysattrs, &device->sysattrs_iterator, &v);
        return v;
}

_public_ const char *sd_device_get_sysattr_next(sd_device *device) {
        void *v;

        assert_return(device, NULL);

        if (!device->sysattrs_read)
                return NULL;

        (void) set_iterate(device->sysattrs, &device->sysattrs_iterator, &v);
        return v;
}

_public_ int sd_device_has_tag(sd_device *device, const char *tag) {
        assert_return(device, -EINVAL);
        assert_return(tag, -EINVAL);

        (void) device_read_db(device);

        return set_contains(device->all_tags, tag);
}

_public_ int sd_device_has_current_tag(sd_device *device, const char *tag) {
        assert_return(device, -EINVAL);
        assert_return(tag, -EINVAL);

        if (!device_database_supports_current_tags(device))
                return sd_device_has_tag(device, tag);

        (void) device_read_db(device);

        return set_contains(device->current_tags, tag);
}

_public_ int sd_device_get_property_value(sd_device *device, const char *key, const char **ret_value) {
        const char *value;
        int r;

        assert_return(device, -EINVAL);
        assert_return(key, -EINVAL);

        r = device_properties_prepare(device);
        if (r < 0)
                return r;

        value = ordered_hashmap_get(device->properties, key);
        if (!value)
                return -ENOENT;

        if (ret_value)
                *ret_value = value;
        return 0;
}

int device_get_property_bool(sd_device *device, const char *key) {
        const char *value;
        int r;

        assert(device);
        assert(key);

        r = sd_device_get_property_value(device, key, &value);
        if (r < 0)
                return r;

        return parse_boolean(value);
}

int device_get_property_int(sd_device *device, const char *key, int *ret) {
        const char *value;
        int r, v;

        assert(device);
        assert(key);

        r = sd_device_get_property_value(device, key, &value);
        if (r < 0)
                return r;

        r = safe_atoi(value, &v);
        if (r < 0)
                return r;

        if (ret)
                *ret = v;
        return 0;
}

_public_ int sd_device_get_trigger_uuid(sd_device *device, sd_id128_t *ret) {
        const char *s;
        sd_id128_t id;
        int r;

        assert_return(device, -EINVAL);

        /* Retrieves the UUID attached to a uevent when triggering it from userspace via
         * sd_device_trigger_with_uuid() or an equivalent interface. Returns -ENOENT if the record is not
         * caused by a synthetic event and -ENODATA if it was but no UUID was specified */

        r = sd_device_get_property_value(device, "SYNTH_UUID", &s);
        if (r < 0)
                return r;

        if (streq(s, "0")) /* SYNTH_UUID=0 is set whenever a device is triggered by userspace without specifying a UUID */
                return -ENODATA;

        r = sd_id128_from_string(s, &id);
        if (r < 0)
                return r;

        if (ret)
                *ret = id;

        return 0;
}

void device_clear_sysattr_cache(sd_device *device) {
        device->sysattr_values = hashmap_free(device->sysattr_values);
}

int device_cache_sysattr_value(sd_device *device, const char *key, char *value) {
        _unused_ _cleanup_free_ char *old_value = NULL;
        _cleanup_free_ char *new_key = NULL;
        int r;

        assert(device);
        assert(key);

        /* This takes the reference of the input value. The input value may be NULL.
         * This replaces the value if it already exists. */

        /* First, remove the old cache entry. So, we do not need to clear cache on error. */
        old_value = hashmap_remove2(device->sysattr_values, key, (void **) &new_key);
        if (!new_key) {
                new_key = strdup(key);
                if (!new_key)
                        return -ENOMEM;
        }

        r = hashmap_ensure_put(&device->sysattr_values, &string_hash_ops_free_free, new_key, value);
        if (r < 0)
                return r;

        TAKE_PTR(new_key);

        return 0;
}

int device_get_cached_sysattr_value(sd_device *device, const char *key, const char **ret_value) {
        const char *k = NULL, *value;

        assert(device);
        assert(key);

        value = hashmap_get2(device->sysattr_values, key, (void **) &k);
        if (!k)
                return -ESTALE; /* We have not read the attribute. */
        if (!value)
                return -ENOENT; /* We have looked up the attribute before and it did not exist. */
        if (ret_value)
                *ret_value = value;
        return 0;
}

/* We cache all sysattr lookups. If an attribute does not exist, it is stored
 * with a NULL value in the cache, otherwise the returned string is stored */
_public_ int sd_device_get_sysattr_value(sd_device *device, const char *sysattr, const char **ret_value) {
        _cleanup_free_ char *value = NULL, *path = NULL;
        const char *syspath;
        struct stat statbuf;
        int r;

        assert_return(device, -EINVAL);
        assert_return(sysattr, -EINVAL);

        /* look for possibly already cached result */
        r = device_get_cached_sysattr_value(device, sysattr, ret_value);
        if (r != -ESTALE)
                return r;

        r = sd_device_get_syspath(device, &syspath);
        if (r < 0)
                return r;

        path = path_join(syspath, sysattr);
        if (!path)
                return -ENOMEM;

        if (lstat(path, &statbuf) < 0) {
                int k;

                r = -errno;

                /* remember that we could not access the sysattr */
                k = device_cache_sysattr_value(device, sysattr, NULL);
                if (k < 0)
                        log_device_debug_errno(device, k,
                                               "sd-device: failed to cache attribute '%s' with NULL, ignoring: %m",
                                               sysattr);

                return r;
        } else if (S_ISLNK(statbuf.st_mode)) {
                /* Some core links return only the last element of the target path,
                 * these are just values, the paths should not be exposed. */
                if (STR_IN_SET(sysattr, "driver", "subsystem", "module")) {
                        r = readlink_value(path, &value);
                        if (r < 0)
                                return r;
                } else
                        return -EINVAL;
        } else if (S_ISDIR(statbuf.st_mode))
                /* skip directories */
                return -EISDIR;
        else if (!(statbuf.st_mode & S_IRUSR))
                /* skip non-readable files */
                return -EPERM;
        else {
                size_t size;

                /* Read attribute value, Some attributes contain embedded '\0'. So, it is necessary to
                 * also get the size of the result. See issue #20025. */
                r = read_full_virtual_file(path, &value, &size);
                if (r < 0)
                        return r;

                /* drop trailing newlines */
                while (size > 0 && strchr(NEWLINE, value[--size]))
                        value[size] = '\0';
        }

        /* Unfortunately, we need to return 'const char*' instead of 'char*'. Hence, failure in caching
         * sysattr value is critical unlike the other places. */
        r = device_cache_sysattr_value(device, sysattr, value);
        if (r < 0) {
                log_device_debug_errno(device, r,
                                       "sd-device: failed to cache attribute '%s' with '%s'%s: %m",
                                       sysattr, value, ret_value ? "" : ", ignoring");
                if (ret_value)
                        return r;

                return 0;
        }

        if (ret_value)
                *ret_value = value;

        TAKE_PTR(value);
        return 0;
}

int device_get_sysattr_int(sd_device *device, const char *sysattr, int *ret_value) {
        const char *value;
        int r;

        r = sd_device_get_sysattr_value(device, sysattr, &value);
        if (r < 0)
                return r;

        int v;
        r = safe_atoi(value, &v);
        if (r < 0)
                return log_device_debug_errno(device, r, "Failed to parse '%s' attribute: %m", sysattr);

        if (ret_value)
                *ret_value = v;
        /* We return "true" if the value is positive. */
        return v > 0;
}

int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value) {
        const char *value;
        int r;

        r = sd_device_get_sysattr_value(device, sysattr, &value);
        if (r < 0)
                return r;

        unsigned v;
        r = safe_atou(value, &v);
        if (r < 0)
                return log_device_debug_errno(device, r, "Failed to parse '%s' attribute: %m", sysattr);

        if (ret_value)
                *ret_value = v;
        /* We return "true" if the value is positive. */
        return v > 0;
}

int device_get_sysattr_bool(sd_device *device, const char *sysattr) {
        const char *value;
        int r;

        assert(device);
        assert(sysattr);

        r = sd_device_get_sysattr_value(device, sysattr, &value);
        if (r < 0)
                return r;

        return parse_boolean(value);
}

static void device_remove_cached_sysattr_value(sd_device *device, const char *_key) {
        _cleanup_free_ char *key = NULL;

        assert(device);
        assert(_key);

        free(hashmap_remove2(device->sysattr_values, _key, (void **) &key));
}

_public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr, const char *_value) {
        _cleanup_free_ char *value = NULL, *path = NULL;
        const char *syspath;
        size_t len;
        int r;

        assert_return(device, -EINVAL);
        assert_return(sysattr, -EINVAL);

        /* Set the attribute and save it in the cache. */

        if (!_value) {
                /* If input value is NULL, then clear cache and not write anything. */
                device_remove_cached_sysattr_value(device, sysattr);
                return 0;
        }

        r = sd_device_get_syspath(device, &syspath);
        if (r < 0)
                return r;

        path = path_join(syspath, sysattr);
        if (!path)
                return -ENOMEM;

        len = strlen(_value);

        /* drop trailing newlines */
        while (len > 0 && strchr(NEWLINE, _value[len - 1]))
                len --;

        /* value length is limited to 4k */
        if (len > 4096)
                return -EINVAL;

        value = strndup(_value, len);
        if (!value)
                return -ENOMEM;

        r = write_string_file(path, value, WRITE_STRING_FILE_DISABLE_BUFFER | WRITE_STRING_FILE_NOFOLLOW);
        if (r < 0) {
                /* On failure, clear cache entry, as we do not know how it fails. */
                device_remove_cached_sysattr_value(device, sysattr);
                return r;
        }

        /* Do not cache action string written into uevent file. */
        if (streq(sysattr, "uevent"))
                return 0;

        r = device_cache_sysattr_value(device, sysattr, value);
        if (r < 0)
                log_device_debug_errno(device, r,
                                       "sd-device: failed to cache attribute '%s' with '%s', ignoring: %m",
                                       sysattr, value);
        else
                TAKE_PTR(value);

        return 0;
}

_public_ int sd_device_set_sysattr_valuef(sd_device *device, const char *sysattr, const char *format, ...) {
        _cleanup_free_ char *value = NULL;
        va_list ap;
        int r;

        assert_return(device, -EINVAL);
        assert_return(sysattr, -EINVAL);

        if (!format) {
                device_remove_cached_sysattr_value(device, sysattr);
                return 0;
        }

        va_start(ap, format);
        r = vasprintf(&value, format, ap);
        va_end(ap);

        if (r < 0)
                return -ENOMEM;

        return sd_device_set_sysattr_value(device, sysattr, value);
}

_public_ int sd_device_trigger(sd_device *device, sd_device_action_t action) {
        const char *s;

        assert_return(device, -EINVAL);

        s = device_action_to_string(action);
        if (!s)
                return -EINVAL;

        /* This uses the simple no-UUID interface of kernel < 4.13 */
        return sd_device_set_sysattr_value(device, "uevent", s);
}

_public_ int sd_device_trigger_with_uuid(
                sd_device *device,
                sd_device_action_t action,
                sd_id128_t *ret_uuid) {

        const char *s, *j;
        sd_id128_t u;
        int r;

        assert_return(device, -EINVAL);

        /* If no one wants to know the UUID, use the simple interface from pre-4.13 times */
        if (!ret_uuid)
                return sd_device_trigger(device, action);

        s = device_action_to_string(action);
        if (!s)
                return -EINVAL;

        r = sd_id128_randomize(&u);
        if (r < 0)
                return r;

        j = strjoina(s, " ", SD_ID128_TO_UUID_STRING(u));

        r = sd_device_set_sysattr_value(device, "uevent", j);
        if (r < 0)
                return r;

        *ret_uuid = u;
        return 0;
}

_public_ int sd_device_open(sd_device *device, int flags) {
        _cleanup_close_ int fd = -EBADF, fd2 = -EBADF;
        const char *devname, *subsystem = NULL;
        uint64_t q, diskseq = 0;
        struct stat st;
        dev_t devnum;
        int r;

        assert_return(device, -EINVAL);
        assert_return(FLAGS_SET(flags, O_PATH) || !FLAGS_SET(flags, O_NOFOLLOW), -EINVAL);

        r = sd_device_get_devname(device, &devname);
        if (r == -ENOENT)
                return -ENOEXEC;
        if (r < 0)
                return r;

        r = sd_device_get_devnum(device, &devnum);
        if (r == -ENOENT)
                return -ENOEXEC;
        if (r < 0)
                return r;

        r = sd_device_get_subsystem(device, &subsystem);
        if (r < 0 && r != -ENOENT)
                return r;

        fd = open(devname, FLAGS_SET(flags, O_PATH) ? flags : O_CLOEXEC|O_NOFOLLOW|O_PATH);
        if (fd < 0)
                return -errno;

        if (fstat(fd, &st) < 0)
                return -errno;

        if (st.st_rdev != devnum)
                return -ENXIO;

        if (streq_ptr(subsystem, "block") ? !S_ISBLK(st.st_mode) : !S_ISCHR(st.st_mode))
                return -ENXIO;

        /* If flags has O_PATH, then we cannot check diskseq. Let's return earlier. */
        if (FLAGS_SET(flags, O_PATH))
                return TAKE_FD(fd);

        /* If the device is not initialized, then we cannot determine if we should check diskseq through
         * ID_IGNORE_DISKSEQ property. Let's skip to check diskseq in that case. */
        r = sd_device_get_is_initialized(device);
        if (r < 0)
                return r;
        if (r > 0) {
                r = device_get_property_bool(device, "ID_IGNORE_DISKSEQ");
                if (r < 0 && r != -ENOENT)
                        return r;
                if (r <= 0) {
                        r = sd_device_get_diskseq(device, &diskseq);
                        if (r < 0 && r != -ENOENT)
                                return r;
                }
        }

        fd2 = fd_reopen(fd, flags);
        if (fd2 < 0)
                return fd2;

        if (diskseq == 0)
                return TAKE_FD(fd2);

        r = fd_get_diskseq(fd2, &q);
        if (r < 0)
                return r;

        if (q != diskseq)
                return -ENXIO;

        return TAKE_FD(fd2);
}

int device_opendir(sd_device *device, const char *subdir, DIR **ret) {
        _cleanup_closedir_ DIR *d = NULL;
        _cleanup_free_ char *path = NULL;
        const char *syspath;
        int r;

        assert(device);
        assert(ret);

        r = sd_device_get_syspath(device, &syspath);
        if (r < 0)
                return r;

        if (subdir) {
                if (!path_is_safe(subdir))
                        return -EINVAL;

                path = path_join(syspath, subdir);
                if (!path)
                        return -ENOMEM;
        }

        d = opendir(path ?: syspath);
        if (!d)
                return -errno;

        *ret = TAKE_PTR(d);
        return 0;
}
