From 3332c4110c354ad707c42a33f24140fc99f26ccb Mon Sep 17 00:00:00 2001 From: Senthil Date: Wed, 4 Jan 2017 17:32:33 -0800 Subject: [PATCH 1/4] cache work --- src/corehost/cli/args.cpp | 59 +++++++++-- src/corehost/cli/args.h | 65 ++++++------ src/corehost/cli/deps_resolver.cpp | 148 +++++++++++----------------- src/corehost/cli/deps_resolver.h | 18 +--- src/corehost/cli/hostpolicy.cpp | 2 +- src/corehost/cli/libhost.h | 54 ++++++---- src/corehost/cli/runtime_config.cpp | 12 +++ src/corehost/cli/runtime_config.h | 2 + src/corehost/common/pal.h | 2 + src/corehost/common/pal.unix.cpp | 79 +++++++++++++++ src/corehost/common/pal.windows.cpp | 56 +++++++++-- src/corehost/common/utils.cpp | 22 +++++ src/corehost/common/utils.h | 1 + 13 files changed, 357 insertions(+), 163 deletions(-) diff --git a/src/corehost/cli/args.cpp b/src/corehost/cli/args.cpp index 246728e0e6..73cb28a2ef 100644 --- a/src/corehost/cli/args.cpp +++ b/src/corehost/cli/args.cpp @@ -18,10 +18,53 @@ arguments_t::arguments_t() : { } +/** + * + * Setup the shared package directories. + * + * o %DOTNET_SHARED_PACKAGES% -- multiple delimited paths + * o $HOME/.dotnet/{x86|x64}/ or %USERPROFILE%\.dotnet\{x86|x64} + * o dotnet.exe relative shared packages + * o Global location + * Windows: C:\Program Files (x86) or + * Unix: directory of dotnet on the path. + */ +void setup_shared_package_paths(const hostpolicy_init_t& init, const pal::string_t& own_dir, arguments_t* args) +{ + if (init.tfm.empty()) + { + // Old (MNA < 1.1.*) "runtimeconfig.json" files do not contain TFM property. + return; + } + + // Environment variable DOTNET_SHARED_PACKAGES + (void) get_env_shared_package_dirs(&args->env_shared_packages, get_arch(), init.tfm); + + // User profile based packages + pal::string_t local_shared_packages; + if (pal::get_local_shared_package_dir(&local_shared_packages)) + { + append_path(&local_shared_packages, init.tfm.c_str()); + args->local_shared_packages = local_shared_packages; + } + + // "dotnet.exe" relative shared packages folder + if (init.host_mode == host_mode_t::muxer) + { + args->dotnet_shared_packages = own_dir; + append_path(&args->dotnet_shared_packages, _X("packages")); + append_path(&args->dotnet_shared_packages, init.tfm.c_str()); + } + + // Global shared package dir + if (pal::get_global_shared_package_dir(&args->global_shared_packages)) + { + append_path(&args->global_shared_packages, init.tfm.c_str()); + } +} + bool parse_arguments( - const pal::string_t& deps_path, - const std::vector& probe_paths, - host_mode_t mode, + const hostpolicy_init_t& init, const int argc, const pal::char_t* argv[], arguments_t* arg_out) { arguments_t& args = *arg_out; @@ -35,7 +78,7 @@ bool parse_arguments( auto own_name = get_filename(args.own_path); auto own_dir = get_directory(args.own_path); - if (mode != host_mode_t::standalone) + if (init.host_mode != host_mode_t::standalone) { // corerun mode. First argument is managed app if (argc < 2) @@ -70,13 +113,13 @@ bool parse_arguments( args.app_argc = argc - 1; } - if (!deps_path.empty()) + if (!init.deps_file.empty()) { - args.deps_path = deps_path; + args.deps_path = init.deps_file; args.app_dir = get_directory(args.deps_path); } - for (const auto& probe : probe_paths) + for (const auto& probe : init.probe_paths) { args.probe_paths.push_back(probe); } @@ -96,5 +139,7 @@ bool parse_arguments( pal::getenv(_X("DOTNET_HOSTING_OPTIMIZATION_CACHE"), &args.dotnet_packages_cache); pal::get_default_servicing_directory(&args.core_servicing); + setup_shared_package_paths(init, own_dir, &args); + return true; } diff --git a/src/corehost/cli/args.h b/src/corehost/cli/args.h index ac062d7dc7..7d9ff14b48 100644 --- a/src/corehost/cli/args.h +++ b/src/corehost/cli/args.h @@ -21,68 +21,65 @@ struct probe_config_t bool only_runtime_assets; bool only_serviceable_assets; + bool probe_publish_dir; + void print() const { - trace::verbose(_X("probe_config_t: probe=[%s] match-hash=[%d] patch-roll-forward=[%d] prerelease-roll-forward=[%d] deps-json=[%p]"), - probe_dir.c_str(), match_hash, patch_roll_fwd, prerelease_roll_fwd, probe_deps_json); - } - bool is_roll_fwd_set() const - { - return patch_roll_fwd || prerelease_roll_fwd; + trace::verbose(_X("probe_config_t: probe=[%s] match-hash=[%d] deps-json=[%p] deps-dir-probe=[%d]"), + probe_dir.c_str(), match_hash, probe_deps_json, probe_publish_dir); } probe_config_t( const pal::string_t& probe_dir, bool match_hash, - bool patch_roll_fwd, - bool prerelease_roll_fwd, const deps_json_t* probe_deps_json, bool only_serviceable_assets, - bool only_runtime_assets) + bool only_runtime_assets, + bool probe_publish_dir) : probe_dir(probe_dir) , match_hash(match_hash) - , patch_roll_fwd(patch_roll_fwd) - , prerelease_roll_fwd(prerelease_roll_fwd) , probe_deps_json(probe_deps_json) , only_serviceable_assets(only_serviceable_assets) , only_runtime_assets(only_runtime_assets) + , probe_publish_dir(probe_publish_dir) { - // Cannot roll forward and also match hash. - assert(!is_roll_fwd_set() || !match_hash); - // Will not roll forward within a deps json. - assert(!is_roll_fwd_set() || probe_deps_json == nullptr); // Will not do hash match when probing a deps json. assert(!match_hash || probe_deps_json == nullptr); } - static probe_config_t svc_ni(const pal::string_t& dir, bool patch_roll_fwd, bool prerelease_roll_fwd) + static probe_config_t svc_ni(const pal::string_t& dir) { - return probe_config_t(dir, false, patch_roll_fwd, prerelease_roll_fwd, nullptr, true, true); + return probe_config_t(dir, false, nullptr, true, true, false); } - static probe_config_t svc(const pal::string_t& dir, bool patch_roll_fwd, bool prerelease_roll_fwd) + static probe_config_t svc(const pal::string_t& dir) { - return probe_config_t(dir, false, patch_roll_fwd, prerelease_roll_fwd, nullptr, true, false); + return probe_config_t(dir, false, nullptr, true, false, false); } static probe_config_t cache_ni(const pal::string_t& dir) { - return probe_config_t(dir, true, false, false, nullptr, false, true); + return probe_config_t(dir, true, nullptr, false, true, false); } static probe_config_t cache(const pal::string_t& dir) { - return probe_config_t(dir, true, false, false, nullptr, false, false); + return probe_config_t(dir, true, nullptr, false, false, false); } static probe_config_t fx(const pal::string_t& dir, const deps_json_t* deps) { - return probe_config_t(dir, false, false, false, deps, false, false); + return probe_config_t(dir, false, deps, false, false, false); } - static probe_config_t additional(const pal::string_t& dir) + static probe_config_t lookup(const pal::string_t& dir) { - return probe_config_t(dir, false, false, false, nullptr, false, false); + return probe_config_t(dir, false, nullptr, false, false, false); + } + + static probe_config_t published_deps_dir() + { + return probe_config_t(_X(""), false, nullptr, false, false, true); } }; @@ -95,7 +92,10 @@ struct arguments_t std::vector probe_paths; pal::string_t dotnet_packages_cache; pal::string_t managed_application; - + pal::string_t local_shared_packages; + pal::string_t global_shared_packages; + pal::string_t dotnet_shared_packages; + std::vector env_shared_packages; int app_argc; const pal::char_t** app_argv; @@ -105,16 +105,25 @@ struct arguments_t { if (trace::is_enabled()) { - trace::verbose(_X("-- arguments_t: own_path=%s app_dir=%s deps=%s core_svc=%s packages_cache=%s mgd_app=%s"), + trace::verbose(_X("-- arguments_t: own_path='%s' app_dir='%s' deps='%s' core_svc='%s' packages_cache='%s' mgd_app='%s'"), own_path.c_str(), app_dir.c_str(), deps_path.c_str(), core_servicing.c_str(), dotnet_packages_cache.c_str(), managed_application.c_str()); for (const auto& probe : probe_paths) { - trace::verbose(_X("-- arguments_t: probe dir: [%s]"), probe.c_str()); + trace::verbose(_X("-- arguments_t: probe dir: '%s'"), probe.c_str()); + } + for (const auto& shared : env_shared_packages) + { + trace::verbose(_X("-- arguments_t: env shared packages: '%s'"), shared.c_str()); } + trace::verbose(_X("-- arguments_t: local shared packages: '%s'"), local_shared_packages.c_str()); + trace::verbose(_X("-- arguments_t: dotnet shared packages: '%s'"), dotnet_shared_packages.c_str()); + trace::verbose(_X("-- arguments_t: global shared packages: '%s'"), global_shared_packages.c_str()); } } }; -bool parse_arguments(const pal::string_t& deps_path, const std::vector& probe_paths, host_mode_t mode, const int argc, const pal::char_t* argv[], arguments_t* args); +bool parse_arguments( + const hostpolicy_init_t& init, + const int argc, const pal::char_t* argv[], arguments_t* arg_out); #endif // ARGS_H diff --git a/src/corehost/cli/deps_resolver.cpp b/src/corehost/cli/deps_resolver.cpp index f35d9426c7..1013af54e2 100644 --- a/src/corehost/cli/deps_resolver.cpp +++ b/src/corehost/cli/deps_resolver.cpp @@ -133,65 +133,35 @@ void deps_resolver_t::get_dir_assemblies( } } -bool deps_resolver_t::try_roll_forward(const deps_entry_t& entry, - const pal::string_t& probe_dir, - bool patch_roll_fwd, - bool prerelease_roll_fwd, - pal::string_t* candidate) +void deps_resolver_t::setup_shared_package_probes( + const hostpolicy_init_t& init, + const arguments_t& args) { - trace::verbose(_X("Attempting a roll forward for [%s/%s/%s] in [%s]"), entry.library_name.c_str(), entry.library_version.c_str(), entry.relative_path.c_str(), probe_dir.c_str()); - - const pal::string_t& lib_ver = entry.library_version; - - fx_ver_t cur_ver(-1, -1, -1); - if (!fx_ver_t::parse(lib_ver, &cur_ver, false)) - { - trace::verbose(_X("No roll forward as specified version [%s] could not be parsed"), lib_ver.c_str()); - return false; - } - pal::string_t path = probe_dir; - append_path(&path, entry.library_name.c_str()); - pal::string_t max_str = lib_ver; - if (cur_ver.is_prerelease() && prerelease_roll_fwd) + for (const auto& shared : args.env_shared_packages) { - pal::string_t maj_min_pat_star = cur_ver.prerelease_glob(); - - pal::string_t cache_key = path; - append_path(&cache_key, maj_min_pat_star.c_str()); - - if (m_prerelease_roll_forward_cache.count(cache_key)) - { - max_str = m_prerelease_roll_forward_cache[cache_key]; - trace::verbose(_X("Found cached roll forward version [%s] -> [%s]"), lib_ver.c_str(), max_str.c_str()); - } - else + if (pal::directory_exists(shared)) { - try_prerelease_roll_forward_in_dir(path, cur_ver, &max_str); - m_prerelease_roll_forward_cache[cache_key] = max_str; + // Shared Packages probe: DOTNET_SHARED_PACKAGES + m_probes.push_back(probe_config_t::lookup(shared)); } } - if (!cur_ver.is_prerelease() && patch_roll_fwd) - { - // Extract glob string of the form: 1.0.* from the version 1.0.0-prerelease-00001. - pal::string_t maj_min_star = cur_ver.patch_glob(); - pal::string_t cache_key = path; - append_path(&cache_key, maj_min_star.c_str()); + if (pal::directory_exists(args.local_shared_packages)) + { + // Shared Packages probe: $HOME/.dotnet/packages or %USERPROFILE%\.dotnet\packages + m_probes.push_back(probe_config_t::lookup(args.local_shared_packages)); + } - if (m_patch_roll_forward_cache.count(cache_key)) - { - max_str = m_patch_roll_forward_cache[cache_key]; - trace::verbose(_X("Found cached roll forward version [%s] -> [%s]"), lib_ver.c_str(), max_str.c_str()); - } - else - { - try_patch_roll_forward_in_dir(path, cur_ver, &max_str); - m_patch_roll_forward_cache[cache_key] = max_str; - } + if (pal::directory_exists(args.dotnet_shared_packages)) + { + m_probes.push_back(probe_config_t::lookup(args.dotnet_shared_packages)); } - append_path(&path, max_str.c_str()); - return entry.to_rel_path(path, candidate); + if (args.global_shared_packages != args.dotnet_shared_packages && pal::directory_exists(args.global_shared_packages)) + { + // Shared Packages probe: /usr/share/dotnet/packages or C:\Program Files (x86)\dotnet\packages + m_probes.push_back(probe_config_t::lookup(args.global_shared_packages)); + } } void deps_resolver_t::setup_probe_config( @@ -205,13 +175,13 @@ void deps_resolver_t::setup_probe_config( if (pal::directory_exists(ext_ni)) { // Servicing NI probe. - m_probes.push_back(probe_config_t::svc_ni(ext_ni, false, false)); + m_probes.push_back(probe_config_t::svc_ni(ext_ni)); } // Servicing normal probe. pal::string_t ext_pkgs = args.core_servicing; append_path(&ext_pkgs, _X("pkgs")); - m_probes.push_back(probe_config_t::svc(ext_pkgs, false, false)); + m_probes.push_back(probe_config_t::svc(ext_pkgs)); } if (pal::directory_exists(args.dotnet_packages_cache)) @@ -234,10 +204,16 @@ void deps_resolver_t::setup_probe_config( m_probes.push_back(probe_config_t::fx(m_fx_dir, m_fx_deps.get())); } + // The published deps directory to be probed: either app or FX directory. + // The probe directory will be available at probe time. + m_probes.push_back(probe_config_t::published_deps_dir()); + + setup_shared_package_probes(init, args); + for (const auto& probe : m_additional_probes) { // Additional paths - m_probes.push_back(probe_config_t::additional(probe)); + m_probes.push_back(probe_config_t::lookup(probe)); } if (trace::is_enabled()) @@ -267,9 +243,18 @@ void deps_resolver_t::setup_additional_probes(const std::vector& } } -bool deps_resolver_t::probe_entry_in_configs(const deps_entry_t& entry, pal::string_t* candidate) +/** + * Given a deps entry, do a probe (lookup) for the file, based on the probe config. + * -- When match hash is specified, the nuget cache SHA is matched. See .sha512 files in %USERPROFILE%\.nuget. + * -- When crossgen-ed folders are looked up, look up only "runtime" (managed) assets. + * -- When servicing directories are looked up, look up only if the deps file marks the entry as serviceable. + * -- When a deps json based probe is performed, the deps entry's package name and version must match. + * -- When looking into a published dir, for rid specific assets lookup rid split folders; for non-rid assets lookup the layout dir. + */ +bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::string_t& deps_dir, pal::string_t* candidate) { candidate->clear(); + for (const auto& config : m_probes) { trace::verbose(_X(" Considering entry [%s/%s/%s] and probe dir [%s]"), entry.library_name.c_str(), entry.library_version.c_str(), entry.relative_path.c_str(), config.probe_dir.c_str()); @@ -289,7 +274,6 @@ bool deps_resolver_t::probe_entry_in_configs(const deps_entry_t& entry, pal::str { if (entry.to_hash_matched_path(probe_dir, candidate)) { - assert(!config.is_roll_fwd_set()); trace::verbose(_X(" Matched hash for [%s]"), candidate->c_str()); return true; } @@ -297,62 +281,44 @@ bool deps_resolver_t::probe_entry_in_configs(const deps_entry_t& entry, pal::str } else if (config.probe_deps_json) { - // If the deps json has it then someone has already done rid selection and put the right stuff in the dir. - // So checking just package name and version would suffice. No need to check further for the exact asset relative path. + // If the deps json has the package name and version, then someone has already done rid selection and + // put the right asset in the dir. So checking just package name and version would suffice. + // No need to check further for the exact asset relative sub path. if (config.probe_deps_json->has_package(entry.library_name, entry.library_version) && entry.to_dir_path(probe_dir, candidate)) { - trace::verbose(_X(" Probed deps json and matched [%s]"), candidate->c_str()); + trace::verbose(_X(" Probed deps json and matched '%s'"), candidate->c_str()); return true; } trace::verbose(_X(" Skipping... probe in deps json failed")); } - else if (!config.is_roll_fwd_set()) + else if (config.probe_publish_dir) { - if (entry.to_full_path(probe_dir, candidate)) + // This is a published dir probe, so look up rid specific assets in the rid folders. + if (entry.is_rid_specific && entry.to_rel_path(deps_dir, candidate)) { - trace::verbose(_X(" Specified no roll forward; matched [%s]"), candidate->c_str()); + trace::verbose(_X(" Probed deps dir and matched '%s'"), candidate->c_str()); return true; } - trace::verbose(_X(" Skipping... not found in probe dir")); - } - else if (config.is_roll_fwd_set()) - { - if (try_roll_forward(entry, probe_dir, config.patch_roll_fwd, config.prerelease_roll_fwd, candidate)) + // Non-rid assets, lookup in the published dir. + if (!entry.is_rid_specific && entry.to_dir_path(deps_dir, candidate)) { - trace::verbose(_X(" Specified roll forward; matched [%s]"), candidate->c_str()); + trace::verbose(_X(" Probed deps dir and matched '%s'"), candidate->c_str()); return true; } - trace::verbose(_X(" Skipping... could not roll forward and match in probe dir")); + trace::verbose(_X(" Skipping... probe in deps dir '%s' failed"), deps_dir.c_str()); + } + else if (entry.to_full_path(probe_dir, candidate)) + { + trace::verbose(_X(" Probed package dir and matched '%s'"), candidate->c_str()); + return true; } + trace::verbose(_X(" Skipping... not found in probe dir '%s'"), probe_dir.c_str()); // continue to try next probe config } return false; } -/** - * Probe helper for a deps entry. Lookup all probe configurations and then - * lookup in the directory where the deps file is present. For app dirs, - * 1. RID specific entries are present in the package relative structure. - * 2. Non-RID entries are present in the directory path. - */ -bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::string_t& deps_dir, pal::string_t* candidate) -{ - if (probe_entry_in_configs(entry, candidate)) - { - return true; - } - if (entry.is_rid_specific && entry.to_rel_path(deps_dir, candidate)) - { - return true; - } - if (!entry.is_rid_specific && entry.to_dir_path(deps_dir, candidate)) - { - return true; - } - return false; -} - /** * Resovle the TPA assembly locations */ diff --git a/src/corehost/cli/deps_resolver.h b/src/corehost/cli/deps_resolver.h index aac8dacccf..db56788322 100644 --- a/src/corehost/cli/deps_resolver.h +++ b/src/corehost/cli/deps_resolver.h @@ -73,6 +73,11 @@ class deps_resolver_t errors->clear(); return true; } + + void setup_shared_package_probes( + const hostpolicy_init_t& init, + const arguments_t& args); + void setup_probe_config( const hostpolicy_init_t& init, const arguments_t& args); @@ -135,19 +140,6 @@ class deps_resolver_t const pal::string_t& deps_dir, pal::string_t* candidate); - // Probe entry in probe configurations. - bool probe_entry_in_configs( - const deps_entry_t& entry, - pal::string_t* candidate); - - // Try auto roll forward, if not return entry in probe dir. - bool try_roll_forward( - const deps_entry_t& entry, - const pal::string_t& probe_dir, - bool patch_roll_fwd, - bool prerelease_roll_fwd, - pal::string_t* candidate); - // Framework deps file. pal::string_t m_fx_dir; diff --git a/src/corehost/cli/hostpolicy.cpp b/src/corehost/cli/hostpolicy.cpp index d1b4276e93..ef78306e98 100644 --- a/src/corehost/cli/hostpolicy.cpp +++ b/src/corehost/cli/hostpolicy.cpp @@ -290,7 +290,7 @@ SHARED_API int corehost_main(const int argc, const pal::char_t* argv[]) // Take care of arguments arguments_t args; - if (!parse_arguments(g_init.deps_file, g_init.probe_paths, g_init.host_mode, argc, argv, &args)) + if (!parse_arguments(g_init, argc, argv, &args)) { return StatusCode::LibHostInvalidArgs; } diff --git a/src/corehost/cli/libhost.h b/src/corehost/cli/libhost.h index 8fd16ef51b..27fcbc7713 100644 --- a/src/corehost/cli/libhost.h +++ b/src/corehost/cli/libhost.h @@ -48,6 +48,7 @@ struct host_interface_t size_t patch_roll_forward; size_t prerelease_roll_forward; size_t host_mode; + const pal::char_t* tfm; // !! WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING // !! 1. Only append to this structure to maintain compat. // !! 2. Any nested structs should not use compiler specific padding (pack with _HOST_INTERFACE_PACK) @@ -70,7 +71,8 @@ static_assert(offsetof(host_interface_t, probe_paths) == 10 * sizeof(size_t), "S static_assert(offsetof(host_interface_t, patch_roll_forward) == 12 * sizeof(size_t), "Struct offset breaks backwards compatibility"); static_assert(offsetof(host_interface_t, prerelease_roll_forward) == 13 * sizeof(size_t), "Struct offset breaks backwards compatibility"); static_assert(offsetof(host_interface_t, host_mode) == 14 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(sizeof(host_interface_t) == 15 * sizeof(size_t), "Did you add static asserts for the newly added fields?"); +static_assert(offsetof(host_interface_t, tfm) == 15 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(sizeof(host_interface_t) == 16 * sizeof(size_t), "Did you add static asserts for the newly added fields?"); #define HOST_INTERFACE_LAYOUT_VERSION_HI 0x16041101 // YYMMDD:nn always increases when layout breaks compat. #define HOST_INTERFACE_LAYOUT_VERSION_LO sizeof(host_interface_t) @@ -82,6 +84,7 @@ class corehost_init_t std::vector m_clr_values; std::vector m_clr_keys_cstr; std::vector m_clr_values_cstr; + const pal::string_t m_tfm; const pal::string_t m_fx_dir; const pal::string_t m_fx_name; const pal::string_t m_deps_file; @@ -110,6 +113,7 @@ class corehost_init_t , m_host_mode(mode) , m_host_interface() , m_fx_ver(runtime_config.get_fx_version()) + , m_tfm(runtime_config.get_tfm()) { runtime_config.config_kv(&m_clr_keys, &m_clr_values); make_cstr_arr(m_clr_keys, &m_clr_keys_cstr); @@ -122,6 +126,11 @@ class corehost_init_t return m_fx_dir; } + const pal::string_t& tfm() const + { + return m_tfm; + } + const pal::string_t& fx_name() const { return m_fx_name; @@ -156,6 +165,8 @@ class corehost_init_t hi.patch_roll_forward = m_patch_roll_forward; hi.prerelease_roll_forward = m_prerelease_roll_forward; hi.host_mode = m_host_mode; + + hi.tfm = m_tfm.c_str(); return hi; } @@ -179,6 +190,7 @@ struct hostpolicy_init_t std::vector> cfg_values; pal::string_t deps_file; std::vector probe_paths; + pal::string_t tfm; pal::string_t fx_dir; pal::string_t fx_name; host_mode_t host_mode; @@ -194,27 +206,35 @@ struct hostpolicy_init_t trace::error(_X("The version of the data layout used to initialize %s is [0x%04x]; expected version [0x%04x]"), LIBHOSTPOLICY_NAME, input->version_hi, HOST_INTERFACE_LAYOUT_VERSION_HI); return false; } - // Check if the size is at least what we expect to contain. - if (input->version_lo < HOST_INTERFACE_LAYOUT_VERSION_LO) - { - trace::error(_X("The size of the data layout used to initialize %s is %d; expected at least %d"), LIBHOSTPOLICY_NAME, input->version_lo, HOST_INTERFACE_LAYOUT_VERSION_LO); - return false; - } + trace::verbose(_X("Reading from host interface version: [0x%04x:%d] to initialize policy version: [0x%04x:%d]"), input->version_hi, input->version_lo, HOST_INTERFACE_LAYOUT_VERSION_HI, HOST_INTERFACE_LAYOUT_VERSION_LO); - make_clrstr_arr(input->config_keys.len, input->config_keys.arr, &init->cfg_keys); - make_clrstr_arr(input->config_values.len, input->config_values.arr, &init->cfg_values); + if (input->version_lo >= offsetof(host_interface_t, host_mode) + sizeof(input->host_mode)) + { + make_clrstr_arr(input->config_keys.len, input->config_keys.arr, &init->cfg_keys); + make_clrstr_arr(input->config_values.len, input->config_values.arr, &init->cfg_values); - init->fx_dir = input->fx_dir; - init->fx_name = input->fx_name; - init->deps_file = input->deps_file; - init->is_portable = input->is_portable; + init->fx_dir = input->fx_dir; + init->fx_name = input->fx_name; + init->deps_file = input->deps_file; + init->is_portable = input->is_portable; - make_palstr_arr(input->probe_paths.len, input->probe_paths.arr, &init->probe_paths); + make_palstr_arr(input->probe_paths.len, input->probe_paths.arr, &init->probe_paths); - init->patch_roll_forward = input->patch_roll_forward; - init->prerelease_roll_forward = input->prerelease_roll_forward; - init->host_mode = (host_mode_t) input->host_mode; + init->patch_roll_forward = input->patch_roll_forward; + init->prerelease_roll_forward = input->prerelease_roll_forward; + init->host_mode = (host_mode_t)input->host_mode; + } + else + { + trace::error(_X("The size of the data layout used to initialize %s is %d; expected at least %d"), LIBHOSTPOLICY_NAME, input->version_lo, + offsetof(host_interface_t, host_mode) + sizeof(input->host_mode)); + } + + if (input->version_lo >= offsetof(host_interface_t, tfm) + sizeof(input->tfm)) + { + init->tfm = input->tfm; + } return true; } diff --git a/src/corehost/cli/runtime_config.cpp b/src/corehost/cli/runtime_config.cpp index 748f33572c..b89039905e 100644 --- a/src/corehost/cli/runtime_config.cpp +++ b/src/corehost/cli/runtime_config.cpp @@ -71,6 +71,12 @@ bool runtime_config_t::parse_opts(const json_value& opts) m_prerelease_roll_fwd = prerelease_roll_fwd->second.as_bool(); } + auto tfm = opts_obj.find(_X("tfm")); + if (tfm != opts_obj.end()) + { + m_tfm = tfm->second.as_string(); + } + auto framework = opts_obj.find(_X("framework")); if (framework == opts_obj.end()) { @@ -176,6 +182,12 @@ bool runtime_config_t::ensure_parsed() return true; } +const pal::string_t& runtime_config_t::get_tfm() const +{ + assert(m_valid); + return m_tfm; +} + const pal::string_t& runtime_config_t::get_fx_name() const { assert(m_valid); diff --git a/src/corehost/cli/runtime_config.h b/src/corehost/cli/runtime_config.h index f51e0324f8..2386f0d6f2 100644 --- a/src/corehost/cli/runtime_config.h +++ b/src/corehost/cli/runtime_config.h @@ -21,6 +21,7 @@ class runtime_config_t const pal::string_t& get_gc_server() const; const pal::string_t& get_fx_version() const; const pal::string_t& get_fx_name() const; + const pal::string_t& get_tfm() const; const std::list& get_probe_paths() const; bool get_patch_roll_fwd() const; bool get_prerelease_roll_fwd() const; @@ -36,6 +37,7 @@ class runtime_config_t std::vector m_prop_keys; std::vector m_prop_values; std::list m_probe_paths; + pal::string_t m_tfm; pal::string_t m_fx_name; pal::string_t m_fx_ver; bool m_patch_roll_fwd; diff --git a/src/corehost/common/pal.h b/src/corehost/common/pal.h index ca85b7344f..feb8effe6c 100644 --- a/src/corehost/common/pal.h +++ b/src/corehost/common/pal.h @@ -200,6 +200,8 @@ namespace pal bool get_own_executable_path(string_t* recv); bool getenv(const char_t* name, string_t* recv); bool get_default_servicing_directory(string_t* recv); + bool get_local_shared_package_dir(string_t* recv); + bool get_global_shared_package_dir(string_t* recv); bool get_default_breadcrumb_store(string_t* recv); bool is_path_rooted(const string_t& path); diff --git a/src/corehost/common/pal.unix.cpp b/src/corehost/common/pal.unix.cpp index e84c535269..7bb2dc472b 100644 --- a/src/corehost/common/pal.unix.cpp +++ b/src/corehost/common/pal.unix.cpp @@ -170,6 +170,85 @@ bool pal::get_default_servicing_directory(string_t* recv) return true; } +bool pal::get_local_shared_package_dir(pal::string_t* recv) +{ + recv->clear(); + pal::string_t dir; + if (!pal::getenv("HOME", &dir)) + { + struct passwd* pw = getpwuid(getuid()); + if (pw && pw->pw_dir) + { + dir.assign(pw->pw_dir); + } + } + if (dir.empty()) + { + return false; + } + append_path(&dir, _X(".dotnet")); + append_path(&dir, get_arch()); + append_path(&dir, _X("packages")); + recv->assign(dir); + return true; +} + +static +bool is_executable(const pal::string_t& file_path) +{ + struct stat st; + if (::stat(file_path.c_str(), &st) < 0) + { + return false; + } + + return ((st.st_mode & S_IEXEC) != 0); +} + +static +bool locate_dotnet_on_path(pal::string_t* dotnet_exe) +{ + pal::string_t path; + if (!pal::getenv(_X("PATH"), &path)) + { + return false; + } + + pal::string_t tok; + pal::stringstream_t ss(path); + while (std::getline(ss, tok, PATH_SEPARATOR)) + { + size_t start_pos = tok.find_first_not_of(_X(" \t")); + if (start_pos == pal::string_t::npos) + { + continue; + } + + append_path(&tok, _X("dotnet")); + if (pal::realpath(&tok) && is_executable(tok)) + { + *dotnet_exe = tok; + return true; + } + tok.clear(); + } + return false; +} + +bool pal::get_global_shared_package_dir(pal::string_t* recv) +{ + recv->clear(); + pal::string_t dotnet_exe; + if (!locate_dotnet_on_path(&dotnet_exe)) + { + return false; + } + pal::string_t dir = get_directory(dotnet_exe); + append_path(&dir, _X("packages")); + recv->assign(dir); + return true; +} + #if defined(__APPLE__) bool pal::get_os_moniker(os_moniker_t* moniker) { diff --git a/src/corehost/common/pal.windows.cpp b/src/corehost/common/pal.windows.cpp index da45118029..154140bb47 100644 --- a/src/corehost/common/pal.windows.cpp +++ b/src/corehost/common/pal.windows.cpp @@ -152,21 +152,38 @@ bool pal::get_default_breadcrumb_store(string_t* recv) return true; } -bool pal::get_default_servicing_directory(string_t* recv) +static +bool get_program_files_by_id(KNOWNFOLDERID kfid, pal::string_t* recv) { recv->clear(); + pal::char_t* prog_files; + HRESULT hr = ::SHGetKnownFolderPath(kfid, 0, NULL, &prog_files); + if (hr != S_OK) + { + trace::verbose(_X("Failed to obtain Program Files directory, HRESULT: 0x%X"), hr); + return false; + } + recv->assign(prog_files); + return true; +} - // See https://github.com/dotnet/cli/issues/2179 +static +bool get_wow_mode_program_files(pal::string_t* recv) +{ #if defined(_TARGET_AMD64_) - if (!pal::getenv(_X("ProgramFiles(x86)"), recv)) + KNOWNFOLDERID kfid = FOLDERID_ProgramFilesX86; #else - // In WOW64 mode, PF maps to PFx86. - if (!pal::getenv(_X("ProgramFiles"), recv)) + KNOWNFOLDERID kfid = FOLDERID_ProgramFiles; #endif + return get_program_files_by_id(kfid, recv); +} + +bool pal::get_default_servicing_directory(string_t* recv) +{ + if (!get_wow_mode_program_files(recv)) { return false; } - append_path(recv, _X("coreservicing")); return true; } @@ -318,3 +335,30 @@ void pal::readdir(const string_t& path, std::vector* list) pal::readdir(path, _X("*"), list); } +bool pal::get_global_shared_package_dir(pal::string_t* dir) +{ + if (!get_program_files_by_id(FOLDERID_ProgramFiles, dir)) + { + return false; + } + append_path(dir, _X("dotnet")); + append_path(dir, _X("packages")); + return true; +} + +bool pal::get_local_shared_package_dir(pal::string_t* dir) +{ + pal::char_t* profile; + HRESULT hr = ::SHGetKnownFolderPath(FOLDERID_Profile, 0, NULL, &profile); + if (hr != S_OK) + { + trace::verbose(_X("Failed to obtain user profile directory, HRESULT: 0x%X"), hr); + return false; + } + + dir->assign(profile); + append_path(dir, _X(".dotnet")); + append_path(dir, get_arch()); + append_path(dir, _X("packages")); + return true; +} diff --git a/src/corehost/common/utils.cpp b/src/corehost/common/utils.cpp index 1d1477f957..05ad7c0a2c 100644 --- a/src/corehost/common/utils.cpp +++ b/src/corehost/common/utils.cpp @@ -252,3 +252,25 @@ bool skip_utf8_bom(pal::ifstream_t* stream) return true; } + +bool get_env_shared_package_dirs(std::vector* dirs, const pal::string_t& arch, const pal::string_t& tfm) +{ + pal::string_t path; + if (!pal::getenv(_X("DOTNET_SHARED_PACKAGES"), &path)) + { + return false; + } + + pal::string_t tok; + pal::stringstream_t ss(path); + while (std::getline(ss, tok, PATH_SEPARATOR)) + { + if (pal::realpath(&tok)) + { + append_path(&tok, arch.c_str()); + append_path(&tok, tfm.c_str()); + dirs->push_back(tok); + } + } + return true; +} diff --git a/src/corehost/common/utils.h b/src/corehost/common/utils.h index f7544cad2c..d41036eee6 100644 --- a/src/corehost/common/utils.h +++ b/src/corehost/common/utils.h @@ -32,4 +32,5 @@ bool parse_known_args( std::unordered_map>* opts, int* num_args); bool skip_utf8_bom(pal::ifstream_t* stream); +bool get_env_shared_package_dirs(std::vector* dirs, const pal::string_t& arch, const pal::string_t& tfm); #endif From 31a4a03d38565d3fdd13101a830a78ad5fb6bf1e Mon Sep 17 00:00:00 2001 From: Rama Krishnan Raghupathy Date: Thu, 26 Jan 2017 17:56:19 -0800 Subject: [PATCH 2/4] Some Refactoring and comments --- src/corehost/cli/args.cpp | 4 +-- src/corehost/cli/libhost.h | 4 +++ src/corehost/common/pal.h | 4 +-- src/corehost/common/pal.unix.cpp | 48 ++++++++++++------------- src/corehost/common/pal.windows.cpp | 54 ++++++++++++++--------------- src/corehost/common/utils.cpp | 21 +++++++++++ src/corehost/common/utils.h | 2 ++ 7 files changed, 81 insertions(+), 56 deletions(-) diff --git a/src/corehost/cli/args.cpp b/src/corehost/cli/args.cpp index 73cb28a2ef..aabde34ea2 100644 --- a/src/corehost/cli/args.cpp +++ b/src/corehost/cli/args.cpp @@ -42,7 +42,7 @@ void setup_shared_package_paths(const hostpolicy_init_t& init, const pal::string // User profile based packages pal::string_t local_shared_packages; - if (pal::get_local_shared_package_dir(&local_shared_packages)) + if (get_local_shared_package_dir(&local_shared_packages)) { append_path(&local_shared_packages, init.tfm.c_str()); args->local_shared_packages = local_shared_packages; @@ -57,7 +57,7 @@ void setup_shared_package_paths(const hostpolicy_init_t& init, const pal::string } // Global shared package dir - if (pal::get_global_shared_package_dir(&args->global_shared_packages)) + if (get_global_shared_package_dir(&args->global_shared_packages)) { append_path(&args->global_shared_packages, init.tfm.c_str()); } diff --git a/src/corehost/cli/libhost.h b/src/corehost/cli/libhost.h index 27fcbc7713..bef027ef24 100644 --- a/src/corehost/cli/libhost.h +++ b/src/corehost/cli/libhost.h @@ -209,6 +209,8 @@ struct hostpolicy_init_t trace::verbose(_X("Reading from host interface version: [0x%04x:%d] to initialize policy version: [0x%04x:%d]"), input->version_hi, input->version_lo, HOST_INTERFACE_LAYOUT_VERSION_HI, HOST_INTERFACE_LAYOUT_VERSION_LO); + //This check is to ensure is an old hostfxr can still load new hostpolicy. + //We should not read garbage due to potentially shorter struct size if (input->version_lo >= offsetof(host_interface_t, host_mode) + sizeof(input->host_mode)) { make_clrstr_arr(input->config_keys.len, input->config_keys.arr, &init->cfg_keys); @@ -231,6 +233,8 @@ struct hostpolicy_init_t offsetof(host_interface_t, host_mode) + sizeof(input->host_mode)); } + //An old hostfxr before we added TFM struct field, will not provide it. + //The version_lo (sizeof) the old hostfxr saw at build time would be smaller and we should not attempt to read tfm in that case. if (input->version_lo >= offsetof(host_interface_t, tfm) + sizeof(input->tfm)) { init->tfm = input->tfm; diff --git a/src/corehost/common/pal.h b/src/corehost/common/pal.h index feb8effe6c..a388f7bb4a 100644 --- a/src/corehost/common/pal.h +++ b/src/corehost/common/pal.h @@ -200,8 +200,8 @@ namespace pal bool get_own_executable_path(string_t* recv); bool getenv(const char_t* name, string_t* recv); bool get_default_servicing_directory(string_t* recv); - bool get_local_shared_package_dir(string_t* recv); - bool get_global_shared_package_dir(string_t* recv); + bool get_local_dotnet_dir(string_t* recv); + bool get_global_dotnet_dir(string_t* recv); bool get_default_breadcrumb_store(string_t* recv); bool is_path_rooted(const string_t& path); diff --git a/src/corehost/common/pal.unix.cpp b/src/corehost/common/pal.unix.cpp index 7bb2dc472b..fd46fe652b 100644 --- a/src/corehost/common/pal.unix.cpp +++ b/src/corehost/common/pal.unix.cpp @@ -170,29 +170,6 @@ bool pal::get_default_servicing_directory(string_t* recv) return true; } -bool pal::get_local_shared_package_dir(pal::string_t* recv) -{ - recv->clear(); - pal::string_t dir; - if (!pal::getenv("HOME", &dir)) - { - struct passwd* pw = getpwuid(getuid()); - if (pw && pw->pw_dir) - { - dir.assign(pw->pw_dir); - } - } - if (dir.empty()) - { - return false; - } - append_path(&dir, _X(".dotnet")); - append_path(&dir, get_arch()); - append_path(&dir, _X("packages")); - recv->assign(dir); - return true; -} - static bool is_executable(const pal::string_t& file_path) { @@ -235,7 +212,29 @@ bool locate_dotnet_on_path(pal::string_t* dotnet_exe) return false; } -bool pal::get_global_shared_package_dir(pal::string_t* recv) +bool pal::get_local_dotnet_dir(pal::string_t* recv) +{ + recv->clear(); + pal::string_t dir; + if (!pal::getenv("HOME", &dir)) + { + struct passwd* pw = getpwuid(getuid()); + if (pw && pw->pw_dir) + { + dir.assign(pw->pw_dir); + } + } + if (dir.empty()) + { + return false; + } + append_path(&dir, _X(".dotnet")); + append_path(&dir, get_arch()); + recv->assign(dir); + return true; +} + + bool pal::get_global_dotnet_dir(pal::string_t* recv) { recv->clear(); pal::string_t dotnet_exe; @@ -244,7 +243,6 @@ bool pal::get_global_shared_package_dir(pal::string_t* recv) return false; } pal::string_t dir = get_directory(dotnet_exe); - append_path(&dir, _X("packages")); recv->assign(dir); return true; } diff --git a/src/corehost/common/pal.windows.cpp b/src/corehost/common/pal.windows.cpp index 154140bb47..5dab80239e 100644 --- a/src/corehost/common/pal.windows.cpp +++ b/src/corehost/common/pal.windows.cpp @@ -188,6 +188,33 @@ bool pal::get_default_servicing_directory(string_t* recv) return true; } +bool pal::get_global_dotnet_dir(pal::string_t* dir) +{ + if (!get_program_files_by_id(FOLDERID_ProgramFiles, dir)) + { + return false; + } + + append_path(dir, _X("dotnet")); + return true; +} + +bool pal::get_local_dotnet_dir(pal::string_t* dir) +{ + pal::char_t* profile; + HRESULT hr = ::SHGetKnownFolderPath(FOLDERID_Profile, 0, NULL, &profile); + if (hr != S_OK) + { + trace::verbose(_X("Failed to obtain user profile directory, HRESULT: 0x%X"), hr); + return false; + } + + dir->assign(profile); + append_path(dir, _X(".dotnet")); + append_path(dir, get_arch()); + return true; +} + bool pal::is_path_rooted(const string_t& path) { return path.length() >= 2 && path[1] == L':'; @@ -335,30 +362,3 @@ void pal::readdir(const string_t& path, std::vector* list) pal::readdir(path, _X("*"), list); } -bool pal::get_global_shared_package_dir(pal::string_t* dir) -{ - if (!get_program_files_by_id(FOLDERID_ProgramFiles, dir)) - { - return false; - } - append_path(dir, _X("dotnet")); - append_path(dir, _X("packages")); - return true; -} - -bool pal::get_local_shared_package_dir(pal::string_t* dir) -{ - pal::char_t* profile; - HRESULT hr = ::SHGetKnownFolderPath(FOLDERID_Profile, 0, NULL, &profile); - if (hr != S_OK) - { - trace::verbose(_X("Failed to obtain user profile directory, HRESULT: 0x%X"), hr); - return false; - } - - dir->assign(profile); - append_path(dir, _X(".dotnet")); - append_path(dir, get_arch()); - append_path(dir, _X("packages")); - return true; -} diff --git a/src/corehost/common/utils.cpp b/src/corehost/common/utils.cpp index 05ad7c0a2c..b9e7b55f16 100644 --- a/src/corehost/common/utils.cpp +++ b/src/corehost/common/utils.cpp @@ -274,3 +274,24 @@ bool get_env_shared_package_dirs(std::vector* dirs, const pal::st } return true; } + +bool get_global_shared_package_dir(pal::string_t* dir) +{ + if (!pal::get_global_dotnet_dir(dir)) + { + return false; + } + append_path(dir, _X("packages")); + return true; +} + +bool get_local_shared_package_dir(pal::string_t* dir) +{ + if (!pal::get_local_dotnet_dir(dir)) + { + return false; + } + + append_path(dir, _X("packages")); + return true; +} diff --git a/src/corehost/common/utils.h b/src/corehost/common/utils.h index d41036eee6..c8f4bad02b 100644 --- a/src/corehost/common/utils.h +++ b/src/corehost/common/utils.h @@ -33,4 +33,6 @@ bool parse_known_args( int* num_args); bool skip_utf8_bom(pal::ifstream_t* stream); bool get_env_shared_package_dirs(std::vector* dirs, const pal::string_t& arch, const pal::string_t& tfm); +bool get_local_shared_package_dir(pal::string_t* recv); +bool get_global_shared_package_dir(pal::string_t* recv); #endif From bf12179ebc12f246e43ee4c6137e932a6cda8adc Mon Sep 17 00:00:00 2001 From: Rama Krishnan Raghupathy Date: Thu, 26 Jan 2017 18:52:51 -0800 Subject: [PATCH 3/4] Removing DOTNET_HOSTING_OPTIMIZATION_CACHE --- src/corehost/cli/args.cpp | 2 -- src/corehost/cli/args.h | 5 ++--- src/corehost/cli/deps_resolver.cpp | 14 -------------- 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/src/corehost/cli/args.cpp b/src/corehost/cli/args.cpp index aabde34ea2..6d672c9646 100644 --- a/src/corehost/cli/args.cpp +++ b/src/corehost/cli/args.cpp @@ -12,7 +12,6 @@ arguments_t::arguments_t() : app_dir(_X("")), app_argc(0), app_argv(nullptr), - dotnet_packages_cache(_X("")), core_servicing(_X("")), deps_path(_X("")) { @@ -136,7 +135,6 @@ bool parse_arguments( args.deps_path.append(_X(".deps.json")); } - pal::getenv(_X("DOTNET_HOSTING_OPTIMIZATION_CACHE"), &args.dotnet_packages_cache); pal::get_default_servicing_directory(&args.core_servicing); setup_shared_package_paths(init, own_dir, &args); diff --git a/src/corehost/cli/args.h b/src/corehost/cli/args.h index 7d9ff14b48..0bab93a3b6 100644 --- a/src/corehost/cli/args.h +++ b/src/corehost/cli/args.h @@ -90,7 +90,6 @@ struct arguments_t pal::string_t deps_path; pal::string_t core_servicing; std::vector probe_paths; - pal::string_t dotnet_packages_cache; pal::string_t managed_application; pal::string_t local_shared_packages; pal::string_t global_shared_packages; @@ -105,8 +104,8 @@ struct arguments_t { if (trace::is_enabled()) { - trace::verbose(_X("-- arguments_t: own_path='%s' app_dir='%s' deps='%s' core_svc='%s' packages_cache='%s' mgd_app='%s'"), - own_path.c_str(), app_dir.c_str(), deps_path.c_str(), core_servicing.c_str(), dotnet_packages_cache.c_str(), managed_application.c_str()); + trace::verbose(_X("-- arguments_t: own_path='%s' app_dir='%s' deps='%s' core_svc='%s' mgd_app='%s'"), + own_path.c_str(), app_dir.c_str(), deps_path.c_str(), core_servicing.c_str(), managed_application.c_str()); for (const auto& probe : probe_paths) { trace::verbose(_X("-- arguments_t: probe dir: '%s'"), probe.c_str()); diff --git a/src/corehost/cli/deps_resolver.cpp b/src/corehost/cli/deps_resolver.cpp index 1013af54e2..4f01dbdba5 100644 --- a/src/corehost/cli/deps_resolver.cpp +++ b/src/corehost/cli/deps_resolver.cpp @@ -184,20 +184,6 @@ void deps_resolver_t::setup_probe_config( m_probes.push_back(probe_config_t::svc(ext_pkgs)); } - if (pal::directory_exists(args.dotnet_packages_cache)) - { - pal::string_t ni_packages_cache = args.dotnet_packages_cache; - append_path(&ni_packages_cache, get_arch()); - if (pal::directory_exists(ni_packages_cache)) - { - // Packages cache NI probe - m_probes.push_back(probe_config_t::cache_ni(ni_packages_cache)); - } - - // Packages cache probe - m_probes.push_back(probe_config_t::cache(args.dotnet_packages_cache)); - } - if (pal::directory_exists(m_fx_dir)) { // FX probe From 8d2969489eed71571ccc1555c690b67171b275e1 Mon Sep 17 00:00:00 2001 From: Rama Krishnan Raghupathy Date: Thu, 26 Jan 2017 18:56:05 -0800 Subject: [PATCH 4/4] removing match_hash logic --- src/corehost/cli/args.h | 29 ++------ src/corehost/cli/deps_entry.cpp | 116 +---------------------------- src/corehost/cli/deps_entry.h | 3 - src/corehost/cli/deps_resolver.cpp | 13 +--- 4 files changed, 10 insertions(+), 151 deletions(-) diff --git a/src/corehost/cli/args.h b/src/corehost/cli/args.h index 0bab93a3b6..a3aa065d61 100644 --- a/src/corehost/cli/args.h +++ b/src/corehost/cli/args.h @@ -13,7 +13,6 @@ struct probe_config_t { pal::string_t probe_dir; - bool match_hash; bool patch_roll_fwd; bool prerelease_roll_fwd; const deps_json_t* probe_deps_json; @@ -25,61 +24,47 @@ struct probe_config_t void print() const { - trace::verbose(_X("probe_config_t: probe=[%s] match-hash=[%d] deps-json=[%p] deps-dir-probe=[%d]"), - probe_dir.c_str(), match_hash, probe_deps_json, probe_publish_dir); + trace::verbose(_X("probe_config_t: probe=[%s] deps-json=[%p] deps-dir-probe=[%d]"), + probe_dir.c_str(), probe_deps_json, probe_publish_dir); } probe_config_t( const pal::string_t& probe_dir, - bool match_hash, const deps_json_t* probe_deps_json, bool only_serviceable_assets, bool only_runtime_assets, bool probe_publish_dir) : probe_dir(probe_dir) - , match_hash(match_hash) , probe_deps_json(probe_deps_json) , only_serviceable_assets(only_serviceable_assets) , only_runtime_assets(only_runtime_assets) , probe_publish_dir(probe_publish_dir) { - // Will not do hash match when probing a deps json. - assert(!match_hash || probe_deps_json == nullptr); } static probe_config_t svc_ni(const pal::string_t& dir) { - return probe_config_t(dir, false, nullptr, true, true, false); + return probe_config_t(dir, nullptr, true, true, false); } static probe_config_t svc(const pal::string_t& dir) { - return probe_config_t(dir, false, nullptr, true, false, false); - } - - static probe_config_t cache_ni(const pal::string_t& dir) - { - return probe_config_t(dir, true, nullptr, false, true, false); - } - - static probe_config_t cache(const pal::string_t& dir) - { - return probe_config_t(dir, true, nullptr, false, false, false); + return probe_config_t(dir, nullptr, true, false, false); } static probe_config_t fx(const pal::string_t& dir, const deps_json_t* deps) { - return probe_config_t(dir, false, deps, false, false, false); + return probe_config_t(dir, deps, false, false, false); } static probe_config_t lookup(const pal::string_t& dir) { - return probe_config_t(dir, false, nullptr, false, false, false); + return probe_config_t(dir, nullptr, false, false, false); } static probe_config_t published_deps_dir() { - return probe_config_t(_X(""), false, nullptr, false, false, true); + return probe_config_t(_X(""), nullptr, false, false, true); } }; diff --git a/src/corehost/cli/deps_entry.cpp b/src/corehost/cli/deps_entry.cpp index 6fb022786b..4b613b9816 100644 --- a/src/corehost/cli/deps_entry.cpp +++ b/src/corehost/cli/deps_entry.cpp @@ -130,118 +130,4 @@ bool deps_entry_t::to_full_path(const pal::string_t& base, pal::string_t* str) c } return to_rel_path(new_base, str); -} - -// ----------------------------------------------------------------------------- -// Given a "base" directory, yield the relative path of this file in the package -// layout if the entry hash matches the hash file in the "base" directory -// -// Parameters: -// base - The base directory to look for the relative path of this entry and -// the hash file. -// str - If the method returns true, contains the file path for this deps -// entry relative to the "base" directory -// -// Description: -// Looks for a file named "{PackageName}.{PackageVersion}.nupkg.{HashAlgorithm}" -// If the deps entry's {HashAlgorithm}-{HashValue} matches the contents then -// yields the relative path of this entry in the "base" dir. -// -// Returns: -// If the file exists in the path relative to the "base" directory and there -// was hash file match with this deps entry. -// -// See: to_full_path(base, str) -// -bool deps_entry_t::to_hash_matched_path(const pal::string_t& base, pal::string_t* str) const -{ - pal::string_t& candidate = *str; - - candidate.clear(); - - // Base directory must be present to perform hash lookup. - if (base.empty()) - { - return false; - } - - // First detect position of hyphen in [Algorithm]-[Hash] in the string. - size_t pos = library_hash.find(_X("-")); - if (pos == 0 || pos == pal::string_t::npos) - { - trace::verbose(_X("Invalid hash %s value for deps file entry: %s"), library_hash.c_str(), library_name.c_str()); - return false; - } - - // Build the relative hash path (what is added to the package directory path). - pal::string_t relative_hash_path; - if (library_hash_path.empty()) - { - // Reserve approx 8 char_t's for the algorithm name. - relative_hash_path.reserve(library_name.length() + 1 + library_version.length() + 16); - relative_hash_path.append(library_name); - relative_hash_path.append(_X(".")); - relative_hash_path.append(library_version); - relative_hash_path.append(_X(".nupkg.")); - relative_hash_path.append(library_hash.substr(0, pos)); - } - else - { - relative_hash_path.assign(library_hash_path); - } - - // Build the directory that contains the hash file. - pal::string_t hash_file; - if (library_path.empty()) - { - hash_file.reserve(base.length() + 1 + - library_name.length() + 1 + library_version.length() + 1 + - relative_hash_path.length()); - hash_file.assign(base); - - append_path(&hash_file, library_name.c_str()); - append_path(&hash_file, library_version.c_str()); - } - else - { - hash_file.reserve(base.length() + 1 + - library_path.length() + 1 + - relative_hash_path.length()); - hash_file.assign(base); - - append_path(&hash_file, library_path.c_str()); - } - - // Append the relative path to the hash file. - append_path(&hash_file, relative_hash_path.c_str()); - - // Read the contents of the hash file. - pal::ifstream_t fstream(hash_file); - if (!fstream.good()) - { - trace::verbose(_X("The hash file is invalid [%s]"), hash_file.c_str()); - return false; - } - - // Obtain the hash from the file. - std::string hash; - hash.assign(pal::istreambuf_iterator_t(fstream), - pal::istreambuf_iterator_t()); - pal::string_t pal_hash; - if (!pal::utf8_palstring(hash.c_str(), &pal_hash)) - { - return false; - } - - // Check if contents match deps entry. - pal::string_t entry_hash = library_hash.substr(pos + 1); - if (entry_hash != pal_hash) - { - trace::verbose(_X("The file hash [%s][%d] did not match entry hash [%s][%d]"), - pal_hash.c_str(), pal_hash.length(), entry_hash.c_str(), entry_hash.length()); - return false; - } - - // All good, just append the relative dir to base. - return to_full_path(base, &candidate); -} +} \ No newline at end of file diff --git a/src/corehost/cli/deps_entry.h b/src/corehost/cli/deps_entry.h index 385dd1f5ce..01b2d84795 100644 --- a/src/corehost/cli/deps_entry.h +++ b/src/corehost/cli/deps_entry.h @@ -46,9 +46,6 @@ struct deps_entry_t // Given a "base" dir, yield the relative path with package name, version in the package layout. bool to_full_path(const pal::string_t& root, pal::string_t* str) const; - // Given a "base" dir, yield the relative path with package name, version in the package layout only if - // the hash matches contents of the hash file. - bool to_hash_matched_path(const pal::string_t& root, pal::string_t* str) const; }; #endif // __DEPS_ENTRY_H_ diff --git a/src/corehost/cli/deps_resolver.cpp b/src/corehost/cli/deps_resolver.cpp index 4f01dbdba5..151f4330ca 100644 --- a/src/corehost/cli/deps_resolver.cpp +++ b/src/corehost/cli/deps_resolver.cpp @@ -231,7 +231,6 @@ void deps_resolver_t::setup_additional_probes(const std::vector& /** * Given a deps entry, do a probe (lookup) for the file, based on the probe config. - * -- When match hash is specified, the nuget cache SHA is matched. See .sha512 files in %USERPROFILE%\.nuget. * -- When crossgen-ed folders are looked up, look up only "runtime" (managed) assets. * -- When servicing directories are looked up, look up only if the deps file marks the entry as serviceable. * -- When a deps json based probe is performed, the deps entry's package name and version must match. @@ -256,16 +255,8 @@ bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::str continue; } pal::string_t probe_dir = config.probe_dir; - if (config.match_hash) - { - if (entry.to_hash_matched_path(probe_dir, candidate)) - { - trace::verbose(_X(" Matched hash for [%s]"), candidate->c_str()); - return true; - } - trace::verbose(_X(" Skipping... match hash failed")); - } - else if (config.probe_deps_json) + + if (config.probe_deps_json) { // If the deps json has the package name and version, then someone has already done rid selection and // put the right asset in the dir. So checking just package name and version would suffice.