From 1c3a549ef9ebaecf9a0eab7515adddc594c78779 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 12 May 2015 12:26:38 -0400 Subject: [PATCH] postprocess: Handle Fedora rawhide kernel installation The vmlinuz binary has moved to /usr/lib/modules, which is a change mostly for the better, but we need to adapt. Closes: https://github.com/projectatomic/rpm-ostree/pull/143 --- src/libpriv/rpmostree-postprocess.c | 98 +++++++++++++++++++++++++++++++------ 1 file changed, 84 insertions(+), 14 deletions(-) diff --git a/src/libpriv/rpmostree-postprocess.c b/src/libpriv/rpmostree-postprocess.c index c690fe2..7b390f9 100644 --- a/src/libpriv/rpmostree-postprocess.c +++ b/src/libpriv/rpmostree-postprocess.c @@ -168,7 +168,8 @@ find_kernel_and_initramfs_in_bootdir (GFile *bootdir, name = g_file_info_get_name (file_info); - if (g_str_has_prefix (name, "vmlinuz-")) + /* Current Fedora 23 kernel.spec installs as just vmlinuz */ + if (strcmp (name, "vmlinuz") == 0 || g_str_has_prefix (name, "vmlinuz-")) { if (ret_kernel) { @@ -192,17 +193,57 @@ find_kernel_and_initramfs_in_bootdir (GFile *bootdir, } } - if (!ret_kernel) + ret = TRUE; + gs_transfer_out_value (out_kernel, &ret_kernel); + gs_transfer_out_value (out_initramfs, &ret_initramfs); + out: + return ret; +} + +/* Given a directory @d, find the first child that is a directory, + * returning it in @out_subdir. If there are multiple directories, + * return an error. + */ +static gboolean +find_ensure_one_subdirectory (GFile *d, + GFile **out_subdir, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + gs_unref_object GFileEnumerator *direnum = NULL; + gs_unref_object GFile *ret_subdir = NULL; + + direnum = g_file_enumerate_children (d, "standard::name,standard::type", 0, + cancellable, error); + if (!direnum) + goto out; + + while (TRUE) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unable to find vmlinuz- in %s", - gs_file_get_path_cached (bootdir)); - goto out; + GFileInfo *file_info; + GFile *child; + + if (!gs_file_enumerator_iterate (direnum, &file_info, &child, + cancellable, error)) + goto out; + if (!file_info) + break; + + if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) + { + if (ret_subdir) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Multiple subdirectories found in: %s", gs_file_get_path_cached (d)); + goto out; + } + ret_subdir = g_object_ref (child); + } } ret = TRUE; - gs_transfer_out_value (out_kernel, &ret_kernel); - gs_transfer_out_value (out_initramfs, &ret_initramfs); + gs_transfer_out_value (out_subdir, &ret_subdir); out: return ret; } @@ -220,14 +261,38 @@ do_kernel_prep (GFile *yumroot, gs_unref_object GFile *initramfs_path = NULL; const char *boot_checksum_str = NULL; GChecksum *boot_checksum = NULL; - const char *kname; - const char *kver; + g_autofree char *kver = NULL; if (!find_kernel_and_initramfs_in_bootdir (bootdir, &kernel_path, &initramfs_path, cancellable, error)) goto out; + if (kernel_path == NULL) + { + gs_unref_object GFile *mod_dir = g_file_resolve_relative_path (yumroot, "usr/lib/modules"); + gs_unref_object GFile *modversion_dir = NULL; + + if (!find_ensure_one_subdirectory (mod_dir, &modversion_dir, cancellable, error)) + goto out; + + if (modversion_dir) + { + kver = g_file_get_basename (modversion_dir); + if (!find_kernel_and_initramfs_in_bootdir (modversion_dir, &kernel_path, + &initramfs_path, + cancellable, error)) + goto out; + } + } + + if (kernel_path == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Unable to find kernel (vmlinuz) in /boot or /usr/lib/modules"); + goto out; + } + if (initramfs_path) { g_print ("Removing RPM-generated '%s'\n", @@ -236,10 +301,15 @@ do_kernel_prep (GFile *yumroot, goto out; } - kname = gs_file_get_basename_cached (kernel_path); - kver = strchr (kname, '-'); - g_assert (kver); - kver += 1; + if (!kver) + { + const char *kname = gs_file_get_basename_cached (kernel_path); + const char *kver_p; + + kver_p = strchr (kname, '-'); + g_assert (kver_p); + kver = g_strdup (kver_p + 1); + } /* OSTree needs to own this */ { -- 1.8.3.1