diff options
-rw-r--r-- | apidoc/ostree-sections.txt | 1 | ||||
-rw-r--r-- | src/libostree/libostree-devel.sym | 1 | ||||
-rw-r--r-- | src/libostree/ostree-repo-commit.c | 61 | ||||
-rw-r--r-- | src/libostree/ostree-repo.c | 15 | ||||
-rw-r--r-- | src/libostree/ostree-repo.h | 44 | ||||
-rw-r--r-- | src/ostree/ot-builtin-fsck.c | 12 |
6 files changed, 100 insertions, 34 deletions
diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt index e8faeb10..252a563a 100644 --- a/apidoc/ostree-sections.txt +++ b/apidoc/ostree-sections.txt @@ -333,6 +333,7 @@ ostree_repo_set_cache_dir ostree_repo_sign_delta ostree_repo_has_object ostree_repo_mark_commit_partial +ostree_repo_mark_commit_partial_reason ostree_repo_write_metadata ostree_repo_write_metadata_async ostree_repo_write_metadata_finish diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym index f552bcea..58d35f55 100644 --- a/src/libostree/libostree-devel.sym +++ b/src/libostree/libostree-devel.sym @@ -19,6 +19,7 @@ /* Add new symbols here. Release commits should copy this section into -released.sym. */ LIBOSTREE_2019.4 { + ostree_repo_mark_commit_partial_reason; } LIBOSTREE_2019.3; /* Stub section for the stable release *after* this development one; don't diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index e7bc9820..0aaebbdb 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -1874,26 +1874,29 @@ ensure_txn_refs (OstreeRepo *self) } /** - * ostree_repo_mark_commit_partial: + * ostree_repo_mark_commit_partial_reason: * @self: Repo * @checksum: Commit SHA-256 * @is_partial: Whether or not this commit is partial + * @in_state: Reason bitmask for partial commit * @error: Error * - * Commits in "partial" state do not have all their child objects written. This - * occurs in various situations, such as during a pull, but also if a "subpath" - * pull is used, as well as "commit only" pulls. + * Allows the setting of a reason code for a partial commit. Presently + * it only supports setting reason bitmask to + * OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL, or + * OSTREE_REPO_COMMIT_STATE_NORMAL. This will allow successive ostree + * fsck operations to exit properly with an error code if the + * repository has been truncated as a result of fsck trying to repair + * it. * - * This function is used by ostree_repo_pull_with_options(); you - * should use this if you are implementing a different type of transport. - * - * Since: 2017.15 + * Since: 2019.4 */ gboolean -ostree_repo_mark_commit_partial (OstreeRepo *self, - const char *checksum, - gboolean is_partial, - GError **error) +ostree_repo_mark_commit_partial_reason (OstreeRepo *self, + const char *checksum, + gboolean is_partial, + OstreeRepoCommitState in_state, + GError **error) { g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (checksum); if (is_partial) @@ -1905,6 +1908,12 @@ ostree_repo_mark_commit_partial (OstreeRepo *self, if (errno != EEXIST) return glnx_throw_errno_prefix (error, "open(%s)", commitpartial_path); } + else + { + if (in_state & OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL) + if (glnx_loop_write (fd, "f", 1) < 0) + return glnx_throw_errno_prefix (error, "write(%s)", commitpartial_path); + } } else { @@ -1916,6 +1925,34 @@ ostree_repo_mark_commit_partial (OstreeRepo *self, } /** + * ostree_repo_mark_commit_partial: + * @self: Repo + * @checksum: Commit SHA-256 + * @is_partial: Whether or not this commit is partial + * @error: Error + * + * Commits in the "partial" state do not have all their child objects + * written. This occurs in various situations, such as during a pull, + * but also if a "subpath" pull is used, as well as "commit only" + * pulls. + * + * This function is used by ostree_repo_pull_with_options(); you + * should use this if you are implementing a different type of transport. + * + * Since: 2017.15 + */ +gboolean +ostree_repo_mark_commit_partial (OstreeRepo *self, + const char *checksum, + gboolean is_partial, + GError **error) +{ + return ostree_repo_mark_commit_partial_reason (self, checksum, is_partial, + OSTREE_REPO_COMMIT_STATE_NORMAL, + error); +} + +/** * ostree_repo_transaction_set_refspec: * @self: An #OstreeRepo * @refspec: The refspec to write diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index eb652bef..b654aff2 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -3768,10 +3768,19 @@ load_metadata_internal (OstreeRepo *self, g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (sha256); *out_state = 0; - if (!glnx_fstatat_allow_noent (self->repo_dir_fd, commitpartial_path, NULL, 0, error)) + glnx_autofd int fd = -1; + if (!ot_openat_ignore_enoent (self->repo_dir_fd, commitpartial_path, &fd, error)) return FALSE; - if (errno == 0) - *out_state |= OSTREE_REPO_COMMIT_STATE_PARTIAL; + if (fd != -1) + { + *out_state |= OSTREE_REPO_COMMIT_STATE_PARTIAL; + char reason; + if (read (fd, &reason, 1) == 1) + { + if (reason == 'f') + *out_state |= OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL; + } + } } } else if (self->parent_repo) diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 038bbd41..aaaaa622 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -249,6 +249,26 @@ gboolean ostree_repo_write_config (OstreeRepo *self, GError **error); /** + * OstreeRepoCommitState: + * @OSTREE_REPO_COMMIT_STATE_NORMAL: Commit is complete. This is the default. + * (Since: 2017.14.) + * @OSTREE_REPO_COMMIT_STATE_PARTIAL: One or more objects are missing from the + * local copy of the commit, but metadata is present. (Since: 2015.7.) + * @OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL: One or more objects are missing from the + * local copy of the commit, due to an fsck --delete. (Since: 2019.3.) + * + * Flags representing the state of a commit in the local repository, as returned + * by ostree_repo_load_commit(). + * + * Since: 2015.7 + */ +typedef enum { + OSTREE_REPO_COMMIT_STATE_NORMAL = 0, + OSTREE_REPO_COMMIT_STATE_PARTIAL = (1 << 0), + OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL = (1 << 1), +} OstreeRepoCommitState; + +/** * OstreeRepoTransactionStats: * @metadata_objects_total: The total number of metadata objects * in the repository after this transaction has completed. @@ -316,6 +336,13 @@ gboolean ostree_repo_mark_commit_partial (OstreeRepo *self, GError **error); _OSTREE_PUBLIC +gboolean ostree_repo_mark_commit_partial_reason (OstreeRepo *self, + const char *checksum, + gboolean is_partial, + OstreeRepoCommitState in_state, + GError **error); + +_OSTREE_PUBLIC void ostree_repo_transaction_set_refspec (OstreeRepo *self, const char *refspec, const char *checksum); @@ -526,23 +553,6 @@ gboolean ostree_repo_load_variant_if_exists (OstreeRepo *self, GVariant **out_variant, GError **error); -/** - * OstreeRepoCommitState: - * @OSTREE_REPO_COMMIT_STATE_NORMAL: Commit is complete. This is the default. - * (Since: 2017.14.) - * @OSTREE_REPO_COMMIT_STATE_PARTIAL: One or more objects are missing from the - * local copy of the commit, but metadata is present. (Since: 2015.7.) - * - * Flags representing the state of a commit in the local repository, as returned - * by ostree_repo_load_commit(). - * - * Since: 2015.7 - */ -typedef enum { - OSTREE_REPO_COMMIT_STATE_NORMAL = 0, - OSTREE_REPO_COMMIT_STATE_PARTIAL = (1 << 0), -} OstreeRepoCommitState; - _OSTREE_PUBLIC gboolean ostree_repo_load_commit (OstreeRepo *self, const char *checksum, diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c index a7ecd3d0..44e98a76 100644 --- a/src/ostree/ot-builtin-fsck.c +++ b/src/ostree/ot-builtin-fsck.c @@ -127,7 +127,7 @@ fsck_one_object (OstreeRepo *repo, if ((state & OSTREE_REPO_COMMIT_STATE_PARTIAL) == 0) { g_printerr ("Marking commit as partial: %s\n", parent_commit); - if (!ostree_repo_mark_commit_partial (repo, parent_commit, TRUE, error)) + if (!ostree_repo_mark_commit_partial_reason (repo, parent_commit, TRUE, OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL, error)) return FALSE; } } @@ -302,6 +302,7 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, opt_verify_bindings = TRUE; guint n_partial = 0; + guint n_fsck_partial = 0; g_hash_table_iter_init (&hash_iter, objects); while (g_hash_table_iter_next (&hash_iter, &key, &value)) { @@ -410,7 +411,11 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, } if (commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) - n_partial++; + { + n_partial++; + if (commitstate & OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL) + n_fsck_partial++; + } else g_hash_table_add (commits, g_variant_ref (serialized_key)); } @@ -450,5 +455,8 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, if (found_corruption) return glnx_throw (error, "Repository corruption encountered"); + if (n_fsck_partial > 0) + return glnx_throw (error, "%u fsck deleted partial commits not verified", n_partial); + return TRUE; } |