On Fri, Mar 26, 2021 at 11:48:10AM -0500, Jonathon Jongsma wrote: > We need to query mdevctl for changes to device definitions since an > administrator can define new devices by executing mdevctl outside of > libvirt. > > In the future, mdevctl may add a way to signal device add/remove via > events, but for now we resort to a bit of a workaround: monitoring the > mdevctl config directory for changes to files. When a change is > detected, we query mdevctl and update our device list. The mdevctl > querying is handled in a throwaway thread, and these threads are > synchronized with a mutex. > > Signed-off-by: Jonathon Jongsma <jjongsma@xxxxxxxxxx> > --- ... > +static void > +mdevctlEventHandleCallback(GFileMonitor *monitor G_GNUC_UNUSED, > + GFile *file, > + GFile *other_file G_GNUC_UNUSED, > + GFileMonitorEvent event_type, > + gpointer user_data) > +{ > + udevEventData *priv = user_data; > + /* if a new directory appears, monitor that directory for changes */ > + if (event_type == G_FILE_MONITOR_EVENT_CREATED && > + g_file_query_file_type(file, G_FILE_QUERY_INFO_NONE, NULL) == > + G_FILE_TYPE_DIRECTORY) { ^probably better written as: if (event_type == G_FILE_MONITOR_EVENT_CREATED) { file_type = g_file_query_file_type(file, G_FILE_QUERY_INFO_NONE, NULL); if (file_type == G_FILE_TYPE_DIRECTORY) { ... } } > + GList *newmonitors = monitorFileRecursively(priv, file); newline here for better optical code separation > + virMutexLock(&priv->mdevctlLock); > + priv->mdevctlMonitors = g_list_concat(priv->mdevctlMonitors, newmonitors); > + virMutexUnlock(&priv->mdevctlLock); > + } > + > + /* When mdevctl creates a device, it can result in multiple notify events > + * emitted for a single logical change (e.g. several CHANGED events, or a > + * CREATED and CHANGED event followed by CHANGES_DONE_HINT). To avoid > + * spawning a mdevctl thread multiple times for a single logical > + * configuration change, try to coalesce these changes by waiting for the > + * CHANGES_DONE_HINT event. As a fallback, add a timeout to trigger the > + * signal if that event never comes */ > + if (event_type != G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT) { > + if (priv->mdevctlTimeout > 0) > + virEventRemoveTimeout(priv->mdevctlTimeout); > + priv->mdevctlTimeout = virEventAddTimeout(100, scheduleMdevctlHandler, > + priv, NULL); > + return; > + } > + > + scheduleMdevctlHandler(-1, priv); > +} Reviewed-by: Erik Skultety <eskultet@xxxxxxxxxx>