source: trunk/user/init/init.c

Last change on this file was 682, checked in by alain, 6 years ago

Introduce three new applications:

  • windows : to test the FBF windows kernel manager
  • udp_chat : chat application based on UDP sockets.
  • tcp_chat : chat application based on TCP sockets (including packet loss recovery).
File size: 6.9 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////////
2// File : init.c
3// Date : January 2018
4// Author : Alain Greiner
5///////////////////////////////////////////////////////////////////////////////////////
6// This single thread application implement the "init" process for ALMOS-MKH.
7// It uses the fork/exec syscalls to create N KSH child processes
8// (one child process per user TXT terminal).
9// Then it calls the wait() function to block, and recreate any child KSH process
10// that has been deleted, using a new fork/exec.
11///////////////////////////////////////////////////////////////////////////////////////
12
13#include <unistd.h>
14#include <stdlib.h>
15#include <stdio.h>
16#include <pthread.h>
17#include <almosmkh.h>
18#include <hal_macros.h>
19#include <sys/wait.h>
20#include <shared_syscalls.h>
21
22#define DEBUG_PROCESS_INIT 0
23
24////////////////
25int main( void )
26{
27 unsigned int i;
28 int ret_fork; // fork return value
29 int ret_exec; // exec return value
30 int rcv_pid; // pid received from the wait syscall
31 int status; // used by the wait syscall
32 char string[64]; // log messages on kernel TXT0
33 unsigned int cxy; // target cluster identifier
34
35#if DEBUG_PROCESS_INIT
36display_string("[init] process enters");
37#endif
38
39 // get number of TXT channels and number of clusters
40 hard_config_t config;
41
42 get_config( &config );
43
44 unsigned int txt_channels = config.txt_channels;
45 unsigned int x_size = config.x_size;
46 unsigned int y_size = config.y_size;
47 unsigned int n_clusters = x_size * y_size;
48
49 // check number of TXT channels
50 if( txt_channels < 2 )
51 {
52 snprintf( string , 64 ,
53 "\n[init ERROR] number of TXT channels must be larger than 1");
54 display_string( string );
55 exit( EXIT_FAILURE );
56 }
57
58 cxy = 0;
59
60 // create the KSH processes (one per user terminal)
61 for( i = 1 ; i < txt_channels ; i++ )
62 {
63 // compute target cluster
64 cxy = (cxy + 1) % n_clusters;
65
66 // select target cluster
67 if( place_fork( cxy ) )
68 {
69 // INIT display error message
70 snprintf( string , 64 ,
71 "\n[init ERROR] cannot place fork for child[%d] => suicide" , i );
72 display_string( string );
73
74 // INIT suicide
75 exit( EXIT_FAILURE );
76 }
77
78
79 // INIT process fork process CHILD[i]
80 ret_fork = fork();
81
82 if( ret_fork < 0 ) // error in fork
83 {
84 // INIT display error message
85 snprintf( string , 64 ,
86 "\n[init ERROR] cannot fork child[%d] => suicide" , i );
87 display_string( string );
88
89 // INIT suicide
90 exit( EXIT_FAILURE );
91 }
92 else if( ret_fork == 0 ) // we are in CHILD[i] process
93 {
94
95#if DEBUG_PROCESS_INIT
96 snprintf( string , 64 ,
97 "\n[init] CHILD[%d] process forked / call execve", i );
98 display_string( string );
99#endif
100 // CHILD[i] process exec process KSH[i]
101 ret_exec = execve( "/bin/user/ksh.elf" , NULL , NULL );
102
103 if ( ret_exec ) // error in exec
104 {
105 // CHILD[i] display error message
106 snprintf( string , 64 ,
107 "\n[init ERROR] CHILD[%d] cannot exec KSH" , i );
108 display_string( string );
109
110 // CHILD[i] suicide
111 exit( EXIT_FAILURE );
112 }
113 }
114 else // we are in INIT process
115 {
116 // INIT display CHILD[i] process PID
117 snprintf( string , 64 ,
118 "[init] (pid 0x1) create ksh[%d] (pid %x)", i , ret_fork );
119 display_string( string );
120 }
121 }
122
123#if DEBUG_PROCESS_INIT
124{
125 // keep blocked for 2 seconds
126 // to allow all KSH[i] process
127 // to be launched before display
128
129 sleep( 2 );
130
131 unsigned int x; // cluster x coordinate
132 unsigned int y; // cluster y coordinate
133 unsigned int cxy; // cluster identifier
134 unsigned int lid; // core local index
135
136 unsigned int x_size = config.x_size;
137 unsigned int y_size = config.y_size;
138 unsigned int ncores = config.ncores;
139
140 // INIT displays processes and threads in all clusters
141 for( x = 0 ; x < x_size ; x++ )
142 {
143 for( y = 0 ; y < y_size ; y++ )
144 {
145 cxy = HAL_CXY_FROM_XY( x , y );
146 display_cluster_processes( cxy , 0 );
147 for( lid = 0 ; lid < ncores ; lid++ )
148 {
149 display_sched( cxy , lid );
150 }
151 }
152 }
153}
154#endif
155
156 // This loop detects the termination of the KSH[i] processes,
157 // and recreate a new KSH[i] process when required.
158 while( 1 )
159 {
160 // block on child processes termination
161 rcv_pid = wait( &status );
162
163 if( WIFSTOPPED( status ) ) // stopped => unblock it
164 {
165 // display string to report unexpected KSH process block
166 snprintf( string , 64 , "[init] KSH process %x stopped => unblock it" , rcv_pid );
167 display_string( string );
168
169 // TODO : unblock KSH [AG]
170
171 } // end KSH stopped handling
172
173 if( WIFSIGNALED( status ) || WIFEXITED( status ) ) // killed => recreate it
174 {
175 // display string to report KSH process termination
176 snprintf( string , 64 , "[init] KSH process %x terminated => recreate", rcv_pid );
177 display_string( string );
178
179 // INIT process fork a new CHILD process
180 ret_fork = fork();
181
182 if( ret_fork < 0 ) // error in fork
183 {
184 // INIT display error message
185 snprintf( string , 64 , "[init ERROR] cannot fork child => suicide");
186 display_string( string );
187
188 // INIT suicide
189 exit( 0 );
190 }
191 else if( ret_fork == 0 ) // we are in CHILD process
192 {
193 // CHILD process exec process KSH
194 ret_exec = execve( "/bin/user/ksh.elf" , NULL , NULL );
195
196 if ( ret_exec ) // error in exec
197 {
198 // CHILD display error message on TXT0 terminal
199 snprintf( string , 64 , "[init ERROR] CHILD cannot exec KSH" );
200 display_string( string );
201 }
202 }
203 else // we are in INIT process
204 {
205 // INIT display new KSH process PID
206 snprintf( string , 64 , "[init] re-created KSH / pid = %x", ret_fork );
207 display_string( string );
208 }
209 } // end KSH kill handling
210
211 } // end while waiting KSH[i] termination
212
213} // end main()
214
Note: See TracBrowser for help on using the repository browser.