← Documents Documentation/livepatch/system-state.rst GitHub 원문 ↗

Linux 6.18.37 · Livepatch

System State Changes

누적 라이브패치 사이에서 지속되는 system state 변경의 id·version 호환성과 callback별 인계·복원 규칙입니다.

Source pathDocumentation/livepatch/system-state.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

system-state.rst:1-167

System state tracking은 code를 교체한 뒤에도 남는 callback·shadow data 변경을 `id`와 `version`으로 식별해 누적 patch의 호환성을 판정합니다.

새 patch는 이전 변경을 takeover하거나 update하고, disable·transition reverse·enable 실패 때 각각 원래 상태 또는 교체 전 상태를 정확히 복원해야 합니다.

`pre_patch()`부터 `post_unpatch()`까지의 callback은 data 준비, 실제 변경, 새 code 의존 차단, 이전 상태 복원을 나누어 담당합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ====================
2 System State Changes
3 ====================
4
5 Some users are really reluctant to reboot a system. This brings the need
6 to provide more livepatches and maintain some compatibility between them.
7
8 Maintaining more livepatches is much easier with cumulative livepatches.
9 Each new livepatch completely replaces any older one. It can keep,
10 add, and even remove fixes. And it is typically safe to replace any version
11 of the livepatch with any other one thanks to the atomic replace feature.
12
13 The problems might come with shadow variables and callbacks. They might
14 change the system behavior or state so that it is no longer safe to
15 go back and use an older livepatch or the original kernel code. Also
16 any new livepatch must be able to detect what changes have already been
17 done by the already installed livepatches.
18
19 This is where the livepatch system state tracking gets useful. It
20 allows to:
21
22 - store data needed to manipulate and restore the system state
23
24 - define compatibility between livepatches using a change id
25 and version
26
27
28 1. Livepatch system state API
29 =============================
30
31 The state of the system might get modified either by several livepatch callbacks
32 or by the newly used code. Also it must be possible to find changes done by
33 already installed livepatches.
34
35 Each modified state is described by struct klp_state, see
36 include/linux/livepatch.h.
37
38 Each livepatch defines an array of struct klp_states. They mention
39 all states that the livepatch modifies.
40
41 The livepatch author must define the following two fields for each
42 struct klp_state:
43
44 - *id*
45
46 - Non-zero number used to identify the affected system state.
47
48 - *version*
49
50 - Number describing the variant of the system state change that
51 is supported by the given livepatch.
52
53 The state can be manipulated using two functions:
54
55 - klp_get_state()
56
57 - Get struct klp_state associated with the given livepatch
58 and state id.
59
60 - klp_get_prev_state()
61
62 - Get struct klp_state associated with the given feature id and
63 already installed livepatches.
64
65 2. Livepatch compatibility
66 ==========================
67
68 The system state version is used to prevent loading incompatible livepatches.
69 The check is done when the livepatch is enabled. The rules are:
70
71 - Any completely new system state modification is allowed.
72
73 - System state modifications with the same or higher version are allowed
74 for already modified system states.
75
76 - Cumulative livepatches must handle all system state modifications from
77 already installed livepatches.
78
79 - Non-cumulative livepatches are allowed to touch already modified
80 system states.
81
82 3. Supported scenarios
83 ======================
84
85 Livepatches have their life-cycle and the same is true for the system
86 state changes. Every compatible livepatch has to support the following
87 scenarios:
88
89 - Modify the system state when the livepatch gets enabled and the state
90 has not been already modified by a livepatches that are being
91 replaced.
92
93 - Take over or update the system state modification when is has already
94 been done by a livepatch that is being replaced.
95
96 - Restore the original state when the livepatch is disabled.
97
98 - Restore the previous state when the transition is reverted.
99 It might be the original system state or the state modification
100 done by livepatches that were being replaced.
101
102 - Remove any already made changes when error occurs and the livepatch
103 cannot get enabled.
104
105 4. Expected usage
106 =================
107
108 System states are usually modified by livepatch callbacks. The expected
109 role of each callback is as follows:
110
111 *pre_patch()*
112
113 - Allocate *state->data* when necessary. The allocation might fail
114 and *pre_patch()* is the only callback that could stop loading
115 of the livepatch. The allocation is not needed when the data
116 are already provided by previously installed livepatches.
117
118 - Do any other preparatory action that is needed by
119 the new code even before the transition gets finished.
120 For example, initialize *state->data*.
121
122 The system state itself is typically modified in *post_patch()*
123 when the entire system is able to handle it.
124
125 - Clean up its own mess in case of error. It might be done by a custom
126 code or by calling *post_unpatch()* explicitly.
127
128 *post_patch()*
129
130 - Copy *state->data* from the previous livepatch when they are
131 compatible.
132
133 - Do the actual system state modification. Eventually allow
134 the new code to use it.
135
136 - Make sure that *state->data* has all necessary information.
137
138 - Free *state->data* from replaces livepatches when they are
139 not longer needed.
140
141 *pre_unpatch()*
142
143 - Prevent the code, added by the livepatch, relying on the system
144 state change.
145
146 - Revert the system state modification..
147
148 *post_unpatch()*
149
150 - Distinguish transition reverse and livepatch disabling by
151 checking *klp_get_prev_state()*.
152
153 - In case of transition reverse, restore the previous system
154 state. It might mean doing nothing.
155
156 - Remove any not longer needed setting or data.
157
158 .. note::
159
160 *pre_unpatch()* typically does symmetric operations to *post_patch()*.
161 Except that it is called only when the livepatch is being disabled.
162 Therefore it does not need to care about any previously installed
163 livepatch.
164
165 *post_unpatch()* typically does symmetric operations to *pre_patch()*.
166 It might be called also during the transition reverse. Therefore it
167 has to handle the state of the previously installed livepatches.
168

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

누적 패치와 system state 추적

1-27

재부팅을 꺼리는 사용자를 지원하려면 더 많은 라이브패치를 제공하고 패치 사이의 호환성을 유지해야 합니다. Cumulative livepatch는 새 패치가 이전 패치를 완전히 대체하면서 fix를 유지·추가·제거할 수 있게 해 이 관리를 단순화합니다.

Atomic replace 기능 덕분에 보통은 한 livepatch version을 다른 version으로 안전하게 교체할 수 있습니다. 하지만 shadow variable과 callback은 system behavior나 state를 바꿀 수 있어, 이전 livepatch 또는 원래 kernel code로 돌아가는 것이 더 이상 안전하지 않을 수 있습니다.

또한 새 livepatch는 이미 설치된 패치가 어떤 변경을 수행했는지 알아야 합니다. Livepatch system state tracking은 상태를 조작하고 복원하는 데 필요한 data를 저장하고, change id와 version으로 livepatch 사이의 호환성을 정의합니다.

System state tracking의 목적
문제추적 정보해결
이전 callback이 system state를 변경변경 data교체·해제·rollback 때 복원
Shadow variable이 이전 code와 호환되지 않음Change id와 version새 patch enable 전 호환성 판정
Cumulative patch가 이전 변경을 인계이전 `struct klp_state`상태 takeover 또는 update

Code 교체를 넘어 지속되는 상태 변경을 버전별로 인계합니다.

====================
System State Changes
====================

Some users are really reluctant to reboot a system. This brings the need
to provide more livepatches and maintain some compatibility between them.

Maintaining more livepatches is much easier with cumulative livepatches.
Each new livepatch completely replaces any older one. It can keep,
add, and even remove fixes. And it is typically safe to replace any version
of the livepatch with any other one thanks to the atomic replace feature.

The problems might come with shadow variables and callbacks. They might
change the system behavior or state so that it is no longer safe to
go back and use an older livepatch or the original kernel code. Also
any new livepatch must be able to detect what changes have already been
done by the already installed livepatches.

This is where the livepatch system state tracking gets useful. It
allows to:

  - store data needed to manipulate and restore the system state

  - define compatibility between livepatches using a change id
    and version

System state API

28-64

System state는 여러 livepatch callback이나 새로 사용되는 code가 변경할 수 있습니다. 이미 설치된 livepatch가 수행한 변경도 찾아야 하므로 각 변경 상태를 `include/linux/livepatch.h`에 정의된 `struct klp_state`로 설명합니다.

각 livepatch는 자신이 수정하는 모든 상태를 열거한 `struct klp_states` array를 정의합니다. 각 `struct klp_state`에는 작성자가 `id`와 `version` 두 field를 지정해야 합니다.

`id`는 영향을 받는 system state를 식별하는 0이 아닌 숫자입니다. `version`은 해당 livepatch가 지원하는 system state 변경 variant를 나타내는 숫자입니다.

`klp_get_state()`는 주어진 livepatch와 state id에 연결된 `struct klp_state`를 얻습니다. `klp_get_prev_state()`는 같은 feature id를 가진 이미 설치된 livepatch의 `struct klp_state`를 찾습니다.

`struct klp_state`와 조회 API
항목입력·값의미
`state->id`0이 아닌 number영향받은 system state 식별
`state->version`Number해당 patch가 지원하는 상태 변경 variant
`klp_get_state()`Livepatch + state id현재 patch의 state entry 조회
`klp_get_prev_state()`Feature id + installed livepatches교체 대상 patch의 이전 state 조회

Id는 상태의 종류를, version은 그 상태 표현의 호환 단계를 나타냅니다.

상태 인계 준비
새 livepatch의 `struct klp_states` array 확인`klp_get_state()`로 현재 state entry 획득`klp_get_prev_state()`로 이전 patch의 같은 id 검색Version 호환성 비교호환되면 data와 변경 상태 인계

새 patch는 자신의 상태 정의와 설치된 이전 상태를 함께 조회합니다.

1. Livepatch system state API
=============================

The state of the system might get modified either by several livepatch callbacks
or by the newly used code. Also it must be possible to find changes done by
already installed livepatches.

Each modified state is described by struct klp_state, see
include/linux/livepatch.h.

Each livepatch defines an array of struct klp_states. They mention
all states that the livepatch modifies.

The livepatch author must define the following two fields for each
struct klp_state:

  - *id*

    - Non-zero number used to identify the affected system state.

  - *version*

    - Number describing the variant of the system state change that
      is supported by the given livepatch.

The state can be manipulated using two functions:

  - klp_get_state()

    - Get struct klp_state associated with the given livepatch
      and state id.

  - klp_get_prev_state()

    - Get struct klp_state associated with the given feature id and
      already installed livepatches.

Livepatch 호환성 규칙

65-81

System state version은 호환되지 않는 livepatch의 적재를 막는 데 사용하며, 검사는 livepatch를 enable할 때 수행합니다.

완전히 새로운 system state modification은 허용됩니다. 이미 수정된 state에 대해서는 같은 version 또는 더 높은 version의 변경을 허용합니다.

Cumulative livepatch는 이미 설치된 livepatch가 수행한 모든 system state modification을 처리해야 합니다. 반면 non-cumulative livepatch도 이미 수정된 system state를 건드리는 것이 허용됩니다.

Enable 시 version 판정
상황허용 조건새 patch의 의무
처음 보는 state id항상 허용새 변경을 처음부터 구성
이미 수정된 state같거나 더 높은 version이전 변경을 이해하고 인계
Cumulative livepatch설치된 모든 변경과 호환모든 이전 system state modification 처리
Non-cumulative livepatch기존 state 수정 가능자신이 건드리는 state의 호환성 유지

이전 state가 있는지와 새 patch의 version으로 호환성을 판단합니다.

2. Livepatch compatibility
==========================

The system state version is used to prevent loading incompatible livepatches.
The check is done when the livepatch is enabled. The rules are:

  - Any completely new system state modification is allowed.

  - System state modifications with the same or higher version are allowed
    for already modified system states.

  - Cumulative livepatches must handle all system state modifications from
    already installed livepatches.

  - Non-cumulative livepatches are allowed to touch already modified
    system states.

지원해야 하는 lifecycle 시나리오

82-104

Livepatch에 lifecycle이 있듯 system state 변경에도 lifecycle이 있습니다. 호환 가능한 모든 livepatch는 enable, replace, disable, transition reverse, enable 실패 상황을 처리해야 합니다.

Enable할 때 교체 대상 livepatch가 아직 해당 state를 수정하지 않았다면 새 patch가 system state를 변경합니다. 이미 변경했다면 새 patch가 그 변경을 takeover하거나 최신 version으로 update해야 합니다.

Livepatch를 disable하면 원래 state를 복원해야 합니다. 진행 중 transition을 되돌리면 이전 state를 복원해야 하는데, 이는 원래 kernel state일 수도 있고 교체되던 livepatch가 만든 state일 수도 있습니다.

오류로 livepatch를 enable할 수 없다면 그때까지 수행한 변경을 모두 제거해야 합니다. Enable 실패는 반쯤 적용된 state를 남기지 않아야 합니다.

System state lifecycle
Enable: 이전 변경이 없으면 새 state 적용Replace: 이전 변경이 있으면 takeover 또는 updateDisable: 원래 kernel state 복원Transition reverse: 교체 전 livepatch state 복원Enable error: 이번 시도에서 만든 모든 변경 제거

각 전환의 목표 상태와 복구 대상을 구분합니다.

3. Supported scenarios
======================

Livepatches have their life-cycle and the same is true for the system
state changes. Every compatible livepatch has to support the following
scenarios:

  - Modify the system state when the livepatch gets enabled and the state
    has not been already modified by a livepatches that are being
    replaced.

  - Take over or update the system state modification when is has already
    been done by a livepatch that is being replaced.

  - Restore the original state when the livepatch is disabled.

  - Restore the previous state when the transition is reverted.
    It might be the original system state or the state modification
    done by livepatches that were being replaced.

  - Remove any already made changes when error occurs and the livepatch
    cannot get enabled.

Callback별 예상 역할

105-167

System state는 보통 livepatch callback에서 변경합니다. `pre_patch()`는 필요한 경우 `state->data`를 할당합니다. Allocation은 실패할 수 있으며, livepatch 적재를 중단할 수 있는 callback은 `pre_patch()`뿐입니다. 이전 livepatch가 이미 data를 제공했다면 다시 할당할 필요가 없습니다.

`pre_patch()`는 transition이 끝나기 전에도 새 code가 요구하는 준비 작업을 수행하고 `state->data`를 초기화할 수 있습니다. 실제 system state 변경은 전체 system이 이를 처리할 수 있게 된 뒤 `post_patch()`에서 수행하는 것이 일반적입니다.

`pre_patch()`에서 오류가 나면 자신이 만든 변경을 직접 정리하거나 `post_unpatch()`를 명시적으로 호출해 정리해야 합니다.

`post_patch()`는 호환되는 이전 livepatch에서 `state->data`를 복사하고 실제 system state를 변경해 새 code가 사용할 수 있게 합니다. `state->data`에 복원에 필요한 모든 정보가 있는지 보장하고, 더 이상 필요 없는 교체 대상 livepatch의 data를 해제합니다.

`pre_unpatch()`는 livepatch가 추가한 code가 system state 변경에 의존하지 못하게 차단한 뒤 실제 변경을 되돌립니다.

`post_unpatch()`는 `klp_get_prev_state()`를 확인해 transition reverse와 livepatch disable을 구별합니다. Reverse라면 이전 system state를 복원하며, 이미 그 상태가 남아 있다면 아무 작업도 하지 않을 수 있습니다. 마지막으로 더 이상 필요 없는 설정과 data를 제거합니다.

일반적으로 `pre_unpatch()`는 `post_patch()`의 대칭 작업입니다. 하지만 livepatch를 disable할 때만 호출되므로 이전에 설치된 livepatch를 고려할 필요는 없습니다.

`post_unpatch()`는 `pre_patch()`의 대칭 작업이지만 transition reverse 중에도 호출될 수 있습니다. 따라서 이전에 설치된 livepatch의 state를 반드시 처리해야 합니다.

Callback 책임 분담
Callback주요 역할실패·이전 state 고려
`pre_patch()``state->data` 할당·초기화, 사전 준비적재 중단 가능, 오류 시 자체 정리
`post_patch()`이전 data 인계, 실제 state 변경, old data 해제호환되는 이전 patch 고려
`pre_unpatch()`새 code 의존 차단, state 변경 취소Disable에서만 호출, 이전 patch 고려 불필요
`post_unpatch()`Reverse·disable 구별, 이전 state 복원, data 정리`klp_get_prev_state()`로 이전 patch 고려

준비·적용·차단·복원 단계를 callback별로 분리합니다.

Callback 실행과 state 소유권
`pre_patch()`: data 확보와 준비Task transition 진행`post_patch()`: 실제 state 적용과 이전 data 인계Disable 시 `pre_unpatch()`: 새 code 의존 차단과 변경 취소`post_unpatch()`: 이전 또는 원래 state 복원남은 setting과 `state->data` 정리

Transition 전후에 data와 실제 system state의 소유권이 이동합니다.

4. Expected usage
=================

System states are usually modified by livepatch callbacks. The expected
role of each callback is as follows:

*pre_patch()*

  - Allocate *state->data* when necessary. The allocation might fail
    and *pre_patch()* is the only callback that could stop loading
    of the livepatch. The allocation is not needed when the data
    are already provided by previously installed livepatches.

  - Do any other preparatory action that is needed by
    the new code even before the transition gets finished.
    For example, initialize *state->data*.

    The system state itself is typically modified in *post_patch()*
    when the entire system is able to handle it.

  - Clean up its own mess in case of error. It might be done by a custom
    code or by calling *post_unpatch()* explicitly.

*post_patch()*

  - Copy *state->data* from the previous livepatch when they are
    compatible.

  - Do the actual system state modification. Eventually allow
    the new code to use it.

  - Make sure that *state->data* has all necessary information.

  - Free *state->data* from replaces livepatches when they are
    not longer needed.

*pre_unpatch()*

  - Prevent the code, added by the livepatch, relying on the system
    state change.

  - Revert the system state modification..

*post_unpatch()*

  - Distinguish transition reverse and livepatch disabling by
    checking *klp_get_prev_state()*.

  - In case of transition reverse, restore the previous system
    state. It might mean doing nothing.

  - Remove any not longer needed setting or data.

.. note::

   *pre_unpatch()* typically does symmetric operations to *post_patch()*.
   Except that it is called only when the livepatch is being disabled.
   Therefore it does not need to care about any previously installed
   livepatch.

   *post_unpatch()* typically does symmetric operations to *pre_patch()*.
   It might be called also during the transition reverse. Therefore it
   has to handle the state of the previously installed livepatches.