'verbose' -> 'debug' in a few more places.
[virt-mem.git] / dmesg / virt_dmesg.ml
1 (* Memory info for virtual domains.
2    (C) Copyright 2008 Richard W.M. Jones, Red Hat Inc.
3    http://libvirt.org/
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  *)
19
20 open Printf
21
22 open Virt_mem_gettext.Gettext
23 open Virt_mem_utils
24 open Virt_mem_mmap
25
26 let usage = s_"NAME
27   virt-dmesg - dmesg command for virtual machines
28
29 SUMMARY
30   virt-dmesg [-options] [domains]
31
32 DESCRIPTION
33   virt-dmesg prints the kernel messages for virtual machines running
34   under libvirt.  The output is similar to the ordinary dmesg command
35   run inside the virtual machine."
36
37 let _, images = Virt_mem.start usage
38
39 let () =
40   List.iter (
41     fun (name, arch, mem, lookup_ksym) ->
42       try
43         (* I don't know why but this symbol doesn't exist in 2.6.9
44          * even in kallsyms.  Hence this won't work with that kernel.
45          * It's possible we can fall back to memory scanning. XXX
46          *)
47         let log_buf = lookup_ksym "log_buf" in
48         let log_buf = follow_pointer mem log_buf in
49         let log_buf_len = lookup_ksym "log_buf_len" in
50         let log_buf_len = Int64.of_int32 (get_C_int mem log_buf_len) in
51 (*      let log_start = lookup_ksym "log_start" in
52         let log_start = get_C_long mem log_start in *)
53         let log_end = lookup_ksym "log_end" in
54         let log_end = get_C_long mem log_end in
55 (*      let con_start = lookup_ksym "con_start" in
56         let con_start = get_C_long mem con_start in *)
57         let logged_chars = lookup_ksym "logged_chars" in
58         let logged_chars = get_C_long mem logged_chars in
59
60         (* This is basically the same algorithm from printk.c:do_syslog
61          * type=3, translated into OCaml.  Unlike the kernel version
62          * however we don't copy the buffer backwards.
63          *)
64         let get_log_buf idx =
65           let addr = log_buf +^ (idx &^ (log_buf_len -^ 1L)) in
66           Char.chr (get_byte mem addr)
67         in
68
69         let count = log_buf_len in
70         let count = if count > logged_chars then logged_chars else count in
71         let limit = log_end in
72
73         let rec loop i =
74           if i >= 0L then (
75             let j = limit-^1L-^i in
76             if j +^ log_buf_len >= log_end then (
77               let c = get_log_buf j in
78               printf "%c" c;
79               loop (i-^1L)
80             )
81           )
82         in
83         loop (count-^1L)
84       with
85         Not_found ->
86           eprintf (f_"%s: could not find kernel log buffer in kernel image\n")
87             name
88   ) images