PackageKit/master.patch

805 lines
25 KiB
Diff

commit 09c9cde8c0cfec3a5f4320ec10bf2e1b0f9b460f
Author: Richard Hughes <richard@hughsie.com>
Date: Thu Jan 23 13:46:49 2014 +0000
hawkey: Fix installing i386 packages on a 64bit computer
diff --git a/backends/hawkey/pk-backend-hawkey.c b/backends/hawkey/pk-backend-hawkey.c
index f2ee746..b069396 100644
--- a/backends/hawkey/pk-backend-hawkey.c
+++ b/backends/hawkey/pk-backend-hawkey.c
@@ -3196,10 +3196,12 @@ out:
}
/**
- * hif_is_installed_package_name:
+ * hif_is_installed_package_name_arch:
*/
static gboolean
-hif_is_installed_package_name (HySack sack, const gchar *name)
+hif_is_installed_package_name_arch (HySack sack,
+ const gchar *name,
+ const gchar *arch)
{
gboolean ret;
HyPackageList pkglist = NULL;
@@ -3208,6 +3210,7 @@ hif_is_installed_package_name (HySack sack, const gchar *name)
/* run query */
query = hy_query_create (sack);
hy_query_filter (query, HY_PKG_NAME, HY_EQ, name);
+ hy_query_filter (query, HY_PKG_ARCH, HY_EQ, arch);
hy_query_filter (query, HY_PKG_REPONAME, HY_EQ, HY_SYSTEM_REPO_NAME);
pkglist = hy_query_run (query);
@@ -3228,7 +3231,9 @@ hif_is_installed_package_id (HySack sack, const gchar *package_id)
gboolean ret;
gchar **split;
split = pk_package_id_split (package_id);
- ret = hif_is_installed_package_name (sack, split[PK_PACKAGE_ID_NAME]);
+ ret = hif_is_installed_package_name_arch (sack,
+ split[PK_PACKAGE_ID_NAME],
+ split[PK_PACKAGE_ID_ARCH]);
g_strfreev (split);
return ret;
}
commit 5776000231f81f7d0d764038a9957439c35a7a5d
Author: Richard Hughes <richard@hughsie.com>
Date: Thu Jan 23 14:25:55 2014 +0000
hawkey: Release locks early if the state fails
diff --git a/backends/hawkey/hif-lock.c b/backends/hawkey/hif-lock.c
index 97066f4..a644330 100644
--- a/backends/hawkey/hif-lock.c
+++ b/backends/hawkey/hif-lock.c
@@ -91,6 +91,19 @@ hif_lock_type_to_string (HifLockType lock_type)
}
/**
+ * hif_lock_mode_to_string:
+ **/
+static const gchar *
+hif_lock_mode_to_string (HifLockMode lock_mode)
+{
+ if (lock_mode == HIF_LOCK_MODE_THREAD)
+ return "thread";
+ if (lock_mode == HIF_LOCK_MODE_PROCESS)
+ return "process";
+ return "unknown";
+}
+
+/**
* hif_lock_get_item_by_type_mode:
**/
static HifLockItem *
@@ -337,7 +350,9 @@ hif_lock_take (HifLock *lock,
g_set_error (error,
HIF_ERROR,
PK_ERROR_ENUM_CANNOT_GET_LOCK,
- "already locked by %s",
+ "%s[%s] already locked by %s",
+ hif_lock_type_to_string (type),
+ hif_lock_mode_to_string (mode),
cmdline);
goto out;
}
@@ -520,7 +535,7 @@ hif_lock_finalize (GObject *object)
if (item->refcount > 0) {
g_warning ("held lock %s at shutdown",
hif_lock_type_to_string (item->type));
- hif_lock_release (lock, item->type, NULL);
+ hif_lock_release (lock, item->id, NULL);
}
}
diff --git a/backends/hawkey/hif-source.c b/backends/hawkey/hif-source.c
index b79f525..fffcc31 100644
--- a/backends/hawkey/hif-source.c
+++ b/backends/hawkey/hif-source.c
@@ -695,6 +695,7 @@ hif_source_update (HifSource *src,
if (!ret)
goto out;
out:
+ hif_state_release_locks (state);
lr_handle_setopt (src->repo_handle, NULL, LRO_PROGRESSCB, NULL);
lr_handle_setopt (src->repo_handle, NULL, LRO_PROGRESSDATA, 0xdeadbeef);
return ret;
diff --git a/backends/hawkey/hif-state.c b/backends/hawkey/hif-state.c
index 6cd706f..fc6753c 100644
--- a/backends/hawkey/hif-state.c
+++ b/backends/hawkey/hif-state.c
@@ -273,13 +273,17 @@ hif_state_set_speed (HifState *state, guint64 speed)
/**
* hif_state_release_locks:
**/
-static gboolean
+gboolean
hif_state_release_locks (HifState *state)
{
gboolean ret = TRUE;
guint i;
guint lock_id;
+ /* release children first */
+ if (state->priv->child != NULL)
+ hif_state_release_locks (state->priv->child);
+
/* release each one */
for (i = 0; i < state->priv->lock_ids->len; i++) {
lock_id = GPOINTER_TO_UINT (g_ptr_array_index (state->priv->lock_ids, i));
diff --git a/backends/hawkey/hif-state.h b/backends/hawkey/hif-state.h
index ffd42e9..b7b26f4 100644
--- a/backends/hawkey/hif-state.h
+++ b/backends/hawkey/hif-state.h
@@ -131,6 +131,7 @@ gboolean hif_state_take_lock (HifState *state,
HifLockType lock_type,
HifLockMode lock_mode,
GError **error);
+gboolean hif_state_release_locks (HifState *state);
G_END_DECLS
diff --git a/backends/hawkey/pk-backend-hawkey.c b/backends/hawkey/pk-backend-hawkey.c
index b069396..40831b9 100644
--- a/backends/hawkey/pk-backend-hawkey.c
+++ b/backends/hawkey/pk-backend-hawkey.c
@@ -521,8 +521,10 @@ pk_backend_stop_job (PkBackend *backend, PkBackendJob *job)
PkBackendHifJobData *job_data = pk_backend_job_get_user_data (job);
g_object_unref (job_data->cancellable);
- if (job_data->state != NULL)
+ if (job_data->state != NULL) {
+ hif_state_release_locks (job_data->state);
g_object_unref (job_data->state);
+ }
if (job_data->sources != NULL)
g_ptr_array_unref (job_data->sources);
g_ptr_array_unref (job_data->packages_to_download);
@@ -2954,6 +2956,7 @@ pk_backend_transaction_commit (PkBackendJob *job, HifState *state, GError **erro
if (!ret)
goto out;
out:
+ hif_state_release_locks (state);
g_free (verbosity_string);
if (commit != NULL) {
g_timer_destroy (commit->timer);
diff --git a/backends/hawkey/hif-sack.c b/backends/hawkey/hif-sack.c
index 28c1a65..0c151c3 100644
--- a/backends/hawkey/hif-sack.c
+++ b/backends/hawkey/hif-sack.c
@@ -34,6 +34,7 @@
gboolean
hif_sack_add_source (HySack sack,
HifSource *src,
+ guint permissible_cache_age,
HifSackAddFlags flags,
HifState *state,
GError **error)
@@ -54,7 +55,10 @@ hif_sack_add_source (HySack sack,
/* check repo */
state_local = hif_state_get_child (state);
- ret = hif_source_check (src, state_local, &error_local);
+ ret = hif_source_check (src,
+ permissible_cache_age,
+ state_local,
+ &error_local);
if (!ret) {
g_debug ("failed to check, attempting update: %s",
error_local->message);
@@ -118,6 +122,7 @@ out:
gboolean
hif_sack_add_sources (HySack sack,
GPtrArray *sources,
+ guint permissible_cache_age,
HifSackAddFlags flags,
HifState *state,
GError **error)
@@ -143,7 +148,12 @@ hif_sack_add_sources (HySack sack,
continue;
state_local = hif_state_get_child (state);
- ret = hif_sack_add_source (sack, src, flags, state_local, error);
+ ret = hif_sack_add_source (sack,
+ src,
+ permissible_cache_age,
+ flags,
+ state_local,
+ error);
if (!ret)
goto out;
diff --git a/backends/hawkey/hif-sack.h b/backends/hawkey/hif-sack.h
index abfe7f9..435e95b 100644
--- a/backends/hawkey/hif-sack.h
+++ b/backends/hawkey/hif-sack.h
@@ -39,11 +39,13 @@ typedef enum {
gboolean hif_sack_add_source (HySack sack,
HifSource *src,
+ guint permissible_cache_age,
HifSackAddFlags flags,
HifState *state,
GError **error);
gboolean hif_sack_add_sources (HySack sack,
GPtrArray *sources,
+ guint permissible_cache_age,
HifSackAddFlags flags,
HifState *state,
GError **error);
diff --git a/backends/hawkey/hif-source.c b/backends/hawkey/hif-source.c
index fffcc31..3dc5c85 100644
--- a/backends/hawkey/hif-source.c
+++ b/backends/hawkey/hif-source.c
@@ -44,7 +44,8 @@ struct HifSource {
gchar *id;
gchar *location; /* /var/cache/PackageKit/metadata/fedora */
gchar *location_tmp; /* /var/cache/PackageKit/metadata/fedora.tmp */
- gint64 timestamp;
+ gint64 timestamp_generated; /* µs */
+ gint64 timestamp_modified; /* µs */
GKeyFile *keyfile;
HifSourceKind kind;
HyRepo repo;
@@ -342,10 +343,48 @@ hif_source_update_state_cb (void *user_data,
}
/**
+ * hif_source_set_timestamp_modified:
+ */
+static gboolean
+hif_source_set_timestamp_modified (HifSource *src, GError **error)
+{
+ gboolean ret = TRUE;
+ gchar *filename;
+ GFile *file;
+ GFileInfo *info;
+
+ filename = g_build_filename (src->location, "repodata", "repomd.xml", NULL);
+ file = g_file_new_for_path (filename);
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_TIME_MODIFIED ","
+ G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC,
+ G_FILE_QUERY_INFO_NONE,
+ NULL,
+ error);
+ if (info == NULL) {
+ ret = FALSE;
+ goto out;
+ }
+ src->timestamp_modified = g_file_info_get_attribute_uint64 (info,
+ G_FILE_ATTRIBUTE_TIME_MODIFIED) * G_USEC_PER_SEC;
+ src->timestamp_modified += g_file_info_get_attribute_uint32 (info,
+ G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
+out:
+ g_free (filename);
+ g_object_unref (file);
+ if (info != NULL)
+ g_object_unref (info);
+ return ret;
+}
+
+/**
* hif_source_check:
*/
gboolean
-hif_source_check (HifSource *src, HifState *state, GError **error)
+hif_source_check (HifSource *src,
+ guint permissible_cache_age,
+ HifState *state,
+ GError **error)
{
const gchar *download_list[] = { "primary",
"filelists",
@@ -357,6 +396,7 @@ hif_source_check (HifSource *src, HifState *state, GError **error)
GError *error_local = NULL;
LrYumRepo *yum_repo;
const gchar *urls[] = { "", NULL };
+ gint64 age_of_data; /* in seconds */
/* has the media repo vanished? */
if (src->kind == HIF_SOURCE_KIND_MEDIA &&
@@ -406,7 +446,7 @@ hif_source_check (HifSource *src, HifState *state, GError **error)
/* get timestamp */
ret = lr_result_getinfo (src->repo_result, &error_local,
- LRR_YUM_TIMESTAMP, &src->timestamp);
+ LRR_YUM_TIMESTAMP, &src->timestamp_generated);
if (!ret) {
g_set_error (error,
HIF_ERROR,
@@ -417,6 +457,23 @@ hif_source_check (HifSource *src, HifState *state, GError **error)
goto out;
}
+ /* check metadata age */
+ if (permissible_cache_age != G_MAXUINT) {
+ ret = hif_source_set_timestamp_modified (src, error);
+ if (!ret)
+ goto out;
+ age_of_data = (g_get_real_time () - src->timestamp_modified) / G_USEC_PER_SEC;
+ if (age_of_data > permissible_cache_age) {
+ ret = FALSE;
+ g_set_error (error,
+ HIF_ERROR,
+ PK_ERROR_ENUM_INTERNAL_ERROR,
+ "cache too old: %"G_GINT64_FORMAT" > %i",
+ age_of_data, permissible_cache_age);
+ goto out;
+ }
+ }
+
/* create a HyRepo */
src->repo = hy_repo_create (src->id);
hy_repo_set_string (src->repo, HY_REPO_MD_FN, yum_repo->repomd);
@@ -653,7 +710,7 @@ hif_source_update (HifSource *src,
goto out;
}
if ((flags & HIF_SOURCE_UPDATE_FLAG_FORCE) == 0 ||
- timestamp_new < src->timestamp) {
+ timestamp_new < src->timestamp_generated) {
g_debug ("fresh metadata was older than what we have, ignoring");
goto out;
}
@@ -686,7 +743,7 @@ hif_source_update (HifSource *src,
/* now setup internal hawkey stuff */
state_local = hif_state_get_child (state);
- ret = hif_source_check (src, state_local, error);
+ ret = hif_source_check (src, G_MAXUINT, state_local, error);
if (!ret)
goto out;
diff --git a/backends/hawkey/hif-source.h b/backends/hawkey/hif-source.h
index df4b805..f1d230e 100644
--- a/backends/hawkey/hif-source.h
+++ b/backends/hawkey/hif-source.h
@@ -62,6 +62,7 @@ gchar *hif_source_get_description (HifSource *src);
HyRepo hif_source_get_repo (HifSource *src);
gboolean hif_source_is_devel (HifSource *src);
gboolean hif_source_check (HifSource *src,
+ guint permissible_cache_age,
HifState *state,
GError **error);
gboolean hif_source_update (HifSource *src,
diff --git a/backends/hawkey/pk-backend-hawkey.c b/backends/hawkey/pk-backend-hawkey.c
index 40831b9..1a10e04 100644
--- a/backends/hawkey/pk-backend-hawkey.c
+++ b/backends/hawkey/pk-backend-hawkey.c
@@ -593,8 +593,12 @@ hif_utils_add_remote (PkBackendJob *job,
/* add each repo */
state_local = hif_state_get_child (state);
- ret = hif_sack_add_sources (sack, job_data->sources,
- flags, state_local, error);
+ ret = hif_sack_add_sources (sack,
+ job_data->sources,
+ pk_backend_job_get_cache_age (job),
+ flags,
+ state_local,
+ error);
if (!ret)
goto out;
@@ -648,6 +652,13 @@ hif_utils_create_sack_for_filters (PkBackendJob *job,
}
g_timer_reset (priv->repos_timer);
+ /* if we've specified a specific cache-age then do not use the cache */
+ if ((flags & HIF_SACK_ADD_FLAG_REMOTE) > 0 &&
+ pk_backend_job_get_cache_age (job) != G_MAXUINT) {
+ g_debug ("not reusing sack specific cache age requested");
+ create_flags &= ~HIF_CREATE_SACK_FLAG_USE_CACHE;
+ }
+
/* do we have anything in the cache */
cache_key = g_strdup_printf ("HySack::%i", flags);
if ((create_flags & HIF_CREATE_SACK_FLAG_USE_CACHE) > 0)
@@ -1306,7 +1317,10 @@ pk_backend_get_mime_types (PkBackend *backend)
* pk_backend_refresh_source:
*/
static gboolean
-pk_backend_refresh_source (HifSource *src, HifState *state, GError **error)
+pk_backend_refresh_source (PkBackendJob *job,
+ HifSource *src,
+ HifState *state,
+ GError **error)
{
gboolean ret;
gboolean src_okay;
@@ -1323,7 +1337,10 @@ pk_backend_refresh_source (HifSource *src, HifState *state, GError **error)
/* is the source up to date? */
state_local = hif_state_get_child (state);
- src_okay = hif_source_check (src, state_local, &error_local);
+ src_okay = hif_source_check (src,
+ pk_backend_job_get_cache_age (job),
+ state_local,
+ &error_local);
if (!src_okay) {
g_debug ("repo %s not okay [%s], refreshing",
hif_source_get_id (src), error_local->message);
@@ -1424,7 +1441,7 @@ pk_backend_refresh_cache_thread (PkBackendJob *job,
/* check and download */
state_local = hif_state_get_child (job_data->state);
- ret = pk_backend_refresh_source (src, state_local, &error);
+ ret = pk_backend_refresh_source (job, src, state_local, &error);
if (!ret) {
pk_backend_job_error_code (job, error->code, "%s", error->message);
g_error_free (error);
@@ -3199,21 +3216,20 @@ out:
}
/**
- * hif_is_installed_package_name_arch:
+ * hif_is_installed_package_id_name:
*/
static gboolean
-hif_is_installed_package_name_arch (HySack sack,
- const gchar *name,
- const gchar *arch)
+hif_is_installed_package_id_name (HySack sack, const gchar *package_id)
{
gboolean ret;
+ gchar **split;
HyPackageList pkglist = NULL;
HyQuery query = NULL;
/* run query */
query = hy_query_create (sack);
- hy_query_filter (query, HY_PKG_NAME, HY_EQ, name);
- hy_query_filter (query, HY_PKG_ARCH, HY_EQ, arch);
+ split = pk_package_id_split (package_id);
+ hy_query_filter (query, HY_PKG_NAME, HY_EQ, split[PK_PACKAGE_ID_NAME]);
hy_query_filter (query, HY_PKG_REPONAME, HY_EQ, HY_SYSTEM_REPO_NAME);
pkglist = hy_query_run (query);
@@ -3222,21 +3238,34 @@ hif_is_installed_package_name_arch (HySack sack,
hy_packagelist_free (pkglist);
hy_query_free (query);
+ g_strfreev (split);
return ret;
}
/**
- * hif_is_installed_package_id:
+ * hif_is_installed_package_id_name_arch:
*/
static gboolean
-hif_is_installed_package_id (HySack sack, const gchar *package_id)
+hif_is_installed_package_id_name_arch (HySack sack, const gchar *package_id)
{
gboolean ret;
gchar **split;
+ HyPackageList pkglist = NULL;
+ HyQuery query = NULL;
+
+ /* run query */
+ query = hy_query_create (sack);
split = pk_package_id_split (package_id);
- ret = hif_is_installed_package_name_arch (sack,
- split[PK_PACKAGE_ID_NAME],
- split[PK_PACKAGE_ID_ARCH]);
+ hy_query_filter (query, HY_PKG_NAME, HY_EQ, split[PK_PACKAGE_ID_NAME]);
+ hy_query_filter (query, HY_PKG_ARCH, HY_EQ, split[PK_PACKAGE_ID_ARCH]);
+ hy_query_filter (query, HY_PKG_REPONAME, HY_EQ, HY_SYSTEM_REPO_NAME);
+ pkglist = hy_query_run (query);
+
+ /* any matches? */
+ ret = hy_packagelist_count (pkglist) > 0;
+
+ hy_packagelist_free (pkglist);
+ hy_query_free (query);
g_strfreev (split);
return ret;
}
@@ -3322,7 +3351,7 @@ pk_backend_remove_packages_thread (PkBackendJob *job, GVariant *params, gpointer
/* ensure packages are already installed */
for (i = 0; package_ids[i] != NULL; i++) {
- ret = hif_is_installed_package_id (sack, package_ids[i]);
+ ret = hif_is_installed_package_id_name_arch (sack, package_ids[i]);
if (!ret) {
gchar *printable_tmp;
printable_tmp = pk_package_id_to_printable (package_ids[i]);
@@ -3465,7 +3494,7 @@ pk_backend_install_packages_thread (PkBackendJob *job, GVariant *params, gpointe
/* ensure packages are not already installed */
for (i = 0; package_ids[i] != NULL; i++) {
- ret = hif_is_installed_package_id (sack, package_ids[i]);
+ ret = hif_is_installed_package_id_name_arch (sack, package_ids[i]);
if (ret) {
gchar *printable_tmp;
printable_tmp = pk_package_id_to_printable (package_ids[i]);
@@ -3729,13 +3758,13 @@ pk_backend_update_packages_thread (PkBackendJob *job, GVariant *params, gpointer
/* ensure packages are not already installed */
for (i = 0; package_ids[i] != NULL; i++) {
- ret = hif_is_installed_package_id (sack, package_ids[i]);
+ ret = hif_is_installed_package_id_name (sack, package_ids[i]);
if (!ret) {
gchar *printable_tmp;
printable_tmp = pk_package_id_to_printable (package_ids[i]);
pk_backend_job_error_code (job,
PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED,
- "%s is not already installed",
+ "cannot update: %s is not already installed",
printable_tmp);
g_free (printable_tmp);
goto out;
diff --git a/client/pk-console.c b/client/pk-console.c
index 79f1bb5..4f01942 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -1801,7 +1801,7 @@ main (int argc, char *argv[])
gboolean background = FALSE;
gboolean noninteractive = FALSE;
gboolean only_download = FALSE;
- guint cache_age = 0;
+ guint cache_age = G_MAXUINT;
gint retval_copy = 0;
gboolean plain = FALSE;
gboolean program_version = FALSE;
diff --git a/contrib/systemd-updates/pk-offline-update.c b/contrib/systemd-updates/pk-offline-update.c
index cf0447d..295b2dd 100644
--- a/contrib/systemd-updates/pk-offline-update.c
+++ b/contrib/systemd-updates/pk-offline-update.c
@@ -33,6 +33,7 @@
#define PK_OFFLINE_UPDATE_RESULTS_GROUP "PackageKit Offline Update Results"
#define PK_OFFLINE_UPDATE_TRIGGER_FILENAME "/system-update"
#define PK_OFFLINE_UPDATE_RESULTS_FILENAME "/var/lib/PackageKit/offline-update-competed"
+#define PK_OFFLINE_UPDATE_ACTION_FILENAME "/var/lib/PackageKit/offline-update-action"
#define PK_OFFLINE_PREPARED_UPDATE_FILENAME "/var/lib/PackageKit/prepared-update"
/**
@@ -200,12 +201,6 @@ pk_offline_update_reboot (void)
GError *error = NULL;
GVariant *val = NULL;
- /* allow testing without rebooting */
- if (g_getenv ("PK_OFFLINE_UPDATE_TEST") != NULL) {
- g_print ("TESTING, so not rebooting\n");
- return;
- }
-
/* reboot using systemd */
sd_journal_print (LOG_INFO, "rebooting");
pk_offline_update_set_plymouth_mode ("shutdown");
@@ -245,6 +240,54 @@ out:
}
/**
+ * pk_offline_update_power_off:
+ **/
+static void
+pk_offline_update_power_off (void)
+{
+ GDBusConnection *connection;
+ GError *error = NULL;
+ GVariant *val = NULL;
+
+ /* reboot using systemd */
+ sd_journal_print (LOG_INFO, "shutting down");
+ pk_offline_update_set_plymouth_mode ("shutdown");
+ /* TRANSLATORS: we've finished doing offline updates */
+ pk_offline_update_set_plymouth_msg (_("Shutting down after installing updates…"));
+ connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (connection == NULL) {
+ sd_journal_print (LOG_WARNING,
+ "Failed to get system bus connection: %s",
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ val = g_dbus_connection_call_sync (connection,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "PowerOff",
+ NULL,
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ if (val == NULL) {
+ sd_journal_print (LOG_WARNING,
+ "Failed to power off: %s",
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+out:
+ if (connection != NULL)
+ g_object_unref (connection);
+ if (val != NULL)
+ g_variant_unref (val);
+}
+
+/**
* pk_offline_update_write_error:
**/
static void
@@ -487,6 +530,50 @@ pk_offline_update_sigint_cb (gpointer user_data)
return FALSE;
}
+typedef enum {
+ PK_OFFLINE_UPDATE_ACTION_NOTHING,
+ PK_OFFLINE_UPDATE_ACTION_REBOOT,
+ PK_OFFLINE_UPDATE_ACTION_POWER_OFF
+} PkOfflineUpdateAction;
+
+static PkOfflineUpdateAction
+pk_offline_update_get_action (void)
+{
+ gboolean ret;
+ gchar *action_data = NULL;
+ PkOfflineUpdateAction action;
+
+ /* allow testing without rebooting */
+ if (g_getenv ("PK_OFFLINE_UPDATE_TEST") != NULL) {
+ g_print ("TESTING, so not doing action\n");
+ action = PK_OFFLINE_UPDATE_ACTION_NOTHING;
+ goto out;
+ }
+
+ ret = g_file_get_contents (PK_OFFLINE_UPDATE_ACTION_FILENAME,
+ &action_data,
+ NULL,
+ NULL);
+ if (!ret) {
+ g_warning ("Failed to get post-update action, using reboot");
+ action = PK_OFFLINE_UPDATE_ACTION_REBOOT;
+ goto out;
+ }
+ if (g_strcmp0 (action_data, "reboot") == 0) {
+ action = PK_OFFLINE_UPDATE_ACTION_REBOOT;
+ goto out;
+ }
+ if (g_strcmp0 (action_data, "power-off") == 0) {
+ action = PK_OFFLINE_UPDATE_ACTION_POWER_OFF;
+ goto out;
+ }
+ g_warning ("failed to parse action '%s', using reboot", action_data);
+ action = PK_OFFLINE_UPDATE_ACTION_REBOOT;
+out:
+ g_free (action_data);
+ return action;
+}
+
/**
* main:
**/
@@ -502,6 +589,7 @@ main (int argc, char *argv[])
GMainLoop *loop = NULL;
PkResults *results = NULL;
PkTask *task = NULL;
+ PkOfflineUpdateAction action;
PkProgressBar *progressbar = NULL;
#if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 35)
@@ -598,7 +686,12 @@ out:
g_timeout_add_seconds (10, pk_offline_update_loop_quit_cb, loop);
g_main_loop_run (loop);
}
- pk_offline_update_reboot ();
+ /* we have to manually either restart or shutdown */
+ action = pk_offline_update_get_action ();
+ if (action == PK_OFFLINE_UPDATE_ACTION_REBOOT)
+ pk_offline_update_reboot ();
+ else if (action == PK_OFFLINE_UPDATE_ACTION_POWER_OFF)
+ pk_offline_update_power_off ();
g_free (packages_data);
g_strfreev (package_ids);
if (progressbar != NULL)
diff --git a/contrib/systemd-updates/pk-trigger-offline-update.c b/contrib/systemd-updates/pk-trigger-offline-update.c
index 3b59b1d..532bf3d 100644
--- a/contrib/systemd-updates/pk-trigger-offline-update.c
+++ b/contrib/systemd-updates/pk-trigger-offline-update.c
@@ -30,17 +30,21 @@
#include <unistd.h>
#define PK_OFFLINE_UPDATE_GENERATOR_FLAG "/system-update"
+#define PK_OFFLINE_UPDATE_ACTION_FILENAME "/var/lib/PackageKit/offline-update-action"
int
main (int argc, char *argv[])
{
+ FILE *fp = NULL;
int rc;
+ int retval = EXIT_SUCCESS;
struct passwd *pw;
/* ensure root user */
if (getuid () != 0 || geteuid () != 0) {
fprintf (stderr, "This program can only be used using pkexec\n");
- return EXIT_FAILURE;
+ retval = EXIT_FAILURE;
+ goto out;
}
if (argc > 1 && strcmp (argv[1], "--cancel") == 0) {
@@ -48,18 +52,34 @@ main (int argc, char *argv[])
if (rc < 0) {
fprintf (stderr, "Failed to remove file " PK_OFFLINE_UPDATE_GENERATOR_FLAG ": %s\n",
strerror (errno));
- return EXIT_FAILURE;
+ retval = EXIT_FAILURE;
+ goto out;
}
return EXIT_SUCCESS;
}
+ /* open success action */
+ fp = fopen (PK_OFFLINE_UPDATE_ACTION_FILENAME, "w+");
+ if (fp == NULL) {
+ fprintf (stderr, "Failed to open %s for writing\n",
+ PK_OFFLINE_UPDATE_ACTION_FILENAME);
+ retval = EXIT_FAILURE;
+ goto out;
+ }
+ if (argc > 1 && strcmp (argv[1], "power-off") == 0) {
+ fputs ("power-off", fp);
+ } else {
+ fputs ("reboot", fp);
+ }
+
/* create symlink for the systemd-system-update-generator */
rc = symlink ("/var/cache", PK_OFFLINE_UPDATE_GENERATOR_FLAG);
if (rc < 0) {
fprintf (stderr, "Failed to create symlink: %s\n",
strerror (errno));
- return EXIT_FAILURE;
+ retval = EXIT_FAILURE;
+ goto out;
}
/* get UID for username */
@@ -67,7 +87,8 @@ main (int argc, char *argv[])
if (pw == NULL) {
fprintf (stderr, "Failed to get PackageKit uid: %s\n",
strerror (errno));
- return EXIT_FAILURE;
+ retval = EXIT_FAILURE;
+ goto out;
}
/* change it to the PackageKit user so the daemon can delete
@@ -76,8 +97,11 @@ main (int argc, char *argv[])
if (rc < 0) {
fprintf (stderr, "Failed to change owner of symlink: %s\n",
strerror (errno));
- return EXIT_FAILURE;
+ retval = EXIT_FAILURE;
+ goto out;
}
-
- return EXIT_SUCCESS;
+out:
+ if (fp != NULL)
+ fclose (fp);
+ return retval;
}
diff --git a/lib/packagekit-glib2/pk-control.h b/lib/packagekit-glib2/pk-control.h
index a6c3493..3c483e6 100644
--- a/lib/packagekit-glib2/pk-control.h
+++ b/lib/packagekit-glib2/pk-control.h
@@ -132,13 +132,6 @@ void pk_control_set_proxy2_async (PkControl *control,
gboolean pk_control_set_proxy_finish (PkControl *control,
GAsyncResult *res,
GError **error);
-void pk_control_get_network_state_async (PkControl *control,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-PkNetworkEnum pk_control_get_network_state_finish (PkControl *control,
- GAsyncResult *res,
- GError **error);
void pk_control_get_time_since_action_async (PkControl *control,
PkRoleEnum role,
GCancellable *cancellable,