static void autolog_open(SERVER_REC *server, const char *server_tag, const char *target) { LOG_REC *log; char *fname, *dir, *fixed_target, *params; log = logs_find_item(LOG_ITEM_TARGET, target, server_tag, NULL); if (log != NULL && !log->failed) { log_start_logging(log); return; } /* '/' -> '_' - don't even accidentally try to log to #../../../file if you happen to join to such channel.. similar for some characters that are metacharacters and/or illegal in Windows filenames. '%' -> '%%' - so strftime() won't mess with them */ fixed_target = escape_target(target); if (CHAT_PROTOCOL(server)->case_insensitive) g_strdown(fixed_target); /* $0 = target, $1 = server tag */ params = g_strconcat(fixed_target, " ", server_tag, NULL); g_free(fixed_target); fname = parse_special_string(autolog_path, server, NULL, params, NULL, 0); g_free(params); if (log_find(fname) == NULL) { log = log_create_rec(fname, autolog_level); if (!settings_get_bool("autolog_colors")) log->colorizer = log_colorizer_strip; log_item_add(log, LOG_ITEM_TARGET, target, server_tag); dir = g_path_get_dirname(log->real_fname); mkpath(dir, log_dir_create_mode); g_free(dir); log->temp = TRUE; log_update(log); log_start_logging(log); } g_free(fname); }
/* ARGSUSED */ static int log_close(queue_t *q, int flag, cred_t *cr) { log_t *lp = (log_t *)q->q_ptr; qprocsoff(q); lp->log_inuse = 0; log_update(lp, NULL, 0, NULL); freemsg(lp->log_data); lp->log_data = NULL; if (lp->log_major == LOG_CONSMIN) log_free(lp); q->q_ptr = NULL; WR(q)->q_ptr = NULL; return (0); }
/* Create log file entry to window, but don't start logging */ static void cmd_window_logfile(const char *data) { LOG_REC *log; char window[MAX_INT_STRLEN]; ltoa(window, active_win->refnum); log = log_find_item(window); if (log != NULL) { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_WINDOWLOG_FILE_LOGGING); return; } log = log_create_rec(data, MSGLEVEL_ALL, window); if (log == NULL) printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_WINDOWLOG_FILE, data); else log_update(log); }
/* SYNTAX: WINDOW LOGFILE <file> */ static void cmd_window_logfile(const char *data) { LOG_REC *log; char window[MAX_INT_STRLEN]; ltoa(window, active_win->refnum); log = logs_find_item(LOG_ITEM_WINDOW_REFNUM, window, NULL, NULL); if (log != NULL) { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_WINDOWLOG_FILE_LOGGING); return; } log = log_create_rec(data, MSGLEVEL_ALL); log->colorizer = log_colorizer_strip; log_item_add(log, LOG_ITEM_WINDOW_REFNUM, window, NULL); log_update(log); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_WINDOWLOG_FILE, data); }
/* SYNTAX: LOG OPEN [-noopen] [-autoopen] [-window] [-<server tag>] [-targets <targets>] [-colors] <fname> [<levels>] */ static void cmd_log_open(const char *data) { SERVER_REC *server; GHashTable *optlist; char *targetarg, *fname, *levels, *servertag; void *free_arg; char window[MAX_INT_STRLEN]; LOG_REC *log; int level; if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_OPTIONS | PARAM_FLAG_STRIP_TRAILING_WS, "log open", &optlist, &fname, &levels)) return; if (*fname == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); level = level2bits(levels, NULL); log = log_create_rec(fname, level != 0 ? level : MSGLEVEL_ALL); /* -<server tag> */ server = cmd_options_get_server("log open", optlist, NULL); servertag = server == NULL ? NULL : server->tag; if (g_hash_table_lookup(optlist, "window")) { /* log by window ref# */ targetarg = g_hash_table_lookup(optlist, "targets"); if (targetarg == NULL || !is_numeric(targetarg, '\0')) { ltoa(window, active_win->refnum); targetarg = window; } log_item_add(log, LOG_ITEM_WINDOW_REFNUM, targetarg, servertag); } else { targetarg = g_hash_table_lookup(optlist, "targets"); if (targetarg != NULL && *targetarg != '\0') log_add_targets(log, targetarg, servertag); else if (servertag != NULL) log_add_targets(log, "*", servertag); } if (g_hash_table_lookup(optlist, "autoopen")) log->autoopen = TRUE; if (g_hash_table_lookup(optlist, "colors") == NULL) log->colorizer = log_colorizer_strip; log_update(log); if (log->handle == -1 && g_hash_table_lookup(optlist, "noopen") == NULL) { /* start logging */ if (log_start_logging(log)) { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_LOG_OPENED, fname); } else { log_close(log); } } cmd_params_free(free_arg); }
static int log_wput(queue_t *q, mblk_t *mp) { log_t *lp = (log_t *)q->q_ptr; struct iocblk *iocp; mblk_t *mp2; cred_t *cr = DB_CRED(mp); zoneid_t zoneid; /* * Default to global zone if dblk doesn't have a valid cred. * Calls to syslog() go through putmsg(), which does set up * the cred. */ zoneid = (cr != NULL) ? crgetzoneid(cr) : GLOBAL_ZONEID; switch (DB_TYPE(mp)) { case M_FLUSH: if (*mp->b_rptr & FLUSHW) { flushq(q, FLUSHALL); *mp->b_rptr &= ~FLUSHW; } if (*mp->b_rptr & FLUSHR) { flushq(RD(q), FLUSHALL); qreply(q, mp); return (0); } break; case M_IOCTL: iocp = (struct iocblk *)mp->b_rptr; if (lp->log_major != LOG_LOGMIN) { /* write-only device */ miocnak(q, mp, 0, EINVAL); return (0); } if (iocp->ioc_count == TRANSPARENT) { miocnak(q, mp, 0, EINVAL); return (0); } if (lp->log_flags) { miocnak(q, mp, 0, EBUSY); return (0); } freemsg(lp->log_data); lp->log_data = mp->b_cont; mp->b_cont = NULL; switch (iocp->ioc_cmd) { case I_CONSLOG: log_update(lp, RD(q), SL_CONSOLE, log_console); break; case I_TRCLOG: if (lp->log_data == NULL) { miocnak(q, mp, 0, EINVAL); return (0); } log_update(lp, RD(q), SL_TRACE, log_trace); break; case I_ERRLOG: log_update(lp, RD(q), SL_ERROR, log_error); break; default: miocnak(q, mp, 0, EINVAL); return (0); } miocack(q, mp, 0, 0); return (0); case M_PROTO: if (MBLKL(mp) == sizeof (log_ctl_t) && mp->b_cont != NULL) { log_ctl_t *lc = (log_ctl_t *)mp->b_rptr; /* This code is used by savecore to log dump msgs */ if (mp->b_band != 0 && secpolicy_sys_config(CRED(), B_FALSE) == 0) { (void) putq(log_consq, mp); return (0); } if ((lc->pri & LOG_FACMASK) == LOG_KERN) lc->pri |= LOG_USER; mp2 = log_makemsg(LOG_MID, LOG_CONSMIN, lc->level, lc->flags, lc->pri, mp->b_cont->b_rptr, MBLKL(mp->b_cont) + 1, 0); if (mp2 != NULL) log_sendmsg(mp2, zoneid); } break; case M_DATA: mp2 = log_makemsg(LOG_MID, LOG_CONSMIN, 0, SL_CONSOLE, LOG_USER | LOG_INFO, mp->b_rptr, MBLKL(mp) + 1, 0); if (mp2 != NULL) log_sendmsg(mp2, zoneid); break; } freemsg(mp); return (0); }
void log_init(void) { int log_maxzones; /* * Create a backlog queue to consume console messages during periods * when there is no console reader (e.g. before syslogd(1M) starts). */ log_backlogq = log_consq = log_makeq(0, LOG_HIWAT, NULL); /* * Create a queue to hold free message of size <= LOG_MSGSIZE. * Calls from high-level interrupt handlers will do a getq_noenab() * from this queue, so its q_lock must be a maximum SPL spin lock. */ log_freeq = log_makeq(LOG_MINFREE, LOG_MAXFREE, (void *)ipltospl(SPL8)); /* * Create a queue for messages from high-level interrupt context. * These messages are drained via softcall, or explicitly by panic(). */ log_intrq = log_makeq(0, LOG_HIWAT, (void *)ipltospl(SPL8)); /* * Create a queue to hold the most recent 8K of console messages. * Useful for debugging. Required by the "$<msgbuf" adb macro. */ log_recentq = log_makeq(0, LOG_RECENTSIZE, NULL); /* * Create an id space for clone devices opened via /dev/log. * Need to limit the number of zones to avoid exceeding the * available minor number space. */ log_maxzones = (L_MAXMIN32 - LOG_LOGMIN) / LOG_NUMCLONES - 1; if (log_maxzones < maxzones) maxzones = log_maxzones; log_minorspace = id_space_create("logminor_space", LOG_LOGMIN + 1, L_MAXMIN32); /* * Put ourselves on the ZSD list. Note that zones have not been * initialized yet, but our constructor will be called on the global * zone when they are. */ zone_key_create(&log_zone_key, log_zoneinit, NULL, log_zonefree); /* * Initialize backlog structure. */ log_backlog.log_zoneid = GLOBAL_ZONEID; log_backlog.log_minor = LOG_BACKLOG; /* Allocate kmem cache for conslog's log structures */ log_cons_cache = kmem_cache_create("log_cons_cache", sizeof (struct log), 0, log_cons_constructor, log_cons_destructor, NULL, NULL, NULL, 0); /* * Let the logging begin. */ log_update(&log_backlog, log_backlogq, SL_CONSOLE, log_console); /* * Now that logging is enabled, emit the OS banner. */ printf("\rSunOS Release %s Version %s %u-bit\n", utsname.release, utsname.version, NBBY * (uint_t)sizeof (void *)); printf("Copyright (c) 1983, 2010, Oracle and/or its affiliates. " "All rights reserved.\n"); printf("Copyright 2015 Nexenta Systems, Inc. All rights reserved.\n"); #ifdef DEBUG printf("DEBUG enabled\n"); #endif }
int main(int argc, char **argv) { //***************************************************************************** FILE *pfcfg; syncsig_t *psync; sem_t wrk_sem; sem_t *pwrk_sem = &wrk_sem; struct timespec wait_wrk_sem; size_t i, wrk_amount = CLIENT_MAX, client_max = CLIENT_MAX; pthread_t *pworker; name_attach_t* pnat; frame_t frame; iov_t *piov, *pheader; cash_t *pcash; pheader = malloc(sizeof(iov_t)); SETIOV(pheader, &frame, sizeof(frame_t)); char buf[BUFFER_SIZE], cmd[BUFFER_SIZE], param[BUFFER_SIZE]; int rcvid, slave_chid; char srv_name[BUFFER_SIZE] = SRV_NAME; // Slave support slave_t slave; slave.amount = 0; uint32_t *proute; //***************************************************************************** // Configs //log_start(FILE_NAME_LOG, FILE_NAME_ERR); printf("%s\n", MSG_VER_START); wait_wrk_sem.tv_nsec = WRK_SEM_TIMEOUT; wait_wrk_sem.tv_sec = 0; if(argc == 2) { pfcfg = fopen(argv[1], "r"); } else { pfcfg = fopen(FILE_NAME_CFG, "r"); } if(NULL != pfcfg) { while(0 == feof(pfcfg)) { fscanf(pfcfg, "%s %s", cmd, param); if(0 == strcmp(cmd, CFG_PAR_WRKAM)) { wrk_amount = atoi(param); } else if(0 == strcmp(cmd, CFG_PAR_WRKSEMTIME)) { wait_wrk_sem.tv_nsec = atol(param); } else if(0 == strcmp(cmd, CFG_PAR_MASTER)) { slave.amount = atoi(param); } else if(0 == strcmp(cmd, CFG_PAR_SLAVE)) { strcpy(srv_name, SLAVE_NAME); strcat(srv_name, param); } else if(0 == strcmp(cmd, CFG_PAR_CLIENTMAX)) { client_max = atoi(param); } } fclose(pfcfg); } else { perror(MSG_ERR_CFGFILE); } printf("%s\n", MSG_VER_CFG); signal(SIGINT, fsigint); // Net pnat = name_attach(NULL, srv_name, NAME_FLAG_ATTACH_GLOBAL); __ERROR_EXIT(pnat, NULL, "name_attach"); chid = pnat->chid; // Cash pcash = malloc(sizeof(cash_t)*client_max); //memset(pcash, NULL, sizeof(cash_t)*client_max); /*for(size_t i=0; i<client_max; ++i) { pcash[i].status = EMPTY; }*/ proute = malloc(sizeof(uint32_t)*client_max); // Slaves if(slave.amount > 0) { slave.pslave = malloc(sizeof(slave_info_t)*slave.amount); for(int i = 0; i< slave.amount; ++i) { slave.pslave[i].name = malloc(sizeof(char)*BUFFER_SIZE); strcpy(slave.pslave[i].name, SLAVE_NAME); itoa(i, buf, 10); strcat(slave.pslave[i].name, buf); slave.pslave[i].status = DOWN; slave.pslave[i].clientmax = CLIENT_MAX; slave.pslave[i].clientnow = 0; sem_init(&slave.pslave[i].sem, 0, 1); } connectslaves(&slave); slave_chid = ChannelCreate(0); __ERROR_EXIT(slave_chid, -1, "ChannelCreate"); } // Workers __ERROR_EXIT(sem_init(pwrk_sem, 0, 0), -1, "pwrk_sem: sem_init"); psync = malloc(sizeof(syncsig_t)*wrk_amount); pworker = malloc(sizeof(pthread_t)*wrk_amount); wrk_info_t wrk_info; wrk_info.psem = pwrk_sem; wrk_info.chid = pnat->chid; wrk_info.pcash = pcash; wrk_info.pslave = &slave; wrk_info.client_amount = client_max; wrk_info.wrk_amount = wrk_amount; wrk_info.proute = proute; wrk_info.psync = psync; if(slave.amount > 0) { for(size_t i = 0; i<wrk_amount; ++i) { wrk_info.id = i; pthread_create(&pworker[i], NULL, router, &wrk_info); } } else { for(size_t i = 0; i<wrk_amount; ++i) { wrk_info.id = i; pthread_create(&pworker[i], NULL, worker, &wrk_info); } } /* * __ERROR_CHECK(TimerTimeout(CLOCK_REALTIME , _NTO_TIMEOUT_RECEIVE , NULL, &wait_wrk_sem.tv_nsec, NULL), -1, "TimerTimeout"); */ printf("%s\n", MSG_VER_WORK); //***************************************************************************** while(working) { log_update(); sleep(1); } //***************************************************************************** for(size_t i = 0; i<wrk_amount; ++i) { pthread_kill(pworker[i], SIGKILL); } for(size_t i = 0; i<wrk_amount; ++i) { pthread_join(pworker[i], NULL); } if(slave.amount > 0) { for(size_t i = 0; i<slave.amount; ++i) { free(slave.pslave[i].name); } free(slave.pslave); } name_detach(pnat, NULL); free(pworker); free(psync); free(proute); log_update(); //log_stop(); return EXIT_SUCCESS; }