[FL-2675] /int space reservation (#1448)

* storage: added global #defines for /int, /ext & /any
* storage: introduced PATH_EXT, PATH_INT& PATH_ANY macros
* core apps: moved hardcoded config files names to separate headers; prefixed them with "."; updater: added file name migration to new naming convention on backup extraction
* storage: fixed storage_merge_recursive handling of complex directory structures; storage_move_to_sd: changed data migration logic to all non-dot files & all folders
* core: added macro aliases for core record names
* Bumped protobuf commit pointer
* storage: reserved 5 pages in /int; denying write&creation of non-dot files when running out of free space

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
hedger
2022-07-26 15:21:51 +03:00
committed by GitHub
parent 52a83fc929
commit 056446dfed
171 changed files with 1111 additions and 910 deletions

View File

@@ -2,7 +2,36 @@
#include <toolbox/tar/tar_archive.h>
#define LFS_BACKUP_DEFAULT_LOCATION "/ext/" LFS_BACKUP_DEFAULT_FILENAME
#include <bt/bt_settings_filename.h>
#include <bt/bt_service/bt_keys_filename.h>
#include <dolphin/helpers/dolphin_state_filename.h>
#include <desktop/helpers/slideshow_filename.h>
#include <desktop/desktop_settings/desktop_settings_filename.h>
#include <notification/notification_settings_filename.h>
#define LFS_BACKUP_DEFAULT_LOCATION EXT_PATH(LFS_BACKUP_DEFAULT_FILENAME)
static void backup_name_converter(string_t filename) {
if(string_empty_p(filename) || (string_get_char(filename, 0) == '.')) {
return;
}
/* Filenames are already prefixed with '.' */
const char* const names[] = {
BT_SETTINGS_FILE_NAME,
BT_KEYS_STORAGE_FILE_NAME,
DESKTOP_SETTINGS_FILE_NAME,
NOTIFICATION_SETTINGS_FILE_NAME,
SLIDESHOW_FILE_NAME,
};
for(size_t i = 0; i < COUNT_OF(names); i++) {
if(string_equal_str_p(filename, &names[i][1])) {
string_set_str(filename, names[i]);
return;
}
}
}
bool lfs_backup_create(Storage* storage, const char* destination) {
const char* final_destination =
@@ -18,5 +47,5 @@ bool lfs_backup_exists(Storage* storage, const char* source) {
bool lfs_backup_unpack(Storage* storage, const char* source) {
const char* final_source = source && strlen(source) ? source : LFS_BACKUP_DEFAULT_LOCATION;
return storage_int_restore(storage, final_source) == FSE_OK;
return storage_int_restore(storage, final_source, backup_name_converter) == FSE_OK;
}

View File

@@ -157,14 +157,14 @@ bool update_manifest_has_obdata(UpdateManifest* update_manifest) {
}
bool update_manifest_init(UpdateManifest* update_manifest, const char* manifest_filename) {
Storage* storage = furi_record_open("storage");
Storage* storage = furi_record_open(RECORD_STORAGE);
FlipperFormat* flipper_file = flipper_format_file_alloc(storage);
if(flipper_format_file_open_existing(flipper_file, manifest_filename)) {
update_manifest_init_from_ff(update_manifest, flipper_file);
}
flipper_format_free(flipper_file);
furi_record_close("storage");
furi_record_close(RECORD_STORAGE);
return update_manifest->valid;
}

View File

@@ -9,8 +9,7 @@ extern "C" {
#include <m-string.h>
#include <furi_hal_flash.h>
/* Paths don't include /ext -- because at startup SD card is mounted as root */
#define UPDATE_DIR_DEFAULT_REL_PATH "/update"
/* Paths don't include /ext -- because at startup SD card is mounted as FS root */
#define UPDATE_MANIFEST_DEFAULT_NAME "update.fuf"
#define UPDATE_MANIFEST_POINTER_FILE_NAME ".fupdate"

View File

@@ -9,9 +9,8 @@
#include <lib/toolbox/path.h>
#include <lib/toolbox/crc32_calc.h>
#define UPDATE_ROOT_DIR "/ext" UPDATE_DIR_DEFAULT_REL_PATH
#define UPDATE_PREFIX "/ext" UPDATE_DIR_DEFAULT_REL_PATH "/"
#define UPDATE_SUFFIX "/" UPDATE_MANIFEST_DEFAULT_NAME
#define UPDATE_ROOT_DIR EXT_PATH("update")
/* Need at least 4 free LFS pages before update */
#define UPDATE_MIN_INT_FREE_SPACE 4 * 4 * 1024
@@ -70,7 +69,7 @@ static bool update_operation_get_current_package_path_rtc(Storage* storage, stri
return found;
}
#define UPDATE_FILE_POINTER_FN "/ext/" UPDATE_MANIFEST_POINTER_FILE_NAME
#define UPDATE_FILE_POINTER_FN EXT_PATH(UPDATE_MANIFEST_POINTER_FILE_NAME)
#define UPDATE_MANIFEST_MAX_PATH_LEN 256u
bool update_operation_get_current_package_manifest_path(Storage* storage, string_t out_path) {
@@ -137,7 +136,7 @@ static bool update_operation_persist_manifest_path(Storage* storage, const char*
UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) {
UpdatePrepareResult result = UpdatePrepareResultIntFull;
Storage* storage = furi_record_open("storage");
Storage* storage = furi_record_open(RECORD_STORAGE);
UpdateManifest* manifest = update_manifest_alloc();
File* file = storage_file_alloc(storage);
@@ -145,7 +144,8 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) {
string_t stage_path;
string_init(stage_path);
do {
if((storage_common_fs_info(storage, "/int", NULL, &free_int_space) != FSE_OK) ||
if((storage_common_fs_info(storage, STORAGE_INT_PATH_PREFIX, NULL, &free_int_space) !=
FSE_OK) ||
(free_int_space < UPDATE_MIN_INT_FREE_SPACE)) {
break;
}
@@ -197,7 +197,7 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) {
storage_file_free(file);
update_manifest_free(manifest);
furi_record_close("storage");
furi_record_close(RECORD_STORAGE);
return result;
}
@@ -206,10 +206,10 @@ bool update_operation_is_armed() {
FuriHalRtcBootMode boot_mode = furi_hal_rtc_get_boot_mode();
const uint32_t rtc_upd_index =
furi_hal_rtc_get_register(FuriHalRtcRegisterUpdateFolderFSIndex);
Storage* storage = furi_record_open("storage");
Storage* storage = furi_record_open(RECORD_STORAGE);
const bool upd_fn_ptr_exists =
(storage_common_stat(storage, UPDATE_FILE_POINTER_FN, NULL) == FSE_OK);
furi_record_close("storage");
furi_record_close(RECORD_STORAGE);
return (boot_mode >= FuriHalRtcBootModePreUpdate) &&
(boot_mode <= FuriHalRtcBootModePostUpdate) &&
((rtc_upd_index != INT_MAX) || upd_fn_ptr_exists);
@@ -218,7 +218,7 @@ bool update_operation_is_armed() {
void update_operation_disarm() {
furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal);
furi_hal_rtc_set_register(FuriHalRtcRegisterUpdateFolderFSIndex, INT_MAX);
Storage* storage = furi_record_open("storage");
Storage* storage = furi_record_open(RECORD_STORAGE);
storage_simply_remove(storage, UPDATE_FILE_POINTER_FN);
furi_record_close("storage");
}
furi_record_close(RECORD_STORAGE);
}