mirror of
https://git.proxmox.com/git/fwupd
synced 2025-07-27 12:30:17 +00:00
Allow overriding daemon parameters using /var/etc/fwupd/daemon.conf
This is super useful for debugging immutable systems like ChromeOS.
This commit is contained in:
parent
122dee1a19
commit
38bab8fc4f
@ -1448,6 +1448,13 @@ fu_common_get_path(FuPathKind path_kind)
|
|||||||
return g_build_filename(tmp, NULL);
|
return g_build_filename(tmp, NULL);
|
||||||
basedir = fu_common_get_path(FU_PATH_KIND_LOCALSTATEDIR);
|
basedir = fu_common_get_path(FU_PATH_KIND_LOCALSTATEDIR);
|
||||||
return g_build_filename(basedir, "cache", PACKAGE_NAME, NULL);
|
return g_build_filename(basedir, "cache", PACKAGE_NAME, NULL);
|
||||||
|
/* /var/etc/fwupd */
|
||||||
|
case FU_PATH_KIND_LOCALCONFDIR_PKG:
|
||||||
|
tmp = g_getenv("LOCALCONF_DIRECTORY");
|
||||||
|
if (tmp != NULL && g_file_test(tmp, G_FILE_TEST_EXISTS))
|
||||||
|
return g_build_filename(tmp, NULL);
|
||||||
|
basedir = fu_common_get_path(FU_PATH_KIND_LOCALSTATEDIR);
|
||||||
|
return g_build_filename(basedir, "etc", PACKAGE_NAME, NULL);
|
||||||
/* /run/lock */
|
/* /run/lock */
|
||||||
case FU_PATH_KIND_LOCKDIR:
|
case FU_PATH_KIND_LOCKDIR:
|
||||||
return g_strdup("/run/lock");
|
return g_strdup("/run/lock");
|
||||||
|
@ -83,6 +83,7 @@ typedef guint FuEndianType;
|
|||||||
* @FU_PATH_KIND_LOCALSTATEDIR_REMOTES: The local state directory for remotes (IE
|
* @FU_PATH_KIND_LOCALSTATEDIR_REMOTES: The local state directory for remotes (IE
|
||||||
* /var/lib/fwupd/remotes.d)
|
* /var/lib/fwupd/remotes.d)
|
||||||
* @FU_PATH_KIND_WIN32_BASEDIR: The root of the install directory on Windows
|
* @FU_PATH_KIND_WIN32_BASEDIR: The root of the install directory on Windows
|
||||||
|
* @FU_PATH_KIND_LOCALCONFDIR_PKG: The package configuration override (IE /var/etc/fwupd)
|
||||||
*
|
*
|
||||||
* Path types to use when dynamically determining a path at runtime
|
* Path types to use when dynamically determining a path at runtime
|
||||||
**/
|
**/
|
||||||
@ -111,6 +112,7 @@ typedef enum {
|
|||||||
FU_PATH_KIND_LOCALSTATEDIR_METADATA,
|
FU_PATH_KIND_LOCALSTATEDIR_METADATA,
|
||||||
FU_PATH_KIND_LOCALSTATEDIR_REMOTES,
|
FU_PATH_KIND_LOCALSTATEDIR_REMOTES,
|
||||||
FU_PATH_KIND_WIN32_BASEDIR,
|
FU_PATH_KIND_WIN32_BASEDIR,
|
||||||
|
FU_PATH_KIND_LOCALCONFDIR_PKG,
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
FU_PATH_KIND_LAST
|
FU_PATH_KIND_LAST
|
||||||
} FuPathKind;
|
} FuPathKind;
|
||||||
|
@ -23,15 +23,15 @@ fu_config_finalize(GObject *obj);
|
|||||||
|
|
||||||
struct _FuConfig {
|
struct _FuConfig {
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
GFileMonitor *monitor;
|
GPtrArray *monitors; /* (element-type GFileMonitor) */
|
||||||
GPtrArray *disabled_devices; /* (element-type utf-8) */
|
GPtrArray *disabled_devices; /* (element-type utf-8) */
|
||||||
GPtrArray *disabled_plugins; /* (element-type utf-8) */
|
GPtrArray *disabled_plugins; /* (element-type utf-8) */
|
||||||
GPtrArray *approved_firmware; /* (element-type utf-8) */
|
GPtrArray *approved_firmware; /* (element-type utf-8) */
|
||||||
GPtrArray *blocked_firmware; /* (element-type utf-8) */
|
GPtrArray *blocked_firmware; /* (element-type utf-8) */
|
||||||
GPtrArray *uri_schemes; /* (element-type utf-8) */
|
GPtrArray *uri_schemes; /* (element-type utf-8) */
|
||||||
|
GPtrArray *filenames; /* (element-type utf-8) */
|
||||||
guint64 archive_size_max;
|
guint64 archive_size_max;
|
||||||
guint idle_timeout;
|
guint idle_timeout;
|
||||||
gchar *config_file;
|
|
||||||
gchar *host_bkc;
|
gchar *host_bkc;
|
||||||
gboolean update_motd;
|
gboolean update_motd;
|
||||||
gboolean enumerate_all_devices;
|
gboolean enumerate_all_devices;
|
||||||
@ -65,13 +65,30 @@ fu_config_reload(FuConfig *self, GError **error)
|
|||||||
g_autoptr(GError) error_ignore_power = NULL;
|
g_autoptr(GError) error_ignore_power = NULL;
|
||||||
g_autoptr(GError) error_only_trusted = NULL;
|
g_autoptr(GError) error_only_trusted = NULL;
|
||||||
g_autoptr(GError) error_enumerate_all = NULL;
|
g_autoptr(GError) error_enumerate_all = NULL;
|
||||||
|
g_autoptr(GByteArray) buf = g_byte_array_new();
|
||||||
|
|
||||||
if (g_file_test(self->config_file, G_FILE_TEST_EXISTS)) {
|
/* we have to load each file into a buffer as g_key_file_load_from_file() clears the
|
||||||
g_debug("loading config values from %s", self->config_file);
|
* GKeyFile state before loading each file, and we want to allow the mutable version to be
|
||||||
if (!g_key_file_load_from_file(keyfile, self->config_file, G_KEY_FILE_NONE, error))
|
* incomplete and just *override* a specific option */
|
||||||
|
for (guint i = 0; i < self->filenames->len; i++) {
|
||||||
|
const gchar *fn = g_ptr_array_index(self->filenames, i);
|
||||||
|
g_debug("trying to load config values from %s", fn);
|
||||||
|
if (g_file_test(fn, G_FILE_TEST_EXISTS)) {
|
||||||
|
g_autoptr(GBytes) blob = fu_common_get_contents_bytes(fn, error);
|
||||||
|
if (blob == NULL)
|
||||||
|
return FALSE;
|
||||||
|
fu_byte_array_append_bytes(buf, blob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* load if either file found */
|
||||||
|
if (buf->len > 0) {
|
||||||
|
if (!g_key_file_load_from_data(keyfile,
|
||||||
|
(const gchar *)buf->data,
|
||||||
|
buf->len,
|
||||||
|
G_KEY_FILE_NONE,
|
||||||
|
error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else {
|
|
||||||
g_warning("Daemon configuration %s not found", self->config_file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get disabled devices */
|
/* get disabled devices */
|
||||||
@ -223,7 +240,8 @@ fu_config_monitor_changed_cb(GFileMonitor *monitor,
|
|||||||
{
|
{
|
||||||
FuConfig *self = FU_CONFIG(user_data);
|
FuConfig *self = FU_CONFIG(user_data);
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_debug("%s changed, reloading all configs", self->config_file);
|
g_autofree gchar *fn = g_file_get_path(file);
|
||||||
|
g_debug("%s changed, reloading all configs", fn);
|
||||||
if (!fu_config_reload(self, &error))
|
if (!fu_config_reload(self, &error))
|
||||||
g_warning("failed to rescan daemon config: %s", error->message);
|
g_warning("failed to rescan daemon config: %s", error->message);
|
||||||
fu_config_emit_changed(self);
|
fu_config_emit_changed(self);
|
||||||
@ -233,38 +251,55 @@ gboolean
|
|||||||
fu_config_set_key_value(FuConfig *self, const gchar *key, const gchar *value, GError **error)
|
fu_config_set_key_value(FuConfig *self, const gchar *key, const gchar *value, GError **error)
|
||||||
{
|
{
|
||||||
g_autoptr(GKeyFile) keyfile = g_key_file_new();
|
g_autoptr(GKeyFile) keyfile = g_key_file_new();
|
||||||
if (!g_key_file_load_from_file(keyfile, self->config_file, G_KEY_FILE_KEEP_COMMENTS, error))
|
const gchar *fn;
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
|
if (self->filenames->len == 0) {
|
||||||
|
g_set_error(error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, "no config to load");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* only write the file in /etc */
|
||||||
|
fn = g_ptr_array_index(self->filenames, 0);
|
||||||
|
if (!g_key_file_load_from_file(keyfile, fn, G_KEY_FILE_KEEP_COMMENTS, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
g_key_file_set_string(keyfile, "fwupd", key, value);
|
g_key_file_set_string(keyfile, "fwupd", key, value);
|
||||||
if (!g_key_file_save_to_file(keyfile, self->config_file, error))
|
if (!g_key_file_save_to_file(keyfile, fn, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return fu_config_reload(self, error);
|
return fu_config_reload(self, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
fu_config_load(FuConfig *self, GError **error)
|
fu_config_load(FuConfig *self, GError **error)
|
||||||
{
|
{
|
||||||
g_autofree gchar *configdir = NULL;
|
g_autofree gchar *configdir_mut = fu_common_get_path(FU_PATH_KIND_LOCALCONFDIR_PKG);
|
||||||
g_autoptr(GFile) file = NULL;
|
g_autofree gchar *configdir = fu_common_get_path(FU_PATH_KIND_SYSCONFDIR_PKG);
|
||||||
|
|
||||||
g_return_val_if_fail(FU_IS_CONFIG(self), FALSE);
|
g_return_val_if_fail(FU_IS_CONFIG(self), FALSE);
|
||||||
g_return_val_if_fail(self->config_file == NULL, FALSE);
|
g_return_val_if_fail(self->filenames->len == 0, FALSE);
|
||||||
|
|
||||||
/* load the main daemon config file */
|
/* load the main daemon config file */
|
||||||
configdir = fu_common_get_path(FU_PATH_KIND_SYSCONFDIR_PKG);
|
g_ptr_array_add(self->filenames, g_build_filename(configdir, "daemon.conf", NULL));
|
||||||
self->config_file = g_build_filename(configdir, "daemon.conf", NULL);
|
g_ptr_array_add(self->filenames, g_build_filename(configdir_mut, "daemon.conf", NULL));
|
||||||
if (!fu_config_reload(self, error))
|
if (!fu_config_reload(self, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* set up a notify watch */
|
/* set up a notify watches */
|
||||||
file = g_file_new_for_path(self->config_file);
|
for (guint i = 0; i < self->filenames->len; i++) {
|
||||||
self->monitor = g_file_monitor(file, G_FILE_MONITOR_NONE, NULL, error);
|
const gchar *fn = g_ptr_array_index(self->filenames, i);
|
||||||
if (self->monitor == NULL)
|
g_autoptr(GFile) file = g_file_new_for_path(fn);
|
||||||
return FALSE;
|
g_autoptr(GFileMonitor) monitor = NULL;
|
||||||
g_signal_connect(G_FILE_MONITOR(self->monitor),
|
|
||||||
"changed",
|
monitor = g_file_monitor(file, G_FILE_MONITOR_NONE, NULL, error);
|
||||||
G_CALLBACK(fu_config_monitor_changed_cb),
|
if (monitor == NULL)
|
||||||
self);
|
return FALSE;
|
||||||
|
g_signal_connect(G_FILE_MONITOR(monitor),
|
||||||
|
"changed",
|
||||||
|
G_CALLBACK(fu_config_monitor_changed_cb),
|
||||||
|
self);
|
||||||
|
g_ptr_array_add(self->monitors, g_steal_pointer(&monitor));
|
||||||
|
}
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -391,11 +426,13 @@ fu_config_class_init(FuConfigClass *klass)
|
|||||||
static void
|
static void
|
||||||
fu_config_init(FuConfig *self)
|
fu_config_init(FuConfig *self)
|
||||||
{
|
{
|
||||||
|
self->filenames = g_ptr_array_new_with_free_func(g_free);
|
||||||
self->disabled_devices = g_ptr_array_new_with_free_func(g_free);
|
self->disabled_devices = g_ptr_array_new_with_free_func(g_free);
|
||||||
self->disabled_plugins = g_ptr_array_new_with_free_func(g_free);
|
self->disabled_plugins = g_ptr_array_new_with_free_func(g_free);
|
||||||
self->approved_firmware = g_ptr_array_new_with_free_func(g_free);
|
self->approved_firmware = g_ptr_array_new_with_free_func(g_free);
|
||||||
self->blocked_firmware = g_ptr_array_new_with_free_func(g_free);
|
self->blocked_firmware = g_ptr_array_new_with_free_func(g_free);
|
||||||
self->uri_schemes = g_ptr_array_new_with_free_func(g_free);
|
self->uri_schemes = g_ptr_array_new_with_free_func(g_free);
|
||||||
|
self->monitors = g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -403,16 +440,17 @@ fu_config_finalize(GObject *obj)
|
|||||||
{
|
{
|
||||||
FuConfig *self = FU_CONFIG(obj);
|
FuConfig *self = FU_CONFIG(obj);
|
||||||
|
|
||||||
if (self->monitor != NULL) {
|
for (guint i = 0; i < self->monitors->len; i++) {
|
||||||
g_file_monitor_cancel(self->monitor);
|
GFileMonitor *monitor = g_ptr_array_index(self->monitors, i);
|
||||||
g_object_unref(self->monitor);
|
g_file_monitor_cancel(monitor);
|
||||||
}
|
}
|
||||||
|
g_ptr_array_unref(self->filenames);
|
||||||
|
g_ptr_array_unref(self->monitors);
|
||||||
g_ptr_array_unref(self->disabled_devices);
|
g_ptr_array_unref(self->disabled_devices);
|
||||||
g_ptr_array_unref(self->disabled_plugins);
|
g_ptr_array_unref(self->disabled_plugins);
|
||||||
g_ptr_array_unref(self->approved_firmware);
|
g_ptr_array_unref(self->approved_firmware);
|
||||||
g_ptr_array_unref(self->blocked_firmware);
|
g_ptr_array_unref(self->blocked_firmware);
|
||||||
g_ptr_array_unref(self->uri_schemes);
|
g_ptr_array_unref(self->uri_schemes);
|
||||||
g_free(self->config_file);
|
|
||||||
g_free(self->host_bkc);
|
g_free(self->host_bkc);
|
||||||
|
|
||||||
G_OBJECT_CLASS(fu_config_parent_class)->finalize(obj);
|
G_OBJECT_CLASS(fu_config_parent_class)->finalize(obj);
|
||||||
|
Loading…
Reference in New Issue
Block a user