1 (* Memory info for virtual domains.
2 (C) Copyright 2008 Richard W.M. Jones, Red Hat Inc.
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.
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.
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.
20 (* This program takes the kernel database (in kernels/ in toplevel
21 directory) and generates parsing code for the various structures
22 in the kernel that we are interested in.
24 The output programs -- *.ml, *.mli files of generated code -- go
25 into lib/ at the toplevel, eg. lib/kernel_task_struct.ml
27 The stuff at the top of this file determine what structures
28 and fields we try to parse.
34 [ "state"; "prio"; "normal_prio"; "static_prio"; "tasks"; "comm"]
42 let (//) = Filename.concat
45 let args = Array.to_list Sys.argv in
47 let kernelsdir, outputdir =
51 let arg0 = Filename.basename Sys.executable_name in
52 eprintf "%s - Turn kernels database into code modules.
55 %s <kernelsdir> <outputdir>
57 Example (from toplevel of virt-mem source tree):
62 (* Get the *.info files from the kernels database. *)
63 let infos = Sys.readdir kernelsdir in
64 let infos = Array.to_list infos in
65 let infos = List.filter (fun name -> String.ends_with name ".info") infos in
66 let infos = List.map ((//) kernelsdir) infos in
68 (* Regular expressions. We really really should use ocaml-mikmatch ... *)
69 let re_oldformat = Pcre.regexp "^RPM: \\d+: \\(build \\d+\\) ([-\\w]+) ([\\w.]+) ([\\w.]+) \\(.*?\\) (\\w+)" in
70 let re_keyvalue = Pcre.regexp "^(\\w+): (.*)" in
72 (* Parse in the *.info files. These have historically had a few different
73 * formats that we need to support.
75 let infos = List.map (
77 (* Get the basename (for getting the .data file later on). *)
78 let basename = Filename.chop_suffix filename ".info" in
80 let chan = open_in filename in
81 let line = input_line chan in
84 if Pcre.pmatch ~rex:re_oldformat line then (
85 (* If the file starts with "RPM: \d+: ..." then it's the original
86 * format. Everything in one line.
88 let subs = Pcre.exec ~rex:re_oldformat line in
89 let name = Pcre.get_substring subs 1 in
90 let version = Pcre.get_substring subs 2 in
91 let release = Pcre.get_substring subs 3 in
92 let arch = Pcre.get_substring subs 4 in
94 name, sprintf "%s-%s.%s" version release arch
96 (* New-style "key: value" entries, up to end of file or the first
99 let name, version, release, arch =
100 ref "", ref "", ref "", ref "" in
103 let subs = Pcre.exec ~rex:re_keyvalue line in
104 let key = Pcre.get_substring subs 1 in
105 let value = Pcre.get_substring subs 2 in
106 if key = "Name" then name := value
107 else if key = "Version" then version := value
108 else if key = "Release" then release := value
109 else if key = "Architecture" then arch := value;
110 let line = input_line chan in
113 Not_found | End_of_file ->
117 let name, version, release, arch =
118 !name, !version, !release, !arch in
119 if name = "" || version = "" || release = "" || arch = "" then
120 failwith (sprintf "%s: missing Name, Version, Release or Architecture key" filename);
121 name, sprintf "%s-%s.%s" version release arch
124 printf "%s -> %s, %s\n" basename name version;
126 (basename, name, version)