805 lines
25 KiB
Diff
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,
|