However, somewhat recently I believe I heard (read) you say on IRC that
the recommended way was actually the other way around, so I switched to
start netlinkd first, and then run coldplug.
 Well, it's really up to you.
 The thing is, if you coldplug first then listen to the netlink, you
have a window where events can appear and won't be picked up: the
netlink listener isn't up yet so the kernel is talking to the hand,
but the coldplugr has already scanned /sys and won't do it again,
so nobody will notice a device needs to be added.

 Listening to the netlink first and then running the coldplug makes
sure there's no race condition where events will be ignored.


But, it seems to me that when you're talking about this you expect one
to have two different instances of mdevd, one for netlinkd & another one
for coldplug. That's not how I made things however: mdevd is a longrun
and I simply have both coldplug & netlinkd piped into it.

 That can work, but I think it's overly complex.


If not, does that mean the recommended way is really to have two
instances of mdevd? Or is there another/better way I'm not seeing? I
like to have only a single mdevd, one longrun (logged) service, as (I
feel) it should be.

 mdevd is not a long-lived process per se: it simply reads from its
stdin, and it dies when it reads EOF. Think "cat". The real long-lived
process is mdevd-netlink, which normally never dies, and never closes
its stdout, so an attached mdevd process would never die either.

 So yes, it's okay to have - temporarily - two mdevd instances, that's
the design I had in mind.

 One is long-lived, reading from mdevd-netlink, and can be logged ; if
you want to both supervise it separately from mdevd-netlink and log its
output, you need a supervision architecture that can pipeline more than
two longruns. (I wonder where that can be found. ;))
 The other one is short-lived, reading from mdevd-coldplug which is a
short-lived program. So you would just have a "mdevd-coldplug | mdevd"
oneshot running after the mdevd-netlink pipeline has been launched.
The second mdevd will simply die when the coldplug is over.

 It's not a problem to have two mdevd instances running concurrently.
The worst that can happen is that an event arrives after mdevd-netlink
is running but before mdevd-coldplug has finished scanning /sys; in
that case, the event will be picked up twice, and depending on how
complex and duplicate-resistant the event handling is in mdev.conf,
shenanigans may happen. But:
 - for the majority of devices, nothing special will happen; the
later instance will just fail to perform some action because the earlier
instance has already done it, it will log a warning and ignore the event.
 - this problem would also occur with a single mdevd instance; you
would simply send it the same event twice.

 I don't think that corner case is worth worrying about. It is
unavoidable no matter the device manager you're using.


On another topic of sorts: so I start mdevd, netlinkd, and run coldplug.
Cool. But what else would I need to do (upon boot) to ensure everything
has been processed correctly?

By that I mean, currently if I don't do anything else, some things
aren't processed. For instance, my audio card isn't there, neither are
a few input devices, such as my (usb) mouse.

 Oh? In that case, I would say it's a bug in mdevd-coldplug, which is
supposed to process everything. Do you have a pattern of stuff that
isn't processed and should be?


#!/usr/bin/execlineb -P
pipeline { find /sys -type f -name uevent -print0 }
forstdin -0 -p f importas -u f f redirfd -w 1 $f echo add

 This is the job of mdevd-coldplug you're duplicating, so yeah, if
you have to do that, then it's better to fix mdevd-coldplug. :)

 The problem with your script is that it's getting a lot of
duplicates, since multiple symlinks in /sys point to the same
directory describing your device. I'm still hoping to avoid scanning
the entirety of /sys, so I'd like to find a correct pattern, but if
there's no other way, I'll just scan everything discarding symlinks.


Now I may be doing something wrong somewhere, but I've always had to use
a larger buffer to make sure things worked correctly myself (That is,
even before w/ s6-uevent-listener).
I'm currently using 1 MB (1048576) to be sure, though it should work
with a smaller one, but I know that even with 131072 (so twice your
"large side" default) I'd always get the following error during boot:

mdevd-netlink: fatal: unable to receive netlink message: No buffer
space available

 Wow. That sounds very weird. What in your boot sequence could create
such a huge burst of events? Can you strace mdevd-netlink to see
what it's reading from the kernel, and tee its output to check whether
those are legit events to be sent to mdevd or line noise that is
improperly filtered at netlink registration time?

--
 Laurent

Reply via email to