Exemple #1
0
/** 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);
}
Exemple #2
0
/**
 * @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);
    }
}
Exemple #4
0
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);
}
Exemple #5
0
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);
}
Exemple #6
0
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);
}
Exemple #7
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;
    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;
}
Exemple #8
0
/* 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);
    }
}
Exemple #9
0
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
}
Exemple #10
0
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;
}
Exemple #11
0
/**
 * @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);
}
Exemple #12
0
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;
    }
}
Exemple #13
0
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;
    }
}
Exemple #14
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;
}
Exemple #15
0
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);
}
Exemple #16
0
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;
			}
		}
	}
Exemple #17
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 *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;
}