#include <linux/smp.h>
#include <linux/security.h>
#include <linux/bootmem.h>
-#include <linux/vs_base.h>
+#include <linux/syscalls.h>
+#include <linux/vserver/cvirt.h>
#include <asm/uaccess.h>
* It is also used in interesting ways to provide interlocking in
* release_console_sem().
*/
-static spinlock_t logbuf_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(logbuf_lock);
static char __log_buf[__LOG_BUF_LEN];
static char *log_buf = __log_buf;
#define MAX_CMDLINECONSOLES 8
static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
+static int selected_console = -1;
static int preferred_console = -1;
/* Flag: console code may call schedule() */
strcpy(name, "ttyS1");
#endif
for(s = name; *s; s++)
- if (*s >= '0' && *s <= '9')
+ if ((*s >= '0' && *s <= '9') || *s == ',')
break;
idx = simple_strtoul(s, NULL, 10);
*s = 0;
for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
if (strcmp(console_cmdline[i].name, name) == 0 &&
console_cmdline[i].index == idx) {
- preferred_console = i;
+ selected_console = i;
return 0;
}
if (i == MAX_CMDLINECONSOLES)
return -E2BIG;
- preferred_console = i;
+ selected_console = i;
c = &console_cmdline[i];
memcpy(c->name, name, sizeof(c->name));
c->name[sizeof(c->name) - 1] = 0;
unsigned long i, j, limit, count;
int do_clear = 0;
char c;
- int error = -EPERM;
-
- if (!vx_check(0, VX_ADMIN|VX_WATCH))
- return error;
+ int error;
error = security_syslog(type);
if (error)
return error;
- switch (type) {
- case 0: /* Close log */
- break;
- case 1: /* Open log */
- break;
- case 2: /* Read from log */
+ if ((type >= 2) && (type <= 4)) {
error = -EINVAL;
if (!buf || len < 0)
goto out;
error = verify_area(VERIFY_WRITE,buf,len);
if (error)
goto out;
+ }
+ if (!vx_check(0, VX_ADMIN|VX_WATCH))
+ return vx_do_syslog(type, buf, len);
+
+ switch (type) {
+ case 0: /* Close log */
+ break;
+ case 1: /* Open log */
+ break;
+ case 2: /* Read from log */
error = wait_event_interruptible(log_wait, (log_start - log_end));
if (error)
goto out;
error = __put_user(c,buf);
buf++;
i++;
+ cond_resched();
spin_lock_irq(&logbuf_lock);
}
spin_unlock_irq(&logbuf_lock);
do_clear = 1;
/* FALL THRU */
case 3: /* Read last kernel messages */
- error = -EINVAL;
- if (!buf || len < 0)
- goto out;
- error = 0;
- if (!len)
- goto out;
- error = verify_area(VERIFY_WRITE,buf,len);
- if (error)
- goto out;
count = len;
if (count > log_buf_len)
count = log_buf_len;
c = LOG_BUF(j);
spin_unlock_irq(&logbuf_lock);
error = __put_user(c,&buf[count-1-i]);
+ cond_resched();
spin_lock_irq(&logbuf_lock);
}
spin_unlock_irq(&logbuf_lock);
error = -EFAULT;
break;
}
+ cond_resched();
}
}
break;
}
EXPORT_SYMBOL(acquire_console_sem);
+int try_acquire_console_sem(void)
+{
+ if (down_trylock(&console_sem))
+ return -1;
+ console_locked = 1;
+ console_may_schedule = 0;
+ return 0;
+}
+EXPORT_SYMBOL(try_acquire_console_sem);
+
int is_console_locked(void)
{
return console_locked;
_con_start = con_start;
_log_end = log_end;
con_start = log_end; /* Flush */
- spin_unlock_irqrestore(&logbuf_lock, flags);
+ spin_unlock(&logbuf_lock);
call_console_drivers(_con_start, _log_end);
+ local_irq_restore(flags);
}
console_locked = 0;
console_may_schedule = 0;
*
* Must be called within acquire_console_sem().
*/
-void console_conditional_schedule(void)
+void __sched console_conditional_schedule(void)
{
- if (console_may_schedule && need_resched()) {
- set_current_state(TASK_RUNNING);
- schedule();
- }
+ if (console_may_schedule)
+ cond_resched();
}
EXPORT_SYMBOL(console_conditional_schedule);
int i;
unsigned long flags;
+ if (preferred_console < 0)
+ preferred_console = selected_console;
+
/*
* See if we want to use this console driver. If we
* didn't select a console we take the first one
* would prevent fbcon from taking over.
*/
if (console_drivers == NULL)
- preferred_console = -1;
+ preferred_console = selected_console;
release_console_sem();
void tty_write_message(struct tty_struct *tty, char *msg)
{
if (tty && tty->driver->write)
- tty->driver->write(tty, 0, msg, strlen(msg));
+ tty->driver->write(tty, msg, strlen(msg));
return;
}
*/
int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
{
- static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
+ static DEFINE_SPINLOCK(ratelimit_lock);
static unsigned long toks = 10*5*HZ;
static unsigned long last_msg;
static int missed;