udev: introduce device_get_sysattr_value_maybe_from_netlink()
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "device-private.h"
|
||||
#include "netlink-util.h"
|
||||
#include "strv.h"
|
||||
#include "udev-netlink.h"
|
||||
|
||||
void link_info_clear(LinkInfo *info) {
|
||||
@@ -85,3 +87,141 @@ int link_info_get(sd_netlink **rtnl, int ifindex, LinkInfo *ret) {
|
||||
info = LINK_INFO_NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cache_unsigned(sd_device *device, const char *attr, uint64_t val) {
|
||||
_cleanup_free_ char *str = NULL;
|
||||
int r;
|
||||
|
||||
assert(device);
|
||||
assert(attr);
|
||||
|
||||
if (device_get_cached_sysattr_value(device, attr, NULL) != -ESTALE)
|
||||
return 0;
|
||||
|
||||
if (asprintf(&str, "%"PRIu64, val) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = device_cache_sysattr_value(device, attr, str);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
TAKE_PTR(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cache_hw_addr(sd_device *device, const char *attr, const struct hw_addr_data *hw_addr) {
|
||||
_cleanup_free_ char *str = NULL;
|
||||
int r;
|
||||
|
||||
assert(device);
|
||||
assert(attr);
|
||||
assert(hw_addr);
|
||||
|
||||
if (device_get_cached_sysattr_value(device, attr, NULL) != -ESTALE)
|
||||
return 0;
|
||||
|
||||
str = new(char, HW_ADDR_TO_STRING_MAX);
|
||||
if (!str)
|
||||
return -ENOMEM;
|
||||
|
||||
r = device_cache_sysattr_value(device, attr, hw_addr_to_string(hw_addr, str));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
TAKE_PTR(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cache_string(sd_device *device, const char *attr, const char *val) {
|
||||
_cleanup_free_ char *str = NULL;
|
||||
int r;
|
||||
|
||||
assert(device);
|
||||
assert(attr);
|
||||
|
||||
if (device_get_cached_sysattr_value(device, attr, NULL) != -ESTALE)
|
||||
return 0;
|
||||
|
||||
if (val) {
|
||||
str = strdup(val);
|
||||
if (!str)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
r = device_cache_sysattr_value(device, attr, str);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
TAKE_PTR(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int device_cache_sysattr_from_link_info(sd_device *device, LinkInfo *info) {
|
||||
int ifindex, r;
|
||||
|
||||
assert(device);
|
||||
assert(info);
|
||||
|
||||
r = sd_device_get_ifindex(device, &ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (ifindex != info->ifindex)
|
||||
return -EINVAL;
|
||||
|
||||
r = cache_unsigned(device, "type", info->iftype);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = cache_hw_addr(device, "address", &info->hw_addr);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = cache_unsigned(device, "iflink", info->iflink);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (info->support_phys_port_name) {
|
||||
r = cache_string(device, "phys_port_name", info->phys_port_name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int device_get_sysattr_value_maybe_from_netlink(
|
||||
sd_device *device,
|
||||
sd_netlink **rtnl,
|
||||
const char *sysattr,
|
||||
const char **ret_value) {
|
||||
|
||||
_cleanup_(link_info_clear) LinkInfo info = LINK_INFO_NULL;
|
||||
int ifindex, r;
|
||||
|
||||
assert(device);
|
||||
assert(rtnl);
|
||||
assert(sysattr);
|
||||
|
||||
if (sd_device_get_ifindex(device, &ifindex) < 0)
|
||||
return sd_device_get_sysattr_value(device, sysattr, ret_value);
|
||||
|
||||
if (!STR_IN_SET(sysattr, "type", "address", "iflink", "phys_port_name"))
|
||||
return sd_device_get_sysattr_value(device, sysattr, ret_value);
|
||||
|
||||
r = device_get_cached_sysattr_value(device, sysattr, ret_value);
|
||||
if (r != -ESTALE)
|
||||
return r;
|
||||
|
||||
r = link_info_get(rtnl, ifindex, &info);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = device_cache_sysattr_from_link_info(device, &info);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Do not use device_get_cached_sysattr_value() here, as kernel may not support
|
||||
* IFLA_PHYS_PORT_NAME, and in that case we need to read the value from sysfs. */
|
||||
return sd_device_get_sysattr_value(device, sysattr, ret_value);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "sd-device.h"
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "ether-addr-util.h"
|
||||
@@ -21,3 +22,9 @@ typedef struct LinkInfo {
|
||||
|
||||
void link_info_clear(LinkInfo *info);
|
||||
int link_info_get(sd_netlink **rtnl, int ifindex, LinkInfo *ret);
|
||||
int device_cache_sysattr_from_link_info(sd_device *device, LinkInfo *info);
|
||||
int device_get_sysattr_value_maybe_from_netlink(
|
||||
sd_device *device,
|
||||
sd_netlink **rtnl,
|
||||
const char *sysattr,
|
||||
const char **ret_value);
|
||||
|
||||
Reference in New Issue
Block a user