xref: /aosp_15_r20/external/fastrpc/src/log_config.c (revision 418b791d679beb2078b579a3b6936cf330c41799)
1*418b791dSBob Badour /*
2*418b791dSBob Badour  * Copyright (c) 2019, The Linux Foundation. All rights reserved.
3*418b791dSBob Badour  *
4*418b791dSBob Badour  * Redistribution and use in source and binary forms, with or without
5*418b791dSBob Badour  * modification, are permitted provided that the following conditions are
6*418b791dSBob Badour  * met:
7*418b791dSBob Badour  *    * Redistributions of source code must retain the above copyright
8*418b791dSBob Badour  *      notice, this list of conditions and the following disclaimer.
9*418b791dSBob Badour  *    * Redistributions in binary form must reproduce the above
10*418b791dSBob Badour  *      copyright notice, this list of conditions and the following
11*418b791dSBob Badour  *      disclaimer in the documentation and/or other materials provided
12*418b791dSBob Badour  *      with the distribution.
13*418b791dSBob Badour  *    * Neither the name of The Linux Foundation nor the names of its
14*418b791dSBob Badour  *      contributors may be used to endorse or promote products derived
15*418b791dSBob Badour  *      from this software without specific prior written permission.
16*418b791dSBob Badour  *
17*418b791dSBob Badour  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18*418b791dSBob Badour  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19*418b791dSBob Badour  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20*418b791dSBob Badour  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21*418b791dSBob Badour  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*418b791dSBob Badour  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*418b791dSBob Badour  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24*418b791dSBob Badour  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25*418b791dSBob Badour  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26*418b791dSBob Badour  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27*418b791dSBob Badour  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*418b791dSBob Badour  */
29*418b791dSBob Badour 
30*418b791dSBob Badour #ifndef VERIFY_PRINT_ERROR
31*418b791dSBob Badour #define VERIFY_PRINT_ERROR
32*418b791dSBob Badour #endif // VERIFY_PRINT_ERROR
33*418b791dSBob Badour #include <pthread.h>
34*418b791dSBob Badour #include <unistd.h>
35*418b791dSBob Badour #include <sys/inotify.h>
36*418b791dSBob Badour #include <sys/eventfd.h>
37*418b791dSBob Badour #include <poll.h>
38*418b791dSBob Badour #include <stdio.h>
39*418b791dSBob Badour #include <string.h>
40*418b791dSBob Badour #include <stdlib.h>
41*418b791dSBob Badour #include <errno.h>
42*418b791dSBob Badour #include <limits.h>
43*418b791dSBob Badour 
44*418b791dSBob Badour #include "apps_std.h"
45*418b791dSBob Badour #include "AEEstd.h"
46*418b791dSBob Badour #include "AEEStdErr.h"
47*418b791dSBob Badour #include "verify.h"
48*418b791dSBob Badour #include "remote_priv.h"
49*418b791dSBob Badour #include "adsp_current_process.h"
50*418b791dSBob Badour #include "adsp_current_process1.h"
51*418b791dSBob Badour #include "adspmsgd_adsp.h"
52*418b791dSBob Badour #include "adspmsgd_adsp1.h"
53*418b791dSBob Badour #include "rpcmem.h"
54*418b791dSBob Badour 
55*418b791dSBob Badour #define EVENT_SIZE          ( sizeof (struct inotify_event) )
56*418b791dSBob Badour #define EVENT_BUF_LEN       ( 1024 * ( EVENT_SIZE + 16 ) )
57*418b791dSBob Badour #ifndef AEE_EUNSUPPORTED
58*418b791dSBob Badour #define AEE_EUNSUPPORTED         20 // API is not supported 	50
59*418b791dSBob Badour #endif
60*418b791dSBob Badour #define DEFAULT_ADSPMSGD_MEMORY_SIZE     8192
61*418b791dSBob Badour #define INVALID_HANDLE      (remote_handle64)(-1)
62*418b791dSBob Badour #define ERRNO (errno == 0 ? -1 : errno)
63*418b791dSBob Badour 
64*418b791dSBob Badour struct log_config_watcher_params {
65*418b791dSBob Badour     int fd;
66*418b791dSBob Badour     int event_fd; // Duplicate fd to quit the poll
67*418b791dSBob Badour     _cstring1_t* paths;
68*418b791dSBob Badour     int* wd;
69*418b791dSBob Badour     uint32 numPaths;
70*418b791dSBob Badour     pthread_attr_t attr;
71*418b791dSBob Badour     pthread_t thread;
72*418b791dSBob Badour     unsigned char stopThread;
73*418b791dSBob Badour     int asidToWatch;
74*418b791dSBob Badour     char* fileToWatch;
75*418b791dSBob Badour     char* asidFileToWatch;
76*418b791dSBob Badour     char* pidFileToWatch;
77*418b791dSBob Badour     boolean adspmsgdEnabled;
78*418b791dSBob Badour };
79*418b791dSBob Badour 
80*418b791dSBob Badour static struct log_config_watcher_params log_config_watcher[NUM_DOMAINS_EXTEND];
81*418b791dSBob Badour extern const char* __progname;
82*418b791dSBob Badour 
83*418b791dSBob Badour const char* get_domain_str(int domain);
84*418b791dSBob Badour remote_handle64 get_adsp_current_process1_handle(int domain);
85*418b791dSBob Badour remote_handle64 get_adspmsgd_adsp1_handle(int domain);
86*418b791dSBob Badour 
parseLogConfig(int dom,unsigned short mask,char * filenames)87*418b791dSBob Badour static int parseLogConfig(int dom, unsigned short mask, char* filenames){
88*418b791dSBob Badour     _cstring1_t* filesToLog = NULL;
89*418b791dSBob Badour     int filesToLogLen = 0;
90*418b791dSBob Badour     char* tempFiles = NULL;
91*418b791dSBob Badour     int nErr = AEE_SUCCESS;
92*418b791dSBob Badour     char *saveptr = NULL;
93*418b791dSBob Badour     char* path = NULL;
94*418b791dSBob Badour     char delim[] = {','};
95*418b791dSBob Badour     int maxPathLen = 0;
96*418b791dSBob Badour     int i = 0;
97*418b791dSBob Badour     remote_handle64 handle;
98*418b791dSBob Badour 
99*418b791dSBob Badour     VERIFYC(filenames != NULL, AEE_EINVALIDFILENAME);
100*418b791dSBob Badour 
101*418b791dSBob Badour     VERIFYC(NULL!= (tempFiles = malloc(sizeof(char) * (std_strlen(filenames) + 1))), AEE_ENOMEMORY);
102*418b791dSBob Badour     std_strlcpy(tempFiles,filenames,std_strlen(filenames) + 1);
103*418b791dSBob Badour 
104*418b791dSBob Badour     // Get the number of folders and max size needed
105*418b791dSBob Badour     path = strtok_r (tempFiles, delim, &saveptr);
106*418b791dSBob Badour     while (path != NULL){
107*418b791dSBob Badour         maxPathLen = STD_MAX(maxPathLen, std_strlen(path)) + 1;
108*418b791dSBob Badour         filesToLogLen++;
109*418b791dSBob Badour         path = strtok_r (NULL, delim, &saveptr);
110*418b791dSBob Badour     }
111*418b791dSBob Badour 
112*418b791dSBob Badour     VERIFY_IPRINTF("%s: #files: %d max_len: %d\n", log_config_watcher[dom].fileToWatch, filesToLogLen, maxPathLen);
113*418b791dSBob Badour 
114*418b791dSBob Badour     // Allocate memory
115*418b791dSBob Badour     VERIFYC(NULL != (filesToLog = malloc(sizeof(_cstring1_t)*filesToLogLen)), AEE_ENOMEMORY);
116*418b791dSBob Badour     for (i = 0; i < filesToLogLen; ++i){
117*418b791dSBob Badour         VERIFYC(NULL != (filesToLog[i].data = malloc(sizeof(char) * maxPathLen)), AEE_ENOMEMORY);
118*418b791dSBob Badour         filesToLog[i].dataLen = maxPathLen;
119*418b791dSBob Badour     }
120*418b791dSBob Badour 
121*418b791dSBob Badour     // Get the number of folders and max size needed
122*418b791dSBob Badour     std_strlcpy(tempFiles,filenames,std_strlen(filenames) + 1);
123*418b791dSBob Badour     i = 0;
124*418b791dSBob Badour     path = strtok_r (tempFiles, delim, &saveptr);
125*418b791dSBob Badour     while (path != NULL){
126*418b791dSBob Badour         VERIFYC((filesToLog != NULL) && (filesToLog[i].data != NULL) &&
127*418b791dSBob Badour                filesToLog[i].dataLen >= (int)strlen(path), AEE_EBADSIZE);
128*418b791dSBob Badour         std_strlcpy(filesToLog[i].data, path, filesToLog[i].dataLen);
129*418b791dSBob Badour         VERIFY_IPRINTF("%s: %s\n", log_config_watcher[dom].fileToWatch, filesToLog[i].data);
130*418b791dSBob Badour         path = strtok_r (NULL, delim, &saveptr);
131*418b791dSBob Badour         i++;
132*418b791dSBob Badour     }
133*418b791dSBob Badour 
134*418b791dSBob Badour     handle = get_adsp_current_process1_handle(dom);
135*418b791dSBob Badour     if (handle != INVALID_HANDLE) {
136*418b791dSBob Badour        VERIFY(AEE_SUCCESS == (nErr = adsp_current_process1_set_logging_params(handle, mask,filesToLog,filesToLogLen)));
137*418b791dSBob Badour     } else {
138*418b791dSBob Badour        VERIFY(AEE_SUCCESS == (nErr = adsp_current_process_set_logging_params(mask,filesToLog,filesToLogLen)));
139*418b791dSBob Badour     }
140*418b791dSBob Badour 
141*418b791dSBob Badour bail:
142*418b791dSBob Badour     if (filesToLog){
143*418b791dSBob Badour         for (i = 0; i < filesToLogLen; ++i){
144*418b791dSBob Badour             if (filesToLog[i].data != NULL){
145*418b791dSBob Badour                 free (filesToLog[i].data);
146*418b791dSBob Badour                 filesToLog[i].data = NULL;
147*418b791dSBob Badour             }
148*418b791dSBob Badour         }
149*418b791dSBob Badour         free(filesToLog);
150*418b791dSBob Badour         filesToLog = NULL;
151*418b791dSBob Badour     }
152*418b791dSBob Badour 
153*418b791dSBob Badour     if(tempFiles){
154*418b791dSBob Badour         free(tempFiles);
155*418b791dSBob Badour         tempFiles = NULL;
156*418b791dSBob Badour     }
157*418b791dSBob Badour     if(nErr != AEE_SUCCESS) {
158*418b791dSBob Badour 	VERIFY_EPRINTF("Error %x: parse log config failed. domain %d, mask %x, filename %s\n", nErr, dom, mask, filenames);
159*418b791dSBob Badour     }
160*418b791dSBob Badour     return nErr;
161*418b791dSBob Badour }
162*418b791dSBob Badour // Read log config given the filename
readLogConfigFromPath(int dom,const char * base,const char * file)163*418b791dSBob Badour static int readLogConfigFromPath(int dom, const char* base, const char* file){
164*418b791dSBob Badour     int nErr = 0;
165*418b791dSBob Badour     apps_std_FILE fp = -1;
166*418b791dSBob Badour     uint64 len;
167*418b791dSBob Badour     byte* buf = NULL;
168*418b791dSBob Badour     int readlen = 0, eof;
169*418b791dSBob Badour     unsigned short mask = 0;
170*418b791dSBob Badour     char* path = NULL;
171*418b791dSBob Badour     char* filenames = NULL;
172*418b791dSBob Badour     boolean fileExists = FALSE;
173*418b791dSBob Badour     int buf_addr = 0;
174*418b791dSBob Badour     remote_handle64 handle;
175*418b791dSBob Badour 
176*418b791dSBob Badour     len = std_snprintf(0, 0, "%s/%s", base, file) + 1;
177*418b791dSBob Badour     VERIFYC(NULL != (path =  malloc(sizeof(char) * len)), AEE_ENOMEMORY);
178*418b791dSBob Badour     std_snprintf(path, (int)len, "%s/%s", base, file);
179*418b791dSBob Badour     VERIFY(AEE_SUCCESS == (nErr = apps_std_fileExists(path,&fileExists)));
180*418b791dSBob Badour     if (fileExists == FALSE){
181*418b791dSBob Badour         VERIFY_IPRINTF("%s: Couldn't find file: %s\n",log_config_watcher[dom].fileToWatch, path);
182*418b791dSBob Badour         nErr = AEE_ENOSUCHFILE;
183*418b791dSBob Badour         goto bail;
184*418b791dSBob Badour     }
185*418b791dSBob Badour     if (log_config_watcher[dom].adspmsgdEnabled == FALSE){
186*418b791dSBob Badour         handle = get_adspmsgd_adsp1_handle(dom);
187*418b791dSBob Badour         if(handle != INVALID_HANDLE) {
188*418b791dSBob Badour            adspmsgd_adsp1_init2(handle);
189*418b791dSBob Badour         } else if(AEE_EUNSUPPORTED == (nErr = adspmsgd_adsp_init2())) {
190*418b791dSBob Badour             nErr = adspmsgd_adsp_init(0, RPCMEM_HEAP_DEFAULT, 0, DEFAULT_ADSPMSGD_MEMORY_SIZE, &buf_addr);
191*418b791dSBob Badour         }
192*418b791dSBob Badour         if (nErr != AEE_SUCCESS){
193*418b791dSBob Badour             VERIFY_EPRINTF("adspmsgd not supported. nErr=%x\n", nErr);
194*418b791dSBob Badour         }else{
195*418b791dSBob Badour             log_config_watcher[dom].adspmsgdEnabled = TRUE;
196*418b791dSBob Badour         }
197*418b791dSBob Badour         VERIFY_EPRINTF("Found %s. adspmsgd enabled \n", log_config_watcher[dom].fileToWatch);
198*418b791dSBob Badour     }
199*418b791dSBob Badour 
200*418b791dSBob Badour     VERIFY(AEE_SUCCESS == (nErr = apps_std_fopen(path, "r", &fp)));
201*418b791dSBob Badour     VERIFY(AEE_SUCCESS == (nErr = apps_std_flen(fp, &len)));
202*418b791dSBob Badour 
203*418b791dSBob Badour     VERIFYC(len < 511, AEE_EBADSIZE);
204*418b791dSBob Badour     VERIFYC(NULL != (buf = calloc(1, sizeof(byte) * (len + 1))), AEE_ENOMEMORY); // extra 1 byte for null character
205*418b791dSBob Badour     VERIFYC(NULL != (filenames = malloc(sizeof(byte) * len)), AEE_ENOMEMORY);
206*418b791dSBob Badour     VERIFY(AEE_SUCCESS == (nErr = apps_std_fread(fp, buf, len, &readlen, &eof)));
207*418b791dSBob Badour     VERIFYC((int)len == readlen, AEE_EFREAD);
208*418b791dSBob Badour 
209*418b791dSBob Badour     VERIFY_IPRINTF("%s: Config file %s contents: %s\n", log_config_watcher[dom].fileToWatch, path, buf);
210*418b791dSBob Badour 
211*418b791dSBob Badour     len = sscanf((const char*)buf, "0x%hx %511s", &mask, filenames);
212*418b791dSBob Badour     switch (len){
213*418b791dSBob Badour         case 1:
214*418b791dSBob Badour             VERIFY_IPRINTF("%s: Setting log mask:0x%x", log_config_watcher[dom].fileToWatch, mask);
215*418b791dSBob Badour             handle = get_adsp_current_process1_handle(dom);
216*418b791dSBob Badour             if (handle != INVALID_HANDLE) {
217*418b791dSBob Badour                VERIFY(AEE_SUCCESS == (nErr = adsp_current_process1_set_logging_params(handle,mask,NULL,0)));
218*418b791dSBob Badour             } else {
219*418b791dSBob Badour                VERIFY(AEE_SUCCESS == (nErr = adsp_current_process_set_logging_params(mask,NULL,0)));
220*418b791dSBob Badour             }
221*418b791dSBob Badour             break;
222*418b791dSBob Badour         case 2:
223*418b791dSBob Badour             VERIFY(AEE_SUCCESS == (nErr = parseLogConfig(dom, mask,filenames)));
224*418b791dSBob Badour             VERIFY_IPRINTF("%s: Setting log mask:0x%x, filename:%s", log_config_watcher[dom].fileToWatch, mask, filenames);
225*418b791dSBob Badour             break;
226*418b791dSBob Badour         default:
227*418b791dSBob Badour             VERIFY_EPRINTF("%s: No valid data found in config file %s", log_config_watcher[dom].fileToWatch, path);
228*418b791dSBob Badour             nErr = AEE_EUNSUPPORTED;
229*418b791dSBob Badour             goto bail;
230*418b791dSBob Badour     }
231*418b791dSBob Badour 
232*418b791dSBob Badour bail:
233*418b791dSBob Badour     if (buf != NULL){
234*418b791dSBob Badour         free(buf);
235*418b791dSBob Badour         buf = NULL;
236*418b791dSBob Badour     }
237*418b791dSBob Badour 
238*418b791dSBob Badour     if (filenames != NULL){
239*418b791dSBob Badour         free(filenames);
240*418b791dSBob Badour         filenames = NULL;
241*418b791dSBob Badour     }
242*418b791dSBob Badour 
243*418b791dSBob Badour     if (fp != -1){
244*418b791dSBob Badour         apps_std_fclose(fp);
245*418b791dSBob Badour     }
246*418b791dSBob Badour 
247*418b791dSBob Badour     if (path != NULL){
248*418b791dSBob Badour         free(path);
249*418b791dSBob Badour         path = NULL;
250*418b791dSBob Badour     }
251*418b791dSBob Badour 
252*418b791dSBob Badour     if(nErr != AEE_SUCCESS) {
253*418b791dSBob Badour 	VERIFY_IPRINTF("Error %x: fopen failed for %s/%s. (%s)\n", nErr, base, file, strerror(ERRNO));
254*418b791dSBob Badour     }
255*418b791dSBob Badour     return nErr;
256*418b791dSBob Badour }
257*418b791dSBob Badour 
258*418b791dSBob Badour 
259*418b791dSBob Badour // Read log config given the watch descriptor
readLogConfigFromEvent(int dom,struct inotify_event * event)260*418b791dSBob Badour static int readLogConfigFromEvent(int dom, struct inotify_event *event){
261*418b791dSBob Badour     int i = 0;
262*418b791dSBob Badour 
263*418b791dSBob Badour     // Ensure we are looking at the right file
264*418b791dSBob Badour     for (i = 0; i < (int)log_config_watcher[dom].numPaths; ++i){
265*418b791dSBob Badour         if (log_config_watcher[dom].wd[i] == event->wd ){
266*418b791dSBob Badour             if(std_strcmp(log_config_watcher[dom].fileToWatch, event->name) == 0){
267*418b791dSBob Badour                 return readLogConfigFromPath(dom, log_config_watcher[dom].paths[i].data, log_config_watcher[dom].fileToWatch);
268*418b791dSBob Badour             }else if (std_strcmp(log_config_watcher[dom].asidFileToWatch, event->name) == 0) {
269*418b791dSBob Badour                 return readLogConfigFromPath(dom, log_config_watcher[dom].paths[i].data, log_config_watcher[dom].asidFileToWatch);
270*418b791dSBob Badour             }else if (std_strcmp(log_config_watcher[dom].pidFileToWatch, event->name) == 0){
271*418b791dSBob Badour                 return readLogConfigFromPath(dom, log_config_watcher[dom].paths[i].data, log_config_watcher[dom].pidFileToWatch);
272*418b791dSBob Badour             }
273*418b791dSBob Badour         }
274*418b791dSBob Badour     }
275*418b791dSBob Badour     VERIFY_IPRINTF("%s: Watch descriptor %d not valid for current process", log_config_watcher[dom].fileToWatch, event->wd);
276*418b791dSBob Badour     return AEE_SUCCESS;
277*418b791dSBob Badour }
278*418b791dSBob Badour 
279*418b791dSBob Badour 
280*418b791dSBob Badour // Read log config given the watch descriptor
resetLogConfigFromEvent(int dom,struct inotify_event * event)281*418b791dSBob Badour static int resetLogConfigFromEvent(int dom, struct inotify_event *event) {
282*418b791dSBob Badour     int i = 0;
283*418b791dSBob Badour     remote_handle64 handle;
284*418b791dSBob Badour 
285*418b791dSBob Badour     // Ensure we are looking at the right file
286*418b791dSBob Badour     for (i = 0; i < (int)log_config_watcher[dom].numPaths; ++i){
287*418b791dSBob Badour         if (log_config_watcher[dom].wd[i] == event->wd ){
288*418b791dSBob Badour             if( (std_strcmp(log_config_watcher[dom].fileToWatch, event->name) == 0)||
289*418b791dSBob Badour                 (std_strcmp(log_config_watcher[dom].asidFileToWatch, event->name) == 0) ||
290*418b791dSBob Badour                 (std_strcmp(log_config_watcher[dom].pidFileToWatch, event->name) == 0) ) {
291*418b791dSBob Badour                 if (log_config_watcher[dom].adspmsgdEnabled == TRUE){
292*418b791dSBob Badour                    handle = get_adspmsgd_adsp1_handle(dom);
293*418b791dSBob Badour                    if(handle != INVALID_HANDLE) {
294*418b791dSBob Badour                       adspmsgd_adsp1_deinit(handle);
295*418b791dSBob Badour                    } else {
296*418b791dSBob Badour                       adspmsgd_adsp_deinit();
297*418b791dSBob Badour                    }
298*418b791dSBob Badour                 }
299*418b791dSBob Badour                 handle = get_adsp_current_process1_handle(dom);
300*418b791dSBob Badour                 if (handle != INVALID_HANDLE) {
301*418b791dSBob Badour                    return adsp_current_process1_set_logging_params(handle,0,NULL,0);
302*418b791dSBob Badour                 } else {
303*418b791dSBob Badour                    return adsp_current_process_set_logging_params(0,NULL,0);
304*418b791dSBob Badour                 }
305*418b791dSBob Badour             }
306*418b791dSBob Badour         }
307*418b791dSBob Badour     }
308*418b791dSBob Badour     VERIFY_IPRINTF("%s: Watch descriptor %d not valid for current process", log_config_watcher[dom].fileToWatch, event->wd);
309*418b791dSBob Badour     return AEE_SUCCESS;
310*418b791dSBob Badour }
311*418b791dSBob Badour 
312*418b791dSBob Badour 
file_watcher_thread(void * arg)313*418b791dSBob Badour static void* file_watcher_thread(void *arg) {
314*418b791dSBob Badour     int dom = (int)(uintptr_t)arg;
315*418b791dSBob Badour     int ret = 0;
316*418b791dSBob Badour     int length = 0;
317*418b791dSBob Badour     int nErr = AEE_SUCCESS;
318*418b791dSBob Badour     int i = 0;
319*418b791dSBob Badour     char buffer[EVENT_BUF_LEN];
320*418b791dSBob Badour     struct pollfd pfd[] = {
321*418b791dSBob Badour         {log_config_watcher[dom].fd,     POLLIN, 0},
322*418b791dSBob Badour         {log_config_watcher[dom].event_fd, POLLIN, 0}
323*418b791dSBob Badour      };
324*418b791dSBob Badour     const char* fileExtension = ".farf";
325*418b791dSBob Badour     int len = 0;
326*418b791dSBob Badour     remote_handle64 handle;
327*418b791dSBob Badour 
328*418b791dSBob Badour     // Check for the presence of the <process_name>.farf file at bootup
329*418b791dSBob Badour     for (i = 0; i < (int)log_config_watcher[dom].numPaths; ++i){
330*418b791dSBob Badour         if (0 == readLogConfigFromPath(dom, log_config_watcher[dom].paths[i].data, log_config_watcher[dom].fileToWatch)){
331*418b791dSBob Badour             VERIFY_IPRINTF("%s: Log config File %s found.\n", log_config_watcher[dom].fileToWatch, log_config_watcher[dom].paths[i].data );
332*418b791dSBob Badour         }
333*418b791dSBob Badour     }
334*418b791dSBob Badour 
335*418b791dSBob Badour     while(log_config_watcher[dom].stopThread == 0){
336*418b791dSBob Badour         // Block forever
337*418b791dSBob Badour         ret = poll(pfd, 2, -1);
338*418b791dSBob Badour         if(ret < 0){
339*418b791dSBob Badour             VERIFY_EPRINTF("%s: Error polling for file change. Runtime FARF will not work for this process. errno=%x !", log_config_watcher[dom].fileToWatch, errno);
340*418b791dSBob Badour             break;
341*418b791dSBob Badour         } else if (pfd[1].revents & POLLIN) { // Check for exit
342*418b791dSBob Badour             VERIFY_IPRINTF("Received exit.\n");
343*418b791dSBob Badour             break;
344*418b791dSBob Badour         } else {
345*418b791dSBob Badour             length = read( log_config_watcher[dom].fd, buffer, EVENT_BUF_LEN );
346*418b791dSBob Badour             i = 0;
347*418b791dSBob Badour             while ( i < length ) {
348*418b791dSBob Badour                 struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
349*418b791dSBob Badour                 if ( event->len ) {
350*418b791dSBob Badour                     // Get the asiD for the current process
351*418b791dSBob Badour                     // Do it once only
352*418b791dSBob Badour                     if (log_config_watcher[dom].asidToWatch == -1){
353*418b791dSBob Badour                         handle = get_adsp_current_process1_handle(dom);
354*418b791dSBob Badour                         if (handle != INVALID_HANDLE) {
355*418b791dSBob Badour                            VERIFY(AEE_SUCCESS == (nErr = adsp_current_process1_getASID(handle,(unsigned int*)&log_config_watcher[dom].asidToWatch )));
356*418b791dSBob Badour                         } else {
357*418b791dSBob Badour                            VERIFY(AEE_SUCCESS == (nErr = adsp_current_process_getASID((unsigned int*)&log_config_watcher[dom].asidToWatch )));
358*418b791dSBob Badour                         }
359*418b791dSBob Badour                         len = strlen(fileExtension) + strlen(__TOSTR__(INT_MAX));
360*418b791dSBob Badour                         VERIFYC(NULL != (log_config_watcher[dom].asidFileToWatch = malloc(sizeof(char) * len)), AEE_ENOMEMORY);
361*418b791dSBob Badour                         snprintf(log_config_watcher[dom].asidFileToWatch, len, "%d%s", log_config_watcher[dom].asidToWatch, fileExtension);
362*418b791dSBob Badour                         VERIFY_IPRINTF("%s: Watching ASID file %s\n", log_config_watcher[dom].fileToWatch, log_config_watcher[dom].asidFileToWatch);
363*418b791dSBob Badour                     }
364*418b791dSBob Badour 
365*418b791dSBob Badour                     VERIFY_IPRINTF("%s: %s %d.\n", log_config_watcher[dom].fileToWatch, event->name, event->mask );
366*418b791dSBob Badour                     if ( (event->mask & IN_CREATE) || (event->mask & IN_MODIFY)) {
367*418b791dSBob Badour                         VERIFY_IPRINTF("%s: File %s created.\n", log_config_watcher[dom].fileToWatch, event->name );
368*418b791dSBob Badour                         if (0 != readLogConfigFromEvent(dom, event)){
369*418b791dSBob Badour                             VERIFY_EPRINTF("%s: Error reading config file %s", log_config_watcher[dom].fileToWatch, log_config_watcher[dom].paths[i].data);
370*418b791dSBob Badour                         }
371*418b791dSBob Badour                     }
372*418b791dSBob Badour                     else if ( event->mask & IN_DELETE ) {
373*418b791dSBob Badour                         VERIFY_IPRINTF("%s: File %s deleted.\n", log_config_watcher[dom].fileToWatch, event->name );
374*418b791dSBob Badour                         if (0 != resetLogConfigFromEvent(dom, event)){
375*418b791dSBob Badour                             VERIFY_EPRINTF("%s: Error resetting FARF runtime log config" ,log_config_watcher[dom].fileToWatch);
376*418b791dSBob Badour                         }
377*418b791dSBob Badour                     }
378*418b791dSBob Badour                 }
379*418b791dSBob Badour 
380*418b791dSBob Badour                 i += EVENT_SIZE + event->len;
381*418b791dSBob Badour             }
382*418b791dSBob Badour         }
383*418b791dSBob Badour     }
384*418b791dSBob Badour bail:
385*418b791dSBob Badour     if (nErr != AEE_SUCCESS){
386*418b791dSBob Badour         VERIFY_EPRINTF("Error %x: file watcher thread exited. Runtime FARF will not work for this process. filename %s\n", nErr, log_config_watcher[dom].fileToWatch);
387*418b791dSBob Badour     }
388*418b791dSBob Badour     return NULL;
389*418b791dSBob Badour }
390*418b791dSBob Badour 
deinitFileWatcher(int dom)391*418b791dSBob Badour void deinitFileWatcher(int dom) {
392*418b791dSBob Badour     int i = 0;
393*418b791dSBob Badour     uint64 stop = 10;
394*418b791dSBob Badour     remote_handle64 handle;
395*418b791dSBob Badour 
396*418b791dSBob Badour     log_config_watcher[dom].stopThread = 1;
397*418b791dSBob Badour     if (0 < log_config_watcher[dom].event_fd) {
398*418b791dSBob Badour        if (write(log_config_watcher[dom].event_fd, &stop, sizeof(uint64)) != sizeof(uint64)) {
399*418b791dSBob Badour          VERIFY_EPRINTF("Error: write failed: Cannot set exit flag to watcher thread.\n");
400*418b791dSBob Badour 	}
401*418b791dSBob Badour     }
402*418b791dSBob Badour     if (log_config_watcher[dom].thread) {
403*418b791dSBob Badour         pthread_join(log_config_watcher[dom].thread, NULL);
404*418b791dSBob Badour 	log_config_watcher[dom].thread = 0;
405*418b791dSBob Badour     }
406*418b791dSBob Badour     if (log_config_watcher[dom].fileToWatch){
407*418b791dSBob Badour         free (log_config_watcher[dom].fileToWatch);
408*418b791dSBob Badour 	log_config_watcher[dom].fileToWatch = 0;
409*418b791dSBob Badour     }
410*418b791dSBob Badour     if (log_config_watcher[dom].asidFileToWatch){
411*418b791dSBob Badour         free (log_config_watcher[dom].asidFileToWatch);
412*418b791dSBob Badour 	log_config_watcher[dom].asidFileToWatch = 0;
413*418b791dSBob Badour     }
414*418b791dSBob Badour     if (log_config_watcher[dom].pidFileToWatch){
415*418b791dSBob Badour         free (log_config_watcher[dom].pidFileToWatch);
416*418b791dSBob Badour 	log_config_watcher[dom].pidFileToWatch = 0;
417*418b791dSBob Badour     }
418*418b791dSBob Badour     if (log_config_watcher[dom].wd){
419*418b791dSBob Badour         for (i = 0; i < (int)log_config_watcher[dom].numPaths; ++i){
420*418b791dSBob Badour             if (log_config_watcher[dom].wd[i] != 0){
421*418b791dSBob Badour                 inotify_rm_watch( log_config_watcher[dom].fd, log_config_watcher[dom].wd[i] );
422*418b791dSBob Badour             }
423*418b791dSBob Badour         }
424*418b791dSBob Badour         free(log_config_watcher[dom].wd);
425*418b791dSBob Badour         log_config_watcher[dom].wd = NULL;
426*418b791dSBob Badour     }
427*418b791dSBob Badour     if (log_config_watcher[dom].paths){
428*418b791dSBob Badour         for (i = 0; i < (int)log_config_watcher[dom].numPaths; ++i){
429*418b791dSBob Badour             if (log_config_watcher[dom].paths[i].data){
430*418b791dSBob Badour                 free(log_config_watcher[dom].paths[i].data);
431*418b791dSBob Badour                 log_config_watcher[dom].paths[i].data = NULL;
432*418b791dSBob Badour             }
433*418b791dSBob Badour         }
434*418b791dSBob Badour         free(log_config_watcher[dom].paths);
435*418b791dSBob Badour         log_config_watcher[dom].paths = NULL;
436*418b791dSBob Badour     }
437*418b791dSBob Badour     if(log_config_watcher[dom].fd != 0){
438*418b791dSBob Badour         close(log_config_watcher[dom].fd);
439*418b791dSBob Badour         log_config_watcher[dom].fd = 0;
440*418b791dSBob Badour     }
441*418b791dSBob Badour     if (log_config_watcher[dom].adspmsgdEnabled == TRUE){
442*418b791dSBob Badour         handle = get_adspmsgd_adsp1_handle(dom);
443*418b791dSBob Badour         if (handle != INVALID_HANDLE) {
444*418b791dSBob Badour            adspmsgd_adsp1_deinit(handle);
445*418b791dSBob Badour         } else {
446*418b791dSBob Badour            adspmsgd_adsp_deinit();
447*418b791dSBob Badour         }
448*418b791dSBob Badour 	log_config_watcher[dom].adspmsgdEnabled = FALSE;
449*418b791dSBob Badour     }
450*418b791dSBob Badour 
451*418b791dSBob Badour     if(log_config_watcher[dom].event_fd != 0){
452*418b791dSBob Badour 	close(log_config_watcher[dom].event_fd);
453*418b791dSBob Badour 	log_config_watcher[dom].event_fd = 0;
454*418b791dSBob Badour     }
455*418b791dSBob Badour 
456*418b791dSBob Badour     log_config_watcher[dom].numPaths = 0;
457*418b791dSBob Badour }
458*418b791dSBob Badour 
initFileWatcher(int dom)459*418b791dSBob Badour int initFileWatcher(int dom) {
460*418b791dSBob Badour     int nErr = AEE_SUCCESS;
461*418b791dSBob Badour     const char* fileExtension = ".farf";
462*418b791dSBob Badour     uint32 len = 0;
463*418b791dSBob Badour     uint16 maxPathLen = 0;
464*418b791dSBob Badour     int i = 0;
465*418b791dSBob Badour     char* name = NULL;
466*418b791dSBob Badour 
467*418b791dSBob Badour     memset(&log_config_watcher[dom], 0, sizeof(struct log_config_watcher_params));
468*418b791dSBob Badour     log_config_watcher[dom].asidToWatch = 0;
469*418b791dSBob Badour 
470*418b791dSBob Badour     VERIFYC(NULL != (name = std_basename(__progname)), AEE_EINVALIDPROCNAME);
471*418b791dSBob Badour 
472*418b791dSBob Badour     len = strlen(name) + strlen(fileExtension) + 1;
473*418b791dSBob Badour     VERIFYC(NULL != (log_config_watcher[dom].fileToWatch = malloc(sizeof(char) * len)), AEE_ENOMEMORY);
474*418b791dSBob Badour     snprintf(log_config_watcher[dom].fileToWatch, len, "%s%s", name, fileExtension);
475*418b791dSBob Badour 
476*418b791dSBob Badour     len = strlen(fileExtension) + strlen(__TOSTR__(INT_MAX));
477*418b791dSBob Badour     VERIFYC(NULL != (log_config_watcher[dom].pidFileToWatch = malloc(sizeof(char) * len)), AEE_ENOMEMORY);
478*418b791dSBob Badour     snprintf(log_config_watcher[dom].pidFileToWatch, len, "%d%s", getpid(), fileExtension);
479*418b791dSBob Badour 
480*418b791dSBob Badour     VERIFY_IPRINTF("%s: Watching PID file: %s\n", log_config_watcher[dom].fileToWatch, log_config_watcher[dom].pidFileToWatch);
481*418b791dSBob Badour 
482*418b791dSBob Badour     log_config_watcher[dom].fd = inotify_init();
483*418b791dSBob Badour     if (log_config_watcher[dom].fd < 0){
484*418b791dSBob Badour         nErr = AEE_EINVALIDFD;
485*418b791dSBob Badour         VERIFY_EPRINTF("Error %x: inotify_init failed. errno = %s\n", nErr, strerror(errno));
486*418b791dSBob Badour         goto bail;
487*418b791dSBob Badour     }
488*418b791dSBob Badour 
489*418b791dSBob Badour     // Duplicate the fd, so we can use it to quit polling
490*418b791dSBob Badour     log_config_watcher[dom].event_fd = eventfd(0, 0);
491*418b791dSBob Badour     if (log_config_watcher[dom].event_fd < 0){
492*418b791dSBob Badour         nErr = AEE_EINVALIDFD;
493*418b791dSBob Badour         VERIFY_EPRINTF("Error %x: eventfd in dup failed. errno %s\n", nErr, strerror(errno));
494*418b791dSBob Badour         goto bail;
495*418b791dSBob Badour     }
496*418b791dSBob Badour     VERIFY_IPRINTF("fd = %d dupfd=%d\n", log_config_watcher[dom].fd, log_config_watcher[dom].event_fd);
497*418b791dSBob Badour 
498*418b791dSBob Badour     // Get the required size
499*418b791dSBob Badour     apps_std_get_search_paths_with_env("ADSP_LIBRARY_PATH", ";", NULL, 0,
500*418b791dSBob Badour         &log_config_watcher[dom].numPaths, &maxPathLen);
501*418b791dSBob Badour 
502*418b791dSBob Badour     maxPathLen += + 1;
503*418b791dSBob Badour 
504*418b791dSBob Badour     // Allocate memory
505*418b791dSBob Badour     VERIFYC(NULL != (log_config_watcher[dom].paths
506*418b791dSBob Badour            = malloc(sizeof(_cstring1_t) * log_config_watcher[dom].numPaths)), AEE_ENOMEMORY);
507*418b791dSBob Badour     VERIFYC(NULL != (log_config_watcher[dom].wd
508*418b791dSBob Badour            = malloc(sizeof(int) * log_config_watcher[dom].numPaths)), AEE_ENOMEMORY);
509*418b791dSBob Badour 
510*418b791dSBob Badour     for (i = 0; i < (int)log_config_watcher[dom].numPaths; ++i){
511*418b791dSBob Badour         VERIFYC( NULL != (log_config_watcher[dom].paths[i].data
512*418b791dSBob Badour                = malloc(sizeof(char) * maxPathLen)), AEE_ENOMEMORY);
513*418b791dSBob Badour         log_config_watcher[dom].paths[i].dataLen = maxPathLen;
514*418b791dSBob Badour     }
515*418b791dSBob Badour 
516*418b791dSBob Badour     // Get the paths
517*418b791dSBob Badour     VERIFY(AEE_SUCCESS == (nErr = apps_std_get_search_paths_with_env("ADSP_LIBRARY_PATH", ";",
518*418b791dSBob Badour            log_config_watcher[dom].paths, log_config_watcher[dom].numPaths, &len, &maxPathLen)));
519*418b791dSBob Badour 
520*418b791dSBob Badour     maxPathLen += 1;
521*418b791dSBob Badour 
522*418b791dSBob Badour     VERIFY_IPRINTF("%s: Watching folders:\n", log_config_watcher[dom].fileToWatch);
523*418b791dSBob Badour     for (i = 0; i < (int)log_config_watcher[dom].numPaths; ++i){
524*418b791dSBob Badour         // Watch for creation, deletion and modification of files in path
525*418b791dSBob Badour 	VERIFY_IPRINTF("log file watcher: %s: %s\n",log_config_watcher[dom].fileToWatch, log_config_watcher[dom].paths[i].data);
526*418b791dSBob Badour 	if((log_config_watcher[dom].wd[i] = inotify_add_watch (log_config_watcher[dom].fd,
527*418b791dSBob Badour 				log_config_watcher[dom].paths[i].data,  IN_CREATE | IN_DELETE)) < 0) {
528*418b791dSBob Badour 		VERIFY_EPRINTF("Unable to add watcher for folder %s : errno is %s\n", log_config_watcher[dom].paths[i].data, strerror(ERRNO));
529*418b791dSBob Badour 	}
530*418b791dSBob Badour     }
531*418b791dSBob Badour 
532*418b791dSBob Badour     // Create a thread to watch for file changes
533*418b791dSBob Badour     log_config_watcher[dom].asidToWatch = -1;
534*418b791dSBob Badour     log_config_watcher[dom].stopThread = 0;
535*418b791dSBob Badour     pthread_create(&log_config_watcher[dom].thread, NULL, file_watcher_thread, (void*)(uintptr_t)dom);
536*418b791dSBob Badour bail:
537*418b791dSBob Badour     if (nErr!=AEE_SUCCESS){
538*418b791dSBob Badour         VERIFY_EPRINTF("Error %x: Failed to register with inotify file %s. Runtime FARF will not work for the process %s!", nErr, log_config_watcher[dom].fileToWatch, name);
539*418b791dSBob Badour         deinitFileWatcher(dom);
540*418b791dSBob Badour     }
541*418b791dSBob Badour 
542*418b791dSBob Badour     return nErr;
543*418b791dSBob Badour }
544