device-private.c revision aa20f49a1c5816e6e7e97f2e2ba209be47f3c0a3
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering/***
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering This file is part of systemd.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Copyright 2014 Tom Gundersen <teg@jklm.no>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is free software; you can redistribute it and/or modify it
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering under the terms of the GNU Lesser General Public License as published by
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (at your option) any later version.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is distributed in the hope that it will be useful, but
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Lesser General Public License for more details.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering You should have received a copy of the GNU Lesser General Public License
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering***/
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <ctype.h>
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering#include <sys/types.h>
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering#include <net/if.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "util.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "macro.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "refcnt.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "path-util.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "strxcpyx.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "fileio.h"
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering#include "hashmap.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "set.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "strv.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "mkdir.h"
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack#include "sd-device.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "device-util.h"
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering#include "device-internal.h"
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering#include "device-private.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint device_add_property(sd_device *device, const char *key, const char *value) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(key);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_add_property_aux(device, key, value, false);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (key[0] != '.') {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_add_property_aux(device, key, value, true);
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering if (r < 0)
4f10118016f9b2fd7e1d26c9ef7d91eb33fba694Lennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int device_add_property_internal_from_string(sd_device *device, const char *str) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering _cleanup_free_ char *key = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering char *value;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(device);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(str);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering key = strdup(str);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!key)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -ENOMEM;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering value = strchr(key, '=');
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!value)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -EINVAL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering *value = '\0';
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (isempty(++value))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering value = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return device_add_property_internal(device, key, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int handle_db_line(sd_device *device, char key, const char *value) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering char *path;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(value);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering switch (key) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case 'S':
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering path = strjoina("/dev/", value);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_add_devlink(device, path);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case 'L':
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = safe_atoi(value, &device->devlink_priority);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case 'E':
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_add_property_internal_from_string(device, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case 'G':
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_add_tag(device, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case 'W':
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = safe_atoi(value, &device->watch_handle);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case 'I':
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_set_usec_initialized(device, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering default:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_debug("device db: unknown key '%c'", key);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringvoid device_set_devlink_priority(sd_device *device, int priority) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering device->devlink_priority = priority;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringvoid device_set_is_initialized(sd_device *device) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering device->is_initialized = true;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint device_ensure_usec_initialized(sd_device *device, sd_device *device_old) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char num[DECIMAL_STR_MAX(usec_t)];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering usec_t usec_initialized;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (device_old && device_old->usec_initialized > 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering usec_initialized = device_old->usec_initialized;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering else
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering usec_initialized = now(CLOCK_MONOTONIC);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = snprintf(num, sizeof(num), USEC_FMT, usec_initialized);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_set_usec_initialized(device, num);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack}
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mackstatic int device_read_db(sd_device *device) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_free_ char *db = NULL;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack char *path;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack const char *id, *value;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack char key;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack size_t db_len;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack unsigned i;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack int r;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack enum {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering PRE_KEY,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering KEY,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering PRE_VALUE,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering VALUE,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering INVALID_LINE,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } state = PRE_KEY;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (device->db_loaded || device->sealed)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_get_id_filename(device, &id);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering path = strjoina("/run/udev/data/", id);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = read_full_file(path, &db, &db_len);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r == -ENOENT)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering else {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_debug("sd-device: failed to read db '%s': %s", path, strerror(-r));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering /* devices with a database entry are initialized */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering device_set_is_initialized(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering for (i = 0; i < db_len; i++) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering switch (state) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case PRE_KEY:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!strchr(NEWLINE, db[i])) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering key = db[i];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering state = KEY;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case KEY:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (db[i] != ':') {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_debug("sd-device: ignoring invalid db entry with key '%c'", key);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering state = INVALID_LINE;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } else {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering db[i] = '\0';
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering state = PRE_VALUE;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case PRE_VALUE:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering value = &db[i];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering state = VALUE;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case INVALID_LINE:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (strchr(NEWLINE, db[i]))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering state = PRE_KEY;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case VALUE:
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering if (strchr(NEWLINE, db[i])) {
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack db[i] = '\0';
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering r = handle_db_line(device, key, value);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_debug("sd-device: failed to handle db entry '%c:%s': %s", key, value, strerror(-r));
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack state = PRE_KEY;
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering default:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert_not_reached("invalid state when parsing db");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering device->db_loaded = true;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringuint64_t device_get_properties_generation(sd_device *device) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return device->properties_generation;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringuint64_t device_get_tags_generation(sd_device *device) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return device->tags_generation;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringuint64_t device_get_devlinks_generation(sd_device *device) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return device->devlinks_generation;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint device_get_devnode_mode(sd_device *device, mode_t *mode) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
31938a8560a664c32a9d72f1fc2d4347b232e6e9Michal Schmidt assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(mode);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_read_db(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *mode = device->devmode;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek return 0;
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek}
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint device_get_devnode_uid(sd_device *device, uid_t *uid) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(uid);
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek r = device_read_db(device);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt if (r < 0)
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *uid = device->devuid;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int device_set_devuid(sd_device *device, const char *uid) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering unsigned u;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(uid);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = safe_atou(uid, &u);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_add_property_internal(device, "DEVUID", uid);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering device->devuid = u;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint device_get_devnode_gid(sd_device *device, gid_t *gid) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(gid);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_read_db(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *gid = device->devgid;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int device_set_devgid(sd_device *device, const char *gid) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering unsigned g;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(device);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(gid);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = safe_atou(gid, &g);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_add_property_internal(device, "DEVGID", gid);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering device->devgid = g;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int device_ammend(sd_device *device, const char *key, const char *value) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(key);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(value);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (streq(key, "DEVPATH")) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering char *path;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering path = strjoina("/sys", value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* the caller must verify or trust this data (e.g., if it comes from the kernel) */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_set_syspath(device, path, false);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return log_debug_errno(r, "sd-device: could not set syspath to '%s': %m", path);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else if (streq(key, "SUBSYSTEM")) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_set_subsystem(device, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return log_debug_errno(r, "sd-device: could not set subsystem to '%s': %m", value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else if (streq(key, "DEVTYPE")) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_set_devtype(device, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return log_debug_errno(r, "sd-device: could not set devtype to '%s': %m", value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else if (streq(key, "DEVNAME")) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_set_devname(device, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return log_debug_errno(r, "sd-device: could not set devname to '%s': %m", value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else if (streq(key, "USEC_INITIALIZED")) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_set_usec_initialized(device, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return log_debug_errno(r, "sd-device: could not set usec-initialized to '%s': %m", value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else if (streq(key, "DRIVER")) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_set_driver(device, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return log_debug_errno(r, "sd-device: could not set driver to '%s': %m", value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else if (streq(key, "IFINDEX")) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_set_ifindex(device, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return log_debug_errno(r, "sd-device: could not set ifindex to '%s': %m", value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else if (streq(key, "DEVMODE")) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt r = device_set_devmode(device, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return log_debug_errno(r, "sd-device: could not set devmode to '%s': %m", value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else if (streq(key, "DEVUID")) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_set_devuid(device, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return log_debug_errno(r, "sd-device: could not set devuid to '%s': %m", value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else if (streq(key, "DEVGID")) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_set_devgid(device, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return log_debug_errno(r, "sd-device: could not set devgid to '%s': %m", value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else if (streq(key, "DEVLINKS")) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering char *devlinks, *next;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering devlinks = strdupa(value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering while ((next = strchr(devlinks, ' '))) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering next[0] = '\0';
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_add_devlink(device, devlinks);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return log_debug_errno(r, "sd-device: could not add devlink '%s': %m", devlinks);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering devlinks = next + 1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } else if (streq(key, "TAGS")) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering char *tags, *next;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering tags = strdupa(value);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering while ((next = strchr(tags, ':'))) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering next[0] = '\0';
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_add_tag(device, tags);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return log_debug_errno(r, "sd-device: could not add tag '%s': %m", tags);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering tags = next + 1;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
db2cb23b5b179707000d28a11efb3d888d06ee80Umut Tezduyar Lindskog } else {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_add_property_internal(device, key, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return log_debug_errno(r, "sd-device: could not add property '%s=%s': %m", key, value);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
31938a8560a664c32a9d72f1fc2d4347b232e6e9Michal Schmidt
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic const char* const device_action_table[_DEVICE_ACTION_MAX] = {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering [DEVICE_ACTION_ADD] = "add",
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering [DEVICE_ACTION_REMOVE] = "remove",
31938a8560a664c32a9d72f1fc2d4347b232e6e9Michal Schmidt [DEVICE_ACTION_CHANGE] = "change",
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering [DEVICE_ACTION_MOVE] = "move",
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering [DEVICE_ACTION_ONLINE] = "online",
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering [DEVICE_ACTION_OFFLINE] = "offline",
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering};
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart PoetteringDEFINE_STRING_TABLE_LOOKUP(device_action, DeviceAction);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int device_append(sd_device *device, char *key, const char **_major, const char **_minor, uint64_t *_seqnum,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering DeviceAction *_action) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering DeviceAction action = _DEVICE_ACTION_INVALID;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering uint64_t seqnum = 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *major = NULL, *minor = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering char *value;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(device);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(key);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(_major);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(_minor);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(_seqnum);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack assert(_action);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack value = strchr(key, '=');
31938a8560a664c32a9d72f1fc2d4347b232e6e9Michal Schmidt if (!value) {
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack log_debug("sd-device: not a key-value pair: '%s'", key);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack return -EINVAL;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack }
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack *value = '\0';
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering value++;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (streq(key, "MAJOR"))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering major = value;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering else if (streq(key, "MINOR"))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering minor = value;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering else {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (streq(key, "ACTION")) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering action = device_action_from_string(value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (action == _DEVICE_ACTION_INVALID)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -EINVAL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else if (streq(key, "SEQNUM")) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = safe_atou64(value, &seqnum);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering else if (seqnum == 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* kernel only sends seqnum > 0 */
8d0e0ddda6501479eb69164687c83c1a7667b33aJan Engelhardt return -EINVAL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_ammend(device, key, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
31938a8560a664c32a9d72f1fc2d4347b232e6e9Michal Schmidt
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (major != 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering *_major = major;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (minor != 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering *_minor = minor;
8d0e0ddda6501479eb69164687c83c1a7667b33aJan Engelhardt
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (action != _DEVICE_ACTION_INVALID)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering *_action = action;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (seqnum > 0)
31938a8560a664c32a9d72f1fc2d4347b232e6e9Michal Schmidt *_seqnum = seqnum;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringvoid device_seal(sd_device *device) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(device);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering device->sealed = true;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int device_verify(sd_device *device, DeviceAction action, uint64_t seqnum) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!device->devpath || !device->subsystem || action == _DEVICE_ACTION_INVALID || seqnum == 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_debug("sd-device: device created from strv lacks devpath, subsystem, action or seqnum");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -EINVAL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering device->sealed = true;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack}
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mackint device_new_from_strv(sd_device **ret, char **strv) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_device_unref_ sd_device *device = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char **key;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *major = NULL, *minor = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering DeviceAction action = _DEVICE_ACTION_INVALID;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering uint64_t seqnum;
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering int r;
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering
ff975efb2e88dcd5221a2f0d76c4c87e85b821a8Lennart Poettering assert(ret);
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering assert(strv);
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_new_aux(&device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering STRV_FOREACH(key, strv) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_append(device, *key, &major, &minor, &seqnum, &action);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (major) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_set_devnum(device, major, minor);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return log_debug_errno(r, "sd-device: could not set devnum %s:%s: %m", major, minor);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_verify(device, action, seqnum);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *ret = device;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering device = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_device_unref_ sd_device *device = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *major = NULL, *minor = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering DeviceAction action = _DEVICE_ACTION_INVALID;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering uint64_t seqnum;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering unsigned i = 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(ret);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(nulstr);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(len);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_new_aux(&device);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering while (i < len) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char *key;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *end;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering key = (char*)&nulstr[i];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering end = memchr(key, '\0', len - i);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!end) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_debug("sd-device: failed to parse nulstr");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -EINVAL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering i += end - key + 1;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_append(device, key, &major, &minor, &seqnum, &action);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (major) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_set_devnum(device, major, minor);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return log_debug_errno(r, "sd-device: could not set devnum %s:%s: %m", major, minor);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_verify(device, action, seqnum);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering *ret = device;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering device = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mackstatic int device_update_properties_bufs(sd_device *device) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *val, *prop;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char **buf_strv = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering uint8_t *buf_nulstr = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering size_t allocated_nulstr = 0, allocated_strv = 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering size_t nulstr_len = 0, strv_size = 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!device->properties_buf_outdated)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering FOREACH_DEVICE_PROPERTY(device, prop, val) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering size_t len = 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering len = strlen(prop) + 1 + strlen(val);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering buf_nulstr = GREEDY_REALLOC0(buf_nulstr, allocated_nulstr, nulstr_len + len + 2);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!buf_nulstr)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -ENOMEM;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering buf_strv = GREEDY_REALLOC0(buf_strv, allocated_strv, strv_size + 2);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!buf_strv)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -ENOMEM;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering buf_strv[++ strv_size] = (char *)&buf_nulstr[nulstr_len];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering strscpyl((char *)buf_nulstr + nulstr_len, len + 1, prop, "=", val, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering nulstr_len += len + 1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering free(device->properties_nulstr);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering free(device->properties_strv);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering device->properties_nulstr = buf_nulstr;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering device->properties_nulstr_len = nulstr_len;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering device->properties_strv = buf_strv;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering device->properties_buf_outdated = false;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint device_get_properties_nulstr(sd_device *device, const uint8_t **nulstr, size_t *len) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(nulstr);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(len);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_update_properties_bufs(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *nulstr = device->properties_nulstr;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering *len = device->properties_nulstr_len;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringint device_get_properties_strv(sd_device *device, char ***strv) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering assert(device);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(strv);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_update_properties_bufs(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering *strv = device->properties_strv;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint device_get_devlink_priority(sd_device *device, int *priority) {
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(priority);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_read_db(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *priority = device->devlink_priority;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint device_get_watch_handle(sd_device *device, int *handle) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(device);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(handle);
94e15fdc4d9d96fa6607bfb4eaaea164a3aec417David Herrmann
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = device_read_db(device);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering return r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering *handle = device->watch_handle;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return 0;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering}
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poetteringvoid device_set_watch_handle(sd_device *device, int handle) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(device);
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering device->watch_handle = handle;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering}
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poetteringint device_rename(sd_device *device, const char *name) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering _cleanup_free_ char *dirname = NULL;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering char *new_syspath;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering const char *interface;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering int r;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering assert(device);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(name);
94e15fdc4d9d96fa6607bfb4eaaea164a3aec417David Herrmann
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering dirname = dirname_malloc(device->syspath);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (!dirname)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return -ENOMEM;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering new_syspath = strjoina(dirname, "/", name);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering /* the user must trust that the new name is correct */
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = device_set_syspath(device, new_syspath, false);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = sd_device_get_property_value(device, "INTERFACE", &interface);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r >= 0) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = device_add_property_internal(device, "INTERFACE", name);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
94e15fdc4d9d96fa6607bfb4eaaea164a3aec417David Herrmann return r;
94e15fdc4d9d96fa6607bfb4eaaea164a3aec417David Herrmann
94e15fdc4d9d96fa6607bfb4eaaea164a3aec417David Herrmann /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = device_add_property_internal(device, "INTERFACE_OLD", interface);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return r;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering } else if (r != -ENOENT)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return 0;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering}
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poetteringint device_shallow_clone(sd_device *old_device, sd_device **new_device) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering _cleanup_device_unref_ sd_device *ret = NULL;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering int r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(old_device);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(new_device);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = device_new_aux(&ret);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = device_set_syspath(ret, old_device->syspath, false);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return r;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = device_set_subsystem(ret, old_device->subsystem);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering ret->devnum = old_device->devnum;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering *new_device = ret;
94e15fdc4d9d96fa6607bfb4eaaea164a3aec417David Herrmann ret = NULL;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering return 0;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering}
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poetteringint device_clone_with_db(sd_device *old_device, sd_device **new_device) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering _cleanup_device_unref_ sd_device *ret = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(old_device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(new_device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = device_shallow_clone(old_device, &ret);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering r = device_read_db(ret);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering ret->sealed = true;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *new_device = ret;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering ret = NULL;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint device_new_from_synthetic_event(sd_device **new_device, const char *syspath, const char *action) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_device_unref_ sd_device *ret = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(new_device);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(syspath);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(action);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_device_new_from_syspath(&ret, syspath);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_read_uevent_file(ret);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_add_property_internal(ret, "ACTION", action);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering *new_device = ret;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering ret = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
deffddf1df29a5ed047feff3a0f2b765006fb71bLukas Nykryn return 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringint device_copy_properties(sd_device *device_dst, sd_device *device_src) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *property, *value;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering int r;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering assert(device_dst);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(device_src);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering FOREACH_DEVICE_PROPERTY(device_src, property, value) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_add_property(device_dst, property, value);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringvoid device_cleanup_tags(sd_device *device) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(device);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering set_free_free(device->tags);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering device->tags = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering device->property_tags_outdated = true;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering device->tags_generation ++;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringvoid device_cleanup_devlinks(sd_device *device) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(device);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering set_free_free(device->devlinks);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering device->devlinks = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering device->property_devlinks_outdated = true;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering device->devlinks_generation ++;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringvoid device_remove_tag(sd_device *device, const char *tag) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(device);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(tag);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering free(set_remove(device->tags, tag));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering device->property_tags_outdated = true;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering device->tags_generation ++;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int device_tag(sd_device *device, const char *tag, bool add) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *id;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering char *path;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(device);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(tag);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering r = device_get_id_filename(device, &id);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering path = strjoina("/run/udev/tags/", tag, "/", id);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (add) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0444);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = unlink(path);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0 && errno != ENOENT)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint device_tag_index(sd_device *device, sd_device *device_old, bool add) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *tag;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r = 0, k;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (add && device_old) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* delete possible left-over tags */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering FOREACH_DEVICE_TAG(device_old, tag) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!sd_device_has_tag(device, tag)) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering k = device_tag(device_old, tag, false);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r >= 0 && k < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = k;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering FOREACH_DEVICE_TAG(device, tag) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering k = device_tag(device, tag, add);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r >= 0 && k < 0)
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering r = k;
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering }
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering return r;
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering}
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poetteringstatic bool device_has_info(sd_device *device) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!set_isempty(device->devlinks))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return true;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (device->devlink_priority != 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return true;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!ordered_hashmap_isempty(device->properties_db))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return true;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!set_isempty(device->tags))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return true;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (device->watch_handle >= 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return true;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return false;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringvoid device_set_db_persist(sd_device *device) {
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering assert(device);
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering device->db_persist = true;
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering}
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poetteringint device_update_db(sd_device *device) {
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering const char *id;
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering char *path;
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering _cleanup_free_ char *path_tmp = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bool has_info;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack assert(device);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering has_info = device_has_info(device);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = device_get_id_filename(device, &id);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering path = strjoina("/run/udev/data/", id);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* do not store anything for otherwise empty devices */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!has_info && major(device->devnum) == 0 && device->ifindex == 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = unlink(path);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0 && errno != ENOENT)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -errno;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 0;
700ff4d97311902a440109a2c081731ab6ae8a20Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* write a database file */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = mkdir_parents(path, 0755);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = fopen_temporary(path, &f, &path_tmp);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /*
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * set 'sticky' bit to indicate that we should not clean the
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * database when we transition from initramfs to the real root
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (device->db_persist) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = fchmod(fileno(f), 01644);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = -errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } else {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = fchmod(fileno(f), 0644);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = -errno;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto fail;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (has_info) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *property, *value, *tag;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Iterator i;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (major(device->devnum) > 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *devlink;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering FOREACH_DEVICE_DEVLINK(device, devlink)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering fprintf(f, "S:%s\n", devlink + strlen("/dev/"));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (device->devlink_priority != 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering fprintf(f, "L:%i\n", device->devlink_priority);
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering if (device->watch_handle >= 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering fprintf(f, "W:%i\n", device->watch_handle);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (device->usec_initialized > 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering fprintf(f, "I:"USEC_FMT"\n", device->usec_initialized);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering ORDERED_HASHMAP_FOREACH_KEY(value, property, device->properties_db, i)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering fprintf(f, "E:%s=%s\n", property, value);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering FOREACH_DEVICE_TAG(device, tag)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering fprintf(f, "G:%s\n", tag);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = fflush_and_check(f);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
r = rename(path_tmp, path);
if (r < 0) {
r = -errno;
goto fail;
}
log_debug("created %s file '%s' for '%s'", has_info ? "db" : "empty",
path, device->devpath);
return 0;
fail:
log_error_errno(r, "failed to create %s file '%s' for '%s'", has_info ? "db" : "empty",
path, device->devpath);
unlink(path);
unlink(path_tmp);
return r;
}
int device_delete_db(sd_device *device) {
const char *id;
char *path;
int r;
assert(device);
r = device_get_id_filename(device, &id);
if (r < 0)
return r;
path = strjoina("/run/udev/data/", id);
r = unlink(path);
if (r < 0 && errno != ENOENT)
return -errno;
return 0;
}