daemon: Time out client txn connections after 30s
This removes the "transaction monitor". Originally the idea here was things would queue, but we never really made that work. Since transactions started grabbing the libostree sysroot lock in particular. Rip out the transaction monitor code with the queue and have a singleton txn ref in the sysroot object. This should ensure that if a txn is active, one always gets an error message about which one. Next, add a 30s timeout for connections to the transaction DBus sockets after they're complete. This should address https://github.com/projectatomic/rpm-ostree/issues/1692 which is a case where gnome-software was leaking the txn DBus connection and keeping it alive. Closes: #1755 Approved by: cgwalters
This commit is contained in:
parent
e58ee20996
commit
aea374710e
@ -40,8 +40,6 @@ librpmostreed_la_SOURCES = \
|
|||||||
src/daemon/rpmostreed-deployment-utils.c \
|
src/daemon/rpmostreed-deployment-utils.c \
|
||||||
src/daemon/rpmostreed-transaction.h \
|
src/daemon/rpmostreed-transaction.h \
|
||||||
src/daemon/rpmostreed-transaction.c \
|
src/daemon/rpmostreed-transaction.c \
|
||||||
src/daemon/rpmostreed-transaction-monitor.h \
|
|
||||||
src/daemon/rpmostreed-transaction-monitor.c \
|
|
||||||
src/daemon/rpmostreed-transaction-types.h \
|
src/daemon/rpmostreed-transaction-types.h \
|
||||||
src/daemon/rpmostreed-transaction-types.c \
|
src/daemon/rpmostreed-transaction-types.c \
|
||||||
src/daemon/rpmostreed-transaction-livefs.c \
|
src/daemon/rpmostreed-transaction-livefs.c \
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include "rpmostreed-utils.h"
|
#include "rpmostreed-utils.h"
|
||||||
#include "rpmostree-util.h"
|
#include "rpmostree-util.h"
|
||||||
#include "rpmostreed-transaction.h"
|
#include "rpmostreed-transaction.h"
|
||||||
#include "rpmostreed-transaction-monitor.h"
|
|
||||||
#include "rpmostreed-transaction-types.h"
|
#include "rpmostreed-transaction-types.h"
|
||||||
|
|
||||||
typedef struct _RpmostreedOSExperimentalClass RpmostreedOSExperimentalClass;
|
typedef struct _RpmostreedOSExperimentalClass RpmostreedOSExperimentalClass;
|
||||||
@ -39,7 +38,6 @@ typedef struct _RpmostreedOSExperimentalClass RpmostreedOSExperimentalClass;
|
|||||||
struct _RpmostreedOSExperimental
|
struct _RpmostreedOSExperimental
|
||||||
{
|
{
|
||||||
RPMOSTreeOSSkeleton parent_instance;
|
RPMOSTreeOSSkeleton parent_instance;
|
||||||
RpmostreedTransactionMonitor *transaction_monitor;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _RpmostreedOSExperimentalClass
|
struct _RpmostreedOSExperimentalClass
|
||||||
@ -57,23 +55,6 @@ G_DEFINE_TYPE_WITH_CODE (RpmostreedOSExperimental,
|
|||||||
rpmostreed_osexperimental_iface_init)
|
rpmostreed_osexperimental_iface_init)
|
||||||
);
|
);
|
||||||
|
|
||||||
static RpmostreedTransaction *
|
|
||||||
merge_compatible_txn (RpmostreedOSExperimental *self,
|
|
||||||
GDBusMethodInvocation *invocation)
|
|
||||||
{
|
|
||||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
|
||||||
|
|
||||||
/* If a compatible transaction is in progress, share its bus address. */
|
|
||||||
transaction = rpmostreed_transaction_monitor_ref_active_transaction (self->transaction_monitor);
|
|
||||||
if (transaction != NULL)
|
|
||||||
{
|
|
||||||
if (rpmostreed_transaction_is_compatible (transaction, invocation))
|
|
||||||
return g_steal_pointer (&transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -89,8 +70,6 @@ os_dispose (GObject *object)
|
|||||||
object_path, object);
|
object_path, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_clear_object (&self->transaction_monitor);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (rpmostreed_osexperimental_parent_class)->dispose (object);
|
G_OBJECT_CLASS (rpmostreed_osexperimental_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,13 +138,15 @@ osexperimental_handle_live_fs (RPMOSTreeOSExperimental *interface,
|
|||||||
GDBusMethodInvocation *invocation,
|
GDBusMethodInvocation *invocation,
|
||||||
GVariant *arg_options)
|
GVariant *arg_options)
|
||||||
{
|
{
|
||||||
RpmostreedOSExperimental *self = RPMOSTREED_OSEXPERIMENTAL (interface);
|
|
||||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
|
||||||
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
||||||
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
||||||
GError *local_error = NULL;
|
GError *local_error = NULL;
|
||||||
|
|
||||||
transaction = merge_compatible_txn (self, invocation);
|
/* try to merge with an existing transaction, otherwise start a new one */
|
||||||
|
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
||||||
|
RpmostreedSysroot *rsysroot = rpmostreed_sysroot_get ();
|
||||||
|
if (!rpmostreed_sysroot_prep_for_txn (rsysroot, invocation, &transaction, &local_error))
|
||||||
|
goto out;
|
||||||
if (transaction)
|
if (transaction)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -184,7 +165,7 @@ osexperimental_handle_live_fs (RPMOSTreeOSExperimental *interface,
|
|||||||
if (transaction == NULL)
|
if (transaction == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);
|
rpmostreed_sysroot_set_txn (rsysroot, transaction);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (local_error != NULL)
|
if (local_error != NULL)
|
||||||
@ -213,23 +194,18 @@ rpmostreed_osexperimental_iface_init (RPMOSTreeOSExperimentalIface *iface)
|
|||||||
RPMOSTreeOSExperimental *
|
RPMOSTreeOSExperimental *
|
||||||
rpmostreed_osexperimental_new (OstreeSysroot *sysroot,
|
rpmostreed_osexperimental_new (OstreeSysroot *sysroot,
|
||||||
OstreeRepo *repo,
|
OstreeRepo *repo,
|
||||||
const char *name,
|
const char *name)
|
||||||
RpmostreedTransactionMonitor *monitor)
|
|
||||||
{
|
{
|
||||||
RpmostreedOSExperimental *obj = NULL;
|
RpmostreedOSExperimental *obj = NULL;
|
||||||
g_autofree char *path = NULL;
|
g_autofree char *path = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (OSTREE_IS_SYSROOT (sysroot), NULL);
|
g_return_val_if_fail (OSTREE_IS_SYSROOT (sysroot), NULL);
|
||||||
g_return_val_if_fail (name != NULL, NULL);
|
g_return_val_if_fail (name != NULL, NULL);
|
||||||
g_return_val_if_fail (RPMOSTREED_IS_TRANSACTION_MONITOR (monitor), NULL);
|
|
||||||
|
|
||||||
path = rpmostreed_generate_object_path (BASE_DBUS_PATH, name, NULL);
|
path = rpmostreed_generate_object_path (BASE_DBUS_PATH, name, NULL);
|
||||||
|
|
||||||
obj = g_object_new (RPMOSTREED_TYPE_OSEXPERIMENTAL, NULL);
|
obj = g_object_new (RPMOSTREED_TYPE_OSEXPERIMENTAL, NULL);
|
||||||
|
|
||||||
/* FIXME Make this a construct-only property? */
|
|
||||||
obj->transaction_monitor = g_object_ref (monitor);
|
|
||||||
|
|
||||||
rpmostreed_daemon_publish (rpmostreed_daemon_get (), path, FALSE, obj);
|
rpmostreed_daemon_publish (rpmostreed_daemon_get (), path, FALSE, obj);
|
||||||
|
|
||||||
return RPMOSTREE_OSEXPERIMENTAL (obj);
|
return RPMOSTREE_OSEXPERIMENTAL (obj);
|
||||||
|
@ -27,5 +27,4 @@
|
|||||||
GType rpmostreed_osexperimental_get_type (void) G_GNUC_CONST;
|
GType rpmostreed_osexperimental_get_type (void) G_GNUC_CONST;
|
||||||
RPMOSTreeOSExperimental * rpmostreed_osexperimental_new (OstreeSysroot *sysroot,
|
RPMOSTreeOSExperimental * rpmostreed_osexperimental_new (OstreeSysroot *sysroot,
|
||||||
OstreeRepo *repo,
|
OstreeRepo *repo,
|
||||||
const char *name,
|
const char *name);
|
||||||
RpmostreedTransactionMonitor *monitor);
|
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
#include "rpmostreed-utils.h"
|
#include "rpmostreed-utils.h"
|
||||||
#include "rpmostree-util.h"
|
#include "rpmostree-util.h"
|
||||||
#include "rpmostreed-transaction.h"
|
#include "rpmostreed-transaction.h"
|
||||||
#include "rpmostreed-transaction-monitor.h"
|
|
||||||
#include "rpmostreed-transaction-types.h"
|
#include "rpmostreed-transaction-types.h"
|
||||||
|
|
||||||
typedef struct _RpmostreedOSClass RpmostreedOSClass;
|
typedef struct _RpmostreedOSClass RpmostreedOSClass;
|
||||||
@ -42,7 +41,6 @@ typedef struct _RpmostreedOSClass RpmostreedOSClass;
|
|||||||
struct _RpmostreedOS
|
struct _RpmostreedOS
|
||||||
{
|
{
|
||||||
RPMOSTreeOSSkeleton parent_instance;
|
RPMOSTreeOSSkeleton parent_instance;
|
||||||
RpmostreedTransactionMonitor *transaction_monitor;
|
|
||||||
gboolean on_session_bus;
|
gboolean on_session_bus;
|
||||||
guint signal_id;
|
guint signal_id;
|
||||||
};
|
};
|
||||||
@ -260,8 +258,6 @@ os_dispose (GObject *object)
|
|||||||
object_path, object);
|
object_path, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_clear_object (&self->transaction_monitor);
|
|
||||||
|
|
||||||
if (self->signal_id > 0)
|
if (self->signal_id > 0)
|
||||||
g_signal_handler_disconnect (rpmostreed_sysroot_get (), self->signal_id);
|
g_signal_handler_disconnect (rpmostreed_sysroot_get (), self->signal_id);
|
||||||
|
|
||||||
@ -448,23 +444,6 @@ out:
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RpmostreedTransaction *
|
|
||||||
merge_compatible_txn (RpmostreedOS *self,
|
|
||||||
GDBusMethodInvocation *invocation)
|
|
||||||
{
|
|
||||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
|
||||||
|
|
||||||
/* If a compatible transaction is in progress, share its bus address. */
|
|
||||||
transaction = rpmostreed_transaction_monitor_ref_active_transaction (self->transaction_monitor);
|
|
||||||
if (transaction != NULL)
|
|
||||||
{
|
|
||||||
if (rpmostreed_transaction_is_compatible (transaction, invocation))
|
|
||||||
return g_steal_pointer (&transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
refresh_cached_update (RpmostreedOS*, GError **error);
|
refresh_cached_update (RpmostreedOS*, GError **error);
|
||||||
|
|
||||||
@ -484,13 +463,16 @@ os_handle_download_update_rpm_diff (RPMOSTreeOS *interface,
|
|||||||
GDBusMethodInvocation *invocation)
|
GDBusMethodInvocation *invocation)
|
||||||
{
|
{
|
||||||
RpmostreedOS *self = RPMOSTREED_OS (interface);
|
RpmostreedOS *self = RPMOSTREED_OS (interface);
|
||||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
|
||||||
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
||||||
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
||||||
const char *osname;
|
const char *osname;
|
||||||
GError *local_error = NULL;
|
GError *local_error = NULL;
|
||||||
|
|
||||||
transaction = merge_compatible_txn (self, invocation);
|
/* try to merge with an existing transaction, otherwise start a new one */
|
||||||
|
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
||||||
|
RpmostreedSysroot *rsysroot = rpmostreed_sysroot_get ();
|
||||||
|
if (!rpmostreed_sysroot_prep_for_txn (rsysroot, invocation, &transaction, &local_error))
|
||||||
|
goto out;
|
||||||
if (transaction)
|
if (transaction)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -514,13 +496,13 @@ os_handle_download_update_rpm_diff (RPMOSTreeOS *interface,
|
|||||||
if (transaction == NULL)
|
if (transaction == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
rpmostreed_sysroot_set_txn (rsysroot, transaction);
|
||||||
|
|
||||||
/* Make sure we refresh CachedUpdate after the transaction. This normally happens
|
/* Make sure we refresh CachedUpdate after the transaction. This normally happens
|
||||||
* automatically if new data was downloaded (through the repo mtime bump --> UPDATED
|
* automatically if new data was downloaded (through the repo mtime bump --> UPDATED
|
||||||
* signal), but we also want to do this even if the data was already present. */
|
* signal), but we also want to do this even if the data was already present. */
|
||||||
g_signal_connect (transaction, "closed", G_CALLBACK (on_auto_update_done), self);
|
g_signal_connect (transaction, "closed", G_CALLBACK (on_auto_update_done), self);
|
||||||
|
|
||||||
rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (local_error != NULL)
|
if (local_error != NULL)
|
||||||
{
|
{
|
||||||
@ -576,9 +558,11 @@ os_merge_or_start_deployment_txn (RPMOSTreeOS *interface,
|
|||||||
g_autoptr(GError) local_error = NULL;
|
g_autoptr(GError) local_error = NULL;
|
||||||
|
|
||||||
/* try to merge with an existing transaction, otherwise start a new one */
|
/* try to merge with an existing transaction, otherwise start a new one */
|
||||||
|
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
||||||
|
RpmostreedSysroot *rsysroot = rpmostreed_sysroot_get ();
|
||||||
|
if (!rpmostreed_sysroot_prep_for_txn (rsysroot, invocation, &transaction, &local_error))
|
||||||
|
goto err;
|
||||||
|
|
||||||
glnx_unref_object RpmostreedTransaction *transaction =
|
|
||||||
merge_compatible_txn (self, invocation);
|
|
||||||
if (!transaction)
|
if (!transaction)
|
||||||
{
|
{
|
||||||
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
||||||
@ -594,7 +578,7 @@ os_merge_or_start_deployment_txn (RPMOSTreeOS *interface,
|
|||||||
if (!transaction)
|
if (!transaction)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);
|
rpmostreed_sysroot_set_txn (rsysroot, transaction);
|
||||||
|
|
||||||
/* For the AutomaticUpdateTrigger "check" case, we want to make sure we refresh
|
/* For the AutomaticUpdateTrigger "check" case, we want to make sure we refresh
|
||||||
* the CachedUpdate property; "stage" will do this through sysroot_changed */
|
* the CachedUpdate property; "stage" will do this through sysroot_changed */
|
||||||
@ -815,8 +799,6 @@ os_handle_rollback (RPMOSTreeOS *interface,
|
|||||||
GDBusMethodInvocation *invocation,
|
GDBusMethodInvocation *invocation,
|
||||||
GVariant *arg_options)
|
GVariant *arg_options)
|
||||||
{
|
{
|
||||||
RpmostreedOS *self = RPMOSTREED_OS (interface);
|
|
||||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
|
||||||
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
||||||
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
||||||
const char *osname;
|
const char *osname;
|
||||||
@ -824,7 +806,11 @@ os_handle_rollback (RPMOSTreeOS *interface,
|
|||||||
GVariantDict options_dict;
|
GVariantDict options_dict;
|
||||||
GError *local_error = NULL;
|
GError *local_error = NULL;
|
||||||
|
|
||||||
transaction = merge_compatible_txn (self, invocation);
|
/* try to merge with an existing transaction, otherwise start a new one */
|
||||||
|
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
||||||
|
RpmostreedSysroot *rsysroot = rpmostreed_sysroot_get ();
|
||||||
|
if (!rpmostreed_sysroot_prep_for_txn (rsysroot, invocation, &transaction, &local_error))
|
||||||
|
goto out;
|
||||||
if (transaction)
|
if (transaction)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -855,7 +841,7 @@ os_handle_rollback (RPMOSTreeOS *interface,
|
|||||||
if (transaction == NULL)
|
if (transaction == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);
|
rpmostreed_sysroot_set_txn (rsysroot, transaction);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (local_error != NULL)
|
if (local_error != NULL)
|
||||||
@ -877,8 +863,6 @@ os_handle_refresh_md (RPMOSTreeOS *interface,
|
|||||||
GDBusMethodInvocation *invocation,
|
GDBusMethodInvocation *invocation,
|
||||||
GVariant *arg_options)
|
GVariant *arg_options)
|
||||||
{
|
{
|
||||||
RpmostreedOS *self = RPMOSTREED_OS (interface);
|
|
||||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
|
||||||
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
||||||
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
||||||
const char *osname;
|
const char *osname;
|
||||||
@ -886,7 +870,11 @@ os_handle_refresh_md (RPMOSTreeOS *interface,
|
|||||||
RpmOstreeTransactionRefreshMdFlags flags = 0;
|
RpmOstreeTransactionRefreshMdFlags flags = 0;
|
||||||
g_auto(GVariantDict) dict;
|
g_auto(GVariantDict) dict;
|
||||||
|
|
||||||
transaction = merge_compatible_txn (self, invocation);
|
/* try to merge with an existing transaction, otherwise start a new one */
|
||||||
|
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
||||||
|
RpmostreedSysroot *rsysroot = rpmostreed_sysroot_get ();
|
||||||
|
if (!rpmostreed_sysroot_prep_for_txn (rsysroot, invocation, &transaction, &local_error))
|
||||||
|
goto out;
|
||||||
if (transaction)
|
if (transaction)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -912,7 +900,7 @@ os_handle_refresh_md (RPMOSTreeOS *interface,
|
|||||||
if (transaction == NULL)
|
if (transaction == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);
|
rpmostreed_sysroot_set_txn (rsysroot, transaction);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (local_error != NULL)
|
if (local_error != NULL)
|
||||||
@ -934,15 +922,17 @@ os_handle_clear_rollback_target (RPMOSTreeOS *interface,
|
|||||||
GDBusMethodInvocation *invocation,
|
GDBusMethodInvocation *invocation,
|
||||||
GVariant *arg_options)
|
GVariant *arg_options)
|
||||||
{
|
{
|
||||||
RpmostreedOS *self = RPMOSTREED_OS (interface);
|
|
||||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
|
||||||
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
||||||
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
||||||
RpmOstreeTransactionCleanupFlags flags = 0;
|
RpmOstreeTransactionCleanupFlags flags = 0;
|
||||||
const char *osname;
|
const char *osname;
|
||||||
GError *local_error = NULL;
|
GError *local_error = NULL;
|
||||||
|
|
||||||
transaction = merge_compatible_txn (self, invocation);
|
/* try to merge with an existing transaction, otherwise start a new one */
|
||||||
|
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
||||||
|
RpmostreedSysroot *rsysroot = rpmostreed_sysroot_get ();
|
||||||
|
if (!rpmostreed_sysroot_prep_for_txn (rsysroot, invocation, &transaction, &local_error))
|
||||||
|
goto out;
|
||||||
if (transaction)
|
if (transaction)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -963,7 +953,7 @@ os_handle_clear_rollback_target (RPMOSTreeOS *interface,
|
|||||||
if (transaction == NULL)
|
if (transaction == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);
|
rpmostreed_sysroot_set_txn (rsysroot, transaction);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (local_error != NULL)
|
if (local_error != NULL)
|
||||||
@ -986,8 +976,6 @@ os_handle_set_initramfs_state (RPMOSTreeOS *interface,
|
|||||||
const char *const*args,
|
const char *const*args,
|
||||||
GVariant *arg_options)
|
GVariant *arg_options)
|
||||||
{
|
{
|
||||||
RpmostreedOS *self = RPMOSTREED_OS (interface);
|
|
||||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
|
||||||
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
||||||
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
||||||
g_autoptr(GVariantDict) dict = NULL;
|
g_autoptr(GVariantDict) dict = NULL;
|
||||||
@ -995,7 +983,11 @@ os_handle_set_initramfs_state (RPMOSTreeOS *interface,
|
|||||||
gboolean reboot = FALSE;
|
gboolean reboot = FALSE;
|
||||||
GError *local_error = NULL;
|
GError *local_error = NULL;
|
||||||
|
|
||||||
transaction = merge_compatible_txn (self, invocation);
|
/* try to merge with an existing transaction, otherwise start a new one */
|
||||||
|
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
||||||
|
RpmostreedSysroot *rsysroot = rpmostreed_sysroot_get ();
|
||||||
|
if (!rpmostreed_sysroot_prep_for_txn (rsysroot, invocation, &transaction, &local_error))
|
||||||
|
goto out;
|
||||||
if (transaction)
|
if (transaction)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -1022,7 +1014,7 @@ os_handle_set_initramfs_state (RPMOSTreeOS *interface,
|
|||||||
if (transaction == NULL)
|
if (transaction == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);
|
rpmostreed_sysroot_set_txn (rsysroot, transaction);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (local_error != NULL)
|
if (local_error != NULL)
|
||||||
@ -1060,13 +1052,15 @@ os_handle_kernel_args (RPMOSTreeOS *interface,
|
|||||||
const char * const *kernel_args_deleted,
|
const char * const *kernel_args_deleted,
|
||||||
GVariant *arg_options)
|
GVariant *arg_options)
|
||||||
{
|
{
|
||||||
RpmostreedOS *self = RPMOSTREED_OS (interface);
|
|
||||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
|
||||||
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
||||||
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
||||||
GError *local_error = NULL;
|
GError *local_error = NULL;
|
||||||
|
|
||||||
transaction = merge_compatible_txn (self, invocation);
|
/* try to merge with an existing transaction, otherwise start a new one */
|
||||||
|
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
||||||
|
RpmostreedSysroot *rsysroot = rpmostreed_sysroot_get ();
|
||||||
|
if (!rpmostreed_sysroot_prep_for_txn (rsysroot, invocation, &transaction, &local_error))
|
||||||
|
goto out;
|
||||||
if (transaction)
|
if (transaction)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -1091,7 +1085,7 @@ os_handle_kernel_args (RPMOSTreeOS *interface,
|
|||||||
if (transaction == NULL)
|
if (transaction == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);
|
rpmostreed_sysroot_set_txn (rsysroot, transaction);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (local_error != NULL)
|
if (local_error != NULL)
|
||||||
@ -1195,15 +1189,17 @@ os_handle_cleanup (RPMOSTreeOS *interface,
|
|||||||
GDBusMethodInvocation *invocation,
|
GDBusMethodInvocation *invocation,
|
||||||
const char *const*args)
|
const char *const*args)
|
||||||
{
|
{
|
||||||
RpmostreedOS *self = RPMOSTREED_OS (interface);
|
|
||||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
|
||||||
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
||||||
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
||||||
RpmOstreeTransactionCleanupFlags flags = 0;
|
RpmOstreeTransactionCleanupFlags flags = 0;
|
||||||
const char *osname;
|
const char *osname;
|
||||||
GError *local_error = NULL;
|
GError *local_error = NULL;
|
||||||
|
|
||||||
transaction = merge_compatible_txn (self, invocation);
|
/* try to merge with an existing transaction, otherwise start a new one */
|
||||||
|
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
||||||
|
RpmostreedSysroot *rsysroot = rpmostreed_sysroot_get ();
|
||||||
|
if (!rpmostreed_sysroot_prep_for_txn (rsysroot, invocation, &transaction, &local_error))
|
||||||
|
goto out;
|
||||||
if (transaction)
|
if (transaction)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -1245,7 +1241,7 @@ os_handle_cleanup (RPMOSTreeOS *interface,
|
|||||||
if (transaction == NULL)
|
if (transaction == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);
|
rpmostreed_sysroot_set_txn (rsysroot, transaction);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (local_error != NULL)
|
if (local_error != NULL)
|
||||||
@ -1338,14 +1334,16 @@ os_handle_download_rebase_rpm_diff (RPMOSTreeOS *interface,
|
|||||||
const char * const *arg_packages)
|
const char * const *arg_packages)
|
||||||
{
|
{
|
||||||
/* TODO: Totally ignoring arg_packages for now */
|
/* TODO: Totally ignoring arg_packages for now */
|
||||||
RpmostreedOS *self = RPMOSTREED_OS (interface);
|
|
||||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
|
||||||
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
||||||
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
||||||
const char *osname;
|
const char *osname;
|
||||||
GError *local_error = NULL;
|
GError *local_error = NULL;
|
||||||
|
|
||||||
transaction = merge_compatible_txn (self, invocation);
|
/* try to merge with an existing transaction, otherwise start a new one */
|
||||||
|
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
||||||
|
RpmostreedSysroot *rsysroot = rpmostreed_sysroot_get ();
|
||||||
|
if (!rpmostreed_sysroot_prep_for_txn (rsysroot, invocation, &transaction, &local_error))
|
||||||
|
goto out;
|
||||||
if (transaction)
|
if (transaction)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -1369,7 +1367,7 @@ os_handle_download_rebase_rpm_diff (RPMOSTreeOS *interface,
|
|||||||
if (transaction == NULL)
|
if (transaction == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);
|
rpmostreed_sysroot_set_txn (rsysroot, transaction);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (local_error != NULL)
|
if (local_error != NULL)
|
||||||
@ -1475,8 +1473,6 @@ os_handle_download_deploy_rpm_diff (RPMOSTreeOS *interface,
|
|||||||
const char *arg_revision,
|
const char *arg_revision,
|
||||||
const char * const *arg_packages)
|
const char * const *arg_packages)
|
||||||
{
|
{
|
||||||
RpmostreedOS *self = RPMOSTREED_OS (interface);
|
|
||||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
|
||||||
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
||||||
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
|
||||||
const char *osname;
|
const char *osname;
|
||||||
@ -1484,7 +1480,11 @@ os_handle_download_deploy_rpm_diff (RPMOSTreeOS *interface,
|
|||||||
|
|
||||||
/* XXX Ignoring arg_packages for now. */
|
/* XXX Ignoring arg_packages for now. */
|
||||||
|
|
||||||
transaction = merge_compatible_txn (self, invocation);
|
/* try to merge with an existing transaction, otherwise start a new one */
|
||||||
|
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
||||||
|
RpmostreedSysroot *rsysroot = rpmostreed_sysroot_get ();
|
||||||
|
if (!rpmostreed_sysroot_prep_for_txn (rsysroot, invocation, &transaction, &local_error))
|
||||||
|
goto out;
|
||||||
if (transaction)
|
if (transaction)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -1507,7 +1507,7 @@ os_handle_download_deploy_rpm_diff (RPMOSTreeOS *interface,
|
|||||||
if (transaction == NULL)
|
if (transaction == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);
|
rpmostreed_sysroot_set_txn (rsysroot, transaction);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (local_error != NULL)
|
if (local_error != NULL)
|
||||||
@ -1693,23 +1693,18 @@ rpmostreed_os_iface_init (RPMOSTreeOSIface *iface)
|
|||||||
RPMOSTreeOS *
|
RPMOSTreeOS *
|
||||||
rpmostreed_os_new (OstreeSysroot *sysroot,
|
rpmostreed_os_new (OstreeSysroot *sysroot,
|
||||||
OstreeRepo *repo,
|
OstreeRepo *repo,
|
||||||
const char *name,
|
const char *name)
|
||||||
RpmostreedTransactionMonitor *monitor)
|
|
||||||
{
|
{
|
||||||
RpmostreedOS *obj = NULL;
|
RpmostreedOS *obj = NULL;
|
||||||
g_autofree char *path = NULL;
|
g_autofree char *path = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (OSTREE_IS_SYSROOT (sysroot), NULL);
|
g_return_val_if_fail (OSTREE_IS_SYSROOT (sysroot), NULL);
|
||||||
g_return_val_if_fail (name != NULL, NULL);
|
g_return_val_if_fail (name != NULL, NULL);
|
||||||
g_return_val_if_fail (RPMOSTREED_IS_TRANSACTION_MONITOR (monitor), NULL);
|
|
||||||
|
|
||||||
path = rpmostreed_generate_object_path (BASE_DBUS_PATH, name, NULL);
|
path = rpmostreed_generate_object_path (BASE_DBUS_PATH, name, NULL);
|
||||||
|
|
||||||
obj = g_object_new (RPMOSTREED_TYPE_OS, "name", name, NULL);
|
obj = g_object_new (RPMOSTREED_TYPE_OS, "name", name, NULL);
|
||||||
|
|
||||||
/* FIXME Make this a construct-only property? */
|
|
||||||
obj->transaction_monitor = g_object_ref (monitor);
|
|
||||||
|
|
||||||
/* FIXME - use GInitable */
|
/* FIXME - use GInitable */
|
||||||
{ g_autoptr(GError) local_error = NULL;
|
{ g_autoptr(GError) local_error = NULL;
|
||||||
if (!rpmostreed_os_load_internals (obj, &local_error))
|
if (!rpmostreed_os_load_internals (obj, &local_error))
|
||||||
|
@ -30,5 +30,4 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(RpmOstreeUpdateDeploymentModifiers, g_variant_unre
|
|||||||
GType rpmostreed_os_get_type (void) G_GNUC_CONST;
|
GType rpmostreed_os_get_type (void) G_GNUC_CONST;
|
||||||
RPMOSTreeOS * rpmostreed_os_new (OstreeSysroot *sysroot,
|
RPMOSTreeOS * rpmostreed_os_new (OstreeSysroot *sysroot,
|
||||||
OstreeRepo *repo,
|
OstreeRepo *repo,
|
||||||
const char *name,
|
const char *name);
|
||||||
RpmostreedTransactionMonitor *monitor);
|
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include "rpmostreed-deployment-utils.h"
|
#include "rpmostreed-deployment-utils.h"
|
||||||
#include "rpmostreed-errors.h"
|
#include "rpmostreed-errors.h"
|
||||||
#include "rpmostreed-transaction.h"
|
#include "rpmostreed-transaction.h"
|
||||||
#include "rpmostreed-transaction-monitor.h"
|
|
||||||
|
|
||||||
#include "rpmostree-output.h"
|
#include "rpmostree-output.h"
|
||||||
|
|
||||||
@ -39,6 +38,9 @@
|
|||||||
#include <systemd/sd-login.h>
|
#include <systemd/sd-login.h>
|
||||||
#include <systemd/sd-journal.h>
|
#include <systemd/sd-journal.h>
|
||||||
|
|
||||||
|
/* Avoid clients leaking their bus connections keeping the transaction open */
|
||||||
|
#define FORCE_CLOSE_TXN_TIMEOUT_SECS 30
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
sysroot_reload_ostree_configs_and_deployments (RpmostreedSysroot *self,
|
sysroot_reload_ostree_configs_and_deployments (RpmostreedSysroot *self,
|
||||||
gboolean *out_changed,
|
gboolean *out_changed,
|
||||||
@ -66,7 +68,8 @@ struct _RpmostreedSysroot {
|
|||||||
OstreeSysroot *ot_sysroot;
|
OstreeSysroot *ot_sysroot;
|
||||||
OstreeRepo *repo;
|
OstreeRepo *repo;
|
||||||
struct stat repo_last_stat;
|
struct stat repo_last_stat;
|
||||||
RpmostreedTransactionMonitor *transaction_monitor;
|
RpmostreedTransaction *transaction;
|
||||||
|
guint close_transaction_timeout_id;
|
||||||
PolkitAuthority *authority;
|
PolkitAuthority *authority;
|
||||||
gboolean on_session_bus;
|
gboolean on_session_bus;
|
||||||
|
|
||||||
@ -103,7 +106,6 @@ static void
|
|||||||
sysroot_output_cb (RpmOstreeOutputType type, void *data, void *opaque)
|
sysroot_output_cb (RpmOstreeOutputType type, void *data, void *opaque)
|
||||||
{
|
{
|
||||||
RpmostreedSysroot *self = RPMOSTREED_SYSROOT (opaque);
|
RpmostreedSysroot *self = RPMOSTREED_SYSROOT (opaque);
|
||||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
|
||||||
gboolean output_to_self = FALSE;
|
gboolean output_to_self = FALSE;
|
||||||
|
|
||||||
// The API previously passed these each time, but now we retain them as
|
// The API previously passed these each time, but now we retain them as
|
||||||
@ -112,22 +114,20 @@ sysroot_output_cb (RpmOstreeOutputType type, void *data, void *opaque)
|
|||||||
static bool progress_state_percent;
|
static bool progress_state_percent;
|
||||||
static guint progress_state_n_items;
|
static guint progress_state_n_items;
|
||||||
|
|
||||||
transaction =
|
if (self->transaction)
|
||||||
rpmostreed_transaction_monitor_ref_active_transaction (self->transaction_monitor);
|
g_object_get (self->transaction, "output-to-self", &output_to_self, NULL);
|
||||||
if (transaction)
|
|
||||||
g_object_get (transaction, "output-to-self", &output_to_self, NULL);
|
|
||||||
|
|
||||||
if (!transaction || output_to_self)
|
if (!self->transaction || output_to_self)
|
||||||
{
|
{
|
||||||
rpmostree_output_default_handler (type, data, opaque);
|
rpmostree_output_default_handler (type, data, opaque);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RPMOSTreeTransaction *transaction = RPMOSTREE_TRANSACTION (self->transaction);
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case RPMOSTREE_OUTPUT_MESSAGE:
|
case RPMOSTREE_OUTPUT_MESSAGE:
|
||||||
rpmostree_transaction_emit_message (RPMOSTREE_TRANSACTION (transaction),
|
rpmostree_transaction_emit_message (transaction, ((RpmOstreeOutputMessage*)data)->text);
|
||||||
((RpmOstreeOutputMessage*)data)->text);
|
|
||||||
break;
|
break;
|
||||||
case RPMOSTREE_OUTPUT_PROGRESS_BEGIN:
|
case RPMOSTREE_OUTPUT_PROGRESS_BEGIN:
|
||||||
{
|
{
|
||||||
@ -138,8 +138,7 @@ sysroot_output_cb (RpmOstreeOutputType type, void *data, void *opaque)
|
|||||||
if (begin->percent)
|
if (begin->percent)
|
||||||
{
|
{
|
||||||
progress_str = g_strdup (begin->prefix);
|
progress_str = g_strdup (begin->prefix);
|
||||||
rpmostree_transaction_emit_percent_progress (RPMOSTREE_TRANSACTION (transaction),
|
rpmostree_transaction_emit_percent_progress (transaction, progress_str, 0);
|
||||||
progress_str, 0);
|
|
||||||
progress_state_percent = true;
|
progress_state_percent = true;
|
||||||
}
|
}
|
||||||
else if (begin->n > 0)
|
else if (begin->n > 0)
|
||||||
@ -147,13 +146,11 @@ sysroot_output_cb (RpmOstreeOutputType type, void *data, void *opaque)
|
|||||||
progress_str = g_strdup (begin->prefix);
|
progress_str = g_strdup (begin->prefix);
|
||||||
progress_state_n_items = begin->n;
|
progress_state_n_items = begin->n;
|
||||||
/* For backcompat, this is a percentage. See below */
|
/* For backcompat, this is a percentage. See below */
|
||||||
rpmostree_transaction_emit_percent_progress (RPMOSTREE_TRANSACTION (transaction),
|
rpmostree_transaction_emit_percent_progress (transaction, progress_str, 0);
|
||||||
progress_str, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rpmostree_transaction_emit_task_begin (RPMOSTREE_TRANSACTION (transaction),
|
rpmostree_transaction_emit_task_begin (transaction, begin->prefix);
|
||||||
begin->prefix);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -169,11 +166,11 @@ sysroot_output_cb (RpmOstreeOutputType type, void *data, void *opaque)
|
|||||||
int percentage = (update->c == progress_state_n_items) ? 100 :
|
int percentage = (update->c == progress_state_n_items) ? 100 :
|
||||||
(((double)(update->c)) / (progress_state_n_items) * 100);
|
(((double)(update->c)) / (progress_state_n_items) * 100);
|
||||||
g_autofree char *newtext = g_strdup_printf ("%s (%u/%u)", progress_str, update->c, progress_state_n_items);
|
g_autofree char *newtext = g_strdup_printf ("%s (%u/%u)", progress_str, update->c, progress_state_n_items);
|
||||||
rpmostree_transaction_emit_percent_progress (RPMOSTREE_TRANSACTION (transaction), newtext, percentage);
|
rpmostree_transaction_emit_percent_progress (transaction, newtext, percentage);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rpmostree_transaction_emit_percent_progress (RPMOSTREE_TRANSACTION (transaction), progress_str, update->c);
|
rpmostree_transaction_emit_percent_progress (transaction, progress_str, update->c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -186,11 +183,11 @@ sysroot_output_cb (RpmOstreeOutputType type, void *data, void *opaque)
|
|||||||
{
|
{
|
||||||
if (progress_state_percent || progress_state_n_items > 0)
|
if (progress_state_percent || progress_state_n_items > 0)
|
||||||
{
|
{
|
||||||
rpmostree_transaction_emit_progress_end (RPMOSTREE_TRANSACTION (transaction));
|
rpmostree_transaction_emit_progress_end (transaction);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rpmostree_transaction_emit_task_end (RPMOSTREE_TRANSACTION (transaction), "done");
|
rpmostree_transaction_emit_task_end (transaction, "done");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -270,51 +267,6 @@ handle_get_os (RPMOSTreeSysroot *object,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
sysroot_transform_transaction_to_attrs (GBinding *binding,
|
|
||||||
const GValue *src_value,
|
|
||||||
GValue *dst_value,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
RpmostreedTransaction *transaction;
|
|
||||||
GVariant *variant;
|
|
||||||
const char *method_name = "";
|
|
||||||
const char *path = "";
|
|
||||||
const char *sender_name = "";
|
|
||||||
|
|
||||||
transaction = g_value_get_object (src_value);
|
|
||||||
|
|
||||||
if (transaction != NULL)
|
|
||||||
{
|
|
||||||
GDBusMethodInvocation *invocation;
|
|
||||||
|
|
||||||
invocation = rpmostreed_transaction_get_invocation (transaction);
|
|
||||||
method_name = g_dbus_method_invocation_get_method_name (invocation);
|
|
||||||
path = g_dbus_method_invocation_get_object_path (invocation);
|
|
||||||
sender_name = g_dbus_method_invocation_get_sender (invocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
variant = g_variant_new ("(sss)", method_name, sender_name, path);
|
|
||||||
|
|
||||||
g_value_set_variant (dst_value, variant);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
sysroot_transform_transaction_to_address (GBinding *binding,
|
|
||||||
const GValue *src_value,
|
|
||||||
GValue *dst_value,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
RpmostreedTransaction *transaction = g_value_get_object (src_value);
|
|
||||||
const char *address = "";
|
|
||||||
if (transaction != NULL)
|
|
||||||
address = rpmostreed_transaction_get_client_address (transaction);
|
|
||||||
g_value_set_string (dst_value, address);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
sysroot_populate_deployments_unlocked (RpmostreedSysroot *self,
|
sysroot_populate_deployments_unlocked (RpmostreedSysroot *self,
|
||||||
gboolean *out_changed,
|
gboolean *out_changed,
|
||||||
@ -386,13 +338,11 @@ sysroot_populate_deployments_unlocked (RpmostreedSysroot *self,
|
|||||||
if (!g_hash_table_contains (self->os_interfaces, deployment_os))
|
if (!g_hash_table_contains (self->os_interfaces, deployment_os))
|
||||||
{
|
{
|
||||||
RPMOSTreeOS *obj = rpmostreed_os_new (self->ot_sysroot, self->repo,
|
RPMOSTreeOS *obj = rpmostreed_os_new (self->ot_sysroot, self->repo,
|
||||||
deployment_os,
|
deployment_os);
|
||||||
self->transaction_monitor);
|
|
||||||
g_hash_table_insert (self->os_interfaces, g_strdup (deployment_os), obj);
|
g_hash_table_insert (self->os_interfaces, g_strdup (deployment_os), obj);
|
||||||
|
|
||||||
RPMOSTreeOSExperimental *eobj = rpmostreed_osexperimental_new (self->ot_sysroot, self->repo,
|
RPMOSTreeOSExperimental *eobj = rpmostreed_osexperimental_new (self->ot_sysroot, self->repo,
|
||||||
deployment_os,
|
deployment_os);
|
||||||
self->transaction_monitor);
|
|
||||||
g_hash_table_insert (self->osexperimental_interfaces, g_strdup (deployment_os), eobj);
|
g_hash_table_insert (self->osexperimental_interfaces, g_strdup (deployment_os), eobj);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -569,7 +519,7 @@ sysroot_dispose (GObject *object)
|
|||||||
g_hash_table_remove_all (self->os_interfaces);
|
g_hash_table_remove_all (self->os_interfaces);
|
||||||
g_hash_table_remove_all (self->osexperimental_interfaces);
|
g_hash_table_remove_all (self->osexperimental_interfaces);
|
||||||
|
|
||||||
g_clear_object (&self->transaction_monitor);
|
g_clear_object (&self->transaction);
|
||||||
g_clear_object (&self->authority);
|
g_clear_object (&self->authority);
|
||||||
|
|
||||||
G_OBJECT_CLASS (rpmostreed_sysroot_parent_class)->dispose (object);
|
G_OBJECT_CLASS (rpmostreed_sysroot_parent_class)->dispose (object);
|
||||||
@ -604,8 +554,6 @@ rpmostreed_sysroot_init (RpmostreedSysroot *self)
|
|||||||
|
|
||||||
self->monitor = NULL;
|
self->monitor = NULL;
|
||||||
|
|
||||||
self->transaction_monitor = rpmostreed_transaction_monitor_new ();
|
|
||||||
|
|
||||||
if (g_getenv ("RPMOSTREE_USE_SESSION_BUS") != NULL)
|
if (g_getenv ("RPMOSTREE_USE_SESSION_BUS") != NULL)
|
||||||
self->on_session_bus = TRUE;
|
self->on_session_bus = TRUE;
|
||||||
|
|
||||||
@ -623,35 +571,6 @@ rpmostreed_sysroot_init (RpmostreedSysroot *self)
|
|||||||
rpmostree_output_set_callback (sysroot_output_cb, self);
|
rpmostree_output_set_callback (sysroot_output_cb, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
sysroot_constructed (GObject *object)
|
|
||||||
{
|
|
||||||
RpmostreedSysroot *self = RPMOSTREED_SYSROOT (object);
|
|
||||||
|
|
||||||
g_object_bind_property_full (self->transaction_monitor,
|
|
||||||
"active-transaction",
|
|
||||||
self,
|
|
||||||
"active-transaction",
|
|
||||||
G_BINDING_DEFAULT |
|
|
||||||
G_BINDING_SYNC_CREATE,
|
|
||||||
sysroot_transform_transaction_to_attrs,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
g_object_bind_property_full (self->transaction_monitor,
|
|
||||||
"active-transaction",
|
|
||||||
self,
|
|
||||||
"active-transaction-path",
|
|
||||||
G_BINDING_DEFAULT |
|
|
||||||
G_BINDING_SYNC_CREATE,
|
|
||||||
sysroot_transform_transaction_to_address,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (rpmostreed_sysroot_parent_class)->constructed (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
sysroot_authorize_method (GDBusInterfaceSkeleton *interface,
|
sysroot_authorize_method (GDBusInterfaceSkeleton *interface,
|
||||||
GDBusMethodInvocation *invocation)
|
GDBusMethodInvocation *invocation)
|
||||||
@ -751,7 +670,6 @@ rpmostreed_sysroot_class_init (RpmostreedSysrootClass *klass)
|
|||||||
gobject_class = G_OBJECT_CLASS (klass);
|
gobject_class = G_OBJECT_CLASS (klass);
|
||||||
gobject_class->dispose = sysroot_dispose;
|
gobject_class->dispose = sysroot_dispose;
|
||||||
gobject_class->finalize = sysroot_finalize;
|
gobject_class->finalize = sysroot_finalize;
|
||||||
gobject_class->constructed = sysroot_constructed;
|
|
||||||
|
|
||||||
signals[UPDATED] = g_signal_new ("updated",
|
signals[UPDATED] = g_signal_new ("updated",
|
||||||
RPMOSTREED_TYPE_SYSROOT,
|
RPMOSTREED_TYPE_SYSROOT,
|
||||||
@ -903,6 +821,108 @@ rpmostreed_sysroot_load_state (RpmostreedSysroot *self,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
rpmostreed_sysroot_prep_for_txn (RpmostreedSysroot *self,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
RpmostreedTransaction **out_compat_txn,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
if (self->transaction)
|
||||||
|
{
|
||||||
|
if (rpmostreed_transaction_is_compatible (self->transaction, invocation))
|
||||||
|
{
|
||||||
|
*out_compat_txn = g_object_ref (self->transaction);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
const char *title = rpmostree_transaction_get_title ((RPMOSTreeTransaction*)(self->transaction));
|
||||||
|
return glnx_throw (error, "Transaction in progress: %s", title);
|
||||||
|
}
|
||||||
|
*out_compat_txn = NULL;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
rpmostreed_sysroot_has_txn (RpmostreedSysroot *self)
|
||||||
|
{
|
||||||
|
return self->transaction != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
on_force_close (gpointer data)
|
||||||
|
{
|
||||||
|
RpmostreedSysroot *self = data;
|
||||||
|
|
||||||
|
if (self->transaction)
|
||||||
|
{
|
||||||
|
rpmostreed_transaction_force_close (self->transaction);
|
||||||
|
rpmostreed_sysroot_set_txn (self, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_txn_executed_changed (GObject *object,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
RpmostreedSysroot *self = user_data;
|
||||||
|
gboolean executed;
|
||||||
|
g_object_get (object, "executed", &executed, NULL);
|
||||||
|
if (executed && self->close_transaction_timeout_id == 0)
|
||||||
|
{
|
||||||
|
self->close_transaction_timeout_id =
|
||||||
|
g_timeout_add_seconds (FORCE_CLOSE_TXN_TIMEOUT_SECS, on_force_close, self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rpmostreed_sysroot_set_txn (RpmostreedSysroot *self,
|
||||||
|
RpmostreedTransaction *txn)
|
||||||
|
{
|
||||||
|
/* If the transaction is changing, clear the timer */
|
||||||
|
if (self->close_transaction_timeout_id > 0)
|
||||||
|
{
|
||||||
|
g_source_remove (self->close_transaction_timeout_id);
|
||||||
|
self->close_transaction_timeout_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txn != NULL)
|
||||||
|
{
|
||||||
|
g_assert (self->transaction == NULL);
|
||||||
|
self->transaction = g_object_ref (txn);
|
||||||
|
|
||||||
|
g_signal_connect (self->transaction, "notify::executed",
|
||||||
|
G_CALLBACK (on_txn_executed_changed), self);
|
||||||
|
|
||||||
|
GDBusMethodInvocation *invocation = rpmostreed_transaction_get_invocation (self->transaction);
|
||||||
|
g_autoptr(GVariant) v = g_variant_ref_sink (g_variant_new ("(sss)",
|
||||||
|
g_dbus_method_invocation_get_method_name (invocation),
|
||||||
|
g_dbus_method_invocation_get_object_path (invocation),
|
||||||
|
g_dbus_method_invocation_get_sender (invocation)));
|
||||||
|
rpmostree_sysroot_set_active_transaction ((RPMOSTreeSysroot*)self, v);
|
||||||
|
rpmostree_sysroot_set_active_transaction_path ((RPMOSTreeSysroot*)self,
|
||||||
|
rpmostreed_transaction_get_client_address (self->transaction));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_assert (self->transaction);
|
||||||
|
g_clear_object (&self->transaction);
|
||||||
|
|
||||||
|
g_autoptr(GVariant) v = g_variant_ref_sink (g_variant_new ("(sss)", "", "", ""));
|
||||||
|
rpmostree_sysroot_set_active_transaction ((RPMOSTreeSysroot *)self, v);
|
||||||
|
rpmostree_sysroot_set_active_transaction_path ((RPMOSTreeSysroot *)self, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rpmostreed_sysroot_finish_txn (RpmostreedSysroot *self,
|
||||||
|
RpmostreedTransaction *txn)
|
||||||
|
{
|
||||||
|
g_assert (self->transaction == txn);
|
||||||
|
rpmostreed_sysroot_set_txn (self, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
OstreeSysroot *
|
OstreeSysroot *
|
||||||
rpmostreed_sysroot_get_root (RpmostreedSysroot *self)
|
rpmostreed_sysroot_get_root (RpmostreedSysroot *self)
|
||||||
{
|
{
|
||||||
|
@ -49,4 +49,17 @@ gboolean rpmostreed_sysroot_load_state (RpmostreedSysroot *self
|
|||||||
OstreeRepo **out_repo,
|
OstreeRepo **out_repo,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
gboolean rpmostreed_sysroot_prep_for_txn (RpmostreedSysroot *self,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
RpmostreedTransaction **out_compat_txn,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
gboolean rpmostreed_sysroot_has_txn (RpmostreedSysroot *self);
|
||||||
|
|
||||||
|
void rpmostreed_sysroot_finish_txn (RpmostreedSysroot *self,
|
||||||
|
RpmostreedTransaction *txn);
|
||||||
|
|
||||||
|
void rpmostreed_sysroot_set_txn (RpmostreedSysroot *self,
|
||||||
|
RpmostreedTransaction *txn);
|
||||||
|
|
||||||
void rpmostreed_sysroot_emit_update (RpmostreedSysroot *self);
|
void rpmostreed_sysroot_emit_update (RpmostreedSysroot *self);
|
||||||
|
@ -1,204 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2015 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This program 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 program 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 program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "rpmostreed-transaction-monitor.h"
|
|
||||||
|
|
||||||
#include <libglnx.h>
|
|
||||||
|
|
||||||
#include "rpmostreed-transaction.h"
|
|
||||||
|
|
||||||
typedef struct _RpmostreedTransactionMonitorClass RpmostreedTransactionMonitorClass;
|
|
||||||
|
|
||||||
struct _RpmostreedTransactionMonitor {
|
|
||||||
GObjectClass parent;
|
|
||||||
|
|
||||||
/* The head of the queue is the active transaction. */
|
|
||||||
GQueue *transactions;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _RpmostreedTransactionMonitorClass {
|
|
||||||
GObjectClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PROP_0,
|
|
||||||
PROP_ACTIVE_TRANSACTION
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (RpmostreedTransactionMonitor,
|
|
||||||
rpmostreed_transaction_monitor,
|
|
||||||
G_TYPE_OBJECT)
|
|
||||||
|
|
||||||
static void
|
|
||||||
transaction_monitor_remove_transaction (RpmostreedTransactionMonitor *monitor,
|
|
||||||
RPMOSTreeTransaction *transaction)
|
|
||||||
{
|
|
||||||
GList *link;
|
|
||||||
|
|
||||||
link = g_queue_find (monitor->transactions, transaction);
|
|
||||||
|
|
||||||
if (link != NULL)
|
|
||||||
{
|
|
||||||
GList *head;
|
|
||||||
gboolean need_notify;
|
|
||||||
|
|
||||||
/* The head of the queue is the active transaction. */
|
|
||||||
head = g_queue_peek_head_link (monitor->transactions);
|
|
||||||
need_notify = (link == head);
|
|
||||||
|
|
||||||
g_object_unref (link->data);
|
|
||||||
g_queue_delete_link (monitor->transactions, link);
|
|
||||||
|
|
||||||
if (need_notify)
|
|
||||||
{
|
|
||||||
/* Issue a notification so property bindings get updated. */
|
|
||||||
g_object_notify (G_OBJECT (monitor), "active-transaction");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
transaction_monitor_notify_active_cb (RPMOSTreeTransaction *transaction,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
RpmostreedTransactionMonitor *monitor)
|
|
||||||
{
|
|
||||||
GList *head, *link;
|
|
||||||
|
|
||||||
/* The head of the queue is the active transaction. */
|
|
||||||
head = g_queue_peek_head_link (monitor->transactions);
|
|
||||||
link = g_queue_find (monitor->transactions, transaction);
|
|
||||||
|
|
||||||
if (link == head)
|
|
||||||
{
|
|
||||||
/* Issue a notification so property bindings get updated. */
|
|
||||||
g_object_notify (G_OBJECT (monitor), "active-transaction");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
transaction_monitor_closed_cb (RPMOSTreeTransaction *transaction,
|
|
||||||
RpmostreedTransactionMonitor *monitor)
|
|
||||||
{
|
|
||||||
transaction_monitor_remove_transaction (monitor, transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
transaction_monitor_get_property (GObject *object,
|
|
||||||
guint property_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
RpmostreedTransactionMonitor *monitor = RPMOSTREED_TRANSACTION_MONITOR (object);
|
|
||||||
gpointer v_object;
|
|
||||||
|
|
||||||
switch (property_id)
|
|
||||||
{
|
|
||||||
case PROP_ACTIVE_TRANSACTION:
|
|
||||||
v_object = rpmostreed_transaction_monitor_ref_active_transaction (monitor);
|
|
||||||
g_value_take_object (value, v_object);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
transaction_monitor_dispose (GObject *object)
|
|
||||||
{
|
|
||||||
RpmostreedTransactionMonitor *monitor = RPMOSTREED_TRANSACTION_MONITOR (object);
|
|
||||||
|
|
||||||
g_queue_free_full (monitor->transactions, (GDestroyNotify) g_object_unref);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (rpmostreed_transaction_monitor_parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
rpmostreed_transaction_monitor_class_init (RpmostreedTransactionMonitorClass *class)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class;
|
|
||||||
|
|
||||||
object_class = G_OBJECT_CLASS (class);
|
|
||||||
object_class->get_property = transaction_monitor_get_property;
|
|
||||||
object_class->dispose = transaction_monitor_dispose;
|
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
|
||||||
PROP_ACTIVE_TRANSACTION,
|
|
||||||
g_param_spec_object ("active-transaction",
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
RPMOSTREED_TYPE_TRANSACTION,
|
|
||||||
G_PARAM_READABLE |
|
|
||||||
G_PARAM_STATIC_STRINGS));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
rpmostreed_transaction_monitor_init (RpmostreedTransactionMonitor *monitor)
|
|
||||||
{
|
|
||||||
monitor->transactions = g_queue_new ();
|
|
||||||
}
|
|
||||||
|
|
||||||
RpmostreedTransactionMonitor *
|
|
||||||
rpmostreed_transaction_monitor_new (void)
|
|
||||||
{
|
|
||||||
return g_object_new (RPMOSTREED_TYPE_TRANSACTION_MONITOR, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rpmostreed_transaction_monitor_add (RpmostreedTransactionMonitor *monitor,
|
|
||||||
RpmostreedTransaction *transaction)
|
|
||||||
{
|
|
||||||
g_return_if_fail (RPMOSTREED_IS_TRANSACTION_MONITOR (monitor));
|
|
||||||
g_return_if_fail (RPMOSTREED_IS_TRANSACTION (transaction));
|
|
||||||
|
|
||||||
g_signal_connect_object (transaction, "notify::active",
|
|
||||||
G_CALLBACK (transaction_monitor_notify_active_cb),
|
|
||||||
monitor, 0);
|
|
||||||
|
|
||||||
g_signal_connect_object (transaction, "closed",
|
|
||||||
G_CALLBACK (transaction_monitor_closed_cb),
|
|
||||||
monitor, 0);
|
|
||||||
|
|
||||||
g_queue_push_head (monitor->transactions, g_object_ref (transaction));
|
|
||||||
g_object_notify (G_OBJECT (monitor), "active-transaction");
|
|
||||||
}
|
|
||||||
|
|
||||||
RpmostreedTransaction *
|
|
||||||
rpmostreed_transaction_monitor_ref_active_transaction (RpmostreedTransactionMonitor *monitor)
|
|
||||||
{
|
|
||||||
RpmostreedTransaction *transaction;
|
|
||||||
|
|
||||||
g_return_val_if_fail (RPMOSTREED_IS_TRANSACTION_MONITOR (monitor), NULL);
|
|
||||||
|
|
||||||
/* The head of the queue is the active transaction. */
|
|
||||||
transaction = g_queue_peek_head (monitor->transactions);
|
|
||||||
|
|
||||||
if (transaction != NULL)
|
|
||||||
{
|
|
||||||
/* An "inactive" transaction has completed its task
|
|
||||||
* and does not block other transactions from starting. */
|
|
||||||
if (rpmostreed_transaction_get_active (transaction))
|
|
||||||
g_object_ref (transaction);
|
|
||||||
else
|
|
||||||
transaction = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return transaction;
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2015 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This program 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 program 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 program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ostree.h"
|
|
||||||
#include "rpmostreed-types.h"
|
|
||||||
|
|
||||||
#define RPMOSTREED_TYPE_TRANSACTION_MONITOR (rpmostreed_transaction_monitor_get_type ())
|
|
||||||
#define RPMOSTREED_TRANSACTION_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), RPMOSTREED_TYPE_TRANSACTION_MONITOR, RpmostreedTransactionMonitor))
|
|
||||||
#define RPMOSTREED_IS_TRANSACTION_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), RPMOSTREED_TYPE_TRANSACTION_MONITOR))
|
|
||||||
|
|
||||||
GType rpmostreed_transaction_monitor_get_type (void) G_GNUC_CONST;
|
|
||||||
RpmostreedTransactionMonitor *
|
|
||||||
rpmostreed_transaction_monitor_new (void);
|
|
||||||
void rpmostreed_transaction_monitor_add (RpmostreedTransactionMonitor *monitor,
|
|
||||||
RpmostreedTransaction *transaction);
|
|
||||||
RpmostreedTransaction *
|
|
||||||
rpmostreed_transaction_monitor_ref_active_transaction
|
|
||||||
(RpmostreedTransactionMonitor *monitor);
|
|
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
struct _RpmostreedTransactionPrivate {
|
struct _RpmostreedTransactionPrivate {
|
||||||
GDBusMethodInvocation *invocation;
|
GDBusMethodInvocation *invocation;
|
||||||
|
gboolean executed; /* TRUE if the transaction has completed (successfully or not) */
|
||||||
GCancellable *cancellable;
|
GCancellable *cancellable;
|
||||||
|
|
||||||
/* For the duration of the transaction, we hold a ref to a new
|
/* For the duration of the transaction, we hold a ref to a new
|
||||||
@ -50,7 +51,7 @@ struct _RpmostreedTransactionPrivate {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_ACTIVE,
|
PROP_EXECUTED,
|
||||||
PROP_INVOCATION,
|
PROP_INVOCATION,
|
||||||
PROP_SYSROOT_PATH,
|
PROP_SYSROOT_PATH,
|
||||||
PROP_REDIRECT_OUTPUT
|
PROP_REDIRECT_OUTPUT
|
||||||
@ -98,6 +99,8 @@ transaction_maybe_emit_closed (RpmostreedTransaction *self)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
g_signal_emit (self, signals[CLOSED], 0);
|
g_signal_emit (self, signals[CLOSED], 0);
|
||||||
|
|
||||||
|
rpmostreed_sysroot_finish_txn (rpmostreed_sysroot_get (), self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -365,7 +368,8 @@ transaction_execute_done_cb (GObject *source_object,
|
|||||||
priv->finished_params = g_variant_new ("(bs)", success, error_message);
|
priv->finished_params = g_variant_new ("(bs)", success, error_message);
|
||||||
g_variant_ref_sink (priv->finished_params);
|
g_variant_ref_sink (priv->finished_params);
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (self), "active");
|
priv->executed = TRUE;
|
||||||
|
g_object_notify (G_OBJECT (self), "executed");
|
||||||
|
|
||||||
transaction_maybe_emit_closed (self);
|
transaction_maybe_emit_closed (self);
|
||||||
}
|
}
|
||||||
@ -416,6 +420,9 @@ transaction_get_property (GObject *object,
|
|||||||
case PROP_REDIRECT_OUTPUT:
|
case PROP_REDIRECT_OUTPUT:
|
||||||
g_value_set_boolean (value, priv->redirect_output);
|
g_value_set_boolean (value, priv->redirect_output);
|
||||||
break;
|
break;
|
||||||
|
case PROP_EXECUTED:
|
||||||
|
g_value_set_boolean (value, priv->executed);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -428,9 +435,6 @@ transaction_dispose (GObject *object)
|
|||||||
RpmostreedTransaction *self = RPMOSTREED_TRANSACTION (object);
|
RpmostreedTransaction *self = RPMOSTREED_TRANSACTION (object);
|
||||||
RpmostreedTransactionPrivate *priv = rpmostreed_transaction_get_private (self);
|
RpmostreedTransactionPrivate *priv = rpmostreed_transaction_get_private (self);
|
||||||
|
|
||||||
if (priv->sysroot != NULL)
|
|
||||||
ostree_sysroot_unlock (priv->sysroot);
|
|
||||||
|
|
||||||
g_hash_table_remove_all (priv->peer_connections);
|
g_hash_table_remove_all (priv->peer_connections);
|
||||||
|
|
||||||
g_clear_object (&priv->invocation);
|
g_clear_object (&priv->invocation);
|
||||||
@ -452,6 +456,9 @@ transaction_finalize (GObject *object)
|
|||||||
|
|
||||||
g_debug ("%s (%p): Finalized", G_OBJECT_TYPE_NAME (self), self);
|
g_debug ("%s (%p): Finalized", G_OBJECT_TYPE_NAME (self), self);
|
||||||
|
|
||||||
|
if (priv->sysroot != NULL)
|
||||||
|
ostree_sysroot_unlock (priv->sysroot);
|
||||||
|
|
||||||
if (priv->watch_id > 0)
|
if (priv->watch_id > 0)
|
||||||
g_bus_unwatch_name (priv->watch_id);
|
g_bus_unwatch_name (priv->watch_id);
|
||||||
|
|
||||||
@ -490,6 +497,25 @@ transaction_constructed (GObject *object)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
foreach_close_peer (gpointer key,
|
||||||
|
gpointer value,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GDBusConnection *conn = key;
|
||||||
|
g_dbus_connection_close_sync (conn, NULL, NULL);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rpmostreed_transaction_force_close (RpmostreedTransaction *transaction)
|
||||||
|
{
|
||||||
|
RpmostreedTransactionPrivate *priv = rpmostreed_transaction_get_private (transaction);
|
||||||
|
g_assert (priv->executed);
|
||||||
|
g_dbus_server_stop (priv->server);
|
||||||
|
g_hash_table_foreach_remove (priv->peer_connections, foreach_close_peer, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_sysroot_journal_msg (OstreeSysroot *sysroot,
|
on_sysroot_journal_msg (OstreeSysroot *sysroot,
|
||||||
const char *msg,
|
const char *msg,
|
||||||
@ -663,11 +689,11 @@ rpmostreed_transaction_class_init (RpmostreedTransactionClass *class)
|
|||||||
object_class->constructed = transaction_constructed;
|
object_class->constructed = transaction_constructed;
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
g_object_class_install_property (object_class,
|
||||||
PROP_ACTIVE,
|
PROP_EXECUTED,
|
||||||
g_param_spec_boolean ("active",
|
g_param_spec_boolean ("executed",
|
||||||
"Active",
|
"Executed",
|
||||||
"Whether the transaction is active (unfinished)",
|
"Whether the transaction has finished",
|
||||||
TRUE,
|
FALSE,
|
||||||
G_PARAM_READABLE |
|
G_PARAM_READABLE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
@ -724,6 +750,7 @@ rpmostreed_transaction_dbus_iface_init (RPMOSTreeTransactionIface *iface)
|
|||||||
static void
|
static void
|
||||||
rpmostreed_transaction_init (RpmostreedTransaction *self)
|
rpmostreed_transaction_init (RpmostreedTransaction *self)
|
||||||
{
|
{
|
||||||
|
g_assert (!rpmostreed_sysroot_has_txn (rpmostreed_sysroot_get ()));
|
||||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||||
RPMOSTREED_TYPE_TRANSACTION,
|
RPMOSTREED_TYPE_TRANSACTION,
|
||||||
RpmostreedTransactionPrivate);
|
RpmostreedTransactionPrivate);
|
||||||
|
@ -56,3 +56,4 @@ void rpmostreed_transaction_connect_download_progress
|
|||||||
void rpmostreed_transaction_connect_signature_progress
|
void rpmostreed_transaction_connect_signature_progress
|
||||||
(RpmostreedTransaction *transaction,
|
(RpmostreedTransaction *transaction,
|
||||||
OstreeRepo *repo);
|
OstreeRepo *repo);
|
||||||
|
void rpmostreed_transaction_force_close (RpmostreedTransaction *transaction);
|
||||||
|
@ -39,6 +39,3 @@ typedef struct _RpmostreedOSExperimental RpmostreedOSExperimental;
|
|||||||
|
|
||||||
struct _RpmostreedTransaction;
|
struct _RpmostreedTransaction;
|
||||||
typedef struct _RpmostreedTransaction RpmostreedTransaction;
|
typedef struct _RpmostreedTransaction RpmostreedTransaction;
|
||||||
|
|
||||||
struct _RpmostreedTransactionMonitor;
|
|
||||||
typedef struct _RpmostreedTransactionMonitor RpmostreedTransactionMonitor;
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user