diff --git a/pressure-vessel/runtime.c b/pressure-vessel/runtime.c index c9afcd743de600cad9a8342f3d8552fc912c996c..2f528fa5d55419073870c7655ebd38079b0dae2a 100644 --- a/pressure-vessel/runtime.c +++ b/pressure-vessel/runtime.c @@ -4316,9 +4316,6 @@ pv_runtime_finish_libc_family (PvRuntime *self, GHashTable *gconv_in_provider, GError **error) { - g_autofree gchar *localedef = NULL; - g_autofree gchar *ldconfig = NULL; - g_autofree gchar *locale = NULL; GHashTableIter iter; const gchar *gconv_path; gsize i; @@ -4334,6 +4331,33 @@ pv_runtime_finish_libc_family (PvRuntime *self, "/usr/i686-pc-linux-gnu/lib/locale", NULL }; + static const struct + { + const char *executable; + const char *target_path; + enum { OPTIONAL, IMPORTANT, ESSENTIAL } priority; + } glibc_executables[] = + { + /* This is basically the libc-bin Debian package, which is + * marked Essential. At least ldd can fail to work if it is too + * dissimilar to the libc.so.6 in use. */ + { "catchsegv" }, + { "getconf" }, + { "getent" }, + { "iconv" }, + { "ldconfig", .priority = ESSENTIAL, .target_path = "/sbin/ldconfig" }, + { "ldd", .priority = IMPORTANT }, + { "locale", .priority = IMPORTANT }, + { "localedef", .priority = IMPORTANT }, + { "pldd" }, + { "tzselect" }, + { "zdump" }, + /* We probably don't need developer tools gencat, rpcgen, memusage, + * memusagestat, mtrace, sotruss, sprof from libc-dev-bin, libc-devtools + * (and some have non-trivial dependencies). */ + /* We probably don't need sysadmin tools /usr/sbin/iconvconfig, + * /usr/sbin/zic from libc-bin. */ + }; g_return_val_if_fail (self->provider != NULL, FALSE); g_return_val_if_fail (bwrap != NULL || self->mutable_sysroot != NULL, FALSE); @@ -4384,47 +4408,53 @@ pv_runtime_finish_libc_family (PvRuntime *self, error)) return FALSE; - localedef = pv_graphics_provider_search_in_path_and_bin (self->provider, "localedef"); - - if (localedef == NULL) + for (i = 0; i < G_N_ELEMENTS (glibc_executables); i++) { - g_warning ("Cannot find localedef"); - } - else if (!pv_runtime_take_from_provider (self, bwrap, localedef, - "/usr/bin/localedef", - TAKE_FROM_PROVIDER_FLAGS_IF_CONTAINER_COMPATIBLE, - error)) - { - return FALSE; - } + g_autoptr(GError) local_error = NULL; + const char *executable = glibc_executables[i].executable; + g_autofree char *provider_impl = NULL; + g_autofree char *target_path_alloc = NULL; + const char *target_path = glibc_executables[i].target_path; + TakeFromProviderFlags flags; - locale = pv_graphics_provider_search_in_path_and_bin (self->provider, "locale"); + provider_impl = pv_graphics_provider_search_in_path_and_bin (self->provider, + executable); - if (locale == NULL) - { - g_warning ("Cannot find locale"); - } - else if (!pv_runtime_take_from_provider (self, bwrap, locale, - "/usr/bin/locale", - TAKE_FROM_PROVIDER_FLAGS_IF_CONTAINER_COMPATIBLE, - error)) - { - return FALSE; - } + if (target_path == NULL) + { + target_path_alloc = g_build_filename ("/usr/bin", executable, NULL); + target_path = target_path_alloc; + } - ldconfig = pv_graphics_provider_search_in_path_and_bin (self->provider, "ldconfig"); + if (glibc_executables[i].priority >= ESSENTIAL) + flags = TAKE_FROM_PROVIDER_FLAGS_NONE; + else + flags = TAKE_FROM_PROVIDER_FLAGS_IF_CONTAINER_COMPATIBLE; - if (ldconfig == NULL) - { - g_warning ("Cannot find ldconfig"); - } - else if (!pv_runtime_take_from_provider (self, bwrap, - ldconfig, - "/sbin/ldconfig", - TAKE_FROM_PROVIDER_FLAGS_NONE, - error)) - { - return FALSE; + if (provider_impl == NULL) + { + if (glibc_executables[i].priority >= IMPORTANT) + g_warning ("Cannot find %s", executable); + else + g_debug ("Cannot find %s", executable); + } + else if (!pv_runtime_take_from_provider (self, bwrap, provider_impl, + target_path, + flags, + &local_error)) + { + if (glibc_executables[i].priority >= IMPORTANT) + { + g_propagate_error (error, g_steal_pointer (&local_error)); + return FALSE; + } + else + { + g_debug ("Cannot take %s from provider, ignoring: %s", + provider_impl, local_error->message); + g_clear_error (&local_error); + } + } } g_debug ("Making provider gconv modules visible in container");