[systemd-devel] Confusing hwdb matching behaviour
David Herrmann
dh.herrmann at gmail.com
Mon Sep 12 12:18:23 UTC 2016
Hey!
On Wed, Aug 31, 2016 at 6:37 AM, Peter Hutterer
<peter.hutterer at who-t.net> wrote:
> The hwdb behaviour is a bit hard to predict when multiple matches with globs
> apply to a device so I'm wondering whether this is just an implementation
> result or intended behaviour.
>
> Example 1:
> $> cat 99-test.hwdb
> test:*
> match=generic
>
> test:specific*
> match=specific
>
> $> systemd-hwdb query "test:specific_match"
> match=specific
>
> This is what I would expect from the hwdb entries. But if we have a rule where
> glob matches before specific, the generic one overwrites the specific one:
>
> Example 2:
> $> cat 99-test.hwdb
> test:*
> match=generic
>
> test:*specific*
> match=specific
> match2=yep
>
> $> systemd-hwdb query "test:specific_match"
> match=generic
> match2=yep
>
> Definitely not what I expected (note: the order of the entries
> doesn't matter). This is actually a problem for libinput because it means we
> can't overwrite generic matches with specific matches.
> But it gets even weirder once we start stacking more:
>
> Example 3:
> $> cat 99-test.hwdb
> test:*
> match=generic
>
> test:*specific*
> match=specific
> match2=yep
>
> test:*specific_match
> match=specific
> match2=nope
> match3=yep
>
> $> sudo systemd-hwdb query "test:specific_match"
> match=generic
> match2=nope
> match3=yep
>
> It picks the most generic one last but the more specific one over the less
> specific one. This is confusing and hard to predict. But it gets worse:
>
> Example 4:
> $> cat 99-test.hwdb
> test:*
> match=generic
>
> test:*specific*
> match=specific
> match2=yep
>
> test:*spe*match
> match=specific
> match2=nope
> match3=yep
>
> test:*specific*match
> match=specific
> match2=oh
> match3=what
> match4=confused
>
> $> sudo systemd-hwdb query "test:specific_match"
> match=generic
> match2=yep
> match3=what
> match4=confused
>
> And now I'm lost :)
> As a homework, try predicting what this one produces:
>
> Exercise:
> test:*
> MATCH=generic
>
> # changing this to test:specific gives different results
> test:*specific*
> MATCH=specific
> MATCH2=yep
>
> test:*spe*match
> MATCH=specific
> MATCH2=nope
> MATCH3=yep
>
> test:*specific_*
> MATCH=specific
> MATCH2=oh
> MATCH3=crap
> MATCH4=what?
>
> test:*specific*match
> MATCH=specific
> MATCH2=doh
> MATCH3=what
> MATCH4=confused
> MATCH5=boo
>
>
> Solution:
> "generic, oh, crap, what?, boo" with the glob, without the glob it's
> "specific, yep, crap, what?, boo"
>
> So the question is: is this the intended behaviour (if so, we should
> document it and make it official) or is this a side-effect. If that, can we
> change it or is it set in stone? I think no-one but me is currently eagerly
> stacking hwdb snippets, so maybe there's room to move.
The matching order always matches children before a node itself, and
children in alphabetical order (ASCII). The trie is built based on
prefix-matches. So parsing order does not matter. Lets look at your
last example (with both possible scenarios):
test:*
test:specific
test:*specific*
test:*spe*match
test:*specific_*
test:*specific*match
This will be searched in this order:
test:*spe*match
test:*specific*match
test:*specific*
test:*specific_*
test:*
test:specific
(Ascii order: '*' < UPPER-CASE < '_' < LOWER-CASE)
(Later matches override properties of earlier matches)
I'm not saying this is a useful order, I'm just describing what the
code currently does.
> As for expected behaviour, I'd intuitively expect a more sequential matching,
> with an entry in 99-test.hwd overwriting whatever entry was in 10-test.hwdb.
If things are not stored in ASCII order, you break bsearch() and
lookup performance would drop.
A much easier solution would be to use multiple virtual tries: Prefix
your generic matches with "test-generic:*foobar*" and your specific
ones with "test-specific:*foobar*" and then always lookup both. This
obviously only works if the number of levels is static.
As a hack, I think you can use "**", "***", ... to change the ordering
to your needs.
We could also say each hwdb-source gets its own virtual trie and
they're searched in alphabetical order. This would break ABI, but
would make it a lot more powerful.
Not sure. Maybe Kay has some comments?
David
More information about the systemd-devel
mailing list