Skip to content

Commit 54fe9ff

Browse files
committed
daemon/guestos_mgr: Check for used kernel images
A/B update requires keeping more than only the latest version of the kernel guestos in the guestos store. Usually (if everything works fine) these are the last two versions, however, this may change if an update was not successful and was rolled back to the previous version. Then the 'oldold' version on the backup must be kept. Add an additional check that keeps a guestos if one of the redundant mount options points corresponds to the kernel image of the guestos. Signed-off-by: Johannes Wiesböck <[email protected]>
1 parent b044b64 commit 54fe9ff

File tree

1 file changed

+65
-1
lines changed

1 file changed

+65
-1
lines changed

daemon/guestos_mgr.c

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,69 @@ guestos_mgr_is_this_guestos_used_by_containers(guestos_t *os)
179179
return false;
180180
}
181181

182+
#ifdef A_B_UPDATE
183+
static bool
184+
guestos_mgr_is_this_guestos_kernel_used_by_boot_option(guestos_t *os)
185+
{
186+
ASSERT(os);
187+
bool ret = false;
188+
189+
if (strcmp(guestos_get_name(os), "kernel")) {
190+
return false;
191+
}
192+
193+
mount_t *mnt = mount_new();
194+
guestos_fill_mount(os, mnt);
195+
196+
mount_entry_t *e = mount_get_entry_by_img(mnt, "kernel");
197+
if (!e) {
198+
goto out_mnt;
199+
}
200+
201+
char *mount_point_a = mem_printf("%s.A", mount_entry_get_dir(e));
202+
char *mount_point_b = mem_printf("%s.B", mount_entry_get_dir(e));
203+
204+
char *hash_mount_a = crypto_hash_file_block_new(mount_point_a, SHA256);
205+
if (!hash_mount_a) {
206+
goto out_mnt_points;
207+
}
208+
209+
char *hash_mount_b = crypto_hash_file_block_new(mount_point_b, SHA256);
210+
if (!hash_mount_b) {
211+
mem_free0(hash_mount_a);
212+
goto out_mnt_points;
213+
}
214+
215+
if (!strcmp(hash_mount_a, mount_entry_get_sha256(e))) {
216+
ret = true;
217+
goto out_hashes;
218+
}
219+
220+
if (!strcmp(hash_mount_b, mount_entry_get_sha256(e))) {
221+
ret = true;
222+
goto out_hashes;
223+
}
224+
225+
DEBUG("Found unused kernel version %ld", guestos_get_version(os));
226+
227+
out_hashes:
228+
mem_free0(hash_mount_a);
229+
mem_free0(hash_mount_b);
230+
out_mnt_points:
231+
mem_free0(mount_point_a);
232+
mem_free0(mount_point_b);
233+
out_mnt:
234+
mount_free(mnt);
235+
return ret;
236+
}
237+
#else
238+
static inline bool
239+
guestos_mgr_is_this_guestos_kernel_used_by_boot_option(UNUSED guestos_t *os)
240+
{
241+
return false;
242+
}
243+
#endif
244+
182245
/******************************************************************************/
183246

184247
int
@@ -241,7 +304,8 @@ guestos_mgr_purge_obsolete(void)
241304
guestos_t *os = l->data;
242305
guestos_t *latest = guestos_mgr_get_latest_by_name(guestos_get_name(os), true);
243306
if (latest && guestos_get_version(os) < guestos_get_version(latest) &&
244-
!guestos_mgr_is_this_guestos_used_by_containers(os)) {
307+
!guestos_mgr_is_this_guestos_used_by_containers(os) &&
308+
!guestos_mgr_is_this_guestos_kernel_used_by_boot_option(os)) {
245309
guestos_list = list_unlink(guestos_list, l);
246310
guestos_purge(os);
247311
guestos_free(os);

0 commit comments

Comments
 (0)