1 -- $Id: 400_select_subparts.lua,v 1.24 2005/03/29 13:12:43 den Exp $
3 local expert_mode = false
5 local datasets_list = nil
7 local fillout_missing_expert_values = function()
10 for i in datasets_list do
11 local dataset = datasets_list[i]
13 if not dataset.softupdates and
14 not dataset.fsize and not dataset.bsize then
15 if dataset.mountpoint == "/" then
16 dataset.softupdates = "N"
18 dataset.softupdates = "Y"
21 size = StorageDescriptor.parse_capstring(dataset.capstring, -1)
22 if size and size < (1024 * 1024 * 1024) then
23 dataset.fsize = "1024"
24 dataset.bsize = "8192"
26 dataset.fsize = "2048"
27 dataset.bsize = "16384"
33 local warn_subpartition_selections = function(pd)
35 local consequences = ""
37 if not pd:get_subpart_by_mountpoint("/var") then
38 omit = omit .. "/var "
39 consequences = consequences ..
40 _("%s will be a plain dir in %s\n", "/var", "/")
43 if not pd:get_subpart_by_mountpoint("/usr") then
44 omit = omit .. "/usr "
45 consequences = consequences ..
46 _("%s will be a plain dir in %s\n", "/usr", "/")
49 if not pd:get_subpart_by_mountpoint("/tmp") then
50 omit = omit .. "/tmp "
51 consequences = consequences ..
52 _("%s will be symlinked to %s\n", "/tmp", "/var/tmp")
55 if not pd:get_subpart_by_mountpoint("/home") then
56 omit = omit .. "/home "
57 consequences = consequences ..
58 _("%s will be symlinked to %s\n", "/home", "/usr/home")
61 if string.len(omit) > 0 then
64 choices[_("Omit Subpartition(s)")] = true
65 choices[_("Return to Create Subpartitions")] = false
67 return App.ui:select(_(
68 "You have elected to not have the following " ..
69 "subpartition(s):\n\n%s\n\n" ..
70 "The ramifications of these subpartition(s) being " ..
71 "missing will be:\n\n%s\n" ..
72 "Is this really what you want to do?",
73 omit, consequences), choices)
79 local validate_subpart_descriptors = function(pd)
81 local part_size = pd:get_size()
85 -- XXX this should come from a config file.
91 min_size[k] = StorageDescriptor.parse_capstring(v, 0) or 0
95 -- If the user didn't select a /usr partition, / is going to
96 -- have to hold all that stuff - so make sure it's big enough.
98 if not pd:get_subpart_by_mountpoint("/usr") then
99 min_size["/"] = min_size["/"] + min_size["/usr"]
102 for spd in pd:get_subparts() do
103 local spd_size = spd:get_size()
104 local mtpt = spd:get_mountpoint()
105 local min_mt_size = min_size[mtpt]
107 used_size = used_size + spd_size
109 if min_mt_size and spd_size < min_mt_size then
110 if not App.ui:confirm(_(
111 "WARNING: the %s subpartition should " ..
112 "be at least %s in size or you will " ..
113 "risk running out of space during " ..
114 "the installation.\n\n" ..
117 StorageDescriptor.format_capstring(min_mt_size))) then
123 if used_size > part_size then
124 if not App.ui:confirm(_(
125 "WARNING: The total number of sectors needed " ..
126 "for the requested subpartitions (%d) exceeds the " ..
127 "number of sectors available in the partition (%d) " ..
128 "by %d sectors (%s.)\n\n" ..
129 "This is an invalid configuration; we " ..
130 "recommend shrinking the size of one or " ..
131 "more subpartitions before proceeding.\n\n" ..
133 used_size, part_size, used_size - part_size,
134 StorageDescriptor.format_capstring(used_size - part_size))) then
139 if used_size < part_size - App.state.max_waste then
140 if not App.ui:confirm(_(
141 "Note: the total capacity required " ..
142 "for the requested subpartitions (%s) does not make " ..
143 "full use of the capacity available in the " ..
144 "partition (%s.) %d sectors (%s) of space will go " ..
146 "You may wish to expand one or more subpartitions " ..
147 "before proceeding.\n\n" ..
149 StorageDescriptor.format_capstring(used_size),
150 StorageDescriptor.format_capstring(part_size),
151 part_size - used_size,
152 StorageDescriptor.format_capstring(part_size - used_size))) then
157 if App.option.enable_crashdumps then
158 local num_swap_subparts = 0
159 local num_dumponable = 0
161 for spd in pd:get_subparts() do
162 if spd:is_swap() then
163 num_swap_subparts = num_swap_subparts + 1
164 if spd:get_capacity() >= App.state.store:get_ram() then
165 num_dumponable = num_dumponable + 1
170 if num_swap_subparts > 0 and num_dumponable == 0 then
171 if not App.ui:confirm(_(
172 "Note: none of the swap subpartitions that " ..
173 "you have selected are large enough to hold " ..
174 "the contents of memory, and thus cannot be " ..
175 "used to hold a crash dump (an image of the " ..
176 "computers' memory at the time of failure.) " ..
177 "Because this complicates troubleshooting, " ..
178 "we recommend that you increase the size of " ..
179 "one of your swap subpartitions.\n\n" ..
187 return warn_subpartition_selections(pd)
191 -- Take a list of tables representing the user's choices and
192 -- create a matching set of subpartition descriptors under
193 -- the given partition description from them. In the process,
194 -- the desired subpartitions are checked for validity.
196 local create_subpart_descriptors = function(pd, list)
197 local i, letter, dataset
198 local size, offset, fstype
200 local wildcard_size = false
205 for i, dataset in list do
206 if dataset.capstring == "*" then
207 if wildcard_size then
209 "Only one subpartition may have " ..
216 size = StorageDescriptor.parse_capstring(dataset.capstring, 0)
219 "Capacity must either end in 'M' " ..
220 "for megabytes, 'G' for gigabytes, " ..
221 "or be '*' to indicate 'use all " ..
226 total_size = total_size + size
230 for i, letter in ipairs({"a", "b", "d", "e", "f", "g", "h", "i",
231 "j", "k", "l", "m", "n", "o", "p" }) do
232 if i > table.getn(list) then break end
235 size = StorageDescriptor.parse_capstring(dataset.capstring,
236 pd:get_size() - total_size)
238 if dataset.mountpoint == "swap" then
244 pd:add_subpart(SubpartitionDescriptor.new{
250 fsize = tonumber(dataset.fsize),
251 bsize = tonumber(dataset.bsize),
252 mountpoint = dataset.mountpoint
255 offset = offset + size
258 return validate_subpart_descriptors(pd)
262 name = "select_subparts",
263 title = "Select Subpartitions",
264 action = function(fsm)
266 local part_actions = {}
269 if not datasets_list then
270 datasets_list = App.load_conf("mountpoints")(
271 App.state.sel_part:get_capacity(),
272 App.state.storage:get_ram()
276 local fields_list = {
279 name = _("Mountpoint")
287 local actions_list = {
290 name = _("Accept and Create"),
297 name = _("Return to %s", fsm:prev().title),
305 table.insert(fields_list,
308 name = _("Softupdates?"),
312 table.insert(fields_list,
315 name = _("Frag Size")
318 table.insert(fields_list,
321 name = _("Block Size")
325 table.insert(actions_list,
328 name = _("Switch to Normal Mode"),
330 expert_mode = not expert_mode
336 table.insert(actions_list,
339 name = _("Switch to Expert Mode"),
341 expert_mode = not expert_mode
348 local response = App.ui:present({
349 id = "select_subpartitions",
350 name = _("Select Subpartitions"),
351 short_desc = _("Set up the subpartitions (also known " ..
352 "as just `partitions' in BSD tradition) you want to " ..
353 "have on this primary partition.\n\n" ..
354 "For Capacity, use 'M' to indicate megabytes, 'G' to " ..
355 "indicate gigabytes, or a single '*' to indicate " ..
356 "'use the remaining space on the primary partition'."),
357 long_desc = _("Subpartitions further divide a primary partition for " ..
358 "use with %s. Some reasons you may want " ..
359 "a set of subpartitions are:\n\n" ..
360 "- you want to restrict how much data can be written " ..
361 "to certain parts of the primary partition, to quell " ..
362 "denial-of-service attacks; and\n" ..
363 "- you want to speed up access to data on the disk.",
365 special = "bsdinstaller_create_subpartitions",
366 minimum_width = "64",
368 actions = actions_list,
369 fields = fields_list,
370 datasets = datasets_list,
376 -- remember these subpartition selections in case we come back here.
377 datasets_list = response.datasets
378 fillout_missing_expert_values()
380 if response.action_id == "ok" then
381 if create_subpart_descriptors(App.state.sel_part, datasets_list) then
382 local cmds = CmdChain.new()
384 App.state.sel_part:cmds_disklabel(cmds)
391 return response.result