liyujie
2025-08-28 786ff4f4ca2374bdd9177f2e24b503d43e7a3b93
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# Copyright 2014 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
 
import gzip, logging, os, re
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
 
class KernelConfig():
    """
    Parse the kernel config and enable us to query it.
    Used to verify the kernel config (see kernel_ConfigVerify).
    """
 
    def _passed(self, msg):
        logging.info('ok: %s', msg)
 
    def _failed(self, msg):
        logging.error('FAIL: %s', msg)
        self._failures.append(msg)
 
    def failures(self):
        """Return the list of failures that occured during the test.
 
        @return a list of string describing errors that occured since
                initialization.
        """
        return self._failures
 
    def _fatal(self, msg):
        logging.error('FATAL: %s', msg)
        raise error.TestError(msg)
 
    def get(self, key, default):
        """Get the value associated to key or default if it does not exist
 
        @param key: key to look for.
        @param default: value returned if key is not set in self._config
        """
        return self._config.get(key, default)
 
    def _config_required(self, name, wanted):
        value = self._config.get(name, None)
        if value in wanted:
            self._passed('"%s" was "%s" in kernel config' % (name, value))
        else:
            states = []
            for state in wanted:
                if state == None:
                    states.append("unset")
                else:
                    states.append(state)
            self._failed('"%s" was "%s" (wanted one of "%s") in kernel config' %
                         (name, value, '|'.join(states)))
 
    def has_value(self, name, value):
        """Determine if the name config item has a specific value.
 
        @param name: name of config item to test
        @param value: value expected for the given config name
        """
        self._config_required('CONFIG_%s' % (name), value)
 
    def has_builtin(self, name):
        """Check if the specific config item is built-in (present but not
        built as a module).
 
        @param name: name of config item to test
        """
        wanted = ['y']
        if name in self._missing_ok:
            wanted.append(None)
        self.has_value(name, wanted)
 
    def has_module(self, name):
        """Check if the specific config item is a module (present but not
        built-in).
 
        @param name: name of config item to test
        """
        wanted = ['m']
        if name in self._missing_ok:
            wanted.append(None)
        self.has_value(name, wanted)
 
    def is_enabled(self, name):
        """Check if the specific config item is present (either built-in or
        a module).
 
        @param name: name of config item to test
        """
        wanted = ['y', 'm']
        if name in self._missing_ok:
            wanted.append(None)
        self.has_value(name, wanted)
 
    def is_missing(self, name):
        """Check if the specific config item is not present (neither built-in
        nor a module).
 
        @param name: name of config item to test
        """
        self.has_value(name, [None])
 
    def is_exclusive(self, exclusive):
        """Given a config item regex, make sure only the expected items
        are present in the kernel configs.
 
        @param exclusive: hash containing "missing", "builtin", "module",
                          "enabled" each to be checked with the corresponding
                          has_* function based on config items matching the
                          "regex" value.
        """
        expected = set()
        for name in exclusive['missing']:
            self.is_missing(name)
        for name in exclusive['builtin']:
            self.has_builtin(name)
            expected.add('CONFIG_%s' % (name))
        for name in exclusive['module']:
            self.has_module(name)
            expected.add('CONFIG_%s' % (name))
        for name in exclusive['enabled']:
            self.is_enabled(name)
            expected.add('CONFIG_%s' % (name))
 
        # Now make sure nothing else with the specified regex exists.
        regex = r'CONFIG_%s' % (exclusive['regex'])
        for name in self._config:
            if not re.match(regex, name):
                continue
            if not name in expected:
                self._failed('"%s" found for "%s" when only "%s" allowed' %
                             (name, regex, "|".join(expected)))
 
    def _open_config(self):
        """Open the kernel's build config file. Attempt to use the built-in
        symbols from /proc first, then fall back to looking for a text file
        in /boot.
 
        @return fileobj for open config file
        """
        filename = '/proc/config.gz'
        if not os.path.exists(filename):
            utils.system("modprobe configs", ignore_status=True)
        if os.path.exists(filename):
            return gzip.open(filename, "r")
 
        filename = '/boot/config-%s' % utils.system_output('uname -r')
        if os.path.exists(filename):
            logging.info('Falling back to reading %s', filename)
            return file(filename, "r")
 
        self._fatal("Cannot locate suitable kernel config file")
 
    def initialize(self, missing_ok=None):
        """Load the kernel configuration and parse it.
        """
        fileobj = self._open_config()
        # Import kernel config variables into a dictionary for each searching.
        config = dict()
        for item in fileobj.readlines():
            item = item.strip()
            if not '=' in item:
                continue
            key, value = item.split('=', 1)
            config[key] = value
 
        # Make sure we actually loaded something sensible.
        if len(config) == 0:
            self._fatal('No CONFIG variables found!')
 
        self._config = config
        self._failures = []
        self._missing_ok = set()
        if missing_ok:
            self._missing_ok |= set(missing_ok)