a4e6f86ac4121e65ce19bbeabeb5a9732c28cdb2
[virt-top.git] / virt-df / virt_df_ext2.ml
1 (* 'df' command for virtual domains.
2  *
3  * Support for EXT2/EXT3 filesystems.
4  *)
5
6 open Unix
7 open Printf
8
9 (* Int64 operators for convenience. *)
10 let (+^) = Int64.add
11 let (-^) = Int64.sub
12 let ( *^ ) = Int64.mul
13 let (/^) = Int64.div
14
15 let sector_size = Virt_df.sector_size
16 let read_int32_le = Virt_df.read_int32_le
17
18 let probe_ext2 target part_type fd start size =
19   LargeFile.lseek fd ((start+^2L) *^ sector_size) SEEK_SET;
20   let str = String.create 128 in
21   if read fd str 0 128 <> 128 then
22     failwith "error reading ext2/ext3 magic"
23   else (
24     if str.[56] != '\x53' || str.[57] != '\xEF' then (
25       Virt_df.ProbeFailed "partition marked EXT2/3 but no valid filesystem"
26     ) else (
27       (* Refer to <linux/ext2_fs.h> *)
28       let s_inodes_count = read_int32_le str 0 in
29       let s_blocks_count = read_int32_le str 4 in
30       let s_r_blocks_count = read_int32_le str 8 in
31       let s_free_blocks_count = read_int32_le str 12 in
32       let s_free_inodes_count = read_int32_le str 16 in
33       let s_first_data_block = read_int32_le str 20 in
34       let s_log_block_size = read_int32_le str 24 in
35       (*let s_log_frag_size = read_int32_le str 28 in*)
36       let s_blocks_per_group = read_int32_le str 32 in
37
38       (* Work out the block size in bytes. *)
39       let s_log_block_size = Int64.to_int s_log_block_size in
40       let block_size = 1024L in
41       let block_size = Int64.shift_left block_size s_log_block_size in
42
43       (* Number of groups. *)
44       let s_groups_count =
45         (s_blocks_count -^ s_first_data_block -^ 1L)
46         /^ s_blocks_per_group +^ 1L in
47
48 (*
49       (* Number of group descriptors per block. *)
50       let s_inodes_per_block = s_blocksize / 
51         let s_desc_per_block = block_size / s_inodes_per_block in
52         let db_count =
53           (s_groups_count +^ s_desc_per_block -^ 1L)
54           /^ s_desc_per_block
55 *)
56
57       (* Calculate the block overhead (used by superblocks, inodes, etc.)
58        * See fs/ext2/super.c.
59        *)
60       let overhead = s_first_data_block in
61       let overhead = (* XXX *) overhead in
62
63
64       Virt_df.Filesystem {
65         Virt_df.fs_name = "Linux ext2/3";
66         fs_block_size = block_size;
67         fs_blocks_total = s_blocks_count -^ overhead;
68         fs_blocks_reserved = s_r_blocks_count;
69         fs_blocks_avail = s_free_blocks_count;
70         fs_blocks_used = s_blocks_count -^ overhead -^ s_free_blocks_count;
71         fs_inodes_total = s_inodes_count;
72         fs_inodes_reserved = 0L;        (* XXX? *)
73         fs_inodes_avail = s_free_inodes_count;
74         fs_inodes_used = s_inodes_count (*-^ 0L*) -^ s_free_inodes_count;
75       }
76     )
77   )
78
79 (* Register with main code. *)
80 let () =
81   Virt_df.fs_register
82     [ 0x83 ]                            (* Partition type. *)
83     probe_ext2