00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <assert.h>
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <stdlib.h>
00026 #include <l4/sys/types.h>
00027 #include <l4/sys/ipc.h>
00028 #include <l4/sys/kdebug.h>
00029 #include <l4/sys/syscalls.h>
00030 #include <l4/rmgr/librmgr.h>
00031 #include <l4/names/libnames.h>
00032 #include <l4/log/l4log.h>
00033 #include <l4/util/parse_cmd.h>
00034 #include <l4/util/l4_macros.h>
00035
00036 #include "../include/log_comm.h"
00037 #include "stuff.h"
00038 #include "flusher.h"
00039 #include "tcpip.h"
00040 #include "config.h"
00041 #include "muxed.h"
00042 #include "log-server.h"
00043
00044 int verbose=0;
00045 unsigned buffer_size, buffer_head, buffer_tail;
00046 #if CONFIG_USE_TCPIP
00047 unsigned buffer_size = 4096;
00048
00049 #endif
00050
00051
00052 static char message_buffer[LOG_BUFFERSIZE+5];
00053
00054
00055 char LOG_tag[9]="log";
00056
00057 int flush_local=1;
00058 int flush_serial;
00059 int serial_esc;
00060
00061 #if CONFIG_USE_TCPIP
00062 bin_conn_t bin_conns[MAX_BIN_CONNS];
00063 int flush_to_net=0;
00064 int flush_muxed=1;
00065
00066 #endif
00067
00068 int prio = 0x20;
00069
00070 char buffer_array[OUTPUT_BUFFER_SIZE];
00071
00072 #define min(a,b) ((a)<(b)?(a):(b))
00073
00074
00075 static void init_buffer(void){
00076 if(buffer_size && buffer_size < 10) buffer_size = 10;
00077
00078 if(buffer_size > sizeof(buffer_array)){
00079 LOGd(CONFIG_LOG_NOTICE,
00080 "requested buffersize of %d, shrinking to %zd\n",
00081 buffer_size, sizeof(buffer_array));
00082 buffer_size = sizeof(buffer_array);
00083 }
00084 buffer_head = buffer_tail = 0;
00085 buffer_array[buffer_head] = 0;
00086 #if CONFIG_USE_TCPIP
00087 memset(bin_conns, 0, sizeof(bin_conns));
00088 #endif
00089 }
00090
00091
00092
00093 static void print_buffered(const char*data){
00094 int len;
00095 int cur_len;
00096 int tail;
00097 int free;
00098
00099 len = strlen(data);
00100 if(buffer_size){
00101 while(len>0){
00102 tail = buffer_tail;
00103 if(tail>buffer_head) free = tail-buffer_head-1;
00104 else free = buffer_size-buffer_head+tail - 1;
00105
00106 assert(free>=0);
00107 LOGd(CONFIG_LOG_RINGBUFFER,
00108 "head=%d, tail=%d, size=%d, free=%d, len=%d\n",
00109 buffer_head, buffer_tail, buffer_size, free, len);
00110
00111 if(free==0){
00112 flush_buffer();
00113 continue;
00114 }
00115
00116 if(tail>buffer_head){
00117 cur_len = min(free,len);
00118 assert(cur_len>0);
00119 LOGd(CONFIG_LOG_RINGBUFFER,
00120 "filling %d+%d\n", buffer_head, cur_len);
00121 memcpy(buffer_array+buffer_head, data, cur_len);
00122 } else {
00123
00124
00125
00126
00127
00128
00129 cur_len = buffer_size-buffer_head-(tail==0);
00130 cur_len = min(cur_len,len);
00131 assert(cur_len>0);
00132 LOGd(CONFIG_LOG_RINGBUFFER,
00133 "filling %d+%d\n", buffer_head, cur_len);
00134 memcpy(buffer_array+buffer_head, data, cur_len);
00135 }
00136 len-=cur_len;
00137 data+=cur_len;
00138 if(buffer_head+cur_len == buffer_size) buffer_head = 0;
00139 else buffer_head+=cur_len;
00140 assert(buffer_head<buffer_size);
00141 }
00142 } else {
00143 if(flush_local){
00144 outstring(data);
00145 }
00146 #if CONFIG_USE_SERIAL
00147 if(flush_serial) serial_flush(data, strlen(data));
00148 #endif
00149 }
00150 }
00151
00152 static void parse_args(int argc, const char**argv){
00153 parse_cmdline(&argc, &argv,
00154 'v', "verbose", "verbose mode",
00155 PARSE_CMD_SWITCH, 1, &verbose,
00156 #if CONFIG_USE_TCPIP
00157 ' ', "net", "use TCP/IP network connections",
00158 PARSE_CMD_SWITCH, 1, &flush_to_net,
00159 ' ', "nonet", "do not use TCP/IP network connections",
00160 PARSE_CMD_SWITCH, 0, &flush_to_net,
00161 'm', "muxed", "flush in muxed mode to TCP/IP",
00162 PARSE_CMD_SWITCH, 1, &flush_muxed,
00163 'M', "nomuxed", "do not flush in muxed mode",
00164 PARSE_CMD_SWITCH, 0, &flush_muxed,
00165 ' ', "ip", "IP address to use",
00166 PARSE_CMD_STRING, "", &ip_addr,
00167 #endif
00168 'l', "local", "flush to local console",
00169 PARSE_CMD_SWITCH, 1, &flush_local,
00170 'L' ,"nolocal", "do not flush to local console",
00171 PARSE_CMD_SWITCH, 0, &flush_local,
00172 #if CONFIG_USE_SERIAL
00173 's' ,"comport", "flush to specified serial interface",
00174 PARSE_CMD_INT, 0, &flush_serial,
00175 'e', "serial-esc", "enter kdebug on esc on serial",
00176 PARSE_CMD_SWITCH, 1, &serial_esc,
00177 #endif
00178 'b', "buffer", "buffered mode",
00179 PARSE_CMD_INT, 0, &buffer_size,
00180 ' ', "flushprio", "priority of flusher thread",
00181 PARSE_CMD_INT, 0x20, &flusher_prio,
00182 'p', "prio", "priority of main thread",
00183 PARSE_CMD_INT, 0x20, &prio,
00184 0);
00185
00186 }
00187
00188 void
00189 log_outstring_component (CORBA_Object _dice_corba_obj,
00190 int flush_flag,
00191 const char* str,
00192 CORBA_Server_Environment *_dice_corba_env)
00193 {
00194 if (verbose && str && str[0])
00195 {
00196 char buf[10];
00197 sprintf(buf, l4util_idfmt_adjust":", l4util_idstr(*_dice_corba_obj));
00198 print_buffered(buf);
00199 }
00200 print_buffered(str);
00201 if(flush_flag ||
00202 strstr(message_buffer, "***"))
00203 flush_buffer();
00204 }
00205
00206 int
00207 log_channel_open_component (CORBA_Object _dice_corba_obj,
00208 l4_snd_fpage_t page,
00209 int channel,
00210 CORBA_Server_Environment *_dice_corba_env)
00211 {
00212 #if CONFIG_USE_TCPIP
00213 int ret = channel_open(page.fpage, channel);
00214 _dice_corba_env->rcv_fpage = channel_get_next_fpage();
00215 return ret;
00216 #else
00217 return -1;
00218 #endif
00219 }
00220
00221 int
00222 log_channel_write_component (CORBA_Object _dice_corba_obj,
00223 int channel,
00224 unsigned int offset,
00225 unsigned int size,
00226 CORBA_Server_Environment *_dice_corba_env)
00227 {
00228 #if CONFIG_USE_TCPIP
00229 return channel_write(channel, offset, size);
00230 #else
00231 return -1;
00232 #endif
00233 }
00234
00235 int
00236 log_channel_flush_component (CORBA_Object _dice_corba_obj,
00237 int channel,
00238 CORBA_Server_Environment *_dice_corba_env)
00239 {
00240 #if CONFIG_USE_TCPIP
00241 return channel_flush(channel);
00242 #else
00243 return -1;
00244 #endif
00245 }
00246
00247 int
00248 log_channel_close_component (CORBA_Object _dice_corba_obj,
00249 int channel,
00250 CORBA_Server_Environment *_dice_corba_env)
00251 {
00252 #if CONFIG_USE_TCPIP
00253 return channel_close(channel);
00254 #else
00255 return -1;
00256 #endif
00257 }
00258
00259 static void*
00260 msg_alloc(unsigned long size)
00261 {
00262 if (size != LOG_BUFFERSIZE)
00263 return 0;
00264 return message_buffer;
00265 }
00266
00267 int main(int argc, const char**argv){
00268 int err;
00269 CORBA_Server_Environment env = dice_default_server_environment;
00270
00271 parse_args(argc,argv);
00272
00273 init_buffer();
00274
00275 rmgr_init();
00276 err = rmgr_set_prio(l4_myself(), prio);
00277 if(err){
00278 LOG_Error("rmgr_set_prio(%d): %d", prio, err);
00279 return 1;
00280 }
00281
00282 err = flusher_init();
00283 if(err){
00284 LOG_Error("Serious problems initalizing the flusher.\n");
00285 }
00286
00287 if(names_register(LOG_NAMESERVER_NAME)==0){
00288 LOG_Error("Cannot register at nameserver, falling asleep\n");
00289 return 1;
00290 }
00291 if(verbose){
00292 printf("Server started and registered as \"%s\"\n",
00293 LOG_NAMESERVER_NAME);
00294 #if CONFIG_USE_TCPIP
00295 printf("Logging to: %s%s%s\n",
00296 flush_local?"console ":"",
00297 flush_to_net?"network ":"",
00298 flush_serial?"serial ":""
00299 );
00300 #else
00301 printf("Logging to: %s%s\n",
00302 flush_local?"kdebug ":"",
00303 flush_serial?"serial":"");
00304 #endif
00305 printf("Buffersize: %d\n", buffer_size);
00306 }
00307
00308 #if CONFIG_USE_TCPIP
00309 env.rcv_fpage = channel_get_next_fpage();
00310 #else
00311 env.rcv_fpage.fpage = 0;
00312 #endif
00313 env.malloc = msg_alloc;
00314
00315 strcpy(message_buffer+LOG_BUFFERSIZE,"...\n");
00316 log_server_loop (&env);
00317 }