9
9
BootContent ,
10
10
KernelCmdline ,
11
11
KernelCmdlineArg ,
12
+ LateTargetKernelCmdlineArgTasks ,
12
13
LiveImagePreparationInfo ,
13
14
LiveModeArtifacts ,
14
15
LiveModeConfig ,
15
- TargetKernelCmdlineArgTasks
16
+ TargetKernelCmdlineArgTasks ,
17
+ UpgradeKernelCmdlineArgTasks
16
18
)
17
19
18
20
19
- def collect_boot_args (livemode_enabled ):
21
+ def collect_upgrade_kernel_args (livemode_enabled ):
20
22
args = {
21
23
'enforcing' : '0' ,
22
24
'rd.plymouth' : '0' ,
@@ -34,7 +36,10 @@ def collect_boot_args(livemode_enabled):
34
36
livemode_args = construct_cmdline_args_for_livemode ()
35
37
args .update (livemode_args )
36
38
37
- return args
39
+ upgrade_kernel_args = collect_set_of_kernel_args_from_msgs (UpgradeKernelCmdlineArgTasks , 'to_add' )
40
+ args .update (upgrade_kernel_args )
41
+
42
+ return set (args .items ())
38
43
39
44
40
45
def collect_undesired_args (livemode_enabled ):
@@ -43,11 +48,11 @@ def collect_undesired_args(livemode_enabled):
43
48
args = dict (zip (('ro' , 'rhgb' , 'quiet' ), itertools .repeat (None )))
44
49
args ['rd.lvm.lv' ] = _get_rdlvm_arg_values ()
45
50
46
- return args
51
+ return set ( args . items ())
47
52
48
53
49
- def format_grubby_args_from_args_dict (args_dict ):
50
- """ Format the given args dictionary in a form required by grubby's --args. """
54
+ def format_grubby_args_from_args_set (args_dict ):
55
+ """ Format the given args set in a form required by grubby's --args. """
51
56
52
57
def fmt_single_arg (arg_pair ):
53
58
key , value = arg_pair
@@ -65,7 +70,7 @@ def flatten_arguments(arg_pair):
65
70
else :
66
71
yield (key , value ) # Just a single (key, value) pair
67
72
68
- arg_sequence = itertools .chain (* (flatten_arguments (arg_pair ) for arg_pair in args_dict . items () ))
73
+ arg_sequence = itertools .chain (* (flatten_arguments (arg_pair ) for arg_pair in args_dict ))
69
74
70
75
# Sorting should be fine as only values can be None, but we cannot have a (key, None) and (key, value) in
71
76
# the dictionary at the same time.
@@ -78,7 +83,7 @@ def flatten_arguments(arg_pair):
78
83
def figure_out_commands_needed_to_add_entry (kernel_path , initramfs_path , args_to_add , args_to_remove ):
79
84
boot_entry_modification_commands = []
80
85
81
- args_to_add_str = format_grubby_args_from_args_dict (args_to_add )
86
+ args_to_add_str = format_grubby_args_from_args_set (args_to_add )
82
87
83
88
create_entry_cmd = [
84
89
'/usr/sbin/grubby' ,
@@ -93,7 +98,7 @@ def figure_out_commands_needed_to_add_entry(kernel_path, initramfs_path, args_to
93
98
94
99
# We need to update root= param separately, since we cannot do it during --add-kernel with --copy-default.
95
100
# This is likely a bug in grubby.
96
- root_param_value = args_to_add .get ('root' , None )
101
+ root_param_value = dict ( args_to_add ) .get ('root' , None )
97
102
if root_param_value :
98
103
enforce_root_param_for_the_entry_cmd = [
99
104
'/usr/sbin/grubby' ,
@@ -103,7 +108,7 @@ def figure_out_commands_needed_to_add_entry(kernel_path, initramfs_path, args_to
103
108
boot_entry_modification_commands .append (enforce_root_param_for_the_entry_cmd )
104
109
105
110
if args_to_remove :
106
- args_to_remove_str = format_grubby_args_from_args_dict (args_to_remove )
111
+ args_to_remove_str = format_grubby_args_from_args_set (args_to_remove )
107
112
remove_undesired_args_cmd = [
108
113
'/usr/sbin/grubby' ,
109
114
'--update-kernel' , kernel_path ,
@@ -113,18 +118,55 @@ def figure_out_commands_needed_to_add_entry(kernel_path, initramfs_path, args_to
113
118
return boot_entry_modification_commands
114
119
115
120
121
+ def collect_set_of_kernel_args_from_msgs (msg_type , arg_list_field_name ):
122
+ cmdline_modification_msgs = api .consume (msg_type )
123
+ lists_of_args_to_add = (getattr (msg , arg_list_field_name , []) for msg in cmdline_modification_msgs )
124
+ args = itertools .chain (* lists_of_args_to_add )
125
+ return set ((arg .key , arg .value ) for arg in args )
126
+
127
+
128
+ def emit_removal_of_args_meant_only_for_upgrade_kernel (added_upgrade_kernel_args ):
129
+ """
130
+ Emit message requesting removal of upgrade kernel args that should not be on the target kernel.
131
+
132
+ Target kernel args are created by copying the args of the booted (upgrade) kernel. Therefore,
133
+ we need to explicitly modify the target kernel cmdline, removing what should not have been copied.
134
+ """
135
+ target_args_to_add = collect_set_of_kernel_args_from_msgs (TargetKernelCmdlineArgTasks , 'to_add' )
136
+ actual_kernel_args = collect_set_of_kernel_args_from_msgs (KernelCmdline , 'parameters' )
137
+
138
+ # actual_kernel_args should not be changed during upgrade, unless explicitly removed by
139
+ # TargetKernelCmdlineArgTasks.to_remove, but that is handled by some other upgrade component. We just want
140
+ # to make sure we remove what was not on the source system and that we don't overwrite args to be added to target.
141
+ args_not_present_on_target_kernel = added_upgrade_kernel_args - actual_kernel_args - target_args_to_add
142
+
143
+ # We remove only what we've added and what will not be already removed by someone else.
144
+ args_to_remove = [KernelCmdlineArg (key = arg [0 ], value = arg [1 ]) for arg in args_not_present_on_target_kernel ]
145
+
146
+ if args_to_remove :
147
+ msg = ('Following upgrade kernel args were added, but they should not be present '
148
+ 'on target cmdline: `%s`, requesting removal.' )
149
+ api .current_logger ().info (msg , args_not_present_on_target_kernel )
150
+ args_sorted = sorted (args_to_remove , key = lambda arg : arg .key )
151
+ api .produce (LateTargetKernelCmdlineArgTasks (to_remove = args_sorted ))
152
+
153
+
116
154
def add_boot_entry (configs = None ):
117
155
kernel_dst_path , initram_dst_path = get_boot_file_paths ()
156
+
118
157
_remove_old_upgrade_boot_entry (kernel_dst_path , configs = configs )
119
158
120
159
livemode_enabled = next (api .consume (LiveImagePreparationInfo ), None ) is not None
121
160
122
- cmdline_args = collect_boot_args (livemode_enabled )
161
+ # We have to keep the desired and unwanted args separate and modify cmline in two separate grubby calls. Merging
162
+ # these sets and trying to execute only a single command would leave the unwanted cmdline args present if they
163
+ # are present on the original system.
164
+ added_cmdline_args = collect_upgrade_kernel_args (livemode_enabled )
123
165
undesired_cmdline_args = collect_undesired_args (livemode_enabled )
124
166
125
167
commands_to_run = figure_out_commands_needed_to_add_entry (kernel_dst_path ,
126
168
initram_dst_path ,
127
- args_to_add = cmdline_args ,
169
+ args_to_add = added_cmdline_args ,
128
170
args_to_remove = undesired_cmdline_args )
129
171
130
172
def run_commands_adding_entry (extra_command_suffix = None ):
@@ -146,16 +188,8 @@ def run_commands_adding_entry(extra_command_suffix=None):
146
188
# See https://bugzilla.redhat.com/show_bug.cgi?id=1764306
147
189
run (['/usr/sbin/zipl' ])
148
190
149
- if 'debug' in cmdline_args :
150
- # The kernelopts for target kernel are generated based on the cmdline used in the upgrade initramfs,
151
- # therefore, if we enabled debug above, and the original system did not have the debug kernelopt, we
152
- # need to explicitly remove it from the target os boot entry.
153
- # NOTE(mhecko): This will also unconditionally remove debug kernelopt if the source system used it.
154
- api .produce (TargetKernelCmdlineArgTasks (to_remove = [KernelCmdlineArg (key = 'debug' )]))
155
-
156
- # NOTE(mmatuska): This will remove the option even if the source system had it set.
157
- # However enforcing=0 shouldn't be set persistently anyway.
158
- api .produce (TargetKernelCmdlineArgTasks (to_remove = [KernelCmdlineArg (key = 'enforcing' , value = '0' )]))
191
+ effective_upgrade_kernel_args = added_cmdline_args - undesired_cmdline_args
192
+ emit_removal_of_args_meant_only_for_upgrade_kernel (effective_upgrade_kernel_args )
159
193
160
194
except CalledProcessError as e :
161
195
raise StopActorExecutionError (
0 commit comments