From 07ec35ef03ef0e86956f4c0c20044166e0b389d9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 9 Aug 2016 15:36:37 -0400 Subject: [PATCH 01/34] libostree.sym: Add 2016.9 section We should remember to do this in the commit updating configure.ac. Closes: #453 Approved by: jlebon --- configure.ac | 1 + src/libostree/libostree.sym | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index aa4a42bd..6d322c9c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,5 @@ AC_PREREQ([2.63]) +dnl If incrementing the version here, remember to update libostree.sym too AC_INIT([ostree], [2016.8], [walters@verbum.org]) AC_CONFIG_HEADER([config.h]) AC_CONFIG_MACRO_DIR([buildutil]) diff --git a/src/libostree/libostree.sym b/src/libostree/libostree.sym index 3d05ac0e..22eb9eb2 100644 --- a/src/libostree/libostree.sym +++ b/src/libostree/libostree.sym @@ -346,14 +346,21 @@ global: ostree_repo_resolve_rev_ext; } LIBOSTREE_2016.6; -/* NOTE NOTE NOTE - * Versions above here are released. Only add symbols below this line. - * NOTE NOTE NOTE - */ - LIBOSTREE_2016.8 { global: ostree_checksum_b64_to_bytes; ostree_checksum_b64_from_bytes; ostree_repo_checkout_at; } LIBOSTREE_2016.7; + +/* NOTE NOTE NOTE + * Versions above here are released. Only add symbols below this line. + * NOTE NOTE NOTE + */ + +/* Remove comment when first new symbol is added +LIBOSTREE_2016.9 +global: + someostree_symbol_deleteme; +} LIBOSTREE_2016.8; + * Remove comment when first new symbol is added */ From 1e5ff71c498f85af209ccaf0eee3c4cff26f21ac Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Tue, 9 Aug 2016 11:45:25 -0700 Subject: [PATCH 02/34] deltas: Handle cleanup of fd array properly If there's an early error, part_temp_fds will be NULL and dereferencing the len member will segfault. Closes: #454 Closes: #448 Approved by: cgwalters --- .../ostree-repo-static-delta-compilation.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/libostree/ostree-repo-static-delta-compilation.c b/src/libostree/ostree-repo-static-delta-compilation.c index 8b388094..7ef7680d 100644 --- a/src/libostree/ostree-repo-static-delta-compilation.c +++ b/src/libostree/ostree-repo-static-delta-compilation.c @@ -1584,13 +1584,14 @@ ostree_repo_static_delta_generate (OstreeRepo *self, ret = TRUE; out: - for (i = 0; i < part_temp_fds->len; i++) - { - int fd = g_array_index (part_temp_fds, int, i); - if (fd == -1) - continue; - (void) close (fd); - } + if (part_temp_fds) + for (i = 0; i < part_temp_fds->len; i++) + { + int fd = g_array_index (part_temp_fds, int, i); + if (fd == -1) + continue; + (void) close (fd); + } g_clear_pointer (&builder.parts, g_ptr_array_unref); g_clear_pointer (&builder.fallback_objects, g_ptr_array_unref); return ret; From c3c07a2d496f43cdda0a8f5617c6373d961f67df Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Tue, 9 Aug 2016 11:46:30 -0700 Subject: [PATCH 03/34] deltas: Use F_DUPFD_CLOEXEC properly You need to supply an argument to F_DUPFD_CLOEXEC or fcntl will return EINVAL. Use 3 as the minimum fd number as is standard. Closes: #454 Closes: #448 Approved by: cgwalters --- src/libostree/ostree-repo-static-delta-compilation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libostree/ostree-repo-static-delta-compilation.c b/src/libostree/ostree-repo-static-delta-compilation.c index 7ef7680d..188f467d 100644 --- a/src/libostree/ostree-repo-static-delta-compilation.c +++ b/src/libostree/ostree-repo-static-delta-compilation.c @@ -1362,7 +1362,7 @@ ostree_repo_static_delta_generate (OstreeRepo *self, } else { - tmp_dfd = fcntl (self->tmp_dir_fd, F_DUPFD_CLOEXEC); + tmp_dfd = fcntl (self->tmp_dir_fd, F_DUPFD_CLOEXEC, 3); if (tmp_dfd < 0) { glnx_set_error_from_errno (error); From 80c573478b5bfa72254d9f3fbdb2c634bbb1c7af Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Tue, 9 Aug 2016 09:41:48 -0700 Subject: [PATCH 04/34] pull-local: Support requiring static deltas Add the --require-static-deltas option like pull to ensure static deltas are processed for local pulls. Closes: #447 Closes: #448 Approved by: cgwalters --- src/ostree/ot-builtin-pull-local.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ostree/ot-builtin-pull-local.c b/src/ostree/ot-builtin-pull-local.c index b6f649f6..5401a281 100644 --- a/src/ostree/ot-builtin-pull-local.c +++ b/src/ostree/ot-builtin-pull-local.c @@ -33,6 +33,7 @@ static char *opt_remote; static gboolean opt_disable_fsync; static gboolean opt_untrusted; +static gboolean opt_require_static_deltas; static gboolean opt_gpg_verify; static gboolean opt_gpg_verify_summary; static int opt_depth = 0; @@ -41,6 +42,7 @@ static GOptionEntry options[] = { { "remote", 0, 0, G_OPTION_ARG_STRING, &opt_remote, "Add REMOTE to refspec", "REMOTE" }, { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL }, { "untrusted", 0, 0, G_OPTION_ARG_NONE, &opt_untrusted, "Do not trust source", NULL }, + { "require-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_require_static_deltas, "Require static deltas", NULL }, { "gpg-verify", 0, 0, G_OPTION_ARG_NONE, &opt_gpg_verify, "GPG verify commits (must specify --remote)", NULL }, { "gpg-verify-summary", 0, 0, G_OPTION_ARG_NONE, &opt_gpg_verify_summary, "GPG verify summary (must specify --remote)", NULL }, { "depth", 0, 0, G_OPTION_ARG_INT, &opt_depth, "Traverse DEPTH parents (-1=infinite) (default: 0)", "DEPTH" }, @@ -146,6 +148,8 @@ ostree_builtin_pull_local (int argc, char **argv, GCancellable *cancellable, GEr if (opt_remote) g_variant_builder_add (&builder, "{s@v}", "override-remote-name", g_variant_new_variant (g_variant_new_string (opt_remote))); + g_variant_builder_add (&builder, "{s@v}", "require-static-deltas", + g_variant_new_variant (g_variant_new_boolean (opt_require_static_deltas))); if (opt_gpg_verify) g_variant_builder_add (&builder, "{s@v}", "gpg-verify", g_variant_new_variant (g_variant_new_boolean (TRUE))); From 2a810fbef9968421ce5bb83d5eedb01a46581a3f Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Tue, 9 Aug 2016 15:39:41 -0700 Subject: [PATCH 05/34] tests: Ensure deltas for pulling when needed When testing pulling of deltas, use the new --require-static-deltas option to pull-local to ensure that deltas are actually used. To support the require-static-deltas mode, the summary in the remote repo must be generated. Closes: #447 Closes: #448 Approved by: cgwalters --- tests/test-delta.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/test-delta.sh b/tests/test-delta.sh index 1a8f8139..f8209651 100755 --- a/tests/test-delta.sh +++ b/tests/test-delta.sh @@ -158,8 +158,10 @@ assert_streq "${totalsize_legacy_big}" "${totalsize_legacy_little}" echo 'ok heuristic endian detection' +${CMD_PREFIX} ostree --repo=repo summary -u + mkdir repo2 && ${CMD_PREFIX} ostree --repo=repo2 init --mode=archive-z2 -${CMD_PREFIX} ostree --repo=repo2 pull-local repo ${newrev} +${CMD_PREFIX} ostree --repo=repo2 pull-local --require-static-deltas repo ${newrev} ${CMD_PREFIX} ostree --repo=repo2 fsck ${CMD_PREFIX} ostree --repo=repo2 ls ${newrev} >/dev/null @@ -223,10 +225,12 @@ assert_streq "${totalsize_empty}" "Total Uncompressed Size: 0 (0 bytes)" echo 'ok generate + show empty delta part' +${CMD_PREFIX} ostree --repo=repo summary -u + rm -rf repo2 mkdir repo2 && ${CMD_PREFIX} ostree --repo=repo2 init --mode=archive-z2 ${CMD_PREFIX} ostree --repo=repo2 pull-local repo ${newrev} -${CMD_PREFIX} ostree --repo=repo2 pull-local repo ${samerev} +${CMD_PREFIX} ostree --repo=repo2 pull-local --require-static-deltas repo ${samerev} ${CMD_PREFIX} ostree --repo=repo2 fsck ${CMD_PREFIX} ostree --repo=repo2 ls ${samerev} >/dev/null From 1caef17c7f9f411317a17c91dba48d54049a4d54 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Fri, 5 Aug 2016 06:52:55 -0700 Subject: [PATCH 06/34] pull: Disable static deltas by default for local pulls For local pulls there's no benefit pulling the static delta over the individual object files since there's no HTTP overhead. Furthermore, processing deltas always generates the objects whereas a standard pull ensures that the exact object files are copied. Using deltas also prevents hardlinking the objects if the repos exist on the same filesystem. Closes: #447 Closes: #448 Approved by: cgwalters --- src/libostree/ostree-repo-pull.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 712f17dc..5fe30e08 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -2413,6 +2413,12 @@ ostree_repo_pull_with_options (OstreeRepo *self, } } + /* For local pulls, default to disabling static deltas so that the + * exact object files are copied. + */ + if (pull_data->remote_repo_local && !require_static_deltas) + disable_static_deltas = TRUE; + pull_data->static_delta_superblocks = g_ptr_array_new_with_free_func ((GDestroyNotify)g_variant_unref); { From 7ed2f1e5af303ffa5e697d8c1dfd1fc0671818f8 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Tue, 9 Aug 2016 15:41:36 -0700 Subject: [PATCH 07/34] tests: Test that local pulls do not use deltas Pulls from local repos now default to disabling static deltas so that objects are copied. To check this is the case, see if the object files are hardlinked after pulling. Closes: #447 Closes: #448 Approved by: cgwalters --- tests/test-local-pull.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/test-local-pull.sh b/tests/test-local-pull.sh index a9ac1278..9e8c8a00 100755 --- a/tests/test-local-pull.sh +++ b/tests/test-local-pull.sh @@ -26,7 +26,7 @@ unset OSTREE_GPG_HOME skip_without_user_xattrs -echo "1..7" +echo "1..8" setup_test_repository "archive-z2" echo "ok setup" @@ -95,3 +95,13 @@ ${OSTREE} summary -u update --gpg-sign=${TEST_GPG_KEYID_1} --gpg-homedir=${TEST_ ${CMD_PREFIX} ostree --repo=repo6 pull-local --remote=origin --gpg-verify-summary repo test2 2>&1 echo "ok --gpg-verify-summary" + +mkdir repo7 +${CMD_PREFIX} ostree --repo=repo7 init --mode="archive-z2" +${CMD_PREFIX} ostree --repo=repo7 pull-local repo +${CMD_PREFIX} ostree --repo=repo7 fsck +for src_object in `find repo/objects -name '*.filez'`; do + dst_object=${src_object/repo/repo7} + assert_files_hardlinked "$src_object" "$dst_object" +done +echo "ok pull-local z2 to z2 default hardlink" From fd1a044d6e75b336ea880530979067926c9b0a09 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Tue, 9 Aug 2016 15:23:04 +0200 Subject: [PATCH 08/34] Move ostree-* executables to /usr/lib/ostree Why not to use libexecdir? Because this directory does not exist on some distros or paths between distros varies. There are several reasons why a well known path is prefered, for example when generating a kernel command line: init=${ostree}/usr/lib/ostree-boot/ostree-prepare-root In addition this saves us some typing in a console when wanting to access the "ostree" cmd line. Closes: #449 Approved by: cgwalters --- Makefile-boot.am | 2 +- Makefile-decls.am | 2 ++ Makefile-switchroot.am | 6 ++++-- src/boot/dracut/module-setup.sh | 4 ++-- src/boot/mkinitcpio/ostree | 4 ++-- src/boot/ostree-prepare-root.service | 2 +- src/boot/ostree-remount.service | 2 +- src/libostree/ostree-bootloader-grub2.c | 2 +- 8 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Makefile-boot.am b/Makefile-boot.am index 508f59bc..8d7ade07 100644 --- a/Makefile-boot.am +++ b/Makefile-boot.am @@ -53,7 +53,7 @@ grub2configdir = $(sysconfdir)/grub.d INSTALL_DATA_HOOKS += install-grub2-config-hook else # We're using our internal generator -libexec_SCRIPTS = src/boot/grub2/ostree-grub-generator +ostree_boot_SCRIPTS = src/boot/grub2/ostree-grub-generator endif EXTRA_DIST += src/boot/dracut/module-setup.sh \ diff --git a/Makefile-decls.am b/Makefile-decls.am index f7ebd422..d7e61355 100644 --- a/Makefile-decls.am +++ b/Makefile-decls.am @@ -43,6 +43,8 @@ gir_DATA = typelibdir = $(libdir)/girepository-1.0 typelib_DATA = gsettings_SCHEMAS = +ostree_bootdir = /usr/lib/ostree +ostree_boot_PROGRAMS = # This is a special facility to chain together hooks easily INSTALL_DATA_HOOKS = diff --git a/Makefile-switchroot.am b/Makefile-switchroot.am index ef837ced..f79553eb 100644 --- a/Makefile-switchroot.am +++ b/Makefile-switchroot.am @@ -16,8 +16,10 @@ # Boston, MA 02111-1307, USA. if BUILDOPT_SYSTEMD -sbin_PROGRAMS += ostree-prepare-root -sbin_PROGRAMS += ostree-remount + +ostree_boot_PROGRAMS += ostree-prepare-root +ostree_boot_PROGRAMS += ostree-remount + noinst_LTLIBRARIES += libswitchroot-mountutil.la endif diff --git a/src/boot/dracut/module-setup.sh b/src/boot/dracut/module-setup.sh index d8ee05ba..20c828dc 100755 --- a/src/boot/dracut/module-setup.sh +++ b/src/boot/dracut/module-setup.sh @@ -20,7 +20,7 @@ # Boston, MA 02111-1307, USA. check() { - if [[ -x $systemdutildir/systemd ]] && [[ -x /usr/sbin/ostree-prepare-root ]]; then + if [[ -x $systemdutildir/systemd ]] && [[ -x /usr/lib/ostree/ostree-prepare-root ]]; then return 255 fi @@ -32,7 +32,7 @@ depends() { } install() { - dracut_install ostree-prepare-root + dracut_install /usr/lib/ostree/ostree-prepare-root inst_simple "${systemdsystemunitdir}/ostree-prepare-root.service" mkdir -p "${initdir}${systemdsystemconfdir}/initrd-switch-root.target.wants" ln_r "${systemdsystemunitdir}/ostree-prepare-root.service" \ diff --git a/src/boot/mkinitcpio/ostree b/src/boot/mkinitcpio/ostree index 46748370..7f21cacd 100644 --- a/src/boot/mkinitcpio/ostree +++ b/src/boot/mkinitcpio/ostree @@ -1,8 +1,8 @@ #!/bin/bash build() { - add_binary /usr/sbin/ostree-prepare-root - add_binary /usr/sbin/ostree-remount + add_binary /usr/lib/ostree/ostree-prepare-root + add_binary /usr/lib/ostree/ostree-remount add_file /usr/lib/systemd/system/ostree-prepare-root.service add_symlink /usr/lib/systemd/system/initrd-switch-root.target.wants/ostree-prepare-root.service \ diff --git a/src/boot/ostree-prepare-root.service b/src/boot/ostree-prepare-root.service index dbc7b30a..e0659d10 100644 --- a/src/boot/ostree-prepare-root.service +++ b/src/boot/ostree-prepare-root.service @@ -27,7 +27,7 @@ Before=plymouth-switch-root.service [Service] Type=oneshot -ExecStart=/usr/sbin/ostree-prepare-root /sysroot +ExecStart=/usr/lib/ostree/ostree-prepare-root /sysroot StandardInput=null StandardOutput=syslog StandardError=syslog+console diff --git a/src/boot/ostree-remount.service b/src/boot/ostree-remount.service index 196649b7..61dd5fa8 100644 --- a/src/boot/ostree-remount.service +++ b/src/boot/ostree-remount.service @@ -31,7 +31,7 @@ Before=systemd-tmpfiles-setup.service [Service] Type=oneshot -ExecStart=/usr/sbin/ostree-remount +ExecStart=/usr/lib/ostree/ostree-remount StandardInput=null StandardOutput=syslog StandardError=syslog+console diff --git a/src/libostree/ostree-bootloader-grub2.c b/src/libostree/ostree-bootloader-grub2.c index b2c68ac9..f3dc8e16 100644 --- a/src/libostree/ostree-bootloader-grub2.c +++ b/src/libostree/ostree-bootloader-grub2.c @@ -315,7 +315,7 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader, use_system_grub2_mkconfig = FALSE; } else - grub_exec = use_system_grub2_mkconfig ? GRUB2_MKCONFIG_PATH : LIBEXECDIR "/ostree-grub-generator"; + grub_exec = use_system_grub2_mkconfig ? GRUB2_MKCONFIG_PATH : "/usr/lib/ostree/ostree-grub-generator"; if (use_system_grub2_mkconfig && ostree_sysroot_get_booted_deployment (self->sysroot) == NULL && g_file_has_parent (self->sysroot->path, NULL)) From 182cb273c66699c12a5a465bbc1119503463fa7d Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Thu, 11 Aug 2016 10:29:56 -0400 Subject: [PATCH 09/34] ostree_bootdir: prepend $(prefix) to path Otherwise we break local installs. Closes: #456 Approved by: cgwalters --- Makefile-decls.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile-decls.am b/Makefile-decls.am index d7e61355..aa93a5f2 100644 --- a/Makefile-decls.am +++ b/Makefile-decls.am @@ -43,7 +43,7 @@ gir_DATA = typelibdir = $(libdir)/girepository-1.0 typelib_DATA = gsettings_SCHEMAS = -ostree_bootdir = /usr/lib/ostree +ostree_bootdir = $(prefix)/usr/lib/ostree ostree_boot_PROGRAMS = # This is a special facility to chain together hooks easily From 0728304a8a4669f4b4501236d5daa89543f141ab Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Thu, 11 Aug 2016 11:46:44 -0400 Subject: [PATCH 10/34] ostree_bootdir: properly preprend $(prefix) Closes: #457 Approved by: cgwalters --- Makefile-decls.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile-decls.am b/Makefile-decls.am index aa93a5f2..df635706 100644 --- a/Makefile-decls.am +++ b/Makefile-decls.am @@ -43,7 +43,7 @@ gir_DATA = typelibdir = $(libdir)/girepository-1.0 typelib_DATA = gsettings_SCHEMAS = -ostree_bootdir = $(prefix)/usr/lib/ostree +ostree_bootdir = $(prefix)/lib/ostree ostree_boot_PROGRAMS = # This is a special facility to chain together hooks easily From fa59f5adfb85c91923b8f3f24dce884dafe8f2a4 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 10 Aug 2016 15:11:14 -0400 Subject: [PATCH 11/34] manual/repo.md: reword bits about the summary file Closes: #459 Approved by: cgwalters --- docs/manual/repo.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/manual/repo.md b/docs/manual/repo.md index bce7e0c9..c23a4453 100644 --- a/docs/manual/repo.md +++ b/docs/manual/repo.md @@ -113,7 +113,7 @@ that. A later addition to OSTree is the concept of a "summary" file, created via the `ostree summary -u` command. This was introduced for a few -reasons. A primary use case is to be a target a +reasons. A primary use case is to be compatible with [Metalink](https://en.wikipedia.org/wiki/Metalink), which requires a single file with a known checksum as a target. @@ -126,12 +126,12 @@ The summary file primarily contains two mappings: This currently means that it grows linearly with both items. On the other hand, using the summary file, a client can enumerate branches. -Further, the summary file is fetched over e.g. pinned TLS, this -creates a strong end-to-end verification of the commit or static delta. +Further, fetching the summary file over e.g. pinned TLS creates a strong +end-to-end verification of the commit or static delta. -The summary file can also be GPG signed (detached), and currently this -is the only way provide GPG signatures (transitively) on deltas. +The summary file can also be GPG signed (detached). This is currently +the only way to provide GPG signatures (transitively) on deltas. If a repository administrator creates a summary file, they must -thereafter run `ostree summary -u` to update it whenever a commit is -made or a static delta is generated. +thereafter run `ostree summary -u` to update it whenever a ref is +updated or a static delta is generated. From b1d13bb356f67e9dd2d3e1a4c96f1ac136399c59 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Thu, 11 Aug 2016 12:39:19 -0700 Subject: [PATCH 12/34] repo: Really ignore progress changed user data The documentation says this is ignored, implying that you should pass NULL to it. However, the function immediately returns in this case even though the argument isn't used anywhere. Closes: #458 Approved by: cgwalters --- src/libostree/ostree-repo.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 62415f06..a41f29c9 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -3839,10 +3839,6 @@ ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress guint fetched_delta_parts; guint total_delta_parts; - /* Historical note; we used to treat this as a GSConsole instance */ - if (user_data == NULL) - return; - buf = g_string_new (""); status = ostree_async_progress_get_status (progress); From e5cae8140465246d408d41b02ac367ece37b9eb9 Mon Sep 17 00:00:00 2001 From: Adam Miller Date: Fri, 12 Aug 2016 14:37:18 -0500 Subject: [PATCH 13/34] fix typo in docs/manual/atomic-upgrades.md Signed-off-by: Adam Miller Closes: #460 Approved by: cgwalters --- docs/manual/atomic-upgrades.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/manual/atomic-upgrades.md b/docs/manual/atomic-upgrades.md index 40515b83..a60656a8 100644 --- a/docs/manual/atomic-upgrades.md +++ b/docs/manual/atomic-upgrades.md @@ -70,7 +70,7 @@ configuration, and the new deployment (based on its `/usr/etc`). At this point, a new deployment directory has been created as a hardlink farm; the running system is untouched, and the bootloader -configuration is untouched. We want to add this deployment o the +configuration is untouched. We want to add this deployment to the "deployment list". To support a more general case, OSTree supports atomic transitioning From f9933a2631095afe42dfa9cbf7ab69209453cb2b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 12 Aug 2016 17:10:54 -0400 Subject: [PATCH 14/34] prune: Elaborate on what formats are accepted by dates Inquiring minds want to know. Closes: #461 Approved by: giuseppe --- man/ostree-prune.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/man/ostree-prune.xml b/man/ostree-prune.xml index 9e8cc873..516da2ba 100644 --- a/man/ostree-prune.xml +++ b/man/ostree-prune.xml @@ -93,8 +93,11 @@ Boston, MA 02111-1307, USA. =DATE - All commits older than DATE will be pruned. - + All commits older than DATE will be + pruned. The format of DATE is the same as that + accepted by GNU date utility - for more information + see info date. + From 3c6d2bc12040475b65fa80280a706f773b30af3a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 12 Aug 2016 17:15:59 -0400 Subject: [PATCH 15/34] fixup! fix typo in docs/manual/atomic-upgrades.md Closes: #461 Approved by: giuseppe --- man/ostree-prune.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/ostree-prune.xml b/man/ostree-prune.xml index 516da2ba..60e19a5b 100644 --- a/man/ostree-prune.xml +++ b/man/ostree-prune.xml @@ -95,7 +95,7 @@ Boston, MA 02111-1307, USA. All commits older than DATE will be pruned. The format of DATE is the same as that - accepted by GNU date utility - for more information + accepted by GNU date utility - for more information see info date. From 3469161e4157d715285395e80202c9d2dbd43ce8 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 16 Aug 2016 13:07:51 -0400 Subject: [PATCH 16/34] test-rofiles-fuse: Actually check out via hardlinks The test suite was actually doing something before, just not quite what I intended. Without `-U` for bare-user checkouts we end up doing a copy. Now, a future commit will change how rofiles work, which would cause the test suite to permit inplace mutation for non-hardlinked files. So let's ensure they *are* hardlinked. Closes: #462 Approved by: jlebon --- tests/test-rofiles-fuse.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-rofiles-fuse.sh b/tests/test-rofiles-fuse.sh index 736747f7..4dfec514 100755 --- a/tests/test-rofiles-fuse.sh +++ b/tests/test-rofiles-fuse.sh @@ -30,7 +30,7 @@ echo "1..6" mkdir mnt -$OSTREE checkout test2 checkout-test2 +$OSTREE checkout -U test2 checkout-test2 rofiles-fuse checkout-test2 mnt cleanup_fuse() { From 77af6844d8330b31d58080076afb31e08974ce09 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 16 Aug 2016 09:26:16 -0400 Subject: [PATCH 17/34] rofiles-fuse: Rework to be based on nlink Programs like `useradd` try to `open(/etc/passwd, O_RDWR)` to append, which didn't work with rofiles-fuse. Thinking about this, I realized that there's a simpler algorithm for "can we write to this file" which is "does it have a hardlink count <= 1"? Switching to this both drops complexity (we no longer need to keep a hash table of files we created), and also lets useradd work. Closes: #462 Approved by: jlebon --- src/rofiles-fuse/main.c | 131 +++++++++++++--------------------------- 1 file changed, 43 insertions(+), 88 deletions(-) diff --git a/src/rofiles-fuse/main.c b/src/rofiles-fuse/main.c index 8468276d..ac44a438 100644 --- a/src/rofiles-fuse/main.c +++ b/src/rofiles-fuse/main.c @@ -39,7 +39,6 @@ // Global to store our read-write path static int basefd = -1; -static GHashTable *created_devino_hash = NULL; static inline const char * ENSURE_RELPATH (const char *path) @@ -50,51 +49,6 @@ ENSURE_RELPATH (const char *path) return path; } -typedef struct { - dev_t dev; - ino_t ino; -} DevIno; - -static guint -devino_hash (gconstpointer a) -{ - DevIno *a_i = (gpointer)a; - return (guint) (a_i->dev + a_i->ino); -} - -static int -devino_equal (gconstpointer a, - gconstpointer b) -{ - DevIno *a_i = (gpointer)a; - DevIno *b_i = (gpointer)b; - return a_i->dev == b_i->dev - && a_i->ino == b_i->ino; -} - -static gboolean -devino_set_contains (dev_t dev, ino_t ino) -{ - DevIno devino = { dev, ino }; - return g_hash_table_contains (created_devino_hash, &devino); -} - -static gboolean -devino_set_insert (dev_t dev, ino_t ino) -{ - DevIno *devino = g_new (DevIno, 1); - devino->dev = dev; - devino->ino = ino; - return g_hash_table_add (created_devino_hash, devino); -} - -static gboolean -devino_set_remove (dev_t dev, ino_t ino) -{ - DevIno devino = { dev, ino }; - return g_hash_table_remove (created_devino_hash, &devino); -} - static int callback_getattr (const char *path, struct stat *st_data) { @@ -188,15 +142,7 @@ callback_mkdir (const char *path, mode_t mode) static int callback_unlink (const char *path) { - struct stat stbuf; path = ENSURE_RELPATH (path); - - if (fstatat (basefd, path, &stbuf, AT_SYMLINK_NOFOLLOW) == 0) - { - if (!S_ISDIR (stbuf.st_mode)) - devino_set_remove (stbuf.st_dev, stbuf.st_ino); - } - if (unlinkat (basefd, path, 0) == -1) return -errno; return 0; @@ -250,6 +196,12 @@ callback_link (const char *from, const char *to) return 0; } +static gboolean +stbuf_is_regfile_hardlinked (struct stat *stbuf) +{ + return S_ISREG (stbuf->st_mode) && stbuf->st_nlink > 1; +} + static int can_write (const char *path) { @@ -261,11 +213,8 @@ can_write (const char *path) else return -errno; } - if (!S_ISDIR (stbuf.st_mode)) - { - if (!devino_set_contains (stbuf.st_dev, stbuf.st_ino)) - return -EROFS; - } + if (stbuf_is_regfile_hardlinked (&stbuf)) + return -EROFS; return 0; } @@ -334,41 +283,49 @@ callback_utime (const char *path, struct utimbuf *buf) static int do_open (const char *path, mode_t mode, struct fuse_file_info *finfo) { - const int flags = finfo->flags & O_ACCMODE; int fd; struct stat stbuf; - /* Support read only opens */ - G_STATIC_ASSERT (O_RDONLY == 0); - path = ENSURE_RELPATH (path); - if (flags == 0) - fd = openat (basefd, path, flags); + if ((finfo->flags & O_ACCMODE) == O_RDONLY) + { + /* Read */ + fd = openat (basefd, path, finfo->flags); + if (fd == -1) + return -errno; + } else { - const int forced_excl_flags = flags | O_CREAT | O_EXCL; - /* Do an exclusive open, don't allow writable fds for existing - files */ - fd = openat (basefd, path, forced_excl_flags, mode); - /* If they didn't specify O_EXCL, give them EROFS if the file - * exists. - */ - if (fd == -1 && (flags & O_EXCL) == 0) - { - if (errno == EEXIST) - errno = EROFS; - } - else if (fd != -1) - { - if (fstat (fd, &stbuf) == -1) - return -errno; - devino_set_insert (stbuf.st_dev, stbuf.st_ino); - } - } + /* Write */ - if (fd == -1) - return -errno; + /* We need to specially handle O_TRUNC */ + fd = openat (basefd, path, finfo->flags & ~O_TRUNC, mode); + if (fd == -1) + return -errno; + + if (fstat (fd, &stbuf) == -1) + { + (void) close (fd); + return -errno; + } + + if (stbuf_is_regfile_hardlinked (&stbuf)) + { + (void) close (fd); + return -EROFS; + } + + /* Handle O_TRUNC here only after verifying hardlink state */ + if (finfo->flags & O_TRUNC) + { + if (ftruncate (fd, 0) == -1) + { + (void) close (fd); + return -errno; + } + } + } finfo->fh = fd; @@ -594,8 +551,6 @@ main (int argc, char *argv[]) exit (EXIT_FAILURE); } - created_devino_hash = g_hash_table_new_full (devino_hash, devino_equal, g_free, NULL); - fuse_main (args.argc, args.argv, &callback_oper, NULL); return 0; From e005da74efa68b257f5600c074aa13c66269311e Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Thu, 18 Aug 2016 10:34:50 -0400 Subject: [PATCH 18/34] pull_with_options: fix remote parameter name & desc Closes: #465 Approved by: cgwalters --- src/libostree/ostree-repo-pull.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 5fe30e08..f273c87e 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -2159,7 +2159,7 @@ repo_remote_fetch_summary (OstreeRepo *self, /** * ostree_repo_pull_with_options: * @self: Repo - * @remote_name: Name of remote + * @remote_name_or_baseurl: Name of remote or file:// url * @options: A GVariant a{sv} with an extensible set of flags. * @progress: (allow-none): Progress * @cancellable: Cancellable From 21d3063fcfa47fe475561edb6fada4e5b6b346bd Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Thu, 18 Aug 2016 10:35:31 -0400 Subject: [PATCH 19/34] pull_with_options: allow GPG verification override We used to only look at the "gpg-verify" and "gpg-verify-summary" options when we're passed a local URL. Make these options also have an effect in the configured remote case. Closes: #465 Approved by: cgwalters --- src/libostree/ostree-repo-pull.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index f273c87e..43ec2ff6 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -2211,8 +2211,8 @@ ostree_repo_pull_with_options (OstreeRepo *self, GSource *update_timeout = NULL; gboolean disable_static_deltas = FALSE; gboolean require_static_deltas = FALSE; - gboolean opt_gpg_verify = FALSE; - gboolean opt_gpg_verify_summary = FALSE; + gboolean opt_gpg_verify_set = FALSE; + gboolean opt_gpg_verify_summary_set = FALSE; const char *url_override = NULL; if (options) @@ -2224,8 +2224,10 @@ ostree_repo_pull_with_options (OstreeRepo *self, flags = flags_i; (void) g_variant_lookup (options, "subdir", "&s", &dir_to_pull); (void) g_variant_lookup (options, "override-remote-name", "s", &pull_data->remote_name); - (void) g_variant_lookup (options, "gpg-verify", "b", &opt_gpg_verify); - (void) g_variant_lookup (options, "gpg-verify-summary", "b", &opt_gpg_verify_summary); + opt_gpg_verify_set = + g_variant_lookup (options, "gpg-verify", "b", &pull_data->gpg_verify); + opt_gpg_verify_summary_set = + g_variant_lookup (options, "gpg-verify-summary", "b", &pull_data->gpg_verify_summary); (void) g_variant_lookup (options, "depth", "i", &pull_data->maxdepth); (void) g_variant_lookup (options, "disable-static-deltas", "b", &disable_static_deltas); (void) g_variant_lookup (options, "require-static-deltas", "b", &require_static_deltas); @@ -2286,9 +2288,6 @@ ostree_repo_pull_with_options (OstreeRepo *self, /* For compatibility with pull-local, don't gpg verify local * pulls by default. */ - pull_data->gpg_verify = opt_gpg_verify; - pull_data->gpg_verify_summary = opt_gpg_verify_summary; - if ((pull_data->gpg_verify || pull_data->gpg_verify_summary) && pull_data->remote_name == NULL) { @@ -2300,12 +2299,18 @@ ostree_repo_pull_with_options (OstreeRepo *self, else { pull_data->remote_name = g_strdup (remote_name_or_baseurl); - if (!ostree_repo_remote_get_gpg_verify (self, pull_data->remote_name, - &pull_data->gpg_verify, error)) - goto out; - if (!ostree_repo_remote_get_gpg_verify_summary (self, pull_data->remote_name, - &pull_data->gpg_verify_summary, error)) - goto out; + + /* Fetch GPG verification settings from remote if it wasn't already + * explicitly set in the options. */ + if (!opt_gpg_verify_set) + if (!ostree_repo_remote_get_gpg_verify (self, pull_data->remote_name, + &pull_data->gpg_verify, error)) + goto out; + + if (!opt_gpg_verify_summary_set) + if (!ostree_repo_remote_get_gpg_verify_summary (self, pull_data->remote_name, + &pull_data->gpg_verify_summary, error)) + goto out; } pull_data->phase = OSTREE_PULL_PHASE_FETCHING_REFS; From 76166cb52eae8b2637503e5cac9743b283d429be Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Thu, 18 Aug 2016 10:37:11 -0400 Subject: [PATCH 20/34] pull_with_options: fix stray return FALSE Closes: #465 Approved by: cgwalters --- src/libostree/ostree-repo-pull.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 43ec2ff6..f990c6b2 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -2676,7 +2676,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (G_UNLIKELY (errno != EEXIST)) { glnx_set_error_from_errno (error); - return FALSE; + goto out; } } From 05ac14326c824748d37aaabf045856c478b82b05 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 24 Aug 2016 20:18:09 -0400 Subject: [PATCH 21/34] pull: Make .commitpartial files world readable In CentOS, these happened to appear in a repo that is served via rsync, and having them not be world-readable caused mirroring tools to fail. They aren't secret, so don't make them so. Closes: #468 Approved by: giuseppe --- src/libostree/ostree-repo-pull.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index f990c6b2..066233be 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -423,7 +423,7 @@ write_commitpartial_for (OtPullData *pull_data, g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (checksum); glnx_fd_close int fd = -1; - fd = openat (pull_data->repo->repo_dir_fd, commitpartial_path, O_EXCL | O_CREAT | O_WRONLY | O_CLOEXEC | O_NOCTTY, 0600); + fd = openat (pull_data->repo->repo_dir_fd, commitpartial_path, O_EXCL | O_CREAT | O_WRONLY | O_CLOEXEC | O_NOCTTY, 0644); if (fd == -1) { if (errno != EEXIST) From 683e060099025f4030ebeab445471a9dbc978e10 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 25 Aug 2016 13:16:46 -0400 Subject: [PATCH 22/34] repo: Add prefixes to errors for querying size/deleting I hit these while causing errors in prune. Let's add the specific object we were looking for. Closes: #471 Approved by: jlebon --- src/libostree/ostree-repo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index a41f29c9..5e9818fd 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -3136,7 +3136,7 @@ ostree_repo_delete_object (OstreeRepo *self, while (G_UNLIKELY (res == -1 && errno == EINTR)); if (G_UNLIKELY (res == -1)) { - glnx_set_error_from_errno (error); + glnx_set_prefix_error_from_errno (error, "Deleting object %s.%s", sha256, ostree_object_type_to_string (objtype)); goto out; } @@ -3444,7 +3444,7 @@ ostree_repo_query_object_storage_size (OstreeRepo *self, while (G_UNLIKELY (res == -1 && errno == EINTR)); if (G_UNLIKELY (res == -1)) { - glnx_set_error_from_errno (error); + glnx_set_prefix_error_from_errno (error, "Querying object %s.%s", sha256, ostree_object_type_to_string (objtype)); goto out; } From 3ef4cc2e5b9ed36c5b9d11a75162a20d3868ded6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 25 Aug 2016 11:53:27 -0400 Subject: [PATCH 23/34] lib: Add an API to list only "our" objects, fix prune to use it When doing a prune, we should not try to delete objects in parent repos, since it'll fail. There is a bigger discussion about the semantics of `parent=` to be had, but this will fix trying to use `ostree prune --repo=/ostree/repo/extensions/rpmostree/pkgcache`. Closes: https://github.com/ostreedev/ostree/issues/467 Closes: #471 Approved by: jlebon --- src/libostree/ostree-repo-prune.c | 4 ++-- src/libostree/ostree-repo.c | 2 +- src/libostree/ostree-repo.h | 4 +++- tests/test-prune.sh | 38 ++++++++++++++++++++++++++++++- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/libostree/ostree-repo-prune.c b/src/libostree/ostree-repo-prune.c index 8c5d13e9..66170d4d 100644 --- a/src/libostree/ostree-repo-prune.c +++ b/src/libostree/ostree-repo-prune.c @@ -337,8 +337,8 @@ ostree_repo_prune (OstreeRepo *self, } } - if (!ostree_repo_list_objects (self, OSTREE_REPO_LIST_OBJECTS_ALL, &objects, - cancellable, error)) + if (!ostree_repo_list_objects (self, OSTREE_REPO_LIST_OBJECTS_ALL | OSTREE_REPO_LIST_OBJECTS_NO_PARENTS, + &objects, cancellable, error)) goto out; if (!refs_only) diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 5e9818fd..d33a96ab 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -3590,7 +3590,7 @@ ostree_repo_list_objects (OstreeRepo *self, { if (!list_loose_objects (self, ret_objects, NULL, cancellable, error)) goto out; - if (self->parent_repo) + if ((flags & OSTREE_REPO_LIST_OBJECTS_NO_PARENTS) == 0 && self->parent_repo) { if (!list_loose_objects (self->parent_repo, ret_objects, NULL, cancellable, error)) goto out; diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index ff1e712d..5547473a 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -798,11 +798,13 @@ gboolean ostree_repo_read_commit (OstreeRepo *self, * @OSTREE_REPO_LIST_OBJECTS_LOOSE: List only loose (plain file) objects * @OSTREE_REPO_LIST_OBJECTS_PACKED: List only packed (compacted into blobs) objects * @OSTREE_REPO_LIST_OBJECTS_ALL: List all objects + * @OSTREE_REPO_LIST_OBJECTS_NO_PARENTS: Only list objects in this repo, not parents */ typedef enum { OSTREE_REPO_LIST_OBJECTS_LOOSE = (1 << 0), OSTREE_REPO_LIST_OBJECTS_PACKED = (1 << 1), - OSTREE_REPO_LIST_OBJECTS_ALL = (1 << 2) + OSTREE_REPO_LIST_OBJECTS_ALL = (1 << 2), + OSTREE_REPO_LIST_OBJECTS_NO_PARENTS = (1 << 3), } OstreeRepoListObjectsFlags; /** diff --git a/tests/test-prune.sh b/tests/test-prune.sh index 5134d560..ce14ce67 100755 --- a/tests/test-prune.sh +++ b/tests/test-prune.sh @@ -25,7 +25,7 @@ skip_without_user_xattrs setup_fake_remote_repo1 "archive-z2" -echo '1..2' +echo '1..3' cd ${test_tmpdir} mkdir repo @@ -142,3 +142,39 @@ ${CMD_PREFIX} ostree --repo=repo pull --depth=-1 --commit-metadata-only origin t ${CMD_PREFIX} ostree --repo=repo prune echo "ok prune with partial repo" + +assert_has_n_objects() { + find $1/objects -name '*.filez' | wc -l > object-count + assert_file_has_content object-count $2 + rm object-count +} + +cd ${test_tmpdir} +for repo in repo child-repo tmp-repo; do + rm ${repo} -rf + ${CMD_PREFIX} ostree --repo=${repo} init --mode=archive +done +echo parent=${test_tmpdir}/repo >> child-repo/config +mkdir files +for x in $(seq 3); do + echo afile${x} > files/afile${x} +done +${CMD_PREFIX} ostree --repo=repo commit -b test files +assert_has_n_objects repo 3 +# Inherit 1-3, add 4-6 +for x in $(seq 4 6); do + echo afile${x} > files/afile${x} +done +# Commit into a temp repo, then do a local pull, which triggers +# the parent repo lookup for dedup +${CMD_PREFIX} ostree --repo=tmp-repo commit -b childtest files +${CMD_PREFIX} ostree --repo=child-repo pull-local tmp-repo childtest +assert_has_n_objects child-repo 3 +# Sanity check prune doesn't do anything +for repo in repo child-repo; do ${CMD_PREFIX} ostree --repo=${repo} prune; done +# Now, leave orphaned objects in the parent only pointed to by the child +${CMD_PREFIX} ostree --repo=repo refs --delete test +${CMD_PREFIX} ostree --repo=child-repo prune --refs-only --depth=0 +assert_has_n_objects child-repo 3 + +echo "ok prune with parent repo" From 47b0b4120a9bb3d68318b7e479b1314183857868 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 26 Aug 2016 17:35:17 +0200 Subject: [PATCH 24/34] pull: use same name for parameter and documentation comment Fixes this warning: src/libostree/ostree-repo-pull.c:2162: Warning: OSTree: ostree_repo_pull_with_options: unknown parameter 'remote_name_or_baseurl' in documentation comment, should be 'remote_name' Signed-off-by: Giuseppe Scrivano Closes: #472 Approved by: jlebon --- src/libostree/ostree-repo-pull.c | 2 +- src/libostree/ostree-repo.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 066233be..604e8254 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -3005,7 +3005,7 @@ out: gboolean ostree_repo_pull_with_options (OstreeRepo *self, - const char *remote_name, + const char *remote_name_or_baseurl, GVariant *options, OstreeAsyncProgress *progress, GCancellable *cancellable, diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 5547473a..f1f9da41 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -1006,7 +1006,7 @@ ostree_repo_pull_one_dir (OstreeRepo *self, _OSTREE_PUBLIC gboolean ostree_repo_pull_with_options (OstreeRepo *self, - const char *remote_name, + const char *remote_name_or_baseurl, GVariant *options, OstreeAsyncProgress *progress, GCancellable *cancellable, From b6ec7526b58fa6d42792c460f3eedff410cb2c60 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Tue, 23 Aug 2016 14:32:35 +0200 Subject: [PATCH 25/34] u-boot: Merge ostree's and systems uEnv.txt This is a proper fix for: https://bugzilla.gnome.org/show_bug.cgi?id=755787 With this patch, an admin (system builder) can now: 1) Edit /usr/lib/ostree-boot/uEnv.txt 2) Deploy the new tree. OSTree will append system's uEnv.txt to the OSTree's managed uEnv.txt (loader/uEnv.txt). It is common for u-boot systems to read in an extra env from external /uEnv.txt. The same file OSTree uses to pass in its env. With this patch /uEnv.txt now contains OSTree's env + custom env added by system builders. Closes: #466 Approved by: cgwalters --- src/libostree/ostree-bootloader-uboot.c | 40 ++++++++++++++++++++++++- tests/admin-test.sh | 2 -- tests/test-admin-deploy-grub2.sh | 2 ++ tests/test-admin-deploy-syslinux.sh | 2 ++ tests/test-admin-deploy-uboot.sh | 18 +++++++++++ 5 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/libostree/ostree-bootloader-uboot.c b/src/libostree/ostree-bootloader-uboot.c index f95ea843..81ea95a6 100644 --- a/src/libostree/ostree-bootloader-uboot.c +++ b/src/libostree/ostree-bootloader-uboot.c @@ -95,7 +95,45 @@ create_config_from_boot_loader_entries (OstreeBootloaderUboot *self, val = ostree_bootconfig_parser_get (config, "options"); if (val) - g_ptr_array_add (new_lines, g_strdup_printf ("bootargs=%s", val)); + { + glnx_fd_close int uenv_fd = -1; + __attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL; + const char *uenv_path = NULL; + const char *ostree_arg = NULL; + + g_ptr_array_add (new_lines, g_strdup_printf ("bootargs=%s", val)); + + /* Append system's uEnv.txt, if it exists in $deployment/usr/lib/ostree-boot/ */ + kargs = _ostree_kernel_args_from_string (val); + ostree_arg = _ostree_kernel_args_get_last_value (kargs, "ostree"); + if (!ostree_arg) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No ostree= kernel argument found in boot loader configuration file"); + return FALSE; + } + ostree_arg += 1; + uenv_path = glnx_strjoina (ostree_arg, "/usr/lib/ostree-boot/uEnv.txt"); + uenv_fd = openat (self->sysroot->sysroot_fd, uenv_path, O_CLOEXEC | O_RDONLY); + if (uenv_fd != -1) + { + char *uenv = glnx_fd_readall_utf8 (uenv_fd, NULL, cancellable, error); + if (!uenv) + { + g_prefix_error (error, "Reading %s: ", uenv_path); + return FALSE; + } + g_ptr_array_add (new_lines, uenv); + } + else + { + if (errno != ENOENT) + { + g_prefix_error (error, "openat %s: ", uenv_path); + return FALSE; + } + } + } return TRUE; } diff --git a/tests/admin-test.sh b/tests/admin-test.sh index dcc34068..76fc8b85 100755 --- a/tests/admin-test.sh +++ b/tests/admin-test.sh @@ -18,8 +18,6 @@ set -euo pipefail -echo "1..16" - function validate_bootloader() { cd ${test_tmpdir}; bootloader="" diff --git a/tests/test-admin-deploy-grub2.sh b/tests/test-admin-deploy-grub2.sh index 6109a950..2b90c286 100755 --- a/tests/test-admin-deploy-grub2.sh +++ b/tests/test-admin-deploy-grub2.sh @@ -19,6 +19,8 @@ set -euo pipefail +echo "1..16" + . $(dirname $0)/libtest.sh # Exports OSTREE_SYSROOT so --sysroot not needed. diff --git a/tests/test-admin-deploy-syslinux.sh b/tests/test-admin-deploy-syslinux.sh index 419df2ba..70b3b4d3 100755 --- a/tests/test-admin-deploy-syslinux.sh +++ b/tests/test-admin-deploy-syslinux.sh @@ -19,6 +19,8 @@ set -euo pipefail +echo "1..16" + . $(dirname $0)/libtest.sh # Exports OSTREE_SYSROOT so --sysroot not needed. diff --git a/tests/test-admin-deploy-uboot.sh b/tests/test-admin-deploy-uboot.sh index b998e082..d4c3a0db 100755 --- a/tests/test-admin-deploy-uboot.sh +++ b/tests/test-admin-deploy-uboot.sh @@ -20,9 +20,27 @@ set -euo pipefail +echo "1..17" + . $(dirname $0)/libtest.sh # Exports OSTREE_SYSROOT so --sysroot not needed. setup_os_repository "archive-z2" "uboot" . $(dirname $0)/admin-test.sh + +cd ${test_tmpdir} +ln -s ../../boot/ osdata/usr/lib/ostree-boot +cat << 'EOF' > osdata/boot/uEnv.txt +loaduimage=load mmc ${bootpart} ${loadaddr} ${kernel_image} +loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}${fdtfile} +loadramdisk=load mmc ${bootpart} ${rdaddr} ${ramdisk_image} +mmcargs=setenv bootargs $bootargs console=${console} ${optargs} root=${mmcroot} rootfstype=${mmcrootfstype} +mmcboot=run loadramdisk; echo Booting from mmc ....; run mmcargs; bootz ${loadaddr} ${rdaddr} ${fdtaddr} +EOF +${CMD_PREFIX} ostree --repo=testos-repo commit --tree=dir=osdata/ -b testos/buildmaster/x86_64-runtime +${CMD_PREFIX} ostree admin upgrade --os=testos +assert_file_has_content sysroot/boot/uEnv.txt "loadfdt=" +assert_file_has_content sysroot/boot/uEnv.txt "kernel_image=" + +echo "ok merging uEnv.txt files" From cfc3934e81bd1cd083f089c9711d1324b2612c9f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 27 Aug 2016 08:50:47 -0400 Subject: [PATCH 26/34] sysroot: Drop unnecessary `dup()` invocation It's close-on-exec, not close-on-fork. I was clearly confused when writing this; it works just fine to reference the fd in the child and `fchdir()` before exec. So drop the unnecessary duplication. Just noticed this while reading the code for a random other reason. Closes: #473 Approved by: giuseppe --- src/libostree/ostree-sysroot.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c index 2a55c6b1..227fdd24 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -1776,17 +1776,6 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, * threads, etc. */ { - /* Make a copy of the fd that's *not* FD_CLOEXEC so that we pass - * it to the child. - */ - glnx_fd_close int child_deployment_dfd = dup (deployment_dfd); - - if (child_deployment_dfd < 0) - { - glnx_set_error_from_errno (error); - goto out; - } - mount_child = fork (); if (mount_child < 0) { @@ -1796,9 +1785,8 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, else if (mount_child == 0) { /* Child process. Do NOT use any GLib API here. */ - if (fchdir (child_deployment_dfd) < 0) + if (fchdir (deployment_dfd) < 0) exit (EXIT_FAILURE); - (void) close (child_deployment_dfd); if (mount ("overlay", "/usr", "overlay", 0, ovl_options) < 0) exit (EXIT_FAILURE); exit (EXIT_SUCCESS); From 8ece4d6d51bdbe3e41ab318259276bb83e553aa0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 28 Aug 2016 22:22:59 -0400 Subject: [PATCH 27/34] sysroot: Add a flag to suppress post-deploy cleanup I noticed seeing the output of `prune` twice in rpm-ostree, and had always wondered why. When reading the rpm-ostree code to fix something else, reasons, I noticed the reason - we were pruning once here, and then once after rpm-ostree regenerates its "base" refs. There's no reason to clean twice, so let's add a flag so rpm-ostree can suppress doing it inside libostree. Closes: #474 Approved by: giuseppe --- src/libostree/ostree-sysroot.c | 8 ++++++-- src/libostree/ostree-sysroot.h | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c index 227fdd24..82f864cb 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -1540,6 +1540,7 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, OstreeDeployment *booted_deployment = NULL; g_autoptr(GPtrArray) deployments = NULL; g_autoptr(GPtrArray) new_deployments = g_ptr_array_new_with_free_func (g_object_unref); + const gboolean postclean = (flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN) == 0; gboolean retain = (flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN) > 0; const gboolean make_default = !((flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT) > 0); gboolean added_new = FALSE; @@ -1593,8 +1594,11 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, if (!ostree_sysroot_write_deployments (sysroot, new_deployments, cancellable, error)) goto out; - if (!ostree_sysroot_cleanup (sysroot, cancellable, error)) - goto out; + if (postclean) + { + if (!ostree_sysroot_cleanup (sysroot, cancellable, error)) + goto out; + } ret = TRUE; out: diff --git a/src/libostree/ostree-sysroot.h b/src/libostree/ostree-sysroot.h index 1e60ddbe..1e98cc10 100644 --- a/src/libostree/ostree-sysroot.h +++ b/src/libostree/ostree-sysroot.h @@ -182,7 +182,8 @@ GKeyFile *ostree_sysroot_origin_new_from_refspec (OstreeSysroot *self, typedef enum { OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NONE = 0, OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN = (1 << 0), - OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT = (1 << 1) + OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT = (1 << 1), + OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN = (1 << 2), } OstreeSysrootSimpleWriteDeploymentFlags; _OSTREE_PUBLIC From a269075724dda958bb66e19f0d4ec3f5e52d97ba Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 29 Aug 2016 11:03:35 -0400 Subject: [PATCH 28/34] commit: Don't delete tmp/cache dir We hold a fd open on this, and it's basically now expected to be immortal. Confer that status. This was showing up in flatpak crashers, because we'd get an unexpected errno. (I didn't test this fixes the crasher, but it's clearly right) https://bugzilla.redhat.com/show_bug.cgi?id=1347293 Closes: #476 Approved by: alexlarsson --- src/libostree/ostree-repo-commit.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 9a938ddc..8dfe276f 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -1219,6 +1219,12 @@ cleanup_tmpdir (OstreeRepo *self, if (dent == NULL) break; + /* Special case this; we create it when opening, and don't want + * to blow it away. + */ + if (strcmp (dent->d_name, "cache") == 0) + continue; + if (TEMP_FAILURE_RETRY (fstatat (dfd_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW)) < 0) { if (errno == ENOENT) /* Did another cleanup win? */ From faee3df8ae244896f531ab7ad00c8ea75f148da3 Mon Sep 17 00:00:00 2001 From: William Manley Date: Tue, 26 Jul 2016 17:42:17 +0100 Subject: [PATCH 29/34] switchroot: Fix building with musl libc POSIX and GNU define conflicting versions of `strerror_r`. The GNU version returns the string but doesn't necessilary write into buf. The POSIX version writes into buf and returns the length but doesn't necessilary append a terminate the string with a NUL if it's too long to fit in buf. This commit fixes building ostree-prepare-root with musl libc. The stripped static build with musl on my machine is 30K vs. 724K with glibc static and 11K with glibc shared. Closes: #477 Approved by: cgwalters --- src/switchroot/ostree-mount-util.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/switchroot/ostree-mount-util.c b/src/switchroot/ostree-mount-util.c index bb27026c..9789bd86 100644 --- a/src/switchroot/ostree-mount-util.c +++ b/src/switchroot/ostree-mount-util.c @@ -40,7 +40,13 @@ perrorv (const char *format, ...) char buf[1024]; char *p; +#ifdef _GNU_SOURCE p = strerror_r (errno, buf, sizeof (buf)); +#else + strerror_r (errno, buf, sizeof (buf)); + buf[sizeof (buf) - 1] = '\0'; + p = buf; +#endif /* _GNU_SOURCE */ va_start (args, format); From 42dab85728385eaf538b36ed56e9db7ff3f96faa Mon Sep 17 00:00:00 2001 From: William Manley Date: Tue, 30 Aug 2016 20:28:02 +0100 Subject: [PATCH 30/34] ostree-prepare-root: Allow building statically with musl If the `--with-static-compiler=musl-gcc` configure flag is given. ostree-prepare-root can be used as init in a system without a populated /lib. To support this use case we need to link statically as we will be unable to locate libc.so at run time if it's not installed in /lib. We support building ostree-prepare-root with a different compiler to the rest of ostree so we can use musl rather than glibc. This reduces the size of the executable significantly: from ~700K -> ~30K. We have to use `_SCRIPTS` here to get autotools to install this as an executable but without generating rules to make it itself which we have specified manually. See https://lists.gnu.org/archive/html/help-gnu-utils/2007-01/msg00007.html for advice on using autotools in this manner. Closes: #477 Approved by: cgwalters --- Makefile-switchroot.am | 28 +++++++++++++++++++++++++--- configure.ac | 10 +++++++++- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/Makefile-switchroot.am b/Makefile-switchroot.am index f79553eb..10866bd1 100644 --- a/Makefile-switchroot.am +++ b/Makefile-switchroot.am @@ -17,7 +17,6 @@ if BUILDOPT_SYSTEMD -ostree_boot_PROGRAMS += ostree-prepare-root ostree_boot_PROGRAMS += ostree-remount noinst_LTLIBRARIES += libswitchroot-mountutil.la @@ -28,9 +27,32 @@ libswitchroot_mountutil_la_SOURCES = \ src/switchroot/ostree-mount-util.h \ $(NULL) -ostree_prepare_root_SOURCES = src/switchroot/ostree-prepare-root.c -ostree_prepare_root_LDADD = libswitchroot-mountutil.la +ostree_prepare_root_SOURCES = \ + src/switchroot/ostree-mount-util.c \ + src/switchroot/ostree-mount-util.h \ + src/switchroot/ostree-prepare-root.c \ + $(NULL) + +if BUILDOPT_USE_STATIC_COMPILER +# ostree-prepare-root can be used as init in a system without a populated /lib. +# To support this use case we need to link statically as we will be unable to +# locate libc.so at run time if it's not installed in /lib. +# +# We support building ostree-prepare-root with a different compiler to the rest +# of ostree so we can use musl rather than glibc. This reduces the size of the +# executable significantly: from ~700K -> ~30K. We have to use _SCRIPTS here +# to get autotools to install this as an executable but without generating rules +# to make it itself which we have specified manually. See +# https://lists.gnu.org/archive/html/help-gnu-utils/2007-01/msg00007.html +ostree_boot_SCRIPTS = ostree-prepare-root + +ostree-prepare-root : $(ostree_prepare_root_SOURCES) + $(STATIC_COMPILER) -o $@ -static $(ostree_prepare_root_SOURCES) $(AM_CPPFLAGS) $(AM_CFLAGS) +else +ostree_boot_PROGRAMS += ostree-prepare-root + ostree_prepare_root_CFLAGS = $(AM_CFLAGS) -Isrc/switchroot +endif ostree_remount_SOURCES = src/switchroot/ostree-remount.c ostree_remount_LDADD = libswitchroot-mountutil.la diff --git a/configure.ac b/configure.ac index 6d322c9c..51fb13c0 100644 --- a/configure.ac +++ b/configure.ac @@ -295,6 +295,13 @@ AS_IF([test x$with_grub2_mkconfig_path = x], [ ],[GRUB2_MKCONFIG=$with_grub2_mkconfig_path]) AC_DEFINE_UNQUOTED([GRUB2_MKCONFIG_PATH], ["$GRUB2_MKCONFIG"], [The system grub2-mkconfig executible name]) +AC_ARG_WITH(static-compiler, + AS_HELP_STRING([--with-static-compiler], + [Use the given compiler to build ostree-prepare-root statically linked (default: no)]),, + [with_static_compiler=no]) +AM_CONDITIONAL(BUILDOPT_USE_STATIC_COMPILER, test x$with_static_compiler != xno) +AC_SUBST(STATIC_COMPILER, $with_static_compiler) + dnl for tests AS_IF([test "x$found_introspection" = xyes], [ AC_PATH_PROG(GJS, [gjs]) @@ -332,7 +339,8 @@ echo " api docs (gtk-doc): $enable_gtk_doc gjs-based tests: $have_gjs dracut: $with_dracut - mkinitcpio: $with_mkinitcpio" + mkinitcpio: $with_mkinitcpio + Static compiler for ostree-prepare-root: $with_static_compiler" AS_IF([test x$with_builtin_grub2_mkconfig = xyes], [ echo " builtin grub2-mkconfig (instead of system): $with_builtin_grub2_mkconfig" ], [ From a128abd9bcf9842ae7cd61ef951b5345573c3df6 Mon Sep 17 00:00:00 2001 From: William Manley Date: Tue, 30 Aug 2016 22:36:20 +0100 Subject: [PATCH 31/34] switchroot: Replace custom error printing with err/warn functions from libc The `warn()` libc extension has exactly the same behaviour as our own `perrorv` function, but is available in (at least) glibc and musl. As an added bonus the similar function `err()` which will exit with an error code afterwards. This implementation is tidier and allows us to get rid of our own `perrorv`. It paves the way to removing `ostree-mount-util.c` to simplify the build scripts. Original idea by @cgwalters in #477. Closes: #478 Approved by: cgwalters --- src/switchroot/ostree-mount-util.c | 38 +--------- src/switchroot/ostree-mount-util.h | 2 - src/switchroot/ostree-prepare-root.c | 109 ++++++--------------------- src/switchroot/ostree-remount.c | 15 +--- 4 files changed, 29 insertions(+), 135 deletions(-) diff --git a/src/switchroot/ostree-mount-util.c b/src/switchroot/ostree-mount-util.c index 9789bd86..a26d2bd6 100644 --- a/src/switchroot/ostree-mount-util.c +++ b/src/switchroot/ostree-mount-util.c @@ -22,53 +22,19 @@ #include "config.h" -#include -#include -#include -#include -#include -#include +#include #include #include #include "ostree-mount-util.h" -int -perrorv (const char *format, ...) -{ - va_list args; - char buf[1024]; - char *p; - -#ifdef _GNU_SOURCE - p = strerror_r (errno, buf, sizeof (buf)); -#else - strerror_r (errno, buf, sizeof (buf)); - buf[sizeof (buf) - 1] = '\0'; - p = buf; -#endif /* _GNU_SOURCE */ - - va_start (args, format); - - vfprintf (stderr, format, args); - fprintf (stderr, ": %s\n", p); - fflush (stderr); - - va_end (args); - - return 0; -} - int path_is_on_readonly_fs (char *path) { struct statvfs stvfsbuf; if (statvfs (path, &stvfsbuf) == -1) - { - perrorv ("statvfs(%s): ", path); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "statvfs(%s)", path); return (stvfsbuf.f_flag & ST_RDONLY) != 0; } diff --git a/src/switchroot/ostree-mount-util.h b/src/switchroot/ostree-mount-util.h index 475b2cab..eb233d2f 100644 --- a/src/switchroot/ostree-mount-util.h +++ b/src/switchroot/ostree-mount-util.h @@ -21,6 +21,4 @@ #pragma once -int perrorv (const char *format, ...) __attribute__ ((format (printf, 1, 2))); - int path_is_on_readonly_fs (char *path); diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c index 895b2e51..d866f88e 100644 --- a/src/switchroot/ostree-prepare-root.c +++ b/src/switchroot/ostree-prepare-root.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -86,27 +87,18 @@ parse_ostree_cmdline (void) { // Mount proc if (mount ("proc", "/proc", "proc", 0, NULL) < 0) - { - perrorv ("failed to mount proc on /proc: "); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to mount proc on /proc"); cmdline = read_proc_cmdline (); tmp_errno = errno; /* Leave the filesystem in the state that we found it: */ if (umount ("/proc")) - { - perrorv ("failed to umount proc from /proc: "); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to umount proc from /proc"); errno = tmp_errno; if (!cmdline) - { - perrorv ("failed to read /proc/cmdline: "); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to read /proc/cmdline"); } iter = cmdline; @@ -158,29 +150,17 @@ resolve_deploy_path (const char * root_mountpoint) ostree_target = parse_ostree_cmdline (); if (!ostree_target) - { - fprintf (stderr, "No OSTree target; expected ostree=/ostree/boot.N/...\n"); - exit (EXIT_FAILURE); - } + errx (EXIT_FAILURE, "No OSTree target; expected ostree=/ostree/boot.N/..."); snprintf (destpath, sizeof(destpath), "%s/%s", root_mountpoint, ostree_target); printf ("Examining %s\n", destpath); if (lstat (destpath, &stbuf) < 0) - { - perrorv ("Couldn't find specified OSTree root '%s': ", destpath); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "Couldn't find specified OSTree root '%s'", destpath); if (!S_ISLNK (stbuf.st_mode)) - { - fprintf (stderr, "OSTree target is not a symbolic link: %s\n", destpath); - exit (EXIT_FAILURE); - } + errx (EXIT_FAILURE, "OSTree target is not a symbolic link: %s", destpath); deploy_path = realpath (destpath, NULL); if (deploy_path == NULL) - { - perrorv ("realpath(%s) failed: ", destpath); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "realpath(%s) failed", destpath); printf ("Resolved OSTree target to: %s\n", deploy_path); return deploy_path; } @@ -214,33 +194,21 @@ main(int argc, char *argv[]) * * https://bugzilla.redhat.com/show_bug.cgi?id=847418 */ if (mount (NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL) < 0) - { - perrorv ("failed to make \"/\" private mount: %m"); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to make \"/\" private mount"); /* Make deploy_path a bind mount, so we can move it later */ if (mount (deploy_path, deploy_path, NULL, MS_BIND, NULL) < 0) - { - perrorv ("failed to make initial bind mount %s", deploy_path); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to make initial bind mount %s", deploy_path); /* chdir to our new root. We need to do this after bind-mounting it over * itself otherwise our cwd is still on the non-bind-mounted filesystem * below. */ if (chdir (deploy_path) < 0) - { - perrorv ("failed to chdir to deploy_path"); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to chdir to deploy_path"); /* Link to the deployment's /var */ if (mount ("../../var", "var", NULL, MS_MGC_VAL|MS_BIND, NULL) < 0) - { - perrorv ("failed to bind mount ../../var to var"); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to bind mount ../../var to var"); /* If /boot is on the same partition, use a bind mount to make it visible * at /boot inside the deployment. */ @@ -251,10 +219,7 @@ main(int argc, char *argv[]) { snprintf (srcpath, sizeof(srcpath), "%s/boot", root_mountpoint); if (mount (srcpath, "boot", NULL, MS_BIND, NULL) < 0) - { - perrorv ("failed to bind mount %s to boot", srcpath); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to bind mount %s to boot", srcpath); } } @@ -271,31 +236,19 @@ main(int argc, char *argv[]) if (path_is_on_readonly_fs (".")) { if (mount (".", ".", NULL, MS_REMOUNT | MS_SILENT, NULL) < 0) - { - perrorv ("failed to remount rootfs writable (for overlayfs)"); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to remount rootfs writable (for overlayfs)"); } if (mount ("overlay", "usr", "overlay", 0, usr_ovl_options) < 0) - { - perrorv ("failed to mount /usr overlayfs"); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to mount /usr overlayfs"); } else { /* Otherwise, a read-only bind mount for /usr */ if (mount ("usr", "usr", NULL, MS_BIND, NULL) < 0) - { - perrorv ("failed to bind mount (class:readonly) /usr"); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to bind mount (class:readonly) /usr"); if (mount ("usr", "usr", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0) - { - perrorv ("failed to bind mount (class:readonly) /usr"); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to bind mount (class:readonly) /usr"); } touch_run_ostree (); @@ -309,10 +262,7 @@ main(int argc, char *argv[]) * sysroot, so moving sysroot would also move the deploy location. In * reality attempting mount --move would fail with EBUSY. */ if (pivot_root (".", "sysroot") < 0) - { - perrorv ("failed to pivot_root to deployment"); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to pivot_root to deployment"); } else { @@ -330,35 +280,22 @@ main(int argc, char *argv[]) * 3. /sysroot.tmp -> /sysroot */ if (mkdir ("/sysroot.tmp", 0755) < 0) - { - perrorv ("couldn't create temporary sysroot /sysroot.tmp: "); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "couldn't create temporary sysroot /sysroot.tmp"); if (mount (deploy_path, "/sysroot.tmp", NULL, MS_MOVE, NULL) < 0) - { - perrorv ("failed to MS_MOVE '%s' to '/sysroot.tmp'", deploy_path); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to MS_MOVE '%s' to '/sysroot.tmp'", deploy_path); if (mount (root_mountpoint, "sysroot", NULL, MS_MOVE, NULL) < 0) - { - perrorv ("failed to MS_MOVE '%s' to 'sysroot'", root_mountpoint); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to MS_MOVE '%s' to 'sysroot'", root_mountpoint); if (mount (".", root_mountpoint, NULL, MS_MOVE, NULL) < 0) - { - perrorv ("failed to MS_MOVE %s to %s", deploy_path, root_mountpoint); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to MS_MOVE %s to %s", deploy_path, root_mountpoint); } if (getpid() == 1) { execl ("/sbin/init", "/sbin/init", NULL); - perrorv ("failed to exec init inside ostree"); - exit (EXIT_FAILURE); + err (EXIT_FAILURE, "failed to exec init inside ostree"); } else { diff --git a/src/switchroot/ostree-remount.c b/src/switchroot/ostree-remount.c index aecaf9a8..589a3867 100644 --- a/src/switchroot/ostree-remount.c +++ b/src/switchroot/ostree-remount.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "ostree-mount-util.h" @@ -49,15 +50,10 @@ maybe_mount_tmpfs_on_var (void) return; if (umount ("/var") < 0 && errno != EINVAL) - { - perror ("failed to unmount /var prior to mounting tmpfs, mounting over"); - } + warn ("failed to unmount /var prior to mounting tmpfs, mounting over"); if (mount ("tmpfs", "/var", "tmpfs", 0, NULL) < 0) - { - perror ("failed to mount tmpfs on /var"); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to mount tmpfs on /var"); } int @@ -94,10 +90,7 @@ main(int argc, char *argv[]) * already, then assume things are OK. */ if (errno != EINVAL) - { - perrorv ("failed to remount %s", target); - exit (EXIT_FAILURE); - } + err (EXIT_FAILURE, "failed to remount %s", target); } } From 1dc69dc879612abfd6509a1e81c04990fed8ea49 Mon Sep 17 00:00:00 2001 From: William Manley Date: Tue, 30 Aug 2016 22:49:15 +0100 Subject: [PATCH 32/34] switchroot: Move `path_is_on_readonly_fs` to header file This simplifies the build system by removing the need for `libswitchroot-mountutil.la`. Original idea by @cgwalters in #477. Closes: #478 Approved by: cgwalters --- Makefile-switchroot.am | 15 +++-------- src/switchroot/ostree-mount-util.c | 40 ------------------------------ src/switchroot/ostree-mount-util.h | 20 +++++++++++++-- 3 files changed, 22 insertions(+), 53 deletions(-) delete mode 100644 src/switchroot/ostree-mount-util.c diff --git a/Makefile-switchroot.am b/Makefile-switchroot.am index 10866bd1..9c215e44 100644 --- a/Makefile-switchroot.am +++ b/Makefile-switchroot.am @@ -16,19 +16,10 @@ # Boston, MA 02111-1307, USA. if BUILDOPT_SYSTEMD - ostree_boot_PROGRAMS += ostree-remount - -noinst_LTLIBRARIES += libswitchroot-mountutil.la endif -libswitchroot_mountutil_la_SOURCES = \ - src/switchroot/ostree-mount-util.c \ - src/switchroot/ostree-mount-util.h \ - $(NULL) - ostree_prepare_root_SOURCES = \ - src/switchroot/ostree-mount-util.c \ src/switchroot/ostree-mount-util.h \ src/switchroot/ostree-prepare-root.c \ $(NULL) @@ -54,6 +45,8 @@ ostree_boot_PROGRAMS += ostree-prepare-root ostree_prepare_root_CFLAGS = $(AM_CFLAGS) -Isrc/switchroot endif -ostree_remount_SOURCES = src/switchroot/ostree-remount.c -ostree_remount_LDADD = libswitchroot-mountutil.la +ostree_remount_SOURCES = \ + src/switchroot/ostree-mount-util.h \ + src/switchroot/ostree-remount.c \ + $(NULL) ostree_remount_CFLAGS = $(AM_CFLAGS) -Isrc/switchroot diff --git a/src/switchroot/ostree-mount-util.c b/src/switchroot/ostree-mount-util.c deleted file mode 100644 index a26d2bd6..00000000 --- a/src/switchroot/ostree-mount-util.c +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2011,2013 Colin Walters - * - * 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. - * - * Author: Colin Walters - */ - -#include "config.h" - -#include -#include -#include - -#include "ostree-mount-util.h" - -int -path_is_on_readonly_fs (char *path) -{ - struct statvfs stvfsbuf; - - if (statvfs (path, &stvfsbuf) == -1) - err (EXIT_FAILURE, "statvfs(%s)", path); - - return (stvfsbuf.f_flag & ST_RDONLY) != 0; -} diff --git a/src/switchroot/ostree-mount-util.h b/src/switchroot/ostree-mount-util.h index eb233d2f..b24aa44d 100644 --- a/src/switchroot/ostree-mount-util.h +++ b/src/switchroot/ostree-mount-util.h @@ -19,6 +19,22 @@ * */ -#pragma once +#ifndef __OSTREE_MOUNT_UTIL_H_ +#define __OSTREE_MOUNT_UTIL_H_ -int path_is_on_readonly_fs (char *path); +#include +#include +#include + +static inline int +path_is_on_readonly_fs (char *path) +{ + struct statvfs stvfsbuf; + + if (statvfs (path, &stvfsbuf) == -1) + err (EXIT_FAILURE, "statvfs(%s)", path); + + return (stvfsbuf.f_flag & ST_RDONLY) != 0; +} + +#endif /* __OSTREE_MOUNT_UTIL_H_ */ From cafc517c6bb93bb45777b6969125cb9599f217f6 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 31 Aug 2016 12:02:01 -0300 Subject: [PATCH 33/34] repo-pull: properly store the cancellable OSTree function ostree_repo_pull_with_options starts a series of operations that makes heavy use of the PullData's cancellable. This isn't effective, however, since nowhere in the code the OtPullData.cancellable field is set. This is visible, for example, when trying to cancel a Flatpak pull and nothing happens, because the cancellable is not properly passed to the pull data. Fix that by setting the cancellable field of the pull data. It owns a reference for safety reasons, and unreferences it at the end of the operation. ostreedev/ostree#482 Closes: #483 Approved by: cgwalters --- src/libostree/ostree-repo-pull.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 604e8254..ed1c67ef 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -2252,6 +2252,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, pull_data->is_mirror = (flags & OSTREE_REPO_PULL_FLAGS_MIRROR) > 0; pull_data->is_commit_only = (flags & OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY) > 0; pull_data->is_untrusted = (flags & OSTREE_REPO_PULL_FLAGS_UNTRUSTED) > 0; + pull_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; if (error) pull_data->async_error = &pull_data->cached_async_error; @@ -2895,6 +2896,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_source_destroy (update_timeout); g_strfreev (configured_branches); g_clear_object (&pull_data->fetcher); + g_clear_object (&pull_data->cancellable); g_clear_object (&pull_data->remote_repo_local); g_free (pull_data->remote_name); if (pull_data->base_uri) From dd71999dc913f4eaf862e3f5607ade2b51bcd3b3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 31 Aug 2016 10:40:18 -0400 Subject: [PATCH 34/34] Release 2016.9 Closes: #481 Approved by: jlebon --- configure.ac | 2 +- src/libostree/libostree.sym | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 51fb13c0..008728dd 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.63]) dnl If incrementing the version here, remember to update libostree.sym too -AC_INIT([ostree], [2016.8], [walters@verbum.org]) +AC_INIT([ostree], [2016.9], [walters@verbum.org]) AC_CONFIG_HEADER([config.h]) AC_CONFIG_MACRO_DIR([buildutil]) AC_CONFIG_AUX_DIR([build-aux]) diff --git a/src/libostree/libostree.sym b/src/libostree/libostree.sym index 22eb9eb2..705c9eea 100644 --- a/src/libostree/libostree.sym +++ b/src/libostree/libostree.sym @@ -353,13 +353,15 @@ global: ostree_repo_checkout_at; } LIBOSTREE_2016.7; +/* No new symbols in 2016.9 */ + /* NOTE NOTE NOTE * Versions above here are released. Only add symbols below this line. * NOTE NOTE NOTE */ /* Remove comment when first new symbol is added -LIBOSTREE_2016.9 +LIBOSTREE_2016.10 global: someostree_symbol_deleteme; } LIBOSTREE_2016.8;