New upstream version 2018.6

This commit is contained in:
Simon McVittie committed 2018-06-21 19:16:18 +01:00
commit 8125d7d0dd
200 files changed
+51719 -2229

No files matched your search

-53
View File
@@ -18,59 +18,6 @@
***/
/* Add new symbols here. Release commits should copy this section into -released.sym. */
LIBOSTREE_2018.6 {
global:
ostree_collection_ref_dup;
ostree_collection_ref_dupv;
ostree_collection_ref_equal;
ostree_collection_ref_free;
ostree_collection_ref_freev;
ostree_collection_ref_get_type;
ostree_collection_ref_hash;
ostree_collection_ref_new;
ostree_remote_get_name;
ostree_remote_get_type;
ostree_remote_get_url;
ostree_remote_ref;
ostree_remote_unref;
ostree_repo_find_remotes_async;
ostree_repo_find_remotes_finish;
ostree_repo_finder_avahi_get_type;
ostree_repo_finder_avahi_new;
ostree_repo_finder_avahi_start;
ostree_repo_finder_avahi_stop;
ostree_repo_finder_config_get_type;
ostree_repo_finder_config_new;
ostree_repo_finder_get_type;
ostree_repo_finder_mount_get_type;
ostree_repo_finder_mount_new;
ostree_repo_finder_override_add_uri;
ostree_repo_finder_override_get_type;
ostree_repo_finder_override_new;
ostree_repo_finder_resolve_all_async;
ostree_repo_finder_resolve_all_finish;
ostree_repo_finder_resolve_async;
ostree_repo_finder_resolve_finish;
ostree_repo_finder_result_compare;
ostree_repo_finder_result_dup;
ostree_repo_finder_result_free;
ostree_repo_finder_result_freev;
ostree_repo_finder_result_get_type;
ostree_repo_finder_result_new;
ostree_repo_get_collection_id;
ostree_repo_list_collection_refs;
ostree_repo_pull_from_remotes_async;
ostree_repo_pull_from_remotes_finish;
ostree_repo_remote_list_collection_refs;
ostree_repo_resolve_collection_ref;
ostree_repo_resolve_keyring_for_collection;
ostree_repo_set_collection_id;
ostree_repo_set_collection_ref_immediate;
ostree_repo_transaction_set_collection_ref;
ostree_repo_traverse_reachable_refs;
ostree_sysroot_cleanup_prune_repo;
ostree_validate_collection_id;
} LIBOSTREE_2018.5;
/* Stub section for the stable release *after* this development one; don't
* edit this other than to update the last number. This is just a copy/paste
+54
View File
@@ -473,6 +473,60 @@ LIBOSTREE_2018.5 {
ostree_repo_traverse_commit_union_with_parents;
} LIBOSTREE_2018.3;
LIBOSTREE_2018.6 {
global:
ostree_collection_ref_dup;
ostree_collection_ref_dupv;
ostree_collection_ref_equal;
ostree_collection_ref_free;
ostree_collection_ref_freev;
ostree_collection_ref_get_type;
ostree_collection_ref_hash;
ostree_collection_ref_new;
ostree_remote_get_name;
ostree_remote_get_type;
ostree_remote_get_url;
ostree_remote_ref;
ostree_remote_unref;
ostree_repo_find_remotes_async;
ostree_repo_find_remotes_finish;
ostree_repo_finder_avahi_get_type;
ostree_repo_finder_avahi_new;
ostree_repo_finder_avahi_start;
ostree_repo_finder_avahi_stop;
ostree_repo_finder_config_get_type;
ostree_repo_finder_config_new;
ostree_repo_finder_get_type;
ostree_repo_finder_mount_get_type;
ostree_repo_finder_mount_new;
ostree_repo_finder_override_add_uri;
ostree_repo_finder_override_get_type;
ostree_repo_finder_override_new;
ostree_repo_finder_resolve_all_async;
ostree_repo_finder_resolve_all_finish;
ostree_repo_finder_resolve_async;
ostree_repo_finder_resolve_finish;
ostree_repo_finder_result_compare;
ostree_repo_finder_result_dup;
ostree_repo_finder_result_free;
ostree_repo_finder_result_freev;
ostree_repo_finder_result_get_type;
ostree_repo_finder_result_new;
ostree_repo_get_collection_id;
ostree_repo_list_collection_refs;
ostree_repo_pull_from_remotes_async;
ostree_repo_pull_from_remotes_finish;
ostree_repo_remote_list_collection_refs;
ostree_repo_resolve_collection_ref;
ostree_repo_resolve_keyring_for_collection;
ostree_repo_set_collection_id;
ostree_repo_set_collection_ref_immediate;
ostree_repo_transaction_set_collection_ref;
ostree_repo_traverse_reachable_refs;
ostree_sysroot_cleanup_prune_repo;
ostree_validate_collection_id;
} LIBOSTREE_2018.5;
/* NOTE: Only add more content here in release commits! See the
* comments at the top of this file.
*/
@@ -23,6 +23,9 @@
#pragma once
/* Private, not for introspection */
#ifndef __GI_SCANNER__
#include "config.h"
#include <gio/gio.h>
@@ -64,3 +67,5 @@ ot_open_archive_read (const char *path, GError **error)
#endif
G_END_DECLS
#endif
+50 -13
View File
@@ -889,17 +889,22 @@ write_content_object (OstreeRepo *self,
size = 0;
/* Free space check; only applies during transactions */
if (self->min_free_space_percent > 0 && self->in_transaction)
if ((self->min_free_space_percent > 0 || self->min_free_space_mb > 0) && self->in_transaction)
{
g_mutex_lock (&self->txn_lock);
g_assert_cmpint (self->txn.blocksize, >, 0);
const fsblkcnt_t object_blocks = (size / self->txn.blocksize) + 1;
if (object_blocks > self->txn.max_blocks)
{
guint64 bytes_required = (guint64)object_blocks * self->txn.blocksize;
g_mutex_unlock (&self->txn_lock);
g_autofree char *formatted_required = g_format_size ((guint64)object_blocks * self->txn.blocksize);
return glnx_throw (error, "min-free-space-percent '%u%%' would be exceeded, %s more required",
self->min_free_space_percent, formatted_required);
g_autofree char *formatted_required = g_format_size (bytes_required);
if (self->min_free_space_percent > 0)
return glnx_throw (error, "min-free-space-percent '%u%%' would be exceeded, %s more required",
self->min_free_space_percent, formatted_required);
else
return glnx_throw (error, "min-free-space-size %luMB would be exceeded, %s more required",
self->min_free_space_mb, formatted_required);
}
/* This is the main bit that needs mutex protection */
self->txn.max_blocks -= object_blocks;
@@ -1491,6 +1496,25 @@ devino_cache_lookup (OstreeRepo *self,
return dev_ino_val->checksum;
}
static guint64
min_free_space_calculate_reserved_blocks (OstreeRepo *self, struct statvfs *stvfsbuf)
{
guint64 reserved_blocks = 0;
if (self->min_free_space_mb > 0)
{
reserved_blocks = (self->min_free_space_mb << 20) / stvfsbuf->f_bsize;
}
else if (self->min_free_space_percent > 0)
{
/* Convert fragment to blocks to compute the total */
guint64 total_blocks = (stvfsbuf->f_frsize * stvfsbuf->f_blocks) / stvfsbuf->f_bsize;
reserved_blocks = ((double)total_blocks) * (self->min_free_space_percent/100.0);
}
return reserved_blocks;
}
/**
* ostree_repo_scan_hardlinks:
* @self: An #OstreeRepo
@@ -1572,26 +1596,29 @@ ostree_repo_prepare_transaction (OstreeRepo *self,
return FALSE;
self->in_transaction = TRUE;
if (self->min_free_space_percent > 0)
if (self->min_free_space_percent >= 0 || self->min_free_space_mb >= 0)
{
struct statvfs stvfsbuf;
if (TEMP_FAILURE_RETRY (fstatvfs (self->repo_dir_fd, &stvfsbuf)) < 0)
return glnx_throw_errno_prefix (error, "fstatvfs");
g_mutex_lock (&self->txn_lock);
self->txn.blocksize = stvfsbuf.f_bsize;
/* Convert fragment to blocks to compute the total */
guint64 total_blocks = (stvfsbuf.f_frsize * stvfsbuf.f_blocks) / stvfsbuf.f_bsize;
guint64 reserved_blocks = min_free_space_calculate_reserved_blocks (self, &stvfsbuf);
/* Use the appropriate free block count if we're unprivileged */
guint64 bfree = (getuid () != 0 ? stvfsbuf.f_bavail : stvfsbuf.f_bfree);
guint64 reserved_blocks = ((double)total_blocks) * (self->min_free_space_percent/100.0);
if (bfree > reserved_blocks)
self->txn.max_blocks = bfree - reserved_blocks;
else
{
guint64 bytes_required = bfree * self->txn.blocksize;
g_mutex_unlock (&self->txn_lock);
g_autofree char *formatted_free = g_format_size (bfree * self->txn.blocksize);
return glnx_throw (error, "min-free-space-percent '%u%%' would be exceeded, %s available",
self->min_free_space_percent, formatted_free);
g_autofree char *formatted_free = g_format_size (bytes_required);
if (self->min_free_space_percent > 0)
return glnx_throw (error, "min-free-space-percent '%u%%' would be exceeded, %s available",
self->min_free_space_percent, formatted_free);
else
return glnx_throw (error, "min-free-space-size %luMB would be exceeded, %s available",
self->min_free_space_mb, formatted_free);
}
g_mutex_unlock (&self->txn_lock);
}
@@ -2163,6 +2190,8 @@ ostree_repo_abort_transaction (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GError) cleanup_error = NULL;
/* Always ignore the cancellable to avoid the chance that, if it gets
* canceled, the transaction may not be fully cleaned up.
* See https://github.com/ostreedev/ostree/issues/1491 .
@@ -2173,8 +2202,9 @@ ostree_repo_abort_transaction (OstreeRepo *self,
if (!self->in_transaction)
return TRUE;
if (!cleanup_tmpdir (self, cancellable, error))
return FALSE;
/* Do not propagate failures from cleanup_tmpdir() immediately, as we want
* to clean up the rest of the internal transaction state first. */
cleanup_tmpdir (self, cancellable, &cleanup_error);
if (self->loose_object_devino_hash)
g_hash_table_remove_all (self->loose_object_devino_hash);
@@ -2194,6 +2224,13 @@ ostree_repo_abort_transaction (OstreeRepo *self,
self->txn_locked = FALSE;
}
/* Propagate cleanup_tmpdir() failure. */
if (cleanup_error != NULL)
{
g_propagate_error (error, g_steal_pointer (&cleanup_error));
return FALSE;
}
return TRUE;
}
+1
View File
@@ -151,6 +151,7 @@ struct OstreeRepo {
uid_t target_owner_uid; /* Ensure files are chowned to this uid/gid */
gid_t target_owner_gid;
guint min_free_space_percent; /* See the min-free-space-percent config option */
guint64 min_free_space_mb; /* See the min-free-space-size config option */
guint test_error_flags; /* OstreeRepoTestErrorFlags */
+9 -6
View File
@@ -153,26 +153,29 @@ _ostree_repo_prune_tmp (OstreeRepo *self,
size_t len;
gboolean has_sig_suffix = FALSE;
struct dirent *dent;
g_autofree gchar *d_name = NULL;
if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error))
return FALSE;
if (dent == NULL)
break;
len = strlen (dent->d_name);
if (len > 4 && g_strcmp0 (dent->d_name + len - 4, ".sig") == 0)
/* dirent->d_name can't be modified directly; see `man 3 readdir` */
d_name = g_strdup (dent->d_name);
len = strlen (d_name);
if (len > 4 && g_strcmp0 (d_name + len - 4, ".sig") == 0)
{
has_sig_suffix = TRUE;
dent->d_name[len - 4] = '\0';
d_name[len - 4] = '\0';
}
if (!g_hash_table_contains (self->remotes, dent->d_name))
if (!g_hash_table_contains (self->remotes, d_name))
{
/* Restore the previous value to get the file name. */
if (has_sig_suffix)
dent->d_name[len - 4] = '.';
d_name[len - 4] = '.';
if (!glnx_unlinkat (dfd_iter.fd, dent->d_name, 0, error))
if (!glnx_unlinkat (dfd_iter.fd, d_name, 0, error))
return FALSE;
}
}
+22 -1
View File
@@ -245,7 +245,28 @@ resolve_refspec (OstreeRepo *self,
{
ret_rev = g_strdup (ref);
}
else if (remote != NULL)
else if (self->in_transaction)
{
const char *refspec;
if (remote != NULL)
refspec = glnx_strjoina (remote, ":", ref);
else
refspec = ref;
g_mutex_lock (&self->txn_lock);
if (self->txn.refs)
ret_rev = g_strdup (g_hash_table_lookup (self->txn.refs, refspec));
g_mutex_unlock (&self->txn_lock);
}
if (ret_rev != NULL)
{
ot_transfer_out_value (out_rev, &ret_rev);
return TRUE;
}
if (remote != NULL)
{
const char *remote_ref = glnx_strjoina ("refs/remotes/", remote, "/", ref);
+73 -10
View File
@@ -2654,6 +2654,48 @@ get_remotes_d_dir (OstreeRepo *self,
return g_file_resolve_relative_path (sysroot, SYSCONF_REMOTES);
}
static gboolean
min_free_space_size_validate_and_convert (OstreeRepo *self,
const char *min_free_space_size_str,
GError **error)
{
static GRegex *regex;
static gsize regex_initialized;
if (g_once_init_enter (&regex_initialized))
{
regex = g_regex_new ("^([0-9]+)(G|M|T)B$", 0, 0, NULL);
g_assert (regex);
g_once_init_leave (&regex_initialized, 1);
}
g_autoptr(GMatchInfo) match = NULL;
if (!g_regex_match (regex, min_free_space_size_str, 0, &match))
return glnx_prefix_error (error, "Failed to parse min-free-space-size parameter: '%s'", min_free_space_size_str);
g_autofree char *size_str = g_match_info_fetch (match, 1);
g_autofree char *unit = g_match_info_fetch (match, 2);
guint shifts;
switch (*unit)
{
case 'M':
shifts = 0;
break;
case 'G':
shifts = 10;
break;
case 'T':
shifts = 20;
break;
default:
g_assert_not_reached ();
}
self->min_free_space_mb = g_ascii_strtoull (size_str, NULL, 10) << shifts;
return TRUE;
}
static gboolean
reload_core_config (OstreeRepo *self,
GCancellable *cancellable,
@@ -2771,18 +2813,39 @@ reload_core_config (OstreeRepo *self,
self->zlib_compression_level = OSTREE_ARCHIVE_DEFAULT_COMPRESSION_LEVEL;
}
{ g_autofree char *min_free_space_percent_str = NULL;
/* If changing this, be sure to change the man page too */
const char *default_min_free_space = "3";
{
if (g_key_file_has_key (self->config, "core", "min-free-space-size", NULL) &&
g_key_file_has_key (self->config, "core", "min-free-space-percent", NULL))
{
return glnx_throw (error, "min-free-space-percent and min-free-space-size are mutually exclusive");
}
else if (g_key_file_has_key (self->config, "core", "min-free-space-size", NULL))
{
g_autofree char *min_free_space_size_str = NULL;
if (!ot_keyfile_get_value_with_default (self->config, "core", "min-free-space-percent",
default_min_free_space,
&min_free_space_percent_str, error))
return FALSE;
if (!ot_keyfile_get_value_with_default (self->config, "core", "min-free-space-size",
NULL, &min_free_space_size_str, error))
return FALSE;
self->min_free_space_percent = g_ascii_strtoull (min_free_space_percent_str, NULL, 10);
if (self->min_free_space_percent > 99)
return glnx_throw (error, "Invalid min-free-space-percent '%s'", min_free_space_percent_str);
/* Validate the string and convert the size to MBs */
if (!min_free_space_size_validate_and_convert (self, min_free_space_size_str, error))
return glnx_throw (error, "Invalid min-free-space-size '%s'", min_free_space_size_str);
}
else
{
g_autofree char *min_free_space_percent_str = NULL;
/* If changing this, be sure to change the man page too */
const char *default_min_free_space = "3";
if (!ot_keyfile_get_value_with_default (self->config, "core", "min-free-space-percent",
default_min_free_space,
&min_free_space_percent_str, error))
return FALSE;
self->min_free_space_percent = g_ascii_strtoull (min_free_space_percent_str, NULL, 10);
if (self->min_free_space_percent > 99)
return glnx_throw (error, "Invalid min-free-space-percent '%s'", min_free_space_percent_str);
}
}
{
+16 -7
View File
@@ -684,15 +684,10 @@ selinux_relabel_dir (OstreeSysroot *sysroot,
static gboolean
selinux_relabel_var_if_needed (OstreeSysroot *sysroot,
OstreeSePolicy *sepolicy,
OstreeDeployment *deployment,
int os_deploy_dfd,
GCancellable *cancellable,
GError **error)
{
const char *osdeploypath = glnx_strjoina ("ostree/deploy/", ostree_deployment_get_osname (deployment));
glnx_autofd int os_deploy_dfd = -1;
if (!glnx_opendirat (sysroot->sysroot_fd, osdeploypath, TRUE, &os_deploy_dfd, error))
return FALSE;
/* This is a bit of a hack; we should change the code at some
* point in the distant future to only create (and label) /var
* when doing a deployment.
@@ -2529,11 +2524,25 @@ sysroot_finalize_deployment (OstreeSysroot *self,
return FALSE;
}
const char *osdeploypath = glnx_strjoina ("ostree/deploy/", ostree_deployment_get_osname (deployment));
glnx_autofd int os_deploy_dfd = -1;
if (!glnx_opendirat (self->sysroot_fd, osdeploypath, TRUE, &os_deploy_dfd, error))
return FALSE;
/* Ensure that the new deployment does not have /etc/.updated or
* /var/.updated so that systemd ConditionNeedsUpdate=/etc|/var services run
* after rebooting.
*/
if (!ot_ensure_unlinked_at (deployment_dfd, "etc/.updated", error))
return FALSE;
if (!ot_ensure_unlinked_at (os_deploy_dfd, "var/.updated", error))
return FALSE;
g_autoptr(OstreeSePolicy) sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error);
if (!sepolicy)
return FALSE;
if (!selinux_relabel_var_if_needed (self, sepolicy, deployment, cancellable, error))
if (!selinux_relabel_var_if_needed (self, sepolicy, os_deploy_dfd, cancellable, error))
return FALSE;
/* Rewrite the origin using the final merged selinux config, just to be
+6 -6
View File
@@ -42,6 +42,9 @@ static OstreeCommand admin_subcommands[] = {
{ "deploy", OSTREE_BUILTIN_FLAG_NO_REPO,
ot_admin_builtin_deploy,
"Checkout revision REFSPEC as the new default deployment" },
{ "finalize-staged", OSTREE_BUILTIN_FLAG_NO_REPO | OSTREE_BUILTIN_FLAG_HIDDEN,
ot_admin_builtin_finalize_staged,
"Internal command to run at shutdown time" },
{ "init-fs", OSTREE_BUILTIN_FLAG_NO_REPO,
ot_admin_builtin_init_fs,
"Initialize a root filesystem" },
@@ -51,15 +54,12 @@ static OstreeCommand admin_subcommands[] = {
{ "os-init", OSTREE_BUILTIN_FLAG_NO_REPO,
ot_admin_builtin_os_init,
"Initialize empty state for given operating system" },
{ "set-origin", OSTREE_BUILTIN_FLAG_NO_REPO,
ot_admin_builtin_set_origin,
"Set Origin and create a new origin file" },
{ "pin", OSTREE_BUILTIN_FLAG_NO_REPO,
ot_admin_builtin_pin,
"Change the \"pinning\" state of a deployment" },
{ "finalize-staged", OSTREE_BUILTIN_FLAG_NO_REPO | OSTREE_BUILTIN_FLAG_HIDDEN,
ot_admin_builtin_finalize_staged,
"Internal command to run at shutdown time" },
{ "set-origin", OSTREE_BUILTIN_FLAG_NO_REPO,
ot_admin_builtin_set_origin,
"Set Origin and create a new origin file" },
{ "status", OSTREE_BUILTIN_FLAG_NO_REPO,
ot_admin_builtin_status,
"List deployments" },