Fedora 中 ostree 更新 grub 引导的流程
ssk-wh Lv4

grub.d 下的脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
root@fedora:/etc/grub.d# ls -al
总计 108
drwx------. 1 root root 392 6月11日 13:16 .
drwxr-xr-x. 1 root root 4048 6月11日 13:22 ..
-rwxr-xr-x. 1 root root 9346 6月11日 13:16 00_header
-rwxr-xr-x. 1 root root 236 6月11日 13:16 01_users
-rwxr-xr-x. 1 root root 835 6月11日 13:16 08_fallback_counting
-rwxr-xr-x. 1 root root 19332 6月11日 13:16 10_linux
-rwxr-xr-x. 1 root root 833 6月11日 13:16 10_reset_boot_success
-rwxr-xr-x. 1 root root 892 6月11日 13:16 12_menu_auto_hide
-rwxr-xr-x. 1 root root 410 6月11日 13:16 14_menu_show_once
lrwxrwxrwx. 1 root root 38 6月11日 13:16 15_ostree -> /usr/libexec/libostree/grub2-15_ostree
-rwxr-xr-x. 1 root root 13613 6月11日 13:16 20_linux_xen
-rwxr-xr-x. 1 root root 2562 6月11日 13:16 20_ppc_terminfo
-rwxr-xr-x. 1 root root 10869 6月11日 13:16 30_os-prober
-rwxr-xr-x. 1 root root 1122 6月11日 13:16 30_uefi-firmware
-rwxr-xr-x. 1 root root 725 6月11日 13:16 35_fwupd
-rwxr-xr-x. 1 root root 218 6月11日 13:16 40_custom
-rwxr-xr-x. 1 root root 219 6月11日 13:16 41_custom
-rw-r--r--. 1 root root 483 6月11日 13:16 README

ostree 修改 grub 引导项

核心逻辑见最后一行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#!/usr/bin/sh
#
# Copyright (C) 2014 Colin Walters <walters@verbum.org>
#
# This program 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 licence 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, see <https://www.gnu.org/licenses/>.

# Gracefully exit if ostree is not installed, or there's
# no system repository initialized.
if ! which ostree >/dev/null 2>/dev/null; then
exit 0
fi
if ! test -d /ostree/repo; then
exit 0
fi

# Gracefully exit if we can not find the grub2 'default' configuration as it is
# the case on new installations with bootupd where it is not needed.
if ! test -f /etc/default/grub; then
exit 0
fi

# Gracefully exit if the grub2 configuration has BLS enabled,
# and the installed version has support for the blscfg module.
# Since there is no need to create menu entries for that case.
# See: https://src.fedoraproject.org/rpms/grub2/c/7c2bab5e98d
. /etc/default/grub
if test -f /boot/grub2/.grub2-blscfg-supported && \
test "${GRUB_ENABLE_BLSCFG}" = "true"; then
exit 0
fi

# Make sure we're in the right environment
if ! test -n "${GRUB_DEVICE}"; then
echo "This script must be run as a child of grub2-mkconfig" 1>&2
exit 1
fi

set -e

# Pick up stuff from grub's helper that we want to inject into our
# generated bootloader configuration. Yes, this is pretty awful, but
# it's a lot better than reimplementing the config-generating bits of
# OSTree in shell script.

. /usr/share/grub/grub-mkconfig_lib

DEVICE=${GRUB_DEVICE_BOOT:-${GRUB_DEVICE}}

GRUB2_BOOT_DEVICE_ID="$(grub_get_device_id ${DEVICE})"
export GRUB2_BOOT_DEVICE_ID
GRUB2_PREPARE_ROOT_CACHE="$(prepare_grub_to_access_device ${DEVICE})"
export GRUB2_PREPARE_ROOT_CACHE

exec ostree admin instutil grub2-generate

具体实现

阅读 ostree 源码,函数调用顺序如下:
ot_admin_instutil_builtin_grub2_generate
ostree_generate_grub2_config
impl_ostree_generate_grub2_config
_ostree_bootloader_grub2_generate_config // 向target_fd(实际是向标准输出)中写入引导数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/* This implementation is quite complex; see this issue for
* a starting point:
* https://github.com/ostreedev/ostree/issues/717
*/
gboolean
_ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot,
int bootversion,
int target_fd,
GCancellable *cancellable,
GError **error)
{
/* So... yeah. Just going to hardcode these. */
static const char hardcoded_video[] = "load_video\n"
"set gfxpayload=keep\n";
static const char hardcoded_insmods[] = "insmod gzio\n";
const char *grub2_boot_device_id =
g_getenv ("GRUB2_BOOT_DEVICE_ID");
const char *grub2_prepare_root_cache =
g_getenv ("GRUB2_PREPARE_ROOT_CACHE");

/* We must have been called via the wrapper script */
g_assert (grub2_boot_device_id != NULL);
g_assert (grub2_prepare_root_cache != NULL);

/* Passed from the parent */
gboolean is_efi = g_getenv ("_OSTREE_GRUB2_IS_EFI") != NULL;

g_autoptr(GOutputStream) out_stream = g_unix_output_stream_new (target_fd, FALSE);

g_autoptr(GPtrArray) loader_configs = NULL;
if (!_ostree_sysroot_read_boot_loader_configs (sysroot, bootversion,
&loader_configs,
cancellable, error))
return FALSE;

g_autoptr(GString) output = g_string_new ("");
for (guint i = 0; i < loader_configs->len; i++)
{
OstreeBootconfigParser *config = loader_configs->pdata[i];
const char *title;
const char *options;
const char *kernel;
const char *initrd;
const char *devicetree;
char *quoted_title = NULL;
char *uuid = NULL;
char *quoted_uuid = NULL;

title = ostree_bootconfig_parser_get (config, "title");
if (!title)
title = "(Untitled)";

kernel = ostree_bootconfig_parser_get (config, "linux");

quoted_title = g_shell_quote (title);
uuid = g_strdup_printf ("ostree-%u-%s", (guint)i, grub2_boot_device_id);
quoted_uuid = g_shell_quote (uuid);
g_string_append_printf (output, "menuentry %s --class gnu-linux --class gnu --class os --unrestricted %s {\n", quoted_title, quoted_uuid);
g_free (uuid);
g_free (quoted_title);
g_free (quoted_uuid);

/* Hardcoded sections */
g_string_append (output, hardcoded_video);
g_string_append (output, hardcoded_insmods);
g_string_append (output, grub2_prepare_root_cache);
g_string_append_c (output, '\n');

if (!kernel)
return glnx_throw (error, "No \"linux\" key in bootloader config");
g_string_append (output, "linux");
if (is_efi)
g_string_append (output, GRUB2_EFI_SUFFIX);
else
g_string_append (output, GRUB2_SUFFIX);
g_string_append_c (output, ' ');
g_string_append (output, kernel);

options = ostree_bootconfig_parser_get (config, "options");
if (options)
{
g_string_append_c (output, ' ');
g_string_append (output, options);
}
g_string_append_c (output, '\n');

initrd = ostree_bootconfig_parser_get (config, "initrd");
if (initrd)
{
g_string_append (output, "initrd");
if (is_efi)
g_string_append (output, GRUB2_EFI_SUFFIX);
else
g_string_append (output, GRUB2_SUFFIX);
g_string_append_c (output, ' ');
g_string_append (output, initrd);
g_string_append_c (output, '\n');
}

devicetree = ostree_bootconfig_parser_get (config, "devicetree");
if (devicetree)
{
g_string_append (output, "devicetree");
g_string_append_c (output, ' ');
g_string_append (output, devicetree);
g_string_append_c (output, '\n');
}

g_string_append (output, "}\n");
}

gsize bytes_written;
if (!g_output_stream_write_all (out_stream, output->str, output->len,
&bytes_written, cancellable, error))
return FALSE;

return TRUE;
}

查看所属软件包

1
2
root@fedora:/etc/grub.d# rpm -qf /usr/libexec/libostree/grub2-15_ostree
ostree-grub2-2024.5-1.fc40.x86_64

查询软件包提供者

源码也是由 ostree 提供

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
root@fedora:/etc/grub.d# rpm -qi ostree-grub2
Name : ostree-grub2
Version : 2024.5
Release : 1.fc40
Architecture: x86_64
Install Date: 2024年04月15日 星期一 02时09分59秒
Group : Unspecified
Size : 2266
License : LGPL-2.0-or-later
Signature : RSA/SHA256, 2024年03月15日 星期五 07时19分33秒, Key ID 0727707ea15b79cc
Source RPM : ostree-2024.5-1.fc40.src.rpm
Build Date : 2024年03月15日 星期五 06时09分26秒
Build Host : buildhw-x86-08.iad2.fedoraproject.org
Packager : Fedora Project
Vendor : Fedora Project
URL : https://ostree.readthedocs.io/en/latest/
Bug URL : https://bugz.fedoraproject.org/ostree
Summary : GRUB2 integration for OSTree
Description :
GRUB2 integration for OSTree

结论

ostree-grub2 安装时提供了 /usr/libexec/libostree/grub2-15_ostree , 并链接至 /etc/grub.d/15_ostree,在重启前,执行 grub-mkconfig 操作,更新 grub 引导数据。

 Comments
Comment plugin failed to load
Loading comment plugin