/** Write to a stream (unbuffered). * * @param buf Source buffer. * @param size Size of each record. * @param nmemb Number of records to write. * @param stream Pointer to the stream. */ static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream) { size_t left; size_t done; if (size == 0 || nmemb == 0) return 0; left = size * nmemb; done = 0; while ((left > 0) && (!stream->error)) { ssize_t wr; if (stream->klog) wr = klog_write(buf + done, left); else wr = write(stream->fd, buf + done, left); if (wr <= 0) stream->error = true; else { left -= wr; done += wr; } } if (done > 0) stream->need_sync = true; return (done / size); }
/** * @brief Writes a message to the kernel's output device and panics the kernel. * * @param fmt Formatted message to be written onto kernel's output device. */ PUBLIC void kpanic(const char *fmt, ...) { int i; /* Loop index. */ va_list args; /* Variable arguments list. */ char buffer[KBUFFER_SIZE + 1]; /* Temporary buffer. */ kstrncpy(buffer, "PANIC: ", 7); /* Convert to raw string. */ va_start(args, fmt); i = kvsprintf(buffer + 7, fmt, args) + 7; buffer[i++] = '\n'; va_end(args); /* Save on kernel log and write on kout. */ cdev_write(kout, buffer, i); klog_write(buffer, i); /* * Disable interrupts, so we cannot * be bothered. */ disable_interrupts(); while(1); halt(); }
/* Log directly to the specified log */ static void do_log_line(struct log_info *log_info, char *line) { if (log_info->log_target == LOG_KLOG) { klog_write(6, log_info->klog_fmt, line); } else if (log_info->log_target == LOG_ALOG) { ALOG(LOG_INFO, log_info->btag, "%s", line); } }
static void asc_write_exists(struct conn *c) { const char *str = "EXISTS"; size_t len = sizeof("EXISTS") - 1; asc_write_string(c, str, len); klog_write(c->peer, c->req_type, c->req, c->req_len, RSP_EXISTS, len); }
static void asc_write_not_stored(struct conn *c) { const char *str = "NOT_STORED"; size_t len = sizeof("NOT_STORED") - 1; asc_write_string(c, str, len); klog_write(c->peer, c->req_type, c->req, c->req_len, RSP_NOT_STORED, len); }
static void asc_write_deleted(struct conn *c) { const char *str = "DELETED"; size_t len = sizeof("DELETED") - 1; asc_write_string(c, str, len); klog_write(c->peer, c->req_type, c->req, c->req_len, RSP_DELETED, len); }
/* * Build the response. Each hit adds three elements to the outgoing * reponse vector, viz: * "VALUE " * key * " " + flags + " " + data length + "\r\n" + data (with \r\n) */ static rstatus_t asc_respond_get(struct conn *c, unsigned valid_key_iter, struct item *it, bool return_cas) { rstatus_t status; char *cas_suffix = NULL; int cas_suffix_len = 0; int total_len = it->nkey + it->nsuffix + it->nbyte; if (return_cas) { status = asc_create_cas_suffix(c, valid_key_iter, &cas_suffix); if (status != MC_OK) { return status; } cas_suffix_len = snprintf(cas_suffix, CAS_SUFFIX_SIZE, " %"PRIu64, item_cas(it)); } status = conn_add_iov(c, "VALUE ", sizeof("VALUE ") - 1); if (status != MC_OK) { return status; } status = conn_add_iov(c, item_key(it), it->nkey); if (status != MC_OK) { return status; } status = conn_add_iov(c, item_suffix(it), it->nsuffix - CRLF_LEN); if (status != MC_OK) { return status; } if (return_cas) { status = conn_add_iov(c, cas_suffix, cas_suffix_len); if (status != MC_OK) { return status; } total_len += cas_suffix_len; } status = conn_add_iov(c, CRLF, CRLF_LEN); if (status != MC_OK) { return status; } status = conn_add_iov(c, item_data(it), it->nbyte); if (status != MC_OK) { return status; } klog_write(c->peer, c->req_type, item_key(it), it->nkey, 0, total_len); return MC_OK; }
/* Log directly to the specified log */ static void do_log_line(struct log_info *log_info, char *line) { if (log_info->log_target & LOG_KLOG) { klog_write(6, log_info->klog_fmt, line); } if (log_info->log_target & LOG_ALOG) { ALOG(LOG_INFO, log_info->btag, "%s", line); } if (log_info->log_target & LOG_FILE) { fprintf(log_info->fp, "%s\n", line); } }
static void ___cprintf(char* fmt, ...) { #ifdef DEBUG va_list list; va_start(list, fmt); char text[128]; memset(text, 0, 128); vsnprintf(text, 128, fmt, list); va_end(list); //tty_puts_native(tty_find(0), text); //tty_new_line(tty_find(0)); /* Write directly to the log file */ tty_t active = tty_active(); if(active && active->codes_logged) { klog_write(code_log, text, strlen(text)); char nl = '\n'; klog_write(code_log, &nl, 1); } #endif }
static int klog_vprintf_wstr_write(const wchar_t *str, size_t size, void *data) { size_t offset = 0; size_t chars = 0; while (offset < size) { char buf[STR_BOUNDS(1)]; size_t sz = 0; if (chr_encode(str[chars], buf, &sz, STR_BOUNDS(1)) == EOK) klog_write(buf, sz); chars++; offset += sizeof(wchar_t); } return chars; }
/** * @brief Writes on the screen a formated string. * * @param fmt Formated string. */ PUBLIC void kprintf(const char *fmt, ...) { int i; /* Loop index. */ va_list args; /* Variable arguments list. */ char buffer[KBUFFER_SIZE + 1]; /* Temporary buffer. */ const char *buffer_no_code; /* Temporary buffer for log level printing. */ /* Convert to raw string. */ va_start(args, fmt); i = kvsprintf(buffer, fmt, args); buffer[i++] = '\n'; va_end(args); /* Save on kernel log, skip code in case it's not correctly done and write on kout. */ klog_write(0, buffer, i); buffer_no_code = skip_code(buffer, &i); cdev_write(kout, buffer_no_code, i); }
static void asc_process_arithmetic(struct conn *c, struct token *token, int ntoken) { item_delta_result_t res; char temp[INCR_MAX_STORAGE_LEN]; uint64_t delta; char *key; size_t nkey; bool incr; asc_set_noreply_maybe(c, token, ntoken); if (!asc_ntoken_valid(c, ntoken)) { log_hexdump(LOG_NOTICE, c->req, c->req_len, "client error on c %d for " "req of type %d with %d invalid tokens", c->sd, c->req_type, ntoken); asc_write_client_error(c); return; } incr = (c->req_type == REQ_INCR) ? true : false; key = token[TOKEN_KEY].val; nkey = token[TOKEN_KEY].len; if (nkey > KEY_MAX_LEN) { log_debug(LOG_NOTICE, "client error on c %d for req of type %d and %d " "length key", c->sd, c->req_type, nkey); asc_write_client_error(c); return; } if (!mc_strtoull(token[TOKEN_DELTA].val, &delta)) { log_debug(LOG_NOTICE, "client error on c %d for req of type %d with " "invalid delta '%.*s'", c->sd, c->req_type, token[TOKEN_DELTA].len, token[TOKEN_DELTA].val); asc_write_client_error(c); return; } res = item_add_delta(c, key, nkey, incr, delta, temp); switch (res) { case DELTA_OK: asc_write_string(c, temp, strlen(temp)); klog_write(c->peer, c->req_type, c->req, c->req_len, res, strlen(temp)); break; case DELTA_NON_NUMERIC: log_debug(LOG_NOTICE, "client error on c %d for req of type %d with " "non-numeric value", c->sd, c->req_type); asc_write_client_error(c); break; case DELTA_EOM: log_warn("server error on c %d for req of type %d because of oom", c->sd, c->req_type); asc_write_server_error(c); break; case DELTA_NOT_FOUND: if (incr) { stats_thread_incr(incr_miss); } else { stats_thread_incr(decr_miss); } asc_write_not_found(c); break; default: NOT_REACHED(); break; } }
static inline void asc_process_read(struct conn *c, struct token *token, int ntoken) { rstatus_t status; char *key; size_t nkey; unsigned valid_key_iter = 0; struct item *it; struct token *key_token; bool return_cas; if (!asc_ntoken_valid(c, ntoken)) { log_hexdump(LOG_NOTICE, c->req, c->req_len, "client error on c %d for " "req of type %d with %d invalid tokens", c->sd, c->req_type, ntoken); asc_write_client_error(c); return; } return_cas = (c->req_type == REQ_GETS) ? true : false; key_token = &token[TOKEN_KEY]; do { while (key_token->len != 0) { key = key_token->val; nkey = key_token->len; if (nkey > KEY_MAX_LEN) { log_debug(LOG_NOTICE, "client error on c %d for req of type %d " "and %d length key", c->sd, c->req_type, nkey); asc_write_client_error(c); return; } if (return_cas) { stats_thread_incr(gets); } else { stats_thread_incr(get); } it = item_get(key, nkey); if (it != NULL) { /* item found */ if (return_cas) { stats_slab_incr(it->id, gets_hit); } else { stats_slab_incr(it->id, get_hit); } if (valid_key_iter >= c->isize) { struct item **new_list; new_list = mc_realloc(c->ilist, sizeof(struct item *) * c->isize * 2); if (new_list != NULL) { c->isize *= 2; c->ilist = new_list; } else { item_remove(it); break; } } status = asc_respond_get(c, valid_key_iter, it, return_cas); if (status != MC_OK) { log_debug(LOG_NOTICE, "client error on c %d for req of type " "%d with %d tokens", c->sd, c->req_type, ntoken); stats_thread_incr(cmd_error); item_remove(it); break; } log_debug(LOG_VVERB, ">%d sending key %.*s", c->sd, it->nkey, item_key(it)); item_touch(it); *(c->ilist + valid_key_iter) = it; valid_key_iter++; } else { /* item not found */ if (return_cas) { stats_thread_incr(gets_miss); } else { stats_thread_incr(get_miss); } klog_write(c->peer, c->req_type, key, nkey, 1, 0); } key_token++; } /* * If the command string hasn't been fully processed, get the next set * of token. */ if (key_token->val != NULL) { ntoken = asc_tokenize(key_token->val, token, TOKEN_MAX); /* ntoken is unused */ key_token = token; } } while (key_token->val != NULL); c->icurr = c->ilist; c->ileft = valid_key_iter; if (return_cas) { c->scurr = c->slist; c->sleft = valid_key_iter; } log_debug(LOG_VVERB, ">%d END", c->sd); /* * If the loop was terminated because of out-of-memory, it is not * reliable to add END\r\n to the buffer, because it might not end * in \r\n. So we send SERVER_ERROR instead. */ if (key_token->val != NULL || conn_add_iov(c, "END\r\n", 5) != MC_OK || (c->udp && conn_build_udp_headers(c) != MC_OK)) { log_warn("server error on c %d for req of type %d with enomem", c->sd, c->req_type); asc_write_server_error(c); } else { conn_set_state(c, CONN_MWRITE); c->msg_curr = 0; } }
/* * Build the response. Each hit adds three elements to the outgoing * reponse vector, viz: * "VALUE " * key * " " + flags + " " + data length + "\r\n" + data (with \r\n) */ static rstatus_t asc_respond_get(struct conn *c, unsigned valid_key_iter, struct item *it, bool return_cas) { rstatus_t status; char *cas_suffix = NULL; char suffix[SUFFIX_MAX_LEN]; int sz; int total_len = 0; status = conn_add_iov(c, "VALUE ", sizeof("VALUE ") - 1); if (status != MC_OK) { return status; } status = conn_add_iov(c, item_key(it), it->nkey); if (status != MC_OK) { return status; } total_len += it->nkey; sz = snprintf(suffix, SUFFIX_MAX_LEN, " %"PRIu32" %"PRIu32, it->dataflags, it->nbyte); if (sz < 0) { return MC_ERROR; } ASSERT(sz < SUFFIX_MAX_LEN); /* or we have a corrupted item */ status = conn_add_iov(c, suffix, sz); if (status != MC_OK) { return status; } total_len += sz; if (return_cas) { status = asc_create_cas_suffix(c, valid_key_iter, &cas_suffix); if (status != MC_OK) { return status; } sz = snprintf(cas_suffix, CAS_SUFFIX_SIZE, " %"PRIu64, item_cas(it)); if (sz < 0) { return MC_ERROR; } ASSERT(sz < CAS_SUFFIX_SIZE); status = conn_add_iov(c, cas_suffix, sz); if (status != MC_OK) { return status; } total_len += sz; } status = conn_add_iov(c, CRLF, CRLF_LEN); if (status != MC_OK) { return status; } total_len += CRLF_LEN; status = conn_add_iov(c, item_data(it), it->nbyte); if (status != MC_OK) { return status; } total_len += it->nbyte; status = conn_add_iov(c, CRLF, CRLF_LEN); if (status != MC_OK) { return status; } total_len += CRLF_LEN; klog_write(c->peer, c->req_type, item_key(it), it->nkey, 0, total_len); return MC_OK; }
static int klog_vprintf_str_write(const char *str, size_t size, void *data) { size_t wr = klog_write(str, size); return str_nlength(str, wr); }
asmlinkage int vprintk(const char *fmt, va_list args) { int printed_len = 0; int current_log_level = default_message_loglevel; unsigned long flags; int this_cpu; char *p; boot_delay_msec(); printk_delay(); preempt_disable(); /* This stops the holder of console_sem just where we want him */ raw_local_irq_save(flags); this_cpu = smp_processor_id(); /* * Ouch, printk recursed into itself! */ if (unlikely(printk_cpu == this_cpu)) { /* * If a crash is occurring during printk() on this CPU, * then try to get the crash message out but make sure * we can't deadlock. Otherwise just return to avoid the * recursion and return - but flag the recursion so that * it can be printed at the next appropriate moment: */ if (!oops_in_progress) { recursion_bug = 1; goto out_restore_irqs; } zap_locks(); } lockdep_off(); spin_lock(&logbuf_lock); printk_cpu = this_cpu; if (recursion_bug) { recursion_bug = 0; strcpy(printk_buf, recursion_bug_msg); printed_len = strlen(recursion_bug_msg); } /* Emit the output into the temporary buffer */ printed_len += vscnprintf(printk_buf + printed_len, sizeof(printk_buf) - printed_len, fmt, args); #ifdef CONFIG_DEBUG_LL printascii(printk_buf); #endif #ifdef CONFIG_KERNEL_LOG klog_write(printk_buf, printed_len); #endif p = printk_buf; /* Do we have a loglevel in the string? */ if (p[0] == '<') { unsigned char c = p[1]; if (c && p[2] == '>') { switch (c) { case '0' ... '7': /* loglevel */ current_log_level = c - '0'; /* Fallthrough - make sure we're on a new line */ case 'd': /* KERN_DEFAULT */ if (!new_text_line) { emit_log_char('\n'); new_text_line = 1; } /* Fallthrough - skip the loglevel */ case 'c': /* KERN_CONT */ p += 3; break; } } }
/* * Build the response. Each hit adds three elements to the outgoing * reponse vector, viz: * "VALUE " * key * " " + flags + " " + data length + "\r\n" + data (with \r\n) */ static rstatus_t asc_respond_get(struct conn *c, unsigned valid_key_iter, struct item *it, bool return_cas) { rstatus_t status; char *suffix = NULL; int sz; int total_len = 0; uint32_t nbyte = it->nbyte; char *data = item_data(it); status = conn_add_iov(c, VALUE, VALUE_LEN); if (status != MC_OK) { return status; } total_len += VALUE_LEN; status = conn_add_iov(c, item_key(it), it->nkey); if (status != MC_OK) { return status; } total_len += it->nkey; status = asc_create_suffix(c, valid_key_iter, &suffix); if (status != MC_OK) { return status; } if (return_cas) { sz = mc_snprintf(suffix, SUFFIX_MAX_LEN, " %"PRIu32" %"PRIu32" %"PRIu64, it->dataflags, nbyte, item_cas(it)); ASSERT(sz <= SUFFIX_SIZE + CAS_SUFFIX_SIZE); } else { sz = mc_snprintf(suffix, SUFFIX_MAX_LEN, " %"PRIu32" %"PRIu32, it->dataflags, nbyte); ASSERT(sz <= SUFFIX_SIZE); } if (sz < 0) { return MC_ERROR; } status = conn_add_iov(c, suffix, sz); if (status != MC_OK) { return status; } total_len += sz; status = conn_add_iov(c, CRLF, CRLF_LEN); if (status != MC_OK) { return status; } total_len += CRLF_LEN; status = conn_add_iov(c, data, nbyte); if (status != MC_OK) { return status; } total_len += nbyte; status = conn_add_iov(c, CRLF, CRLF_LEN); if (status != MC_OK) { return status; } total_len += CRLF_LEN; klog_write(c->peer, c->req_type, item_key(it), it->nkey, 0, total_len); return MC_OK; }