1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License. 5d9f0492fSopenharmony_ci * You may obtain a copy of the License at 6d9f0492fSopenharmony_ci * 7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d9f0492fSopenharmony_ci * 9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and 13d9f0492fSopenharmony_ci * limitations under the License. 14d9f0492fSopenharmony_ci */ 15d9f0492fSopenharmony_ci 16d9f0492fSopenharmony_ci#include <errno.h> 17d9f0492fSopenharmony_ci#include <time.h> 18d9f0492fSopenharmony_ci#include <unistd.h> 19d9f0492fSopenharmony_ci 20d9f0492fSopenharmony_ci#include "init_utils.h" 21d9f0492fSopenharmony_ci#include "param_manager.h" 22d9f0492fSopenharmony_ci#include "param_persist.h" 23d9f0492fSopenharmony_ci#include "param_utils.h" 24d9f0492fSopenharmony_ci 25d9f0492fSopenharmony_ci// for linux, no mutex 26d9f0492fSopenharmony_cistatic ParamMutex g_saveMutex = {}; 27d9f0492fSopenharmony_ci 28d9f0492fSopenharmony_cistatic int LoadOnePersistParam_(const uint32_t *context, const char *name, const char *value) 29d9f0492fSopenharmony_ci{ 30d9f0492fSopenharmony_ci UNUSED(context); 31d9f0492fSopenharmony_ci uint32_t dataIndex = 0; 32d9f0492fSopenharmony_ci return WriteParam(name, value, &dataIndex, 0); 33d9f0492fSopenharmony_ci} 34d9f0492fSopenharmony_ci 35d9f0492fSopenharmony_cistatic void LoadPersistParam_(const char *fileName, char *buffer, uint32_t buffSize) 36d9f0492fSopenharmony_ci{ 37d9f0492fSopenharmony_ci FILE *fp = fopen(fileName, "r"); 38d9f0492fSopenharmony_ci PARAM_WARNING_CHECK(fp != NULL, return, "No valid persist parameter file %s", fileName); 39d9f0492fSopenharmony_ci 40d9f0492fSopenharmony_ci uint32_t paramNum = 0; 41d9f0492fSopenharmony_ci while (fgets(buffer, buffSize, fp) != NULL) { 42d9f0492fSopenharmony_ci buffer[buffSize - 1] = '\0'; 43d9f0492fSopenharmony_ci int ret = SplitParamString(buffer, NULL, 0, LoadOnePersistParam_, NULL); 44d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, continue, "Failed to set param %d %s", ret, buffer); 45d9f0492fSopenharmony_ci paramNum++; 46d9f0492fSopenharmony_ci } 47d9f0492fSopenharmony_ci (void)fclose(fp); 48d9f0492fSopenharmony_ci PARAM_LOGI("LoadPersistParam from file %s paramNum %d", fileName, paramNum); 49d9f0492fSopenharmony_ci} 50d9f0492fSopenharmony_ci 51d9f0492fSopenharmony_cistatic int LoadPersistParam(void) 52d9f0492fSopenharmony_ci{ 53d9f0492fSopenharmony_ci CheckAndCreateDir(PARAM_PERSIST_SAVE_PATH); 54d9f0492fSopenharmony_ci const uint32_t buffSize = PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX + 10; // 10 max len 55d9f0492fSopenharmony_ci char *buffer = malloc(buffSize); 56d9f0492fSopenharmony_ci PARAM_CHECK(buffer != NULL, return -1, "Failed to alloc"); 57d9f0492fSopenharmony_ci 58d9f0492fSopenharmony_ci int updaterMode = InUpdaterMode(); 59d9f0492fSopenharmony_ci char *tmpPath = (updaterMode == 0) ? PARAM_PERSIST_SAVE_PATH : "/param/persist_parameters"; 60d9f0492fSopenharmony_ci LoadPersistParam_(tmpPath, buffer, buffSize); 61d9f0492fSopenharmony_ci tmpPath = (updaterMode == 0) ? PARAM_PERSIST_SAVE_TMP_PATH : "/param/tmp_persist_parameters"; 62d9f0492fSopenharmony_ci LoadPersistParam_(tmpPath, buffer, buffSize); 63d9f0492fSopenharmony_ci free(buffer); 64d9f0492fSopenharmony_ci return 0; 65d9f0492fSopenharmony_ci} 66d9f0492fSopenharmony_ci 67d9f0492fSopenharmony_cistatic int SavePersistParam(const char *name, const char *value) 68d9f0492fSopenharmony_ci{ 69d9f0492fSopenharmony_ci ParamMutexPend(&g_saveMutex); 70d9f0492fSopenharmony_ci char *path = (InUpdaterMode() == 0) ? PARAM_PERSIST_SAVE_PATH : "/param/persist_parameters"; 71d9f0492fSopenharmony_ci FILE *fp = fopen(path, "a+"); 72d9f0492fSopenharmony_ci int ret = -1; 73d9f0492fSopenharmony_ci if (fp != NULL) { 74d9f0492fSopenharmony_ci ret = fprintf(fp, "%s=%s\n", name, value); 75d9f0492fSopenharmony_ci (void)fclose(fp); 76d9f0492fSopenharmony_ci } 77d9f0492fSopenharmony_ci ParamMutexPost(&g_saveMutex); 78d9f0492fSopenharmony_ci if (ret <= 0) { 79d9f0492fSopenharmony_ci PARAM_LOGE("Failed to save persist param %s", name); 80d9f0492fSopenharmony_ci } 81d9f0492fSopenharmony_ci return ret; 82d9f0492fSopenharmony_ci} 83d9f0492fSopenharmony_ci 84d9f0492fSopenharmony_cistatic int BatchSavePersistParamBegin(PERSIST_SAVE_HANDLE *handle) 85d9f0492fSopenharmony_ci{ 86d9f0492fSopenharmony_ci ParamMutexPend(&g_saveMutex); 87d9f0492fSopenharmony_ci char *path = (InUpdaterMode() == 0) ? PARAM_PERSIST_SAVE_TMP_PATH : "/param/tmp_persist_parameters"; 88d9f0492fSopenharmony_ci unlink(path); 89d9f0492fSopenharmony_ci FILE *fp = fopen(path, "w"); 90d9f0492fSopenharmony_ci if (fp == NULL) { 91d9f0492fSopenharmony_ci ParamMutexPost(&g_saveMutex); 92d9f0492fSopenharmony_ci PARAM_LOGE("Open file %s fail error %d", path, errno); 93d9f0492fSopenharmony_ci return -1; 94d9f0492fSopenharmony_ci } 95d9f0492fSopenharmony_ci *handle = (PERSIST_SAVE_HANDLE)fp; 96d9f0492fSopenharmony_ci return 0; 97d9f0492fSopenharmony_ci} 98d9f0492fSopenharmony_ci 99d9f0492fSopenharmony_cistatic int BatchSavePersistParam(PERSIST_SAVE_HANDLE handle, const char *name, const char *value) 100d9f0492fSopenharmony_ci{ 101d9f0492fSopenharmony_ci FILE *fp = (FILE *)handle; 102d9f0492fSopenharmony_ci int ret = fprintf(fp, "%s=%s\n", name, value); 103d9f0492fSopenharmony_ci PARAM_LOGV("BatchSavePersistParam %s=%s", name, value); 104d9f0492fSopenharmony_ci return (ret > 0) ? 0 : -1; 105d9f0492fSopenharmony_ci} 106d9f0492fSopenharmony_ci 107d9f0492fSopenharmony_cistatic void BatchSavePersistParamEnd(PERSIST_SAVE_HANDLE handle) 108d9f0492fSopenharmony_ci{ 109d9f0492fSopenharmony_ci int ret; 110d9f0492fSopenharmony_ci FILE *fp = (FILE *)handle; 111d9f0492fSopenharmony_ci (void)fflush(fp); 112d9f0492fSopenharmony_ci (void)fsync(fileno(fp)); 113d9f0492fSopenharmony_ci (void)fclose(fp); 114d9f0492fSopenharmony_ci if (InUpdaterMode() == 0) { 115d9f0492fSopenharmony_ci unlink(PARAM_PERSIST_SAVE_PATH); 116d9f0492fSopenharmony_ci ret = rename(PARAM_PERSIST_SAVE_TMP_PATH, PARAM_PERSIST_SAVE_PATH); 117d9f0492fSopenharmony_ci } else { 118d9f0492fSopenharmony_ci unlink("/param/persist_parameters"); 119d9f0492fSopenharmony_ci ret = rename("/param/tmp_persist_parameters", "/param/persist_parameters"); 120d9f0492fSopenharmony_ci } 121d9f0492fSopenharmony_ci ParamMutexPost(&g_saveMutex); 122d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return, "BatchSavePersistParamEnd %s fail error %d", PARAM_PERSIST_SAVE_TMP_PATH, errno); 123d9f0492fSopenharmony_ci} 124d9f0492fSopenharmony_ci 125d9f0492fSopenharmony_ciint RegisterPersistParamOps(PersistParamOps *ops) 126d9f0492fSopenharmony_ci{ 127d9f0492fSopenharmony_ci ParamMutexCreate(&g_saveMutex); 128d9f0492fSopenharmony_ci PARAM_CHECK(ops != NULL, return -1, "Invalid ops"); 129d9f0492fSopenharmony_ci ops->save = SavePersistParam; 130d9f0492fSopenharmony_ci ops->load = LoadPersistParam; 131d9f0492fSopenharmony_ci ops->batchSaveBegin = BatchSavePersistParamBegin; 132d9f0492fSopenharmony_ci ops->batchSave = BatchSavePersistParam; 133d9f0492fSopenharmony_ci ops->batchSaveEnd = BatchSavePersistParamEnd; 134d9f0492fSopenharmony_ci return 0; 135d9f0492fSopenharmony_ci}