[libvirt PATCH v6 14/30] nodedev: Refresh mdev devices when changes are detected

Erik Skultety eskultet at redhat.com
Tue Mar 30 16:21:22 UTC 2021


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 at redhat.com>
> ---
...

> +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 at redhat.com>




More information about the libvir-list mailing list