From 8642e04b78cd6856a7de6a25d5c78230bba8452b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 22 Jul 2022 09:46:52 +0900 Subject: [PATCH] network: also assign rfkill device to Wiphy object Preparation for later commits. --- src/network/networkd-manager.c | 6 +++ src/network/networkd-wiphy.c | 91 ++++++++++++++++++++++++++++++++++ src/network/networkd-wiphy.h | 2 + 3 files changed, 99 insertions(+) diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 302ba729bd2..265c7e62c67 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -190,6 +190,8 @@ static int manager_process_uevent(sd_device_monitor *monitor, sd_device *device, r = manager_udev_process_link(m, device, action); else if (streq(s, "ieee80211")) r = manager_udev_process_wiphy(m, device, action); + else if (streq(s, "rfkill")) + r = manager_udev_process_rfkill(m, device, action); else { log_device_debug(device, "Received device with unexpected subsystem \"%s\", ignoring.", s); return 0; @@ -225,6 +227,10 @@ static int manager_connect_udev(Manager *m) { if (r < 0) return log_error_errno(r, "Could not add device monitor filter for ieee80211 subsystem: %m"); + r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "rfkill", NULL); + if (r < 0) + return log_error_errno(r, "Could not add device monitor filter for rfkill subsystem: %m"); + r = sd_device_monitor_attach_event(m->device_monitor, m->event); if (r < 0) return log_error_errno(r, "Failed to attach event to device monitor: %m"); diff --git a/src/network/networkd-wiphy.c b/src/network/networkd-wiphy.c index 113b6714792..1c258e24169 100644 --- a/src/network/networkd-wiphy.c +++ b/src/network/networkd-wiphy.c @@ -7,6 +7,7 @@ #include "networkd-manager.h" #include "networkd-wiphy.h" #include "parse-util.h" +#include "path-util.h" #include "udev-util.h" #include "wifi-util.h" @@ -21,6 +22,7 @@ Wiphy *wiphy_free(Wiphy *w) { } sd_device_unref(w->dev); + sd_device_unref(w->rfkill); free(w->name); return mfree(w); @@ -163,6 +165,59 @@ static int wiphy_update_device(Wiphy *w) { return 0; } +static int wiphy_update_rfkill(Wiphy *w) { + _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; + sd_device *rfkill; + int r; + + assert(w); + + if (!udev_available()) + return 0; + + w->rfkill = sd_device_unref(w->rfkill); + + if (!w->dev) + return 0; + + r = sd_device_enumerator_new(&e); + if (r < 0) + return r; + + r = sd_device_enumerator_allow_uninitialized(e); + if (r < 0) + return r; + + r = sd_device_enumerator_add_match_subsystem(e, "rfkill", true); + if (r < 0) + return r; + + r = sd_device_enumerator_add_match_parent(e, w->dev); + if (r < 0) + return r; + + rfkill = sd_device_enumerator_get_device_first(e); + if (!rfkill) { + /* rfkill device may not detected by the kernel yet, and may appear later. */ + log_wiphy_debug_errno(w, SYNTHETIC_ERRNO(ENODEV), "No rfkill device found, ignoring."); + return 0; + } + + if (sd_device_enumerator_get_device_next(e)) + return log_wiphy_debug_errno(w, SYNTHETIC_ERRNO(EEXIST), "Multiple rfkill devices found."); + + w->rfkill = sd_device_ref(rfkill); + + if (DEBUG_LOGGING) { + const char *s = NULL; + + (void) sd_device_get_syspath(rfkill, &s); + log_wiphy_debug(w, "Found rfkill device: %s", strna(s)); + } + + return 0; +} + static int wiphy_update(Wiphy *w) { int r; @@ -172,6 +227,10 @@ static int wiphy_update(Wiphy *w) { if (r < 0) return log_wiphy_debug_errno(w, r, "Failed to update wiphy device: %m"); + r = wiphy_update_rfkill(w); + if (r < 0) + return log_wiphy_debug_errno(w, r, "Failed to update rfkill device: %m"); + return 0; } @@ -284,3 +343,35 @@ int manager_udev_process_wiphy(Manager *m, sd_device *device, sd_device_action_t return device_unref_and_replace(w->dev, action == SD_DEVICE_REMOVE ? NULL : device); } + +int manager_udev_process_rfkill(Manager *m, sd_device *device, sd_device_action_t action) { + _cleanup_free_ char *parent_path = NULL, *parent_name = NULL; + const char *s; + Wiphy *w; + int r; + + assert(m); + assert(device); + + r = sd_device_get_syspath(device, &s); + if (r < 0) + return log_device_debug_errno(device, r, "Failed to get syspath: %m"); + + /* Do not use sd_device_get_parent() here, as this might be a 'remove' uevent. */ + r = path_extract_directory(s, &parent_path); + if (r < 0) + return log_device_debug_errno(device, r, "Failed to get parent syspath: %m"); + + r = path_extract_filename(parent_path, &parent_name); + if (r < 0) + return log_device_debug_errno(device, r, "Failed to get parent name: %m"); + + r = wiphy_get_by_name(m, parent_name, &w); + if (r < 0) { + /* This error is not critical, as the corresponding genl message may be received later. */ + log_device_debug_errno(device, r, "Failed to get Wiphy object: %m"); + return 0; + } + + return device_unref_and_replace(w->rfkill, action == SD_DEVICE_REMOVE ? NULL : device); +} diff --git a/src/network/networkd-wiphy.h b/src/network/networkd-wiphy.h index 9e8a3a5560b..5f0f47a2306 100644 --- a/src/network/networkd-wiphy.h +++ b/src/network/networkd-wiphy.h @@ -16,6 +16,7 @@ typedef struct Wiphy { char *name; sd_device *dev; + sd_device *rfkill; } Wiphy; Wiphy *wiphy_free(Wiphy *w); @@ -26,6 +27,7 @@ int wiphy_get_by_name(Manager *manager, const char *name, Wiphy **ret); int manager_genl_process_nl80211_wiphy(sd_netlink *genl, sd_netlink_message *message, Manager *manager); int manager_udev_process_wiphy(Manager *m, sd_device *device, sd_device_action_t action); +int manager_udev_process_rfkill(Manager *m, sd_device *device, sd_device_action_t action); #define log_wiphy_full_errno_zerook(w, level, error, ...) \ ({ \ -- 2.47.3