summaryrefslogtreecommitdiffstats
path: root/meta-boot2qt/recipes-core/ostree/ostree/Create-firmware-convenience-symlinks.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-boot2qt/recipes-core/ostree/ostree/Create-firmware-convenience-symlinks.patch')
-rw-r--r--meta-boot2qt/recipes-core/ostree/ostree/Create-firmware-convenience-symlinks.patch126
1 files changed, 126 insertions, 0 deletions
diff --git a/meta-boot2qt/recipes-core/ostree/ostree/Create-firmware-convenience-symlinks.patch b/meta-boot2qt/recipes-core/ostree/ostree/Create-firmware-convenience-symlinks.patch
new file mode 100644
index 0000000..656887d
--- /dev/null
+++ b/meta-boot2qt/recipes-core/ostree/ostree/Create-firmware-convenience-symlinks.patch
@@ -0,0 +1,126 @@
1From c4df63488b9e09a9aa69e32ea5c0671c9dc50c9d Mon Sep 17 00:00:00 2001
2From: Gatis Paeglis <gatis.paeglis@qt.io>
3Date: Wed, 24 Aug 2016 12:29:38 +0200
4Subject: [PATCH] Create firmware convenience symlinks.
5
6Later this could be moved into utils or a similar
7location, if other boot loader backends will need
8this functionality.
9---
10 src/libostree/ostree-bootloader-uboot.c | 93 ++++++++++++++++++++++++++++++++-
11 1 file changed, 92 insertions(+), 1 deletion(-)
12
13diff --git a/src/libostree/ostree-bootloader-uboot.c b/src/libostree/ostree-bootloader-uboot.c
14index 22251da..26a3127 100644
15--- a/src/libostree/ostree-bootloader-uboot.c
16+++ b/src/libostree/ostree-bootloader-uboot.c
17@@ -62,6 +62,97 @@ _ostree_bootloader_uboot_get_name (OstreeBootloader *bootloader)
18 return "U-Boot";
19 }
20
21+/* It is common for firmware to search / on the boot partition for additional
22+ * files that are required for booting. It can be difficult to change this search
23+ * logic if it is hardcoded somewhere low in the stack or is in a read-only memory.
24+ * This issue can be solved by system builders by creating a convenience symlink:
25+ *
26+ * cd sysroot/boot
27+ * ln -s loader/second-stage-bootloader second-stage-bootloader
28+ *
29+ * This function will make sure that loader/second-stage-bootloader points to the
30+ * correct target file version. This function does nothing if boot/ does not contain
31+ * symlink files pointing into the loader/ directory.
32+ */
33+static gboolean
34+create_firmware_convenience_symlinks (OstreeBootloaderUboot *self,
35+ char *bootcsum_dir,
36+ int bootversion,
37+ GCancellable *cancellable,
38+ GError **error)
39+{
40+ glnx_fd_close int loader_dfd = -1;
41+ glnx_fd_close int boot_dfd = -1;
42+ g_autofree char *loader_dir = NULL;
43+ g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
44+
45+ loader_dir = g_strdup_printf ("boot/loader.%d/", bootversion);
46+ if (!glnx_opendirat (self->sysroot->sysroot_fd, loader_dir, FALSE, &loader_dfd, error))
47+ return FALSE;
48+ if (!glnx_opendirat (self->sysroot->sysroot_fd, "boot", FALSE, &boot_dfd, error))
49+ return FALSE;
50+ if (!glnx_dirfd_iterator_init_take_fd (dup (boot_dfd), &dfd_iter, error))
51+ return FALSE;
52+
53+ while (TRUE) {
54+ struct dirent *dent;
55+ struct stat stbuf;
56+
57+ if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error))
58+ return FALSE;
59+ if (dent == NULL)
60+ break;
61+
62+ if (fstatat (dfd_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW) != 0)
63+ {
64+ if (errno == ENOENT)
65+ continue;
66+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "fstatat");
67+ return FALSE;
68+ }
69+
70+ if (S_ISLNK(stbuf.st_mode))
71+ {
72+ char path_buffer[PATH_MAX];
73+ g_autofree char *symlink_target = NULL;
74+ symlink_target = glnx_readlinkat_malloc (boot_dfd, dent->d_name, cancellable, error);
75+
76+ if (g_str_has_prefix (symlink_target, "loader/"))
77+ {
78+ if (g_strcmp0 (dent->d_name, "uEnv.txt") == 0)
79+ continue;
80+
81+ snprintf (path_buffer, sizeof(path_buffer), "%s/%s", bootcsum_dir, dent->d_name);
82+ if (faccessat (boot_dfd, path_buffer + 1, F_OK, AT_SYMLINK_NOFOLLOW) == -1)
83+ {
84+ /* This bootcsum dir does not contain the final target, do nothing. */
85+ if (errno == ENOENT)
86+ continue;
87+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "faccessat");
88+ return FALSE;
89+ }
90+
91+ /* Cleanup from stray symlinks. This can happend when the previous deployment was
92+ interrupted and no cleanup routines were run before restaring the deployment. */
93+ if (unlinkat (loader_dfd, dent->d_name, 0) == -1 && errno != ENOENT)
94+ {
95+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "unlinkat");
96+ return FALSE;
97+ }
98+ /* Complete the link chain to the current boot file version. */
99+ snprintf (path_buffer, sizeof(path_buffer), "..%s/%s", bootcsum_dir, dent->d_name);
100+ if (symlinkat (path_buffer, loader_dfd, dent->d_name) == -1)
101+ {
102+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "symlinkat");
103+ return FALSE;
104+ }
105+ }
106+ }
107+ }
108+
109+ return TRUE;
110+}
111+
112 static gboolean
113 create_config_from_boot_loader_entries (OstreeBootloaderUboot *self,
114 int bootversion,
115@@ -138,7 +229,7 @@ create_config_from_boot_loader_entries (OstreeBootloaderUboot *self,
116 }
117 }
118
119- return TRUE;
120+ return create_firmware_convenience_symlinks (self, bootdir, bootversion, cancellable, error);
121 }
122
123 static gboolean
124--
1252.7.4
126