tracker-miners/SOURCES/backport-seccomp-improvemen...

3634 lines
129 KiB
Diff

From ec32dc4f0c7bb8f8583b3d5fb844a52d3221f969 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sat, 23 Sep 2023 10:42:37 +0200
Subject: [PATCH 01/22] tracker-extract: Drop SIGINT/SIGTERM handlers
These bring some questions if using seccomp for the full
process (e.g. requiring additional syscalls, or glib spawning
a thread for it), and are not really mandatory since there's
no requirements for a clean exit.
The only thing that is somewhat lost is ease at valgrinding
with noise from things "definitely lost" in the abrupt termination,
but that does already require manually disabling the seccomp
jail, it's not a big stretch to pile up more local hacks, or
ignore the noise.
---
src/tracker-extract/tracker-main.c | 65 ------------------------------
1 file changed, 65 deletions(-)
diff --git a/src/tracker-extract/tracker-main.c b/src/tracker-extract/tracker-main.c
index 1d3e32567..7732f443d 100644
--- a/src/tracker-extract/tracker-main.c
+++ b/src/tracker-extract/tracker-main.c
@@ -138,66 +138,6 @@ initialize_priority_and_scheduling (TrackerSchedIdle sched_idle,
}
}
-static void
-initialize_directories (void)
-{
- gchar *user_data_dir;
-
- /* NOTE: We don't create the database directories here, the
- * tracker-db-manager does that for us.
- */
-
- user_data_dir = g_build_filename (g_get_user_data_dir (),
- "tracker",
- NULL);
-
- /* g_message ("Checking directory exists:'%s'", user_data_dir); */
- g_mkdir_with_parents (user_data_dir, 00755);
-
- g_free (user_data_dir);
-}
-
-static gboolean
-signal_handler (gpointer user_data)
-{
- int signo = GPOINTER_TO_INT (user_data);
-
- static gboolean in_loop = FALSE;
-
- /* Die if we get re-entrant signals handler calls */
- if (in_loop) {
- _exit (EXIT_FAILURE);
- }
-
- switch (signo) {
- case SIGTERM:
- case SIGINT:
- in_loop = TRUE;
- g_main_loop_quit (main_loop);
-
- /* Fall through */
- default:
- if (g_strsignal (signo)) {
- g_print ("\n");
- g_print ("Received signal:%d->'%s'\n",
- signo,
- g_strsignal (signo));
- }
- break;
- }
-
- return G_SOURCE_CONTINUE;
-}
-
-static void
-initialize_signal_handler (void)
-{
-#ifndef G_OS_WIN32
- g_unix_signal_add (SIGTERM, signal_handler, GINT_TO_POINTER (SIGTERM));
- g_unix_signal_add (SIGINT, signal_handler, GINT_TO_POINTER (SIGINT));
-#endif /* G_OS_WIN32 */
-}
-
static void
log_handler (const gchar *domain,
GLogLevelFlags log_level,
@@ -433,9 +373,6 @@ main (int argc, char *argv[])
return run_standalone (config);
}
- /* Initialize subsystems */
- initialize_directories ();
-
/* This makes sure we don't steal all the system's resources */
initialize_priority_and_scheduling (tracker_config_get_sched_idle (config), TRUE);
@@ -509,8 +446,6 @@ main (int argc, char *argv[])
G_CALLBACK (on_decorator_items_available),
main_loop);
- initialize_signal_handler ();
-
g_main_loop_run (main_loop);
my_main_loop = main_loop;
--
2.43.0
From 8e826fd2952c40b4fc991aaef86d614bb3dd5a99 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sun, 24 Sep 2023 15:53:22 +0200
Subject: [PATCH 02/22] tracker-extract: Drop handling of wait-for-miner-fs
Even though this setting is off by default, that is the stock
behavior of tracker-miner-fs, by activating the tracker-extract-3
D-Bus name after going idle.
Furthermore, enabling this setting will have clunky interaction
with the current behavior since 3.1.0 that tracker-miner-fs-3
forwards the tracker-extract-3 status (commit bd3ce694d7), since
tracker-extract-3 activity will make the tracker-miner-fs-3 status
"non-idle", which will pause the extractor, which will make the miner
idle, which will unpause the extractor, ...
It's arguable that we should keep supporting this as a setting
altogether, so just drop the tracker-extract-3 side code handling
this setting.
---
.../tracker-extract-controller.c | 168 ------------------
1 file changed, 168 deletions(-)
diff --git a/src/tracker-extract/tracker-extract-controller.c b/src/tracker-extract/tracker-extract-controller.c
index 9c03112bb..3a34a8dbf 100644
--- a/src/tracker-extract/tracker-extract-controller.c
+++ b/src/tracker-extract/tracker-extract-controller.c
@@ -30,185 +30,19 @@ enum {
struct TrackerExtractControllerPrivate {
TrackerDecorator *decorator;
- TrackerConfig *config;
GCancellable *cancellable;
GDBusConnection *connection;
- guint watch_id;
- guint progress_signal_id;
gint paused;
};
G_DEFINE_TYPE (TrackerExtractController, tracker_extract_controller, G_TYPE_OBJECT)
-static void
-files_miner_idleness_changed (TrackerExtractController *self,
- gboolean idle)
-{
- if (idle && self->priv->paused) {
- tracker_miner_resume (TRACKER_MINER (self->priv->decorator));
- self->priv->paused = FALSE;
- } else if (!idle && !self->priv->paused) {
- self->priv->paused = FALSE;
- tracker_miner_pause (TRACKER_MINER (self->priv->decorator));
- }
-}
-
-static void
-files_miner_status_changed (TrackerExtractController *self,
- const gchar *status)
-{
- files_miner_idleness_changed (self, g_str_equal (status, "Idle"));
-}
-
-static void
-files_miner_get_status_cb (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- TrackerExtractController *self = user_data;
- GDBusConnection *conn = (GDBusConnection *) source;
- GVariant *reply;
- const gchar *status;
- GError *error = NULL;
-
- reply = g_dbus_connection_call_finish (conn, result, &error);
- if (!reply) {
- g_debug ("Failed to get tracker-miner-fs status: %s",
- error->message);
- g_clear_error (&error);
- } else {
- g_variant_get (reply, "(&s)", &status);
- files_miner_status_changed (self, status);
- g_variant_unref (reply);
- }
-
- g_clear_object (&self->priv->cancellable);
- g_object_unref (self);
-}
-
-static void
-appeared_cb (GDBusConnection *connection,
- const gchar *name,
- const gchar *name_owner,
- gpointer user_data)
-{
- TrackerExtractController *self = user_data;
-
- /* Get initial status */
- self->priv->cancellable = g_cancellable_new ();
- g_dbus_connection_call (connection,
- "org.freedesktop.Tracker1.Miner.Files",
- "/org/freedesktop/Tracker1/Miner/Files",
- "org.freedesktop.Tracker1.Miner",
- "GetStatus",
- NULL,
- G_VARIANT_TYPE ("(s)"),
- G_DBUS_CALL_FLAGS_NO_AUTO_START,
- -1,
- self->priv->cancellable,
- files_miner_get_status_cb,
- g_object_ref (self));
-}
-
-static void
-vanished_cb (GDBusConnection *connection,
- const gchar *name,
- gpointer user_data)
-{
- TrackerExtractController *self = user_data;
-
- /* tracker-miner-fs vanished, we don't have anything to wait for
- * anymore. */
- files_miner_idleness_changed (self, TRUE);
-}
-
-static void
-files_miner_progress_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- gpointer user_data)
-{
- TrackerExtractController *self = user_data;
- const gchar *status;
-
- g_return_if_fail (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sdi)")));
-
- /* If we didn't get the initial status yet, ignore Progress signals */
- if (self->priv->cancellable)
- return;
-
- g_variant_get (parameters, "(&sdi)", &status, NULL, NULL);
- files_miner_status_changed (self, status);
-}
-
-static void
-disconnect_all (TrackerExtractController *self)
-{
- GDBusConnection *conn = self->priv->connection;
-
- if (self->priv->watch_id != 0)
- g_bus_unwatch_name (self->priv->watch_id);
- self->priv->watch_id = 0;
-
- if (self->priv->progress_signal_id != 0)
- g_dbus_connection_signal_unsubscribe (conn,
- self->priv->progress_signal_id);
- self->priv->progress_signal_id = 0;
-
- if (self->priv->cancellable)
- g_cancellable_cancel (self->priv->cancellable);
- g_clear_object (&self->priv->cancellable);
-}
-
-static void
-update_wait_for_miner_fs (TrackerExtractController *self)
-{
- GDBusConnection *conn = self->priv->connection;
-
- if (tracker_config_get_wait_for_miner_fs (self->priv->config)) {
- self->priv->progress_signal_id =
- g_dbus_connection_signal_subscribe (conn,
- "org.freedesktop.Tracker1.Miner.Files",
- "org.freedesktop.Tracker1.Miner",
- "Progress",
- "/org/freedesktop/Tracker1/Miner/Files",
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- files_miner_progress_cb,
- self, NULL);
-
- /* appeared_cb is guaranteed to be called even if the service
- * was already running, so we'll start the miner from there. */
- self->priv->watch_id = g_bus_watch_name_on_connection (conn,
- "org.freedesktop.Tracker1.Miner.Files",
- G_BUS_NAME_WATCHER_FLAGS_NONE,
- appeared_cb,
- vanished_cb,
- self, NULL);
- } else {
- disconnect_all (self);
- files_miner_idleness_changed (self, TRUE);
- }
-}
-
static void
tracker_extract_controller_constructed (GObject *object)
{
TrackerExtractController *self = (TrackerExtractController *) object;
G_OBJECT_CLASS (tracker_extract_controller_parent_class)->constructed (object);
-
- g_assert (self->priv->decorator != NULL);
-
- self->priv->config = g_object_ref (tracker_main_get_config ());
- g_signal_connect_object (self->priv->config,
- "notify::wait-for-miner-fs",
- G_CALLBACK (update_wait_for_miner_fs),
- self, G_CONNECT_SWAPPED);
- update_wait_for_miner_fs (self);
}
static void
@@ -253,9 +87,7 @@ tracker_extract_controller_dispose (GObject *object)
{
TrackerExtractController *self = (TrackerExtractController *) object;
- disconnect_all (self);
g_clear_object (&self->priv->decorator);
- g_clear_object (&self->priv->config);
G_OBJECT_CLASS (tracker_extract_controller_parent_class)->dispose (object);
}
--
2.43.0
From 874665ba0edecd826fd2cedd989edfc3102f5fa5 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sun, 24 Sep 2023 14:20:01 +0200
Subject: [PATCH 03/22] tracker-extract: Handle configuration through D-Bus
Add an interface on tracker-miner-fs-3 so that tracker-extract-3
can get the relevant settings without using DConf/GSettings directly.
This replaces all settings usage from tracker-extract-3.
---
src/libtracker-extract/tracker-extract-info.c | 12 +-
src/libtracker-extract/tracker-extract-info.h | 5 +-
src/miners/fs/Makefile.am | 2 +
src/miners/fs/meson.build | 1 +
src/miners/fs/tracker-files-interface.c | 184 ++++++++++
src/miners/fs/tracker-files-interface.h | 35 ++
src/miners/fs/tracker-main.c | 6 +
src/tracker-extract/Makefile.am | 2 -
src/tracker-extract/meson.build | 1 -
src/tracker-extract/tracker-config.c | 328 ------------------
src/tracker-extract/tracker-config.h | 61 ----
.../tracker-extract-controller.c | 61 ++++
src/tracker-extract/tracker-extract-epub.c | 21 +-
src/tracker-extract/tracker-extract-html.c | 4 +-
.../tracker-extract-msoffice-xml.c | 6 +-
.../tracker-extract-msoffice.c | 4 +-
src/tracker-extract/tracker-extract-oasis.c | 6 +-
src/tracker-extract/tracker-extract-pdf.c | 4 +-
src/tracker-extract/tracker-extract-text.c | 5 +-
src/tracker-extract/tracker-extract.c | 19 +-
src/tracker-extract/tracker-extract.h | 3 +
src/tracker-extract/tracker-main.c | 45 +--
src/tracker-extract/tracker-main.h | 5 -
.../tracker-extract-info-test.c | 4 +-
24 files changed, 348 insertions(+), 476 deletions(-)
create mode 100644 src/miners/fs/tracker-files-interface.c
create mode 100644 src/miners/fs/tracker-files-interface.h
delete mode 100644 src/tracker-extract/tracker-config.c
delete mode 100644 src/tracker-extract/tracker-config.h
diff --git a/src/libtracker-extract/tracker-extract-info.c b/src/libtracker-extract/tracker-extract-info.c
index 8e445ecad..b69630b83 100644
--- a/src/libtracker-extract/tracker-extract-info.c
+++ b/src/libtracker-extract/tracker-extract-info.c
@@ -44,6 +44,8 @@ struct _TrackerExtractInfo
GFile *file;
gchar *mimetype;
+ gint max_text;
+
gint ref_count;
};
@@ -64,7 +66,8 @@ G_DEFINE_BOXED_TYPE (TrackerExtractInfo, tracker_extract_info,
**/
TrackerExtractInfo *
tracker_extract_info_new (GFile *file,
- const gchar *mimetype)
+ const gchar *mimetype,
+ gint max_text)
{
TrackerExtractInfo *info;
@@ -73,6 +76,7 @@ tracker_extract_info_new (GFile *file,
info = g_slice_new0 (TrackerExtractInfo);
info->file = g_object_ref (file);
info->mimetype = g_strdup (mimetype);
+ info->max_text = max_text;
info->resource = NULL;
@@ -220,3 +224,9 @@ tracker_extract_info_set_resource (TrackerExtractInfo *info,
g_object_ref (resource);
info->resource = resource;
}
+
+gint
+tracker_extract_info_get_max_text (TrackerExtractInfo *info)
+{
+ return info->max_text;
+}
diff --git a/src/libtracker-extract/tracker-extract-info.h b/src/libtracker-extract/tracker-extract-info.h
index 537efb3b4..fd3c27d95 100644
--- a/src/libtracker-extract/tracker-extract-info.h
+++ b/src/libtracker-extract/tracker-extract-info.h
@@ -36,12 +36,15 @@ typedef struct _TrackerExtractInfo TrackerExtractInfo;
GType tracker_extract_info_get_type (void) G_GNUC_CONST;
TrackerExtractInfo * tracker_extract_info_new (GFile *file,
- const gchar *mimetype);
+ const gchar *mimetype,
+ gint max_text);
TrackerExtractInfo * tracker_extract_info_ref (TrackerExtractInfo *info);
void tracker_extract_info_unref (TrackerExtractInfo *info);
GFile * tracker_extract_info_get_file (TrackerExtractInfo *info);
const gchar * tracker_extract_info_get_mimetype (TrackerExtractInfo *info);
+gint tracker_extract_info_get_max_text (TrackerExtractInfo *info);
+
TrackerResource * tracker_extract_info_get_resource (TrackerExtractInfo *info);
void tracker_extract_info_set_resource (TrackerExtractInfo *info,
TrackerResource *resource);
diff --git a/src/miners/fs/Makefile.am b/src/miners/fs/Makefile.am
index c8af61099..cb812e0b5 100644
--- a/src/miners/fs/Makefile.am
+++ b/src/miners/fs/Makefile.am
@@ -33,6 +33,8 @@ tracker_miner_fs_SOURCES = \
tracker-config.h \
tracker-extract-watchdog.c \
tracker-extract-watchdog.h \
+ tracker-files-interface.c \
+ tracker-files-interface.h \
tracker-main.c \
tracker-miner-files.c \
tracker-miner-files.h \
diff --git a/src/miners/fs/meson.build b/src/miners/fs/meson.build
index 288610b97..c26c0240e 100644
--- a/src/miners/fs/meson.build
+++ b/src/miners/fs/meson.build
@@ -1,6 +1,7 @@
sources = [
'tracker-config.c',
'tracker-extract-watchdog.c',
+ 'tracker-files-interface.c',
'tracker-main.c',
'tracker-miner-files.c',
'tracker-miner-files-index.c',
diff --git a/src/miners/fs/tracker-files-interface.c b/src/miners/fs/tracker-files-interface.c
new file mode 100644
index 000000000..0e259a6ce
--- /dev/null
+++ b/src/miners/fs/tracker-files-interface.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2023 Red Hat Inc.
+
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Carlos Garnacho <carlosg@gnome.org>
+ */
+
+#include "config.h"
+
+#include "tracker-files-interface.h"
+
+struct _TrackerFilesInterface
+{
+ GObject parent_instance;
+ GDBusConnection *connection;
+ GSettings *settings;
+ guint object_id;
+};
+
+enum {
+ PROP_0,
+ PROP_CONNECTION,
+ N_PROPS,
+};
+
+static GParamSpec *props[N_PROPS] = { 0, };
+
+static const gchar *introspection_xml =
+ "<node>"
+ " <interface name='org.freedesktop.Tracker3.Files'>"
+ " <property name='ExtractorConfig' type='a{sv}' access='read' />"
+ " </interface>"
+ "</node>";
+
+G_DEFINE_TYPE (TrackerFilesInterface, tracker_files_interface, G_TYPE_OBJECT)
+
+static void
+tracker_files_interface_init (TrackerFilesInterface *files_interface)
+{
+}
+
+static GVariant *
+handle_get_property (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *property_name,
+ GError **error,
+ gpointer user_data)
+{
+ TrackerFilesInterface *files_interface = user_data;
+
+ if (g_strcmp0 (object_path, "/org/freedesktop/Tracker3/Files") != 0 ||
+ g_strcmp0 (interface_name, "org.freedesktop.Tracker3.Files") != 0) {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
+ "Wrong object/interface");
+ return NULL;
+ }
+
+ if (g_strcmp0 (property_name, "ExtractorConfig") == 0) {
+ GVariantBuilder builder;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+ g_variant_builder_add (&builder, "{sv}", "max-bytes",
+ g_settings_get_value (files_interface->settings, "max-bytes"));
+
+ return g_variant_builder_end (&builder);
+ } else {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
+ "Unknown property");
+ return NULL;
+ }
+}
+
+static void
+tracker_files_interface_constructed (GObject *object)
+{
+ TrackerFilesInterface *files_interface = TRACKER_FILES_INTERFACE (object);
+ GDBusInterfaceVTable vtable = { NULL, handle_get_property, NULL };
+ g_autoptr (GDBusNodeInfo) introspection_data = NULL;
+
+ G_OBJECT_CLASS (tracker_files_interface_parent_class)->constructed (object);
+
+ introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+ files_interface->object_id =
+ g_dbus_connection_register_object (files_interface->connection,
+ "/org/freedesktop/Tracker3/Files",
+ introspection_data->interfaces[0],
+ &vtable, object, NULL, NULL);
+
+ files_interface->settings = g_settings_new ("org.freedesktop.Tracker.Extract");
+}
+
+static void
+tracker_files_interface_finalize (GObject *object)
+{
+ TrackerFilesInterface *files_interface = TRACKER_FILES_INTERFACE (object);
+
+ g_dbus_connection_unregister_object (files_interface->connection,
+ files_interface->object_id);
+ g_clear_object (&files_interface->connection);
+ g_clear_object (&files_interface->settings);
+
+ G_OBJECT_CLASS (tracker_files_interface_parent_class)->finalize (object);
+}
+
+static void
+tracker_files_interface_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TrackerFilesInterface *files_interface = TRACKER_FILES_INTERFACE (object);
+
+ switch (prop_id) {
+ case PROP_CONNECTION:
+ files_interface->connection = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+tracker_files_interface_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TrackerFilesInterface *files_interface = TRACKER_FILES_INTERFACE (object);
+
+ switch (prop_id) {
+ case PROP_CONNECTION:
+ g_value_set_object (value, files_interface->connection);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+tracker_files_interface_class_init (TrackerFilesInterfaceClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructed = tracker_files_interface_constructed;
+ object_class->finalize = tracker_files_interface_finalize;
+ object_class->set_property = tracker_files_interface_set_property;
+ object_class->get_property = tracker_files_interface_get_property;
+
+ props[PROP_CONNECTION] =
+ g_param_spec_object ("connection",
+ NULL, NULL,
+ G_TYPE_DBUS_CONNECTION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, N_PROPS, props);
+}
+
+TrackerFilesInterface *
+tracker_files_interface_new (GDBusConnection *connection)
+{
+ return g_object_new (TRACKER_TYPE_FILES_INTERFACE,
+ "connection", connection,
+ NULL);
+}
diff --git a/src/miners/fs/tracker-files-interface.h b/src/miners/fs/tracker-files-interface.h
new file mode 100644
index 000000000..e040e41d0
--- /dev/null
+++ b/src/miners/fs/tracker-files-interface.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 Red Hat Inc.
+
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Carlos Garnacho <carlosg@gnome.org>
+ */
+
+#ifndef __TRACKER_FILES_INTERFACE_H__
+#define __TRACKER_FILES_INTERFACE_H__
+
+#include <gio/gio.h>
+
+#define TRACKER_TYPE_FILES_INTERFACE (tracker_files_interface_get_type ())
+G_DECLARE_FINAL_TYPE (TrackerFilesInterface,
+ tracker_files_interface,
+ TRACKER, FILES_INTERFACE,
+ GObject)
+
+TrackerFilesInterface * tracker_files_interface_new (GDBusConnection *connection);
+
+#endif /* __TRACKER_FILES_INTERFACE_H__ */
diff --git a/src/miners/fs/tracker-main.c b/src/miners/fs/tracker-main.c
index 09a838942..e7e809560 100644
--- a/src/miners/fs/tracker-main.c
+++ b/src/miners/fs/tracker-main.c
@@ -39,6 +39,7 @@
#include "tracker-miner-files.h"
#include "tracker-miner-files-index.h"
#include "tracker-writeback.h"
+#include "tracker-files-interface.h"
#define ABOUT \
"Tracker " PACKAGE_VERSION "\n"
@@ -668,6 +669,7 @@ main (gint argc, gchar *argv[])
GDBusConnection *connection;
TrackerDomainOntology *domain_ontology;
gchar *domain_name, *dbus_name;
+ TrackerFilesInterface *files_interface;
main_loop = NULL;
@@ -723,6 +725,8 @@ main (gint argc, gchar *argv[])
return EXIT_FAILURE;
}
+ files_interface = tracker_files_interface_new (connection);
+
/* Initialize logging */
config = tracker_config_new ();
@@ -871,6 +875,8 @@ main (gint argc, gchar *argv[])
tracker_miner_files_set_need_mtime_check (FALSE);
}
+ g_object_unref (files_interface);
+
g_main_loop_unref (main_loop);
g_object_unref (config);
g_object_unref (miner_files_index);
diff --git a/src/tracker-extract/Makefile.am b/src/tracker-extract/Makefile.am
index 05bb532a2..5b5b0227d 100644
--- a/src/tracker-extract/Makefile.am
+++ b/src/tracker-extract/Makefile.am
@@ -533,8 +533,6 @@ libextract_dummy_la_LIBADD = \
libexec_PROGRAMS = tracker-extract
tracker_extract_SOURCES = \
- tracker-config.c \
- tracker-config.h \
tracker-extract.c \
tracker-extract.h \
tracker-extract-controller.c \
diff --git a/src/tracker-extract/meson.build b/src/tracker-extract/meson.build
index 9834dc422..7f0ccb699 100644
--- a/src/tracker-extract/meson.build
+++ b/src/tracker-extract/meson.build
@@ -146,7 +146,6 @@ tracker_extract_priority_dbus = gnome.gdbus_codegen(
namespace: 'TrackerExtractDBus')
tracker_extract_sources = [
- 'tracker-config.c',
'tracker-extract.c',
'tracker-extract-controller.c',
'tracker-extract-decorator.c',
diff --git a/src/tracker-extract/tracker-config.c b/src/tracker-extract/tracker-config.c
deleted file mode 100644
index 20f6383f8..000000000
--- a/src/tracker-extract/tracker-config.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (C) 2009, Nokia <ivan.frade@nokia.com>
- * Copyright (C) 2014, Lanedo <martyn@lanedo.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#define G_SETTINGS_ENABLE_BACKEND
-#include <gio/gsettingsbackend.h>
-
-#include <libtracker-miners-common/tracker-common.h>
-
-#include "tracker-config.h"
-
-#define CONFIG_SCHEMA "org.freedesktop.Tracker.Extract"
-#define CONFIG_PATH "/org/freedesktop/tracker/extract/"
-
-static void config_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec);
-static void config_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec);
-static void config_finalize (GObject *object);
-static void config_constructed (GObject *object);
-
-enum {
- PROP_0,
- PROP_VERBOSITY,
- PROP_SCHED_IDLE,
- PROP_MAX_BYTES,
- PROP_MAX_MEDIA_ART_WIDTH,
- PROP_WAIT_FOR_MINER_FS,
-};
-
-G_DEFINE_TYPE (TrackerConfig, tracker_config, G_TYPE_SETTINGS);
-
-static void
-tracker_config_class_init (TrackerConfigClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->set_property = config_set_property;
- object_class->get_property = config_get_property;
- object_class->finalize = config_finalize;
- object_class->constructed = config_constructed;
-
- /* General */
- g_object_class_install_property (object_class,
- PROP_VERBOSITY,
- g_param_spec_enum ("verbosity",
- "Log verbosity",
- "Log verbosity (0=errors, 1=minimal, 2=detailed, 3=debug)",
- TRACKER_TYPE_VERBOSITY,
- TRACKER_VERBOSITY_ERRORS,
- G_PARAM_READWRITE));
- g_object_class_install_property (object_class,
- PROP_SCHED_IDLE,
- g_param_spec_enum ("sched-idle",
- "Scheduler priority when idle",
- "Scheduler priority when idle (0=always, 1=first-index, 2=never)",
- TRACKER_TYPE_SCHED_IDLE,
- TRACKER_SCHED_IDLE_FIRST_INDEX,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_MAX_BYTES,
- g_param_spec_int ("max-bytes",
- "Max Bytes",
- "Maximum number of UTF-8 bytes to extract per file [0->10485760]",
- 0, 1024 * 1024 * 10,
- 1024 * 1024,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_MAX_MEDIA_ART_WIDTH,
- g_param_spec_int ("max-media-art-width",
- "Max Media Art Width",
- " Maximum width of the Media Art to be generated (-1=disable, 0=original width, 1->2048=max pixel width)",
- -1,
- 2048,
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_WAIT_FOR_MINER_FS,
- g_param_spec_boolean ("wait-for-miner-fs",
- "Wait for FS miner to be done before extracting",
- "%TRUE to wait for tracker-miner-fs is done before extracting. %FAlSE otherwise",
- FALSE,
- G_PARAM_READWRITE));
-}
-
-static void
-tracker_config_init (TrackerConfig *object)
-{
-}
-
-static void
-config_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- TrackerConfig *config = TRACKER_CONFIG (object);
-
- switch (param_id) {
- /* General */
- /* NOTE: We handle these because we have to be able
- * to save these based on command line overrides.
- */
- case PROP_VERBOSITY:
- tracker_config_set_verbosity (config, g_value_get_enum (value));
- break;
-
- /* We don't care about the others... we don't save anyway. */
- case PROP_SCHED_IDLE:
- case PROP_MAX_BYTES:
- case PROP_MAX_MEDIA_ART_WIDTH:
- case PROP_WAIT_FOR_MINER_FS:
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- };
-}
-
-static void
-config_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec)
-{
- TrackerConfig *config = TRACKER_CONFIG (object);
-
- switch (param_id) {
- case PROP_VERBOSITY:
- g_value_set_enum (value,
- tracker_config_get_verbosity (config));
- break;
-
- case PROP_SCHED_IDLE:
- g_value_set_enum (value,
- tracker_config_get_sched_idle (config));
- break;
-
- case PROP_MAX_BYTES:
- g_value_set_int (value,
- tracker_config_get_max_bytes (config));
- break;
-
- case PROP_MAX_MEDIA_ART_WIDTH:
- g_value_set_int (value,
- tracker_config_get_max_media_art_width (config));
- break;
-
- case PROP_WAIT_FOR_MINER_FS:
- g_value_set_boolean (value,
- tracker_config_get_wait_for_miner_fs (config));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- };
-}
-
-static void
-config_finalize (GObject *object)
-{
- /* For now we do nothing here, we left this override in for
- * future expansion.
- */
-
- (G_OBJECT_CLASS (tracker_config_parent_class)->finalize) (object);
-}
-
-static void
-config_constructed (GObject *object)
-{
- GSettings *settings;
-
- (G_OBJECT_CLASS (tracker_config_parent_class)->constructed) (object);
-
- settings = G_SETTINGS (object);
-
- if (G_LIKELY (!g_getenv ("TRACKER_USE_CONFIG_FILES"))) {
- g_settings_delay (settings);
- }
-
- /* Set up bindings:
- *
- * What's interesting here is that 'verbosity' and
- * 'initial-sleep' are command line arguments that can be
- * overridden, so we don't update the config when we set them
- * from main() because it's a session configuration only, not
- * a permanent one. To do this we use the flag
- * G_SETTINGS_BIND_GET_NO_CHANGES.
- *
- * For the other settings, we don't bind the
- * G_SETTINGS_BIND_SET because we don't want to save anything,
- * ever, we only want to know about updates to the settings as
- * they're changed externally. The only time this may be
- * different is where we use the environment variable
- * TRACKER_USE_CONFIG_FILES and we want to write a config
- * file for convenience. But this is only necessary if the
- * config is different to the default.
- */
- g_settings_bind (settings, "verbosity", object, "verbosity", G_SETTINGS_BIND_GET | G_SETTINGS_BIND_GET_NO_CHANGES);
- g_settings_bind (settings, "sched-idle", object, "sched-idle", G_SETTINGS_BIND_GET);
- g_settings_bind (settings, "max-media-art-width", object, "max-media-art-width", G_SETTINGS_BIND_GET);
- g_settings_bind (settings, "wait-for-miner-fs", object, "wait-for-miner-fs", G_SETTINGS_BIND_GET);
-
- /* Cache settings accessed from extractor modules, we don't want
- * the GSettings object accessed within these as it may trigger
- * unintended open() calls.
- */
- TRACKER_CONFIG (settings)->max_bytes = g_settings_get_int (settings, "max-bytes");
-}
-
-TrackerConfig *
-tracker_config_new (void)
-{
- TrackerConfig *config = NULL;
-
- /* FIXME: should we unset GSETTINGS_BACKEND env var? */
-
- if (G_UNLIKELY (g_getenv ("TRACKER_USE_CONFIG_FILES"))) {
- GSettingsBackend *backend;
- gchar *filename, *basename;
- gboolean need_to_save;
-
- basename = g_strdup_printf ("%s.cfg", g_get_prgname ());
- filename = g_build_filename (g_get_user_config_dir (), "tracker", basename, NULL);
- g_free (basename);
-
- need_to_save = g_file_test (filename, G_FILE_TEST_EXISTS) == FALSE;
-
- backend = g_keyfile_settings_backend_new (filename, CONFIG_PATH, "General");
- g_info ("Using config file '%s'", filename);
- g_free (filename);
-
- config = g_object_new (TRACKER_TYPE_CONFIG,
- "backend", backend,
- "schema-id", CONFIG_SCHEMA,
- "path", CONFIG_PATH,
- NULL);
- g_object_unref (backend);
-
- if (need_to_save) {
- g_info (" Config file does not exist, using default values...");
- }
- } else {
- config = g_object_new (TRACKER_TYPE_CONFIG,
- "schema-id", CONFIG_SCHEMA,
- "path", CONFIG_PATH,
- NULL);
- }
-
- return config;
-}
-
-gint
-tracker_config_get_verbosity (TrackerConfig *config)
-{
- g_return_val_if_fail (TRACKER_IS_CONFIG (config), TRACKER_VERBOSITY_ERRORS);
-
- return g_settings_get_enum (G_SETTINGS (config), "verbosity");
-}
-
-void
-tracker_config_set_verbosity (TrackerConfig *config,
- gint value)
-{
- g_return_if_fail (TRACKER_IS_CONFIG (config));
-
- g_settings_set_enum (G_SETTINGS (config), "verbosity", value);
-}
-
-gint
-tracker_config_get_sched_idle (TrackerConfig *config)
-{
- g_return_val_if_fail (TRACKER_IS_CONFIG (config), TRACKER_SCHED_IDLE_FIRST_INDEX);
-
- return g_settings_get_enum (G_SETTINGS (config), "sched-idle");
-}
-
-gint
-tracker_config_get_max_bytes (TrackerConfig *config)
-{
- g_return_val_if_fail (TRACKER_IS_CONFIG (config), 0);
-
- return config->max_bytes;
-}
-
-gint
-tracker_config_get_max_media_art_width (TrackerConfig *config)
-{
- g_return_val_if_fail (TRACKER_IS_CONFIG (config), 0);
-
- return g_settings_get_int (G_SETTINGS (config), "max-media-art-width");
-}
-
-gboolean
-tracker_config_get_wait_for_miner_fs (TrackerConfig *config)
-{
- g_return_val_if_fail (TRACKER_IS_CONFIG (config), FALSE);
-
- return g_settings_get_boolean (G_SETTINGS (config), "wait-for-miner-fs");
-}
diff --git a/src/tracker-extract/tracker-config.h b/src/tracker-extract/tracker-config.h
deleted file mode 100644
index c8af8ef57..000000000
--- a/src/tracker-extract/tracker-config.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2009, Nokia <ivan.frade@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __TRACKER_EXTRACT_CONFIG_H__
-#define __TRACKER_EXTRACT_CONFIG_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define TRACKER_TYPE_CONFIG (tracker_config_get_type ())
-#define TRACKER_CONFIG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_CONFIG, TrackerConfig))
-#define TRACKER_CONFIG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), TRACKER_TYPE_CONFIG, TrackerConfigClass))
-#define TRACKER_IS_CONFIG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_CONFIG))
-#define TRACKER_IS_CONFIG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TRACKER_TYPE_CONFIG))
-#define TRACKER_CONFIG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_CONFIG, TrackerConfigClass))
-
-typedef struct TrackerConfig TrackerConfig;
-typedef struct TrackerConfigClass TrackerConfigClass;
-
-struct TrackerConfig {
- GSettings parent;
- gint max_bytes;
-};
-
-struct TrackerConfigClass {
- GSettingsClass parent_class;
-};
-
-GType tracker_config_get_type (void) G_GNUC_CONST;
-
-TrackerConfig *tracker_config_new (void);
-gint tracker_config_get_verbosity (TrackerConfig *config);
-gint tracker_config_get_sched_idle (TrackerConfig *config);
-gint tracker_config_get_max_bytes (TrackerConfig *config);
-gint tracker_config_get_max_media_art_width (TrackerConfig *config);
-gboolean tracker_config_get_wait_for_miner_fs (TrackerConfig *config);
-
-void tracker_config_set_verbosity (TrackerConfig *config,
- gint value);
-
-G_END_DECLS
-
-#endif /* __TRACKER_EXTRACT_CONFIG_H__ */
-
diff --git a/src/tracker-extract/tracker-extract-controller.c b/src/tracker-extract/tracker-extract-controller.c
index 3a34a8dbf..01a2ae4f7 100644
--- a/src/tracker-extract/tracker-extract-controller.c
+++ b/src/tracker-extract/tracker-extract-controller.c
@@ -32,17 +32,78 @@ struct TrackerExtractControllerPrivate {
TrackerDecorator *decorator;
GCancellable *cancellable;
GDBusConnection *connection;
+ GDBusProxy *miner_proxy;
gint paused;
};
G_DEFINE_TYPE (TrackerExtractController, tracker_extract_controller, G_TYPE_OBJECT)
+static void
+update_extract_config (TrackerExtractController *controller,
+ GDBusProxy *proxy)
+{
+ TrackerExtractControllerPrivate *priv;
+ GVariantIter iter;
+ g_autoptr (GVariant) v = NULL;
+ GVariant *value;
+ gchar *key;
+
+ priv = tracker_extract_controller_get_instance_private (controller);
+
+ v = g_dbus_proxy_get_cached_property (proxy, "ExtractorConfig");
+ if (!v)
+ return;
+
+ g_variant_iter_init (&iter, v);
+
+ while (g_variant_iter_next (&iter, "{sv}", &key, &value)) {
+ if (g_strcmp0 (key, "max-bytes") == 0 &&
+ g_variant_is_of_type (value, G_VARIANT_TYPE_INT32)) {
+ TrackerExtract *extract = NULL;
+ gint max_bytes;
+
+ max_bytes = g_variant_get_int32 (value);
+ g_object_get (priv->decorator, "extractor", &extract, NULL);
+
+ if (extract) {
+ tracker_extract_set_max_text (extract, max_bytes);
+ g_object_unref (extract);
+ }
+ }
+
+ g_free (key);
+ g_variant_unref (value);
+ }
+}
+
+static void
+miner_properties_changed_cb (GDBusProxy *proxy,
+ GVariant *changed_properties,
+ GStrv invalidated_properties,
+ gpointer user_data)
+{
+ update_extract_config (user_data, proxy);
+}
+
static void
tracker_extract_controller_constructed (GObject *object)
{
TrackerExtractController *self = (TrackerExtractController *) object;
G_OBJECT_CLASS (tracker_extract_controller_parent_class)->constructed (object);
+
+ self->priv->miner_proxy = g_dbus_proxy_new_sync (self->priv->connection,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ NULL,
+ "org.freedesktop.Tracker3.Miner.Files",
+ "/org/freedesktop/Tracker3/Files",
+ "org.freedesktop.Tracker3.Files",
+ NULL, NULL);
+ if (self->priv->miner_proxy) {
+ g_signal_connect (self->priv->miner_proxy, "g-properties-changed",
+ G_CALLBACK (miner_properties_changed_cb), self);
+ update_extract_config (self, self->priv->miner_proxy);
+ }
}
static void
diff --git a/src/tracker-extract/tracker-extract-epub.c b/src/tracker-extract/tracker-extract-epub.c
index 2e65e10bd..8bd945738 100644
--- a/src/tracker-extract/tracker-extract-epub.c
+++ b/src/tracker-extract/tracker-extract-epub.c
@@ -561,12 +561,12 @@ extract_opf_path (const gchar *uri)
}
static gchar *
-extract_opf_contents (const gchar *uri,
- const gchar *content_prefix,
- GList *content_files)
+extract_opf_contents (TrackerExtractInfo *info,
+ const gchar *uri,
+ const gchar *content_prefix,
+ GList *content_files)
{
OPFContentData content_data = { 0 };
- TrackerConfig *config;
GError *error = NULL;
GList *l;
GMarkupParser xml_parser = {
@@ -575,10 +575,8 @@ extract_opf_contents (const gchar *uri,
NULL, NULL
};
- config = tracker_main_get_config ();
-
content_data.contents = g_string_new ("");
- content_data.limit = (gsize) tracker_config_get_max_bytes (config);
+ content_data.limit = (gsize) tracker_extract_info_get_max_text (info);
g_debug ("Extracting up to %" G_GSIZE_FORMAT " bytes of content", content_data.limit);
@@ -611,8 +609,9 @@ extract_opf_contents (const gchar *uri,
}
static TrackerResource *
-extract_opf (const gchar *uri,
- const gchar *opf_path)
+extract_opf (TrackerExtractInfo *info,
+ const gchar *uri,
+ const gchar *opf_path)
{
TrackerResource *ebook;
GMarkupParseContext *context;
@@ -652,7 +651,7 @@ extract_opf (const gchar *uri,
}
dirname = g_path_get_dirname (opf_path);
- contents = extract_opf_contents (uri, dirname, data->pages);
+ contents = extract_opf_contents (info, uri, dirname, data->pages);
g_free (dirname);
if (contents && *contents) {
@@ -682,7 +681,7 @@ tracker_extract_get_metadata (TrackerExtractInfo *info)
return FALSE;
}
- ebook = extract_opf (uri, opf_path);
+ ebook = extract_opf (info, uri, opf_path);
g_free (opf_path);
g_free (uri);
diff --git a/src/tracker-extract/tracker-extract-html.c b/src/tracker-extract/tracker-extract-html.c
index 6fb030ff5..8390cef3b 100644
--- a/src/tracker-extract/tracker-extract-html.c
+++ b/src/tracker-extract/tracker-extract-html.c
@@ -233,7 +233,6 @@ tracker_extract_get_metadata (TrackerExtractInfo *info)
{
TrackerResource *metadata;
GFile *file;
- TrackerConfig *config;
htmlDocPtr doc;
parser_data pd;
gchar *filename;
@@ -283,8 +282,7 @@ tracker_extract_get_metadata (TrackerExtractInfo *info)
pd.plain_text = g_string_new (NULL);
pd.title = g_string_new (NULL);
- config = tracker_main_get_config ();
- pd.n_bytes_remaining = tracker_config_get_max_bytes (config);
+ pd.n_bytes_remaining = tracker_extract_info_get_max_text (info);
filename = g_file_get_path (file);
doc = htmlSAXParseFile (filename, NULL, &handler, &pd);
diff --git a/src/tracker-extract/tracker-extract-msoffice-xml.c b/src/tracker-extract/tracker-extract-msoffice-xml.c
index b45667e33..e58ea83e8 100644
--- a/src/tracker-extract/tracker-extract-msoffice-xml.c
+++ b/src/tracker-extract/tracker-extract-msoffice-xml.c
@@ -814,7 +814,6 @@ tracker_extract_get_metadata (TrackerExtractInfo *extract_info)
MsOfficeXMLParserInfo info = { 0 };
MsOfficeXMLFileType file_type;
TrackerResource *metadata;
- TrackerConfig *config;
GMarkupParseContext *context = NULL;
GError *error = NULL;
GFile *file;
@@ -830,9 +829,6 @@ tracker_extract_get_metadata (TrackerExtractInfo *extract_info)
/* Get current Content Type */
file_type = msoffice_xml_get_file_type (uri);
- /* Setup conf */
- config = tracker_main_get_config ();
-
g_debug ("Extracting MsOffice XML format...");
metadata = tracker_resource_new (NULL);
@@ -848,7 +844,7 @@ tracker_extract_get_metadata (TrackerExtractInfo *extract_info)
info.content = NULL;
info.title_already_set = FALSE;
info.generator_already_set = FALSE;
- info.bytes_pending = tracker_config_get_max_bytes (config);
+ info.bytes_pending = tracker_extract_info_get_max_text (extract_info);
/* Create content-type parser context */
context = g_markup_parse_context_new (&content_types_parser,
diff --git a/src/tracker-extract/tracker-extract-msoffice.c b/src/tracker-extract/tracker-extract-msoffice.c
index 289dc9899..5516071dd 100644
--- a/src/tracker-extract/tracker-extract-msoffice.c
+++ b/src/tracker-extract/tracker-extract-msoffice.c
@@ -1623,7 +1623,6 @@ G_MODULE_EXPORT gboolean
tracker_extract_get_metadata (TrackerExtractInfo *info)
{
TrackerResource *metadata;
- TrackerConfig *config;
GsfInfile *infile = NULL;
gchar *content = NULL, *uri;
gboolean is_encrypted = FALSE;
@@ -1670,8 +1669,7 @@ tracker_extract_get_metadata (TrackerExtractInfo *info)
extract_summary (metadata, infile, uri);
/* Set max bytes to read from content */
- config = tracker_main_get_config ();
- max_bytes = tracker_config_get_max_bytes (config);
+ max_bytes = tracker_extract_info_get_max_text (info);
if (g_ascii_strcasecmp (mime_used, "application/msword") == 0) {
/* Word file */
diff --git a/src/tracker-extract/tracker-extract-oasis.c b/src/tracker-extract/tracker-extract-oasis.c
index 1dd977c29..c3187e49f 100644
--- a/src/tracker-extract/tracker-extract-oasis.c
+++ b/src/tracker-extract/tracker-extract-oasis.c
@@ -168,7 +168,6 @@ G_MODULE_EXPORT gboolean
tracker_extract_get_metadata (TrackerExtractInfo *extract_info)
{
TrackerResource *metadata;
- TrackerConfig *config;
ODTMetadataParseInfo info = { 0 };
ODTFileType file_type;
GFile *file;
@@ -193,9 +192,6 @@ tracker_extract_get_metadata (TrackerExtractInfo *extract_info)
file = tracker_extract_info_get_file (extract_info);
uri = g_file_get_uri (file);
- /* Setup conf */
- config = tracker_main_get_config ();
-
g_debug ("Extracting OASIS metadata and contents from '%s'", uri);
/* First, parse metadata */
@@ -230,7 +226,7 @@ tracker_extract_get_metadata (TrackerExtractInfo *extract_info)
/* Extract content with the given limitations */
extract_oasis_content (uri,
- tracker_config_get_max_bytes (config),
+ tracker_extract_info_get_max_text (extract_info),
file_type,
metadata);
diff --git a/src/tracker-extract/tracker-extract-pdf.c b/src/tracker-extract/tracker-extract-pdf.c
index a91fe63e9..e6d6e1ef6 100644
--- a/src/tracker-extract/tracker-extract-pdf.c
+++ b/src/tracker-extract/tracker-extract-pdf.c
@@ -280,7 +280,6 @@ write_pdf_data (PDFData data,
G_MODULE_EXPORT gboolean
tracker_extract_get_metadata (TrackerExtractInfo *info)
{
- TrackerConfig *config;
GTime creation_date;
GError *error = NULL;
TrackerResource *metadata;
@@ -522,8 +521,7 @@ tracker_extract_get_metadata (TrackerExtractInfo *info)
tracker_resource_set_int64 (metadata, "nfo:pageCount", poppler_document_get_n_pages(document));
- config = tracker_main_get_config ();
- n_bytes = tracker_config_get_max_bytes (config);
+ n_bytes = tracker_extract_info_get_max_text (info);
content = extract_content_text (document, n_bytes);
if (content) {
diff --git a/src/tracker-extract/tracker-extract-text.c b/src/tracker-extract/tracker-extract-text.c
index 5f94d7309..4c4a6cca0 100644
--- a/src/tracker-extract/tracker-extract-text.c
+++ b/src/tracker-extract/tracker-extract-text.c
@@ -84,13 +84,10 @@ G_MODULE_EXPORT gboolean
tracker_extract_get_metadata (TrackerExtractInfo *info)
{
TrackerResource *metadata;
- TrackerConfig *config;
gchar *content;
- config = tracker_main_get_config ();
-
content = get_file_content (tracker_extract_info_get_file (info),
- tracker_config_get_max_bytes (config));
+ tracker_extract_info_get_max_text (info));
metadata = tracker_resource_new (NULL);
tracker_resource_add_uri (metadata, "rdf:type", "nfo:PlainTextDocument");
diff --git a/src/tracker-extract/tracker-extract.c b/src/tracker-extract/tracker-extract.c
index ec08d050d..cd0511e8f 100644
--- a/src/tracker-extract/tracker-extract.c
+++ b/src/tracker-extract/tracker-extract.c
@@ -45,6 +45,8 @@
G_DEFINE_QUARK (TrackerExtractError, tracker_extract_error)
+#define DEFAULT_MAX_TEXT 1048576
+
extern gboolean debug;
typedef struct {
@@ -56,6 +58,8 @@ typedef struct {
GHashTable *statistics_data;
GList *running_tasks;
+ gint max_text;
+
/* used to maintain the running tasks
* and stats from different threads
*/
@@ -83,6 +87,7 @@ typedef struct {
GAsyncResult *res;
gchar *file;
gchar *mimetype;
+ gint max_text;
TrackerMimetypeInfo *mimetype_handlers;
@@ -129,6 +134,7 @@ tracker_extract_init (TrackerExtract *object)
priv->statistics_data = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) statistics_data_free);
priv->single_thread_extractors = g_hash_table_new (NULL, NULL);
+ priv->max_text = DEFAULT_MAX_TEXT;
priv->thread_pool = g_thread_pool_new ((GFunc) get_metadata,
NULL, 10, TRUE, NULL);
@@ -277,7 +283,7 @@ get_file_metadata (TrackerExtractTask *task,
*info_out = NULL;
file = g_file_new_for_uri (task->file);
- info = tracker_extract_info_new (file, task->mimetype);
+ info = tracker_extract_info_new (file, task->mimetype, task->max_text);
g_object_unref (file);
if (task->mimetype && *task->mimetype) {
@@ -345,6 +351,7 @@ extract_task_new (TrackerExtract *extract,
GAsyncResult *res,
GError **error)
{
+ TrackerExtractPrivate *priv = TRACKER_EXTRACT_GET_PRIVATE (extract);
TrackerExtractTask *task;
gchar *mimetype_used;
@@ -381,6 +388,7 @@ extract_task_new (TrackerExtract *extract,
task->file = g_strdup (uri);
task->mimetype = mimetype_used;
task->extract = extract;
+ task->max_text = priv->max_text;
if (task->cancellable) {
task->signal_id = g_cancellable_connect (cancellable,
@@ -779,3 +787,12 @@ tracker_extract_file_finish (TrackerExtract *extract,
return g_task_propagate_pointer (G_TASK (res), error);
}
+
+void
+tracker_extract_set_max_text (TrackerExtract *extract,
+ gint max_text)
+{
+ TrackerExtractPrivate *priv = TRACKER_EXTRACT_GET_PRIVATE (extract);
+
+ priv->max_text = max_text;
+}
diff --git a/src/tracker-extract/tracker-extract.h b/src/tracker-extract/tracker-extract.h
index 06aae9578..66271805b 100644
--- a/src/tracker-extract/tracker-extract.h
+++ b/src/tracker-extract/tracker-extract.h
@@ -73,6 +73,9 @@ TrackerExtractInfo *
void tracker_extract_dbus_start (TrackerExtract *extract);
void tracker_extract_dbus_stop (TrackerExtract *extract);
+void tracker_extract_set_max_text (TrackerExtract *extract,
+ gint max_text);
+
/* Not DBus API */
void tracker_extract_get_metadata_by_cmdline (TrackerExtract *object,
const gchar *path,
diff --git a/src/tracker-extract/tracker-main.c b/src/tracker-extract/tracker-main.c
index 7732f443d..92333c62f 100644
--- a/src/tracker-extract/tracker-main.c
+++ b/src/tracker-extract/tracker-main.c
@@ -40,7 +40,6 @@
#include <libtracker-miners-common/tracker-common.h>
-#include "tracker-config.h"
#include "tracker-main.h"
#include "tracker-extract.h"
#include "tracker-extract-controller.h"
@@ -74,8 +73,6 @@ static gboolean version;
static gchar *domain_ontology_name = NULL;
static guint shutdown_timeout_id = 0;
-static TrackerConfig *config;
-
static GOptionEntry entries[] = {
{ "verbosity", 'v', 0,
G_OPTION_ARG_INT, &verbosity,
@@ -164,26 +161,8 @@ log_handler (const gchar *domain,
}
}
-static void
-sanity_check_option_values (TrackerConfig *config)
-{
- g_message ("General options:");
- g_message (" Verbosity ............................ %d",
- tracker_config_get_verbosity (config));
- g_message (" Sched Idle ........................... %d",
- tracker_config_get_sched_idle (config));
- g_message (" Max bytes (per file) ................. %d",
- tracker_config_get_max_bytes (config));
-}
-
-TrackerConfig *
-tracker_main_get_config (void)
-{
- return config;
-}
-
static int
-run_standalone (TrackerConfig *config)
+run_standalone (void)
{
TrackerExtract *object;
GFile *file;
@@ -217,7 +196,7 @@ run_standalone (TrackerConfig *config)
tracker_locale_sanity_check ();
/* This makes sure we don't steal all the system's resources */
- initialize_priority_and_scheduling (tracker_config_get_sched_idle (config), TRUE);
+ initialize_priority_and_scheduling (TRACKER_SCHED_IDLE_ALWAYS, TRUE);
file = g_file_new_for_commandline_arg (filename);
uri = g_file_get_uri (file);
@@ -353,33 +332,23 @@ main (int argc, char *argv[])
return EXIT_FAILURE;
}
- config = tracker_config_new ();
-
- /* Extractor command line arguments */
- if (verbosity > -1) {
- tracker_config_set_verbosity (config, verbosity);
- }
-
- tracker_log_init (tracker_config_get_verbosity (config), &log_filename);
+ tracker_log_init (MAX (verbosity, 0), &log_filename);
if (log_filename != NULL) {
g_message ("Using log file:'%s'", log_filename);
g_free (log_filename);
}
- sanity_check_option_values (config);
-
/* Set conditions when we use stand alone settings */
if (filename) {
- return run_standalone (config);
+ return run_standalone ();
}
/* This makes sure we don't steal all the system's resources */
- initialize_priority_and_scheduling (tracker_config_get_sched_idle (config), TRUE);
+ initialize_priority_and_scheduling (TRACKER_SCHED_IDLE_ALWAYS, TRUE);
extract = tracker_extract_new (TRUE, force_module);
if (!extract) {
- g_object_unref (config);
tracker_log_shutdown ();
return EXIT_FAILURE;
}
@@ -390,7 +359,6 @@ main (int argc, char *argv[])
if (error) {
g_critical ("Could not start decorator: %s\n", error->message);
- g_object_unref (config);
tracker_log_shutdown ();
return EXIT_FAILURE;
}
@@ -400,7 +368,6 @@ main (int argc, char *argv[])
g_critical ("Could not create miner DBus proxy: %s\n", error->message);
g_error_free (error);
g_object_unref (decorator);
- g_object_unref (config);
tracker_log_shutdown ();
return EXIT_FAILURE;
}
@@ -464,7 +431,5 @@ main (int argc, char *argv[])
tracker_log_shutdown ();
- g_object_unref (config);
-
return EXIT_SUCCESS;
}
diff --git a/src/tracker-extract/tracker-main.h b/src/tracker-extract/tracker-main.h
index 4af2e3e06..5ee12c697 100644
--- a/src/tracker-extract/tracker-main.h
+++ b/src/tracker-extract/tracker-main.h
@@ -21,13 +21,8 @@
#ifndef __TRACKER_MAIN_H__
#define __TRACKER_MAIN_H__
-#include "tracker-config.h"
-
G_BEGIN_DECLS
-/* Enables getting the config object from extractors */
-TrackerConfig *tracker_main_get_config (void);
-
G_END_DECLS
#endif /* __TRACKER_MAIN_H__ */
diff --git a/tests/libtracker-extract/tracker-extract-info-test.c b/tests/libtracker-extract/tracker-extract-info-test.c
index d189d44c3..b364254cc 100644
--- a/tests/libtracker-extract/tracker-extract-info-test.c
+++ b/tests/libtracker-extract/tracker-extract-info-test.c
@@ -29,7 +29,7 @@ test_extract_info_setters (void)
file = g_file_new_for_path ("./imaginary-file-2");
- info = tracker_extract_info_new (file, "imaginary/mime");
+ info = tracker_extract_info_new (file, "imaginary/mime", 100);
info_ref = tracker_extract_info_ref (info);
g_assert (g_file_equal (file, tracker_extract_info_get_file (info)));
@@ -50,7 +50,7 @@ test_extract_info_empty_objects (void)
file = g_file_new_for_path ("./imaginary-file");
- info = tracker_extract_info_new (file, "imaginary/mime");
+ info = tracker_extract_info_new (file, "imaginary/mime", 100);
info_ref = tracker_extract_info_ref (info);
tracker_extract_info_unref (info_ref);
--
2.43.0
From 6917c65c66338dd6b14bdfbfa301785997648b4d Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sun, 24 Sep 2023 19:18:52 +0200
Subject: [PATCH 04/22] tracker-extract: Avoid file access for persistence
Use a memfd_create() FD, maintained and kept alive by tracker-miner-fs-3.
This FD is obtained through D-Bus, and used for temporary storage. Since
processing of files in the extractor is largely linear nowadays, this
also simplifies the persistent storage to store a single file.
---
config.h.meson.in | 3 +
meson.build | 1 +
src/miners/fs/tracker-files-interface.c | 72 ++++-
.../tracker-extract-controller.c | 65 ++++-
.../tracker-extract-controller.h | 5 +-
.../tracker-extract-decorator.c | 98 ++++---
.../tracker-extract-decorator.h | 2 +
.../tracker-extract-persistence.c | 267 +++++-------------
.../tracker-extract-persistence.h | 19 +-
src/tracker-extract/tracker-main.c | 9 +-
10 files changed, 273 insertions(+), 268 deletions(-)
diff --git a/config.h.meson.in b/config.h.meson.in
index 176088724..78e6cd2bc 100644
--- a/config.h.meson.in
+++ b/config.h.meson.in
@@ -87,6 +87,9 @@
/* Define to 0 if tracker FTS is not compiled */
#mesondefine HAVE_TRACKER_FTS
+/* Define to 1 if you have the `memfd_create' function. */
+#mesondefine HAVE_MEMFD_CREATE
+
/* Define if we have UPOWER */
#mesondefine HAVE_UPOWER
diff --git a/meson.build b/meson.build
index fd536f2e6..1812daa1b 100644
--- a/meson.build
+++ b/meson.build
@@ -320,6 +320,7 @@ conf.set('HAVE_GETLINE', cc.has_function('getline', prefix : '#include <stdio.h>
conf.set('HAVE_POSIX_FADVISE', cc.has_function('posix_fadvise', prefix : '#include <fcntl.h>'))
conf.set('HAVE_STATVFS64', cc.has_header_symbol('sys/statvfs.h', 'statvfs64', args: '-D_LARGEFILE64_SOURCE'))
conf.set('HAVE_STRNLEN', cc.has_function('strnlen', prefix : '#include <string.h>'))
+conf.set('HAVE_MEMFD_CREATE', cc.has_function('memfd_create', prefix : '#define _GNU_SOURCE\n#include <sys/mman.h>'))
conf.set('LOCALEDIR', '"@0@/@1@"'.format(get_option('prefix'), get_option('localedir')))
conf.set('SHAREDIR', '"@0@/@1@"'.format(get_option('prefix'), get_option('datadir')))
diff --git a/src/miners/fs/tracker-files-interface.c b/src/miners/fs/tracker-files-interface.c
index 0e259a6ce..ee2c1b985 100644
--- a/src/miners/fs/tracker-files-interface.c
+++ b/src/miners/fs/tracker-files-interface.c
@@ -23,12 +23,16 @@
#include "tracker-files-interface.h"
+#include <gio/gunixfdlist.h>
+#include <sys/mman.h>
+
struct _TrackerFilesInterface
{
GObject parent_instance;
GDBusConnection *connection;
GSettings *settings;
guint object_id;
+ int fd;
};
enum {
@@ -43,6 +47,9 @@ static const gchar *introspection_xml =
"<node>"
" <interface name='org.freedesktop.Tracker3.Files'>"
" <property name='ExtractorConfig' type='a{sv}' access='read' />"
+ " <method name='GetPersistenceStorage'>"
+ " <arg type='h' direction='out' />"
+ " </method>"
" </interface>"
"</node>";
@@ -53,6 +60,66 @@ tracker_files_interface_init (TrackerFilesInterface *files_interface)
{
}
+static void
+handle_method_call (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ TrackerFilesInterface *files_interface = user_data;
+
+ if (g_strcmp0 (method_name, "GetPersistenceStorage") == 0) {
+ GVariant *out_parameters;
+ g_autoptr (GUnixFDList) fd_list = NULL;
+ g_autoptr (GError) error = NULL;
+ int idx;
+
+ if (files_interface->fd <= 0) {
+#ifdef HAVE_MEMFD_CREATE
+ files_interface->fd = memfd_create ("extract-persistent-storage",
+ MFD_CLOEXEC);
+#else
+ g_autofree gchar *path = NULL;
+
+ path = g_strdup_printf ("%s/tracker-persistence.XXXXXX",
+ g_get_tmp_dir ());
+ files_interface->fd = g_mkstemp_full (path, 0, 0600);
+ unlink (path);
+#endif
+
+ if (files_interface->fd < 0) {
+ g_dbus_method_invocation_return_error (invocation,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Could not create memfd");
+ return;
+ }
+ }
+
+ fd_list = g_unix_fd_list_new ();
+ idx = g_unix_fd_list_append (fd_list, files_interface->fd, &error);
+
+ if (error) {
+ g_dbus_method_invocation_return_gerror (invocation, error);
+ } else {
+ out_parameters = g_variant_new ("(h)", idx);
+ g_dbus_method_invocation_return_value_with_unix_fd_list (invocation,
+ out_parameters,
+ fd_list);
+ }
+ } else {
+ g_dbus_method_invocation_return_error (invocation,
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_METHOD,
+ "Unknown method %s",
+ method_name);
+ }
+}
+
static GVariant *
handle_get_property (GDBusConnection *connection,
const gchar *sender,
@@ -90,7 +157,7 @@ static void
tracker_files_interface_constructed (GObject *object)
{
TrackerFilesInterface *files_interface = TRACKER_FILES_INTERFACE (object);
- GDBusInterfaceVTable vtable = { NULL, handle_get_property, NULL };
+ GDBusInterfaceVTable vtable = { handle_method_call, handle_get_property, NULL };
g_autoptr (GDBusNodeInfo) introspection_data = NULL;
G_OBJECT_CLASS (tracker_files_interface_parent_class)->constructed (object);
@@ -115,6 +182,9 @@ tracker_files_interface_finalize (GObject *object)
g_clear_object (&files_interface->connection);
g_clear_object (&files_interface->settings);
+ if (files_interface->fd)
+ close (files_interface->fd);
+
G_OBJECT_CLASS (tracker_files_interface_parent_class)->finalize (object);
}
diff --git a/src/tracker-extract/tracker-extract-controller.c b/src/tracker-extract/tracker-extract-controller.c
index 01a2ae4f7..1affb0ef8 100644
--- a/src/tracker-extract/tracker-extract-controller.c
+++ b/src/tracker-extract/tracker-extract-controller.c
@@ -23,13 +23,17 @@
#include "tracker-main.h"
+#include <gio/gunixfdlist.h>
+
enum {
PROP_DECORATOR = 1,
PROP_CONNECTION,
+ PROP_PERSISTENCE,
};
struct TrackerExtractControllerPrivate {
TrackerDecorator *decorator;
+ TrackerExtractPersistence *persistence;
GCancellable *cancellable;
GDBusConnection *connection;
GDBusProxy *miner_proxy;
@@ -85,6 +89,38 @@ miner_properties_changed_cb (GDBusProxy *proxy,
update_extract_config (user_data, proxy);
}
+static gboolean
+set_up_persistence (TrackerExtractController *controller,
+ GCancellable *cancellable,
+ GError **error)
+{
+ TrackerExtractControllerPrivate *priv =
+ tracker_extract_controller_get_instance_private (controller);
+ g_autoptr (GUnixFDList) out_fd_list = NULL;
+ g_autoptr (GVariant) variant = NULL;
+ int idx, fd;
+
+ variant = g_dbus_proxy_call_with_unix_fd_list_sync (priv->miner_proxy,
+ "GetPersistenceStorage",
+ NULL,
+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ -1,
+ NULL,
+ &out_fd_list,
+ cancellable,
+ error);
+ if (!variant)
+ return FALSE;
+
+ g_variant_get (variant, "(h)", &idx);
+ fd = g_unix_fd_list_get (out_fd_list, idx, error);
+ if (fd < 0)
+ return FALSE;
+
+ tracker_extract_persistence_set_fd (priv->persistence, fd);
+ return TRUE;
+}
+
static void
tracker_extract_controller_constructed (GObject *object)
{
@@ -104,6 +140,8 @@ tracker_extract_controller_constructed (GObject *object)
G_CALLBACK (miner_properties_changed_cb), self);
update_extract_config (self, self->priv->miner_proxy);
}
+
+ set_up_persistence (self, NULL, NULL);
}
static void
@@ -121,6 +159,12 @@ tracker_extract_controller_get_property (GObject *object,
case PROP_CONNECTION:
g_value_set_object (value, self->priv->connection);
break;
+ case PROP_PERSISTENCE:
+ g_value_set_object (value, self->priv->persistence);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
}
}
@@ -140,6 +184,12 @@ tracker_extract_controller_set_property (GObject *object,
case PROP_CONNECTION:
self->priv->connection = g_value_dup_object (value);
break;
+ case PROP_PERSISTENCE:
+ self->priv->persistence = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
}
}
@@ -149,6 +199,7 @@ tracker_extract_controller_dispose (GObject *object)
TrackerExtractController *self = (TrackerExtractController *) object;
g_clear_object (&self->priv->decorator);
+ g_clear_object (&self->priv->persistence);
G_OBJECT_CLASS (tracker_extract_controller_parent_class)->dispose (object);
}
@@ -181,6 +232,14 @@ tracker_extract_controller_class_init (TrackerExtractControllerClass *klass)
G_PARAM_STATIC_STRINGS |
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (object_class,
+ PROP_PERSISTENCE,
+ g_param_spec_object ("persistence",
+ NULL, NULL,
+ TRACKER_TYPE_EXTRACT_PERSISTENCE,
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
g_type_class_add_private (object_class,
sizeof (TrackerExtractControllerPrivate));
@@ -195,13 +254,15 @@ tracker_extract_controller_init (TrackerExtractController *self)
}
TrackerExtractController *
-tracker_extract_controller_new (TrackerDecorator *decorator,
- GDBusConnection *connection)
+tracker_extract_controller_new (TrackerDecorator *decorator,
+ GDBusConnection *connection,
+ TrackerExtractPersistence *persistence)
{
g_return_val_if_fail (TRACKER_IS_DECORATOR (decorator), NULL);
return g_object_new (TRACKER_TYPE_EXTRACT_CONTROLLER,
"decorator", decorator,
"connection", connection,
+ "persistence", persistence,
NULL);
}
diff --git a/src/tracker-extract/tracker-extract-controller.h b/src/tracker-extract/tracker-extract-controller.h
index 7d8a70816..3ba85751c 100644
--- a/src/tracker-extract/tracker-extract-controller.h
+++ b/src/tracker-extract/tracker-extract-controller.h
@@ -47,8 +47,9 @@ struct TrackerExtractControllerClass {
};
GType tracker_extract_controller_get_type (void) G_GNUC_CONST;
-TrackerExtractController * tracker_extract_controller_new (TrackerDecorator *decorator,
- GDBusConnection *connection);
+TrackerExtractController * tracker_extract_controller_new (TrackerDecorator *decorator,
+ GDBusConnection *connection,
+ TrackerExtractPersistence *persistence);
G_END_DECLS
diff --git a/src/tracker-extract/tracker-extract-decorator.c b/src/tracker-extract/tracker-extract-decorator.c
index 516e1ee48..e2575d662 100644
--- a/src/tracker-extract/tracker-extract-decorator.c
+++ b/src/tracker-extract/tracker-extract-decorator.c
@@ -27,7 +27,9 @@
#include "tracker-extract-priority-dbus.h"
enum {
- PROP_EXTRACTOR = 1
+ PROP_0,
+ PROP_EXTRACTOR,
+ PROP_PERSISTENCE,
};
#define TRACKER_EXTRACT_DATA_SOURCE TRACKER_PREFIX_TRACKER "extractor-data-source"
@@ -51,7 +53,6 @@ struct _TrackerExtractDecoratorPrivate {
guint n_extracting_files;
TrackerExtractPersistence *persistence;
- GHashTable *recovery_files;
/* DBus name -> AppData */
GHashTable *apps;
@@ -82,6 +83,9 @@ static GInitableIface *parent_initable_iface;
static void decorator_get_next_file (TrackerDecorator *decorator);
static void tracker_extract_decorator_initable_iface_init (GInitableIface *iface);
+static void decorator_ignore_file (GFile *file,
+ gpointer user_data);
+
G_DEFINE_TYPE_WITH_CODE (TrackerExtractDecorator, tracker_extract_decorator,
TRACKER_TYPE_DECORATOR_FS,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, tracker_extract_decorator_initable_iface_init))
@@ -100,6 +104,12 @@ tracker_extract_decorator_get_property (GObject *object,
case PROP_EXTRACTOR:
g_value_set_object (value, priv->extractor);
break;
+ case PROP_PERSISTENCE:
+ g_value_set_object (value, priv->persistence);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
}
}
@@ -117,6 +127,12 @@ tracker_extract_decorator_set_property (GObject *object,
case PROP_EXTRACTOR:
priv->extractor = g_value_dup_object (value);
break;
+ case PROP_PERSISTENCE:
+ priv->persistence = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
}
}
@@ -135,7 +151,7 @@ tracker_extract_decorator_finalize (GObject *object)
g_object_unref (priv->iface);
g_hash_table_unref (priv->apps);
- g_hash_table_unref (priv->recovery_files);
+ g_object_unref (priv->persistence);
G_OBJECT_CLASS (tracker_extract_decorator_parent_class)->finalize (object);
}
@@ -183,8 +199,7 @@ get_metadata_cb (TrackerExtract *extract,
priv = TRACKER_EXTRACT_DECORATOR (data->decorator)->priv;
info = tracker_extract_file_finish (extract, result, &error);
- tracker_extract_persistence_remove_file (priv->persistence, data->file);
- g_hash_table_remove (priv->recovery_files, tracker_decorator_info_get_url (data->decorator_info));
+ tracker_extract_persistence_set_file (priv->persistence, NULL);
if (error) {
g_message ("Extraction failed: %s\n", error ? error->message : "no error given");
@@ -214,26 +229,6 @@ get_metadata_cb (TrackerExtract *extract,
g_free (data);
}
-static GFile *
-decorator_get_recovery_file (TrackerExtractDecorator *decorator,
- TrackerDecoratorInfo *info)
-{
- TrackerExtractDecoratorPrivate *priv;
- GFile *file;
-
- priv = decorator->priv;
- file = g_hash_table_lookup (priv->recovery_files,
- tracker_decorator_info_get_url (info));
-
- if (file) {
- g_object_ref (file);
- } else {
- file = g_file_new_for_uri (tracker_decorator_info_get_url (info));
- }
-
- return file;
-}
-
static void
decorator_next_item_cb (TrackerDecorator *decorator,
GAsyncResult *result,
@@ -277,12 +272,12 @@ decorator_next_item_cb (TrackerDecorator *decorator,
data = g_new0 (ExtractData, 1);
data->decorator = decorator;
data->decorator_info = info;
- data->file = decorator_get_recovery_file (TRACKER_EXTRACT_DECORATOR (decorator), info);
+ data->file = g_file_new_for_uri (tracker_decorator_info_get_url (info));
task = tracker_decorator_info_get_task (info);
g_message ("Extracting metadata for '%s'", tracker_decorator_info_get_url (info));
- tracker_extract_persistence_add_file (priv->persistence, data->file);
+ tracker_extract_persistence_set_file (priv->persistence, data->file);
tracker_extract_file (priv->extractor,
tracker_decorator_info_get_url (info),
@@ -341,6 +336,22 @@ tracker_extract_decorator_resumed (TrackerMiner *miner)
decorator_get_next_file (TRACKER_DECORATOR (miner));
}
+static void
+tracker_extract_decorator_started (TrackerMiner *miner)
+{
+ TrackerExtractDecorator *decorator = TRACKER_EXTRACT_DECORATOR (miner);
+ TrackerExtractDecoratorPrivate *priv =
+ tracker_extract_decorator_get_instance_private (decorator);
+ GFile *file;
+
+ file = tracker_extract_persistence_get_file (priv->persistence);
+
+ if (file)
+ decorator_ignore_file (file, decorator);
+
+ TRACKER_MINER_CLASS (tracker_extract_decorator_parent_class)->started (miner);
+}
+
static void
tracker_extract_decorator_items_available (TrackerDecorator *decorator)
{
@@ -544,6 +555,7 @@ tracker_extract_decorator_class_init (TrackerExtractDecoratorClass *klass)
miner_class->paused = tracker_extract_decorator_paused;
miner_class->resumed = tracker_extract_decorator_resumed;
+ miner_class->started = tracker_extract_decorator_started;
decorator_class->items_available = tracker_extract_decorator_items_available;
decorator_class->finished = tracker_extract_decorator_finished;
@@ -555,25 +567,21 @@ tracker_extract_decorator_class_init (TrackerExtractDecoratorClass *klass)
"Extractor",
TRACKER_TYPE_EXTRACT,
G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class,
+ PROP_PERSISTENCE,
+ g_param_spec_object ("persistence",
+ NULL, NULL,
+ TRACKER_TYPE_EXTRACT_PERSISTENCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
g_type_class_add_private (object_class,
sizeof (TrackerExtractDecoratorPrivate));
}
-static void
-decorator_retry_file (GFile *file,
- gpointer user_data)
-{
- TrackerExtractDecorator *decorator = user_data;
- TrackerExtractDecoratorPrivate *priv = decorator->priv;
- gchar *path;
-
- path = g_file_get_uri (file);
- g_hash_table_insert (priv->recovery_files, path, g_object_ref (file));
- tracker_decorator_fs_prepend_file (TRACKER_DECORATOR_FS (decorator), file);
-}
-
static void
decorator_ignore_file (GFile *file,
gpointer user_data)
@@ -612,9 +620,6 @@ tracker_extract_decorator_init (TrackerExtractDecorator *decorator)
TrackerExtractDecoratorPrivate *priv;
decorator->priv = priv = TRACKER_EXTRACT_DECORATOR_GET_PRIVATE (decorator);
- priv->recovery_files = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) g_object_unref);
}
static gboolean
@@ -667,9 +672,6 @@ tracker_extract_decorator_initable_init (GInitable *initable,
ret = FALSE;
}
- priv->persistence = tracker_extract_persistence_initialize (decorator_retry_file,
- decorator_ignore_file,
- decorator);
out:
g_clear_object (&conn);
@@ -685,6 +687,7 @@ tracker_extract_decorator_initable_iface_init (GInitableIface *iface)
TrackerDecorator *
tracker_extract_decorator_new (TrackerExtract *extract,
+ TrackerExtractPersistence *persistence,
GCancellable *cancellable,
GError **error)
{
@@ -693,5 +696,6 @@ tracker_extract_decorator_new (TrackerExtract *extract,
"data-source", TRACKER_EXTRACT_DATA_SOURCE,
"class-names", supported_classes,
"extractor", extract,
+ "persistence", persistence,
NULL);
}
diff --git a/src/tracker-extract/tracker-extract-decorator.h b/src/tracker-extract/tracker-extract-decorator.h
index 6d16eeb64..9e9146ca1 100644
--- a/src/tracker-extract/tracker-extract-decorator.h
+++ b/src/tracker-extract/tracker-extract-decorator.h
@@ -24,6 +24,7 @@
#include <libtracker-miner/tracker-miner.h>
#include "tracker-extract.h"
+#include "tracker-extract-persistence.h"
G_BEGIN_DECLS
@@ -49,6 +50,7 @@ struct TrackerExtractDecoratorClass {
GType tracker_extract_decorator_get_type (void) G_GNUC_CONST;
TrackerDecorator * tracker_extract_decorator_new (TrackerExtract *extractor,
+ TrackerExtractPersistence *persistence,
GCancellable *cancellable,
GError **error);
diff --git a/src/tracker-extract/tracker-extract-persistence.c b/src/tracker-extract/tracker-extract-persistence.c
index 1dc542736..3eff4f34d 100644
--- a/src/tracker-extract/tracker-extract-persistence.c
+++ b/src/tracker-extract/tracker-extract-persistence.c
@@ -25,7 +25,7 @@ typedef struct _TrackerExtractPersistencePrivate TrackerExtractPersistencePrivat
struct _TrackerExtractPersistencePrivate
{
- GFile *tmp_dir;
+ int fd;
};
G_DEFINE_TYPE_WITH_PRIVATE (TrackerExtractPersistence, tracker_extract_persistence, G_TYPE_OBJECT)
@@ -33,241 +33,102 @@ G_DEFINE_TYPE_WITH_PRIVATE (TrackerExtractPersistence, tracker_extract_persisten
static GQuark n_retries_quark = 0;
static void
-tracker_extract_persistence_class_init (TrackerExtractPersistenceClass *klass)
-{
- n_retries_quark = g_quark_from_static_string ("tracker-extract-n-retries-quark");
-}
-
-static void
-tracker_extract_persistence_init (TrackerExtractPersistence *persistence)
+tracker_extract_persistence_finalize (GObject *object)
{
- TrackerExtractPersistencePrivate *priv;
- gchar *dirname, *tmp_path;
-
- priv = tracker_extract_persistence_get_instance_private (persistence);
-
- dirname = g_strdup_printf ("tracker-extract-files.%d", getuid ());
- tmp_path = g_build_filename (g_get_tmp_dir (), dirname, NULL);
- g_free (dirname);
+ TrackerExtractPersistence *persistence =
+ TRACKER_EXTRACT_PERSISTENCE (object);
+ TrackerExtractPersistencePrivate *priv =
+ tracker_extract_persistence_get_instance_private (persistence);
- if (g_mkdir_with_parents (tmp_path, 0700) != 0) {
- g_critical ("The directory %s could not be created, or has the wrong permissions",
- tmp_path);
- g_assert_not_reached ();
- }
+ if (priv->fd > 0)
+ close (priv->fd);
- priv->tmp_dir = g_file_new_for_path (tmp_path);
- g_free (tmp_path);
+ G_OBJECT_CLASS (tracker_extract_persistence_parent_class)->finalize (object);
}
static void
-increment_n_retries (GFile *file)
+tracker_extract_persistence_class_init (TrackerExtractPersistenceClass *klass)
{
- guint n_retries;
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
- n_retries = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (file), n_retries_quark));
- g_object_set_qdata (G_OBJECT (file), n_retries_quark, GUINT_TO_POINTER (n_retries + 1));
+ object_class->finalize = tracker_extract_persistence_finalize;
}
-static GFile *
-persistence_create_symlink_file (TrackerExtractPersistence *persistence,
- GFile *file)
+static void
+tracker_extract_persistence_init (TrackerExtractPersistence *persistence)
{
- TrackerExtractPersistencePrivate *priv;
- guint n_retries = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (file), n_retries_quark));
- gchar *link_name, *path, *md5;
- GFile *link_file;
-
- priv = tracker_extract_persistence_get_instance_private (persistence);
- path = g_file_get_path (file);
- md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, path, -1);
- link_name = g_strdup_printf ("%d-%s", n_retries, md5);
- link_file = g_file_get_child (priv->tmp_dir, link_name);
-
- g_free (link_name);
- g_free (path);
- g_free (md5);
-
- return link_file;
}
-static GFile *
-persistence_symlink_get_file (GFileInfo *info)
+TrackerExtractPersistence *
+tracker_extract_persistence_new (void)
{
- const gchar *symlink_name, *symlink_target;
- gchar *md5, **items;
- GFile *file = NULL;
- guint n_retries;
-
- symlink_name = g_file_info_get_name (info);
- symlink_target = g_file_info_get_symlink_target (info);
-
- if (!g_path_is_absolute (symlink_target)) {
- g_critical ("Symlink paths must be absolute, '%s' points to '%s'",
- symlink_name, symlink_target);
- return NULL;
- }
-
- md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, symlink_target, -1);
- items = g_strsplit (symlink_name, "-", 2);
- n_retries = g_strtod (items[0], NULL);
-
- if (g_strcmp0 (items[1], md5) == 0) {
- file = g_file_new_for_path (symlink_target);
- g_object_set_qdata (G_OBJECT (file), n_retries_quark,
- GUINT_TO_POINTER (n_retries));
- } else {
- g_critical ("path MD5 for '%s' doesn't match with symlink '%s'",
- symlink_target, symlink_name);
- }
-
- g_strfreev (items);
- g_free (md5);
-
- return file;
+ return g_object_new (TRACKER_TYPE_EXTRACT_PERSISTENCE,
+ NULL);
}
-static gboolean
-persistence_store_file (TrackerExtractPersistence *persistence,
- GFile *file)
+void
+tracker_extract_persistence_set_fd (TrackerExtractPersistence *persistence,
+ int fd)
{
- GError *error = NULL;
- gboolean success;
- GFile *link_file;
- gchar *path;
-
- increment_n_retries (file);
- path = g_file_get_path (file);
- link_file = persistence_create_symlink_file (persistence, file);
-
- success = g_file_make_symbolic_link (link_file, path, NULL, &error);
-
- if (!success) {
- g_warning ("Could not save '%s' into failsafe persistence store: %s",
- path, error ? error->message : "no error given");
- g_clear_error (&error);
- }
-
- g_object_unref (link_file);
- g_free (path);
+ TrackerExtractPersistencePrivate *priv =
+ tracker_extract_persistence_get_instance_private (persistence);
- return success;
+ if (priv->fd > 0)
+ close (priv->fd);
+ priv->fd = fd;
}
-static gboolean
-persistence_remove_file (TrackerExtractPersistence *persistence,
- GFile *file)
+void
+tracker_extract_persistence_set_file (TrackerExtractPersistence *persistence,
+ GFile *file)
{
- GError *error = NULL;
- GFile *link_file;
- gboolean success;
+ TrackerExtractPersistencePrivate *priv =
+ tracker_extract_persistence_get_instance_private (persistence);
+ g_autofree gchar *path = NULL;
+ int len, written = 0, retval;
- link_file = persistence_create_symlink_file (persistence, file);
- success = g_file_delete (link_file, NULL, &error);
-
- if (!success) {
- gchar *path = g_file_get_path (file);
+ g_return_if_fail (TRACKER_IS_EXTRACT_PERSISTENCE (persistence));
+ g_return_if_fail (!file || G_IS_FILE (file));
- g_warning ("Could not delete '%s' from failsafe persistence store",
- path);
- g_free (path);
+ if (file) {
+ path = g_file_get_path (file);
+ } else {
+ path = g_strdup ("");
}
- g_object_unref (link_file);
-
- return success;
-}
-
-static void
-persistence_retrieve_files (TrackerExtractPersistence *persistence,
- TrackerFileRecoveryFunc retry_func,
- TrackerFileRecoveryFunc ignore_func,
- gpointer user_data)
-{
- TrackerExtractPersistencePrivate *priv;
- GFileEnumerator *enumerator;
- GFileInfo *info;
-
- priv = tracker_extract_persistence_get_instance_private (persistence);
- enumerator = g_file_enumerate_children (priv->tmp_dir,
- G_FILE_ATTRIBUTE_STANDARD_NAME ","
- G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- NULL, NULL);
- if (!enumerator)
- return;
-
- while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL) {
- GFile *file, *symlink_file;
- guint n_retries;
-
- symlink_file = g_file_enumerator_get_child (enumerator, info);
- file = persistence_symlink_get_file (info);
-
- if (!file) {
- /* If we got here, persistence_symlink_get_file() already emitted a g_critical */
- g_object_unref (symlink_file);
- g_object_unref (info);
- continue;
- }
-
- /* Delete the symlink, it will get probably added back soon after,
- * and n_retries incremented.
- */
- g_file_delete (symlink_file, NULL, NULL);
- g_object_unref (symlink_file);
-
- n_retries = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (file), n_retries_quark));
+ /* Write also the trailing \0 */
+ len = strlen (path) + 1;
- /* Trigger retry/ignore func for the symlink target */
- if (n_retries >= MAX_RETRIES) {
- ignore_func (file, user_data);
- } else {
- retry_func (file, user_data);
- }
+ lseek (priv->fd, 0, SEEK_SET);
- g_object_unref (file);
- g_object_unref (info);
- }
-
- g_file_enumerator_close (enumerator, NULL, NULL);
- g_object_unref (enumerator);
-}
-
-TrackerExtractPersistence *
-tracker_extract_persistence_initialize (TrackerFileRecoveryFunc retry_func,
- TrackerFileRecoveryFunc ignore_func,
- gpointer user_data)
-{
- static TrackerExtractPersistence *persistence = NULL;
+ while (TRUE) {
+ retval = write (priv->fd, &path[written], len - written);
+ if (retval < 0)
+ break;
- if (!persistence) {
- persistence = g_object_new (TRACKER_TYPE_EXTRACT_PERSISTENCE,
- NULL);
- persistence_retrieve_files (persistence,
- retry_func, ignore_func,
- user_data);
+ written += retval;
+ if (written >= len)
+ break;
}
-
- return persistence;
}
-void
-tracker_extract_persistence_add_file (TrackerExtractPersistence *persistence,
- GFile *file)
+GFile *
+tracker_extract_persistence_get_file (TrackerExtractPersistence *persistence)
{
- g_return_if_fail (TRACKER_IS_EXTRACT_PERSISTENCE (persistence));
- g_return_if_fail (G_IS_FILE (file));
+ TrackerExtractPersistencePrivate *priv =
+ tracker_extract_persistence_get_instance_private (persistence);
+ gchar buf[2048];
+ int len;
- persistence_store_file (persistence, file);
-}
+ g_return_val_if_fail (TRACKER_IS_EXTRACT_PERSISTENCE (persistence), NULL);
-void
-tracker_extract_persistence_remove_file (TrackerExtractPersistence *persistence,
- GFile *file)
-{
- g_return_if_fail (TRACKER_IS_EXTRACT_PERSISTENCE (persistence));
- g_return_if_fail (G_IS_FILE (file));
+ lseek (priv->fd, 0, SEEK_SET);
+ len = read (priv->fd, buf, sizeof (buf));
+ if (len <= 0)
+ return NULL;
+ if (buf[0] == '\0')
+ return NULL;
- persistence_remove_file (persistence, file);
+ buf[len - 1] = '\0';
+ return g_file_new_for_path (buf);
}
diff --git a/src/tracker-extract/tracker-extract-persistence.h b/src/tracker-extract/tracker-extract-persistence.h
index d5474af0d..c1d498ef7 100644
--- a/src/tracker-extract/tracker-extract-persistence.h
+++ b/src/tracker-extract/tracker-extract-persistence.h
@@ -34,9 +34,6 @@ G_BEGIN_DECLS
typedef struct _TrackerExtractPersistence TrackerExtractPersistence;
typedef struct _TrackerExtractPersistenceClass TrackerExtractPersistenceClass;
-typedef void (* TrackerFileRecoveryFunc) (GFile *file,
- gpointer user_data);
-
struct _TrackerExtractPersistence
{
GObject parent_instance;
@@ -49,15 +46,15 @@ struct _TrackerExtractPersistenceClass
GType tracker_extract_persistence_get_type (void) G_GNUC_CONST;
-TrackerExtractPersistence *
- tracker_extract_persistence_initialize (TrackerFileRecoveryFunc retry_func,
- TrackerFileRecoveryFunc ignore_func,
- gpointer user_data);
+TrackerExtractPersistence * tracker_extract_persistence_new (void);
+
+void tracker_extract_persistence_set_fd (TrackerExtractPersistence *persistence,
+ int fd);
+
+GFile * tracker_extract_persistence_get_file (TrackerExtractPersistence *persistence);
-void tracker_extract_persistence_add_file (TrackerExtractPersistence *persistence,
- GFile *file);
-void tracker_extract_persistence_remove_file (TrackerExtractPersistence *persistence,
- GFile *file);
+void tracker_extract_persistence_set_file (TrackerExtractPersistence *persistence,
+ GFile *file);
G_END_DECLS
diff --git a/src/tracker-extract/tracker-main.c b/src/tracker-extract/tracker-main.c
index 92333c62f..01eaf2ed0 100644
--- a/src/tracker-extract/tracker-main.c
+++ b/src/tracker-extract/tracker-main.c
@@ -44,6 +44,7 @@
#include "tracker-extract.h"
#include "tracker-extract-controller.h"
#include "tracker-extract-decorator.h"
+#include "tracker-extract-persistence.h"
#ifdef THREAD_ENABLE_TRACE
#warning Main thread traces enabled
@@ -269,6 +270,7 @@ main (int argc, char *argv[])
GMainLoop *my_main_loop;
GDBusConnection *connection;
TrackerMinerProxy *proxy;
+ TrackerExtractPersistence *persistence;
TrackerDomainOntology *domain_ontology;
gchar *domain_name, *dbus_name;
@@ -355,7 +357,9 @@ main (int argc, char *argv[])
tracker_module_manager_load_modules ();
- decorator = tracker_extract_decorator_new (extract, NULL, &error);
+ persistence = tracker_extract_persistence_new ();
+
+ decorator = tracker_extract_decorator_new (extract, persistence, NULL, &error);
if (error) {
g_critical ("Could not start decorator: %s\n", error->message);
@@ -379,7 +383,7 @@ main (int argc, char *argv[])
tracker_locale_sanity_check ();
- controller = tracker_extract_controller_new (decorator, connection);
+ controller = tracker_extract_controller_new (decorator, connection, persistence);
tracker_miner_start (TRACKER_MINER (decorator));
/* Request DBus name */
@@ -425,6 +429,7 @@ main (int argc, char *argv[])
g_object_unref (extract);
g_object_unref (decorator);
g_object_unref (controller);
+ g_object_unref (persistence);
g_object_unref (proxy);
g_object_unref (connection);
g_object_unref (domain_ontology);
--
2.43.0
From 7c0d4d69adbdd096fa40dd96a15b61640db2023d Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sun, 24 Sep 2023 23:27:56 +0200
Subject: [PATCH 05/22] tracker-extract: Disable GstRegistry forking
This is going nowhere with the sandbox. Also disable some more
needless GST plugins.
---
src/tracker-extract/tracker-extract-gstreamer.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/tracker-extract/tracker-extract-gstreamer.c b/src/tracker-extract/tracker-extract-gstreamer.c
index 3546069a6..1305ecfa2 100644
--- a/src/tracker-extract/tracker-extract-gstreamer.c
+++ b/src/tracker-extract/tracker-extract-gstreamer.c
@@ -1306,12 +1306,16 @@ tracker_extract_module_init (GError **error)
/* Lifted from totem-video-thumbnailer */
const gchar *blacklisted[] = {
"bcmdec",
+ "camerabin",
+ "fluidsynthmidi",
+ "libcamera",
"vaapi",
"video4linux2"
};
GstRegistry *registry;
guint i;
+ gst_registry_fork_set_enabled (FALSE);
gst_init (NULL, NULL);
registry = gst_registry_get ();
--
2.43.0
From 49493c1f5c2b5fce76d24d598e1388f474a2c0f0 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 22 Sep 2023 23:26:38 +0200
Subject: [PATCH 06/22] libtracker-miners-common: Extend seccomp rules
The plan is to extend the seccomp jail so it affects the full
tracker-extract-3 process. With the changes in the previous
commits we've removed the need for filesystem write access.
We have some remaining outliers, that we're largely sorting
out with rules to error out softly (instead of through SIGSYS).
The only new allowed syscalls are fstatfs and prlimit64 with a
NULL new_limit struct.
---
.../tracker-seccomp.c | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/src/libtracker-miners-common/tracker-seccomp.c b/src/libtracker-miners-common/tracker-seccomp.c
index 71b601740..50cfed4f4 100644
--- a/src/libtracker-miners-common/tracker-seccomp.c
+++ b/src/libtracker-miners-common/tracker-seccomp.c
@@ -97,6 +97,8 @@ tracker_seccomp_init (void)
ALLOW_RULE (statfs64);
ALLOW_RULE (lstat);
ALLOW_RULE (lstat64);
+ ALLOW_RULE (statx);
+ ALLOW_RULE (fstatfs);
ALLOW_RULE (access);
ALLOW_RULE (getdents);
ALLOW_RULE (getdents64);
@@ -163,6 +165,22 @@ tracker_seccomp_init (void)
ALLOW_RULE (getpeername);
ALLOW_RULE (shutdown);
+ ERROR_RULE (inotify_init1, EINVAL);
+ ERROR_RULE (inotify_init, EINVAL);
+
+ ERROR_RULE (mkdir, EPERM);
+ ERROR_RULE (rename, EPERM);
+ ERROR_RULE (unlink, EPERM);
+ ERROR_RULE (ioctl, EBADF);
+ ERROR_RULE (bind, EACCES);
+ ERROR_RULE (setsockopt, EBADF);
+ ERROR_RULE (sched_getattr, EPERM);
+
+ /* Allow prlimit64, only if no new limits are being set */
+ if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(prlimit64), 1,
+ SCMP_CMP(2, SCMP_CMP_EQ, 0)) < 0)
+ goto out;
+
/* Special requirements for socket/socketpair, only on AF_UNIX/AF_LOCAL */
if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
SCMP_CMP(0, SCMP_CMP_EQ, AF_UNIX)) < 0)
@@ -170,6 +188,9 @@ tracker_seccomp_init (void)
if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
SCMP_CMP(0, SCMP_CMP_EQ, AF_LOCAL)) < 0)
goto out;
+ if (seccomp_rule_add (ctx, SCMP_ACT_ERRNO (EACCES), SCMP_SYS(socket), 1,
+ SCMP_CMP(0, SCMP_CMP_EQ, AF_NETLINK)) < 0)
+ goto out;
if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair), 1,
SCMP_CMP(0, SCMP_CMP_EQ, AF_UNIX)) < 0)
goto out;
--
2.43.0
From 78c04b87cbdff97990244166a9e8ae95d35419c7 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 22 Sep 2023 23:14:38 +0200
Subject: [PATCH 07/22] tracker-extract: Extend seccomp jail to full process
Currently, our main thread is exempted from the seccomp jail.
This was so we could do some menial tasks (e.g. persistence handling
to recover from runtime errors, or error reports on failed extraction)
without caring much about plugging seccomp holes.
It may be preferable to extend the seccomp jail to the full process
instead, so do that. Now the only thing happening prior to setting
up the seccomp jail is the setting up of nice/scheduler/ioprio
priorities. Everything else, and every thread spawned afterwards is
covered by seccomp.
Related: https://gitlab.gnome.org/GNOME/tracker-miners/-/issues/277
---
src/tracker-extract/tracker-extract.c | 5 -----
src/tracker-extract/tracker-main.c | 24 ++++++++++++++++--------
2 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/src/tracker-extract/tracker-extract.c b/src/tracker-extract/tracker-extract.c
index cd0511e8f..5eafca7d5 100644
--- a/src/tracker-extract/tracker-extract.c
+++ b/src/tracker-extract/tracker-extract.c
@@ -30,8 +30,6 @@
#include <gio/gunixinputstream.h>
#include <gio/gunixfdlist.h>
-#include <libtracker-miners-common/tracker-common.h>
-
#include <libtracker-extract/tracker-extract.h>
#include "tracker-extract.h"
@@ -507,9 +505,6 @@ get_metadata (TrackerExtractTask *task)
static gpointer
single_thread_get_metadata (GAsyncQueue *queue)
{
- if (!tracker_seccomp_init ())
- g_assert_not_reached ();
-
while (TRUE) {
TrackerExtractTask *task;
diff --git a/src/tracker-extract/tracker-main.c b/src/tracker-extract/tracker-main.c
index 01eaf2ed0..5cfe073c0 100644
--- a/src/tracker-extract/tracker-main.c
+++ b/src/tracker-extract/tracker-main.c
@@ -196,9 +196,6 @@ run_standalone (void)
tracker_locale_sanity_check ();
- /* This makes sure we don't steal all the system's resources */
- initialize_priority_and_scheduling (TRACKER_SCHED_IDLE_ALWAYS, TRUE);
-
file = g_file_new_for_commandline_arg (filename);
uri = g_file_get_uri (file);
@@ -258,8 +255,8 @@ on_decorator_finished (TrackerDecorator *decorator,
main_loop);
}
-int
-main (int argc, char *argv[])
+static int
+do_main (int argc, char *argv[])
{
GOptionContext *context;
GError *error = NULL;
@@ -345,9 +342,6 @@ main (int argc, char *argv[])
return run_standalone ();
}
- /* This makes sure we don't steal all the system's resources */
- initialize_priority_and_scheduling (TRACKER_SCHED_IDLE_ALWAYS, TRUE);
-
extract = tracker_extract_new (TRUE, force_module);
if (!extract) {
@@ -438,3 +432,17 @@ main (int argc, char *argv[])
return EXIT_SUCCESS;
}
+
+int
+main (int argc, char *argv[])
+{
+ /* This function is untouchable! Add things to do_main() */
+
+ /* This makes sure we don't steal all the system's resources */
+ initialize_priority_and_scheduling (TRACKER_SCHED_IDLE_ALWAYS, TRUE);
+
+ if (!tracker_seccomp_init ())
+ g_assert_not_reached ();
+
+ return do_main (argc, argv);
+}
--
2.43.0
From e6f592da48b332ef41493e28a2c2b3dc888aae8c Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Tue, 3 Oct 2023 12:44:42 +0200
Subject: [PATCH 08/22] libtracker-miners-common: Add custom rules through a
define
Bring some more consistence between our ALLOW/ERROR_RULE defines,
and the "custom" rules where we check syscall arguments.
---
.../tracker-seccomp.c | 66 +++++++------------
1 file changed, 23 insertions(+), 43 deletions(-)
diff --git a/src/libtracker-miners-common/tracker-seccomp.c b/src/libtracker-miners-common/tracker-seccomp.c
index 50cfed4f4..05eebd57b 100644
--- a/src/libtracker-miners-common/tracker-seccomp.c
+++ b/src/libtracker-miners-common/tracker-seccomp.c
@@ -52,6 +52,13 @@
goto out; \
} G_STMT_END
+#define CUSTOM_RULE(call, action, arg1) G_STMT_START { \
+ int custom_rule_syscall_number = seccomp_syscall_resolve_name (G_STRINGIFY (call)); \
+ if (custom_rule_syscall_number == __NR_SCMP_ERROR || \
+ seccomp_rule_add (ctx, action, custom_rule_syscall_number, 1, arg1) < 0) \
+ goto out; \
+} G_STMT_END
+
gboolean
tracker_seccomp_init (void)
{
@@ -177,57 +184,30 @@ tracker_seccomp_init (void)
ERROR_RULE (sched_getattr, EPERM);
/* Allow prlimit64, only if no new limits are being set */
- if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(prlimit64), 1,
- SCMP_CMP(2, SCMP_CMP_EQ, 0)) < 0)
- goto out;
+ CUSTOM_RULE (prlimit64, SCMP_ACT_ALLOW, SCMP_CMP(2, SCMP_CMP_EQ, 0));
/* Special requirements for socket/socketpair, only on AF_UNIX/AF_LOCAL */
- if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
- SCMP_CMP(0, SCMP_CMP_EQ, AF_UNIX)) < 0)
- goto out;
- if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
- SCMP_CMP(0, SCMP_CMP_EQ, AF_LOCAL)) < 0)
- goto out;
- if (seccomp_rule_add (ctx, SCMP_ACT_ERRNO (EACCES), SCMP_SYS(socket), 1,
- SCMP_CMP(0, SCMP_CMP_EQ, AF_NETLINK)) < 0)
- goto out;
- if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair), 1,
- SCMP_CMP(0, SCMP_CMP_EQ, AF_UNIX)) < 0)
- goto out;
- if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair), 1,
- SCMP_CMP(0, SCMP_CMP_EQ, AF_LOCAL)) < 0)
- goto out;
+ CUSTOM_RULE (socket, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, AF_UNIX));
+ CUSTOM_RULE (socket, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, AF_LOCAL));
+ CUSTOM_RULE (socket, SCMP_ACT_ERRNO (EACCES), SCMP_CMP(0, SCMP_CMP_EQ, AF_NETLINK));
+
+ CUSTOM_RULE (socketpair, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, AF_UNIX));
+ CUSTOM_RULE (socketpair, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, AF_LOCAL));
/* Special requirements for ioctl, allowed on stdout/stderr */
- if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 1,
- SCMP_CMP(0, SCMP_CMP_EQ, 1)) < 0)
- goto out;
- if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 1,
- SCMP_CMP(0, SCMP_CMP_EQ, 2)) < 0)
- goto out;
+ CUSTOM_RULE (ioctl, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, 1));
+ CUSTOM_RULE (ioctl, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, 2));
/* Special requirements for open/openat, allow O_RDONLY calls,
* but fail if write permissions are requested.
*/
- if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 1,
- SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0)) < 0)
- goto out;
- if (seccomp_rule_add (ctx, SCMP_ACT_ERRNO (EACCES), SCMP_SYS(open), 1,
- SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY)) < 0)
- goto out;
- if (seccomp_rule_add (ctx, SCMP_ACT_ERRNO (EACCES), SCMP_SYS(open), 1,
- SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR)) < 0)
- goto out;
-
- if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), 1,
- SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0)) < 0)
- goto out;
- if (seccomp_rule_add (ctx, SCMP_ACT_ERRNO (EACCES), SCMP_SYS(openat), 1,
- SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY)) < 0)
- goto out;
- if (seccomp_rule_add (ctx, SCMP_ACT_ERRNO (EACCES), SCMP_SYS(openat), 1,
- SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR)) < 0)
- goto out;
+ CUSTOM_RULE (open, SCMP_ACT_ALLOW, SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0));
+ CUSTOM_RULE (open, SCMP_ACT_ERRNO (EACCES), SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY));
+ CUSTOM_RULE (open, SCMP_ACT_ERRNO (EACCES), SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR));
+
+ CUSTOM_RULE (openat, SCMP_ACT_ALLOW, SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0));
+ CUSTOM_RULE (openat, SCMP_ACT_ERRNO (EACCES), SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY));
+ CUSTOM_RULE (openat, SCMP_ACT_ERRNO (EACCES), SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR));
g_debug ("Loading seccomp rules.");
--
2.43.0
From ea33d95f6ecc2e088fc0a77891bc1fa5e77da71e Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Tue, 3 Oct 2023 12:47:57 +0200
Subject: [PATCH 09/22] libtracker-miners-common: Improve "bail out" error
loading seccomp rules
We are out in the dark if we happen to add syscalls that do not exist on
obscure architectures. Keep track of the rules being added, so we can
provide a more useful error if we fall in this situation.
---
src/libtracker-miners-common/tracker-seccomp.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/libtracker-miners-common/tracker-seccomp.c b/src/libtracker-miners-common/tracker-seccomp.c
index 05eebd57b..dae1dc426 100644
--- a/src/libtracker-miners-common/tracker-seccomp.c
+++ b/src/libtracker-miners-common/tracker-seccomp.c
@@ -40,6 +40,7 @@
#define ALLOW_RULE(call) G_STMT_START { \
int allow_rule_syscall_number = seccomp_syscall_resolve_name (G_STRINGIFY (call)); \
+ current_syscall = G_STRINGIFY (call); \
if (allow_rule_syscall_number == __NR_SCMP_ERROR || \
seccomp_rule_add (ctx, SCMP_ACT_ALLOW, allow_rule_syscall_number, 0) < 0) \
goto out; \
@@ -47,6 +48,7 @@
#define ERROR_RULE(call, error) G_STMT_START { \
int error_rule_syscall_number = seccomp_syscall_resolve_name (G_STRINGIFY (call)); \
+ current_syscall = G_STRINGIFY (call); \
if (error_rule_syscall_number == __NR_SCMP_ERROR || \
seccomp_rule_add (ctx, SCMP_ACT_ERRNO (error), error_rule_syscall_number, 0) < 0) \
goto out; \
@@ -54,6 +56,7 @@
#define CUSTOM_RULE(call, action, arg1) G_STMT_START { \
int custom_rule_syscall_number = seccomp_syscall_resolve_name (G_STRINGIFY (call)); \
+ current_syscall = G_STRINGIFY (call); \
if (custom_rule_syscall_number == __NR_SCMP_ERROR || \
seccomp_rule_add (ctx, action, custom_rule_syscall_number, 1, arg1) < 0) \
goto out; \
@@ -63,6 +66,7 @@ gboolean
tracker_seccomp_init (void)
{
scmp_filter_ctx ctx;
+ const gchar *current_syscall = NULL;
ctx = seccomp_init (SCMP_ACT_TRAP);
if (ctx == NULL)
@@ -215,7 +219,7 @@ tracker_seccomp_init (void)
return TRUE;
out:
- g_critical ("Failed to load seccomp rules.");
+ g_critical ("Failed to load seccomp rule for syscall '%s'", current_syscall);
seccomp_release (ctx);
return FALSE;
}
--
2.43.0
From f24b4617bccb63da09eba0297d344916df3c2723 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sun, 8 Oct 2023 00:02:30 +0200
Subject: [PATCH 10/22] libtracker-miners-common: Add more seccomp rules
Seen on debian/ubuntu on some arches. Make mkdirat error out
the same way than mkdir, and allow name_to_handle_at() as
that should be innocuous.
Closes: https://gitlab.gnome.org/GNOME/tracker-miners/-/issues/281
---
src/libtracker-miners-common/tracker-seccomp.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/libtracker-miners-common/tracker-seccomp.c b/src/libtracker-miners-common/tracker-seccomp.c
index dae1dc426..d91175aab 100644
--- a/src/libtracker-miners-common/tracker-seccomp.c
+++ b/src/libtracker-miners-common/tracker-seccomp.c
@@ -175,11 +175,13 @@ tracker_seccomp_init (void)
ALLOW_RULE (getsockname);
ALLOW_RULE (getpeername);
ALLOW_RULE (shutdown);
+ ALLOW_RULE (name_to_handle_at);
ERROR_RULE (inotify_init1, EINVAL);
ERROR_RULE (inotify_init, EINVAL);
ERROR_RULE (mkdir, EPERM);
+ ERROR_RULE (mkdirat, EPERM);
ERROR_RULE (rename, EPERM);
ERROR_RULE (unlink, EPERM);
ERROR_RULE (ioctl, EBADF);
--
2.43.0
From 63b88a31d83e569de2eca56381f5614e2a595867 Mon Sep 17 00:00:00 2001
From: psykose <alice@ayaya.dev>
Date: Tue, 17 Oct 2023 13:29:56 +0000
Subject: [PATCH 11/22] libtracker-miners-common: use macro stringify instead
of G_STRINGIFY
G_STRINGIFY performs macro expansion; this means that on musl, the LFS64
interface define of
#define getdents64 getdents
gets expanded to 'getdents', so the getdents64 syscall becomes not
allowed. using the preprocessor #stringify does not expand the name, so
this works as expected.
closes #285
---
src/libtracker-miners-common/tracker-seccomp.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/libtracker-miners-common/tracker-seccomp.c b/src/libtracker-miners-common/tracker-seccomp.c
index d91175aab..a2dff8296 100644
--- a/src/libtracker-miners-common/tracker-seccomp.c
+++ b/src/libtracker-miners-common/tracker-seccomp.c
@@ -39,24 +39,24 @@
#include <seccomp.h>
#define ALLOW_RULE(call) G_STMT_START { \
- int allow_rule_syscall_number = seccomp_syscall_resolve_name (G_STRINGIFY (call)); \
- current_syscall = G_STRINGIFY (call); \
+ int allow_rule_syscall_number = seccomp_syscall_resolve_name (#call); \
+ current_syscall = #call; \
if (allow_rule_syscall_number == __NR_SCMP_ERROR || \
seccomp_rule_add (ctx, SCMP_ACT_ALLOW, allow_rule_syscall_number, 0) < 0) \
goto out; \
} G_STMT_END
#define ERROR_RULE(call, error) G_STMT_START { \
- int error_rule_syscall_number = seccomp_syscall_resolve_name (G_STRINGIFY (call)); \
- current_syscall = G_STRINGIFY (call); \
+ int error_rule_syscall_number = seccomp_syscall_resolve_name (#call); \
+ current_syscall = #call; \
if (error_rule_syscall_number == __NR_SCMP_ERROR || \
seccomp_rule_add (ctx, SCMP_ACT_ERRNO (error), error_rule_syscall_number, 0) < 0) \
goto out; \
} G_STMT_END
#define CUSTOM_RULE(call, action, arg1) G_STMT_START { \
- int custom_rule_syscall_number = seccomp_syscall_resolve_name (G_STRINGIFY (call)); \
- current_syscall = G_STRINGIFY (call); \
+ int custom_rule_syscall_number = seccomp_syscall_resolve_name (#call); \
+ current_syscall = #call; \
if (custom_rule_syscall_number == __NR_SCMP_ERROR || \
seccomp_rule_add (ctx, action, custom_rule_syscall_number, 1, arg1) < 0) \
goto out; \
--
2.43.0
From 01a0453b86416d6a16592c29b351ace8d12b8d42 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Mon, 16 Oct 2023 11:15:21 +0200
Subject: [PATCH 12/22] libtracker-miners-common: Allow some more syscalls for
i686
These are seen on Debian i686 with the default dependencies pulled
from apt-get build-dep tracker-miners. There's mainly 32-bit syscall
variants (getgid32, fstatfs64), some fancy stuff so far unseen in 64-bit
(timerfd_create), and for some unfathomable reason, gstreamer openNI2
module using chdir() to change the CWD.
Everything is harmless though, so go with that.
Closes: https://gitlab.gnome.org/GNOME/tracker-miners/-/issues/284
---
src/libtracker-miners-common/tracker-seccomp.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/libtracker-miners-common/tracker-seccomp.c b/src/libtracker-miners-common/tracker-seccomp.c
index a2dff8296..0c9054117 100644
--- a/src/libtracker-miners-common/tracker-seccomp.c
+++ b/src/libtracker-miners-common/tracker-seccomp.c
@@ -89,6 +89,8 @@ tracker_seccomp_init (void)
ALLOW_RULE (exit_group);
ALLOW_RULE (getuid);
ALLOW_RULE (getuid32);
+ ALLOW_RULE (getgid);
+ ALLOW_RULE (getgid32);
ALLOW_RULE (getegid);
ALLOW_RULE (getegid32);
ALLOW_RULE (geteuid);
@@ -110,6 +112,7 @@ tracker_seccomp_init (void)
ALLOW_RULE (lstat64);
ALLOW_RULE (statx);
ALLOW_RULE (fstatfs);
+ ALLOW_RULE (fstatfs64);
ALLOW_RULE (access);
ALLOW_RULE (getdents);
ALLOW_RULE (getdents64);
@@ -119,6 +122,7 @@ tracker_seccomp_init (void)
ALLOW_RULE (time);
ALLOW_RULE (fsync);
ALLOW_RULE (umask);
+ ALLOW_RULE (chdir);
/* Processes and threads */
ALLOW_RULE (clone);
ALLOW_RULE (futex);
@@ -148,6 +152,7 @@ tracker_seccomp_init (void)
ALLOW_RULE (clock_gettime);
ALLOW_RULE (clock_getres);
ALLOW_RULE (gettimeofday);
+ ALLOW_RULE (timerfd_create);
/* Descriptors */
ALLOW_RULE (close);
ALLOW_RULE (read);
--
2.43.0
From eeda731c25d7fd7f606bc5c13420d4e848946337 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Tue, 17 Oct 2023 12:52:32 +0200
Subject: [PATCH 13/22] libtracker-miners-common: Allow NETLINK_KOBJECT_UEVENT
access
Sadly, it remains extremely finicky to provide detailed rules with
differing actions for socket() through libseccomp(), due to the way this
syscall is (was?) wrapped through the multiplexed socketcall() syscall on
some architectures.
Since we cannot provide different SCMP_ACT_* values, and we cannot let
AF_NETLINK/NETLINK_KOBJECT_UEVENT requests fail with SIGSYS (e.g.
video4linux2 gstreamer plugin wants udev access and will trigger this
right in gst_init()), go with SCMP_ACT_ALLOW for this specific combination,
along with AF_LOCAL.
This kind of socket is effectively readonly to unprivileged users and
local by definition, so it does not seem a big risk to allow, the only
lingering question being "why should we allow this".
Closes: https://gitlab.gnome.org/GNOME/tracker-miners/-/issues/283
---
src/libtracker-miners-common/tracker-seccomp.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/src/libtracker-miners-common/tracker-seccomp.c b/src/libtracker-miners-common/tracker-seccomp.c
index 0c9054117..cb1ba2f8c 100644
--- a/src/libtracker-miners-common/tracker-seccomp.c
+++ b/src/libtracker-miners-common/tracker-seccomp.c
@@ -36,6 +36,8 @@
#include <sys/socket.h>
#include <fcntl.h>
+#include <linux/netlink.h>
+
#include <seccomp.h>
#define ALLOW_RULE(call) G_STMT_START { \
@@ -62,6 +64,14 @@
goto out; \
} G_STMT_END
+#define CUSTOM_RULE_2ARG(call, action, arg1, arg2) G_STMT_START { \
+ int custom_rule_syscall_number = seccomp_syscall_resolve_name (#call); \
+ current_syscall = #call; \
+ if (custom_rule_syscall_number == __NR_SCMP_ERROR || \
+ seccomp_rule_add (ctx, action, custom_rule_syscall_number, 2, arg1, arg2) < 0) \
+ goto out; \
+} G_STMT_END
+
gboolean
tracker_seccomp_init (void)
{
@@ -197,10 +207,14 @@ tracker_seccomp_init (void)
/* Allow prlimit64, only if no new limits are being set */
CUSTOM_RULE (prlimit64, SCMP_ACT_ALLOW, SCMP_CMP(2, SCMP_CMP_EQ, 0));
- /* Special requirements for socket/socketpair, only on AF_UNIX/AF_LOCAL */
+ /* Special requirements for socket/socketpair, only on AF_UNIX/AF_LOCAL,
+ * and AF_NETLINK/NETLINK_KOBJECT_UEVENT for udev.
+ */
CUSTOM_RULE (socket, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, AF_UNIX));
CUSTOM_RULE (socket, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, AF_LOCAL));
- CUSTOM_RULE (socket, SCMP_ACT_ERRNO (EACCES), SCMP_CMP(0, SCMP_CMP_EQ, AF_NETLINK));
+ CUSTOM_RULE_2ARG (socket, SCMP_ACT_ALLOW,
+ SCMP_CMP (0, SCMP_CMP_EQ, AF_NETLINK),
+ SCMP_CMP (2, SCMP_CMP_EQ, NETLINK_KOBJECT_UEVENT));
CUSTOM_RULE (socketpair, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, AF_UNIX));
CUSTOM_RULE (socketpair, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, AF_LOCAL));
--
2.43.0
From dd954babb31612b635472a12c32ba98fa4dcbf76 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Tue, 17 Oct 2023 09:31:33 +0200
Subject: [PATCH 14/22] libtracker-miners-common: Allow tgkill on self's
process
This is the syscall underneath abort(), assert(), etc. Let this
syscall through for the purpose of killing self's process, and
don't hide the actual errors.
Closes: https://gitlab.gnome.org/GNOME/tracker-miners/-/issues/287
---
src/libtracker-miners-common/tracker-seccomp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/libtracker-miners-common/tracker-seccomp.c b/src/libtracker-miners-common/tracker-seccomp.c
index cb1ba2f8c..c7f986768 100644
--- a/src/libtracker-miners-common/tracker-seccomp.c
+++ b/src/libtracker-miners-common/tracker-seccomp.c
@@ -204,6 +204,9 @@ tracker_seccomp_init (void)
ERROR_RULE (setsockopt, EBADF);
ERROR_RULE (sched_getattr, EPERM);
+ /* Allow tgkill on self, for abort() and friends */
+ CUSTOM_RULE (tgkill, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, getpid()));
+
/* Allow prlimit64, only if no new limits are being set */
CUSTOM_RULE (prlimit64, SCMP_ACT_ALLOW, SCMP_CMP(2, SCMP_CMP_EQ, 0));
--
2.43.0
From aeff5f7125bb437247bad1b5cbc190eb2a9789e0 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Tue, 17 Oct 2023 12:48:42 +0200
Subject: [PATCH 15/22] tracker-extract: Initialize modules also before
commandline extraction
This allows the gstreamer module to block plugins through the registry
in those paths too.
---
src/tracker-extract/tracker-main.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/tracker-extract/tracker-main.c b/src/tracker-extract/tracker-main.c
index 5cfe073c0..4be5e8f22 100644
--- a/src/tracker-extract/tracker-main.c
+++ b/src/tracker-extract/tracker-main.c
@@ -337,6 +337,9 @@ do_main (int argc, char *argv[])
g_free (log_filename);
}
+ tracker_extract_module_manager_init ();
+ tracker_module_manager_load_modules ();
+
/* Set conditions when we use stand alone settings */
if (filename) {
return run_standalone ();
@@ -349,8 +352,6 @@ do_main (int argc, char *argv[])
return EXIT_FAILURE;
}
- tracker_module_manager_load_modules ();
-
persistence = tracker_extract_persistence_new ();
decorator = tracker_extract_decorator_new (extract, persistence, NULL, &error);
--
2.43.0
From 9767d49b33ad071bfa1d1f1869efb59be13191da Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Tue, 17 Oct 2023 13:11:07 +0200
Subject: [PATCH 16/22] libtracker-miners-common: Allow restart_syscall syscall
This syscall may happen after SIGCONT if a previous SIGSTOP caught
the process mid-syscall. This is a plausible situation with gdb, and
through coredumpd/abrtd/etc.
Closes: https://gitlab.gnome.org/GNOME/tracker-miners/-/issues/288
---
src/libtracker-miners-common/tracker-seccomp.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/libtracker-miners-common/tracker-seccomp.c b/src/libtracker-miners-common/tracker-seccomp.c
index c7f986768..76c19a39e 100644
--- a/src/libtracker-miners-common/tracker-seccomp.c
+++ b/src/libtracker-miners-common/tracker-seccomp.c
@@ -145,6 +145,7 @@ tracker_seccomp_init (void)
ALLOW_RULE (waitid);
ALLOW_RULE (waitpid);
ALLOW_RULE (wait4);
+ ALLOW_RULE (restart_syscall);
/* Main loops */
ALLOW_RULE (poll);
ALLOW_RULE (ppoll);
--
2.43.0
From 27943111ba1852fe37c1e6dfedcfebf4eff954e1 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Tue, 17 Oct 2023 14:12:33 +0200
Subject: [PATCH 17/22] libtracker-miners-common: Drop ioctl rules for
stdout/stderr
These were added in the first instance of the sandbox, I do not
remember what they were for, and they seem largely unnecessary
nowadays.
---
src/libtracker-miners-common/tracker-seccomp.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/src/libtracker-miners-common/tracker-seccomp.c b/src/libtracker-miners-common/tracker-seccomp.c
index 76c19a39e..fe8aa1b84 100644
--- a/src/libtracker-miners-common/tracker-seccomp.c
+++ b/src/libtracker-miners-common/tracker-seccomp.c
@@ -223,10 +223,6 @@ tracker_seccomp_init (void)
CUSTOM_RULE (socketpair, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, AF_UNIX));
CUSTOM_RULE (socketpair, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, AF_LOCAL));
- /* Special requirements for ioctl, allowed on stdout/stderr */
- CUSTOM_RULE (ioctl, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, 1));
- CUSTOM_RULE (ioctl, SCMP_ACT_ALLOW, SCMP_CMP(0, SCMP_CMP_EQ, 2));
-
/* Special requirements for open/openat, allow O_RDONLY calls,
* but fail if write permissions are requested.
*/
--
2.43.0
From bf8370b379c75a07001204958062f983cfc23896 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Tue, 17 Oct 2023 14:28:29 +0200
Subject: [PATCH 18/22] libtracker-miners-common: Disallow close/dup2/dup3 on
standard I/O FDs
As an additional measure, forbid these FDs to be replaced by anything.
---
src/libtracker-miners-common/tracker-seccomp.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/libtracker-miners-common/tracker-seccomp.c b/src/libtracker-miners-common/tracker-seccomp.c
index fe8aa1b84..723ac4dd9 100644
--- a/src/libtracker-miners-common/tracker-seccomp.c
+++ b/src/libtracker-miners-common/tracker-seccomp.c
@@ -165,7 +165,9 @@ tracker_seccomp_init (void)
ALLOW_RULE (gettimeofday);
ALLOW_RULE (timerfd_create);
/* Descriptors */
- ALLOW_RULE (close);
+ CUSTOM_RULE (close, SCMP_ACT_ALLOW, SCMP_CMP (0, SCMP_CMP_GT, STDERR_FILENO));
+ CUSTOM_RULE (dup2, SCMP_ACT_ALLOW, SCMP_CMP (1, SCMP_CMP_GT, STDERR_FILENO));
+ CUSTOM_RULE (dup3, SCMP_ACT_ALLOW, SCMP_CMP (1, SCMP_CMP_GT, STDERR_FILENO));
ALLOW_RULE (read);
ALLOW_RULE (pread64);
ALLOW_RULE (lseek);
@@ -175,8 +177,6 @@ tracker_seccomp_init (void)
ALLOW_RULE (write);
ALLOW_RULE (writev);
ALLOW_RULE (dup);
- ALLOW_RULE (dup2);
- ALLOW_RULE (dup3);
/* Needed by some GStreamer modules doing crazy stuff, less
* scary thanks to the restriction below about sockets being
* local.
--
2.43.0
From 49c8c7e79cb7746ad15bc84eddcd8ee14fd32dbf Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Tue, 17 Oct 2023 16:10:11 +0200
Subject: [PATCH 19/22] libtracker-miners-common: Forbid some more
open()/openat() flags
There are some nasty combinations with O_RDONLY that may already
trigger unintended results, like O_CREAT and O_TRUNC. Avoid any
combination that sounds off with O_RDONLY.
---
src/libtracker-miners-common/tracker-seccomp.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/libtracker-miners-common/tracker-seccomp.c b/src/libtracker-miners-common/tracker-seccomp.c
index 723ac4dd9..a853863d7 100644
--- a/src/libtracker-miners-common/tracker-seccomp.c
+++ b/src/libtracker-miners-common/tracker-seccomp.c
@@ -226,11 +226,15 @@ tracker_seccomp_init (void)
/* Special requirements for open/openat, allow O_RDONLY calls,
* but fail if write permissions are requested.
*/
- CUSTOM_RULE (open, SCMP_ACT_ALLOW, SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0));
+ CUSTOM_RULE (open, SCMP_ACT_ALLOW,
+ SCMP_CMP (1, SCMP_CMP_MASKED_EQ,
+ O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC | O_EXCL, 0));
CUSTOM_RULE (open, SCMP_ACT_ERRNO (EACCES), SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY));
CUSTOM_RULE (open, SCMP_ACT_ERRNO (EACCES), SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR));
- CUSTOM_RULE (openat, SCMP_ACT_ALLOW, SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0));
+ CUSTOM_RULE (openat, SCMP_ACT_ALLOW,
+ SCMP_CMP (2, SCMP_CMP_MASKED_EQ,
+ O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC | O_EXCL, 0));
CUSTOM_RULE (openat, SCMP_ACT_ERRNO (EACCES), SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY));
CUSTOM_RULE (openat, SCMP_ACT_ERRNO (EACCES), SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR));
--
2.43.0
From 6be14b13541873b5f490164748287fa6b070e0ec Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Mon, 23 Oct 2023 19:17:41 +0200
Subject: [PATCH 20/22] tracker-miner-fs: Preempt GStreamer registry file
creation
Initialize gstreamer in tracker-miner-fs, mostly as a means to
ensure the registry file is guaranteed to exist and be up-to-date
when the tracker-extract-3 process gets to start up and require the
use of GStreamer plugins.
---
src/miners/fs/Makefile.am | 2 ++
src/miners/fs/meson.build | 7 ++++---
src/miners/fs/tracker-main.c | 7 +++++++
3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/miners/fs/Makefile.am b/src/miners/fs/Makefile.am
index cb812e0b5..526d6b0a2 100644
--- a/src/miners/fs/Makefile.am
+++ b/src/miners/fs/Makefile.am
@@ -7,6 +7,7 @@ AM_CPPFLAGS = \
-DSHAREDIR=\""$(datadir)"\" \
-DLOCALEDIR=\""$(localedir)"\" \
-DLIBEXEC_PATH=\""$(libexecdir)"\" \
+ $(GSTREAMER_CFLAGS) \
$(TRACKER_MINER_FS_CFLAGS)
libexec_PROGRAMS = tracker-miner-fs
@@ -57,6 +58,7 @@ tracker_miner_fs_LDADD = \
$(top_builddir)/src/libtracker-extract/libtracker-extract.la \
$(top_builddir)/src/libtracker-miners-common/libtracker-miners-common.la \
$(BUILD_LIBS) \
+ $(GSTREAMER_LIBS) \
$(TRACKER_MINER_FS_LIBS)
# DBus services
diff --git a/src/miners/fs/meson.build b/src/miners/fs/meson.build
index c26c0240e..9fdfaa395 100644
--- a/src/miners/fs/meson.build
+++ b/src/miners/fs/meson.build
@@ -14,9 +14,10 @@ sources = [
]
tracker_miner_fs_deps = [
- tracker_miner,
- tracker_miners_common_dep,
- tracker_extract_dep
+ tracker_miner,
+ tracker_miners_common_dep,
+ tracker_extract_dep,
+ gstreamer,
]
if battery_detection_library_name == 'upower'
diff --git a/src/miners/fs/tracker-main.c b/src/miners/fs/tracker-main.c
index e7e809560..44912ba5d 100644
--- a/src/miners/fs/tracker-main.c
+++ b/src/miners/fs/tracker-main.c
@@ -31,6 +31,8 @@
#include <glib-object.h>
#include <glib/gi18n.h>
+#include <gst/gst.h>
+
#include <libtracker-miners-common/tracker-common.h>
#include <libtracker-sparql/tracker-sparql.h>
#include <libtracker-miner/tracker-miner.h>
@@ -682,6 +684,11 @@ main (gint argc, gchar *argv[])
/* Set timezone info */
tzset ();
+ /* Preempt possible registry updates, before tracker-extract-3 deals
+ * with gstreamer plugins.
+ */
+ gst_init (NULL, NULL);
+
/* Translators: this messagge will apper immediately after the
* usage string - Usage: COMMAND <THIS_MESSAGE>
*/
--
2.43.0
From 0be7148c185af8bc258dc2e3eab9db9fdf4f1c18 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Wed, 25 Oct 2023 11:21:17 +0200
Subject: [PATCH 21/22] tracker-extract: Disable GST registry updates in
extractor process
Force disable the attempt to update the GStreamer registry from the extractor
process, creation of files is softly forbidden by the seccomp sandbox anyway.
This will have the nice side effect of avoiding GStreamer from attempting to
load changed/new modules at gst_init() time (and the crazy shit some of them
do during plugin initialization), while the less nice side effect (the extractor
not finding old/stale plugins, and being unable to use new ones) should have been
largely avoided by the previous commit.
---
src/tracker-extract/tracker-main.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/tracker-extract/tracker-main.c b/src/tracker-extract/tracker-main.c
index 4be5e8f22..dd1f851d3 100644
--- a/src/tracker-extract/tracker-main.c
+++ b/src/tracker-extract/tracker-main.c
@@ -271,6 +271,8 @@ do_main (int argc, char *argv[])
TrackerDomainOntology *domain_ontology;
gchar *domain_name, *dbus_name;
+ g_setenv ("GST_REGISTRY_UPDATE", "no", TRUE);
+
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
--
2.43.0
From 2da4f2d681896c8f631578f5b5cab6bc9eb21e93 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Thu, 7 Dec 2023 14:28:43 +0100
Subject: [PATCH 22/22] libtracker-common: Allow getresuid/getresgid in seccomp
---
src/libtracker-miners-common/tracker-seccomp.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/libtracker-miners-common/tracker-seccomp.c b/src/libtracker-miners-common/tracker-seccomp.c
index a853863d7..7d705751f 100644
--- a/src/libtracker-miners-common/tracker-seccomp.c
+++ b/src/libtracker-miners-common/tracker-seccomp.c
@@ -108,6 +108,8 @@ tracker_seccomp_init (void)
ALLOW_RULE (getppid);
ALLOW_RULE (gettid);
ALLOW_RULE (getpid);
+ ALLOW_RULE (getresuid);
+ ALLOW_RULE (getresgid);
ALLOW_RULE (exit);
ALLOW_RULE (getrusage);
ALLOW_RULE (getrlimit);
--
2.43.0