1
+ package cfig.lazybox
2
+
3
+ import org.slf4j.LoggerFactory
4
+ import java.io.BufferedWriter
5
+ import java.io.File
6
+ import java.io.FileOutputStream
7
+ import java.io.FileWriter
8
+
9
+ class MountAnalyzer {
10
+ data class MountInfo (
11
+ var dev : String = " " ,
12
+ var mountPoint : String = " " ,
13
+ var fsType : String = " " ,
14
+ var flags : String? = null ,
15
+ )
16
+
17
+ class MiComparator : Comparator <MountInfo > {
18
+ override fun compare (p1 : MountInfo , p2 : MountInfo ): Int {
19
+ var ret = p1.fsType.compareTo(p2.fsType) * 100
20
+ ret + = p1.dev.compareTo(p2.dev) * 10
21
+ ret + = p1.mountPoint.compareTo(p2.mountPoint) * 1
22
+ return ret
23
+ }
24
+ }
25
+
26
+ fun run () {
27
+ val loopApex = mutableListOf<MountInfo >()
28
+ val dmApex = mutableListOf<MountInfo >()
29
+ val tmpApex = mutableListOf<MountInfo >()
30
+ val bootApex = mutableListOf<MountInfo >()
31
+ val fuseInfo = mutableListOf<MountInfo >()
32
+ val sysInfo = mutableListOf<MountInfo >()
33
+ val androidRo = mutableListOf<MountInfo >()
34
+ val androidRw = mutableListOf<MountInfo >()
35
+ val otherRw = mutableListOf<MountInfo >()
36
+ val unknownMi = mutableListOf<MountInfo >()
37
+ val lines = File (" mount.log" ).readLines()
38
+ lines.forEachIndexed { n, line ->
39
+ val regex = Regex (" (\\ S+)\\ s+on\\ s+(\\ S+)\\ s+type\\ s+(\\ w+)\\ s+\\ (([^)]*)\\ )" ) // Capture flags
40
+ val matchResult = regex.find(line)
41
+ if (matchResult != null ) {
42
+ val dev = matchResult.groupValues[1 ]
43
+ val mountPoint = matchResult.groupValues[2 ]
44
+ val fsType = matchResult.groupValues[3 ]
45
+ val flags =
46
+ if (matchResult.groupValues.size > 4 ) matchResult.groupValues[4 ] else null // Handle no flags
47
+ val mi = MountInfo (dev, mountPoint, fsType, flags)
48
+ if (mi.mountPoint.startsWith(" /apex" ) || mi.mountPoint.startsWith(" /bootstrap-apex" )) {
49
+ if (mi.mountPoint.startsWith(" /bootstrap-apex" )) {
50
+ bootApex.add(mi)
51
+ } else if (mi.dev.startsWith(" /dev/block/loop" )) {
52
+ loopApex.add(mi)
53
+ } else if (mi.dev.startsWith(" /dev/block/dm" )) {
54
+ dmApex.add(mi)
55
+ } else if (mi.dev.startsWith(" tmpfs" )) {
56
+ tmpApex.add(mi)
57
+ } else {
58
+ log.info(" $fsType : $dev -> $mountPoint " )
59
+ throw IllegalStateException (" X1" )
60
+ }
61
+ } else if (mi.mountPoint.startsWith(" /sys/" ) || mi.mountPoint == " /sys" ) {
62
+ sysInfo.add(mi)
63
+ } else if (mi.fsType == " fuse" ) {
64
+ fuseInfo.add(mi)
65
+ } else {
66
+ log.info(" $fsType : $dev -> $mountPoint " )
67
+ if (mi.flags!! .contains(" ro," ) or mi.flags!! .contains(" ro)" )) {
68
+ androidRo.add(mi)
69
+ } else if (mi.flags!! .contains(" rw," ) or mi.flags!! .contains(" rw)" )) {
70
+ if (mi.dev.startsWith(" /dev/" )) {
71
+ androidRw.add(mi)
72
+ } else {
73
+ otherRw.add(mi)
74
+ }
75
+ } else {
76
+ throw IllegalStateException (" X2" )
77
+ }
78
+ }
79
+ } else { // For lines without flags
80
+ val regexNoFlags = Regex (" (\\ S+)\\ s+on\\ s+(\\ S+)\\ s+type\\ s+(\\ w+)" )
81
+ val matchResultNoFlags = regexNoFlags.find(line)
82
+ if (matchResultNoFlags != null ) {
83
+ val dev = matchResultNoFlags.groupValues[1 ]
84
+ val mountPoint = matchResultNoFlags.groupValues[2 ]
85
+ val fsType = matchResultNoFlags.groupValues[3 ]
86
+ val mi = MountInfo (dev, mountPoint, fsType, null )
87
+ unknownMi.add(mi)
88
+ } else {
89
+ throw IllegalStateException (" X3" )
90
+ }
91
+ }
92
+ } // end-of-lines
93
+ // sanity check, make sure consistent
94
+ check(
95
+ listOf (
96
+ loopApex,
97
+ dmApex,
98
+ tmpApex,
99
+ bootApex,
100
+ fuseInfo,
101
+ sysInfo,
102
+ androidRo,
103
+ androidRw,
104
+ otherRw,
105
+ unknownMi
106
+ ).sumOf { it.size } == lines.size)
107
+ // dump
108
+ val infoNames = listOf (
109
+ " fusefs" ,
110
+ " sysfs" ,
111
+ " Android RO" ,
112
+ " Android RW" ,
113
+ " other Rw" ,
114
+ " loop apex" ,
115
+ " dm apex" ,
116
+ " tmp apex" ,
117
+ " boot apex" ,
118
+ " unknown"
119
+ )
120
+ BufferedWriter (FileWriter (File (" sorted_mount.log" ))).use { fos ->
121
+ listOf (
122
+ fuseInfo,
123
+ sysInfo,
124
+ androidRo,
125
+ androidRw,
126
+ otherRw,
127
+ loopApex,
128
+ dmApex,
129
+ tmpApex,
130
+ bootApex,
131
+ unknownMi
132
+ ).forEachIndexed { n, mis ->
133
+ mis.sortWith(MiComparator ())
134
+ log.info(infoNames.get(n))
135
+ fos.write(infoNames.get(n) + " \n " )
136
+ mis.forEachIndexed { index, it ->
137
+ log.info(" [$index ] ${it.fsType} : ${it.dev} -> ${it.mountPoint} (${it.flags} )" )
138
+ fos.write(" #$index | ${it.fsType} | ${it.dev} | ${it.mountPoint} | (${it.flags} )\n " )
139
+ }
140
+ fos.write(" \n " )
141
+ }
142
+ }
143
+ }
144
+
145
+ companion object {
146
+ private val log = LoggerFactory .getLogger(MountAnalyzer ::class .java)
147
+ }
148
+ }
0 commit comments