summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2020-11-09 12:11:43 +0100
committerAleksander Morgado <aleksander@aleksander.es>2020-11-14 13:39:40 +0000
commitcca83392f09a2a67178203d493656c4355863106 (patch)
tree752c7999e17e899030c03e0386828aad26f99ebf
parent769ba3cee6fa7c985069165ee4ace99c356df949 (diff)
kerneldevice,generic: implement ATTRS matching for any attribute
Until now we did not support ATTRS{} matches against attributes we don't support in the core codebase. Implement now a simple lookup mechanism which traverses the tree of sysfs path from the port sysfs path to the physical device sysfs path, looking up the attribute requested. This is not completely equivalent to what udev does, because the udev rules matching ATTRS would usually also include an additional previous matching e.g. SUBSYSTEMS and such, so that the ATTRS is looked up exactly in the device that also matches the additional previous rules. In our case, we just simplify the logic and return the first one found.
-rw-r--r--src/kerneldevice/mm-kernel-device-generic.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/src/kerneldevice/mm-kernel-device-generic.c b/src/kerneldevice/mm-kernel-device-generic.c
index e6e69b67..3b9956b2 100644
--- a/src/kerneldevice/mm-kernel-device-generic.c
+++ b/src/kerneldevice/mm-kernel-device-generic.c
@@ -123,6 +123,36 @@ read_sysfs_attribute_link_basename (const gchar *path,
return g_path_get_basename (canonicalized_path);
}
+static gchar *
+lookup_sysfs_attribute_as_string (MMKernelDeviceGeneric *self,
+ const gchar *attribute)
+{
+ g_autofree gchar *iter = NULL;
+
+ /* if there is no parent sysfs path set, we look for the attribute
+ * only in the port sysfs path */
+ if (!self->priv->physdev_sysfs_path)
+ return read_sysfs_attribute_as_string (self->priv->sysfs_path, attribute);
+
+ iter = g_strdup (self->priv->sysfs_path);
+ while (iter) {
+ g_autofree gchar *parent = NULL;
+ gchar *value;
+
+ /* return first one found */
+ if ((value = read_sysfs_attribute_as_string (iter, attribute)) != NULL)
+ return value;
+
+ if (g_strcmp0 (iter, self->priv->physdev_sysfs_path) == 0)
+ break;
+ parent = g_path_get_dirname (iter);
+ g_clear_pointer (&iter, g_free);
+ iter = g_steal_pointer (&parent);
+ }
+
+ return NULL;
+}
+
/*****************************************************************************/
/* Load contents */
@@ -780,8 +810,12 @@ check_condition (MMKernelDeviceGeneric *self,
else if (g_str_equal (attribute, "bInterfaceNumber"))
result = (g_str_equal (match->value, "?*") || ((mm_get_uint_from_hex_str (match->value, &val)) &&
((self->priv->interface_number == val) == condition_equal)));
- else
- mm_obj_warn (self, "unknown attribute: %s", attribute);
+ else {
+ g_autofree gchar *found_value = NULL;
+
+ found_value = lookup_sysfs_attribute_as_string (self, attribute);
+ result = ((found_value && g_str_equal (found_value, match->value)) == condition_equal);
+ }
g_free (contents);
g_free (attribute);