This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / kernel / printk.c
index 3b74688..8bffe04 100644 (file)
@@ -247,7 +247,10 @@ int do_syslog(int type, char __user * buf, int len)
        unsigned long i, j, limit, count;
        int do_clear = 0;
        char c;
-       int error = 0;
+       int error = -EPERM;
+
+       if (!vx_check(0, VX_ADMIN|VX_WATCH))
+               return error;
 
        error = security_syslog(type);
        if (error)
@@ -471,6 +474,27 @@ static void emit_log_char(char c)
                logged_chars++;
 }
 
+/*
+ * Zap console related locks when oopsing. Only zap at most once
+ * every 10 seconds, to leave time for slow consoles to print a
+ * full oops.
+ */
+static void zap_locks(void)
+{
+       static unsigned long oops_timestamp;
+
+       if (time_after_eq(jiffies, oops_timestamp) &&
+                       !time_after(jiffies, oops_timestamp + 30*HZ))
+               return;
+
+       oops_timestamp = jiffies;
+
+       /* If a crash is occurring, make sure we can't deadlock */
+       spin_lock_init(&logbuf_lock);
+       /* And make sure that we print immediately */
+       init_MUTEX(&console_sem);
+}
+
 /*
  * This is printk.  It can be called from any context.  We want it to work.
  * 
@@ -493,12 +517,8 @@ asmlinkage int printk(const char *fmt, ...)
        static char printk_buf[1024];
        static int log_level_unknown = 1;
 
-       if (oops_in_progress) {
-               /* If a crash is occurring, make sure we can't deadlock */
-               spin_lock_init(&logbuf_lock);
-               /* And make sure that we print immediately */
-               init_MUTEX(&console_sem);
-       }
+       if (unlikely(oops_in_progress))
+               zap_locks();
 
        /* This stops the holder of console_sem just where we want him */
        spin_lock_irqsave(&logbuf_lock, flags);