169570cc8Sopenharmony_ci/* 269570cc8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License. 569570cc8Sopenharmony_ci * You may obtain a copy of the License at 669570cc8Sopenharmony_ci * 769570cc8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 869570cc8Sopenharmony_ci * 969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and 1369570cc8Sopenharmony_ci * limitations under the License. 1469570cc8Sopenharmony_ci */ 1569570cc8Sopenharmony_ci 1669570cc8Sopenharmony_ci#ifndef APPSPAWN_MANAGER_H 1769570cc8Sopenharmony_ci#define APPSPAWN_MANAGER_H 1869570cc8Sopenharmony_ci 1969570cc8Sopenharmony_ci#include <limits.h> 2069570cc8Sopenharmony_ci#include <stdbool.h> 2169570cc8Sopenharmony_ci#include <unistd.h> 2269570cc8Sopenharmony_ci 2369570cc8Sopenharmony_ci#include "appspawn.h" 2469570cc8Sopenharmony_ci#include "appspawn_hook.h" 2569570cc8Sopenharmony_ci#include "appspawn_msg.h" 2669570cc8Sopenharmony_ci#include "appspawn_server.h" 2769570cc8Sopenharmony_ci#include "appspawn_utils.h" 2869570cc8Sopenharmony_ci#include "list.h" 2969570cc8Sopenharmony_ci#include "loop_event.h" 3069570cc8Sopenharmony_ci 3169570cc8Sopenharmony_ci#ifdef __cplusplus 3269570cc8Sopenharmony_ciextern "C" { 3369570cc8Sopenharmony_ci#endif 3469570cc8Sopenharmony_ci 3569570cc8Sopenharmony_ci#define MODE_ID_INDEX 1 3669570cc8Sopenharmony_ci#define MODE_VALUE_INDEX 2 3769570cc8Sopenharmony_ci#define FD_ID_INDEX 3 3869570cc8Sopenharmony_ci#define FD_VALUE_INDEX 4 3969570cc8Sopenharmony_ci#define FLAGS_VALUE_INDEX 5 4069570cc8Sopenharmony_ci#define SHM_SIZE_INDEX 6 4169570cc8Sopenharmony_ci#define PARAM_ID_INDEX 7 4269570cc8Sopenharmony_ci#define PARAM_VALUE_INDEX 8 4369570cc8Sopenharmony_ci#define CLIENT_ID_INDEX 9 4469570cc8Sopenharmony_ci#define ARG_NULL 10 4569570cc8Sopenharmony_ci 4669570cc8Sopenharmony_ci#define MAX_DIED_PROCESS_COUNT 5 4769570cc8Sopenharmony_ci 4869570cc8Sopenharmony_ci#define INVALID_OFFSET 0xffffffff 4969570cc8Sopenharmony_ci 5069570cc8Sopenharmony_ci#define APP_STATE_IDLE 1 5169570cc8Sopenharmony_ci#define APP_STATE_SPAWNING 2 5269570cc8Sopenharmony_ci#define APPSPAWN_MAX_TIME 3000000 5369570cc8Sopenharmony_ci 5469570cc8Sopenharmony_ci#define APPSPAWN_INLINE __attribute__((always_inline)) inline 5569570cc8Sopenharmony_ci 5669570cc8Sopenharmony_citypedef struct AppSpawnContent AppSpawnContent; 5769570cc8Sopenharmony_citypedef struct AppSpawnClient AppSpawnClient; 5869570cc8Sopenharmony_citypedef struct TagAppSpawnConnection AppSpawnConnection; 5969570cc8Sopenharmony_ci 6069570cc8Sopenharmony_citypedef struct TagAppSpawnMsgNode { 6169570cc8Sopenharmony_ci AppSpawnConnection *connection; 6269570cc8Sopenharmony_ci AppSpawnMsg msgHeader; 6369570cc8Sopenharmony_ci uint32_t tlvCount; 6469570cc8Sopenharmony_ci uint32_t *tlvOffset; // 记录属性的在msg中的偏移,不完全拷贝试消息完整 6569570cc8Sopenharmony_ci uint8_t *buffer; 6669570cc8Sopenharmony_ci} AppSpawnMsgNode; 6769570cc8Sopenharmony_ci 6869570cc8Sopenharmony_citypedef struct { 6969570cc8Sopenharmony_ci int32_t fd[2]; // 2 fd count 7069570cc8Sopenharmony_ci WatcherHandle watcherHandle; 7169570cc8Sopenharmony_ci WatcherHandle pidFdWatcherHandle; 7269570cc8Sopenharmony_ci TimerHandle timer; 7369570cc8Sopenharmony_ci char *childMsg; 7469570cc8Sopenharmony_ci uint32_t msgSize; 7569570cc8Sopenharmony_ci char *coldRunPath; 7669570cc8Sopenharmony_ci} AppSpawnForkCtx; 7769570cc8Sopenharmony_ci 7869570cc8Sopenharmony_citypedef struct TagAppSpawningCtx { 7969570cc8Sopenharmony_ci AppSpawnClient client; 8069570cc8Sopenharmony_ci struct ListNode node; 8169570cc8Sopenharmony_ci AppSpawnForkCtx forkCtx; 8269570cc8Sopenharmony_ci AppSpawnMsgNode *message; 8369570cc8Sopenharmony_ci bool isPrefork; 8469570cc8Sopenharmony_ci pid_t pid; 8569570cc8Sopenharmony_ci int state; 8669570cc8Sopenharmony_ci struct timespec spawnStart; 8769570cc8Sopenharmony_ci} AppSpawningCtx; 8869570cc8Sopenharmony_ci 8969570cc8Sopenharmony_citypedef struct TagAppSpawnedProcess { 9069570cc8Sopenharmony_ci struct ListNode node; 9169570cc8Sopenharmony_ci uid_t uid; 9269570cc8Sopenharmony_ci pid_t pid; 9369570cc8Sopenharmony_ci uint32_t max; 9469570cc8Sopenharmony_ci int exitStatus; 9569570cc8Sopenharmony_ci struct timespec spawnStart; 9669570cc8Sopenharmony_ci struct timespec spawnEnd; 9769570cc8Sopenharmony_ci#ifdef DEBUG_BEGETCTL_BOOT 9869570cc8Sopenharmony_ci AppSpawnMsgNode *message; 9969570cc8Sopenharmony_ci#endif 10069570cc8Sopenharmony_ci bool isDebuggable; 10169570cc8Sopenharmony_ci char name[0]; 10269570cc8Sopenharmony_ci} AppSpawnedProcess; 10369570cc8Sopenharmony_ci 10469570cc8Sopenharmony_citypedef struct SpawnTime { 10569570cc8Sopenharmony_ci int minAppspawnTime; 10669570cc8Sopenharmony_ci int maxAppspawnTime; 10769570cc8Sopenharmony_ci} SpawnTime; 10869570cc8Sopenharmony_ci 10969570cc8Sopenharmony_citypedef struct TagAppSpawnMgr { 11069570cc8Sopenharmony_ci AppSpawnContent content; 11169570cc8Sopenharmony_ci TaskHandle server; 11269570cc8Sopenharmony_ci SignalHandle sigHandler; 11369570cc8Sopenharmony_ci pid_t servicePid; 11469570cc8Sopenharmony_ci struct ListNode appQueue; // save app pid and name 11569570cc8Sopenharmony_ci uint32_t diedAppCount; 11669570cc8Sopenharmony_ci uint32_t flags; 11769570cc8Sopenharmony_ci struct ListNode diedQueue; // save app pid and name 11869570cc8Sopenharmony_ci struct ListNode appSpawnQueue; // save app pid and name 11969570cc8Sopenharmony_ci struct timespec perLoadStart; 12069570cc8Sopenharmony_ci struct timespec perLoadEnd; 12169570cc8Sopenharmony_ci struct ListNode extData; 12269570cc8Sopenharmony_ci struct SpawnTime spawnTime; 12369570cc8Sopenharmony_ci} AppSpawnMgr; 12469570cc8Sopenharmony_ci 12569570cc8Sopenharmony_ci/** 12669570cc8Sopenharmony_ci * @brief App Spawn Mgr object op 12769570cc8Sopenharmony_ci * 12869570cc8Sopenharmony_ci */ 12969570cc8Sopenharmony_ciAppSpawnMgr *CreateAppSpawnMgr(int mode); 13069570cc8Sopenharmony_ciAppSpawnMgr *GetAppSpawnMgr(void); 13169570cc8Sopenharmony_civoid DeleteAppSpawnMgr(AppSpawnMgr *mgr); 13269570cc8Sopenharmony_ciAppSpawnContent *GetAppSpawnContent(void); 13369570cc8Sopenharmony_ci 13469570cc8Sopenharmony_ci/** 13569570cc8Sopenharmony_ci * @brief 孵化成功后进程或者app实例的操作 13669570cc8Sopenharmony_ci * 13769570cc8Sopenharmony_ci */ 13869570cc8Sopenharmony_citypedef void (*AppTraversal)(const AppSpawnMgr *mgr, AppSpawnedProcess *appInfo, void *data); 13969570cc8Sopenharmony_civoid TraversalSpawnedProcess(AppTraversal traversal, void *data); 14069570cc8Sopenharmony_ciAppSpawnedProcess *AddSpawnedProcess(pid_t pid, const char *processName, bool isDebuggable); 14169570cc8Sopenharmony_ciAppSpawnedProcess *GetSpawnedProcess(pid_t pid); 14269570cc8Sopenharmony_ciAppSpawnedProcess *GetSpawnedProcessByName(const char *name); 14369570cc8Sopenharmony_civoid TerminateSpawnedProcess(AppSpawnedProcess *node); 14469570cc8Sopenharmony_ci 14569570cc8Sopenharmony_ci/** 14669570cc8Sopenharmony_ci * @brief 孵化过程中的ctx对象的操作 14769570cc8Sopenharmony_ci * 14869570cc8Sopenharmony_ci */ 14969570cc8Sopenharmony_citypedef void (*ProcessTraversal)(const AppSpawnMgr *mgr, AppSpawningCtx *ctx, void *data); 15069570cc8Sopenharmony_civoid AppSpawningCtxTraversal(ProcessTraversal traversal, void *data); 15169570cc8Sopenharmony_ciAppSpawningCtx *GetAppSpawningCtxByPid(pid_t pid); 15269570cc8Sopenharmony_ciAppSpawningCtx *CreateAppSpawningCtx(); 15369570cc8Sopenharmony_civoid DeleteAppSpawningCtx(AppSpawningCtx *property); 15469570cc8Sopenharmony_ciint KillAndWaitStatus(pid_t pid, int sig, int *exitStatus); 15569570cc8Sopenharmony_ci 15669570cc8Sopenharmony_ci/** 15769570cc8Sopenharmony_ci * @brief 消息解析、处理 15869570cc8Sopenharmony_ci * 15969570cc8Sopenharmony_ci */ 16069570cc8Sopenharmony_civoid ProcessAppSpawnDumpMsg(const AppSpawnMsgNode *message); 16169570cc8Sopenharmony_ciint ProcessTerminationStatusMsg(const AppSpawnMsgNode *message, AppSpawnResult *result); 16269570cc8Sopenharmony_ci 16369570cc8Sopenharmony_ciAppSpawnMsgNode *CreateAppSpawnMsg(void); 16469570cc8Sopenharmony_civoid DeleteAppSpawnMsg(AppSpawnMsgNode *msgNode); 16569570cc8Sopenharmony_ciint CheckAppSpawnMsg(const AppSpawnMsgNode *message); 16669570cc8Sopenharmony_ciint DecodeAppSpawnMsg(AppSpawnMsgNode *message); 16769570cc8Sopenharmony_ciint GetAppSpawnMsgFromBuffer(const uint8_t *buffer, uint32_t bufferLen, 16869570cc8Sopenharmony_ci AppSpawnMsgNode **outMsg, uint32_t *msgRecvLen, uint32_t *reminder); 16969570cc8Sopenharmony_ciAppSpawnMsgNode *RebuildAppSpawnMsgNode(AppSpawnMsgNode *message, AppSpawnedProcess *appInfo); 17069570cc8Sopenharmony_ci 17169570cc8Sopenharmony_ci/** 17269570cc8Sopenharmony_ci * @brief 消息内容操作接口 17369570cc8Sopenharmony_ci * 17469570cc8Sopenharmony_ci */ 17569570cc8Sopenharmony_civoid DumpAppSpawnMsg(const AppSpawnMsgNode *message); 17669570cc8Sopenharmony_civoid *GetAppSpawnMsgInfo(const AppSpawnMsgNode *message, int type); 17769570cc8Sopenharmony_civoid *GetAppSpawnMsgExtInfo(const AppSpawnMsgNode *message, const char *name, uint32_t *len); 17869570cc8Sopenharmony_ciint CheckAppSpawnMsgFlag(const AppSpawnMsgNode *message, uint32_t type, uint32_t index); 17969570cc8Sopenharmony_ciint SetAppSpawnMsgFlag(const AppSpawnMsgNode *message, uint32_t type, uint32_t index); 18069570cc8Sopenharmony_ci 18169570cc8Sopenharmony_ciAPPSPAWN_INLINE int IsSpawnServer(const AppSpawnMgr *content) 18269570cc8Sopenharmony_ci{ 18369570cc8Sopenharmony_ci return (content != NULL) && (content->servicePid == getpid()); 18469570cc8Sopenharmony_ci} 18569570cc8Sopenharmony_ci 18669570cc8Sopenharmony_ciAPPSPAWN_INLINE int IsNWebSpawnMode(const AppSpawnMgr *content) 18769570cc8Sopenharmony_ci{ 18869570cc8Sopenharmony_ci return (content != NULL) && 18969570cc8Sopenharmony_ci (content->content.mode == MODE_FOR_NWEB_SPAWN || content->content.mode == MODE_FOR_NWEB_COLD_RUN); 19069570cc8Sopenharmony_ci} 19169570cc8Sopenharmony_ci 19269570cc8Sopenharmony_ciAPPSPAWN_INLINE int IsColdRunMode(const AppSpawnMgr *content) 19369570cc8Sopenharmony_ci{ 19469570cc8Sopenharmony_ci return (content != NULL) && 19569570cc8Sopenharmony_ci (content->content.mode == MODE_FOR_APP_COLD_RUN || content->content.mode == MODE_FOR_NWEB_COLD_RUN); 19669570cc8Sopenharmony_ci} 19769570cc8Sopenharmony_ci 19869570cc8Sopenharmony_ciAPPSPAWN_INLINE int IsDeveloperModeOn(const AppSpawningCtx *property) 19969570cc8Sopenharmony_ci{ 20069570cc8Sopenharmony_ci return (property != NULL && ((property->client.flags & APP_DEVELOPER_MODE) == APP_DEVELOPER_MODE)); 20169570cc8Sopenharmony_ci} 20269570cc8Sopenharmony_ci 20369570cc8Sopenharmony_ciAPPSPAWN_INLINE int IsJitFortModeOn(const AppSpawningCtx *property) 20469570cc8Sopenharmony_ci{ 20569570cc8Sopenharmony_ci return (property != NULL && ((property->client.flags & APP_JITFORT_MODE) == APP_JITFORT_MODE)); 20669570cc8Sopenharmony_ci} 20769570cc8Sopenharmony_ci 20869570cc8Sopenharmony_ciAPPSPAWN_INLINE int GetAppSpawnMsgType(const AppSpawningCtx *appProperty) 20969570cc8Sopenharmony_ci{ 21069570cc8Sopenharmony_ci return (appProperty != NULL && appProperty->message != NULL) ? 21169570cc8Sopenharmony_ci appProperty->message->msgHeader.msgType : MAX_TYPE_INVALID; 21269570cc8Sopenharmony_ci} 21369570cc8Sopenharmony_ci 21469570cc8Sopenharmony_ciAPPSPAWN_INLINE const char *GetProcessName(const AppSpawningCtx *property) 21569570cc8Sopenharmony_ci{ 21669570cc8Sopenharmony_ci if (property == NULL || property->message == NULL) { 21769570cc8Sopenharmony_ci return NULL; 21869570cc8Sopenharmony_ci } 21969570cc8Sopenharmony_ci return property->message->msgHeader.processName; 22069570cc8Sopenharmony_ci} 22169570cc8Sopenharmony_ci 22269570cc8Sopenharmony_ciAPPSPAWN_INLINE const char *GetBundleName(const AppSpawningCtx *property) 22369570cc8Sopenharmony_ci{ 22469570cc8Sopenharmony_ci if (property == NULL || property->message == NULL) { 22569570cc8Sopenharmony_ci return NULL; 22669570cc8Sopenharmony_ci } 22769570cc8Sopenharmony_ci AppSpawnMsgBundleInfo *info = (AppSpawnMsgBundleInfo *)GetAppSpawnMsgInfo(property->message, TLV_BUNDLE_INFO); 22869570cc8Sopenharmony_ci if (info != NULL) { 22969570cc8Sopenharmony_ci return info->bundleName; 23069570cc8Sopenharmony_ci } 23169570cc8Sopenharmony_ci return NULL; 23269570cc8Sopenharmony_ci} 23369570cc8Sopenharmony_ci 23469570cc8Sopenharmony_ciAPPSPAWN_INLINE void *GetAppProperty(const AppSpawningCtx *property, uint32_t type) 23569570cc8Sopenharmony_ci{ 23669570cc8Sopenharmony_ci APPSPAWN_CHECK(property != NULL && property->message != NULL, 23769570cc8Sopenharmony_ci return NULL, "Invalid property for type %{public}u", type); 23869570cc8Sopenharmony_ci return GetAppSpawnMsgInfo(property->message, type); 23969570cc8Sopenharmony_ci} 24069570cc8Sopenharmony_ci 24169570cc8Sopenharmony_ciAPPSPAWN_INLINE void *GetAppPropertyExt(const AppSpawningCtx *property, const char *name, uint32_t *len) 24269570cc8Sopenharmony_ci{ 24369570cc8Sopenharmony_ci APPSPAWN_CHECK(name != NULL, return NULL, "Invalid name "); 24469570cc8Sopenharmony_ci APPSPAWN_CHECK(property != NULL && property->message != NULL, 24569570cc8Sopenharmony_ci return NULL, "Invalid property for name %{public}s", name); 24669570cc8Sopenharmony_ci return GetAppSpawnMsgExtInfo(property->message, name, len); 24769570cc8Sopenharmony_ci} 24869570cc8Sopenharmony_ci 24969570cc8Sopenharmony_ciAPPSPAWN_INLINE int CheckAppMsgFlagsSet(const AppSpawningCtx *property, uint32_t index) 25069570cc8Sopenharmony_ci{ 25169570cc8Sopenharmony_ci APPSPAWN_CHECK(property != NULL && property->message != NULL, 25269570cc8Sopenharmony_ci return 0, "Invalid property for name %{public}u", TLV_MSG_FLAGS); 25369570cc8Sopenharmony_ci return CheckAppSpawnMsgFlag(property->message, TLV_MSG_FLAGS, index); 25469570cc8Sopenharmony_ci} 25569570cc8Sopenharmony_ci 25669570cc8Sopenharmony_ciAPPSPAWN_INLINE int CheckAppPermissionFlagSet(const AppSpawningCtx *property, uint32_t index) 25769570cc8Sopenharmony_ci{ 25869570cc8Sopenharmony_ci APPSPAWN_CHECK(property != NULL && property->message != NULL, 25969570cc8Sopenharmony_ci return 0, "Invalid property for name %{public}u", TLV_PERMISSION); 26069570cc8Sopenharmony_ci return CheckAppSpawnMsgFlag(property->message, TLV_PERMISSION, index); 26169570cc8Sopenharmony_ci} 26269570cc8Sopenharmony_ci 26369570cc8Sopenharmony_ciAPPSPAWN_INLINE int SetAppPermissionFlags(const AppSpawningCtx *property, uint32_t index) 26469570cc8Sopenharmony_ci{ 26569570cc8Sopenharmony_ci APPSPAWN_CHECK(property != NULL && property->message != NULL, 26669570cc8Sopenharmony_ci return -1, "Invalid property for name %{public}u", TLV_PERMISSION); 26769570cc8Sopenharmony_ci return SetAppSpawnMsgFlag(property->message, TLV_PERMISSION, index); 26869570cc8Sopenharmony_ci} 26969570cc8Sopenharmony_ci 27069570cc8Sopenharmony_ciAPPSPAWN_INLINE int IsIsolatedNativeSpawnMode(const AppSpawnMgr *content, const AppSpawningCtx *property) 27169570cc8Sopenharmony_ci{ 27269570cc8Sopenharmony_ci return (content != NULL) && (content->content.mode == MODE_FOR_NATIVE_SPAWN) && 27369570cc8Sopenharmony_ci CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE); 27469570cc8Sopenharmony_ci} 27569570cc8Sopenharmony_ci 27669570cc8Sopenharmony_ci#ifdef __cplusplus 27769570cc8Sopenharmony_ci} 27869570cc8Sopenharmony_ci#endif 27969570cc8Sopenharmony_ci#endif // APPSPAWN_MANAGER_H 280