Exemple #1
0
/** Append data to the currently open log entry.
 * 
 * This function requires that the log_lock is acquired by the caller.
 */
static void log_append(const uint8_t *data, size_t len)
{
	/* Cap the length so that the entry entirely fits into the buffer */
	if (len > LOG_LENGTH - log_current_len) {
		len = LOG_LENGTH - log_current_len;
	}
	
	if (len == 0)
		return;
	
	size_t log_free = LOG_LENGTH - log_used - log_current_len;
	
	/* Discard older entries to make space, if necessary */
	while (len > log_free) {
		size_t entry_len;
		log_copy_from((uint8_t *) &entry_len, log_start, sizeof(size_t));
		log_start = (log_start + entry_len) % LOG_LENGTH;
		log_used -= entry_len;
		log_free += entry_len;
		next_for_uspace -= entry_len;
	}
	
	size_t pos = (log_current_start + log_current_len) % LOG_LENGTH;
	log_copy_to(data, pos, len);
	log_current_len += len;
}
Exemple #2
0
/** Control of the log from uspace
 *
 */
sysarg_t sys_klog(sysarg_t operation, void *buf, size_t size,
    sysarg_t level)
{
	char *data;
	int rc;
	
	if (size > PAGE_SIZE)
		return (sysarg_t) ELIMIT;
	
	switch (operation) {
		case KLOG_WRITE:
			data = (char *) malloc(size + 1, 0);
			if (!data)
				return (sysarg_t) ENOMEM;
			
			rc = copy_from_uspace(data, buf, size);
			if (rc) {
				free(data);
				return (sysarg_t) rc;
			}
			data[size] = 0;
			
			if (level >= LVL_LIMIT)
				level = LVL_NOTE;
			
			log(LF_USPACE, level, "%s", data);
			
			free(data);
			return EOK;
		case KLOG_READ:
			data = (char *) malloc(size, 0);
			if (!data)
				return (sysarg_t) ENOMEM;
			
			size_t entry_len = 0;
			size_t copied = 0;
			
			rc = EOK;
	
			spinlock_lock(&log_lock);
			
			while (next_for_uspace < log_used) {
				size_t pos = (log_start + next_for_uspace) % LOG_LENGTH;
				log_copy_from((uint8_t *) &entry_len, pos, sizeof(size_t));
				
				if (entry_len > PAGE_SIZE) {
					/* 
					 * Since we limit data transfer
					 * to uspace to a maximum of PAGE_SIZE
					 * bytes, skip any entries larger
					 * than this limit to prevent
					 * userspace being stuck trying to
					 * read them.
					 */
					next_for_uspace += entry_len;
					continue;
				}
				
				if (size < copied + entry_len) {
					if (copied == 0)
						rc = EOVERFLOW;
					break;
				}
				
				log_copy_from((uint8_t *) (data + copied), pos, entry_len);
				copied += entry_len;
				next_for_uspace += entry_len;
			}
			
			spinlock_unlock(&log_lock);
			
			if (rc != EOK) {
				free(data);
				return (sysarg_t) rc;
			}
			
			rc = copy_to_uspace(buf, data, size);
			
			free(data);
			
			if (rc != EOK)
				return (sysarg_t) rc;
			
			return copied;
		default:
			return (sysarg_t) ENOTSUP;
	}
}