stlog.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. /*
  2. * linux/fs/proc/stlog.c
  3. *
  4. */
  5. #include <linux/types.h>
  6. #include <linux/errno.h>
  7. #include <linux/time.h>
  8. #include <linux/kernel.h>
  9. #include <linux/security.h>
  10. #include <linux/syscalls.h>
  11. #include <linux/proc_fs.h>
  12. #include <linux/module.h>
  13. #include <linux/moduleparam.h>
  14. #include <linux/interrupt.h>
  15. #include <asm/uaccess.h>
  16. #include <linux/stlog.h>
  17. extern wait_queue_head_t ringbuf_wait;
  18. /*
  19. * Compatibility Issue :
  20. * dumpstate process of Android M tries to open stlog node with O_NONBLOCK.
  21. * But on Android L, it tries to open stlog node without O_NONBLOCK.
  22. * In order to resolve this issue, stlog_open() always works as NONBLOCK mode.
  23. * If you want runtime debugging, please use stlog_open_pipe().
  24. */
  25. static int stlog_open(struct inode * inode, struct file * file)
  26. {
  27. //Open as non-blocking mode for printing once.
  28. file->f_flags |= O_NONBLOCK;
  29. return do_stlog(STLOG_ACTION_OPEN, NULL, 0, STLOG_FROM_PROC);
  30. }
  31. static int stlog_open_pipe(struct inode * inode, struct file * file)
  32. {
  33. //Open as blocking mode for runtime debugging
  34. file->f_flags &= ~(O_NONBLOCK);
  35. return do_stlog(STLOG_ACTION_OPEN, NULL, 0, STLOG_FROM_PROC);
  36. }
  37. static int stlog_release(struct inode * inode, struct file * file)
  38. {
  39. (void) do_stlog(STLOG_ACTION_CLOSE, NULL, 0, STLOG_FROM_PROC);
  40. return 0;
  41. }
  42. static ssize_t stlog_read(struct file *file, char __user *buf,
  43. size_t count, loff_t *ppos)
  44. {
  45. //Blocking mode for runtime debugging
  46. if (!(file->f_flags & O_NONBLOCK))
  47. return do_stlog(STLOG_ACTION_READ, buf, count, STLOG_FROM_PROC);
  48. //Non-blocking mode, print once, consume all the buffers
  49. return do_stlog(STLOG_ACTION_READ_ALL, buf, count, STLOG_FROM_PROC);
  50. }
  51. static ssize_t stlog_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
  52. {
  53. return do_stlog_write(STLOG_ACTION_WRITE, buf, count, STLOG_FROM_READER);
  54. }
  55. loff_t stlog_llseek(struct file *file, loff_t offset, int whence)
  56. {
  57. return (loff_t)do_stlog(STLOG_ACTION_SIZE_BUFFER, 0, 0, STLOG_FROM_READER);
  58. }
  59. static const struct file_operations stlog_operations = {
  60. .read = stlog_read,
  61. .write = stlog_write,
  62. .open = stlog_open,
  63. .release = stlog_release,
  64. .llseek = stlog_llseek,
  65. };
  66. static const struct file_operations stlog_pipe_operations = {
  67. .read = stlog_read,
  68. .open = stlog_open_pipe,
  69. .release = stlog_release,
  70. .llseek = stlog_llseek,
  71. };
  72. static const char DEF_STLOG_VER_STR[] = "1.0.2\n";
  73. static ssize_t stlog_ver_read(struct file *file, char __user *buf,
  74. size_t count, loff_t *ppos)
  75. {
  76. ssize_t ret = 0;
  77. loff_t off = *ppos;
  78. ssize_t len = strlen(DEF_STLOG_VER_STR);
  79. if (off >= len)
  80. return 0;
  81. len -= off;
  82. if (count < len)
  83. return -ENOMEM;
  84. ret = copy_to_user(buf, &DEF_STLOG_VER_STR[off], len);
  85. if (ret < 0)
  86. return ret;
  87. len -= ret;
  88. *ppos += len;
  89. return len;
  90. }
  91. static const struct file_operations stlog_ver_operations = {
  92. .read = stlog_ver_read,
  93. };
  94. static int __init stlog_init(void)
  95. {
  96. proc_create("stlog", S_IRUGO, NULL, &stlog_operations);
  97. proc_create("stlog_pipe", S_IRUGO, NULL, &stlog_pipe_operations);
  98. proc_create("stlog_version", S_IRUGO, NULL, &stlog_ver_operations);
  99. return 0;
  100. }
  101. module_init(stlog_init);
  102. //#define CONFIG_STLOG_CPU_ID
  103. #define CONFIG_STLOG_PID
  104. #define CONFIG_STLOG_TIME
  105. #ifdef CONFIG_STLOG
  106. #define CONFIG_RINGBUF_SHIFT 15 /*32KB*/
  107. #else
  108. #define CONFIG_RINGBUF_SHIFT 10 /*1KB*/
  109. #endif
  110. //#define DEBUG_STLOG
  111. #if defined(CONFIG_STLOG_CPU_ID)
  112. static bool stlog_cpu_id = 1;
  113. #else
  114. static bool stlog_cpu_id;
  115. #endif
  116. module_param_named(cpu, stlog_cpu_id, bool, S_IRUGO | S_IWUSR);
  117. #if defined(CONFIG_STLOG_PID)
  118. static bool stlog_pid = 1;
  119. #else
  120. static bool stlog_pid;
  121. #endif
  122. module_param_named(pid, stlog_pid, bool, S_IRUGO | S_IWUSR);
  123. enum ringbuf_flags {
  124. RINGBUF_NOCONS = 1,
  125. RINGBUF_NEWLINE = 2,
  126. RINGBUF_PREFIX = 4,
  127. RINGBUF_CONT = 8,
  128. };
  129. struct ringbuf {
  130. u64 ts_nsec;
  131. u16 len;
  132. u16 text_len;
  133. #ifdef CONFIG_STLOG_CPU_ID
  134. u8 cpu_id;
  135. #endif
  136. #ifdef CONFIG_STLOG_PID
  137. char comm[TASK_COMM_LEN];
  138. pid_t pid;
  139. #endif
  140. u8 flags:5;
  141. u8 level:3;
  142. };
  143. /*
  144. * The ringbuf_lock protects smsg buffer, indices, counters.
  145. */
  146. static DEFINE_RAW_SPINLOCK(ringbuf_lock);
  147. DECLARE_WAIT_QUEUE_HEAD(ringbuf_wait);
  148. /* the next stlog record to read by /proc/stlog */
  149. static u64 stlog_seq;
  150. static u32 stlog_idx;
  151. static enum ringbuf_flags ringbuf_prev;
  152. static u64 ringbuf_first_seq;
  153. static u32 ringbuf_first_idx;
  154. static u64 ringbuf_next_seq;
  155. static u32 ringbuf_next_idx;
  156. static u64 stlog_clear_seq;
  157. static u32 stlog_clear_idx;
  158. #define S_PREFIX_MAX 32
  159. #define RINGBUF_LINE_MAX 1024 - S_PREFIX_MAX
  160. /* record buffer */
  161. #define RINGBUF_ALIGN __alignof__(struct ringbuf)
  162. #define __RINGBUF_LEN (1 << CONFIG_RINGBUF_SHIFT)
  163. static char __ringbuf_buf[__RINGBUF_LEN] __aligned(RINGBUF_ALIGN);
  164. static char *ringbuf_buf = __ringbuf_buf;
  165. static u32 ringbuf_buf_len = __RINGBUF_LEN;
  166. /* cpu currently holding logbuf_lock */
  167. static volatile unsigned int ringbuf_cpu = UINT_MAX;
  168. /* human readable text of the record */
  169. static char *ringbuf_text(const struct ringbuf *msg)
  170. {
  171. return (char *)msg + sizeof(struct ringbuf);
  172. }
  173. static struct ringbuf *ringbuf_from_idx(u32 idx)
  174. {
  175. struct ringbuf *msg = (struct ringbuf *)(ringbuf_buf + idx);
  176. if (!msg->len)
  177. return (struct ringbuf *)ringbuf_buf;
  178. return msg;
  179. }
  180. static u32 ringbuf_next(u32 idx)
  181. {
  182. struct ringbuf *msg = (struct ringbuf *)(ringbuf_buf + idx);
  183. if (!msg->len) {
  184. msg = (struct ringbuf *)ringbuf_buf;
  185. return msg->len;
  186. }
  187. return idx + msg->len;
  188. }
  189. static void ringbuf_store(enum ringbuf_flags flags, const char *text, u16 text_len,
  190. u8 cpu_id, struct task_struct *owner)
  191. {
  192. struct ringbuf *msg;
  193. u32 size, pad_len;
  194. #ifdef DEBUG_STLOG
  195. printk("[STLOG] %s stlog_seq %llu stlog_idx %lu ringbuf_first_seq %llu ringbuf_first_idx %lu ringbuf_next_seq %llu ringbuf_next_idx %lu \n",
  196. __func__,stlog_seq,stlog_idx,ringbuf_first_seq,ringbuf_first_idx,ringbuf_next_seq,ringbuf_next_idx);
  197. #endif
  198. /* number of '\0' padding bytes to next message */
  199. size = sizeof(struct ringbuf) + text_len;
  200. pad_len = (-size) & (RINGBUF_ALIGN - 1);
  201. size += pad_len;
  202. while (ringbuf_first_seq < ringbuf_next_seq) {
  203. u32 free;
  204. if (ringbuf_next_idx > ringbuf_first_idx)
  205. free = max(ringbuf_buf_len - ringbuf_next_idx, ringbuf_first_idx);
  206. else
  207. free = ringbuf_first_idx - ringbuf_next_idx;
  208. if (free > size + sizeof(struct ringbuf))
  209. break;
  210. /* drop old messages until we have enough space */
  211. ringbuf_first_idx = ringbuf_next(ringbuf_first_idx);
  212. ringbuf_first_seq++;
  213. }
  214. if (ringbuf_next_idx + size + sizeof(struct ringbuf) >= ringbuf_buf_len) {
  215. memset(ringbuf_buf + ringbuf_next_idx, 0, sizeof(struct ringbuf));
  216. ringbuf_next_idx = 0;
  217. }
  218. /* fill message */
  219. msg = (struct ringbuf *)(ringbuf_buf + ringbuf_next_idx);
  220. memcpy(ringbuf_text(msg), text, text_len);
  221. msg->text_len = text_len;
  222. msg->flags = flags & 0x1f;
  223. #ifdef CONFIG_STLOG_CPU_ID
  224. msg->cpu_id = cpu_id;
  225. #endif
  226. #ifdef CONFIG_STLOG_PID
  227. msg->pid = owner->pid;
  228. memcpy(msg->comm, owner->comm, TASK_COMM_LEN);
  229. #endif
  230. msg->ts_nsec = local_clock();
  231. msg->len = sizeof(struct ringbuf) + text_len + pad_len;
  232. /* insert message */
  233. ringbuf_next_idx += msg->len;
  234. ringbuf_next_seq++;
  235. wake_up_interruptible(&ringbuf_wait);
  236. }
  237. #if defined(CONFIG_STLOG_TIME)
  238. static bool stlog_time = 1;
  239. #else
  240. static bool stlog_time;
  241. #endif
  242. module_param_named(time, stlog_time, bool, S_IRUGO | S_IWUSR);
  243. static size_t stlog_print_time(u64 ts, char *buf)
  244. {
  245. unsigned long rem_nsec;
  246. if (!stlog_time)
  247. return 0;
  248. rem_nsec = do_div(ts, 1000000000);
  249. if (!buf)
  250. return snprintf(NULL, 0, "[%5lu.000000] ", (unsigned long)ts);
  251. return sprintf(buf, "[%5lu.%06lu] ",
  252. (unsigned long)ts, rem_nsec / 1000);
  253. }
  254. #ifdef CONFIG_STLOG_PID
  255. static size_t stlog_print_pid(const struct ringbuf *msg, char *buf)
  256. {
  257. if (!stlog_pid)
  258. return 0;
  259. if (!buf)
  260. return snprintf(NULL, 0, "[%15s, %d] ", msg->comm, msg->pid);
  261. return sprintf(buf, "[%15s, %d] ", msg->comm, msg->pid);
  262. }
  263. #else
  264. static size_t stlog_print_pid(const struct ringbuf *msg, char *buf)
  265. {
  266. return 0;
  267. }
  268. #endif
  269. #ifdef CONFIG_STLOG_CPU_ID
  270. static size_t stlog_print_cpuid(const struct ringbuf *msg, char *buf)
  271. {
  272. if (!stlog_cpu_id)
  273. return 0;
  274. if (!buf)
  275. return snprintf(NULL, 0, "C%d ", msg->cpu_id);
  276. return sprintf(buf, "C%d ", msg->cpu_id);
  277. }
  278. #else
  279. static size_t stlog_print_cpuid(const struct ringbuf *msg, char *buf)
  280. {
  281. return 0;
  282. }
  283. #endif
  284. static size_t stlog_print_prefix(const struct ringbuf *msg, bool ringbuf, char *buf)
  285. {
  286. size_t len = 0;
  287. len += stlog_print_time(msg->ts_nsec, buf ? buf + len : NULL);
  288. len += stlog_print_cpuid(msg, buf ? buf + len : NULL);
  289. len += stlog_print_pid(msg, buf ? buf + len : NULL);
  290. return len;
  291. }
  292. static size_t stlog_print_text(const struct ringbuf *msg, enum ringbuf_flags prev,
  293. bool ringbuf, char *buf, size_t size)
  294. {
  295. const char *text = ringbuf_text(msg);
  296. size_t text_size = msg->text_len;
  297. bool prefix = true;
  298. bool newline = true;
  299. size_t len = 0;
  300. do {
  301. const char *next = memchr(text, '\n', text_size);
  302. size_t text_len;
  303. if (next) {
  304. text_len = next - text;
  305. next++;
  306. text_size -= next - text;
  307. } else {
  308. text_len = text_size;
  309. }
  310. if (buf) {
  311. if (stlog_print_prefix(msg, ringbuf, NULL) + text_len + 1 >= size - len)
  312. break;
  313. if (prefix)
  314. len += stlog_print_prefix(msg, ringbuf, buf + len);
  315. memcpy(buf + len, text, text_len);
  316. len += text_len;
  317. if (next || newline)
  318. buf[len++] = '\n';
  319. } else {
  320. /* buffer size only calculation */
  321. if (prefix)
  322. len += stlog_print_prefix(msg, ringbuf, NULL);
  323. len += text_len;
  324. if (next || newline)
  325. len++;
  326. }
  327. prefix = true;
  328. text = next;
  329. } while (text);
  330. return len;
  331. }
  332. static int stlog_print(char __user *buf, int size)
  333. {
  334. char *text;
  335. struct ringbuf *msg;
  336. int len = 0;
  337. #ifdef DEBUG_STLOG
  338. printk("[STLOG] %s stlog_seq %llu stlog_idx %lu ringbuf_first_seq %llu ringbuf_first_idx %lu ringbuf_next_seq %llu ringbuf_next_idx %lu \n",
  339. __func__,stlog_seq,stlog_idx,ringbuf_first_seq,ringbuf_first_idx,ringbuf_next_seq,ringbuf_next_idx);
  340. #endif
  341. text = kmalloc(RINGBUF_LINE_MAX + S_PREFIX_MAX, GFP_KERNEL);
  342. if (!text)
  343. return -ENOMEM;
  344. while (size > 0) {
  345. size_t n;
  346. raw_spin_lock_irq(&ringbuf_lock);
  347. if (stlog_seq < ringbuf_first_seq) {
  348. /* messages are gone, move to first one */
  349. stlog_seq = ringbuf_first_seq;
  350. stlog_idx = ringbuf_first_idx;
  351. ringbuf_prev = 0;
  352. }
  353. if (stlog_seq == ringbuf_next_seq) {
  354. raw_spin_unlock_irq(&ringbuf_lock);
  355. break;
  356. }
  357. msg = ringbuf_from_idx(stlog_idx);
  358. n = stlog_print_text(msg, ringbuf_prev, false, text, RINGBUF_LINE_MAX + S_PREFIX_MAX);
  359. if (n <= size) {
  360. /* message fits into buffer, move forward */
  361. stlog_idx = ringbuf_next(stlog_idx);
  362. stlog_seq++;
  363. ringbuf_prev = msg->flags;
  364. } else if (!len){
  365. n = size;
  366. } else
  367. n = 0;
  368. raw_spin_unlock_irq(&ringbuf_lock);
  369. if (!n)
  370. break;
  371. if (copy_to_user(buf, text, n)) {
  372. if (!len)
  373. len = -EFAULT;
  374. break;
  375. }
  376. len += n;
  377. size -= n;
  378. buf += n;
  379. }
  380. kfree(text);
  381. return len;
  382. }
  383. static int stlog_print_all(char __user *buf, int size, bool clear)
  384. {
  385. char *text;
  386. int len = 0;
  387. text = kmalloc(RINGBUF_LINE_MAX + S_PREFIX_MAX, GFP_KERNEL);
  388. if (!text)
  389. return -ENOMEM;
  390. raw_spin_lock_irq(&ringbuf_lock);
  391. if (buf) {
  392. u64 next_seq;
  393. u64 seq;
  394. u32 idx;
  395. enum ringbuf_flags prev;
  396. if (stlog_clear_seq < ringbuf_first_seq) {
  397. /* messages are gone, move to first available one */
  398. stlog_clear_seq = ringbuf_first_seq;
  399. stlog_clear_idx = ringbuf_first_idx;
  400. }
  401. seq = stlog_clear_seq;
  402. idx = stlog_clear_idx;
  403. prev = 0;
  404. while (seq < ringbuf_next_seq) {
  405. struct ringbuf *msg = ringbuf_from_idx(idx);
  406. len += stlog_print_text(msg, prev, false, NULL, 0);
  407. prev = msg->flags;
  408. idx = ringbuf_next(idx);
  409. seq++;
  410. }
  411. /* move first record forward until length fits into the buffer */
  412. seq = stlog_clear_seq;
  413. idx = stlog_clear_idx;
  414. prev = 0;
  415. while (len > size && seq < ringbuf_next_seq) {
  416. struct ringbuf *msg = ringbuf_from_idx(idx);
  417. len -= stlog_print_text(msg, prev, false, NULL, 0);
  418. prev = msg->flags;
  419. idx = ringbuf_next(idx);
  420. seq++;
  421. }
  422. /* last message fitting into this dump */
  423. next_seq = ringbuf_next_seq;
  424. len = 0;
  425. prev = 0;
  426. while (len >= 0 && seq < next_seq) {
  427. struct ringbuf *msg = ringbuf_from_idx(idx);
  428. int textlen;
  429. textlen = stlog_print_text(msg, prev, false, text,
  430. RINGBUF_LINE_MAX + S_PREFIX_MAX);
  431. if (textlen < 0) {
  432. len = textlen;
  433. break;
  434. }
  435. idx = ringbuf_next(idx);
  436. seq++;
  437. prev = msg->flags;
  438. raw_spin_unlock_irq(&ringbuf_lock);
  439. if (copy_to_user(buf + len, text, textlen))
  440. len = -EFAULT;
  441. else{
  442. #ifdef DEBUG_STLOG
  443. printk("[STLOG] %s seq %llu text %s \n",__func__,seq,text);
  444. #endif
  445. len += textlen;
  446. }
  447. raw_spin_lock_irq(&ringbuf_lock);
  448. if (seq < ringbuf_first_seq) {
  449. /* messages are gone, move to next one */
  450. seq = ringbuf_first_seq;
  451. idx = ringbuf_first_idx;
  452. prev = 0;
  453. }
  454. }
  455. }
  456. if (clear) {
  457. stlog_clear_seq = ringbuf_next_seq;
  458. stlog_clear_idx = ringbuf_next_idx;
  459. }
  460. raw_spin_unlock_irq(&ringbuf_lock);
  461. kfree(text);
  462. return len;
  463. }
  464. int do_stlog(int type, char __user *buf, int len, bool from_file)
  465. {
  466. int error=0;
  467. switch (type) {
  468. case STLOG_ACTION_CLOSE: /* Close log */
  469. break;
  470. case STLOG_ACTION_OPEN: /* Open log */
  471. #ifdef DEBUG_STLOG
  472. printk("[STLOG] %s OPEN stlog_seq %llu stlog_idx %lu ringbuf_first_seq %llu ringbuf_first_idx %lu ringbuf_next_seq %llu ringbuf_next_idx %lu \n",
  473. __func__,stlog_seq,stlog_idx,ringbuf_first_seq,ringbuf_first_idx,ringbuf_next_seq,ringbuf_next_idx);
  474. #endif
  475. break;
  476. case STLOG_ACTION_READ: /* cat -f /proc/stlog */
  477. #ifdef DEBUG_STLOG
  478. printk("[STLOG] %s READ stlog_seq %llu stlog_idx %lu ringbuf_first_seq %llu ringbuf_first_idx %lu ringbuf_next_seq %llu ringbuf_next_idx %lu \n",
  479. __func__,stlog_seq,stlog_idx,ringbuf_first_seq,ringbuf_first_idx,ringbuf_next_seq,ringbuf_next_idx);
  480. #endif
  481. error = -EINVAL;
  482. if (!buf || len < 0)
  483. goto out;
  484. if (!len)
  485. goto out;
  486. if (!access_ok(VERIFY_WRITE, buf, len)) {
  487. error = -EFAULT;
  488. goto out;
  489. }
  490. error = wait_event_interruptible(ringbuf_wait,
  491. stlog_seq != ringbuf_next_seq);
  492. if (error)
  493. goto out;
  494. error = stlog_print(buf, len);
  495. break;
  496. case STLOG_ACTION_READ_ALL: /* cat /proc/stlog */ /* dumpstate */
  497. #ifdef DEBUG_STLOG
  498. printk("[STLOG] %s READ_ALL stlog_seq %llu stlog_idx %lu ringbuf_first_seq %llu ringbuf_first_idx %lu ringbuf_next_seq %llu ringbuf_next_idx %lu \n",
  499. __func__,stlog_seq,stlog_idx,ringbuf_first_seq,ringbuf_first_idx,ringbuf_next_seq,ringbuf_next_idx);
  500. #endif
  501. error = -EINVAL;
  502. if (!buf || len < 0)
  503. goto out;
  504. error = 0;
  505. if (!len)
  506. goto out;
  507. if (!access_ok(VERIFY_WRITE, buf, len)) {
  508. error = -EFAULT;
  509. goto out;
  510. }
  511. if(stlog_clear_seq==ringbuf_next_seq){
  512. stlog_clear_seq=ringbuf_first_seq;
  513. stlog_clear_idx=ringbuf_first_idx;
  514. error=0;
  515. goto out;
  516. }
  517. error = stlog_print_all(buf, len, true);
  518. break;
  519. /* Size of the log buffer */
  520. case STLOG_ACTION_SIZE_BUFFER:
  521. #ifdef DEBUG_STLOG
  522. printk("[STLOG] %s SIZE_BUFFER %lu\n",__func__,ringbuf_buf_len);
  523. #endif
  524. error = ringbuf_buf_len;
  525. break;
  526. default:
  527. error = -EINVAL;
  528. break;
  529. }
  530. out:
  531. return error;
  532. }
  533. int do_stlog_write(int type, const char __user *buf, int len, bool from_file)
  534. {
  535. int error=0;
  536. char *kern_buf=0;
  537. char *line=0;
  538. if (!buf || len < 0)
  539. goto out;
  540. if (!len)
  541. goto out;
  542. if (len > RINGBUF_LINE_MAX)
  543. return -EINVAL;
  544. kern_buf = kmalloc(len+1, GFP_KERNEL);
  545. if (kern_buf == NULL)
  546. return -ENOMEM;
  547. line = kern_buf;
  548. if (copy_from_user(line, buf, len)) {
  549. error = -EFAULT;
  550. goto out;
  551. }
  552. line[len] = '\0';
  553. error = stlog("%s", line);
  554. if ((line[len-1] == '\n') && (error == (len-1)))
  555. error++;
  556. out:
  557. kfree(kern_buf);
  558. return error;
  559. }
  560. asmlinkage int vstlog(const char *fmt, va_list args)
  561. {
  562. static char textbuf[RINGBUF_LINE_MAX];
  563. char *text = textbuf;
  564. size_t text_len;
  565. enum ringbuf_flags lflags = 0;
  566. unsigned long flags;
  567. int this_cpu;
  568. int printed_len = 0;
  569. bool stored = false;
  570. local_irq_save(flags);
  571. this_cpu = smp_processor_id();
  572. raw_spin_lock(&ringbuf_lock);
  573. ringbuf_cpu = this_cpu;
  574. text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
  575. /* mark and strip a trailing newline */
  576. if (text_len && text[text_len-1] == '\n') {
  577. text_len--;
  578. lflags |= RINGBUF_NEWLINE;
  579. }
  580. if (!stored)
  581. ringbuf_store(lflags,text, text_len, ringbuf_cpu, current);
  582. printed_len += text_len;
  583. raw_spin_unlock(&ringbuf_lock);
  584. local_irq_restore(flags);
  585. return printed_len;
  586. }
  587. EXPORT_SYMBOL(vstlog);
  588. /**
  589. * stlog - print a storage message
  590. * @fmt: format string
  591. */
  592. asmlinkage int stlog(const char *fmt, ...)
  593. {
  594. va_list args;
  595. int r;
  596. va_start(args, fmt);
  597. r = vstlog(fmt, args);
  598. va_end(args);
  599. return r;
  600. }
  601. EXPORT_SYMBOL(stlog);