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