Project

General

Profile

Formalizing Safety Rules 2 » History » Version 5

Evgeny Novikov, 07/30/2013 01:26 PM

1 4 Evgeny Novikov
{{toc}}
2
3 1 Evgeny Novikov
h1. Formalizing Safety Rules 2
4
5
Before starting formalizing safety rules you need to create an account at this site. The name of this account should be sent to managers of the LDV project, e.g. via e-mail. Then somebody will add you to developers of the LDV project and you will be able to create and to update feature requests and bug reports "here":http://forge.ispras.ru/projects/ldv-rules/issues. 
6
7
Formalizing safety rules consists of following activities that can be fully or partially repeated several times.
8
9 3 Evgeny Novikov
h2. Understanding and Informal Description of the Rule
10 1 Evgeny Novikov
11
Just one time per each rule you need to reserve a rule identifier by creating a feature request "here":http://forge.ispras.ru/projects/ldv-rules/issues. The rule identifier is a number. This number should be greater by one then the maximum of already reserved numbers. Note that you won''t be able to change the rule identifier. 
12
13 2 Evgeny Novikov
To understand the rule you need to:
14
* Read available documentation of the relevant kernel core API, e.g. "here":https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation or in books like "LDD3":http://lwn.net/Kernel/LDD3.
15
* Explore source code, especially relevant header files, of the Linux kernel. For navigation through Linux kernel source code you may use http://lxr.linux.no or http://lxr.free-electrons.com.
16
* Analyze existing violations of the given rule. You may use the Internet or https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git for this purpose.
17
* Analyze verification results that you will obtained at one of the following steps.
18
* Discuss it with developers of the LDV project, if nothing else helps.
19 1 Evgeny Novikov
20 2 Evgeny Novikov
Each time after understanding more details about the rule, you should update informal description of the rule, that includes:
21
* Short name, that should be a part of the name of the feature request you have created before.
22
* Summary, that should outline the essense of the rule.
23
* Detailed description, that should clearly describe all incorrect usages of the relevant kernel core API.
24
* Links to existing violations of the rule. Also it would be greate to provide some short description of each violation, since they may be rather hard for understanding.
25
* Some auxiliary information like absence of required functionality in LDV tools to formalize or/and to check some part of the rule.
26
27 3 Evgeny Novikov
You can find an example of a good description of a rule "here":http://linuxtesting.org/ldv/online?action=show_rule&rule_id=0032. But nobody prevent you from creating a much better description.
28 1 Evgeny Novikov
29 4 Evgeny Novikov
h2. Development of the Rule Model
30 3 Evgeny Novikov
31 4 Evgeny Novikov
h3. Rule Model Description
32 3 Evgeny Novikov
33
All rule models are described in $LDV_TOOLS_SRC/kernel-rules/model-db.xml. So that the most easy way to add one more rule model is to copy description of the existing one (e.g. "100_1a") and to update some information in this description. 
34
35
There is a <model> XML element for each rule model. The identifier of the model is declared by ''id'' attribute. Most likely the identifier of the new rule model will be in form: identifier of the rule concatenated with ''_1a''.
36
37
Child elements of the <model> element include:
38
* rule – identifier of the rule. There can be several models for the same rule.
39
* status – status of readiness. ''public'' means it is ready for public use, other values (e.g., ''default'' or ''private'') mean it is not recommended for some reasons. You should use ''private'' during development
40
* kind – kind of the model. ''aspect'' means the model is defined with CIF aspects, ''plain'' means it is defined as a library. You should use ''aspect'' kind.
41
* error – error label. For now, it must be LDV_ERROR.
42
* engine - a verifier to be used for analysis. You should use ''blast''.
43
* description – informal description of the model. Optional, usually used if there are several models for the same rule. So you may not fill it.
44
* files - list of relative to $LDV_TOOLS_SRC/kernel-rules files defining the model. It contains the following child elements (for ''aspect'' models):
45
** aspect – a file containing CIF "advices":http://en.wikipedia.org/wiki/Advice_%28programming%29 that are applied to all source files of a driver under analysis (this file contains an actual definition of the model, see below).
46
** config – a config file. It should be models/config-tracers.h for new rule models.
47
* hints – hints to a verifier such as extra options to be used for this particular model. Most likely you need to leave this element empty.
48
49
An example of the model element:
50
<pre>
51
<model id="100_1a">
52
    <rule>0100</rule>
53
    <status>public</status>
54
    <kind>aspect</kind>
55
    <error>LDV_ERROR</error>
56
    <engine>blast</engine>
57
    <description></description>
58
    <files>
59
        <aspect>./models/model0100.aspect</aspect>
60
        <config>./models/config-tracers.h</config>
61
    </files>
62
    <hints></hints>
63 1 Evgeny Novikov
</model>
64 3 Evgeny Novikov
</pre>
65
66 4 Evgeny Novikov
h3. Developing Aspect Rule Models
67 3 Evgeny Novikov
68 5 Evgeny Novikov
[[Developing Aspect Rule Models]]
69 3 Evgeny Novikov
70 4 Evgeny Novikov
h3. Model Comments
71 3 Evgeny Novikov
72
Model comments are used by error trace visualizer to highlight important elements of error traces produced by a verifier. It makes analysis of error traces much easier, so it is highly recommended to write model comments from the very beginning. The comments should be short but it should clearly express corresponding situation. For example, comments to _ldv_assert_ should explain what is a problem detected.
73
74
You can use one of the following kinds of model comments:
75
* LDV_COMMENT_MODEL_FUNCTION_DEFINITION(name=''function name to match with'') - describes a model function. The name argument is mandatory. Its value should be equal to a model function name defined at the following line.
76
* LDV_COMMENT_ASSERT - describes what is a problem detected if the assertion failed.
77
* LDV_COMMENT_CHANGE_STATE - decribes changes in model state.
78
* LDV_COMMENT_RETURN - describes a returned value of a model function.
79
* LDV_COMMENT_OTHER - is used to describe any other interesting elements of a model.
80
81
Model comments are written as usual C comments, for example:
82
<pre>
83
/* LDV_COMMENT_MODEL_FUNCTION_DEFINITION(name=''ldv_check_alloc_flags'') Check that a memory allocating function was called with a correct value of flags in spin locking. */
84
void ldv_check_alloc_flags(gfp_t flags)
85
{
86
  /* LDV_COMMENT_ASSERT If spinlock is locked then a memory allocating function should be called with GFP_ATOMIC flag set. */
87
  ldv_assert(ldv_spin == LDV_SPIN_UNLOCKED || flags & GFP_ATOMIC);
88
}
89
90
/* LDV_COMMENT_MODEL_FUNCTION_DEFINITION(name=''ldv_spin_lock'') Lock spinlock. */
91
void ldv_spin_lock(void)
92
{
93
  /* LDV_COMMENT_CHANGE_STATE Lock spinlock. */
94
  ldv_spin = LDV_SPIN_LOCKED;
95
}
96 1 Evgeny Novikov
</pre>
97 5 Evgeny Novikov
98
h2. Test Development
99
100
h3. Common Notes
101
102
Do not pay too much attention to tests. Tests just should show that you are developing the rule model in the proper way. Your actual purpose is described in the next Section. 
103
104
To create tests for a new rule model you can simply copy existing tests for other rule model.
105
106
Tests for rule models should be placed to $LDV_TOOLS_SRC/ldv-tests/rule-models/:
107
* Test drivers are placed to subdirectories of $LDV_TOOLS_SRC/ldv-tests/rule-models/drivers. These subdirectories are to be named in accordance with the rule model identifiers, e.g. $LDV_TOOLS_SRC/ldv-tests/rule-models/drivers/08_1a. Inside these subdirectories test should be placed to subdirectories which names start with ''test-''.
108
* Test tasks are placed to files starting with ''regr-task'' in $LDV_TOOLS_SRC/ldv-tests/rule-models/. Be careful, after merging your branch to the master branch of LDV tools all test tasks starting with ''regr-task'' will be automatically added to QA night test task (regr-tests/test-sets/medium). New tests should be passed, so test them carefully before merging.
109
110
h3. Test Driver
111
112
Each test driver consists of Makefile and a set of C and H source files. Each driver should be compatible with a kernel it is developed for. 
113
114
Состоит из набора исходных кодов .c, .h файлов и Makefile. Драйвер должен компилироваться с тем ядром, для которого он предназначен. В Makefile указывается директива obj-m, определяющая собираемые модули (файлы .ko).
115
116
    Называйте модули согласно вердикту: начинайте название с U где результат должен быть unsafe, и с S — где safe. Если срабатывание ложное — добавляйте букву F (например, "FU" или "FS").
117
    Создав несколько .c файлов с кодом, можно запустить скрипт drivers/gen_makefile.pl, чтобы автоматически сгенерировать Makefile драйвера с модулем .ko на каждый сишник .c.
118
    Повторю, основной критерий качества тестов на функцию: если функция вовсе не инструментируется, то хотя бы один из её тестов должен провалиться. В модели 08_1 на каждую функцию написано три теста: 0, 1 и 2 вызова (только 1 вызов — правильный, safe).
119
    Несколько папок с тестами нужны для возможности их отдельного запуска. Дело в том, что API ядра меняется, и, если в один архив попадут много тестов на разные функции, то с большой вероятностью этот драйвер будет пригоден для тестирования только с одним ядром. Поэтому для существенно разных функций имеет смысл делать разные папки с драйверами (особенно, если эти функции появились в какой-то определённой версии ядра!). 
120
121
h3. Test Task
122
123
Для первого запуска регрессионных тестов вам необходимо сформировать файл задания, где описано хотя бы минимум то, что вы хотите запускать (см. далее Первая часть). После первого запуска надо будет разобраться с полученными результатами (автоматически будет сформирована Вторая часть) и, если все правильно, то можно поменять исходный файл с заданием на сгенерированный.
124
125
Файл задания состоит из записей вида
126
127
 driver=08_1--test-nonseek.tar.bz2;origin=external;kernel=linux-2.6.37;model=08_1;module=drivers/08_1/test-nonseek/S-nonseek-alone-test.ko;main=ldv_main0_sequence_infinite_withcheck_stateful;verdict=safe
128
129
Первая часть переменных описывает параметры запуска
130
131
 driver=08_1--test-nonseek.tar.bz2;origin=external;kernel=linux-2.6.37;model=08_1
132
133
    driver имя архива драйвера, формируется по именам папок от drivers/ с заменой "/" на "--". Например 08_1--test-nonseek.tar.bz2 лежит в drivers/08_1/test-nonseek/.
134
    origin
135
        external - внешний драйвер (для модельных тестов, как правило, будет указан данный вид драйверов)
136
        kernel - внутренний драйвер 
137
    kernel - версия ядра
138
    model - идентификатор модели 
139
140
Вторая часть описывает ожидаемый результат (ее можно не описывать в самом начале)
141
142
 module=drivers/08_1/test-nonseek/S-nonseek-alone-test.ko;main=ldv_main0_sequence_infinite_withcheck_stateful;verdict=safe
143
144
    module - модуль драйвера
145
    main - имя сгенерированной точки входа
146
    verdict - полученный по результатам верификации вердикт 
147
148
В том случае, если вердикт unknown, в дополнительных полях показывается, какой инструмент упал и перечисляются выявленные проблемы:
149
150
verdict=unknown;RCV_status=fail;problems=Blocks_SAT,Exception
151
152
153
h3. Choosing the Linux Kernel
154
155
Ядро для тестирования рекомендуется выбирать на основе уже имеющихся в репозитории (дабы не раздувать размеры репозитория).
156
157
Имеющиеся версии можно посмотреть здесь:
158
159
    ldv-tests/regr-tests/test-sets/big/
160
        linux-2.6.31.6.tar.bz2
161
        linux-2.6.32.15.tar.bz2
162
        linux-2.6.34.tar.bz2 
163
    ldv-tests/rule-models
164
        linux-2.6.37.tar.bz2
165
        linux-3.5.tar.bz2 
166
167
В будущем планируется сделать систему автоматической загрузки нужных версий ядра из локального или одного из глобальных хранилищ. Тогда можно будет себя не ограничивать в выборе версий ядер.
168
Запуск тестов и анализ результатов
169
170
Для начала тесты нужно установить:
171
172
 prefix=/path/to/your/installation/directory make install-testing
173
174
где /path/to/your/installation/directory - путь к установленному ldv-tools. После этого архивы с установленными тестами появятся в директории /ldv-tests/rule-models/. Там же будет лежать и ваш файл задания.
175
176
h3. Regression Testing
177
178
First of all you need to create an empry working directory. Then you need to move to it and run the following command (path to LDV tools executables should be added to $PATH environment 
179
Для запуска следует создать рабочую папку, перейти в неё и выполнить следующую команду:
180
181
 rm -rf * && LDV_DEBUG=100 LDVDBTEST=ldvdb LDVUSERTEST=ldvreports regr-test.pl --test-set /home/shchepetkov/ldv/ldv-tests/rule-models/regr-task-118_1a 
182
183
где:
184
185
    rm -rf * - удаляет все файлы и папки из рабочей директории, возможно оставшиеся после предыдущего запуска. Рабочая папка перед запуском должна быть пустая! 
186
187
    LDVDBTEST=ldvdb LDVUSERTEST=ldvreports - переменные окружения, указывающие на пользователя и базу данных. Подставьте сюда свои значения. Учтите, в результате из этой базы удалятся результаты всех предыдущих запусков! 
188
189
    regr-test.pl - скрипт, отвечающий за запуск тестов. Его содержимое можно посмотреть тут: /bin/regr-test.pl 
190
191
    --test-set /home/shchepetkov/ldv/ldv-tests/rule-models/regr-task-118_1a - тут задаётся абсолютный путь до файла с заданием. --test-set <name> - одна из опция запуска скрипта, как раз указывающая на файл с заданием. Чтобы посмотреть остальные доступные опции, следует выполнить команду: 
192
193
 regr-test.pl --help
194
195
Итак, по окончанию запуска результаты буду залиты на сервер статистики. Так же в папке появятся файлы и директории, которые создаёт скрипт регрессионного тестирования:
196
197
 ls -1
198
199
 current.sorted
200
 launcher-results-dir
201
 launcher-working-dir
202
 original.sorted
203
 regr-task-new
204
 regr-test.diff
205
 work
206
207
Тут нам будут интересны 3 файла - original.sorted, current.sorted и regr-test.diff. Первый - ваш отсортированный тест задания. Второй - это тест задания, сгенерированный скриптом regr-test.pl автоматически на основе результатов запуска. Если ожидаемые результаты не сходятся с фактическими, то разница будет записана в третий файл - regr-test.diff. В этом случае его необходимо посмотреть, понять в чем проблема и исправить её. Если же файл пустой, то тесты успешно проёдены.
208
209
Для большего удобства анализирования результатов можно установить стороннюю программу meld. Она занимается сравниванием содержимого текстовых файлов. Команда:
210
211
 meld current.sorted original.sorted 
212
213
покажет вам различие между этими файлами. Получается гораздо нагляднее и быстрее, чем если просто смотреть regr-test.diff. 
214
215
h2. Verification of Linux Kernel Drivers
216
217
TBD.
218
219
h2. Creating Final Account
220
221
TBD.