• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 <fcntl.h>
18 #include <signal.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #ifdef __MUSL__
22 #include <stropts.h>
23 #endif
24 #include <sys/capability.h>
25 #include <sys/ioctl.h>
26 #include <sys/param.h>
27 #include <sys/stat.h>
28 #include <time.h>
29 #include <unistd.h>
30 
31 #include "init.h"
32 #include "init_adapter.h"
33 #include "init_cmds.h"
34 #include "init_log.h"
35 #include "init_jobs_internal.h"
36 #include "init_service.h"
37 #include "init_service_manager.h"
38 #include "init_service_socket.h"
39 #include "init_utils.h"
40 #include "fd_holder_internal.h"
41 #include "loop_event.h"
42 #include "securec.h"
43 #include "service_control.h"
44 
45 #ifdef WITH_SELINUX
46 #include "init_selinux_param.h"
47 #include <selinux/selinux.h>
48 #endif // WITH_SELINUX
49 
50 #ifndef TIOCSCTTY
51 #define TIOCSCTTY 0x540E
52 #endif
53 
SetAllAmbientCapability(void)54 static int SetAllAmbientCapability(void)
55 {
56     for (int i = 0; i <= CAP_LAST_CAP; ++i) {
57         if (SetAmbientCapability(i) != 0) {
58             return SERVICE_FAILURE;
59         }
60     }
61     return SERVICE_SUCCESS;
62 }
63 
SetPerms(const Service * service)64 static int SetPerms(const Service *service)
65 {
66     INIT_CHECK_RETURN_VALUE(KeepCapability() == 0, SERVICE_FAILURE);
67 
68     if (service->servPerm.gIDCnt == 0) {
69         // use uid as gid
70         INIT_ERROR_CHECK(setgid(service->servPerm.uID) == 0, return SERVICE_FAILURE,
71             "SetPerms, setgid for %s failed. %d", service->name, errno);
72     }
73     if (service->servPerm.gIDCnt > 0) {
74         INIT_ERROR_CHECK(setgid(service->servPerm.gIDArray[0]) == 0, return SERVICE_FAILURE,
75             "SetPerms, setgid for %s failed. %d", service->name, errno);
76     }
77     if (service->servPerm.gIDCnt > 1) {
78         INIT_ERROR_CHECK(setgroups(service->servPerm.gIDCnt - 1, (const gid_t *)&service->servPerm.gIDArray[1]) == 0,
79             return SERVICE_FAILURE,
80             "SetPerms, setgroups failed. errno = %d, gIDCnt=%d", errno, service->servPerm.gIDCnt);
81     }
82     if (service->servPerm.uID != 0) {
83         if (setuid(service->servPerm.uID) != 0) {
84             INIT_LOGE("setuid of service: %s failed, uid = %d", service->name, service->servPerm.uID);
85             return SERVICE_FAILURE;
86         }
87     }
88 
89     struct __user_cap_header_struct capHeader;
90     capHeader.version = _LINUX_CAPABILITY_VERSION_3;
91     capHeader.pid = 0;
92     struct __user_cap_data_struct capData[CAP_NUM] = {};
93     for (unsigned int i = 0; i < service->servPerm.capsCnt; ++i) {
94         if (service->servPerm.caps[i] == FULL_CAP) {
95             for (int j = 0; j < CAP_NUM; ++j) {
96                 capData[j].effective = FULL_CAP;
97                 capData[j].permitted = FULL_CAP;
98                 capData[j].inheritable = FULL_CAP;
99             }
100             break;
101         }
102         capData[CAP_TO_INDEX(service->servPerm.caps[i])].effective |= CAP_TO_MASK(service->servPerm.caps[i]);
103         capData[CAP_TO_INDEX(service->servPerm.caps[i])].permitted |= CAP_TO_MASK(service->servPerm.caps[i]);
104         capData[CAP_TO_INDEX(service->servPerm.caps[i])].inheritable |= CAP_TO_MASK(service->servPerm.caps[i]);
105     }
106 
107     if (capset(&capHeader, capData) != 0) {
108         INIT_LOGE("capset faild for service: %s, error: %d", service->name, errno);
109         return SERVICE_FAILURE;
110     }
111     for (unsigned int i = 0; i < service->servPerm.capsCnt; ++i) {
112         if (service->servPerm.caps[i] == FULL_CAP) {
113             return SetAllAmbientCapability();
114         }
115         if (SetAmbientCapability(service->servPerm.caps[i]) != 0) {
116             INIT_LOGE("SetAmbientCapability faild for service: %s", service->name);
117             return SERVICE_FAILURE;
118         }
119     }
120     return SERVICE_SUCCESS;
121 }
122 
OpenConsole(void)123 static void OpenConsole(void)
124 {
125     const int stdError = 2;
126     setsid();
127     WaitForFile("/dev/console", WAIT_MAX_SECOND);
128     int fd = open("/dev/console", O_RDWR);
129     if (fd >= 0) {
130         ioctl(fd, TIOCSCTTY, 0);
131         dup2(fd, 0);
132         dup2(fd, 1);
133         dup2(fd, stdError); // Redirect fd to 0, 1, 2
134         close(fd);
135     } else {
136         INIT_LOGE("Open /dev/console failed. err = %d", errno);
137     }
138     return;
139 }
140 
WritePid(const Service * service)141 static int WritePid(const Service *service)
142 {
143     const int maxPidStrLen = 50;
144     char pidString[maxPidStrLen];
145     pid_t childPid = getpid();
146     int len = snprintf_s(pidString, maxPidStrLen, maxPidStrLen - 1, "%d", childPid);
147     INIT_ERROR_CHECK(len > 0, return SERVICE_FAILURE, "Failed to format pid for service %s", service->name);
148     for (int i = 0; i < service->writePidArgs.count; i++) {
149         if (service->writePidArgs.argv[i] == NULL) {
150             continue;
151         }
152         FILE *fd = NULL;
153         char *realPath = GetRealPath(service->writePidArgs.argv[i]);
154         if (realPath != NULL) {
155             fd = fopen(realPath, "wb");
156         } else {
157             fd = fopen(service->writePidArgs.argv[i], "wb");
158         }
159         if (fd != NULL) {
160             INIT_CHECK_ONLY_ELOG((int)fwrite(pidString, 1, len, fd) == len,
161                 "Failed to write %s pid:%s", service->writePidArgs.argv[i], pidString);
162             (void)fclose(fd);
163         } else {
164             INIT_LOGE("Failed to open %s.", service->writePidArgs.argv[i]);
165         }
166         if (realPath != NULL) {
167             free(realPath);
168         }
169         INIT_LOGV("ServiceStart writepid filename=%s, childPid=%s, ok", service->writePidArgs.argv[i], pidString);
170     }
171     return SERVICE_SUCCESS;
172 }
173 
SetSecon(Service * service)174 void SetSecon(Service *service)
175 {
176 #ifdef WITH_SELINUX
177     if (*(service->secon)) {
178         if (setexeccon(service->secon) < 0) {
179             INIT_LOGE("failed to set service %s's secon (%s).", service->name, service->secon);
180         } else {
181             INIT_LOGI("service %s secon set to %s.", service->name, service->secon);
182         }
183     }
184 #endif // WITH_SELINUX
185 }
186 
CloseServiceFds(Service * service,bool needFree)187 void CloseServiceFds(Service *service, bool needFree)
188 {
189     if (service == NULL) {
190         return;
191     }
192 
193     INIT_LOGI("Closing service \' %s \' fds", service->name);
194     // fdCount > 0, There is no reason fds is NULL
195     if (service->fdCount != 0) {
196         size_t fdCount = service->fdCount;
197         int *fds = service->fds;
198         for (size_t i = 0; i < fdCount; i++) {
199             INIT_LOGV("Closing fd: %d", fds[i]);
200             close(fds[i]);
201             fds[i] = -1;
202         }
203     }
204     service->fdCount = 0;
205     if (needFree && service->fds != NULL) {
206         free(service->fds);
207         service->fds = NULL;
208     }
209 }
210 
PublishHoldFds(Service * service)211 static void PublishHoldFds(Service *service)
212 {
213     INIT_ERROR_CHECK(service != NULL, return, "Publish hold fds with invalid service");
214     char fdBuffer[MAX_FD_HOLDER_BUFFER] = {};
215     if (service->fdCount > 0 && service->fds != NULL) {
216         size_t pos = 0;
217         for (size_t i = 0; i < service->fdCount; i++) {
218             int fd = dup(service->fds[i]);
219             if (fd < 0) {
220                 INIT_LOGE("Duplicate file descriptors of Service \' %s \' failed. err = %d", service->name, errno);
221                 continue;
222             }
223             if (snprintf_s((char *)fdBuffer + pos, sizeof(fdBuffer) - pos, sizeof(fdBuffer) - 1, "%d ", fd) < 0) {
224                 INIT_LOGE("snprintf_s failed err=%d", errno);
225                 return;
226             }
227             pos = strlen(fdBuffer);
228         }
229         fdBuffer[pos - 1] = '\0'; // Remove last ' '
230         INIT_LOGI("fd buffer: [%s]", fdBuffer);
231         char envName[MAX_BUFFER_LEN] = {};
232         (void)snprintf_s(envName, MAX_BUFFER_LEN, MAX_BUFFER_LEN - 1, ENV_FD_HOLD_PREFIX"%s", service->name);
233         if (setenv(envName, fdBuffer, 1) < 0) {
234             INIT_LOGE("Failed to set env %s", envName);
235         }
236         INIT_LOGI("File descriptors of Service \' %s \' published", service->name);
237     }
238 }
239 
BindCpuCore(Service * service)240 static int BindCpuCore(Service *service)
241 {
242     if (service == NULL) {
243         return SERVICE_SUCCESS;
244     }
245     if (CPU_COUNT(&service->cpuSet) == 0) {
246         return SERVICE_SUCCESS;
247     }
248 #ifndef __LITEOS__
249     int pid = getpid();
250     if (sched_setaffinity(pid, sizeof(service->cpuSet), &service->cpuSet) != 0) {
251         INIT_LOGE("%s set affinity between process(pid=%d) with CPU's core failed", service->name, pid);
252         return SERVICE_FAILURE;
253     }
254     INIT_LOGI("%s set affinity between process(pid=%d) with CPU's core successfully", service->name, pid);
255 #endif
256     return SERVICE_SUCCESS;
257 }
258 
ClearEnvironment(void)259 static void ClearEnvironment(void)
260 {
261     sigset_t mask;
262     sigemptyset(&mask);
263     sigaddset(&mask, SIGCHLD);
264     sigaddset(&mask, SIGTERM);
265     sigprocmask(SIG_UNBLOCK, &mask, NULL);
266     return;
267 }
268 
ServiceStart(Service * service)269 int ServiceStart(Service *service)
270 {
271     INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "start service failed! null ptr.");
272     INIT_ERROR_CHECK(service->pid <= 0, return SERVICE_SUCCESS, "service : %s had started already.", service->name);
273     INIT_ERROR_CHECK(service->pathArgs.count > 0,
274         return SERVICE_FAILURE, "start service %s pathArgs is NULL.", service->name);
275 
276     if (service->attribute & SERVICE_ATTR_INVALID) {
277         INIT_LOGE("start service %s invalid.", service->name);
278         return SERVICE_FAILURE;
279     }
280     struct stat pathStat = { 0 };
281     service->attribute &= (~(SERVICE_ATTR_NEED_RESTART | SERVICE_ATTR_NEED_STOP));
282     if (stat(service->pathArgs.argv[0], &pathStat) != 0) {
283         service->attribute |= SERVICE_ATTR_INVALID;
284         INIT_LOGE("start service %s invalid, please check %s.", service->name, service->pathArgs.argv[0]);
285         return SERVICE_FAILURE;
286     }
287     int pid = fork();
288     if (pid == 0) {
289         INIT_CHECK_ONLY_ELOG(SetAccessToken(service) == SERVICE_SUCCESS,
290             "set access token failed for service %s", service->name);
291         // deal start job
292         if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) {
293             DoJobNow(service->serviceJobs.jobsName[JOB_ON_START]);
294         }
295 
296         ClearEnvironment();
297 
298         if (!IsOnDemandService(service)) {
299             int ret = CreateServiceSocket(service);
300             INIT_ERROR_CHECK(ret >= 0, return SERVICE_FAILURE,
301                 "service %s exit! create socket failed!", service->name);
302         }
303 
304         CreateServiceFile(service->fileCfg);
305         if (service->attribute & SERVICE_ATTR_CONSOLE) {
306             OpenConsole();
307         }
308         PublishHoldFds(service);
309         INIT_CHECK_ONLY_ELOG(BindCpuCore(service) == SERVICE_SUCCESS,
310             "binding core number failed for service %s", service->name);
311         // permissions
312         INIT_ERROR_CHECK(SetPerms(service) == SERVICE_SUCCESS, _exit(PROCESS_EXIT_CODE),
313             "service %s exit! set perms failed! err %d.", service->name, errno);
314         // write pid
315         INIT_ERROR_CHECK(WritePid(service) == SERVICE_SUCCESS, _exit(PROCESS_EXIT_CODE),
316             "service %s exit! write pid failed!", service->name);
317         SetSecon(service);
318         ServiceExec(service);
319         _exit(PROCESS_EXIT_CODE);
320     } else if (pid < 0) {
321         INIT_LOGE("start service %s fork failed!", service->name);
322         return SERVICE_FAILURE;
323     }
324     INIT_LOGI("service %s starting pid %d", service->name, pid);
325     service->pid = pid;
326     NotifyServiceChange(service, SERVICE_STARTED);
327     return SERVICE_SUCCESS;
328 }
329 
ServiceStop(Service * service)330 int ServiceStop(Service *service)
331 {
332     INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "stop service failed! null ptr.");
333     if (service->serviceJobs.jobsName[JOB_ON_STOP] != NULL) {
334         DoJobNow(service->serviceJobs.jobsName[JOB_ON_STOP]);
335     }
336     service->attribute &= ~SERVICE_ATTR_NEED_RESTART;
337     service->attribute |= SERVICE_ATTR_NEED_STOP;
338     if (service->pid <= 0) {
339         return SERVICE_SUCCESS;
340     }
341     CloseServiceSocket(service);
342     CloseServiceFile(service->fileCfg);
343     // Service stop means service is killed by init or command(i.e stop_service) or system is rebooting
344     // There is no reason still to hold fds
345     if (service->fdCount != 0) {
346         CloseServiceFds(service, true);
347     }
348 
349     if (IsServiceWithTimerEnabled(service)) {
350         ServiceStopTimer(service);
351     }
352     INIT_ERROR_CHECK(kill(service->pid, SIGKILL) == 0, return SERVICE_FAILURE,
353         "stop service %s pid %d failed! err %d.", service->name, service->pid, errno);
354     NotifyServiceChange(service, SERVICE_STOPPING);
355     INIT_LOGI("stop service %s, pid %d.", service->name, service->pid);
356     return SERVICE_SUCCESS;
357 }
358 
CalculateCrashTime(Service * service,int crashTimeLimit,int crashCountLimit)359 static bool CalculateCrashTime(Service *service, int crashTimeLimit, int crashCountLimit)
360 {
361     INIT_ERROR_CHECK(service != NULL && crashTimeLimit > 0 && crashCountLimit > 0,
362         return false, "input params error.");
363     time_t curTime = time(NULL);
364     if (service->crashCnt == 0) {
365         service->firstCrashTime = curTime;
366         ++service->crashCnt;
367         if (service->crashCnt == crashCountLimit) {
368             return false;
369         }
370     } else if (difftime(curTime, service->firstCrashTime) > crashTimeLimit) {
371         service->firstCrashTime = curTime;
372         service->crashCnt = 1;
373     } else {
374         ++service->crashCnt;
375         if (service->crashCnt >= crashCountLimit) {
376             return false;
377         }
378     }
379     return true;
380 }
381 
ExecRestartCmd(Service * service)382 static int ExecRestartCmd(Service *service)
383 {
384     INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "Exec service failed! null ptr.");
385     if (service->restartArg == NULL) {
386         return SERVICE_SUCCESS;
387     }
388     for (int i = 0; i < service->restartArg->cmdNum; i++) {
389         INIT_LOGI("ExecRestartCmd cmdLine->cmdContent %s ", service->restartArg->cmds[i].cmdContent);
390         DoCmdByIndex(service->restartArg->cmds[i].cmdIndex, service->restartArg->cmds[i].cmdContent);
391     }
392     free(service->restartArg);
393     service->restartArg = NULL;
394     return SERVICE_SUCCESS;
395 }
396 
PollSocketAfresh(Service * service)397 static void PollSocketAfresh(Service *service)
398 {
399     if (service->socketCfg == NULL) {
400         INIT_LOGE("service %s socket config is NULL!", service->name);
401         return;
402     }
403     ServiceSocket *tmpSock = service->socketCfg;
404     while (tmpSock != NULL) {
405         if (tmpSock->sockFd <= 0) {
406             INIT_LOGE("Invaid socket %s for service", service->name);
407             tmpSock = tmpSock->next;
408         }
409         SocketAddWatcher(&tmpSock->watcher, service, tmpSock->sockFd);
410         tmpSock = tmpSock->next;
411     }
412     return;
413 }
414 
ServiceReap(Service * service)415 void ServiceReap(Service *service)
416 {
417     INIT_CHECK(service != NULL, return);
418     INIT_LOGI("Reap service %s, pid %d.", service->name, service->pid);
419     service->pid = -1;
420     NotifyServiceChange(service, SERVICE_STOPPED);
421 
422     if (service->attribute & SERVICE_ATTR_INVALID) {
423         INIT_LOGE("Reap service %s invalid.", service->name);
424         return;
425     }
426 
427     // If the service set timer
428     // which means the timer handler will start the service
429     // Init should not start it automatically.
430     INIT_CHECK(IsServiceWithTimerEnabled(service) == 0, return);
431 
432     if (!IsOnDemandService(service)) {
433         CloseServiceSocket(service);
434     }
435     CloseServiceFile(service->fileCfg);
436     // stopped by system-init itself, no need to restart even if it is not one-shot service
437     if (service->attribute & SERVICE_ATTR_NEED_STOP) {
438         service->attribute &= (~SERVICE_ATTR_NEED_STOP);
439         service->crashCnt = 0;
440         return;
441     }
442 
443     // for one-shot service
444     if (service->attribute & SERVICE_ATTR_ONCE) {
445         // no need to restart
446         if (!(service->attribute & SERVICE_ATTR_NEED_RESTART)) {
447             service->attribute &= (~SERVICE_ATTR_NEED_STOP);
448             return;
449         }
450         // the service could be restart even if it is one-shot service
451     }
452 
453     if (service->attribute & SERVICE_ATTR_CRITICAL) { // critical
454         if (CalculateCrashTime(service, service->crashTime, service->crashCount) == false) {
455             INIT_LOGE("Critical service \" %s \" crashed %d times, rebooting system",
456                 service->name, service->crashCount);
457             ServiceStop(GetServiceByName("appspawn"));
458             ExecReboot("reboot");
459         }
460     } else if (!(service->attribute & SERVICE_ATTR_NEED_RESTART)) {
461         if (CalculateCrashTime(service, service->crashTime, service->crashCount) == false) {
462             INIT_LOGE("Service name=%s, crash %d times, no more start.", service->name, service->crashCount);
463             return;
464         }
465     }
466     // service no need to restart which socket managed by init until socket message detected
467     if (IsOnDemandService(service)) {
468         PollSocketAfresh(service);
469         return;
470     }
471 
472     int ret = ExecRestartCmd(service);
473     INIT_CHECK_ONLY_ELOG(ret == SERVICE_SUCCESS, "Failed to exec restartArg for %s", service->name);
474 
475     if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) {
476         DoJobNow(service->serviceJobs.jobsName[JOB_ON_RESTART]);
477     }
478     ret = ServiceStart(service);
479     INIT_CHECK_ONLY_ELOG(ret == SERVICE_SUCCESS, "reap service %s start failed!", service->name);
480     service->attribute &= (~SERVICE_ATTR_NEED_RESTART);
481 }
482 
UpdaterServiceFds(Service * service,int * fds,size_t fdCount)483 int UpdaterServiceFds(Service *service, int *fds, size_t fdCount)
484 {
485     if (service == NULL) {
486         INIT_LOGE("Invalid service info");
487         return -1;
488     }
489 
490     if (fdCount == 0) {
491         INIT_LOGE("Update service fds with fdCount is 0, ignore.");
492         return 0;
493     }
494 
495     // if service->fds is NULL, allocate new memory to hold the fds
496     // else if service->fds is not NULL, we will try to override it.
497     // There are two cases:
498     // 1) service->fdCount != fdCount:
499     //  It is not easy to re-use the memory of service->fds, so we have to free the memory first
500     //  then re-allocate memory to store new fds
501     // 2) service->fdCount == fdCount
502     //  A situation we happy to meet, just override it.
503 
504     int ret = 0;
505     if (service->fdCount == fdCount) {
506         // case 2
507         CloseServiceFds(service, false);
508         if (memcpy_s(service->fds, sizeof(int) * (fdCount + 1), fds, sizeof(int) * fdCount) != 0) {
509             INIT_LOGE("Failed to copy fds to service");
510             // Something wrong happened, maybe service->fds is broken, clear it.
511             free(service->fds);
512             service->fds = NULL;
513             service->fdCount = 0;
514             ret = -1;
515         } else {
516             service->fdCount = fdCount;
517         }
518     } else {
519         if (service->fdCount > 0) {
520             // case 1
521             CloseServiceFds(service, true);
522         }
523         service->fds = calloc(fdCount + 1, sizeof(int));
524         if (service->fds == NULL) {
525             INIT_LOGE("Service \' %s \' failed to allocate memory for fds", service->name);
526             ret = -1;
527         } else {
528             if (memcpy_s(service->fds, sizeof(int) * (fdCount + 1), fds, sizeof(int) * fdCount) != 0) {
529                 INIT_LOGE("Failed to copy fds to service");
530                 // Something wrong happened, maybe service->fds is broken, clear it.
531                 free(service->fds);
532                 service->fds = NULL;
533                 service->fdCount = 0;
534                 return -1;
535             } else {
536                 service->fdCount = fdCount;
537             }
538         }
539     }
540     INIT_LOGI("Hold fd for service \' %s \' done", service->name);
541     return ret;
542 }
543 
ServiceStopTimer(Service * service)544 void ServiceStopTimer(Service *service)
545 {
546     INIT_ERROR_CHECK(service != NULL, return, "Stop timer with invalid service");
547     if (IsServiceWithTimerEnabled(service)) {
548         // Stop timer first
549         if (service->timer) {
550             LE_StopTimer(LE_GetDefaultLoop(), service->timer);
551         }
552         service->timer = NULL;
553         DisableServiceTimer(service);
554     }
555 }
556 
ServiceTimerStartProcess(const TimerHandle handler,void * context)557 static void ServiceTimerStartProcess(const TimerHandle handler, void *context)
558 {
559     UNUSED(handler);
560     Service *service = (Service *)context;
561 
562     if (service == NULL) {
563         INIT_LOGE("Service timer process with invalid service");
564         return;
565     }
566 
567     // OK, service is ready to start.
568     // Before start the service, stop service timer.
569     // make sure it will not enter timer handler next time.
570     ServiceStopTimer(service);
571     int ret = ServiceStart(service);
572     if (ret != SERVICE_SUCCESS) {
573         INIT_LOGE("Start service \' %s \' in timer failed");
574     }
575 }
576 
ServiceStartTimer(Service * service,uint64_t timeout)577 void ServiceStartTimer(Service *service, uint64_t timeout)
578 {
579     bool oldTimerClean = false;
580     INIT_ERROR_CHECK(service != NULL, return, "Start timer with invalid service");
581     // If the service already set a timer.
582     // And a new request coming. close it and create a new one.
583     if (IsServiceWithTimerEnabled(service)) {
584         ServiceStopTimer(service);
585         oldTimerClean = true;
586     }
587     LE_STATUS status = LE_CreateTimer(LE_GetDefaultLoop(), &service->timer, ServiceTimerStartProcess,
588         (void *)service);
589     if (status != LE_SUCCESS) {
590         INIT_LOGE("Create service timer for service \' %s \' failed, status = %d", service->name, status);
591         if (oldTimerClean) {
592             INIT_LOGE("previous timer is cleared");
593         }
594         return;
595     }
596     status = LE_StartTimer(LE_GetDefaultLoop(), service->timer, timeout, 1);
597     if (status != LE_SUCCESS) {
598         INIT_LOGE("Start service timer for service \' %s \' failed, status = %d", service->name, status);
599         return;
600     }
601     EnableServiceTimer(service);
602 }
603