boot2: clean up pre-0.19.0 ams contents on upgrade

This commit is contained in:
Michael Scire 2021-03-21 04:12:30 -07:00 committed by SciresM
parent 79e4c82d7e
commit c8404e8452
5 changed files with 127 additions and 25 deletions

View file

@ -23,7 +23,7 @@ namespace ams::boot2 {
/* psc, bus, pcv is the minimal set of required programs to get SD card. */
/* bus depends on pcie, and pcv depends on settings. */
constexpr ncm::SystemProgramId PreSdCardLaunchPrograms[] = {
constexpr const ncm::SystemProgramId PreSdCardLaunchPrograms[] = {
ncm::SystemProgramId::Psc, /* psc */
ncm::SystemProgramId::Pcie, /* pcie */
ncm::SystemProgramId::Bus, /* bus */
@ -33,7 +33,7 @@ namespace ams::boot2 {
};
constexpr size_t NumPreSdCardLaunchPrograms = util::size(PreSdCardLaunchPrograms);
constexpr ncm::SystemProgramId AdditionalLaunchPrograms[] = {
constexpr const ncm::SystemProgramId AdditionalLaunchPrograms[] = {
ncm::SystemProgramId::Am, /* am */
ncm::SystemProgramId::NvServices, /* nvservices */
ncm::SystemProgramId::NvnFlinger, /* nvnflinger */
@ -78,7 +78,7 @@ namespace ams::boot2 {
};
constexpr size_t NumAdditionalLaunchPrograms = util::size(AdditionalLaunchPrograms);
constexpr ncm::SystemProgramId AdditionalMaintenanceLaunchPrograms[] = {
constexpr const ncm::SystemProgramId AdditionalMaintenanceLaunchPrograms[] = {
ncm::SystemProgramId::Am, /* am */
ncm::SystemProgramId::NvServices, /* nvservices */
ncm::SystemProgramId::NvnFlinger, /* nvnflinger */
@ -311,6 +311,57 @@ namespace ams::boot2 {
return hos::GetVersion() >= hos::Version_9_0_0;
}
/* Prior to 0.19.0, we distributed system modules inside /atmosphere/contents/. */
/* We need to clean these up, so that we don't break horribly on first upgrade. */
constexpr const ncm::SystemProgramId StratosphereSystemModulesForPostZeroPointNineteenPointZeroCleanup[] = {
ncm::SystemProgramId::Boot2,
ncm::SystemProgramId::Creport,
ncm::SystemProgramId::Dmnt,
ncm::SystemProgramId::Eclct,
ncm::SystemProgramId::Erpt,
ncm::SystemProgramId::Fatal,
ncm::SystemProgramId::JpegDec,
ncm::SystemProgramId::Pgl,
ncm::SystemProgramId::Ro,
};
alignas(0x40) constinit u8 g_fs_cleanup_buffer[4_KB];
lmem::HeapHandle g_fs_cleanup_heap_handle;
void *AllocateForFsForCleanup(size_t size) {
return lmem::AllocateFromExpHeap(g_fs_cleanup_heap_handle, size);
}
void DeallocateForFsForCleanup(void *p, size_t size) {
return lmem::FreeToExpHeap(g_fs_cleanup_heap_handle, p);
}
void InitializeFsHeapForCleanup() {
g_fs_cleanup_heap_handle = lmem::CreateExpHeap(g_fs_cleanup_buffer, sizeof(g_fs_cleanup_buffer), lmem::CreateOption_None);
fs::SetAllocator(AllocateForFsForCleanup, DeallocateForFsForCleanup);
}
void CleanupSdCardSystemProgramsForUpgradeToZeroPointNineteenPointZero() {
/* Temporarily mount the SD card. */
R_ABORT_UNLESS(fs::MountSdCard("sdmc"));
ON_SCOPE_EXIT { fs::Unmount("sdmc"); };
for (const auto program_id : StratosphereSystemModulesForPostZeroPointNineteenPointZeroCleanup) {
/* Get the program's contents path. */
char path[fs::EntryNameLengthMax];
util::SNPrintf(path, sizeof(path), "sdmc:/atmosphere/contents/%016lx/", program_id.value);
/* Check if we have old contents. */
bool has_dir;
R_ABORT_UNLESS(fs::HasDirectory(std::addressof(has_dir), path));
/* Cleanup the old contents, if we have them. */
if (has_dir) {
R_ABORT_UNLESS(fs::DeleteDirectoryRecursively(path));
}
}
}
}
/* Boot2 API. */
@ -370,6 +421,28 @@ namespace ams::boot2 {
}
}
/* Perform cleanup to faciliate upgrade to 0.19.0. */
/* NOTE: This will be removed in a future atmosphere revision. */
{
/* Setup FS heap for cleanup. */
InitializeFsHeapForCleanup();
/* Temporarily initialize fs. */
sm::DoWithSession([&] {
R_ABORT_UNLESS(fsInitialize());
});
ON_SCOPE_EXIT { fsExit(); };
/* Wait for the sd card to be available. */
cfg::WaitSdCardInitialized();
/* Cleanup. */
if (cfg::HasGlobalFlag("clean_stratosphere_for_0.19.0")) {
CleanupSdCardSystemProgramsForUpgradeToZeroPointNineteenPointZero();
R_ABORT_UNLESS(cfg::DeleteGlobalFlag("clean_stratosphere_for_0.19.0"));
}
}
/* Launch Atmosphere boot2, using NcmStorageId_None to force SD card boot. */
LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::SystemProgramId::Boot2, ncm::StorageId::None), 0);
}