From f86de76db9218ab9eb182ccf7b4f4b60737b5db1 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Wed, 21 Jan 2015 13:38:14 +0100 Subject: [PATCH] pull: Implement --enable-syncfs Differently than fsync that is called after each file is modified, syncfs is used only once at the end of the pull to sync the file system which contains the repository. Results of pull on an empty repository: $ LANG=C sudo time ./ostree --repo=repo --disable-fsync pull master master 0 metadata, 0 content objects fetched; 83524 KiB; 6 delta parts fetched, transferred in 5 seconds 17.09user 2.41system 0:05.77elapsed 337%CPU (0avgtext+0avgdata 296132maxresident)k 0inputs+868584outputs (0major+102828minor)pagefaults 0swaps $ LANG=C sudo time ./ostree --repo=repo pull master master 0 metadata, 0 content objects fetched; 83524 KiB; 6 delta parts fetched, transferred in 401 seconds 17.31user 5.73system 6:41.33elapsed 5%CPU (0avgtext+0avgdata 296864maxresident)k 0inputs+868584outputs (0major+132664minor)pagefaults 0swaps $ LANG=C sudo time ./ostree --repo=repo --enable-syncfs pull master master 0 metadata, 0 content objects fetched; 83524 KiB; 6 delta parts fetched, transferred in 6 seconds 17.14user 2.57system 0:10.60elapsed 185%CPU (0avgtext+0avgdata 296212maxresident)k 0inputs+868584outputs (0major+86783minor)pagefaults 0swaps Signed-off-by: Giuseppe Scrivano --- src/libostree/ostree-repo-private.h | 1 + src/libostree/ostree-repo-pull.c | 9 +++++++++ src/libostree/ostree-repo.c | 16 ++++++++++++++++ src/libostree/ostree-repo.h | 3 +++ src/ostree/ot-builtin-pull.c | 8 ++++++++ tests/pull-test.sh | 1 + 6 files changed, 38 insertions(+) diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index b36e6d9405..bbc8b45638 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -60,6 +60,7 @@ struct OstreeRepo { gboolean writable; gboolean in_transaction; gboolean disable_fsync; + gboolean enable_syncfs; GHashTable *loose_object_devino_hash; GHashTable *updated_uncompressed_dirs; GHashTable *object_sizes; diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index b5b780eba3..421e0d8e98 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -2064,6 +2064,15 @@ ostree_repo_pull_with_options (OstreeRepo *self, } } + if (self->enable_syncfs) + { + if (syncfs (self->tmp_dir_fd) < 0) + { + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno), g_strerror (errno)); + goto out; + } + } + ret = TRUE; out: g_main_context_unref (pull_data->main_context); diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 22abe91423..90865d70a8 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -1418,6 +1418,22 @@ ostree_repo_set_disable_fsync (OstreeRepo *self, self->disable_fsync = disable_fsync; } +/** + * ostree_repo_set_enable_syncfs: + * @self: An #OstreeRepo + * @enable_syncfs: If %TRUE, use syncfs instead of fsync + * + * Use syncfs to synchronize the file system containing the repository + * instead of calling fsync on each file. + * Should offer better performance as the sync is done only once. + */ +void +ostree_repo_set_enable_syncfs (OstreeRepo *self, + gboolean enable_syncfs) +{ + self->enable_syncfs = enable_syncfs; +} + /** * ostree_repo_get_path: diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 9154b43175..062cf3d3c1 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -52,6 +52,9 @@ gboolean ostree_repo_open (OstreeRepo *self, void ostree_repo_set_disable_fsync (OstreeRepo *self, gboolean disable_fsync); +void ostree_repo_set_enable_syncfs (OstreeRepo *self, + gboolean enable_syncfs); + gboolean ostree_repo_is_system (OstreeRepo *repo); gboolean ostree_repo_create (OstreeRepo *self, diff --git a/src/ostree/ot-builtin-pull.c b/src/ostree/ot-builtin-pull.c index 0846605464..bd7c132df9 100644 --- a/src/ostree/ot-builtin-pull.c +++ b/src/ostree/ot-builtin-pull.c @@ -28,11 +28,13 @@ #include "otutil.h" static gboolean opt_disable_fsync; +static gboolean opt_enable_syncfs; static gboolean opt_mirror; static char* opt_subpath; static int opt_depth = 0; static GOptionEntry options[] = { + { "enable-syncfs", 0, 0, G_OPTION_ARG_NONE, &opt_enable_syncfs, "Use syncfs() instead of fsync()", NULL }, { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL }, { "mirror", 0, 0, G_OPTION_ARG_NONE, &opt_mirror, "Write refs suitable for a mirror", NULL }, { "subpath", 0, 0, G_OPTION_ARG_STRING, &opt_subpath, "Only pull the provided subpath", NULL }, @@ -63,6 +65,12 @@ ostree_builtin_pull (int argc, char **argv, GCancellable *cancellable, GError ** goto out; } + if (opt_enable_syncfs) + { + ostree_repo_set_disable_fsync (repo, TRUE); + ostree_repo_set_enable_syncfs (repo, TRUE); + } + if (opt_disable_fsync) ostree_repo_set_disable_fsync (repo, TRUE); diff --git a/tests/pull-test.sh b/tests/pull-test.sh index 5aee090f9d..68e6d2f7dd 100755 --- a/tests/pull-test.sh +++ b/tests/pull-test.sh @@ -39,6 +39,7 @@ function verify_initial_contents() { repo_init ${CMD_PREFIX} ostree --repo=repo pull origin main ${CMD_PREFIX} ostree --repo=repo pull origin:main +${CMD_PREFIX} ostree --repo=repo pull --enable-syncfs origin:main ${CMD_PREFIX} ostree --repo=repo fsck echo "ok pull"