Combined binary.
[virt-mem.git] / dmesg / virt_dmesg.ml
index 2435bbc..0931e91 100644 (file)
@@ -23,20 +23,7 @@ open Virt_mem_gettext.Gettext
 open Virt_mem_utils
 open Virt_mem_mmap
 
-let usage = s_"NAME
-  virt-dmesg - dmesg command for virtual machines
-
-SUMMARY
-  virt-dmesg [-options] [domains]
-
-DESCRIPTION
-  virt-dmesg prints the kernel messages for virtual machines running
-  under libvirt.  The output is similar to the ordinary dmesg command
-  run inside the virtual machine."
-
-let verbose, images = Virt_mem.start usage
-
-let () =
+let run debug images =
   List.iter (
     fun (name, arch, mem, lookup_ksym) ->
       try
@@ -45,15 +32,52 @@ let () =
         * It's possible we can fall back to memory scanning. XXX
         *)
        let log_buf = lookup_ksym "log_buf" in
+       let log_buf = follow_pointer mem log_buf in
        let log_buf_len = lookup_ksym "log_buf_len" in
-       let log_start = lookup_ksym "log_start" in
+       let log_buf_len = Int64.of_int32 (get_C_int mem log_buf_len) in
+(*     let log_start = lookup_ksym "log_start" in
+       let log_start = get_C_long mem log_start in *)
        let log_end = lookup_ksym "log_end" in
-       let con_start = lookup_ksym "con_start" in
+       let log_end = get_C_long mem log_end in
+(*     let con_start = lookup_ksym "con_start" in
+       let con_start = get_C_long mem con_start in *)
+       let logged_chars = lookup_ksym "logged_chars" in
+       let logged_chars = get_C_long mem logged_chars in
 
-       ()
+       (* This is basically the same algorithm from printk.c:do_syslog
+        * type=3, translated into OCaml.  Unlike the kernel version
+        * however we don't copy the buffer backwards.
+        *)
+       let get_log_buf idx =
+         let addr = log_buf +^ (idx &^ (log_buf_len -^ 1L)) in
+         Char.chr (get_byte mem addr)
+       in
+
+       let count = log_buf_len in
+       let count = if count > logged_chars then logged_chars else count in
+       let limit = log_end in
 
+       let rec loop i =
+         if i >= 0L then (
+           let j = limit-^1L-^i in
+           if j +^ log_buf_len >= log_end then (
+             let c = get_log_buf j in
+             printf "%c" c;
+             loop (i-^1L)
+           )
+         )
+       in
+       loop (count-^1L)
       with
        Not_found ->
          eprintf (f_"%s: could not find kernel log buffer in kernel image\n")
            name
   ) images
+
+let summary = s_"display kernel messages"
+let description = s_"\
+virt-dmesg prints the kernel messages for virtual machines running
+under libvirt.  The output is similar to the ordinary dmesg command
+run inside the virtual machine."
+
+let () = Virt_mem.register "dmesg" summary description true run