summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile-tests.am1
-rw-r--r--doc/ostree-sections.txt1
-rw-r--r--src/libostree/ostree-cmdprivate.c2
-rw-r--r--src/libostree/ostree-repo-pull.c28
-rw-r--r--src/libostree/ostree-repo.c52
-rw-r--r--src/libostree/ostree-repo.h10
-rw-r--r--src/libotutil/ot-fs-utils.c18
-rw-r--r--src/libotutil/ot-fs-utils.h4
-rw-r--r--src/ostree/ot-builtin-fsck.c20
-rw-r--r--tests/test-oldstyle-partial.sh37
10 files changed, 153 insertions, 20 deletions
diff --git a/Makefile-tests.am b/Makefile-tests.am
index bf584240..7350032f 100644
--- a/Makefile-tests.am
+++ b/Makefile-tests.am
@@ -48,6 +48,7 @@ testfiles = test-basic \
test-admin-locking \
test-repo-checkout-subpath \
test-reset-nonlinear \
+ test-oldstyle-partial \
test-setuid \
test-delta \
test-xattrs \
diff --git a/doc/ostree-sections.txt b/doc/ostree-sections.txt
index 9e2ef6c3..b75efc97 100644
--- a/doc/ostree-sections.txt
+++ b/doc/ostree-sections.txt
@@ -255,6 +255,7 @@ ostree_repo_write_content_finish
ostree_repo_resolve_rev
ostree_repo_list_refs
ostree_repo_load_variant
+ostree_repo_load_commit
ostree_repo_load_variant_if_exists
ostree_repo_load_file
ostree_repo_load_object_stream
diff --git a/src/libostree/ostree-cmdprivate.c b/src/libostree/ostree-cmdprivate.c
index ea122434..99834937 100644
--- a/src/libostree/ostree-cmdprivate.c
+++ b/src/libostree/ostree-cmdprivate.c
@@ -21,6 +21,8 @@
#include "config.h"
#include "ostree-cmdprivate.h"
+#include "ostree-repo-private.h"
+#include "ostree-core-private.h"
#include "ostree-sysroot.h"
#include "ostree-bootloader-grub2.h"
diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c
index 97c044f8..db91d1ec 100644
--- a/src/libostree/ostree-repo-pull.c
+++ b/src/libostree/ostree-repo-pull.c
@@ -1126,10 +1126,12 @@ scan_one_metadata_object_c (OtPullData *pull_data,
/* For commits, check whether we only had a partial fetch */
if (!do_scan && objtype == OSTREE_OBJECT_TYPE_COMMIT)
{
- g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (tmp_checksum);
- struct stat stbuf;
+ OstreeRepoCommitState commitstate;
- if (fstatat (pull_data->repo->repo_dir_fd, commitpartial_path, &stbuf, 0) == 0)
+ if (!ostree_repo_load_commit (pull_data->repo, tmp_checksum, NULL, &commitstate, error))
+ goto out;
+
+ if (commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL)
{
do_scan = TRUE;
pull_data->commitpartial_exists = TRUE;
@@ -2178,14 +2180,8 @@ ostree_repo_pull_with_options (OstreeRepo *self,
const char *checksum = value;
g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (checksum);
- if (unlinkat (pull_data->repo->repo_dir_fd, commitpartial_path, 0) != 0)
- {
- if (errno != ENOENT)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
- }
+ if (!ot_ensure_unlinked_at (pull_data->repo->repo_dir_fd, commitpartial_path, 0))
+ goto out;
}
g_hash_table_iter_init (&hash_iter, commits_to_fetch);
while (g_hash_table_iter_next (&hash_iter, &key, &value))
@@ -2193,14 +2189,8 @@ ostree_repo_pull_with_options (OstreeRepo *self,
const char *commit = value;
g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (commit);
- if (unlinkat (pull_data->repo->repo_dir_fd, commitpartial_path, 0) != 0)
- {
- if (errno != ENOENT)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
- }
+ if (!ot_ensure_unlinked_at (pull_data->repo->repo_dir_fd, commitpartial_path, 0))
+ goto out;
}
}
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 5499dc11..106298a4 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -2652,6 +2652,58 @@ ostree_repo_load_variant (OstreeRepo *self,
}
/**
+ * ostree_repo_load_commit:
+ * @self: Repo
+ * @checksum: Commit checksum
+ * @out_commit: (out) (allow-none): Commit
+ * @out_state: (out) (allow-none): Commit state
+ * @error: Error
+ *
+ * A version of ostree_repo_load_variant() specialized to commits,
+ * capable of returning extended state information. Currently
+ * the only extended state is %OSTREE_REPO_COMMIT_STATE_PARTIAL, which
+ * means that only a sub-path of the commit is available.
+ */
+gboolean
+ostree_repo_load_commit (OstreeRepo *self,
+ const char *checksum,
+ GVariant **out_variant,
+ OstreeRepoCommitState *out_state,
+ GError **error)
+{
+ gboolean ret = FALSE;
+
+ if (out_variant)
+ {
+ if (!load_metadata_internal (self, OSTREE_OBJECT_TYPE_COMMIT, checksum, TRUE,
+ out_variant, NULL, NULL, NULL, error))
+ goto out;
+ }
+
+ if (out_state)
+ {
+ g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (checksum);
+ struct stat stbuf;
+
+ *out_state = 0;
+
+ if (fstatat (self->repo_dir_fd, commitpartial_path, &stbuf, 0) == 0)
+ {
+ *out_state |= OSTREE_REPO_COMMIT_STATE_PARTIAL;
+ }
+ else if (errno != ENOENT)
+ {
+ glnx_set_error_from_errno (error);
+ goto out;
+ }
+ }
+
+ ret = TRUE;
+ out:
+ return ret;
+}
+
+/**
* ostree_repo_list_objects:
* @self: Repo
* @flags: Flags controlling enumeration
diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h
index e6614dfa..c882356a 100644
--- a/src/libostree/ostree-repo.h
+++ b/src/libostree/ostree-repo.h
@@ -280,6 +280,16 @@ gboolean ostree_repo_load_variant_if_exists (OstreeRepo *self,
GVariant **out_variant,
GError **error);
+typedef enum {
+ OSTREE_REPO_COMMIT_STATE_PARTIAL = (1 << 0),
+} OstreeRepoCommitState;
+
+gboolean ostree_repo_load_commit (OstreeRepo *self,
+ const char *checksum,
+ GVariant **out_commit,
+ OstreeRepoCommitState *out_state,
+ GError **error);
+
gboolean ostree_repo_load_file (OstreeRepo *self,
const char *checksum,
GInputStream **out_input,
diff --git a/src/libotutil/ot-fs-utils.c b/src/libotutil/ot-fs-utils.c
index 040636bd..b0f41a64 100644
--- a/src/libotutil/ot-fs-utils.c
+++ b/src/libotutil/ot-fs-utils.c
@@ -22,6 +22,7 @@
#include "ot-fs-utils.h"
#include "libgsystem.h"
+#include "libglnx.h"
#include <sys/xattr.h>
#include <gio/gunixinputstream.h>
@@ -188,3 +189,20 @@ ot_openat_read_stream (int dfd,
out:
return ret;
}
+
+gboolean
+ot_ensure_unlinked_at (int dfd,
+ const char *path,
+ GError **error)
+{
+ if (unlinkat (dfd, path, 0) != 0)
+ {
+ if (G_UNLIKELY (errno != ENOENT))
+ {
+ glnx_set_error_from_errno (error);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
diff --git a/src/libotutil/ot-fs-utils.h b/src/libotutil/ot-fs-utils.h
index 0113da46..10686be6 100644
--- a/src/libotutil/ot-fs-utils.h
+++ b/src/libotutil/ot-fs-utils.h
@@ -57,4 +57,8 @@ gboolean ot_openat_read_stream (int dfd,
GCancellable *cancellable,
GError **error);
+gboolean ot_ensure_unlinked_at (int dfd,
+ const char *path,
+ GError **error);
+
G_END_DECLS
diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c
index ae1dcce4..8f340439 100644
--- a/src/ostree/ot-builtin-fsck.c
+++ b/src/ostree/ot-builtin-fsck.c
@@ -25,6 +25,7 @@
#include "ot-main.h"
#include "ot-builtins.h"
#include "ostree.h"
+#include "ostree-cmdprivate.h"
#include "otutil.h"
static gboolean opt_quiet;
@@ -242,6 +243,7 @@ ostree_builtin_fsck (int argc, char **argv, GCancellable *cancellable, GError **
GHashTableIter hash_iter;
gpointer key, value;
gboolean found_corruption = FALSE;
+ guint n_partial = 0;
gs_unref_hashtable GHashTable *objects = NULL;
gs_unref_hashtable GHashTable *commits = NULL;
@@ -267,11 +269,22 @@ ostree_builtin_fsck (int argc, char **argv, GCancellable *cancellable, GError **
GVariant *serialized_key = key;
const char *checksum;
OstreeObjectType objtype;
+ OstreeRepoCommitState commitstate = 0;
ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
- g_hash_table_insert (commits, g_variant_ref (serialized_key), serialized_key);
+ {
+ if (!ostree_repo_load_commit (repo, checksum, NULL, &commitstate, error))
+ goto out;
+
+ if (commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL)
+ {
+ n_partial++;
+ }
+ else
+ g_hash_table_insert (commits, g_variant_ref (serialized_key), serialized_key);
+ }
}
g_clear_pointer (&objects, (GDestroyNotify) g_hash_table_unref);
@@ -284,6 +297,11 @@ ostree_builtin_fsck (int argc, char **argv, GCancellable *cancellable, GError **
cancellable, error))
goto out;
+ if (n_partial > 0)
+ {
+ g_print ("%u partial commits not verified\n", n_partial);
+ }
+
if (found_corruption)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
diff --git a/tests/test-oldstyle-partial.sh b/tests/test-oldstyle-partial.sh
new file mode 100644
index 00000000..84460e97
--- /dev/null
+++ b/tests/test-oldstyle-partial.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# Copyright (C) 2015 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+set -e
+
+. $(dirname $0)/libtest.sh
+
+setup_fake_remote_repo1 "archive-z2"
+
+echo '1..1'
+
+cd ${test_tmpdir}
+rm repo -rf
+mkdir repo
+${CMD_PREFIX} ostree --repo=repo init
+${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo
+
+ostree --repo=repo pull origin main --subpath /baz
+ostree fsck --repo=repo >fsck.out
+assert_file_has_content fsck.out 'Verifying content integrity of 0 commit objects'
+assert_file_has_content fsck.out '1 partial commits not verified'