| @@ -1,1000 +1,1000 @@ | | | @@ -1,1000 +1,1000 @@ |
1 | /* $NetBSD: partman.c,v 1.51 2021/01/31 22:45:46 rillig Exp $ */ | | 1 | /* $NetBSD: partman.c,v 1.52 2021/07/17 11:32:50 martin Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright 2012 Eugene Lozovoy | | 4 | * Copyright 2012 Eugene Lozovoy |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
15 | * 3. The name of Eugene Lozovoy may not be used to endorse | | 15 | * 3. The name of Eugene Lozovoy may not be used to endorse |
16 | * or promote products derived from this software without specific prior | | 16 | * or promote products derived from this software without specific prior |
17 | * written permission. | | 17 | * written permission. |
18 | * | | 18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS'' | | 19 | * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS'' |
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
22 | * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE | | 22 | * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE |
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
29 | * THE POSSIBILITY OF SUCH DAMAGE. | | 29 | * THE POSSIBILITY OF SUCH DAMAGE. |
30 | * | | 30 | * |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | /* | | 33 | /* |
34 | * Copyright 2010 The NetBSD Foundation, Inc. | | 34 | * Copyright 2010 The NetBSD Foundation, Inc. |
35 | * All rights reserved. | | 35 | * All rights reserved. |
36 | * | | 36 | * |
37 | * Redistribution and use in source and binary forms, with or without | | 37 | * Redistribution and use in source and binary forms, with or without |
38 | * modification, are permitted provided that the following conditions | | 38 | * modification, are permitted provided that the following conditions |
39 | * are met: | | 39 | * are met: |
40 | * 1. Redistributions of source code must retain the above copyright | | 40 | * 1. Redistributions of source code must retain the above copyright |
41 | * notice, this list of conditions and the following disclaimer. | | 41 | * notice, this list of conditions and the following disclaimer. |
42 | * 2. Redistributions in binary form must reproduce the above copyright | | 42 | * 2. Redistributions in binary form must reproduce the above copyright |
43 | * notice, this list of conditions and the following disclaimer in the | | 43 | * notice, this list of conditions and the following disclaimer in the |
44 | * documentation and/or other materials provided with the distribution. | | 44 | * documentation and/or other materials provided with the distribution. |
45 | * | | 45 | * |
46 | * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS'' | | 46 | * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS'' |
47 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 47 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
48 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 48 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
49 | * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE | | 49 | * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE |
50 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 50 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
51 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 51 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
52 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 52 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
53 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 53 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
54 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 54 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
55 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | 55 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
56 | * THE POSSIBILITY OF SUCH DAMAGE. | | 56 | * THE POSSIBILITY OF SUCH DAMAGE. |
57 | * | | 57 | * |
58 | */ | | 58 | */ |
59 | | | 59 | |
60 | /* partman.c - extended partitioning */ | | 60 | /* partman.c - extended partitioning */ |
61 | | | 61 | |
62 | #include <assert.h> | | 62 | #include <assert.h> |
63 | #include <fcntl.h> | | 63 | #include <fcntl.h> |
64 | #include <errno.h> | | 64 | #include <errno.h> |
65 | #include <libgen.h> | | 65 | #include <libgen.h> |
66 | #include <paths.h> | | 66 | #include <paths.h> |
67 | #include <stdio.h> | | 67 | #include <stdio.h> |
68 | #include <stdlib.h> | | 68 | #include <stdlib.h> |
69 | #include <unistd.h> | | 69 | #include <unistd.h> |
70 | #include <util.h> | | 70 | #include <util.h> |
71 | | | 71 | |
72 | #include "defs.h" | | 72 | #include "defs.h" |
73 | #include "msg_defs.h" | | 73 | #include "msg_defs.h" |
74 | #include "menu_defs.h" | | 74 | #include "menu_defs.h" |
75 | | | 75 | |
76 | /* XXX: replace all MAX_* defines with vars that depend on kernel settings */ | | 76 | /* XXX: replace all MAX_* defines with vars that depend on kernel settings */ |
77 | #define MAX_ENTRIES 96 | | 77 | #define MAX_ENTRIES 96 |
78 | | | 78 | |
79 | #define MAX_RAID 8 | | 79 | #define MAX_RAID 8 |
80 | #define MAX_IN_RAID 48 | | 80 | #define MAX_IN_RAID 48 |
81 | struct raid_comp { | | 81 | struct raid_comp { |
82 | char name[SSTRSIZE]; /* display name for this component */ | | 82 | char name[SSTRSIZE]; /* display name for this component */ |
83 | struct disk_partitions *parts; /* where is this on? */ | | 83 | struct disk_partitions *parts; /* where is this on? */ |
84 | part_id id; /* which partition in parts */ | | 84 | part_id id; /* which partition in parts */ |
85 | bool is_spare; /* is this a spare component? */ | | 85 | bool is_spare; /* is this a spare component? */ |
86 | }; | | 86 | }; |
87 | struct raid_desc { | | 87 | struct raid_desc { |
88 | int enabled; | | 88 | int enabled; |
89 | int blocked; | | 89 | int blocked; |
90 | int node; /* the N in raid${N} */ | | 90 | int node; /* the N in raid${N} */ |
91 | int numRow, numCol, numSpare; | | 91 | int numRow, numCol, numSpare; |
92 | int sectPerSU, SUsPerParityUnit, SUsPerReconUnit, raid_level; | | 92 | int sectPerSU, SUsPerParityUnit, SUsPerReconUnit, raid_level; |
93 | daddr_t total_size; | | 93 | daddr_t total_size; |
94 | struct raid_comp comp[MAX_IN_RAID]; | | 94 | struct raid_comp comp[MAX_IN_RAID]; |
95 | }; | | 95 | }; |
96 | struct raid_desc *raids; | | 96 | struct raid_desc *raids; |
97 | | | 97 | |
98 | #define MAX_VND 4 | | 98 | #define MAX_VND 4 |
99 | struct vnd_desc { | | 99 | struct vnd_desc { |
100 | int enabled; | | 100 | int enabled; |
101 | int blocked; | | 101 | int blocked; |
102 | int node; /* the N in vnd${N} */ | | 102 | int node; /* the N in vnd${N} */ |
103 | char filepath[STRSIZE]; | | 103 | char filepath[STRSIZE]; |
104 | daddr_t size; | | 104 | daddr_t size; |
105 | int readonly; | | 105 | int readonly; |
106 | int is_exist; | | 106 | int is_exist; |
107 | int manual_geom; | | 107 | int manual_geom; |
108 | int secsize, nsectors, ntracks, ncylinders; | | 108 | int secsize, nsectors, ntracks, ncylinders; |
109 | struct pm_devs *pm; /* device this is on */ | | 109 | struct pm_devs *pm; /* device this is on */ |
110 | part_id pm_part; /* which partition (in pm->parts) */ | | 110 | part_id pm_part; /* which partition (in pm->parts) */ |
111 | }; | | 111 | }; |
112 | struct vnd_desc *vnds; | | 112 | struct vnd_desc *vnds; |
113 | | | 113 | |
114 | #define MAX_CGD 4 | | 114 | #define MAX_CGD 4 |
115 | struct cgd_desc { | | 115 | struct cgd_desc { |
116 | int enabled; | | 116 | int enabled; |
117 | int blocked; | | 117 | int blocked; |
118 | int node; /* the N in cgd${N} */ | | 118 | int node; /* the N in cgd${N} */ |
119 | char pm_name[SSTRSIZE]; | | 119 | char pm_name[SSTRSIZE]; |
120 | const char *keygen_type; | | 120 | const char *keygen_type; |
121 | const char *verify_type; | | 121 | const char *verify_type; |
122 | const char *enc_type; | | 122 | const char *enc_type; |
123 | const char *iv_type; | | 123 | const char *iv_type; |
124 | int key_size; | | 124 | int key_size; |
125 | struct pm_devs *pm; /* device this is on */ | | 125 | struct pm_devs *pm; /* device this is on */ |
126 | part_id pm_part; /* which partition (in pm->parts) */ | | 126 | part_id pm_part; /* which partition (in pm->parts) */ |
127 | }; | | 127 | }; |
128 | struct cgd_desc *cgds; | | 128 | struct cgd_desc *cgds; |
129 | | | 129 | |
130 | #define MAX_LVM_VG 16 | | 130 | #define MAX_LVM_VG 16 |
131 | #define MAX_LVM_PV 255 | | 131 | #define MAX_LVM_PV 255 |
132 | #define MAX_LVM_LV 255 | | 132 | #define MAX_LVM_LV 255 |
133 | | | 133 | |
134 | struct lvm_pv_reg { | | 134 | struct lvm_pv_reg { |
135 | struct pm_devs *pm; | | 135 | struct pm_devs *pm; |
136 | daddr_t start; | | 136 | daddr_t start; |
137 | }; | | 137 | }; |
138 | struct lvm_pv_reg lvm_pvs[MAX_LVM_PV]; /* XXX - make dynamic */ | | 138 | struct lvm_pv_reg lvm_pvs[MAX_LVM_PV]; /* XXX - make dynamic */ |
139 | | | 139 | |
140 | typedef struct pv_t { | | 140 | typedef struct pv_t { |
141 | struct pm_devs *pm; | | 141 | struct pm_devs *pm; |
142 | char pm_name[SSTRSIZE]; | | 142 | char pm_name[SSTRSIZE]; |
143 | part_id pm_part; | | 143 | part_id pm_part; |
144 | int metadatasize; | | 144 | int metadatasize; |
145 | int metadatacopies; | | 145 | int metadatacopies; |
146 | int labelsector; | | 146 | int labelsector; |
147 | int setphysicalvolumesize; | | 147 | int setphysicalvolumesize; |
148 | } pv_t; | | 148 | } pv_t; |
149 | typedef struct lv_t { | | 149 | typedef struct lv_t { |
150 | int blocked; | | 150 | int blocked; |
151 | daddr_t size; | | 151 | daddr_t size; |
152 | char name[SSTRSIZE]; | | 152 | char name[SSTRSIZE]; |
153 | int readonly; | | 153 | int readonly; |
154 | int contiguous; | | 154 | int contiguous; |
155 | char extents[SSTRSIZE]; | | 155 | char extents[SSTRSIZE]; |
156 | int minor; | | 156 | int minor; |
157 | int mirrors; | | 157 | int mirrors; |
158 | int regionsize; | | 158 | int regionsize; |
159 | int persistent; | | 159 | int persistent; |
160 | int readahead; | | 160 | int readahead; |
161 | int stripes; | | 161 | int stripes; |
162 | int stripesize; | | 162 | int stripesize; |
163 | int zero; | | 163 | int zero; |
164 | } lv_t; | | 164 | } lv_t; |
165 | typedef struct lvms_t { | | 165 | typedef struct lvms_t { |
166 | int enabled; | | 166 | int enabled; |
167 | int blocked; | | 167 | int blocked; |
168 | char name[SSTRSIZE]; | | 168 | char name[SSTRSIZE]; |
169 | int maxlogicalvolumes; | | 169 | int maxlogicalvolumes; |
170 | int maxphysicalvolumes; | | 170 | int maxphysicalvolumes; |
171 | int physicalextentsize; | | 171 | int physicalextentsize; |
172 | daddr_t total_size; | | 172 | daddr_t total_size; |
173 | pv_t pv[MAX_LVM_PV]; | | 173 | pv_t pv[MAX_LVM_PV]; |
174 | lv_t lv[MAX_LVM_LV]; | | 174 | lv_t lv[MAX_LVM_LV]; |
175 | } lvms_t; | | 175 | } lvms_t; |
176 | lvms_t *lvms; | | 176 | lvms_t *lvms; |
177 | | | 177 | |
178 | typedef struct structinfo_t { | | 178 | typedef struct structinfo_t { |
179 | int max; | | 179 | int max; |
180 | uint entry_size; | | 180 | uint entry_size; |
181 | uint parent_size; | | 181 | uint parent_size; |
182 | void *entry_first; | | 182 | void *entry_first; |
183 | void *entry_enabled; | | 183 | void *entry_enabled; |
184 | void *entry_blocked; | | 184 | void *entry_blocked; |
185 | void *entry_node; | | 185 | void *entry_node; |
186 | } structinfo_t; | | 186 | } structinfo_t; |
187 | structinfo_t raids_t_info, vnds_t_info, cgds_t_info, lvms_t_info, lv_t_info; | | 187 | structinfo_t raids_t_info, vnds_t_info, cgds_t_info, lvms_t_info, lv_t_info; |
188 | | | 188 | |
189 | typedef struct pm_upddevlist_adv_t { | | 189 | typedef struct pm_upddevlist_adv_t { |
190 | const char *create_msg; | | 190 | const char *create_msg; |
191 | int pe_type; | | 191 | int pe_type; |
192 | structinfo_t *s; | | 192 | structinfo_t *s; |
193 | int sub_num; | | 193 | int sub_num; |
194 | struct pm_upddevlist_adv_t *sub; | | 194 | struct pm_upddevlist_adv_t *sub; |
195 | } pm_upddevlist_adv_t; | | 195 | } pm_upddevlist_adv_t; |
196 | | | 196 | |
197 | #define MAX_MNTS 48 | | 197 | #define MAX_MNTS 48 |
198 | struct { | | 198 | struct { |
199 | char dev[STRSIZE]; | | 199 | char dev[STRSIZE]; |
200 | const char *mnt_opts, *on; | | 200 | const char *mnt_opts, *on; |
201 | } *mnts; | | 201 | } *mnts; |
202 | | | 202 | |
203 | static int pm_cursel; /* Number of selected entry in main menu */ | | 203 | static int pm_cursel; /* Number of selected entry in main menu */ |
204 | static int pm_changed; /* flag indicating that we have unsaved changes */ | | 204 | static int pm_changed; /* flag indicating that we have unsaved changes */ |
205 | static int pm_raid_curspare; /* XXX: replace by true way */ | | 205 | static int pm_raid_curspare; /* XXX: replace by true way */ |
206 | static int pm_retvalue; | | 206 | static int pm_retvalue; |
207 | | | 207 | |
208 | enum { /* RAIDframe menu enum */ | | 208 | enum { /* RAIDframe menu enum */ |
209 | PMR_MENU_DEVS, PMR_MENU_DEVSSPARE, PMR_MENU_RAIDLEVEL, PMR_MENU_NUMROW, | | 209 | PMR_MENU_DEVS, PMR_MENU_DEVSSPARE, PMR_MENU_RAIDLEVEL, PMR_MENU_NUMROW, |
210 | PMR_MENU_NUMCOL, PMR_MENU_NUMSPARE, PMR_MENU_SECTPERSU, PMR_MENU_SUSPERPARITYUNIT, | | 210 | PMR_MENU_NUMCOL, PMR_MENU_NUMSPARE, PMR_MENU_SECTPERSU, PMR_MENU_SUSPERPARITYUNIT, |
211 | PMR_MENU_SUSPERRECONUNIT, PMR_MENU_REMOVE, PMR_MENU_END | | 211 | PMR_MENU_SUSPERRECONUNIT, PMR_MENU_REMOVE, PMR_MENU_END |
212 | }; | | 212 | }; |
213 | | | 213 | |
214 | enum { /* VND menu enum */ | | 214 | enum { /* VND menu enum */ |
215 | PMV_MENU_FILEPATH, PMV_MENU_EXIST, PMV_MENU_SIZE, PMV_MENU_RO, PMV_MENU_MGEOM, | | 215 | PMV_MENU_FILEPATH, PMV_MENU_EXIST, PMV_MENU_SIZE, PMV_MENU_RO, PMV_MENU_MGEOM, |
216 | PMV_MENU_SECSIZE, PMV_MENU_NSECTORS, PMV_MENU_NTRACKS, PMV_MENU_NCYLINDERS, | | 216 | PMV_MENU_SECSIZE, PMV_MENU_NSECTORS, PMV_MENU_NTRACKS, PMV_MENU_NCYLINDERS, |
217 | PMV_MENU_REMOVE, PMV_MENU_END | | 217 | PMV_MENU_REMOVE, PMV_MENU_END |
218 | }; | | 218 | }; |
219 | | | 219 | |
220 | enum { /* CGD menu enum */ | | 220 | enum { /* CGD menu enum */ |
221 | PMC_MENU_DEV, PMC_MENU_ENCTYPE, PMC_MENU_KEYSIZE, PMC_MENU_IVTYPE, | | 221 | PMC_MENU_DEV, PMC_MENU_ENCTYPE, PMC_MENU_KEYSIZE, PMC_MENU_IVTYPE, |
222 | PMC_MENU_KEYGENTYPE, PMC_MENU_VERIFYTYPE, PMC_MENU_REMOVE, PMC_MENU_END | | 222 | PMC_MENU_KEYGENTYPE, PMC_MENU_VERIFYTYPE, PMC_MENU_REMOVE, PMC_MENU_END |
223 | }; | | 223 | }; |
224 | | | 224 | |
225 | enum { /* LVM menu enum */ | | 225 | enum { /* LVM menu enum */ |
226 | PML_MENU_PV, PML_MENU_NAME, PML_MENU_MAXLOGICALVOLUMES, | | 226 | PML_MENU_PV, PML_MENU_NAME, PML_MENU_MAXLOGICALVOLUMES, |
227 | PML_MENU_MAXPHYSICALVOLUMES, PML_MENU_PHYSICALEXTENTSIZE, | | 227 | PML_MENU_MAXPHYSICALVOLUMES, PML_MENU_PHYSICALEXTENTSIZE, |
228 | PML_MENU_REMOVE, PML_MENU_END | | 228 | PML_MENU_REMOVE, PML_MENU_END |
229 | }; | | 229 | }; |
230 | | | 230 | |
231 | enum { /* LVM submenu (logical volumes) enum */ | | 231 | enum { /* LVM submenu (logical volumes) enum */ |
232 | PMLV_MENU_NAME, PMLV_MENU_SIZE, PMLV_MENU_READONLY, PMLV_MENU_CONTIGUOUS, | | 232 | PMLV_MENU_NAME, PMLV_MENU_SIZE, PMLV_MENU_READONLY, PMLV_MENU_CONTIGUOUS, |
233 | PMLV_MENU_EXTENTS, PMLV_MENU_MINOR, PMLV_MENU_PERSISTENT, | | 233 | PMLV_MENU_EXTENTS, PMLV_MENU_MINOR, PMLV_MENU_PERSISTENT, |
234 | PMLV_MENU_MIRRORS, PMLV_MENU_REGIONSIZE, PMLV_MENU_READAHEAD, | | 234 | PMLV_MENU_MIRRORS, PMLV_MENU_REGIONSIZE, PMLV_MENU_READAHEAD, |
235 | PMLV_MENU_STRIPES, PMLV_MENU_STRIPESIZE, PMLV_MENU_ZERO, | | 235 | PMLV_MENU_STRIPES, PMLV_MENU_STRIPESIZE, PMLV_MENU_ZERO, |
236 | PMLV_MENU_REMOVE, PMLV_MENU_END | | 236 | PMLV_MENU_REMOVE, PMLV_MENU_END |
237 | }; | | 237 | }; |
238 | | | 238 | |
239 | struct part_entry pm_dev_list(int); | | 239 | struct part_entry pm_dev_list(int); |
240 | static int pm_raid_disk_add(menudesc *, void *); | | 240 | static int pm_raid_disk_add(menudesc *, void *); |
241 | static int pm_raid_disk_del(menudesc *, void *); | | 241 | static int pm_raid_disk_del(menudesc *, void *); |
242 | static int pm_cgd_disk_set(struct cgd_desc *, struct part_entry *); | | 242 | static int pm_cgd_disk_set(struct cgd_desc *, struct part_entry *); |
243 | static int pm_mount(struct pm_devs *, int); | | 243 | static int pm_mount(struct pm_devs *, int); |
244 | static int pm_upddevlist(menudesc *, void *); | | 244 | static int pm_upddevlist(menudesc *, void *); |
245 | static void pm_select(struct pm_devs *); | | 245 | static void pm_select(struct pm_devs *); |
246 | | | 246 | |
247 | static void | | 247 | static void |
248 | pm_edit_size_value(msg prompt_msg, daddr_t bps, daddr_t cylsec, daddr_t *size) | | 248 | pm_edit_size_value(msg prompt_msg, daddr_t bps, daddr_t cylsec, daddr_t *size) |
249 | { | | 249 | { |
250 | | | 250 | |
251 | char answer[16], dflt[16]; | | 251 | char answer[16], dflt[16]; |
252 | daddr_t new_size_val, mult; | | 252 | daddr_t new_size_val, mult; |
253 | | | 253 | |
254 | snprintf(dflt, sizeof dflt, "%" PRIu64 "%s", *size / sizemult, | | 254 | snprintf(dflt, sizeof dflt, "%" PRIu64 "%s", *size / sizemult, |
255 | multname); | | 255 | multname); |
256 | | | 256 | |
257 | msg_prompt_win(prompt_msg, -1, 18, 0, 0, dflt, answer, sizeof answer); | | 257 | msg_prompt_win(prompt_msg, -1, 18, 0, 0, dflt, answer, sizeof answer); |
258 | | | 258 | |
259 | mult = sizemult; | | 259 | mult = sizemult; |
260 | new_size_val = parse_disk_pos(answer, &mult, bps, cylsec, NULL); | | 260 | new_size_val = parse_disk_pos(answer, &mult, bps, cylsec, NULL); |
261 | | | 261 | |
262 | if (new_size_val > 0) | | 262 | if (new_size_val > 0) |
263 | *size = new_size_val * mult; | | 263 | *size = new_size_val * mult; |
264 | } | | 264 | } |
265 | | | 265 | |
266 | static const char * | | 266 | static const char * |
267 | pm_get_mount(struct pm_devs *p, part_id id) | | 267 | pm_get_mount(struct pm_devs *p, part_id id) |
268 | { | | 268 | { |
269 | | | 269 | |
270 | if (p->mounted == NULL) | | 270 | if (p->mounted == NULL) |
271 | return NULL; | | 271 | return NULL; |
272 | if (id >= p->parts->num_part) | | 272 | if (id >= p->parts->num_part) |
273 | return NULL; | | 273 | return NULL; |
274 | return p->mounted[id]; | | 274 | return p->mounted[id]; |
275 | } | | 275 | } |
276 | | | 276 | |
277 | bool pm_set_mount(struct pm_devs *p, part_id id, const char *path); | | 277 | bool pm_set_mount(struct pm_devs *p, part_id id, const char *path); |
278 | | | 278 | |
279 | bool | | 279 | bool |
280 | pm_set_mount(struct pm_devs *p, part_id id, const char *path) | | 280 | pm_set_mount(struct pm_devs *p, part_id id, const char *path) |
281 | { | | 281 | { |
282 | | | 282 | |
283 | if (p->parts == NULL || id >= p->parts->num_part) | | 283 | if (p->parts == NULL || id >= p->parts->num_part) |
284 | return false; | | 284 | return false; |
285 | | | 285 | |
286 | if (p->mounted == NULL) { | | 286 | if (p->mounted == NULL) { |
287 | p->mounted = calloc(p->parts->num_part, sizeof(char*)); | | 287 | p->mounted = calloc(p->parts->num_part, sizeof(char*)); |
288 | if (p->mounted == NULL) | | 288 | if (p->mounted == NULL) |
289 | return false; | | 289 | return false; |
290 | } | | 290 | } |
291 | free(p->mounted[id]); | | 291 | free(p->mounted[id]); |
292 | p->mounted[id] = strdup(path); | | 292 | p->mounted[id] = strdup(path); |
293 | return p->mounted[id] != NULL; | | 293 | return p->mounted[id] != NULL; |
294 | } | | 294 | } |
295 | | | 295 | |
296 | /* Universal menu for RAID/VND/CGD/LVM entry edit */ | | 296 | /* Universal menu for RAID/VND/CGD/LVM entry edit */ |
297 | static int | | 297 | static int |
298 | pm_edit(int menu_entries_count, void (*menu_fmt)(menudesc *, int, void *), | | 298 | pm_edit(int menu_entries_count, void (*menu_fmt)(menudesc *, int, void *), |
299 | int (*action)(menudesc *, void *), int (*check_fun)(void *), | | 299 | int (*action)(menudesc *, void *), int (*check_fun)(void *), |
300 | void (*entry_init)(void *, void *), void *entry_init_arg, | | 300 | void (*entry_init)(void *, void *), void *entry_init_arg, |
301 | void *dev_ptr, int dev_ptr_delta, structinfo_t *s) | | 301 | void *dev_ptr, int dev_ptr_delta, structinfo_t *s) |
302 | { | | 302 | { |
303 | int i, ok = 0; | | 303 | int i, ok = 0; |
304 | menu_ent *menu_entries; | | 304 | menu_ent *menu_entries; |
305 | | | 305 | |
306 | if (dev_ptr == NULL) { | | 306 | if (dev_ptr == NULL) { |
307 | /* We should create new device */ | | 307 | /* We should create new device */ |
308 | for (i = 0; i < s->max && !ok; i++) | | 308 | for (i = 0; i < s->max && !ok; i++) |
309 | if (*(int*)((char*)s->entry_enabled + dev_ptr_delta + s->entry_size * i) == 0) { | | 309 | if (*(int*)((char*)s->entry_enabled + dev_ptr_delta + s->entry_size * i) == 0) { |
310 | dev_ptr = (char*)s->entry_first + dev_ptr_delta + s->entry_size * i; | | 310 | dev_ptr = (char*)s->entry_first + dev_ptr_delta + s->entry_size * i; |
311 | entry_init(dev_ptr, entry_init_arg); | | 311 | entry_init(dev_ptr, entry_init_arg); |
312 | ok = 1; | | 312 | ok = 1; |
313 | } | | 313 | } |
314 | if (!ok) { | | 314 | if (!ok) { |
315 | /* We do not have free device slots */ | | 315 | /* We do not have free device slots */ |
316 | hit_enter_to_continue(NULL, MSG_limitcount); | | 316 | hit_enter_to_continue(NULL, MSG_limitcount); |
317 | return -1; | | 317 | return -1; |
318 | } | | 318 | } |
319 | } | | 319 | } |
320 | | | 320 | |
321 | menu_entries = calloc(menu_entries_count, sizeof *menu_entries); | | 321 | menu_entries = calloc(menu_entries_count, sizeof *menu_entries); |
322 | for (i = 0; i < menu_entries_count - 1; i++) | | 322 | for (i = 0; i < menu_entries_count - 1; i++) |
323 | menu_entries[i] = (menu_ent) { .opt_action=action }; | | 323 | menu_entries[i] = (menu_ent) { .opt_action=action }; |
324 | menu_entries[i] = (menu_ent) { .opt_name=MSG_fremove, | | 324 | menu_entries[i] = (menu_ent) { .opt_name=MSG_fremove, |
325 | .opt_flags=OPT_EXIT, | | 325 | .opt_flags=OPT_EXIT, |
326 | .opt_action=action }; | | 326 | .opt_action=action }; |
327 | | | 327 | |
328 | int menu_no = -1; | | 328 | int menu_no = -1; |
329 | menu_no = new_menu(NULL, menu_entries, menu_entries_count, | | 329 | menu_no = new_menu(NULL, menu_entries, menu_entries_count, |
330 | -1, -1, 0, 40, MC_NOCLEAR | MC_SCROLL, | | 330 | -1, -1, 0, 40, MC_NOCLEAR | MC_SCROLL, |
331 | NULL, menu_fmt, NULL, NULL, MSG_DONE); | | 331 | NULL, menu_fmt, NULL, NULL, MSG_DONE); |
332 | | | 332 | |
333 | process_menu(menu_no, dev_ptr); | | 333 | process_menu(menu_no, dev_ptr); |
334 | free_menu(menu_no); | | 334 | free_menu(menu_no); |
335 | free(menu_entries); | | 335 | free(menu_entries); |
336 | | | 336 | |
337 | return check_fun(dev_ptr); | | 337 | return check_fun(dev_ptr); |
338 | } | | 338 | } |
339 | | | 339 | |
340 | /* Show filtered partitions menu */ | | 340 | /* Show filtered partitions menu */ |
341 | struct part_entry | | 341 | struct part_entry |
342 | pm_dev_list(int type) | | 342 | pm_dev_list(int type) |
343 | { | | 343 | { |
344 | int dev_num = -1, num_devs = 0; | | 344 | int dev_num = -1, num_devs = 0; |
345 | bool ok; | | 345 | bool ok; |
346 | part_id i; | | 346 | part_id i; |
347 | int menu_no; | | 347 | int menu_no; |
348 | struct disk_part_info info; | | 348 | struct disk_part_info info; |
349 | menu_ent menu_entries[MAX_DISKS*MAXPARTITIONS]; | | 349 | menu_ent menu_entries[MAX_DISKS*MAXPARTITIONS]; |
350 | struct part_entry disk_entries[MAX_DISKS*MAXPARTITIONS]; | | 350 | struct part_entry disk_entries[MAX_DISKS*MAXPARTITIONS]; |
351 | struct pm_devs *pm_i; | | 351 | struct pm_devs *pm_i; |
352 | | | 352 | |
353 | SLIST_FOREACH(pm_i, &pm_head, l) { | | 353 | SLIST_FOREACH(pm_i, &pm_head, l) { |
354 | if (pm_i->parts == NULL) | | 354 | if (pm_i->parts == NULL) |
355 | continue; | | 355 | continue; |
356 | for (i = 0; i < pm_i->parts->num_part; i++) { | | 356 | for (i = 0; i < pm_i->parts->num_part; i++) { |
357 | ok = false; | | 357 | ok = false; |
358 | if (!pm_i->parts->pscheme->get_part_info(pm_i->parts, | | 358 | if (!pm_i->parts->pscheme->get_part_info(pm_i->parts, |
359 | i, &info)) | | 359 | i, &info)) |
360 | continue; | | 360 | continue; |
361 | if (info.flags & | | 361 | if (info.flags & |
362 | (PTI_WHOLE_DISK|PTI_PSCHEME_INTERNAL|PTI_RAW_PART)) | | 362 | (PTI_WHOLE_DISK|PTI_PSCHEME_INTERNAL|PTI_RAW_PART)) |
363 | continue; | | 363 | continue; |
364 | switch (type) { | | 364 | switch (type) { |
365 | case PM_RAID: | | 365 | case PM_RAID: |
366 | if (info.fs_type == FS_RAID) | | 366 | if (info.fs_type == FS_RAID) |
367 | ok = 1; | | 367 | ok = 1; |
368 | break; | | 368 | break; |
369 | case PM_CGD: | | 369 | case PM_CGD: |
370 | if (info.fs_type == FS_CGD) | | 370 | if (info.fs_type == FS_CGD) |
371 | ok = 1; | | 371 | ok = 1; |
372 | break; | | 372 | break; |
373 | case PM_LVM: | | 373 | case PM_LVM: |
374 | if (pm_is_lvmpv(pm_i, i, &info)) | | 374 | if (pm_is_lvmpv(pm_i, i, &info)) |
375 | ok = 1; | | 375 | ok = 1; |
376 | break; | | 376 | break; |
377 | } | | 377 | } |
378 | if (!ok) | | 378 | if (!ok) |
379 | continue; | | 379 | continue; |
380 | if (pm_partusage(pm_i, i, 0) != 0) | | 380 | if (pm_partusage(pm_i, i, 0) != 0) |
381 | continue; | | 381 | continue; |
382 | | | 382 | |
383 | disk_entries[num_devs].dev_ptr = pm_i; | | 383 | disk_entries[num_devs].dev_ptr = pm_i; |
384 | disk_entries[num_devs].id = i; | | 384 | disk_entries[num_devs].id = i; |
385 | disk_entries[num_devs].parts = pm_i->parts; | | 385 | disk_entries[num_devs].parts = pm_i->parts; |
386 | | | 386 | |
387 | pm_i->parts->pscheme->get_part_device( | | 387 | pm_i->parts->pscheme->get_part_device( |
388 | pm_i->parts, i, disk_entries[num_devs].fullname, | | 388 | pm_i->parts, i, disk_entries[num_devs].fullname, |
389 | sizeof disk_entries[num_devs].fullname, | | 389 | sizeof disk_entries[num_devs].fullname, |
390 | NULL, plain_name, false, true); | | 390 | NULL, plain_name, false, true); |
391 | | | 391 | |
392 | menu_entries[num_devs] = (struct menu_ent) { | | 392 | menu_entries[num_devs] = (struct menu_ent) { |
393 | .opt_name = disk_entries[num_devs].fullname, | | 393 | .opt_name = disk_entries[num_devs].fullname, |
394 | .opt_action = set_menu_select, | | 394 | .opt_action = set_menu_select, |
395 | .opt_flags = OPT_EXIT, | | 395 | .opt_flags = OPT_EXIT, |
396 | }; | | 396 | }; |
397 | num_devs++; | | 397 | num_devs++; |
398 | } | | 398 | } |
399 | } | | 399 | } |
400 | | | 400 | |
401 | menu_no = new_menu(MSG_avdisks, | | 401 | menu_no = new_menu(MSG_avdisks, |
402 | menu_entries, num_devs, -1, -1, | | 402 | menu_entries, num_devs, -1, -1, |
403 | (num_devs+1<3)?3:num_devs+1, 13, | | 403 | (num_devs+1<3)?3:num_devs+1, 13, |
404 | MC_SCROLL | MC_NOCLEAR, NULL, NULL, NULL, NULL, MSG_cancel); | | 404 | MC_SCROLL | MC_NOCLEAR, NULL, NULL, NULL, NULL, MSG_cancel); |
405 | if (menu_no == -1) | | 405 | if (menu_no == -1) |
406 | return (struct part_entry) { }; | | 406 | return (struct part_entry) { }; |
407 | process_menu(menu_no, &dev_num); | | 407 | process_menu(menu_no, &dev_num); |
408 | free_menu(menu_no); | | 408 | free_menu(menu_no); |
409 | | | 409 | |
410 | if (dev_num < 0 || dev_num >= num_devs) | | 410 | if (dev_num < 0 || dev_num >= num_devs) |
411 | return (struct part_entry) { }; | | 411 | return (struct part_entry) { }; |
412 | | | 412 | |
413 | pm_retvalue = dev_num; | | 413 | pm_retvalue = dev_num; |
414 | return disk_entries[dev_num]; | | 414 | return disk_entries[dev_num]; |
415 | } | | 415 | } |
416 | | | 416 | |
417 | /* Get unused raid*, cgd* or vnd* device */ | | 417 | /* Get unused raid*, cgd* or vnd* device */ |
418 | static int | | 418 | static int |
419 | pm_manage_getfreenode(void *node, const char *d, structinfo_t *s) | | 419 | pm_manage_getfreenode(void *node, const char *d, structinfo_t *s) |
420 | { | | 420 | { |
421 | int i, ii, ok; | | 421 | int i, ii, ok; |
422 | char buf[SSTRSIZE]; | | 422 | char buf[SSTRSIZE]; |
423 | struct pm_devs *pm_i; | | 423 | struct pm_devs *pm_i; |
424 | | | 424 | |
425 | *(int*)node = -1; | | 425 | *(int*)node = -1; |
426 | for (i = 0; i < s->max; i++) { | | 426 | for (i = 0; i < s->max; i++) { |
427 | ok = 1; | | 427 | ok = 1; |
428 | /* Check that node is not already reserved */ | | 428 | /* Check that node is not already reserved */ |
429 | for (ii = 0; ii < s->max; ii++) { | | 429 | for (ii = 0; ii < s->max; ii++) { |
430 | if (*(int*)((char*)s->entry_enabled + s->entry_size | | 430 | if (*(int*)((char*)s->entry_enabled + s->entry_size |
431 | * ii) == 0) | | 431 | * ii) == 0) |
432 | continue; | | 432 | continue; |
433 | if (*(int*)((char*)s->entry_node + s->entry_size * ii) | | 433 | if (*(int*)((char*)s->entry_node + s->entry_size * ii) |
434 | == i) { | | 434 | == i) { |
435 | ok = 0; | | 435 | ok = 0; |
436 | break; | | 436 | break; |
437 | } | | 437 | } |
438 | } | | 438 | } |
439 | if (! ok) | | 439 | if (! ok) |
440 | continue; | | 440 | continue; |
441 | /* Check that node is not in the device list */ | | 441 | /* Check that node is not in the device list */ |
442 | snprintf(buf, SSTRSIZE, "%s%d", d, i); | | 442 | snprintf(buf, SSTRSIZE, "%s%d", d, i); |
443 | SLIST_FOREACH(pm_i, &pm_head, l) | | 443 | SLIST_FOREACH(pm_i, &pm_head, l) |
444 | if (! strcmp(pm_i->diskdev, buf)) { | | 444 | if (! strcmp(pm_i->diskdev, buf)) { |
445 | ok = 0; | | 445 | ok = 0; |
446 | break; | | 446 | break; |
447 | } | | 447 | } |
448 | if (ok) { | | 448 | if (ok) { |
449 | *(int*)node = i; | | 449 | *(int*)node = i; |
450 | return i; | | 450 | return i; |
451 | } | | 451 | } |
452 | } | | 452 | } |
453 | hit_enter_to_continue(NULL, MSG_nofreedev); | | 453 | hit_enter_to_continue(NULL, MSG_nofreedev); |
454 | return -1; | | 454 | return -1; |
455 | } | | 455 | } |
456 | | | 456 | |
457 | /* | | 457 | /* |
458 | * Show a line for a device, usually with full size in the right | | 458 | * Show a line for a device, usually with full size in the right |
459 | * column, alternatively (if != NULL) with no_size_display | | 459 | * column, alternatively (if != NULL) with no_size_display |
460 | * instead in paranthesis (used for error displays or to note | | 460 | * instead in paranthesis (used for error displays or to note |
461 | * a action that can be done to this device. | | 461 | * a action that can be done to this device. |
462 | */ | | 462 | */ |
463 | static void | | 463 | static void |
464 | pm_fmt_disk_line(WINDOW *w, const char *line, const char *on, | | 464 | pm_fmt_disk_line(WINDOW *w, const char *line, const char *on, |
465 | daddr_t total, const char *no_size_display) | | 465 | daddr_t total, const char *no_size_display) |
466 | { | | 466 | { |
467 | char out[STRSIZE], human[6]; | | 467 | char out[STRSIZE], human[6]; |
468 | | | 468 | |
469 | if (on != NULL) { | | 469 | if (on != NULL) { |
470 | snprintf(out, sizeof out, "%s %s %s", line, | | 470 | snprintf(out, sizeof out, "%s %s %s", line, |
471 | msg_string(MSG_pm_menu_on), on); | | 471 | msg_string(MSG_pm_menu_on), on); |
472 | line = out; | | 472 | line = out; |
473 | } | | 473 | } |
474 | if (no_size_display != NULL) { | | 474 | if (no_size_display != NULL) { |
475 | wprintw(w, " %-56s (%s)", line, no_size_display); | | 475 | wprintw(w, " %-56s (%s)", line, no_size_display); |
476 | } else { | | 476 | } else { |
477 | humanize_number(human, sizeof(human), | | 477 | humanize_number(human, sizeof(human), |
478 | total * 512, "", | | 478 | total * 512, "", |
479 | HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); | | 479 | HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); |
480 | wprintw(w, " %-56s %s", line, human); | | 480 | wprintw(w, " %-56s %s", line, human); |
481 | } | | 481 | } |
482 | } | | 482 | } |
483 | | | 483 | |
484 | /*** | | 484 | /*** |
485 | RAIDs | | 485 | RAIDs |
486 | ***/ | | 486 | ***/ |
487 | | | 487 | |
488 | static void | | 488 | static void |
489 | pm_raid_menufmt(menudesc *m, int opt, void *arg) | | 489 | pm_raid_menufmt(menudesc *m, int opt, void *arg) |
490 | { | | 490 | { |
491 | int i, ok = 0; | | 491 | int i, ok = 0; |
492 | char buf[STRSIZE], rdev[STRSIZE], level[STRSIZE], *line; | | 492 | char buf[STRSIZE], rdev[STRSIZE], level[STRSIZE], *line; |
493 | struct raid_desc *dev_ptr = ((struct part_entry *)arg)[opt].dev_ptr; | | 493 | struct raid_desc *dev_ptr = ((struct part_entry *)arg)[opt].dev_ptr; |
494 | | | 494 | |
495 | if (dev_ptr->enabled == 0) | | 495 | if (dev_ptr->enabled == 0) |
496 | return; | | 496 | return; |
497 | buf[0] = '\0'; | | 497 | buf[0] = '\0'; |
498 | sprintf(rdev, "raid%d", dev_ptr->node); | | 498 | sprintf(rdev, "raid%d", dev_ptr->node); |
499 | for (i = 0; i < MAX_IN_RAID; i++) { | | 499 | for (i = 0; i < MAX_IN_RAID; i++) { |
500 | if (dev_ptr->comp[i].parts != NULL) { | | 500 | if (dev_ptr->comp[i].parts != NULL) { |
501 | strlcat(buf, dev_ptr->comp[i].name, sizeof buf); | | 501 | strlcat(buf, dev_ptr->comp[i].name, sizeof buf); |
502 | strlcat(buf, " ", sizeof buf); | | 502 | strlcat(buf, " ", sizeof buf); |
503 | ok = 1; | | 503 | ok = 1; |
504 | } | | 504 | } |
505 | } | | 505 | } |
506 | if (ok) { | | 506 | if (ok) { |
507 | sprintf(level, "%u", dev_ptr->raid_level); | | 507 | sprintf(level, "%u", dev_ptr->raid_level); |
508 | const char *args[] = { rdev, level }; | | 508 | const char *args[] = { rdev, level }; |
509 | line = str_arg_subst(msg_string(MSG_raid_menufmt), | | 509 | line = str_arg_subst(msg_string(MSG_raid_menufmt), |
510 | __arraycount(args), args); | | 510 | __arraycount(args), args); |
511 | pm_fmt_disk_line(m->mw, line, buf, dev_ptr->total_size, NULL); | | 511 | pm_fmt_disk_line(m->mw, line, buf, dev_ptr->total_size, NULL); |
512 | free(line); | | 512 | free(line); |
513 | } else { | | 513 | } else { |
514 | pm_fmt_disk_line(m->mw, buf, NULL, 0, | | 514 | pm_fmt_disk_line(m->mw, buf, NULL, 0, |
515 | msg_string(MSG_raid_err_menufmt)); | | 515 | msg_string(MSG_raid_err_menufmt)); |
516 | } | | 516 | } |
517 | } | | 517 | } |
518 | | | 518 | |
519 | static void | | 519 | static void |
520 | pm_raid_edit_menufmt(menudesc *m, int opt, void *arg) | | 520 | pm_raid_edit_menufmt(menudesc *m, int opt, void *arg) |
521 | { | | 521 | { |
522 | int i; | | 522 | int i; |
523 | char buf[STRSIZE]; | | 523 | char buf[STRSIZE]; |
524 | struct raid_desc *dev_ptr = arg; | | 524 | struct raid_desc *dev_ptr = arg; |
525 | | | 525 | |
526 | buf[0] = '\0'; | | 526 | buf[0] = '\0'; |
527 | switch (opt) { | | 527 | switch (opt) { |
528 | case PMR_MENU_DEVS: | | 528 | case PMR_MENU_DEVS: |
529 | strlcpy(buf, msg_string(MSG_raid_disks_fmt), | | 529 | strlcpy(buf, msg_string(MSG_raid_disks_fmt), |
530 | sizeof buf); | | 530 | sizeof buf); |
531 | strlcat(buf, ": ", sizeof buf); | | 531 | strlcat(buf, ": ", sizeof buf); |
532 | for (i = 0; i < MAX_IN_RAID; i++) { | | 532 | for (i = 0; i < MAX_IN_RAID; i++) { |
533 | if (dev_ptr->comp[i].parts == NULL || | | 533 | if (dev_ptr->comp[i].parts == NULL || |
534 | dev_ptr->comp[i].is_spare) | | 534 | dev_ptr->comp[i].is_spare) |
535 | continue; | | 535 | continue; |
536 | strlcat(buf, " ", sizeof buf); | | 536 | strlcat(buf, " ", sizeof buf); |
537 | strlcat(buf, dev_ptr->comp[i].name, sizeof buf); | | 537 | strlcat(buf, dev_ptr->comp[i].name, sizeof buf); |
538 | } | | 538 | } |
539 | wprintw(m->mw, "%s", buf); | | 539 | wprintw(m->mw, "%s", buf); |
540 | break; | | 540 | break; |
541 | case PMR_MENU_DEVSSPARE: | | 541 | case PMR_MENU_DEVSSPARE: |
542 | strlcpy(buf, msg_string(MSG_raid_spares_fmt), | | 542 | strlcpy(buf, msg_string(MSG_raid_spares_fmt), |
543 | sizeof buf); | | 543 | sizeof buf); |
544 | strlcat(buf, ": ", sizeof buf); | | 544 | strlcat(buf, ": ", sizeof buf); |
545 | for (i = 0; i < MAX_IN_RAID; i++) { | | 545 | for (i = 0; i < MAX_IN_RAID; i++) { |
546 | if (dev_ptr->comp[i].parts == NULL || | | 546 | if (dev_ptr->comp[i].parts == NULL || |
547 | !dev_ptr->comp[i].is_spare) | | 547 | !dev_ptr->comp[i].is_spare) |
548 | continue; | | 548 | continue; |
549 | strlcat(buf, " ", sizeof buf); | | 549 | strlcat(buf, " ", sizeof buf); |
550 | strlcat(buf, dev_ptr->comp[i].name, sizeof buf); | | 550 | strlcat(buf, dev_ptr->comp[i].name, sizeof buf); |
551 | } | | 551 | } |
552 | wprintw(m->mw, "%s", buf); | | 552 | wprintw(m->mw, "%s", buf); |
553 | break; | | 553 | break; |
554 | case PMR_MENU_RAIDLEVEL: | | 554 | case PMR_MENU_RAIDLEVEL: |
555 | wprintw(m->mw, "%s: %u", | | 555 | wprintw(m->mw, "%s: %u", |
556 | msg_string(MSG_raid_level_fmt), | | 556 | msg_string(MSG_raid_level_fmt), |
557 | dev_ptr->raid_level); | | 557 | dev_ptr->raid_level); |
558 | break; | | 558 | break; |
559 | case PMR_MENU_NUMROW: | | 559 | case PMR_MENU_NUMROW: |
560 | wprintw(m->mw, "%s: %u", | | 560 | wprintw(m->mw, "%s: %u", |
561 | msg_string(MSG_raid_numrow_fmt), dev_ptr->numRow); | | 561 | msg_string(MSG_raid_numrow_fmt), dev_ptr->numRow); |
562 | break; | | 562 | break; |
563 | case PMR_MENU_NUMCOL: | | 563 | case PMR_MENU_NUMCOL: |
564 | wprintw(m->mw, "%s: %u", | | 564 | wprintw(m->mw, "%s: %u", |
565 | msg_string(MSG_raid_numcol_fmt), dev_ptr->numCol); | | 565 | msg_string(MSG_raid_numcol_fmt), dev_ptr->numCol); |
566 | break; | | 566 | break; |
567 | case PMR_MENU_NUMSPARE: | | 567 | case PMR_MENU_NUMSPARE: |
568 | wprintw(m->mw, "%s: %u", | | 568 | wprintw(m->mw, "%s: %u", |
569 | msg_string(MSG_raid_numspare_fmt), | | 569 | msg_string(MSG_raid_numspare_fmt), |
570 | dev_ptr->numSpare); | | 570 | dev_ptr->numSpare); |
571 | break; | | 571 | break; |
572 | case PMR_MENU_SECTPERSU: | | 572 | case PMR_MENU_SECTPERSU: |
573 | wprintw(m->mw, "%s: %u", | | 573 | wprintw(m->mw, "%s: %u", |
574 | msg_string(MSG_raid_sectpersu_fmt), | | 574 | msg_string(MSG_raid_sectpersu_fmt), |
575 | dev_ptr->sectPerSU); | | 575 | dev_ptr->sectPerSU); |
576 | break; | | 576 | break; |
577 | case PMR_MENU_SUSPERPARITYUNIT: | | 577 | case PMR_MENU_SUSPERPARITYUNIT: |
578 | wprintw(m->mw, "%s: %u", | | 578 | wprintw(m->mw, "%s: %u", |
579 | msg_string(MSG_raid_superpar_fmt), | | 579 | msg_string(MSG_raid_superpar_fmt), |
580 | dev_ptr->SUsPerParityUnit); | | 580 | dev_ptr->SUsPerParityUnit); |
581 | break; | | 581 | break; |
582 | case PMR_MENU_SUSPERRECONUNIT: | | 582 | case PMR_MENU_SUSPERRECONUNIT: |
583 | wprintw(m->mw, "%s: %u", | | 583 | wprintw(m->mw, "%s: %u", |
584 | msg_string(MSG_raid_superrec_fmt), | | 584 | msg_string(MSG_raid_superrec_fmt), |
585 | dev_ptr->SUsPerReconUnit); | | 585 | dev_ptr->SUsPerReconUnit); |
586 | break; | | 586 | break; |
587 | } | | 587 | } |
588 | } | | 588 | } |
589 | | | 589 | |
590 | static int | | 590 | static int |
591 | pm_raid_set_value(menudesc *m, void *arg) | | 591 | pm_raid_set_value(menudesc *m, void *arg) |
592 | { | | 592 | { |
593 | int retvalue = -1; | | 593 | int retvalue = -1; |
594 | int *out_var = NULL; | | 594 | int *out_var = NULL; |
595 | char buf[SSTRSIZE]; | | 595 | char buf[SSTRSIZE]; |
596 | const char *msg_to_show = NULL; | | 596 | const char *msg_to_show = NULL; |
597 | struct raid_desc *dev_ptr = arg; | | 597 | struct raid_desc *dev_ptr = arg; |
598 | | | 598 | |
599 | static menu_ent menuent_disk_adddel[] = { | | 599 | static menu_ent menuent_disk_adddel[] = { |
600 | { .opt_name=MSG_add, .opt_flags=OPT_EXIT, | | 600 | { .opt_name=MSG_add, .opt_flags=OPT_EXIT, |
601 | .opt_action=pm_raid_disk_add }, | | 601 | .opt_action=pm_raid_disk_add }, |
602 | { .opt_name=MSG_remove, .opt_flags=OPT_EXIT, | | 602 | { .opt_name=MSG_remove, .opt_flags=OPT_EXIT, |
603 | .opt_action=pm_raid_disk_del } | | 603 | .opt_action=pm_raid_disk_del } |
604 | }; | | 604 | }; |
605 | static int menu_disk_adddel = -1; | | 605 | static int menu_disk_adddel = -1; |
606 | if (menu_disk_adddel == -1) { | | 606 | if (menu_disk_adddel == -1) { |
607 | menu_disk_adddel = new_menu(NULL, menuent_disk_adddel, | | 607 | menu_disk_adddel = new_menu(NULL, menuent_disk_adddel, |
608 | __arraycount(menuent_disk_adddel), | | 608 | __arraycount(menuent_disk_adddel), |
609 | -1, -1, 0, 10, MC_NOCLEAR, NULL, NULL, NULL, NULL, | | 609 | -1, -1, 0, 10, MC_NOCLEAR, NULL, NULL, NULL, NULL, |
610 | MSG_cancel); | | 610 | MSG_cancel); |
611 | } | | 611 | } |
612 | | | 612 | |
613 | switch (m->cursel) { | | 613 | switch (m->cursel) { |
614 | case PMR_MENU_DEVS: | | 614 | case PMR_MENU_DEVS: |
615 | pm_raid_curspare = 0; | | 615 | pm_raid_curspare = 0; |
616 | process_menu(menu_disk_adddel, dev_ptr); | | 616 | process_menu(menu_disk_adddel, dev_ptr); |
617 | return 0; | | 617 | return 0; |
618 | case PMR_MENU_DEVSSPARE: | | 618 | case PMR_MENU_DEVSSPARE: |
619 | pm_raid_curspare = 1; | | 619 | pm_raid_curspare = 1; |
620 | process_menu(menu_disk_adddel, dev_ptr); | | 620 | process_menu(menu_disk_adddel, dev_ptr); |
621 | return 0; | | 621 | return 0; |
622 | case PMR_MENU_RAIDLEVEL: | | 622 | case PMR_MENU_RAIDLEVEL: |
623 | process_menu(MENU_raidlevel, &retvalue); | | 623 | process_menu(MENU_raidlevel, &retvalue); |
624 | if (retvalue >= 0) | | 624 | if (retvalue >= 0) |
625 | dev_ptr->raid_level = retvalue; | | 625 | dev_ptr->raid_level = retvalue; |
626 | return 0; | | 626 | return 0; |
627 | case PMR_MENU_NUMROW: | | 627 | case PMR_MENU_NUMROW: |
628 | hit_enter_to_continue(NULL, MSG_raid_nomultidim); | | 628 | hit_enter_to_continue(NULL, MSG_raid_nomultidim); |
629 | return 0; | | 629 | return 0; |
630 | #if 0 /* notyet */ | | 630 | #if 0 /* notyet */ |
631 | msg_to_show = MSG_raid_numrow_ask; | | 631 | msg_to_show = MSG_raid_numrow_ask; |
632 | out_var = &(dev_ptr->numRow); | | 632 | out_var = &(dev_ptr->numRow); |
633 | break; | | 633 | break; |
634 | #endif | | 634 | #endif |
635 | case PMR_MENU_NUMCOL: | | 635 | case PMR_MENU_NUMCOL: |
636 | msg_to_show = MSG_raid_numcol_ask; | | 636 | msg_to_show = MSG_raid_numcol_ask; |
637 | out_var = &(dev_ptr->numCol); | | 637 | out_var = &(dev_ptr->numCol); |
638 | break; | | 638 | break; |
639 | case PMR_MENU_NUMSPARE: | | 639 | case PMR_MENU_NUMSPARE: |
640 | msg_to_show = MSG_raid_numspare_ask; | | 640 | msg_to_show = MSG_raid_numspare_ask; |
641 | out_var = &(dev_ptr->numSpare); | | 641 | out_var = &(dev_ptr->numSpare); |
642 | break; | | 642 | break; |
643 | case PMR_MENU_SECTPERSU: | | 643 | case PMR_MENU_SECTPERSU: |
644 | msg_to_show = MSG_raid_sectpersu_ask; | | 644 | msg_to_show = MSG_raid_sectpersu_ask; |
645 | out_var = &(dev_ptr->sectPerSU); | | 645 | out_var = &(dev_ptr->sectPerSU); |
646 | break; | | 646 | break; |
647 | case PMR_MENU_SUSPERPARITYUNIT: | | 647 | case PMR_MENU_SUSPERPARITYUNIT: |
648 | msg_to_show = MSG_raid_superpar_ask; | | 648 | msg_to_show = MSG_raid_superpar_ask; |
649 | out_var = &(dev_ptr->SUsPerParityUnit); | | 649 | out_var = &(dev_ptr->SUsPerParityUnit); |
650 | break; | | 650 | break; |
651 | case PMR_MENU_SUSPERRECONUNIT: | | 651 | case PMR_MENU_SUSPERRECONUNIT: |
652 | msg_to_show = MSG_raid_superrec_ask; | | 652 | msg_to_show = MSG_raid_superrec_ask; |
653 | out_var = &(dev_ptr->SUsPerReconUnit); | | 653 | out_var = &(dev_ptr->SUsPerReconUnit); |
654 | break; | | 654 | break; |
655 | case PMR_MENU_REMOVE: | | 655 | case PMR_MENU_REMOVE: |
656 | dev_ptr->enabled = 0; | | 656 | dev_ptr->enabled = 0; |
657 | return 0; | | 657 | return 0; |
658 | } | | 658 | } |
659 | if (out_var == NULL || msg_to_show == NULL) | | 659 | if (out_var == NULL || msg_to_show == NULL) |
660 | return -1; | | 660 | return -1; |
661 | snprintf(buf, SSTRSIZE, "%d", *out_var); | | 661 | snprintf(buf, SSTRSIZE, "%d", *out_var); |
662 | msg_prompt_win(msg_to_show, -1, 18, 0, 0, buf, buf, SSTRSIZE); | | 662 | msg_prompt_win(msg_to_show, -1, 18, 0, 0, buf, buf, SSTRSIZE); |
663 | if (atoi(buf) >= 0) | | 663 | if (atoi(buf) >= 0) |
664 | *out_var = atoi(buf); | | 664 | *out_var = atoi(buf); |
665 | return 0; | | 665 | return 0; |
666 | } | | 666 | } |
667 | | | 667 | |
668 | static void | | 668 | static void |
669 | pm_raid_init(void *arg, void *none) | | 669 | pm_raid_init(void *arg, void *none) |
670 | { | | 670 | { |
671 | struct raid_desc *dev_ptr = arg; | | 671 | struct raid_desc *dev_ptr = arg; |
672 | memset(dev_ptr, 0, sizeof(*dev_ptr)); | | 672 | memset(dev_ptr, 0, sizeof(*dev_ptr)); |
673 | *dev_ptr = (struct raid_desc) { | | 673 | *dev_ptr = (struct raid_desc) { |
674 | .enabled = 1, | | 674 | .enabled = 1, |
675 | .blocked = 0, | | 675 | .blocked = 0, |
676 | .sectPerSU = 32, | | 676 | .sectPerSU = 32, |
677 | .SUsPerParityUnit = 1, | | 677 | .SUsPerParityUnit = 1, |
678 | .SUsPerReconUnit = 1, | | 678 | .SUsPerReconUnit = 1, |
679 | }; | | 679 | }; |
680 | } | | 680 | } |
681 | | | 681 | |
682 | static int | | 682 | static int |
683 | pm_raid_check(void *arg) | | 683 | pm_raid_check(void *arg) |
684 | { | | 684 | { |
685 | size_t i, dev_num = 0; | | 685 | size_t i, dev_num = 0; |
686 | daddr_t min_size = 0, cur_size = 0; | | 686 | daddr_t min_size = 0, cur_size = 0; |
687 | struct raid_desc *dev_ptr = arg; | | 687 | struct raid_desc *dev_ptr = arg; |
688 | struct disk_part_info info; | | 688 | struct disk_part_info info; |
689 | struct disk_partitions *parts; | | 689 | struct disk_partitions *parts; |
690 | | | 690 | |
691 | if (dev_ptr->blocked) | | 691 | if (dev_ptr->blocked) |
692 | return 0; | | 692 | return 0; |
693 | | | 693 | |
694 | for (i = 0; i < MAX_IN_RAID; i++) { | | 694 | for (i = 0; i < MAX_IN_RAID; i++) { |
695 | if (dev_ptr->comp[i].parts != NULL) { | | 695 | if (dev_ptr->comp[i].parts != NULL) { |
696 | parts = dev_ptr->comp[i].parts; | | 696 | parts = dev_ptr->comp[i].parts; |
697 | if (!parts->pscheme->get_part_info(parts, | | 697 | if (!parts->pscheme->get_part_info(parts, |
698 | dev_ptr->comp[i].id, &info)) | | 698 | dev_ptr->comp[i].id, &info)) |
699 | continue; | | 699 | continue; |
700 | cur_size = info.size; | | 700 | cur_size = info.size; |
701 | if (cur_size < min_size || dev_num == 0) | | 701 | if (cur_size < min_size || dev_num == 0) |
702 | min_size = cur_size; | | 702 | min_size = cur_size; |
703 | if (dev_ptr->comp[i].is_spare) | | 703 | if (dev_ptr->comp[i].is_spare) |
704 | continue; | | 704 | continue; |
705 | dev_num++; | | 705 | dev_num++; |
706 | } | | 706 | } |
707 | } | | 707 | } |
708 | | | 708 | |
709 | /* Calculate sum of available space */ | | 709 | /* Calculate sum of available space */ |
710 | if (dev_num > 0) { | | 710 | if (dev_num > 0) { |
711 | switch (dev_ptr->raid_level) { | | 711 | switch (dev_ptr->raid_level) { |
712 | case 0: | | 712 | case 0: |
713 | dev_ptr->total_size = min_size * dev_num; | | 713 | dev_ptr->total_size = min_size * dev_num; |
714 | break; | | 714 | break; |
715 | case 1: | | 715 | case 1: |
716 | dev_ptr->total_size = min_size; | | 716 | dev_ptr->total_size = min_size; |
717 | break; | | 717 | break; |
718 | case 4: | | 718 | case 4: |
719 | case 5: | | 719 | case 5: |
720 | dev_ptr->total_size = min_size * (dev_num - 1); | | 720 | dev_ptr->total_size = min_size * (dev_num - 1); |
721 | break; | | 721 | break; |
722 | } | | 722 | } |
723 | pm_manage_getfreenode(&(dev_ptr->node), "raid", &raids_t_info); | | 723 | pm_manage_getfreenode(&(dev_ptr->node), "raid", &raids_t_info); |
724 | if (dev_ptr->node < 0) | | 724 | if (dev_ptr->node < 0) |
725 | dev_ptr->enabled = 0; | | 725 | dev_ptr->enabled = 0; |
726 | } | | 726 | } |
727 | else | | 727 | else |
728 | dev_ptr->enabled = 0; | | 728 | dev_ptr->enabled = 0; |
729 | return dev_ptr->enabled; | | 729 | return dev_ptr->enabled; |
730 | } | | 730 | } |
731 | | | 731 | |
732 | static int | | 732 | static int |
733 | pm_raid_disk_add(menudesc *m, void *arg) | | 733 | pm_raid_disk_add(menudesc *m, void *arg) |
734 | { | | 734 | { |
735 | int i; | | 735 | int i; |
736 | struct raid_desc *dev_ptr = arg; | | 736 | struct raid_desc *dev_ptr = arg; |
737 | struct part_entry disk_entrie = pm_dev_list(PM_RAID); | | 737 | struct part_entry disk_entrie = pm_dev_list(PM_RAID); |
738 | if (pm_retvalue < 0) | | 738 | if (pm_retvalue < 0) |
739 | return pm_retvalue; | | 739 | return pm_retvalue; |
740 | | | 740 | |
741 | for (i = 0; i < MAX_IN_RAID; i++) | | 741 | for (i = 0; i < MAX_IN_RAID; i++) |
742 | if (dev_ptr->comp[i].parts == NULL) { | | 742 | if (dev_ptr->comp[i].parts == NULL) { |
743 | dev_ptr->comp[i].parts = disk_entrie.parts; | | 743 | dev_ptr->comp[i].parts = disk_entrie.parts; |
744 | dev_ptr->comp[i].id = disk_entrie.id; | | 744 | dev_ptr->comp[i].id = disk_entrie.id; |
745 | dev_ptr->comp[i].is_spare = pm_raid_curspare; | | 745 | dev_ptr->comp[i].is_spare = pm_raid_curspare; |
746 | strlcpy(dev_ptr->comp[i].name, disk_entrie.fullname, | | 746 | strlcpy(dev_ptr->comp[i].name, disk_entrie.fullname, |
747 | sizeof dev_ptr->comp[i].name); | | 747 | sizeof dev_ptr->comp[i].name); |
748 | if (pm_raid_curspare) | | 748 | if (pm_raid_curspare) |
749 | dev_ptr->numSpare++; | | 749 | dev_ptr->numSpare++; |
750 | else | | 750 | else |
751 | dev_ptr->numCol++; | | 751 | dev_ptr->numCol++; |
752 | dev_ptr->numRow = 1; | | 752 | dev_ptr->numRow = 1; |
753 | break; | | 753 | break; |
754 | } | | 754 | } |
755 | return 0; | | 755 | return 0; |
756 | } | | 756 | } |
757 | | | 757 | |
758 | static int | | 758 | static int |
759 | pm_raid_disk_del(menudesc *m, void *arg) | | 759 | pm_raid_disk_del(menudesc *m, void *arg) |
760 | { | | 760 | { |
761 | int retvalue = -1, num_devs = 0; | | 761 | int retvalue = -1, num_devs = 0; |
762 | int i, pm_cur; | | 762 | int i, pm_cur; |
763 | int menu_no; | | 763 | int menu_no; |
764 | struct raid_desc *dev_ptr = arg; | | 764 | struct raid_desc *dev_ptr = arg; |
765 | menu_ent menu_entries[MAX_IN_RAID]; | | 765 | menu_ent menu_entries[MAX_IN_RAID]; |
766 | struct part_entry submenu_args[MAX_IN_RAID]; | | 766 | struct part_entry submenu_args[MAX_IN_RAID]; |
767 | | | 767 | |
768 | for (i = 0; i < MAX_IN_RAID; i++) { | | 768 | for (i = 0; i < MAX_IN_RAID; i++) { |
769 | if (dev_ptr->comp[i].parts == NULL || | | 769 | if (dev_ptr->comp[i].parts == NULL || |
770 | dev_ptr->comp[i].is_spare != pm_raid_curspare) | | 770 | dev_ptr->comp[i].is_spare != pm_raid_curspare) |
771 | continue; | | 771 | continue; |
772 | menu_entries[num_devs] = (struct menu_ent) { | | 772 | menu_entries[num_devs] = (struct menu_ent) { |
773 | .opt_name = dev_ptr->comp[i].name, | | 773 | .opt_name = dev_ptr->comp[i].name, |
774 | .opt_action = set_menu_select, | | 774 | .opt_action = set_menu_select, |
775 | .opt_flags = OPT_EXIT, | | 775 | .opt_flags = OPT_EXIT, |
776 | }; | | 776 | }; |
777 | submenu_args[num_devs].dev_ptr = dev_ptr; | | 777 | submenu_args[num_devs].dev_ptr = dev_ptr; |
778 | submenu_args[num_devs].index = i; | | 778 | submenu_args[num_devs].index = i; |
779 | num_devs++; | | 779 | num_devs++; |
780 | } | | 780 | } |
781 | | | 781 | |
782 | menu_no = new_menu(MSG_raid_disks, | | 782 | menu_no = new_menu(MSG_raid_disks, |
783 | menu_entries, num_devs, -1, -1, | | 783 | menu_entries, num_devs, -1, -1, |
784 | (num_devs+1<3)?3:num_devs+1, 13, | | 784 | (num_devs+1<3)?3:num_devs+1, 13, |
785 | MC_SCROLL | MC_NOCLEAR, NULL, NULL, NULL, NULL, MSG_cancel); | | 785 | MC_SCROLL | MC_NOCLEAR, NULL, NULL, NULL, NULL, MSG_cancel); |
786 | if (menu_no == -1) | | 786 | if (menu_no == -1) |
787 | return -1; | | 787 | return -1; |
788 | process_menu(menu_no, &retvalue); | | 788 | process_menu(menu_no, &retvalue); |
789 | free_menu(menu_no); | | 789 | free_menu(menu_no); |
790 | | | 790 | |
791 | if (retvalue < 0 || retvalue >= num_devs) | | 791 | if (retvalue < 0 || retvalue >= num_devs) |
792 | return -1; | | 792 | return -1; |
793 | | | 793 | |
794 | pm_cur = submenu_args[retvalue].index; | | 794 | pm_cur = submenu_args[retvalue].index; |
795 | | | 795 | |
796 | if (dev_ptr->comp[pm_cur].is_spare) | | 796 | if (dev_ptr->comp[pm_cur].is_spare) |
797 | dev_ptr->numSpare--; | | 797 | dev_ptr->numSpare--; |
798 | else | | 798 | else |
799 | dev_ptr->numCol--; | | 799 | dev_ptr->numCol--; |
800 | dev_ptr->numRow = (dev_ptr->numCol)?1:0; | | 800 | dev_ptr->numRow = (dev_ptr->numCol)?1:0; |
801 | dev_ptr->comp[pm_cur].parts = NULL; | | 801 | dev_ptr->comp[pm_cur].parts = NULL; |
802 | | | 802 | |
803 | return 0; | | 803 | return 0; |
804 | } | | 804 | } |
805 | | | 805 | |
806 | static int | | 806 | static int |
807 | pm_raid_commit(void) | | 807 | pm_raid_commit(void) |
808 | { | | 808 | { |
809 | int i, ii; | | 809 | int i, ii; |
810 | FILE *f; | | 810 | FILE *f; |
811 | char f_name[STRSIZE], devname[STRSIZE]; | | 811 | char f_name[STRSIZE], devname[STRSIZE]; |
812 | | | 812 | |
813 | for (i = 0; i < MAX_RAID; i++) { | | 813 | for (i = 0; i < MAX_RAID; i++) { |
814 | if (! pm_raid_check(&raids[i])) | | 814 | if (! pm_raid_check(&raids[i])) |
815 | continue; | | 815 | continue; |
816 | | | 816 | |
817 | /* Generating configure file for our raid */ | | 817 | /* Generating configure file for our raid */ |
818 | snprintf(f_name, SSTRSIZE, "/tmp/raid.%d.conf", raids[i].node); | | 818 | snprintf(f_name, SSTRSIZE, "/tmp/raid.%d.conf", raids[i].node); |
819 | f = fopen(f_name, "w"); | | 819 | f = fopen(f_name, "w"); |
820 | if (f == NULL) { | | 820 | if (f == NULL) { |
821 | endwin(); | | 821 | endwin(); |
822 | (void)fprintf(stderr, | | 822 | (void)fprintf(stderr, |
823 | "Could not open %s for writing\n", f_name); | | 823 | "Could not open %s for writing\n", f_name); |
824 | if (logfp) | | 824 | if (logfp) |
825 | (void)fprintf(logfp, | | 825 | (void)fprintf(logfp, |
826 | "Could not open %s for writing\n", f_name); | | 826 | "Could not open %s for writing\n", f_name); |
827 | return 1; | | 827 | return 1; |
828 | } | | 828 | } |
829 | scripting_fprintf(NULL, "cat <<EOF >%s\n", f_name); | | 829 | scripting_fprintf(NULL, "cat <<EOF >%s\n", f_name); |
830 | scripting_fprintf(f, "START array\n%d %d %d\n", | | 830 | scripting_fprintf(f, "START array\n%d %d %d\n", |
831 | raids[i].numRow, raids[i].numCol, raids[i].numSpare); | | 831 | raids[i].numRow, raids[i].numCol, raids[i].numSpare); |
832 | | | 832 | |
833 | scripting_fprintf(f, "\nSTART disks\n"); | | 833 | scripting_fprintf(f, "\nSTART disks\n"); |
834 | for (ii = 0; ii < MAX_IN_RAID; ii++) { | | 834 | for (ii = 0; ii < MAX_IN_RAID; ii++) { |
835 | if (raids[i].comp[ii].parts != NULL && | | 835 | if (raids[i].comp[ii].parts != NULL && |
836 | !raids[i].comp[ii].is_spare) { | | 836 | !raids[i].comp[ii].is_spare) { |
837 | strcpy(devname, raids[i].comp[ii].name); | | 837 | strcpy(devname, raids[i].comp[ii].name); |
838 | if (raids[i].comp[ii].parts != NULL && | | 838 | if (raids[i].comp[ii].parts != NULL && |
839 | raids[i].comp[ii].id != NO_PART) { | | 839 | raids[i].comp[ii].id != NO_PART) { |
840 | /* wedge may have moved */ | | 840 | /* wedge may have moved */ |
841 | raids[i].comp[ii].parts->pscheme-> | | 841 | raids[i].comp[ii].parts->pscheme-> |
842 | get_part_device( | | 842 | get_part_device( |
843 | raids[i].comp[ii].parts, | | 843 | raids[i].comp[ii].parts, |
844 | raids[i].comp[ii].id, | | 844 | raids[i].comp[ii].id, |
845 | devname, sizeof devname, NULL, | | 845 | devname, sizeof devname, NULL, |
846 | logical_name, true, true); | | 846 | logical_name, true, true); |
847 | raids[i].comp[ii].parts->pscheme-> | | 847 | raids[i].comp[ii].parts->pscheme-> |
848 | get_part_device( | | 848 | get_part_device( |
849 | raids[i].comp[ii].parts, | | 849 | raids[i].comp[ii].parts, |
850 | raids[i].comp[ii].id, | | 850 | raids[i].comp[ii].id, |
851 | raids[i].comp[ii].name, | | 851 | raids[i].comp[ii].name, |
852 | sizeof raids[i].comp[ii].name, | | 852 | sizeof raids[i].comp[ii].name, |
853 | NULL, plain_name, true, true); | | 853 | NULL, plain_name, true, true); |
854 | } | | 854 | } |
855 | scripting_fprintf(f, "%s\n", devname); | | 855 | scripting_fprintf(f, "%s\n", devname); |
856 | } | | 856 | } |
857 | } | | 857 | } |
858 | | | 858 | |
859 | scripting_fprintf(f, "\nSTART spare\n"); | | 859 | scripting_fprintf(f, "\nSTART spare\n"); |
860 | for (ii = 0; ii < MAX_IN_RAID; ii++) { | | 860 | for (ii = 0; ii < MAX_IN_RAID; ii++) { |
861 | if (raids[i].comp[ii].parts != NULL && | | 861 | if (raids[i].comp[ii].parts != NULL && |
862 | raids[i].comp[ii].is_spare) { | | 862 | raids[i].comp[ii].is_spare) { |
863 | strcpy(devname, raids[i].comp[ii].name); | | 863 | strcpy(devname, raids[i].comp[ii].name); |
864 | if (raids[i].comp[ii].parts != NULL && | | 864 | if (raids[i].comp[ii].parts != NULL && |
865 | raids[i].comp[ii].id != NO_PART) { | | 865 | raids[i].comp[ii].id != NO_PART) { |
866 | /* wedge may have moved */ | | 866 | /* wedge may have moved */ |
867 | raids[i].comp[ii].parts->pscheme-> | | 867 | raids[i].comp[ii].parts->pscheme-> |
868 | get_part_device( | | 868 | get_part_device( |
869 | raids[i].comp[ii].parts, | | 869 | raids[i].comp[ii].parts, |
870 | raids[i].comp[ii].id, | | 870 | raids[i].comp[ii].id, |
871 | devname, sizeof devname, NULL, | | 871 | devname, sizeof devname, NULL, |
872 | logical_name, true, true); | | 872 | logical_name, true, true); |
873 | raids[i].comp[ii].parts->pscheme-> | | 873 | raids[i].comp[ii].parts->pscheme-> |
874 | get_part_device( | | 874 | get_part_device( |
875 | raids[i].comp[ii].parts, | | 875 | raids[i].comp[ii].parts, |
876 | raids[i].comp[ii].id, | | 876 | raids[i].comp[ii].id, |
877 | raids[i].comp[ii].name, | | 877 | raids[i].comp[ii].name, |
878 | sizeof raids[i].comp[ii].name, | | 878 | sizeof raids[i].comp[ii].name, |
879 | NULL, plain_name, true, true); | | 879 | NULL, plain_name, true, true); |
880 | } | | 880 | } |
881 | | | 881 | |
882 | scripting_fprintf(f, "%s\n", | | 882 | scripting_fprintf(f, "%s\n", |
883 | devname); | | 883 | devname); |
884 | } | | 884 | } |
885 | } | | 885 | } |
886 | | | 886 | |
887 | scripting_fprintf(f, "\nSTART layout\n%d %d %d %d\n", | | 887 | scripting_fprintf(f, "\nSTART layout\n%d %d %d %d\n", |
888 | raids[i].sectPerSU, raids[i].SUsPerParityUnit, | | 888 | raids[i].sectPerSU, raids[i].SUsPerParityUnit, |
889 | raids[i].SUsPerReconUnit, raids[i].raid_level); | | 889 | raids[i].SUsPerReconUnit, raids[i].raid_level); |
890 | | | 890 | |
891 | scripting_fprintf(f, "\nSTART queue\nfifo 100\n\n"); | | 891 | scripting_fprintf(f, "\nSTART queue\nfifo 100\n\n"); |
892 | scripting_fprintf(NULL, "EOF\n"); | | 892 | scripting_fprintf(NULL, "EOF\n"); |
893 | fclose (f); | | 893 | fclose (f); |
894 | fflush(NULL); | | 894 | fflush(NULL); |
895 | | | 895 | |
896 | /* Raid initialization */ | | 896 | /* Raid initialization */ |
897 | if (run_program(RUN_DISPLAY | RUN_PROGRESS, | | 897 | if (run_program(RUN_DISPLAY | RUN_PROGRESS, |
898 | "raidctl -C %s raid%d", f_name, raids[i].node) == 0 && | | 898 | "raidctl -C %s raid%d", f_name, raids[i].node) == 0 && |
899 | run_program(RUN_DISPLAY | RUN_PROGRESS, | | 899 | run_program(RUN_DISPLAY | RUN_PROGRESS, |
900 | "raidctl -I %d raid%d", rand(), raids[i].node) == 0 && | | 900 | "raidctl -I %d raid%d", rand(), raids[i].node) == 0 && |
901 | run_program(RUN_DISPLAY | RUN_PROGRESS, | | 901 | run_program(RUN_DISPLAY | RUN_PROGRESS, |
902 | "raidctl -vi raid%d", raids[i].node) == 0 && | | 902 | "raidctl -vi raid%d", raids[i].node) == 0 && |
903 | run_program(RUN_DISPLAY | RUN_PROGRESS, | | 903 | run_program(RUN_DISPLAY | RUN_PROGRESS, |
904 | "raidctl -v -A yes raid%d", raids[i].node) == 0) { | | 904 | "raidctl -v -A yes raid%d", raids[i].node) == 0) { |
905 | /* | | 905 | /* |
906 | * RAID creation done, remove it from list to | | 906 | * RAID creation done, remove it from list to |
907 | * prevent its repeated reinitialization | | 907 | * prevent its repeated reinitialization |
908 | */ | | 908 | */ |
909 | raids[i].blocked = 1; | | 909 | raids[i].blocked = 1; |
910 | } | | 910 | } |
911 | } | | 911 | } |
912 | return 0; | | 912 | return 0; |
913 | } | | 913 | } |
914 | | | 914 | |
915 | /*** | | 915 | /*** |
916 | VND | | 916 | VND |
917 | ***/ | | 917 | ***/ |
918 | | | 918 | |
919 | static void | | 919 | static void |
920 | pm_vnd_menufmt(menudesc *m, int opt, void *arg) | | 920 | pm_vnd_menufmt(menudesc *m, int opt, void *arg) |
921 | { | | 921 | { |
922 | struct vnd_desc *dev_ptr = ((struct part_entry *)arg)[opt].dev_ptr; | | 922 | struct vnd_desc *dev_ptr = ((struct part_entry *)arg)[opt].dev_ptr; |
923 | char dev[STRSIZE]; | | 923 | char dev[STRSIZE]; |
924 | | | 924 | |
925 | if (dev_ptr->enabled == 0) | | 925 | if (dev_ptr->enabled == 0) |
926 | return; | | 926 | return; |
927 | sprintf(dev, "vnd%d", dev_ptr->node); | | 927 | sprintf(dev, "vnd%d", dev_ptr->node); |
928 | if (strlen(dev_ptr->filepath) < 1) | | 928 | if (strlen(dev_ptr->filepath) < 1) |
929 | pm_fmt_disk_line(m->mw, dev, NULL, | | 929 | pm_fmt_disk_line(m->mw, dev, NULL, |
930 | 0, msg_string(MSG_vnd_err_menufmt)); | | 930 | 0, msg_string(MSG_vnd_err_menufmt)); |
931 | else if (dev_ptr->is_exist) | | 931 | else if (dev_ptr->is_exist) |
932 | pm_fmt_disk_line(m->mw, dev, dev_ptr->filepath, | | 932 | pm_fmt_disk_line(m->mw, dev, dev_ptr->filepath, |
933 | 0, msg_string(MSG_vnd_assign)); | | 933 | 0, msg_string(MSG_vnd_assign)); |
934 | else | | 934 | else |
935 | pm_fmt_disk_line(m->mw, dev, dev_ptr->filepath, | | 935 | pm_fmt_disk_line(m->mw, dev, dev_ptr->filepath, |
936 | dev_ptr->size, NULL); | | 936 | dev_ptr->size, NULL); |
937 | } | | 937 | } |
938 | | | 938 | |
939 | static int | | 939 | static int |
940 | max_msg_length(const msg *p, size_t cnt) | | 940 | max_msg_length(const msg *p, size_t cnt) |
941 | { | | 941 | { |
942 | int len, m = 0; | | 942 | int len, m = 0; |
943 | | | 943 | |
944 | while (cnt > 0) { | | 944 | while (cnt > 0) { |
945 | len = strlen(msg_string(*p)); | | 945 | len = strlen(msg_string(*p)); |
946 | if (len > m) | | 946 | if (len > m) |
947 | m = len; | | 947 | m = len; |
948 | cnt--; p++; | | 948 | cnt--; p++; |
949 | } | | 949 | } |
950 | | | 950 | |
951 | return m; | | 951 | return m; |
952 | } | | 952 | } |
953 | | | 953 | |
954 | static void | | 954 | static void |
955 | pm_vnd_edit_menufmt(menudesc *m, int opt, void *arg) | | 955 | pm_vnd_edit_menufmt(menudesc *m, int opt, void *arg) |
956 | { | | 956 | { |
957 | struct vnd_desc *dev_ptr = arg; | | 957 | struct vnd_desc *dev_ptr = arg; |
958 | char buf[SSTRSIZE]; | | 958 | char buf[SSTRSIZE]; |
959 | strcpy(buf, "-"); | | 959 | strcpy(buf, "-"); |
960 | static int lcol_width; | | 960 | static int lcol_width; |
961 | if (lcol_width == 0) { | | 961 | if (lcol_width == 0) { |
962 | static const msg labels[] = { | | 962 | static const msg labels[] = { |
963 | MSG_vnd_path_fmt, MSG_vnd_assign_fmt, MSG_vnd_size_fmt, | | 963 | MSG_vnd_path_fmt, MSG_vnd_assign_fmt, MSG_vnd_size_fmt, |
964 | MSG_vnd_ro_fmt, MSG_vnd_geom_fmt, MSG_vnd_bps_fmt, | | 964 | MSG_vnd_ro_fmt, MSG_vnd_geom_fmt, MSG_vnd_bps_fmt, |
965 | MSG_vnd_spt_fmt, MSG_vnd_tpc_fmt, MSG_vnd_cyl_fmt | | 965 | MSG_vnd_spt_fmt, MSG_vnd_tpc_fmt, MSG_vnd_cyl_fmt |
966 | }; | | 966 | }; |
967 | lcol_width = max_msg_length(labels, __arraycount(labels)) + 3; | | 967 | lcol_width = max_msg_length(labels, __arraycount(labels)) + 3; |
968 | } | | 968 | } |
969 | | | 969 | |
970 | switch (opt) { | | 970 | switch (opt) { |
971 | case PMV_MENU_FILEPATH: | | 971 | case PMV_MENU_FILEPATH: |
972 | wprintw(m->mw, "%*s %s", -lcol_width, | | 972 | wprintw(m->mw, "%*s %s", -lcol_width, |
973 | msg_string(MSG_vnd_path_fmt), dev_ptr->filepath); | | 973 | msg_string(MSG_vnd_path_fmt), dev_ptr->filepath); |
974 | break; | | 974 | break; |
975 | case PMV_MENU_EXIST: | | 975 | case PMV_MENU_EXIST: |
976 | wprintw(m->mw, "%*s %s", -lcol_width, | | 976 | wprintw(m->mw, "%*s %s", -lcol_width, |
977 | msg_string(MSG_vnd_assign_fmt), | | 977 | msg_string(MSG_vnd_assign_fmt), |
978 | dev_ptr->is_exist? | | 978 | dev_ptr->is_exist? |
979 | msg_string(MSG_No) : msg_string(MSG_Yes)); | | 979 | msg_string(MSG_No) : msg_string(MSG_Yes)); |
980 | break; | | 980 | break; |
981 | case PMV_MENU_SIZE: | | 981 | case PMV_MENU_SIZE: |
982 | if (!dev_ptr->is_exist) | | 982 | if (!dev_ptr->is_exist) |
983 | snprintf(buf, SSTRSIZE, "%" PRIu64, | | 983 | snprintf(buf, SSTRSIZE, "%" PRIu64, |
984 | dev_ptr->size / sizemult); | | 984 | dev_ptr->size / sizemult); |
985 | wprintw(m->mw, "%*s %s", -lcol_width, | | 985 | wprintw(m->mw, "%*s %s", -lcol_width, |
986 | msg_string(MSG_vnd_size_fmt), buf); | | 986 | msg_string(MSG_vnd_size_fmt), buf); |
987 | break; | | 987 | break; |
988 | case PMV_MENU_RO: | | 988 | case PMV_MENU_RO: |
989 | wprintw(m->mw, "%*s %s", -lcol_width, | | 989 | wprintw(m->mw, "%*s %s", -lcol_width, |
990 | msg_string(MSG_vnd_ro_fmt), | | 990 | msg_string(MSG_vnd_ro_fmt), |
991 | dev_ptr->readonly? | | 991 | dev_ptr->readonly? |
992 | msg_string(MSG_Yes) : msg_string(MSG_No)); | | 992 | msg_string(MSG_Yes) : msg_string(MSG_No)); |
993 | break; | | 993 | break; |
994 | case PMV_MENU_MGEOM: | | 994 | case PMV_MENU_MGEOM: |
995 | if (!dev_ptr->is_exist) | | 995 | if (!dev_ptr->is_exist) |
996 | snprintf(buf, SSTRSIZE, "%s", | | 996 | snprintf(buf, SSTRSIZE, "%s", |
997 | dev_ptr->manual_geom? | | 997 | dev_ptr->manual_geom? |
998 | msg_string(MSG_Yes) : msg_string(MSG_No)); | | 998 | msg_string(MSG_Yes) : msg_string(MSG_No)); |
999 | wprintw(m->mw, "%*s %s", -lcol_width, | | 999 | wprintw(m->mw, "%*s %s", -lcol_width, |
1000 | msg_string(MSG_vnd_geom_fmt), buf); | | 1000 | msg_string(MSG_vnd_geom_fmt), buf); |
| @@ -1851,1563 +1851,1563 @@ pm_lvmlv_edit_menufmt(menudesc *m, int o | | | @@ -1851,1563 +1851,1563 @@ pm_lvmlv_edit_menufmt(menudesc *m, int o |
1851 | snprintf(buf, STRSIZE, "%d", dev_ptr->stripes); | | 1851 | snprintf(buf, STRSIZE, "%d", dev_ptr->stripes); |
1852 | wprintw(m->mw, "%-20s: %s", | | 1852 | wprintw(m->mw, "%-20s: %s", |
1853 | msg_string(MSG_lvmlv_stripes_fmt), buf); | | 1853 | msg_string(MSG_lvmlv_stripes_fmt), buf); |
1854 | break; | | 1854 | break; |
1855 | case PMLV_MENU_STRIPESIZE: | | 1855 | case PMLV_MENU_STRIPESIZE: |
1856 | if (dev_ptr->stripesize > 0) | | 1856 | if (dev_ptr->stripesize > 0) |
1857 | snprintf(buf, STRSIZE, "%dK", dev_ptr->stripesize); | | 1857 | snprintf(buf, STRSIZE, "%dK", dev_ptr->stripesize); |
1858 | wprintw(m->mw, "%-20s: %s", | | 1858 | wprintw(m->mw, "%-20s: %s", |
1859 | msg_string(MSG_lvmlv_stripesiz_fmt), buf); | | 1859 | msg_string(MSG_lvmlv_stripesiz_fmt), buf); |
1860 | break; | | 1860 | break; |
1861 | case PMLV_MENU_ZERO: | | 1861 | case PMLV_MENU_ZERO: |
1862 | wprintw(m->mw, "%-20s: %s", | | 1862 | wprintw(m->mw, "%-20s: %s", |
1863 | msg_string(MSG_lvmlv_zero_fmt), | | 1863 | msg_string(MSG_lvmlv_zero_fmt), |
1864 | dev_ptr->zero ? | | 1864 | dev_ptr->zero ? |
1865 | msg_string(MSG_Yes) : msg_string(MSG_No)); | | 1865 | msg_string(MSG_Yes) : msg_string(MSG_No)); |
1866 | break; | | 1866 | break; |
1867 | } | | 1867 | } |
1868 | } | | 1868 | } |
1869 | | | 1869 | |
1870 | static int | | 1870 | static int |
1871 | pm_lvmlv_set_value(menudesc *m, void *arg) | | 1871 | pm_lvmlv_set_value(menudesc *m, void *arg) |
1872 | { | | 1872 | { |
1873 | char buf[STRSIZE]; | | 1873 | char buf[STRSIZE]; |
1874 | const char *msg_to_show = NULL; | | 1874 | const char *msg_to_show = NULL; |
1875 | int *out_var = NULL; | | 1875 | int *out_var = NULL; |
1876 | lv_t *dev_ptr = arg; | | 1876 | lv_t *dev_ptr = arg; |
1877 | | | 1877 | |
1878 | switch (m->cursel) { | | 1878 | switch (m->cursel) { |
1879 | case PMLV_MENU_NAME: | | 1879 | case PMLV_MENU_NAME: |
1880 | msg_prompt_win(MSG_lvmlv_name_ask, -1, 18, 0, 0, | | 1880 | msg_prompt_win(MSG_lvmlv_name_ask, -1, 18, 0, 0, |
1881 | dev_ptr->name, dev_ptr->name, SSTRSIZE); | | 1881 | dev_ptr->name, dev_ptr->name, SSTRSIZE); |
1882 | return 0; | | 1882 | return 0; |
1883 | case PMLV_MENU_SIZE: | | 1883 | case PMLV_MENU_SIZE: |
1884 | pm_edit_size_value(MSG_lvmlv_size_ask, | | 1884 | pm_edit_size_value(MSG_lvmlv_size_ask, |
1885 | pm->sectorsize, pm->dlcylsize, | | 1885 | pm->sectorsize, pm->dlcylsize, |
1886 | &dev_ptr->size); /* XXX cylsize? */ | | 1886 | &dev_ptr->size); /* XXX cylsize? */ |
1887 | break; | | 1887 | break; |
1888 | case PMLV_MENU_READONLY: | | 1888 | case PMLV_MENU_READONLY: |
1889 | dev_ptr->readonly = !dev_ptr->readonly; | | 1889 | dev_ptr->readonly = !dev_ptr->readonly; |
1890 | return 0; | | 1890 | return 0; |
1891 | case PMLV_MENU_CONTIGUOUS: | | 1891 | case PMLV_MENU_CONTIGUOUS: |
1892 | dev_ptr->contiguous = !dev_ptr->contiguous; | | 1892 | dev_ptr->contiguous = !dev_ptr->contiguous; |
1893 | return 0; | | 1893 | return 0; |
1894 | case PMLV_MENU_EXTENTS: | | 1894 | case PMLV_MENU_EXTENTS: |
1895 | msg_prompt_win(MSG_lvmlv_extnum_ask, -1, 18, 0, 0, | | 1895 | msg_prompt_win(MSG_lvmlv_extnum_ask, -1, 18, 0, 0, |
1896 | dev_ptr->extents, dev_ptr->extents, SSTRSIZE); | | 1896 | dev_ptr->extents, dev_ptr->extents, SSTRSIZE); |
1897 | return 0; | | 1897 | return 0; |
1898 | case PMLV_MENU_MINOR: | | 1898 | case PMLV_MENU_MINOR: |
1899 | msg_to_show = MSG_lvmlv_minor_ask; | | 1899 | msg_to_show = MSG_lvmlv_minor_ask; |
1900 | out_var = &(dev_ptr->minor); | | 1900 | out_var = &(dev_ptr->minor); |
1901 | break; | | 1901 | break; |
1902 | case PMLV_MENU_MIRRORS: | | 1902 | case PMLV_MENU_MIRRORS: |
1903 | msg_to_show = MSG_lvmlv_mirrors_ask; | | 1903 | msg_to_show = MSG_lvmlv_mirrors_ask; |
1904 | out_var = &(dev_ptr->mirrors); | | 1904 | out_var = &(dev_ptr->mirrors); |
1905 | break; | | 1905 | break; |
1906 | case PMLV_MENU_REGIONSIZE: | | 1906 | case PMLV_MENU_REGIONSIZE: |
1907 | msg_to_show = MSG_lvmlv_regsiz_ask; | | 1907 | msg_to_show = MSG_lvmlv_regsiz_ask; |
1908 | out_var = &(dev_ptr->regionsize); | | 1908 | out_var = &(dev_ptr->regionsize); |
1909 | break; | | 1909 | break; |
1910 | case PMLV_MENU_PERSISTENT: | | 1910 | case PMLV_MENU_PERSISTENT: |
1911 | dev_ptr->persistent = !dev_ptr->persistent; | | 1911 | dev_ptr->persistent = !dev_ptr->persistent; |
1912 | return 0; | | 1912 | return 0; |
1913 | case PMLV_MENU_READAHEAD: | | 1913 | case PMLV_MENU_READAHEAD: |
1914 | msg_to_show = MSG_lvmlv_readahsect_ask; | | 1914 | msg_to_show = MSG_lvmlv_readahsect_ask; |
1915 | out_var = &(dev_ptr->readahead); | | 1915 | out_var = &(dev_ptr->readahead); |
1916 | break; | | 1916 | break; |
1917 | case PMLV_MENU_STRIPES: | | 1917 | case PMLV_MENU_STRIPES: |
1918 | msg_to_show = MSG_lvmlv_stripes_ask; | | 1918 | msg_to_show = MSG_lvmlv_stripes_ask; |
1919 | out_var = &(dev_ptr->stripes); | | 1919 | out_var = &(dev_ptr->stripes); |
1920 | break; | | 1920 | break; |
1921 | case PMLV_MENU_STRIPESIZE: | | 1921 | case PMLV_MENU_STRIPESIZE: |
1922 | if (dev_ptr->stripesize << 1 > 512) | | 1922 | if (dev_ptr->stripesize << 1 > 512) |
1923 | dev_ptr->stripesize = 4; | | 1923 | dev_ptr->stripesize = 4; |
1924 | else | | 1924 | else |
1925 | dev_ptr->stripesize <<= 1; | | 1925 | dev_ptr->stripesize <<= 1; |
1926 | return 0; | | 1926 | return 0; |
1927 | case PMLV_MENU_ZERO: | | 1927 | case PMLV_MENU_ZERO: |
1928 | dev_ptr->zero = !dev_ptr->zero; | | 1928 | dev_ptr->zero = !dev_ptr->zero; |
1929 | return 0; | | 1929 | return 0; |
1930 | case PMLV_MENU_REMOVE: | | 1930 | case PMLV_MENU_REMOVE: |
1931 | dev_ptr->size = 0; | | 1931 | dev_ptr->size = 0; |
1932 | return 0; | | 1932 | return 0; |
1933 | } | | 1933 | } |
1934 | if (out_var == NULL || msg_to_show == NULL) | | 1934 | if (out_var == NULL || msg_to_show == NULL) |
1935 | return -1; | | 1935 | return -1; |
1936 | snprintf(buf, SSTRSIZE, "%d", *out_var); | | 1936 | snprintf(buf, SSTRSIZE, "%d", *out_var); |
1937 | msg_prompt_win(msg_to_show, -1, 18, 0, 0, buf, buf, SSTRSIZE); | | 1937 | msg_prompt_win(msg_to_show, -1, 18, 0, 0, buf, buf, SSTRSIZE); |
1938 | if (atoi(buf) >= 0) | | 1938 | if (atoi(buf) >= 0) |
1939 | *out_var = atoi(buf); | | 1939 | *out_var = atoi(buf); |
1940 | return 0; | | 1940 | return 0; |
1941 | } | | 1941 | } |
1942 | | | 1942 | |
1943 | static void | | 1943 | static void |
1944 | pm_lvmlv_init(void *arg, void *none) | | 1944 | pm_lvmlv_init(void *arg, void *none) |
1945 | { | | 1945 | { |
1946 | lv_t *dev_ptr = arg; | | 1946 | lv_t *dev_ptr = arg; |
1947 | memset(dev_ptr, 0, sizeof *(dev_ptr)); | | 1947 | memset(dev_ptr, 0, sizeof *(dev_ptr)); |
1948 | *dev_ptr = (struct lv_t) { | | 1948 | *dev_ptr = (struct lv_t) { |
1949 | .blocked = 0, | | 1949 | .blocked = 0, |
1950 | .size = 1024, | | 1950 | .size = 1024, |
1951 | .stripesize = 64, | | 1951 | .stripesize = 64, |
1952 | }; | | 1952 | }; |
1953 | sprintf (dev_ptr->name, "lvol%.2d", rand()%100); | | 1953 | sprintf (dev_ptr->name, "lvol%.2d", rand()%100); |
1954 | } | | 1954 | } |
1955 | | | 1955 | |
1956 | static int | | 1956 | static int |
1957 | pm_lvmlv_check(void *arg) | | 1957 | pm_lvmlv_check(void *arg) |
1958 | { | | 1958 | { |
1959 | lv_t *dev_ptr = arg; | | 1959 | lv_t *dev_ptr = arg; |
1960 | if (dev_ptr->size > 0 && strlen(dev_ptr->name) > 0) | | 1960 | if (dev_ptr->size > 0 && strlen(dev_ptr->name) > 0) |
1961 | return 1; | | 1961 | return 1; |
1962 | else { | | 1962 | else { |
1963 | dev_ptr->size = 0; | | 1963 | dev_ptr->size = 0; |
1964 | return 0; | | 1964 | return 0; |
1965 | } | | 1965 | } |
1966 | } | | 1966 | } |
1967 | | | 1967 | |
1968 | static int | | 1968 | static int |
1969 | pm_lvm_commit(void) | | 1969 | pm_lvm_commit(void) |
1970 | { | | 1970 | { |
1971 | int i, ii, error; | | 1971 | int i, ii, error; |
1972 | uint used_size = 0; | | 1972 | uint used_size = 0; |
1973 | char params[STRSIZE*3], devs[STRSIZE*3], arg[STRSIZE]; | | 1973 | char params[STRSIZE*3], devs[STRSIZE*3], arg[STRSIZE]; |
1974 | | | 1974 | |
1975 | for (i = 0; i < MAX_LVM_VG; i++) { | | 1975 | for (i = 0; i < MAX_LVM_VG; i++) { |
1976 | /* Stage 0: checks */ | | 1976 | /* Stage 0: checks */ |
1977 | if (! pm_lvm_check(&lvms[i])) | | 1977 | if (! pm_lvm_check(&lvms[i])) |
1978 | continue; | | 1978 | continue; |
1979 | for (ii = 0; ii < MAX_LVM_LV; ii++) | | 1979 | for (ii = 0; ii < MAX_LVM_LV; ii++) |
1980 | used_size += lvms[i].lv[ii].size; | | 1980 | used_size += lvms[i].lv[ii].size; |
1981 | if (used_size > lvms[i].total_size) | | 1981 | if (used_size > lvms[i].total_size) |
1982 | continue; | | 1982 | continue; |
1983 | | | 1983 | |
1984 | params[0] = '\0'; | | 1984 | params[0] = '\0'; |
1985 | devs[0] = '\0'; | | 1985 | devs[0] = '\0'; |
1986 | error = 0; | | 1986 | error = 0; |
1987 | /* Stage 1: creating Physical Volumes (PV's) */ | | 1987 | /* Stage 1: creating Physical Volumes (PV's) */ |
1988 | for (ii = 0; ii < MAX_LVM_PV && ! error; ii++) | | 1988 | for (ii = 0; ii < MAX_LVM_PV && ! error; ii++) |
1989 | if (lvms[i].pv[ii].pm != NULL) { | | 1989 | if (lvms[i].pv[ii].pm != NULL) { |
1990 | run_program(RUN_SILENT | RUN_ERROR_OK, | | 1990 | run_program(RUN_SILENT | RUN_ERROR_OK, |
1991 | "lvm pvremove -ffy /dev/r%s", | | 1991 | "lvm pvremove -ffy /dev/r%s", |
1992 | (char*)lvms[i].pv[ii].pm_name); | | 1992 | (char*)lvms[i].pv[ii].pm_name); |
1993 | error += run_program(RUN_DISPLAY | RUN_PROGRESS, | | 1993 | error += run_program(RUN_DISPLAY | RUN_PROGRESS, |
1994 | "lvm pvcreate -ffy /dev/r%s", | | 1994 | "lvm pvcreate -ffy /dev/r%s", |
1995 | (char*)lvms[i].pv[ii].pm_name); | | 1995 | (char*)lvms[i].pv[ii].pm_name); |
1996 | if (error) | | 1996 | if (error) |
1997 | break; | | 1997 | break; |
1998 | strlcat(devs, " /dev/r", sizeof devs); | | 1998 | strlcat(devs, " /dev/r", sizeof devs); |
1999 | strlcat(devs, lvms[i].pv[ii].pm_name, | | 1999 | strlcat(devs, lvms[i].pv[ii].pm_name, |
2000 | sizeof devs); | | 2000 | sizeof devs); |
2001 | } | | 2001 | } |
2002 | if (error) | | 2002 | if (error) |
2003 | continue; | | 2003 | continue; |
2004 | /* Stage 2: creating Volume Groups (VG's) */ | | 2004 | /* Stage 2: creating Volume Groups (VG's) */ |
2005 | if (lvms[i].maxlogicalvolumes > 0) { | | 2005 | if (lvms[i].maxlogicalvolumes > 0) { |
2006 | snprintf(arg, sizeof arg, " -l %d", | | 2006 | snprintf(arg, sizeof arg, " -l %d", |
2007 | lvms[i].maxlogicalvolumes); | | 2007 | lvms[i].maxlogicalvolumes); |
2008 | strlcat(params, arg, sizeof params); | | 2008 | strlcat(params, arg, sizeof params); |
2009 | } | | 2009 | } |
2010 | if (lvms[i].maxphysicalvolumes > 0) { | | 2010 | if (lvms[i].maxphysicalvolumes > 0) { |
2011 | snprintf(arg, sizeof arg, " -p %d", | | 2011 | snprintf(arg, sizeof arg, " -p %d", |
2012 | lvms[i].maxphysicalvolumes); | | 2012 | lvms[i].maxphysicalvolumes); |
2013 | strlcat(params, arg, sizeof params); | | 2013 | strlcat(params, arg, sizeof params); |
2014 | } | | 2014 | } |
2015 | if (lvms[i].physicalextentsize > 0) { | | 2015 | if (lvms[i].physicalextentsize > 0) { |
2016 | snprintf(arg, sizeof arg, " -s %d", | | 2016 | snprintf(arg, sizeof arg, " -s %d", |
2017 | lvms[i].physicalextentsize); | | 2017 | lvms[i].physicalextentsize); |
2018 | strlcat(params, arg, sizeof params); | | 2018 | strlcat(params, arg, sizeof params); |
2019 | } | | 2019 | } |
2020 | error += run_program(RUN_DISPLAY | RUN_PROGRESS, | | 2020 | error += run_program(RUN_DISPLAY | RUN_PROGRESS, |
2021 | "lvm vgcreate %s %s %s", params, lvms[i].name, devs); | | 2021 | "lvm vgcreate %s %s %s", params, lvms[i].name, devs); |
2022 | if (error) | | 2022 | if (error) |
2023 | continue; | | 2023 | continue; |
2024 | /* Stage 3: creating Logical Volumes (LV's) */ | | 2024 | /* Stage 3: creating Logical Volumes (LV's) */ |
2025 | for (ii = 0; ii < MAX_LVM_LV; ii++) { | | 2025 | for (ii = 0; ii < MAX_LVM_LV; ii++) { |
2026 | if (lvms[i].lv[ii].size <= 0) | | 2026 | if (lvms[i].lv[ii].size <= 0) |
2027 | continue; | | 2027 | continue; |
2028 | | | 2028 | |
2029 | params[0] = '\0'; | | 2029 | params[0] = '\0'; |
2030 | snprintf(arg, sizeof arg, " -C %c", | | 2030 | snprintf(arg, sizeof arg, " -C %c", |
2031 | lvms[i].lv[ii].contiguous?'y':'n'); | | 2031 | lvms[i].lv[ii].contiguous?'y':'n'); |
2032 | strlcat(params, arg, sizeof params); | | 2032 | strlcat(params, arg, sizeof params); |
2033 | snprintf(arg, sizeof arg, " -M %c", | | 2033 | snprintf(arg, sizeof arg, " -M %c", |
2034 | lvms[i].lv[ii].persistent?'y':'n'); | | 2034 | lvms[i].lv[ii].persistent?'y':'n'); |
2035 | strlcat(params, arg, sizeof params); | | 2035 | strlcat(params, arg, sizeof params); |
2036 | snprintf(arg, sizeof arg, " -p %s", | | 2036 | snprintf(arg, sizeof arg, " -p %s", |
2037 | lvms[i].lv[ii].readonly?"r":"rw"); | | 2037 | lvms[i].lv[ii].readonly?"r":"rw"); |
2038 | strlcat(params, arg, sizeof params); | | 2038 | strlcat(params, arg, sizeof params); |
2039 | snprintf(arg, sizeof arg, " -Z %c", | | 2039 | snprintf(arg, sizeof arg, " -Z %c", |
2040 | lvms[i].lv[ii].zero?'y':'n'); | | 2040 | lvms[i].lv[ii].zero?'y':'n'); |
2041 | strlcat(params, arg, sizeof params); | | 2041 | strlcat(params, arg, sizeof params); |
2042 | if (strlen(lvms[i].lv[ii].name) > 0) { | | 2042 | if (strlen(lvms[i].lv[ii].name) > 0) { |
2043 | snprintf(arg, sizeof arg, " -n %s", | | 2043 | snprintf(arg, sizeof arg, " -n %s", |
2044 | lvms[i].lv[ii].name); | | 2044 | lvms[i].lv[ii].name); |
2045 | strlcat(params, arg, sizeof params); | | 2045 | strlcat(params, arg, sizeof params); |
2046 | } | | 2046 | } |
2047 | if (strlen(lvms[i].lv[ii].extents) > 0) { | | 2047 | if (strlen(lvms[i].lv[ii].extents) > 0) { |
2048 | snprintf(arg, sizeof arg, " -l %s", | | 2048 | snprintf(arg, sizeof arg, " -l %s", |
2049 | lvms[i].lv[ii].extents); | | 2049 | lvms[i].lv[ii].extents); |
2050 | strlcat(params, arg, sizeof params); | | 2050 | strlcat(params, arg, sizeof params); |
2051 | } | | 2051 | } |
2052 | if (lvms[i].lv[ii].minor > 0) { | | 2052 | if (lvms[i].lv[ii].minor > 0) { |
2053 | snprintf(arg, sizeof arg, " --minor %d", | | 2053 | snprintf(arg, sizeof arg, " --minor %d", |
2054 | lvms[i].lv[ii].minor); | | 2054 | lvms[i].lv[ii].minor); |
2055 | strlcat(params, arg, sizeof params); | | 2055 | strlcat(params, arg, sizeof params); |
2056 | } | | 2056 | } |
2057 | if (lvms[i].lv[ii].mirrors > 0) { | | 2057 | if (lvms[i].lv[ii].mirrors > 0) { |
2058 | snprintf(arg, sizeof arg, " -m %d", | | 2058 | snprintf(arg, sizeof arg, " -m %d", |
2059 | lvms[i].lv[ii].mirrors); | | 2059 | lvms[i].lv[ii].mirrors); |
2060 | strlcat(params, arg, sizeof params); | | 2060 | strlcat(params, arg, sizeof params); |
2061 | if (lvms[i].lv[ii].regionsize > 0) { | | 2061 | if (lvms[i].lv[ii].regionsize > 0) { |
2062 | snprintf(arg, sizeof arg, " -R %d", | | 2062 | snprintf(arg, sizeof arg, " -R %d", |
2063 | lvms[i].lv[ii].regionsize); | | 2063 | lvms[i].lv[ii].regionsize); |
2064 | strlcat(params, arg, sizeof params); | | 2064 | strlcat(params, arg, sizeof params); |
2065 | } | | 2065 | } |
2066 | } | | 2066 | } |
2067 | if (lvms[i].lv[ii].readahead > 0) { | | 2067 | if (lvms[i].lv[ii].readahead > 0) { |
2068 | snprintf(arg, sizeof arg, " -r %d", | | 2068 | snprintf(arg, sizeof arg, " -r %d", |
2069 | lvms[i].lv[ii].readahead); | | 2069 | lvms[i].lv[ii].readahead); |
2070 | strlcat(params, arg, sizeof params); | | 2070 | strlcat(params, arg, sizeof params); |
2071 | } | | 2071 | } |
2072 | if (lvms[i].lv[ii].stripes > 0) { | | 2072 | if (lvms[i].lv[ii].stripes > 0) { |
2073 | snprintf(arg, sizeof arg, " -i %d", | | 2073 | snprintf(arg, sizeof arg, " -i %d", |
2074 | lvms[i].lv[ii].stripes); | | 2074 | lvms[i].lv[ii].stripes); |
2075 | strlcat(params, arg, sizeof params); | | 2075 | strlcat(params, arg, sizeof params); |
2076 | if (lvms[i].lv[ii].stripesize > 0) { | | 2076 | if (lvms[i].lv[ii].stripesize > 0) { |
2077 | snprintf(arg, sizeof arg, " -I %d", | | 2077 | snprintf(arg, sizeof arg, " -I %d", |
2078 | lvms[i].lv[ii].stripesize); | | 2078 | lvms[i].lv[ii].stripesize); |
2079 | strlcat(params, arg, sizeof params); | | 2079 | strlcat(params, arg, sizeof params); |
2080 | } | | 2080 | } |
2081 | } | | 2081 | } |
2082 | snprintf(arg, sizeof arg, " -L %" PRIi64 "M", | | 2082 | snprintf(arg, sizeof arg, " -L %" PRIi64 "M", |
2083 | lvms[i].lv[ii].size); | | 2083 | lvms[i].lv[ii].size); |
2084 | strlcat(params, arg, sizeof params); | | 2084 | strlcat(params, arg, sizeof params); |
2085 | | | 2085 | |
2086 | error += run_program(RUN_DISPLAY | RUN_PROGRESS, | | 2086 | error += run_program(RUN_DISPLAY | RUN_PROGRESS, |
2087 | "lvm lvcreate %s %s", params, lvms[i].name); | | 2087 | "lvm lvcreate %s %s", params, lvms[i].name); |
2088 | } | | 2088 | } |
2089 | if (! error) { | | 2089 | if (! error) { |
2090 | lvms[i].blocked = 1; | | 2090 | lvms[i].blocked = 1; |
2091 | for (ii = 0; ii < MAX_LVM_PV; ii++) | | 2091 | for (ii = 0; ii < MAX_LVM_PV; ii++) |
2092 | if (lvms[i].pv[ii].pm != NULL) | | 2092 | if (lvms[i].pv[ii].pm != NULL) |
2093 | lvms[i].pv[ii].pm->blocked++; | | 2093 | lvms[i].pv[ii].pm->blocked++; |
2094 | for (ii = 0; ii < MAX_LVM_LV; ii++) | | 2094 | for (ii = 0; ii < MAX_LVM_LV; ii++) |
2095 | if (lvms[i].lv[ii].size > 0) | | 2095 | if (lvms[i].lv[ii].size > 0) |
2096 | lvms[i].lv[ii].blocked = 1; | | 2096 | lvms[i].lv[ii].blocked = 1; |
2097 | } | | 2097 | } |
2098 | } | | 2098 | } |
2099 | | | 2099 | |
2100 | return 0; | | 2100 | return 0; |
2101 | } | | 2101 | } |
2102 | | | 2102 | |
2103 | /*** | | 2103 | /*** |
2104 | Partman generic functions | | 2104 | Partman generic functions |
2105 | ***/ | | 2105 | ***/ |
2106 | | | 2106 | |
2107 | int | | 2107 | int |
2108 | pm_getrefdev(struct pm_devs *pm_cur) | | 2108 | pm_getrefdev(struct pm_devs *pm_cur) |
2109 | { | | 2109 | { |
2110 | int i, ii, dev_num, num_devs, num_devs_s; | | 2110 | int i, ii, dev_num, num_devs, num_devs_s; |
2111 | char descr[MENUSTRSIZE], dev[MENUSTRSIZE] = ""; | | 2111 | char descr[MENUSTRSIZE], dev[MENUSTRSIZE] = ""; |
2112 | | | 2112 | |
2113 | pm_cur->refdev = NULL; | | 2113 | pm_cur->refdev = NULL; |
2114 | if (! strncmp(pm_cur->diskdev, "cgd", 3)) { | | 2114 | if (! strncmp(pm_cur->diskdev, "cgd", 3)) { |
2115 | dev_num = pm_cur->diskdev[3] - '0'; | | 2115 | dev_num = pm_cur->diskdev[3] - '0'; |
2116 | for (i = 0; i < MAX_CGD; i++) | | 2116 | for (i = 0; i < MAX_CGD; i++) |
2117 | if (cgds[i].blocked && cgds[i].node == dev_num) { | | 2117 | if (cgds[i].blocked && cgds[i].node == dev_num) { |
2118 | pm_cur->refdev = &cgds[i]; | | 2118 | pm_cur->refdev = &cgds[i]; |
2119 | snprintf(descr, sizeof descr, | | 2119 | snprintf(descr, sizeof descr, |
2120 | " (%s, %s-%d)", cgds[i].pm_name, | | 2120 | " (%s, %s-%d)", cgds[i].pm_name, |
2121 | cgds[i].enc_type, cgds[i].key_size); | | 2121 | cgds[i].enc_type, cgds[i].key_size); |
2122 | strlcat(pm_cur->diskdev_descr, descr, | | 2122 | strlcat(pm_cur->diskdev_descr, descr, |
2123 | sizeof(pm_cur->diskdev_descr)); | | 2123 | sizeof(pm_cur->diskdev_descr)); |
2124 | break; | | 2124 | break; |
2125 | } | | 2125 | } |
2126 | } else if (! strncmp(pm_cur->diskdev, "vnd", 3)) { | | 2126 | } else if (! strncmp(pm_cur->diskdev, "vnd", 3)) { |
2127 | dev_num = pm_cur->diskdev[3] - '0'; | | 2127 | dev_num = pm_cur->diskdev[3] - '0'; |
2128 | for (i = 0; i < MAX_VND; i++) | | 2128 | for (i = 0; i < MAX_VND; i++) |
2129 | if (vnds[i].blocked && vnds[i].node == dev_num) { | | 2129 | if (vnds[i].blocked && vnds[i].node == dev_num) { |
2130 | pm_cur->refdev = &vnds[i]; | | 2130 | pm_cur->refdev = &vnds[i]; |
2131 | vnds[i].pm->parts->pscheme->get_part_device( | | 2131 | vnds[i].pm->parts->pscheme->get_part_device( |
2132 | vnds[i].pm->parts, vnds[i].pm_part, | | 2132 | vnds[i].pm->parts, vnds[i].pm_part, |
2133 | dev, sizeof dev, NULL, plain_name, false, | | 2133 | dev, sizeof dev, NULL, plain_name, false, |
2134 | true); | | 2134 | true); |
2135 | snprintf(descr, sizeof descr, " (%s, %s)", | | 2135 | snprintf(descr, sizeof descr, " (%s, %s)", |
2136 | dev, vnds[i].filepath); | | 2136 | dev, vnds[i].filepath); |
2137 | strlcat(pm_cur->diskdev_descr, descr, | | 2137 | strlcat(pm_cur->diskdev_descr, descr, |
2138 | sizeof(pm_cur->diskdev_descr)); | | 2138 | sizeof(pm_cur->diskdev_descr)); |
2139 | break; | | 2139 | break; |
2140 | } | | 2140 | } |
2141 | } else if (! strncmp(pm_cur->diskdev, "raid", 4)) { | | 2141 | } else if (! strncmp(pm_cur->diskdev, "raid", 4)) { |
2142 | dev_num = pm_cur->diskdev[4] - '0'; | | 2142 | dev_num = pm_cur->diskdev[4] - '0'; |
2143 | for (i = 0; i < MAX_RAID; i++) | | 2143 | for (i = 0; i < MAX_RAID; i++) |
2144 | if (raids[i].blocked && raids[i].node == dev_num) { | | 2144 | if (raids[i].blocked && raids[i].node == dev_num) { |
2145 | pm_cur->refdev = &raids[i]; | | 2145 | pm_cur->refdev = &raids[i]; |
2146 | num_devs = 0; num_devs_s = 0; | | 2146 | num_devs = 0; num_devs_s = 0; |
2147 | for (ii = 0; ii < MAX_IN_RAID; ii++) | | 2147 | for (ii = 0; ii < MAX_IN_RAID; ii++) |
2148 | if (raids[i].comp[ii].parts != NULL) { | | 2148 | if (raids[i].comp[ii].parts != NULL) { |
2149 | if(raids[i].comp[ii].is_spare) | | 2149 | if(raids[i].comp[ii].is_spare) |
2150 | num_devs_s++; | | 2150 | num_devs_s++; |
2151 | else | | 2151 | else |
2152 | num_devs++; | | 2152 | num_devs++; |
2153 | } | | 2153 | } |
2154 | snprintf(descr, sizeof descr, | | 2154 | snprintf(descr, sizeof descr, |
2155 | " (lvl %d, %d disks, %d spare)", | | 2155 | " (lvl %d, %d disks, %d spare)", |
2156 | raids[i].raid_level, num_devs, | | 2156 | raids[i].raid_level, num_devs, |
2157 | num_devs_s); | | 2157 | num_devs_s); |
2158 | strlcat(pm_cur->diskdev_descr, descr, | | 2158 | strlcat(pm_cur->diskdev_descr, descr, |
2159 | sizeof(pm_cur->diskdev_descr)); | | 2159 | sizeof(pm_cur->diskdev_descr)); |
2160 | break; | | 2160 | break; |
2161 | } | | 2161 | } |
2162 | } else | | 2162 | } else |
2163 | return -1; | | 2163 | return -1; |
2164 | return 0; | | 2164 | return 0; |
2165 | } | | 2165 | } |
2166 | | | 2166 | |
2167 | /* | | 2167 | /* |
2168 | * Enable/disable items in the extended partition disk/partition action | | 2168 | * Enable/disable items in the extended partition disk/partition action |
2169 | * menu | | 2169 | * menu |
2170 | */ | | 2170 | */ |
2171 | void | | 2171 | void |
2172 | pmdiskentry_enable(menudesc *menu, struct part_entry *pe) | | 2172 | pmdiskentry_enable(menudesc *menu, struct part_entry *pe) |
2173 | { | | 2173 | { |
2174 | int i; | | 2174 | int i; |
2175 | menu_ent *m; | | 2175 | menu_ent *m; |
2176 | bool enable; | | 2176 | bool enable; |
2177 | | | 2177 | |
2178 | for (i = 0; i < menu->numopts; i++) { | | 2178 | for (i = 0; i < menu->numopts; i++) { |
2179 | m = &menu->opts[i]; | | 2179 | m = &menu->opts[i]; |
2180 | | | 2180 | |
2181 | enable = false; | | 2181 | enable = false; |
2182 | if (m->opt_name == MSG_unconfig) { | | 2182 | if (m->opt_name == MSG_unconfig) { |
2183 | if (pe->type == PM_DISK) | | 2183 | if (pe->type == PM_DISK) |
2184 | enable = ((struct pm_devs *)pe->dev_ptr) | | 2184 | enable = ((struct pm_devs *)pe->dev_ptr) |
2185 | ->refdev != NULL; | | 2185 | ->refdev != NULL; |
2186 | } else if (m->opt_name == MSG_undo) { | | 2186 | } else if (m->opt_name == MSG_undo) { |
2187 | if (pe->type != PM_DISK) | | 2187 | if (pe->type != PM_DISK) |
2188 | continue; | | 2188 | continue; |
2189 | enable = ((struct pm_devs *)pe->dev_ptr)->unsaved; | | 2189 | enable = ((struct pm_devs *)pe->dev_ptr)->unsaved; |
2190 | } else if (m->opt_name == MSG_switch_parts) { | | 2190 | } else if (m->opt_name == MSG_switch_parts) { |
2191 | enable = pm_from_pe(pe)->parts != NULL; | | 2191 | enable = pm_from_pe(pe)->parts != NULL; |
2192 | } else { | | 2192 | } else { |
2193 | continue; | | 2193 | continue; |
2194 | } | | 2194 | } |
2195 | | | 2195 | |
2196 | if (enable) | | 2196 | if (enable) |
2197 | m->opt_flags &= ~OPT_IGNORE; | | 2197 | m->opt_flags &= ~OPT_IGNORE; |
2198 | else | | 2198 | else |
2199 | m->opt_flags |= OPT_IGNORE; | | 2199 | m->opt_flags |= OPT_IGNORE; |
2200 | } | | 2200 | } |
2201 | } | | 2201 | } |
2202 | | | 2202 | |
2203 | /* Detect that partition is in use */ | | 2203 | /* Detect that partition is in use */ |
2204 | int | | 2204 | int |
2205 | pm_partusage(struct pm_devs *pm_cur, int part_num, int do_del) | | 2205 | pm_partusage(struct pm_devs *pm_cur, int part_num, int do_del) |
2206 | { | | 2206 | { |
2207 | int i, ii, retvalue = 0; | | 2207 | int i, ii, retvalue = 0; |
2208 | struct disk_part_info info; | | 2208 | struct disk_part_info info; |
2209 | part_id id; | | 2209 | part_id id; |
2210 | | | 2210 | |
2211 | if (pm_cur->parts == NULL) | | 2211 | if (pm_cur->parts == NULL) |
2212 | return -1; /* nothing can be in use */ | | 2212 | return -1; /* nothing can be in use */ |
2213 | | | 2213 | |
2214 | if (part_num < 0) { | | 2214 | if (part_num < 0) { |
2215 | /* Check all partitions on device */ | | 2215 | /* Check all partitions on device */ |
2216 | for (id = 0; id < pm_cur->parts->num_part; id++) { | | 2216 | for (id = 0; id < pm_cur->parts->num_part; id++) { |
2217 | if (!pm_cur->parts->pscheme->get_part_info( | | 2217 | if (!pm_cur->parts->pscheme->get_part_info( |
2218 | pm_cur->parts, id, &info)) | | 2218 | pm_cur->parts, id, &info)) |
2219 | continue; | | 2219 | continue; |
2220 | if (info.flags & (PTI_SEC_CONTAINER| | | 2220 | if (info.flags & (PTI_SEC_CONTAINER| |
2221 | PTI_WHOLE_DISK|PTI_PSCHEME_INTERNAL| | | 2221 | PTI_WHOLE_DISK|PTI_PSCHEME_INTERNAL| |
2222 | PTI_RAW_PART)) | | 2222 | PTI_RAW_PART)) |
2223 | continue; | | 2223 | continue; |
2224 | retvalue += pm_partusage(pm_cur, id, do_del); | | 2224 | retvalue += pm_partusage(pm_cur, id, do_del); |
2225 | } | | 2225 | } |
2226 | return retvalue; | | 2226 | return retvalue; |
2227 | } | | 2227 | } |
2228 | | | 2228 | |
2229 | id = (part_id)part_num; | | 2229 | id = (part_id)part_num; |
2230 | if (id >= pm_cur->parts->num_part) | | 2230 | if (id >= pm_cur->parts->num_part) |
2231 | return 0; | | 2231 | return 0; |
2232 | | | 2232 | |
2233 | for (i = 0; i < MAX_CGD; i++) | | 2233 | for (i = 0; i < MAX_CGD; i++) |
2234 | if (cgds[i].enabled && | | 2234 | if (cgds[i].enabled && |
2235 | cgds[i].pm == pm_cur && | | 2235 | cgds[i].pm == pm_cur && |
2236 | cgds[i].pm_part == id) { | | 2236 | cgds[i].pm_part == id) { |
2237 | if (do_del) { | | 2237 | if (do_del) { |
2238 | cgds[i].pm = NULL; | | 2238 | cgds[i].pm = NULL; |
2239 | cgds[i].pm_name[0] = '\0'; | | 2239 | cgds[i].pm_name[0] = '\0'; |
2240 | } | | 2240 | } |
2241 | return 1; | | 2241 | return 1; |
2242 | } | | 2242 | } |
2243 | for (i = 0; i < MAX_RAID; i++) | | 2243 | for (i = 0; i < MAX_RAID; i++) |
2244 | for (ii = 0; ii < MAX_IN_RAID; ii++) | | 2244 | for (ii = 0; ii < MAX_IN_RAID; ii++) |
2245 | if (raids[i].enabled && | | 2245 | if (raids[i].enabled && |
2246 | raids[i].comp[ii].parts == pm_cur->parts && | | 2246 | raids[i].comp[ii].parts == pm_cur->parts && |
2247 | raids[i].comp[ii].id == id) { | | 2247 | raids[i].comp[ii].id == id) { |
2248 | if (do_del) | | 2248 | if (do_del) |
2249 | raids[i].comp[ii].parts = NULL; | | 2249 | raids[i].comp[ii].parts = NULL; |
2250 | return 1; | | 2250 | return 1; |
2251 | } | | 2251 | } |
2252 | for (i = 0; i < MAX_LVM_VG; i++) | | 2252 | for (i = 0; i < MAX_LVM_VG; i++) |
2253 | for (ii = 0; ii < MAX_LVM_PV; ii++) | | 2253 | for (ii = 0; ii < MAX_LVM_PV; ii++) |
2254 | if (lvms[i].enabled && | | 2254 | if (lvms[i].enabled && |
2255 | lvms[i].pv[ii].pm == pm_cur && | | 2255 | lvms[i].pv[ii].pm == pm_cur && |
2256 | lvms[i].pv[ii].pm_part == id) { | | 2256 | lvms[i].pv[ii].pm_part == id) { |
2257 | if (do_del) | | 2257 | if (do_del) |
2258 | lvms[i].pv[ii].pm = NULL; | | 2258 | lvms[i].pv[ii].pm = NULL; |
2259 | return 1; | | 2259 | return 1; |
2260 | } | | 2260 | } |
2261 | | | 2261 | |
2262 | return 0; | | 2262 | return 0; |
2263 | } | | 2263 | } |
2264 | | | 2264 | |
2265 | static void | | 2265 | static void |
2266 | pm_destroy_one(struct pm_devs *pm_i) | | 2266 | pm_destroy_one(struct pm_devs *pm_i) |
2267 | { | | 2267 | { |
2268 | part_id i; | | 2268 | part_id i; |
2269 | | | 2269 | |
2270 | if (pm_i->parts != NULL) { | | 2270 | if (pm_i->parts != NULL) { |
2271 | if (pm_i->mounted != NULL) { | | 2271 | if (pm_i->mounted != NULL) { |
2272 | for (i = 0; i < pm_i->parts->num_part; i++) | | 2272 | for (i = 0; i < pm_i->parts->num_part; i++) |
2273 | free(pm_i->mounted[i]); | | 2273 | free(pm_i->mounted[i]); |
2274 | } | | 2274 | } |
2275 | | | 2275 | |
2276 | pm_i->parts->pscheme->free(pm_i->parts); | | 2276 | pm_i->parts->pscheme->free(pm_i->parts); |
2277 | } | | 2277 | } |
2278 | free(pm_i); | | 2278 | free(pm_i); |
2279 | } | | 2279 | } |
2280 | | | 2280 | |
2281 | /* Clean up removed devices */ | | 2281 | /* Clean up removed devices */ |
2282 | static int | | 2282 | static int |
2283 | pm_clean(void) | | 2283 | pm_clean(void) |
2284 | { | | 2284 | { |
2285 | int count = 0; | | 2285 | int count = 0; |
2286 | struct pm_devs *pm_i, *tmp; | | 2286 | struct pm_devs *pm_i, *tmp; |
2287 | | | 2287 | |
2288 | SLIST_FOREACH_SAFE(pm_i, &pm_head, l, tmp) | | 2288 | SLIST_FOREACH_SAFE(pm_i, &pm_head, l, tmp) |
2289 | if (! pm_i->found) { | | 2289 | if (! pm_i->found) { |
2290 | count++; | | 2290 | count++; |
2291 | SLIST_REMOVE(&pm_head, pm_i, pm_devs, l); | | 2291 | SLIST_REMOVE(&pm_head, pm_i, pm_devs, l); |
2292 | pm_destroy_one(pm_i); | | 2292 | pm_destroy_one(pm_i); |
2293 | } | | 2293 | } |
2294 | return count; | | 2294 | return count; |
2295 | } | | 2295 | } |
2296 | | | 2296 | |
2297 | /* Free all pm storage */ | | 2297 | /* Free all pm storage */ |
2298 | void | | 2298 | void |
2299 | pm_destroy_all(void) | | 2299 | pm_destroy_all(void) |
2300 | { | | 2300 | { |
2301 | struct pm_devs *pm_i, *tmp; | | 2301 | struct pm_devs *pm_i, *tmp; |
2302 | | | 2302 | |
2303 | if (pm_new != pm) | | 2303 | if (pm_new != pm) |
2304 | pm_destroy_one(pm_new); | | 2304 | pm_destroy_one(pm_new); |
2305 | SLIST_FOREACH_SAFE(pm_i, &pm_head, l, tmp) { | | 2305 | SLIST_FOREACH_SAFE(pm_i, &pm_head, l, tmp) { |
2306 | SLIST_REMOVE(&pm_head, pm_i, pm_devs, l); | | 2306 | SLIST_REMOVE(&pm_head, pm_i, pm_devs, l); |
2307 | pm_destroy_one(pm_i); | | 2307 | pm_destroy_one(pm_i); |
2308 | } | | 2308 | } |
2309 | } | | 2309 | } |
2310 | | | 2310 | |
2311 | void | | 2311 | void |
2312 | pm_set_lvmpv(struct pm_devs *my_pm, part_id pno, bool add) | | 2312 | pm_set_lvmpv(struct pm_devs *my_pm, part_id pno, bool add) |
2313 | { | | 2313 | { |
2314 | size_t i; | | 2314 | size_t i; |
2315 | struct disk_part_info info; | | 2315 | struct disk_part_info info; |
2316 | | | 2316 | |
2317 | if (!my_pm->parts->pscheme->get_part_info(my_pm->parts, pno, &info)) | | 2317 | if (!my_pm->parts->pscheme->get_part_info(my_pm->parts, pno, &info)) |
2318 | return; | | 2318 | return; |
2319 | | | 2319 | |
2320 | if (add) { | | 2320 | if (add) { |
2321 | for (i = 0; i < __arraycount(lvm_pvs); i++) | | 2321 | for (i = 0; i < __arraycount(lvm_pvs); i++) |
2322 | if (lvm_pvs[i].pm == NULL && lvm_pvs[i].start == 0) | | 2322 | if (lvm_pvs[i].pm == NULL && lvm_pvs[i].start == 0) |
2323 | break; | | 2323 | break; |
2324 | if (i >= __arraycount(lvm_pvs)) | | 2324 | if (i >= __arraycount(lvm_pvs)) |
2325 | return; | | 2325 | return; |
2326 | lvm_pvs[i].pm = my_pm; | | 2326 | lvm_pvs[i].pm = my_pm; |
2327 | lvm_pvs[i].start = info.start; | | 2327 | lvm_pvs[i].start = info.start; |
2328 | return; | | 2328 | return; |
2329 | } else { | | 2329 | } else { |
2330 | for (i = 0; i < __arraycount(lvm_pvs); i++) | | 2330 | for (i = 0; i < __arraycount(lvm_pvs); i++) |
2331 | if (lvm_pvs[i].pm == my_pm && | | 2331 | if (lvm_pvs[i].pm == my_pm && |
2332 | lvm_pvs[i].start == info.start) | | 2332 | lvm_pvs[i].start == info.start) |
2333 | break; | | 2333 | break; |
2334 | if (i >= __arraycount(lvm_pvs)) | | 2334 | if (i >= __arraycount(lvm_pvs)) |
2335 | return; | | 2335 | return; |
2336 | lvm_pvs[i].pm = NULL; | | 2336 | lvm_pvs[i].pm = NULL; |
2337 | lvm_pvs[i].start = 0; | | 2337 | lvm_pvs[i].start = 0; |
2338 | } | | 2338 | } |
2339 | } | | 2339 | } |
2340 | | | 2340 | |
2341 | bool | | 2341 | bool |
2342 | pm_is_lvmpv(struct pm_devs *my_pm, part_id id, | | 2342 | pm_is_lvmpv(struct pm_devs *my_pm, part_id id, |
2343 | const struct disk_part_info *info) | | 2343 | const struct disk_part_info *info) |
2344 | { | | 2344 | { |
2345 | size_t i; | | 2345 | size_t i; |
2346 | | | 2346 | |
2347 | for (i = 0; i < __arraycount(lvm_pvs); i++) { | | 2347 | for (i = 0; i < __arraycount(lvm_pvs); i++) { |
2348 | if (lvm_pvs[i].pm != my_pm) | | 2348 | if (lvm_pvs[i].pm != my_pm) |
2349 | continue; | | 2349 | continue; |
2350 | if (lvm_pvs[i].start == info->start) | | 2350 | if (lvm_pvs[i].start == info->start) |
2351 | return true; | | 2351 | return true; |
2352 | } | | 2352 | } |
2353 | | | 2353 | |
2354 | return false; | | 2354 | return false; |
2355 | } | | 2355 | } |
2356 | | | 2356 | |
2357 | void | | 2357 | void |
2358 | pm_setfstype(struct pm_devs *pm_cur, part_id id, int fstype, int fs_subtype) | | 2358 | pm_setfstype(struct pm_devs *pm_cur, part_id id, int fstype, int fs_subtype) |
2359 | { | | 2359 | { |
2360 | struct disk_part_info info; | | 2360 | struct disk_part_info info; |
2361 | | | 2361 | |
2362 | if (!pm_cur->parts->pscheme->get_part_info(pm_cur->parts, id, &info)) | | 2362 | if (!pm_cur->parts->pscheme->get_part_info(pm_cur->parts, id, &info)) |
2363 | return; | | 2363 | return; |
2364 | | | 2364 | |
2365 | info.nat_type = pm_cur->parts->pscheme->get_fs_part_type(PT_root, | | 2365 | info.nat_type = pm_cur->parts->pscheme->get_fs_part_type(PT_root, |
2366 | fstype, fs_subtype); | | 2366 | fstype, fs_subtype); |
2367 | if (info.nat_type == NULL) | | 2367 | if (info.nat_type == NULL) |
2368 | return; | | 2368 | return; |
2369 | info.fs_type = fstype; | | 2369 | info.fs_type = fstype; |
2370 | info.fs_sub_type = fs_subtype; | | 2370 | info.fs_sub_type = fs_subtype; |
2371 | pm_cur->parts->pscheme->set_part_info(pm_cur->parts, id, &info, NULL); | | 2371 | pm_cur->parts->pscheme->set_part_info(pm_cur->parts, id, &info, NULL); |
2372 | } | | 2372 | } |
2373 | | | 2373 | |
2374 | static void | | 2374 | static void |
2375 | pm_select(struct pm_devs *pm_devs_in) | | 2375 | pm_select(struct pm_devs *pm_devs_in) |
2376 | { | | 2376 | { |
2377 | pm = pm_devs_in; | | 2377 | pm = pm_devs_in; |
2378 | if (logfp) | | 2378 | if (logfp) |
2379 | (void)fprintf(logfp, "Partman device: %s\n", pm->diskdev); | | 2379 | (void)fprintf(logfp, "Partman device: %s\n", pm->diskdev); |
2380 | } | | 2380 | } |
2381 | | | 2381 | |
2382 | void | | 2382 | void |
2383 | pm_rename(struct pm_devs *pm_cur) | | 2383 | pm_rename(struct pm_devs *pm_cur) |
2384 | { | | 2384 | { |
2385 | #if 0 // XXX - convert to custom attribute or handle similar | | 2385 | #if 0 // XXX - convert to custom attribute or handle similar |
2386 | pm_select(pm_cur); | | 2386 | pm_select(pm_cur); |
2387 | msg_prompt_win(MSG_packname, -1, 18, 0, 0, pm_cur->bsddiskname, | | 2387 | msg_prompt_win(MSG_packname, -1, 18, 0, 0, pm_cur->bsddiskname, |
2388 | pm_cur->bsddiskname, sizeof pm_cur->bsddiskname); | | 2388 | pm_cur->bsddiskname, sizeof pm_cur->bsddiskname); |
2389 | #ifndef NO_DISKLABEL | | 2389 | #ifndef NO_DISKLABEL |
2390 | (void) savenewlabel(pm_cur->bsdlabel, MAXPARTITIONS); | | 2390 | (void) savenewlabel(pm_cur->bsdlabel, MAXPARTITIONS); |
2391 | #endif | | 2391 | #endif |
2392 | #endif | | 2392 | #endif |
2393 | } | | 2393 | } |
2394 | | | 2394 | |
2395 | int | | 2395 | int |
2396 | pm_editpart(int part_num) | | 2396 | pm_editpart(int part_num) |
2397 | { | | 2397 | { |
2398 | struct partition_usage_set pset = {}; | | 2398 | struct partition_usage_set pset = {}; |
2399 | | | 2399 | |
2400 | usage_set_from_parts(&pset, pm->parts); | | 2400 | usage_set_from_parts(&pset, pm->parts); |
2401 | edit_ptn(&(struct menudesc){.cursel = part_num}, &pset); | | 2401 | edit_ptn(&(struct menudesc){.cursel = part_num}, &pset); |
2402 | free_usage_set(&pset); | | 2402 | free_usage_set(&pset); |
2403 | if (checkoverlap(pm->parts)) { | | 2403 | if (checkoverlap(pm->parts)) { |
2404 | hit_enter_to_continue(MSG_cantsave, NULL); | | 2404 | hit_enter_to_continue(MSG_cantsave, NULL); |
2405 | return -1; | | 2405 | return -1; |
2406 | } | | 2406 | } |
2407 | pm->unsaved = 1; | | 2407 | pm->unsaved = 1; |
2408 | return 0; | | 2408 | return 0; |
2409 | } | | 2409 | } |
2410 | | | 2410 | |
2411 | /* Safe erase of disk */ | | 2411 | /* Safe erase of disk */ |
2412 | void | | 2412 | void |
2413 | pm_shred(struct part_entry *pe, int shredtype) | | 2413 | pm_shred(struct part_entry *pe, int shredtype) |
2414 | { | | 2414 | { |
2415 | const char *srcdev; | | 2415 | const char *srcdev; |
2416 | char dev[SSTRSIZE]; | | 2416 | char dev[SSTRSIZE]; |
2417 | struct pm_devs *my_pm; | | 2417 | struct pm_devs *my_pm; |
2418 | | | 2418 | |
2419 | my_pm = pe->dev_ptr; | | 2419 | my_pm = pe->dev_ptr; |
2420 | if (pe->type == PM_DISK) { | | 2420 | if (pe->type == PM_DISK) { |
2421 | snprintf(dev, sizeof dev, | | 2421 | snprintf(dev, sizeof dev, |
2422 | _PATH_DEV "r%s%c", my_pm->diskdev, 'a' + RAW_PART); | | 2422 | _PATH_DEV "r%s%c", my_pm->diskdev, 'a' + RAW_PART); |
2423 | if (pe->parts != NULL) { | | 2423 | if (pe->parts != NULL) { |
2424 | pe->parts->pscheme->free(pe->parts); | | 2424 | pe->parts->pscheme->free(pe->parts); |
2425 | pe->parts = NULL; | | 2425 | pe->parts = NULL; |
2426 | my_pm->parts = NULL; | | 2426 | my_pm->parts = NULL; |
2427 | } | | 2427 | } |
2428 | } else if (pe->type == PM_PART) { | | 2428 | } else if (pe->type == PM_PART) { |
2429 | pe->parts->pscheme->get_part_device(pe->parts, pe->id, | | 2429 | pe->parts->pscheme->get_part_device(pe->parts, pe->id, |
2430 | dev, sizeof dev, NULL, raw_dev_name, true, true); | | 2430 | dev, sizeof dev, NULL, raw_dev_name, true, true); |
2431 | } | | 2431 | } |
2432 | | | 2432 | |
2433 | switch (shredtype) { | | 2433 | switch (shredtype) { |
2434 | case SHRED_ZEROS: | | 2434 | case SHRED_ZEROS: |
2435 | srcdev = _PATH_DEVZERO; | | 2435 | srcdev = _PATH_DEVZERO; |
2436 | break; | | 2436 | break; |
2437 | case SHRED_RANDOM: | | 2437 | case SHRED_RANDOM: |
2438 | srcdev = _PATH_URANDOM; | | 2438 | srcdev = _PATH_URANDOM; |
2439 | break; | | 2439 | break; |
2440 | default: | | 2440 | default: |
2441 | return; | | 2441 | return; |
2442 | } | | 2442 | } |
2443 | run_program(RUN_DISPLAY | RUN_PROGRESS, | | 2443 | run_program(RUN_DISPLAY | RUN_PROGRESS, |
2444 | "progress -f %s -b 1m dd bs=1m of=%s", srcdev, dev); | | 2444 | "progress -f %s -b 1m dd bs=1m of=%s", srcdev, dev); |
2445 | pm_partusage(my_pm, -1, 1); | | 2445 | pm_partusage(my_pm, -1, 1); |
2446 | } | | 2446 | } |
2447 | | | 2447 | |
2448 | #if 0 // XXX | | 2448 | #if 0 // XXX |
2449 | static int | | 2449 | static int |
2450 | pm_mountall_sort(const void *a, const void *b) | | 2450 | pm_mountall_sort(const void *a, const void *b) |
2451 | { | | 2451 | { |
2452 | return strcmp(mnts[*(const int *)a].on, mnts[*(const int *)b].on); | | 2452 | return strcmp(mnts[*(const int *)a].on, mnts[*(const int *)b].on); |
2453 | } | | 2453 | } |
2454 | #endif | | 2454 | #endif |
2455 | | | 2455 | |
2456 | #if 0 // XXX | | 2456 | #if 0 // XXX |
2457 | /* Mount all available partitions */ | | 2457 | /* Mount all available partitions */ |
2458 | static int | | 2458 | static int |
2459 | pm_mountall(void) | | 2459 | pm_mountall(void) |
2460 | { | | 2460 | { |
2461 | int num_devs = 0; | | 2461 | int num_devs = 0; |
2462 | int mnts_order[MAX_MNTS]; | | 2462 | int mnts_order[MAX_MNTS]; |
2463 | int i, ii, error, ok; | | 2463 | int i, ii, error, ok; |
2464 | char dev[SSTRSIZE]; dev[0] = '\0'; | | 2464 | char dev[SSTRSIZE]; dev[0] = '\0'; |
2465 | struct pm_devs *pm_i; | | 2465 | struct pm_devs *pm_i; |
2466 | | | 2466 | |
2467 | localfs_dev[0] = '\0'; | | 2467 | localfs_dev[0] = '\0'; |
2468 | if (mnts == NULL) | | 2468 | if (mnts == NULL) |
2469 | mnts = calloc(MAX_MNTS, sizeof(*mnts)); | | 2469 | mnts = calloc(MAX_MNTS, sizeof(*mnts)); |
2470 | | | 2470 | |
2471 | SLIST_FOREACH(pm_i, &pm_head, l) { | | 2471 | SLIST_FOREACH(pm_i, &pm_head, l) { |
2472 | ok = 0; | | 2472 | ok = 0; |
2473 | for (i = 0; i < MAXPARTITIONS; i++) { | | 2473 | for (i = 0; i < MAXPARTITIONS; i++) { |
2474 | if (!(pm_i->bsdlabel[i].pi_flags & PIF_MOUNT && | | 2474 | if (!(pm_i->bsdlabel[i].pi_flags & PIF_MOUNT && |
2475 | pm_i->bsdlabel[i].mnt_opts != NULL)) | | 2475 | pm_i->bsdlabel[i].mnt_opts != NULL)) |
2476 | continue; | | 2476 | continue; |
2477 | mnts[num_devs].mnt_opts = pm_i->bsdlabel[i].mnt_opts; | | 2477 | mnts[num_devs].mnt_opts = pm_i->bsdlabel[i].mnt_opts; |
2478 | if (strlen(pm_i->bsdlabel[i].mounted) > 0) { | | 2478 | if (strlen(pm_i->bsdlabel[i].mounted) > 0) { |
2479 | /* Device is already mounted. So, doing mount_null */ | | 2479 | /* Device is already mounted. So, doing mount_null */ |
2480 | strlcpy(mnts[num_devs].dev, pm_i->bsdlabel[i].mounted, MOUNTLEN); | | 2480 | strlcpy(mnts[num_devs].dev, pm_i->bsdlabel[i].mounted, MOUNTLEN); |
2481 | mnts[num_devs].mnt_opts = "-t null"; | | 2481 | mnts[num_devs].mnt_opts = "-t null"; |
2482 | } else { | | 2482 | } else { |
2483 | pm_getdevstring(dev, SSTRSIZE, pm_i, i); | | 2483 | pm_getdevstring(dev, SSTRSIZE, pm_i, i); |
2484 | snprintf(mnts[num_devs].dev, STRSIZE, "/dev/%s", dev); | | 2484 | snprintf(mnts[num_devs].dev, STRSIZE, "/dev/%s", dev); |
2485 | } | | 2485 | } |
2486 | mnts[num_devs].on = pm_i->bsdlabel[i].pi_mount; | | 2486 | mnts[num_devs].on = pm_i->bsdlabel[i].pi_mount; |
2487 | if (strcmp(pm_i->bsdlabel[i].pi_mount, "/") == 0) { | | 2487 | if (strcmp(pm_i->bsdlabel[i].pi_mount, "/") == 0) { |
2488 | /* Use disk with / as a default if the user has | | 2488 | /* Use disk with / as a default if the user has |
2489 | the sets on a local disk */ | | 2489 | the sets on a local disk */ |
2490 | strlcpy(localfs_dev, pm_i->diskdev, SSTRSIZE); | | 2490 | strlcpy(localfs_dev, pm_i->diskdev, SSTRSIZE); |
2491 | } | | 2491 | } |
2492 | num_devs++; | | 2492 | num_devs++; |
2493 | ok = 1; | | 2493 | ok = 1; |
2494 | } | | 2494 | } |
2495 | if (ok) | | 2495 | if (ok) |
2496 | md_pre_mount(NULL, 0); | | 2496 | md_pre_mount(NULL, 0); |
2497 | } | | 2497 | } |
2498 | if (strlen(localfs_dev) < 1) { | | 2498 | if (strlen(localfs_dev) < 1) { |
2499 | hit_enter_to_continue(MSG_noroot, NULL); | | 2499 | hit_enter_to_continue(MSG_noroot, NULL); |
2500 | return -1; | | 2500 | return -1; |
2501 | } | | 2501 | } |
2502 | for (i = 0; i < num_devs; i++) | | 2502 | for (i = 0; i < num_devs; i++) |
2503 | mnts_order[i] = i; | | 2503 | mnts_order[i] = i; |
2504 | qsort(mnts_order, num_devs, sizeof mnts_order[0], pm_mountall_sort); | | 2504 | qsort(mnts_order, num_devs, sizeof mnts_order[0], pm_mountall_sort); |
2505 | | | 2505 | |
2506 | for (i = 0; i < num_devs; i++) { | | 2506 | for (i = 0; i < num_devs; i++) { |
2507 | ii = mnts_order[i]; | | 2507 | ii = mnts_order[i]; |
2508 | make_target_dir(mnts[ii].on); | | 2508 | make_target_dir(mnts[ii].on); |
2509 | error = target_mount_do(mnts[ii].mnt_opts, mnts[ii].dev, mnts[ii].on); | | 2509 | error = target_mount_do(mnts[ii].mnt_opts, mnts[ii].dev, mnts[ii].on); |
2510 | if (error) | | 2510 | if (error) |
2511 | return error; | | 2511 | return error; |
2512 | } | | 2512 | } |
2513 | return 0; | | 2513 | return 0; |
2514 | } | | 2514 | } |
2515 | #endif | | 2515 | #endif |
2516 | | | 2516 | |
2517 | /* Mount partition bypassing ordinary order */ | | 2517 | /* Mount partition bypassing ordinary order */ |
2518 | static int | | 2518 | static int |
2519 | pm_mount(struct pm_devs *pm_cur, int part_num) | | 2519 | pm_mount(struct pm_devs *pm_cur, int part_num) |
2520 | { | | 2520 | { |
2521 | int error = 0; | | 2521 | int error = 0; |
2522 | #if 0 // XXX | | 2522 | #if 0 // XXX |
2523 | char buf[MOUNTLEN]; | | 2523 | char buf[MOUNTLEN]; |
2524 | | | 2524 | |
2525 | if (strlen(pm_cur->bsdlabel[part_num].mounted) > 0) | | 2525 | if (strlen(pm_cur->bsdlabel[part_num].mounted) > 0) |
2526 | return 0; | | 2526 | return 0; |
2527 | | | 2527 | |
2528 | snprintf(buf, sizeof(buf), "/tmp/%s%c", pm_cur->diskdev, | | 2528 | snprintf(buf, sizeof(buf), "/tmp/%s%c", pm_cur->diskdev, |
2529 | part_num + 'a'); | | 2529 | part_num + 'a'); |
2530 | if (! dir_exists_p(buf)) | | 2530 | if (! dir_exists_p(buf)) |
2531 | run_program(RUN_DISPLAY | RUN_PROGRESS, "/bin/mkdir -p %s", buf); | | 2531 | run_program(RUN_DISPLAY | RUN_PROGRESS, "/bin/mkdir -p %s", buf); |
2532 | if (pm_cur->bsdlabel[part_num].pi_flags & PIF_MOUNT && | | 2532 | if (pm_cur->bsdlabel[part_num].pi_flags & PIF_MOUNT && |
2533 | pm_cur->bsdlabel[part_num].mnt_opts != NULL && | | 2533 | pm_cur->bsdlabel[part_num].mnt_opts != NULL && |
2534 | strlen(pm_cur->bsdlabel[part_num].mounted) < 1) | | 2534 | strlen(pm_cur->bsdlabel[part_num].mounted) < 1) |
2535 | error += run_program(RUN_DISPLAY | RUN_PROGRESS, "/sbin/mount %s /dev/%s%c %s", | | 2535 | error += run_program(RUN_DISPLAY | RUN_PROGRESS, "/sbin/mount %s /dev/%s%c %s", |
2536 | pm_cur->bsdlabel[part_num].mnt_opts, | | 2536 | pm_cur->bsdlabel[part_num].mnt_opts, |
2537 | pm_cur->diskdev, part_num + 'a', buf); | | 2537 | pm_cur->diskdev, part_num + 'a', buf); |
2538 | | | 2538 | |
2539 | if (error) | | 2539 | if (error) |
2540 | pm_cur->bsdlabel[part_num].mounted[0] = '\0'; | | 2540 | pm_cur->bsdlabel[part_num].mounted[0] = '\0'; |
2541 | else { | | 2541 | else { |
2542 | strlcpy(pm_cur->bsdlabel[part_num].mounted, buf, MOUNTLEN); | | 2542 | strlcpy(pm_cur->bsdlabel[part_num].mounted, buf, MOUNTLEN); |
2543 | pm_cur->blocked++; | | 2543 | pm_cur->blocked++; |
2544 | } | | 2544 | } |
2545 | #endif | | 2545 | #endif |
2546 | return error; | | 2546 | return error; |
2547 | } | | 2547 | } |
2548 | | | 2548 | |
2549 | void | | 2549 | void |
2550 | pm_umount(struct pm_devs *pm_cur, int part_num) | | 2550 | pm_umount(struct pm_devs *pm_cur, int part_num) |
2551 | { | | 2551 | { |
2552 | char buf[SSTRSIZE]; buf[0] = '\0'; | | 2552 | char buf[SSTRSIZE]; buf[0] = '\0'; |
2553 | part_id id; | | 2553 | part_id id; |
2554 | | | 2554 | |
2555 | if (part_num < 0) | | 2555 | if (part_num < 0) |
2556 | return; | | 2556 | return; |
2557 | id = (part_id)part_num; | | 2557 | id = (part_id)part_num; |
2558 | | | 2558 | |
2559 | pm_cur->parts->pscheme->get_part_device(pm_cur->parts, id, buf, | | 2559 | pm_cur->parts->pscheme->get_part_device(pm_cur->parts, id, buf, |
2560 | sizeof buf, NULL, plain_name, false, true); | | 2560 | sizeof buf, NULL, plain_name, false, true); |
2561 | | | 2561 | |
2562 | if (run_program(RUN_DISPLAY | RUN_PROGRESS, | | 2562 | if (run_program(RUN_DISPLAY | RUN_PROGRESS, |
2563 | "umount -f /dev/%s", buf) == 0) { | | 2563 | "umount -f /dev/%s", buf) == 0) { |
2564 | free(pm_cur->mounted[id]); | | 2564 | free(pm_cur->mounted[id]); |
2565 | pm_cur->mounted[id] = NULL; | | 2565 | pm_cur->mounted[id] = NULL; |
2566 | if (pm_cur->blocked > 0) | | 2566 | if (pm_cur->blocked > 0) |
2567 | pm_cur->blocked--; | | 2567 | pm_cur->blocked--; |
2568 | } | | 2568 | } |
2569 | } | | 2569 | } |
2570 | | | 2570 | |
2571 | int | | 2571 | int |
2572 | pm_unconfigure(struct pm_devs *pm_cur) | | 2572 | pm_unconfigure(struct pm_devs *pm_cur) |
2573 | { | | 2573 | { |
2574 | int error = 0; | | 2574 | int error = 0; |
2575 | if (! strncmp(pm_cur->diskdev, "cgd", 3)) { | | 2575 | if (! strncmp(pm_cur->diskdev, "cgd", 3)) { |
2576 | error = run_program(RUN_DISPLAY | RUN_PROGRESS, "cgdconfig -u %s", pm_cur->diskdev); | | 2576 | error = run_program(RUN_DISPLAY | RUN_PROGRESS, "cgdconfig -u %s", pm_cur->diskdev); |
2577 | if (! error && pm_cur->refdev != NULL) { | | 2577 | if (! error && pm_cur->refdev != NULL) { |
2578 | ((struct cgd_desc*)pm_cur->refdev)->pm->blocked--; | | 2578 | ((struct cgd_desc*)pm_cur->refdev)->pm->blocked--; |
2579 | ((struct cgd_desc*)pm_cur->refdev)->blocked = 0; | | 2579 | ((struct cgd_desc*)pm_cur->refdev)->blocked = 0; |
2580 | } | | 2580 | } |
2581 | } else if (! strncmp(pm_cur->diskdev, "vnd", 3)) { | | 2581 | } else if (! strncmp(pm_cur->diskdev, "vnd", 3)) { |
2582 | error = run_program(RUN_DISPLAY | RUN_PROGRESS, "vndconfig -u %s", pm_cur->diskdev); | | 2582 | error = run_program(RUN_DISPLAY | RUN_PROGRESS, "vndconfig -u %s", pm_cur->diskdev); |
2583 | if (! error && pm_cur->refdev != NULL) { | | 2583 | if (! error && pm_cur->refdev != NULL) { |
2584 | ((struct vnd_desc*)pm_cur->refdev)->pm->blocked--; | | 2584 | ((struct vnd_desc*)pm_cur->refdev)->pm->blocked--; |
2585 | ((struct vnd_desc*)pm_cur->refdev)->blocked = 0; | | 2585 | ((struct vnd_desc*)pm_cur->refdev)->blocked = 0; |
2586 | } | | 2586 | } |
2587 | } else if (! strncmp(pm_cur->diskdev, "raid", 4)) { | | 2587 | } else if (! strncmp(pm_cur->diskdev, "raid", 4)) { |
2588 | error = run_program(RUN_DISPLAY | RUN_PROGRESS, "raidctl -u %s", pm_cur->diskdev); | | 2588 | error = run_program(RUN_DISPLAY | RUN_PROGRESS, "raidctl -u %s", pm_cur->diskdev); |
2589 | if (! error && pm_cur->refdev != NULL) { | | 2589 | if (! error && pm_cur->refdev != NULL) { |
2590 | ((struct raid_desc*)pm_cur->refdev)->blocked = 0; | | 2590 | ((struct raid_desc*)pm_cur->refdev)->blocked = 0; |
2591 | #if 0 // XXX | | 2591 | #if 0 // XXX |
2592 | for (i = 0; i < MAX_IN_RAID; i++) | | 2592 | for (i = 0; i < MAX_IN_RAID; i++) |
2593 | if (((struct raid_desc*)pm_cur->refdev)->comp[i].parts != NULL) | | 2593 | if (((struct raid_desc*)pm_cur->refdev)->comp[i].parts != NULL) |
2594 | ((raids_t*)pm_cur->refdev)->pm[i]->blocked--; | | 2594 | ((raids_t*)pm_cur->refdev)->pm[i]->blocked--; |
2595 | #endif | | 2595 | #endif |
2596 | } | | 2596 | } |
2597 | } else if (! strncmp(pm_cur->diskdev, "dk", 2)) { | | 2597 | } else if (! strncmp(pm_cur->diskdev, "dk", 2)) { |
2598 | if (pm_cur->refdev == NULL) | | 2598 | if (pm_cur->refdev == NULL) |
2599 | return -2; | | 2599 | return -2; |
2600 | /* error = */ | | 2600 | /* error = */ |
2601 | run_program(RUN_DISPLAY | RUN_PROGRESS, "dkctl %s delwedge %s", | | 2601 | run_program(RUN_DISPLAY | RUN_PROGRESS, "dkctl %s delwedge %s", |
2602 | ((struct pm_devs*)pm_cur->refdev)->diskdev, pm_cur->diskdev); | | 2602 | ((struct pm_devs*)pm_cur->refdev)->diskdev, pm_cur->diskdev); |
2603 | #if 0 // XXX | | 2603 | #if 0 // XXX |
2604 | if (! error) { | | 2604 | if (! error) { |
2605 | if (pm_cur->refdev != NULL && ((struct pm_devs*)pm_cur->refdev)->blocked > 0) | | 2605 | if (pm_cur->refdev != NULL && ((struct pm_devs*)pm_cur->refdev)->blocked > 0) |
2606 | ((struct pm_devs*)pm_cur->refdev)->blocked--; | | 2606 | ((struct pm_devs*)pm_cur->refdev)->blocked--; |
2607 | sscanf(pm_cur->diskdev, "dk%d", &num); | | 2607 | sscanf(pm_cur->diskdev, "dk%d", &num); |
2608 | if (num >= 0 && num < MAX_WEDGES) | | 2608 | if (num >= 0 && num < MAX_WEDGES) |
2609 | wedges[num].allocated = 0; | | 2609 | wedges[num].allocated = 0; |
2610 | } | | 2610 | } |
2611 | #endif | | 2611 | #endif |
2612 | } /* XXX: lvm */ | | 2612 | } /* XXX: lvm */ |
2613 | else | | 2613 | else |
2614 | error = run_program(RUN_DISPLAY | RUN_PROGRESS, "eject -t disk /dev/%sd", | | 2614 | error = run_program(RUN_DISPLAY | RUN_PROGRESS, "eject -t disk /dev/%sd", |
2615 | pm_cur->diskdev); | | 2615 | pm_cur->diskdev); |
2616 | if (!error) | | 2616 | if (!error) |
2617 | pm_cur->found = 0; | | 2617 | pm_cur->found = 0; |
2618 | return error; | | 2618 | return error; |
2619 | } | | 2619 | } |
2620 | | | 2620 | |
2621 | /* Last checks before leaving partition manager */ | | 2621 | /* Last checks before leaving partition manager */ |
2622 | #if 0 | | 2622 | #if 0 |
2623 | static int | | 2623 | static int |
2624 | pm_lastcheck(void) | | 2624 | pm_lastcheck(void) |
2625 | { | | 2625 | { |
2626 | FILE *file_tmp = fopen(concat_paths(targetroot_mnt, "/etc/fstab"), "r"); | | 2626 | FILE *file_tmp = fopen(concat_paths(targetroot_mnt, "/etc/fstab"), "r"); |
2627 | if (file_tmp == NULL) | | 2627 | if (file_tmp == NULL) |
2628 | return 1; | | 2628 | return 1; |
2629 | fclose(file_tmp); | | 2629 | fclose(file_tmp); |
2630 | return 0; | | 2630 | return 0; |
2631 | } | | 2631 | } |
2632 | #endif | | 2632 | #endif |
2633 | | | 2633 | |
2634 | /* Are there unsaved changes? */ | | 2634 | /* Are there unsaved changes? */ |
2635 | static int | | 2635 | static int |
2636 | pm_needsave(void) | | 2636 | pm_needsave(void) |
2637 | { | | 2637 | { |
2638 | struct pm_devs *pm_i; | | 2638 | struct pm_devs *pm_i; |
2639 | SLIST_FOREACH(pm_i, &pm_head, l) | | 2639 | SLIST_FOREACH(pm_i, &pm_head, l) |
2640 | if (pm_i->unsaved) { | | 2640 | if (pm_i->unsaved) { |
2641 | /* Oops, we have unsaved changes */ | | 2641 | /* Oops, we have unsaved changes */ |
2642 | pm_changed = 1; | | 2642 | pm_changed = 1; |
2643 | msg_display(MSG_saveprompt); | | 2643 | msg_display(MSG_saveprompt); |
2644 | return ask_yesno(NULL); | | 2644 | return ask_yesno(NULL); |
2645 | } | | 2645 | } |
2646 | return 0; | | 2646 | return 0; |
2647 | } | | 2647 | } |
2648 | | | 2648 | |
2649 | /* Write all changes to disk */ | | 2649 | /* Write all changes to disk */ |
2650 | static int | | 2650 | static int |
2651 | pm_commit(menudesc *m, void *arg) | | 2651 | pm_commit(menudesc *m, void *arg) |
2652 | { | | 2652 | { |
2653 | int retcode; | | 2653 | int retcode; |
2654 | struct pm_devs *pm_i; | | 2654 | struct pm_devs *pm_i; |
2655 | struct disk_partitions *secondary; | | 2655 | struct disk_partitions *secondary; |
2656 | | | 2656 | |
2657 | pm_retvalue = -1; | | 2657 | pm_retvalue = -1; |
2658 | SLIST_FOREACH(pm_i, &pm_head, l) { | | 2658 | SLIST_FOREACH(pm_i, &pm_head, l) { |
2659 | if (! pm_i->unsaved) | | 2659 | if (! pm_i->unsaved) |
2660 | continue; | | 2660 | continue; |
2661 | if (pm_i->parts == NULL) { | | 2661 | if (pm_i->parts == NULL) { |
2662 | pm_i->unsaved = false; | | 2662 | pm_i->unsaved = false; |
2663 | continue; | | 2663 | continue; |
2664 | } | | 2664 | } |
2665 | if (!pm_i->parts->pscheme->write_to_disk(pm_i->parts)) { | | 2665 | if (!pm_i->parts->pscheme->write_to_disk(pm_i->parts)) { |
2666 | if (logfp) | | 2666 | if (logfp) |
2667 | fprintf(logfp, "partitining error %s\n", | | 2667 | fprintf(logfp, "partitining error %s\n", |
2668 | pm_i->diskdev); | | 2668 | pm_i->diskdev); |
2669 | return -1; | | 2669 | return -1; |
2670 | } | | 2670 | } |
2671 | if (pm_i->parts->pscheme->secondary_scheme != NULL) { | | 2671 | if (pm_i->parts->pscheme->secondary_scheme != NULL) { |
2672 | secondary = pm_i->parts->pscheme-> | | 2672 | secondary = pm_i->parts->pscheme-> |
2673 | secondary_partitions(pm_i->parts, -1, false); | | 2673 | secondary_partitions(pm_i->parts, -1, false); |
2674 | if (secondary != NULL) { | | 2674 | if (secondary != NULL) { |
2675 | if (!secondary->pscheme->write_to_disk( | | 2675 | if (!secondary->pscheme->write_to_disk( |
2676 | secondary)) { | | 2676 | secondary)) { |
2677 | if (logfp) | | 2677 | if (logfp) |
2678 | fprintf(logfp, | | 2678 | fprintf(logfp, |
2679 | "partitining error %s\n", | | 2679 | "partitining error %s\n", |
2680 | pm_i->diskdev); | | 2680 | pm_i->diskdev); |
2681 | return -1; | | 2681 | return -1; |
2682 | } | | 2682 | } |
2683 | } | | 2683 | } |
2684 | } | | 2684 | } |
2685 | } | | 2685 | } |
2686 | | | 2686 | |
2687 | /* Call all functions that may create new devices */ | | 2687 | /* Call all functions that may create new devices */ |
2688 | if ((retcode = pm_raid_commit()) != 0) { | | 2688 | if ((retcode = pm_raid_commit()) != 0) { |
2689 | if (logfp) | | 2689 | if (logfp) |
2690 | fprintf(logfp, "RAIDframe configuring error #%d\n", retcode); | | 2690 | fprintf(logfp, "RAIDframe configuring error #%d\n", retcode); |
2691 | return -1; | | 2691 | return -1; |
2692 | } | | 2692 | } |
2693 | if ((retcode = pm_cgd_commit()) != 0) { | | 2693 | if ((retcode = pm_cgd_commit()) != 0) { |
2694 | if (logfp) | | 2694 | if (logfp) |
2695 | fprintf(logfp, "CGD configuring error #%d\n", retcode); | | 2695 | fprintf(logfp, "CGD configuring error #%d\n", retcode); |
2696 | return -1; | | 2696 | return -1; |
2697 | } | | 2697 | } |
2698 | if ((retcode = pm_lvm_commit()) != 0) { | | 2698 | if ((retcode = pm_lvm_commit()) != 0) { |
2699 | if (logfp) | | 2699 | if (logfp) |
2700 | fprintf(logfp, "LVM configuring error #%d\n", retcode); | | 2700 | fprintf(logfp, "LVM configuring error #%d\n", retcode); |
2701 | return -1; | | 2701 | return -1; |
2702 | } | | 2702 | } |
2703 | if ((retcode = pm_vnd_commit()) != 0) { | | 2703 | if ((retcode = pm_vnd_commit()) != 0) { |
2704 | if (logfp) | | 2704 | if (logfp) |
2705 | fprintf(logfp, "VND configuring error #%d\n", retcode); | | 2705 | fprintf(logfp, "VND configuring error #%d\n", retcode); |
2706 | return -1; | | 2706 | return -1; |
2707 | } | | 2707 | } |
2708 | if (m != NULL && arg != NULL) | | 2708 | if (m != NULL && arg != NULL) |
2709 | pm_upddevlist(m, arg); | | 2709 | pm_upddevlist(m, arg); |
2710 | if (logfp) | | 2710 | if (logfp) |
2711 | fflush (logfp); | | 2711 | fflush (logfp); |
2712 | | | 2712 | |
2713 | pm_retvalue = 0; | | 2713 | pm_retvalue = 0; |
2714 | return 0; | | 2714 | return 0; |
2715 | } | | 2715 | } |
2716 | | | 2716 | |
2717 | #if 0 // XXX | | 2717 | #if 0 // XXX |
2718 | static int | | 2718 | static int |
2719 | pm_savebootsector(void) | | 2719 | pm_savebootsector(void) |
2720 | { | | 2720 | { |
2721 | struct pm_devs *pm_i; | | 2721 | struct pm_devs *pm_i; |
2722 | SLIST_FOREACH(pm_i, &pm_head, l) | | 2722 | SLIST_FOREACH(pm_i, &pm_head, l) |
2723 | if (pm_i->bootable) { | | 2723 | if (pm_i->bootable) { |
2724 | if (! strncmp("raid", pm_i->diskdev, 4)) | | 2724 | if (! strncmp("raid", pm_i->diskdev, 4)) |
2725 | if (run_program(RUN_DISPLAY | RUN_PROGRESS, | | 2725 | if (run_program(RUN_DISPLAY | RUN_PROGRESS, |
2726 | "raidctl -v -A root %s", pm_i->diskdev) != 0) { | | 2726 | "raidctl -v -A root %s", pm_i->diskdev) != 0) { |
2727 | if (logfp) | | 2727 | if (logfp) |
2728 | fprintf(logfp, "Error writting RAID bootsector to %s\n", | | 2728 | fprintf(logfp, "Error writting RAID bootsector to %s\n", |
2729 | pm_i->diskdev); | | 2729 | pm_i->diskdev); |
2730 | continue; | | 2730 | continue; |
2731 | } | | 2731 | } |
2732 | if (pm_i->no_part) { | | 2732 | if (pm_i->no_part) { |
2733 | if (pm_i->rootpart < 0 || | | 2733 | if (pm_i->rootpart < 0 || |
2734 | run_program(RUN_DISPLAY | RUN_PROGRESS, | | 2734 | run_program(RUN_DISPLAY | RUN_PROGRESS, |
2735 | "gpt biosboot -i %d %s", | | 2735 | "gpt biosboot -i %d %s", |
2736 | pm_i->rootpart + 1, pm_i->diskdev) != 0) { | | 2736 | pm_i->rootpart + 1, pm_i->diskdev) != 0) { |
2737 | if (logfp) | | 2737 | if (logfp) |
2738 | fprintf(logfp, "Error writting GPT bootsector to %s\n", | | 2738 | fprintf(logfp, "Error writting GPT bootsector to %s\n", |
2739 | pm_i->diskdev); | | 2739 | pm_i->diskdev); |
2740 | continue; | | 2740 | continue; |
2741 | } | | 2741 | } |
2742 | } else { | | 2742 | } else { |
2743 | pm_select(pm_i); | | 2743 | pm_select(pm_i); |
2744 | if ( | | 2744 | if ( |
2745 | #ifndef NO_DISKLABEL | | 2745 | #ifndef NO_DISKLABEL |
2746 | !check_partitions(pm_i, pm_i->parts) || | | 2746 | !check_partitions(pm_i, pm_i->parts) || |
2747 | #endif | | 2747 | #endif |
2748 | md_post_newfs() != 0) { | | 2748 | md_post_newfs() != 0) { |
2749 | if (logfp) | | 2749 | if (logfp) |
2750 | fprintf(logfp, "Error writting bootsector to %s\n", | | 2750 | fprintf(logfp, "Error writting bootsector to %s\n", |
2751 | pm_i->diskdev); | | 2751 | pm_i->diskdev); |
2752 | continue; | | 2752 | continue; |
2753 | } | | 2753 | } |
2754 | } | | 2754 | } |
2755 | } | | 2755 | } |
2756 | return 0; | | 2756 | return 0; |
2757 | } | | 2757 | } |
2758 | #endif | | 2758 | #endif |
2759 | | | 2759 | |
2760 | /* Function for 'Enter'-menu */ | | 2760 | /* Function for 'Enter'-menu */ |
2761 | static int | | 2761 | static int |
2762 | pm_submenu(menudesc *m, void *arg) | | 2762 | pm_submenu(menudesc *m, void *arg) |
2763 | { | | 2763 | { |
2764 | struct pm_devs *pm_cur = NULL; | | 2764 | struct pm_devs *pm_cur = NULL; |
2765 | pm_retvalue = m->cursel + 1; | | 2765 | pm_retvalue = m->cursel + 1; |
2766 | struct part_entry *cur_pe = (struct part_entry *)arg + m->cursel; | | 2766 | struct part_entry *cur_pe = (struct part_entry *)arg + m->cursel; |
2767 | | | 2767 | |
2768 | switch (cur_pe->type) { | | 2768 | switch (cur_pe->type) { |
2769 | case PM_DISK: | | 2769 | case PM_DISK: |
2770 | case PM_PART: | | 2770 | case PM_PART: |
2771 | case PM_SPEC: | | 2771 | case PM_SPEC: |
2772 | if (cur_pe->dev_ptr != NULL) { | | 2772 | if (cur_pe->dev_ptr != NULL) { |
2773 | pm_cur = cur_pe->dev_ptr; | | 2773 | pm_cur = cur_pe->dev_ptr; |
2774 | if (pm_cur == NULL) | | 2774 | if (pm_cur == NULL) |
2775 | return -1; | | 2775 | return -1; |
2776 | if (pm_cur->blocked) { | | 2776 | if (pm_cur->blocked) { |
2777 | clear(); | | 2777 | clear(); |
2778 | refresh(); | | 2778 | refresh(); |
2779 | msg_display(MSG_wannaunblock); | | 2779 | msg_display(MSG_wannaunblock); |
2780 | if (!ask_noyes(NULL)) | | 2780 | if (!ask_noyes(NULL)) |
2781 | return -2; | | 2781 | return -2; |
2782 | pm_cur->blocked = 0; | | 2782 | pm_cur->blocked = 0; |
2783 | } | | 2783 | } |
2784 | pm_select(pm_cur); | | 2784 | pm_select(pm_cur); |
2785 | } | | 2785 | } |
2786 | default: | | 2786 | default: |
2787 | break; | | 2787 | break; |
2788 | } | | 2788 | } |
2789 | | | 2789 | |
2790 | switch (cur_pe->type) { | | 2790 | switch (cur_pe->type) { |
2791 | case PM_DISK: | | 2791 | case PM_DISK: |
2792 | process_menu(MENU_pmdiskentry, cur_pe); | | 2792 | process_menu(MENU_pmdiskentry, cur_pe); |
2793 | break; | | 2793 | break; |
2794 | case PM_PART: | | 2794 | case PM_PART: |
2795 | process_menu(MENU_pmpartentry, cur_pe); | | 2795 | process_menu(MENU_pmpartentry, cur_pe); |
2796 | break; | | 2796 | break; |
2797 | case PM_SPEC: | | 2797 | case PM_SPEC: |
2798 | process_menu(MENU_pmpartentry, cur_pe); | | 2798 | process_menu(MENU_pmpartentry, cur_pe); |
2799 | break; | | 2799 | break; |
2800 | case PM_RAID: | | 2800 | case PM_RAID: |
2801 | pm_edit(PMR_MENU_END, pm_raid_edit_menufmt, | | 2801 | pm_edit(PMR_MENU_END, pm_raid_edit_menufmt, |
2802 | pm_raid_set_value, pm_raid_check, pm_raid_init, | | 2802 | pm_raid_set_value, pm_raid_check, pm_raid_init, |
2803 | NULL, cur_pe->dev_ptr, 0, &raids_t_info); | | 2803 | NULL, cur_pe->dev_ptr, 0, &raids_t_info); |
2804 | break; | | 2804 | break; |
2805 | case PM_VND: | | 2805 | case PM_VND: |
2806 | return pm_edit(PMV_MENU_END, pm_vnd_edit_menufmt, | | 2806 | return pm_edit(PMV_MENU_END, pm_vnd_edit_menufmt, |
2807 | pm_vnd_set_value, pm_vnd_check, pm_vnd_init, | | 2807 | pm_vnd_set_value, pm_vnd_check, pm_vnd_init, |
2808 | NULL, cur_pe->dev_ptr, 0, &vnds_t_info); | | 2808 | NULL, cur_pe->dev_ptr, 0, &vnds_t_info); |
2809 | case PM_CGD: | | 2809 | case PM_CGD: |
2810 | pm_cgd_edit_old(cur_pe); | | 2810 | pm_cgd_edit_old(cur_pe); |
2811 | break; | | 2811 | break; |
2812 | case PM_LVM: | | 2812 | case PM_LVM: |
2813 | return pm_edit(PML_MENU_END, pm_lvm_edit_menufmt, | | 2813 | return pm_edit(PML_MENU_END, pm_lvm_edit_menufmt, |
2814 | pm_lvm_set_value, pm_lvm_check, pm_lvm_init, | | 2814 | pm_lvm_set_value, pm_lvm_check, pm_lvm_init, |
2815 | NULL, cur_pe->dev_ptr, 0, &lvms_t_info); | | 2815 | NULL, cur_pe->dev_ptr, 0, &lvms_t_info); |
2816 | case PM_LVMLV: | | 2816 | case PM_LVMLV: |
2817 | return pm_edit(PMLV_MENU_END, pm_lvmlv_edit_menufmt, | | 2817 | return pm_edit(PMLV_MENU_END, pm_lvmlv_edit_menufmt, |
2818 | pm_lvmlv_set_value, pm_lvmlv_check, pm_lvmlv_init, | | 2818 | pm_lvmlv_set_value, pm_lvmlv_check, pm_lvmlv_init, |
2819 | NULL, cur_pe->dev_ptr, | | 2819 | NULL, cur_pe->dev_ptr, |
2820 | cur_pe->dev_ptr_delta, &lv_t_info); | | 2820 | cur_pe->dev_ptr_delta, &lv_t_info); |
2821 | } | | 2821 | } |
2822 | return 0; | | 2822 | return 0; |
2823 | } | | 2823 | } |
2824 | | | 2824 | |
2825 | /* Functions that generate menu entries text */ | | 2825 | /* Functions that generate menu entries text */ |
2826 | static void | | 2826 | static void |
2827 | pm_menufmt(menudesc *m, int opt, void *arg) | | 2827 | pm_menufmt(menudesc *m, int opt, void *arg) |
2828 | { | | 2828 | { |
2829 | const char *dev_status = ""; | | 2829 | const char *dev_status = ""; |
2830 | char buf[STRSIZE], dev[STRSIZE]; | | 2830 | char buf[STRSIZE], dev[STRSIZE]; |
2831 | part_id part_num = ((struct part_entry *)arg)[opt].id; | | 2831 | part_id part_num = ((struct part_entry *)arg)[opt].id; |
2832 | struct pm_devs *pm_cur = ((struct part_entry *)arg)[opt].dev_ptr; | | 2832 | struct pm_devs *pm_cur = ((struct part_entry *)arg)[opt].dev_ptr; |
2833 | struct disk_partitions *parts = ((struct part_entry *)arg)[opt].parts; | | 2833 | struct disk_partitions *parts = ((struct part_entry *)arg)[opt].parts; |
2834 | struct disk_part_info info; | | 2834 | struct disk_part_info info; |
2835 | const char *mount_point, *fstype; | | 2835 | const char *mount_point, *fstype; |
2836 | | | 2836 | |
2837 | switch (((struct part_entry *)arg)[opt].type) { | | 2837 | switch (((struct part_entry *)arg)[opt].type) { |
2838 | case PM_DISK: | | 2838 | case PM_DISK: |
2839 | if (pm_cur->blocked) | | 2839 | if (pm_cur->blocked) |
2840 | dev_status = msg_string(MSG_pmblocked); | | 2840 | dev_status = msg_string(MSG_pmblocked); |
2841 | else if (! pm_cur->unsaved) | | 2841 | else if (! pm_cur->unsaved) |
2842 | dev_status = msg_string(MSG_pmunchanged); | | 2842 | dev_status = msg_string(MSG_pmunchanged); |
2843 | else | | 2843 | else |
2844 | dev_status = msg_string(MSG_pmused); | | 2844 | dev_status = msg_string(MSG_pmused); |
2845 | wprintw(m->mw, "%-43.42s %25.24s", | | 2845 | wprintw(m->mw, "%-43.42s %25.24s", |
2846 | pm_cur->diskdev_descr, | | 2846 | pm_cur->diskdev_descr, |
2847 | dev_status); | | 2847 | dev_status); |
2848 | break; | | 2848 | break; |
2849 | case PM_PART: | | 2849 | case PM_PART: |
2850 | if (parts->pscheme->get_part_device != NULL) | | 2850 | if (parts->pscheme->get_part_device == NULL || |
2851 | parts->pscheme->get_part_device( | | 2851 | !parts->pscheme->get_part_device( |
2852 | parts, part_num, | | 2852 | parts, part_num, |
2853 | dev, sizeof dev, NULL, plain_name, false, | | 2853 | dev, sizeof dev, NULL, plain_name, false, |
2854 | true); | | 2854 | true)) |
2855 | else | | 2855 | strcpy(dev, "-"); |
2856 | strcpy(dev, "-"); | | 2856 | |
2857 | parts->pscheme->get_part_info(parts, | | 2857 | parts->pscheme->get_part_info(parts, |
2858 | part_num, &info); | | 2858 | part_num, &info); |
2859 | if (pm_cur->mounted != NULL && | | 2859 | if (pm_cur->mounted != NULL && |
2860 | pm_cur->mounted[part_num] != NULL && | | 2860 | pm_cur->mounted[part_num] != NULL && |
2861 | pm_cur->mounted[part_num][0] != 0) | | 2861 | pm_cur->mounted[part_num][0] != 0) |
2862 | mount_point = msg_string(MSG_pmmounted); | | 2862 | mount_point = msg_string(MSG_pmmounted); |
2863 | else | | 2863 | else |
2864 | mount_point = msg_string(MSG_pmunused); | | 2864 | mount_point = msg_string(MSG_pmunused); |
2865 | fstype = getfslabelname(info.fs_type, | | 2865 | fstype = getfslabelname(info.fs_type, |
2866 | info.fs_sub_type); | | 2866 | info.fs_sub_type); |
2867 | if (info.last_mounted != NULL) { | | 2867 | if (info.last_mounted != NULL) { |
2868 | snprintf(buf, STRSIZE, "%s (%s) %s", | | 2868 | snprintf(buf, STRSIZE, "%s (%s) %s", |
2869 | info.last_mounted, fstype, | | 2869 | info.last_mounted, fstype, |
2870 | mount_point); | | 2870 | mount_point); |
2871 | pm_fmt_disk_line(m->mw, dev, buf, | | 2871 | pm_fmt_disk_line(m->mw, dev, buf, |
2872 | info.size, NULL); | | 2872 | info.size, NULL); |
2873 | } else { | | 2873 | } else { |
2874 | if (fstype != NULL) { | | 2874 | if (fstype != NULL) { |
2875 | strlcat(dev, " (", sizeof(dev)); | | 2875 | strlcat(dev, " (", sizeof(dev)); |
2876 | strlcat(dev, fstype, sizeof(dev)); | | 2876 | strlcat(dev, fstype, sizeof(dev)); |
2877 | strlcat(dev, ")", sizeof(dev)); | | 2877 | strlcat(dev, ")", sizeof(dev)); |
2878 | } | | 2878 | } |
2879 | pm_fmt_disk_line(m->mw, dev, NULL, | | 2879 | pm_fmt_disk_line(m->mw, dev, NULL, |
2880 | info.size, NULL); | | 2880 | info.size, NULL); |
2881 | } | | 2881 | } |
2882 | break; | | 2882 | break; |
2883 | case PM_SPEC: | | 2883 | case PM_SPEC: |
2884 | /* XXX ? */ | | 2884 | /* XXX ? */ |
2885 | pm_fmt_disk_line(m->mw, pm_cur->diskdev_descr, NULL, | | 2885 | pm_fmt_disk_line(m->mw, pm_cur->diskdev_descr, NULL, |
2886 | pm_cur->dlsize, NULL); | | 2886 | pm_cur->dlsize, NULL); |
2887 | break; | | 2887 | break; |
2888 | case PM_RAID: | | 2888 | case PM_RAID: |
2889 | pm_raid_menufmt(m, opt, arg); | | 2889 | pm_raid_menufmt(m, opt, arg); |
2890 | break; | | 2890 | break; |
2891 | case PM_VND: | | 2891 | case PM_VND: |
2892 | pm_vnd_menufmt(m, opt, arg); | | 2892 | pm_vnd_menufmt(m, opt, arg); |
2893 | break; | | 2893 | break; |
2894 | case PM_CGD: | | 2894 | case PM_CGD: |
2895 | pm_cgd_menufmt(m, opt, arg); | | 2895 | pm_cgd_menufmt(m, opt, arg); |
2896 | break; | | 2896 | break; |
2897 | case PM_LVM: | | 2897 | case PM_LVM: |
2898 | pm_lvm_menufmt(m, opt, arg); | | 2898 | pm_lvm_menufmt(m, opt, arg); |
2899 | break; | | 2899 | break; |
2900 | case PM_LVMLV: | | 2900 | case PM_LVMLV: |
2901 | pm_lvmlv_menufmt(m, opt, arg); | | 2901 | pm_lvmlv_menufmt(m, opt, arg); |
2902 | break; | | 2902 | break; |
2903 | } | | 2903 | } |
2904 | } | | 2904 | } |
2905 | | | 2905 | |
2906 | /* Submenu for RAID/LVM/CGD/VND */ | | 2906 | /* Submenu for RAID/LVM/CGD/VND */ |
2907 | static void | | 2907 | static void |
2908 | pm_upddevlist_adv(menudesc *m, void *arg, int *i, | | 2908 | pm_upddevlist_adv(menudesc *m, void *arg, int *i, |
2909 | pm_upddevlist_adv_t *d) | | 2909 | pm_upddevlist_adv_t *d) |
2910 | { | | 2910 | { |
2911 | int ii; | | 2911 | int ii; |
2912 | if (d->create_msg != NULL) { | | 2912 | if (d->create_msg != NULL) { |
2913 | /* We want to have menu entry that creates a new device */ | | 2913 | /* We want to have menu entry that creates a new device */ |
2914 | ((struct part_entry *)arg)[*i].type = d->pe_type; | | 2914 | ((struct part_entry *)arg)[*i].type = d->pe_type; |
2915 | ((struct part_entry *)arg)[*i].dev_ptr = NULL; | | 2915 | ((struct part_entry *)arg)[*i].dev_ptr = NULL; |
2916 | ((struct part_entry *)arg)[*i].dev_ptr_delta = d->s->parent_size * d->sub_num; | | 2916 | ((struct part_entry *)arg)[*i].dev_ptr_delta = d->s->parent_size * d->sub_num; |
2917 | m->opts[(*i)++] = (struct menu_ent) { | | 2917 | m->opts[(*i)++] = (struct menu_ent) { |
2918 | .opt_name = d->create_msg, | | 2918 | .opt_name = d->create_msg, |
2919 | .opt_action = pm_submenu, | | 2919 | .opt_action = pm_submenu, |
2920 | }; | | 2920 | }; |
2921 | } | | 2921 | } |
2922 | for (ii = 0; ii < d->s->max; ii++) { | | 2922 | for (ii = 0; ii < d->s->max; ii++) { |
2923 | if (d->s->entry_enabled == NULL || | | 2923 | if (d->s->entry_enabled == NULL || |
2924 | d->s->entry_blocked == NULL || | | 2924 | d->s->entry_blocked == NULL || |
2925 | *(int*)((char*)d->s->entry_enabled + d->s->entry_size * ii + | | 2925 | *(int*)((char*)d->s->entry_enabled + d->s->entry_size * ii + |
2926 | d->s->parent_size * d->sub_num) == 0 || | | 2926 | d->s->parent_size * d->sub_num) == 0 || |
2927 | *(int*)((char*)d->s->entry_blocked + d->s->entry_size * ii + | | 2927 | *(int*)((char*)d->s->entry_blocked + d->s->entry_size * ii + |
2928 | d->s->parent_size * d->sub_num) != 0) | | 2928 | d->s->parent_size * d->sub_num) != 0) |
2929 | continue; | | 2929 | continue; |
2930 | /* We have a entry for displaying */ | | 2930 | /* We have a entry for displaying */ |
2931 | pm_changed = 1; | | 2931 | pm_changed = 1; |
2932 | m->opts[*i] = (struct menu_ent) { | | 2932 | m->opts[*i] = (struct menu_ent) { |
2933 | .opt_name = NULL, | | 2933 | .opt_name = NULL, |
2934 | .opt_action = pm_submenu, | | 2934 | .opt_action = pm_submenu, |
2935 | }; | | 2935 | }; |
2936 | ((struct part_entry *)arg)[*i].type = d->pe_type; | | 2936 | ((struct part_entry *)arg)[*i].type = d->pe_type; |
2937 | ((struct part_entry *)arg)[*i].dev_ptr = (char*)d->s->entry_first + | | 2937 | ((struct part_entry *)arg)[*i].dev_ptr = (char*)d->s->entry_first + |
2938 | d->s->entry_size * ii + d->s->parent_size * d->sub_num; | | 2938 | d->s->entry_size * ii + d->s->parent_size * d->sub_num; |
2939 | (*i)++; | | 2939 | (*i)++; |
2940 | /* We should show submenu for current entry */ | | 2940 | /* We should show submenu for current entry */ |
2941 | if (d->sub != NULL) { | | 2941 | if (d->sub != NULL) { |
2942 | d->sub->sub_num = ii; | | 2942 | d->sub->sub_num = ii; |
2943 | pm_upddevlist_adv(m, arg, i, d->sub); | | 2943 | pm_upddevlist_adv(m, arg, i, d->sub); |
2944 | } | | 2944 | } |
2945 | } | | 2945 | } |
2946 | } | | 2946 | } |
2947 | | | 2947 | |
2948 | /* Update partman main menu with devices list */ | | 2948 | /* Update partman main menu with devices list */ |
2949 | static int | | 2949 | static int |
2950 | pm_upddevlist(menudesc *m, void *arg) | | 2950 | pm_upddevlist(menudesc *m, void *arg) |
2951 | { | | 2951 | { |
2952 | int i = 0; | | 2952 | int i = 0; |
2953 | size_t ii; | | 2953 | size_t ii; |
2954 | struct pm_devs *pm_i; | | 2954 | struct pm_devs *pm_i; |
2955 | struct disk_partitions *secondary; | | 2955 | struct disk_partitions *secondary; |
2956 | const struct disk_partitioning_scheme *ps; | | 2956 | const struct disk_partitioning_scheme *ps; |
2957 | struct disk_part_info info; | | 2957 | struct disk_part_info info; |
2958 | | | 2958 | |
2959 | if (arg != NULL) | | 2959 | if (arg != NULL) |
2960 | pm_retvalue = m->cursel + 1; | | 2960 | pm_retvalue = m->cursel + 1; |
2961 | | | 2961 | |
2962 | pm_changed = 0; | | 2962 | pm_changed = 0; |
2963 | /* Mark all devices as not found */ | | 2963 | /* Mark all devices as not found */ |
2964 | SLIST_FOREACH(pm_i, &pm_head, l) { | | 2964 | SLIST_FOREACH(pm_i, &pm_head, l) { |
2965 | if (pm_i->parts != NULL && !pm_i->unsaved) { | | 2965 | if (pm_i->parts != NULL && !pm_i->unsaved) { |
2966 | pm_i->parts->pscheme->free(pm_i->parts); | | 2966 | pm_i->parts->pscheme->free(pm_i->parts); |
2967 | pm_i->parts = NULL; | | 2967 | pm_i->parts = NULL; |
2968 | } | | 2968 | } |
2969 | if (pm_i->found > 0) | | 2969 | if (pm_i->found > 0) |
2970 | pm_i->found = 0; | | 2970 | pm_i->found = 0; |
2971 | } | | 2971 | } |
2972 | | | 2972 | |
2973 | /* Detect all present devices */ | | 2973 | /* Detect all present devices */ |
2974 | (void)find_disks("partman", false); | | 2974 | (void)find_disks("partman", false); |
2975 | if (have_lvm) | | 2975 | if (have_lvm) |
2976 | pm_lvm_find(); | | 2976 | pm_lvm_find(); |
2977 | pm_clean(); | | 2977 | pm_clean(); |
2978 | | | 2978 | |
2979 | if (m == NULL || arg == NULL) | | 2979 | if (m == NULL || arg == NULL) |
2980 | return -1; | | 2980 | return -1; |
2981 | | | 2981 | |
2982 | SLIST_FOREACH(pm_i, &pm_head, l) { | | 2982 | SLIST_FOREACH(pm_i, &pm_head, l) { |
2983 | memset(&m->opts[i], 0, sizeof m->opts[i]); | | 2983 | memset(&m->opts[i], 0, sizeof m->opts[i]); |
2984 | m->opts[i].opt_action = pm_submenu; | | 2984 | m->opts[i].opt_action = pm_submenu; |
2985 | ((struct part_entry *)arg)[i].dev_ptr = pm_i; | | 2985 | ((struct part_entry *)arg)[i].dev_ptr = pm_i; |
2986 | ((struct part_entry *)arg)[i].id = NO_PART; | | 2986 | ((struct part_entry *)arg)[i].id = NO_PART; |
2987 | if (pm_i->no_part) | | 2987 | if (pm_i->no_part) |
2988 | ((struct part_entry *)arg)[i].type = PM_SPEC; | | 2988 | ((struct part_entry *)arg)[i].type = PM_SPEC; |
2989 | else { | | 2989 | else { |
2990 | ps = pm_i->parts != NULL ? pm_i->parts->pscheme : NULL; | | 2990 | ps = pm_i->parts != NULL ? pm_i->parts->pscheme : NULL; |
2991 | secondary = NULL; | | 2991 | secondary = NULL; |
2992 | | | 2992 | |
2993 | ((struct part_entry *)arg)[i].type = PM_DISK; | | 2993 | ((struct part_entry *)arg)[i].type = PM_DISK; |
2994 | | | 2994 | |
2995 | for (ii = 0; pm_i->parts != NULL && | | 2995 | for (ii = 0; pm_i->parts != NULL && |
2996 | ii < pm_i->parts->num_part; ii++) { | | 2996 | ii < pm_i->parts->num_part; ii++) { |
2997 | if (!ps->get_part_info( | | 2997 | if (!ps->get_part_info( |
2998 | pm_i->parts, ii, &info)) | | 2998 | pm_i->parts, ii, &info)) |
2999 | continue; | | 2999 | continue; |
3000 | if (info.flags & PTI_SEC_CONTAINER) { | | 3000 | if (info.flags & PTI_SEC_CONTAINER) { |
3001 | if (secondary == NULL && | | 3001 | if (secondary == NULL && |
3002 | ps->secondary_scheme != NULL) | | 3002 | ps->secondary_scheme != NULL) |
3003 | secondary = ps-> | | 3003 | secondary = ps-> |
3004 | secondary_partitions( | | 3004 | secondary_partitions( |
3005 | pm_i->parts, | | 3005 | pm_i->parts, |
3006 | info.start, false); | | 3006 | info.start, false); |
3007 | continue; | | 3007 | continue; |
3008 | } | | 3008 | } |
3009 | if (info.flags & (PTI_WHOLE_DISK| | | 3009 | if (info.flags & (PTI_WHOLE_DISK| |
3010 | PTI_PSCHEME_INTERNAL|PTI_RAW_PART)) | | 3010 | PTI_PSCHEME_INTERNAL|PTI_RAW_PART)) |
3011 | continue; | | 3011 | continue; |
3012 | if (info.fs_type == FS_UNUSED) | | 3012 | if (info.fs_type == FS_UNUSED) |
3013 | continue; | | 3013 | continue; |
3014 | if (i >= MAX_ENTRIES) | | 3014 | if (i >= MAX_ENTRIES) |
3015 | break; | | 3015 | break; |
3016 | i++; | | 3016 | i++; |
3017 | memset(&m->opts[i], 0, sizeof m->opts[i]); | | 3017 | memset(&m->opts[i], 0, sizeof m->opts[i]); |
3018 | m->opts[i].opt_action = pm_submenu; | | 3018 | m->opts[i].opt_action = pm_submenu; |
3019 | ((struct part_entry *)arg)[i].parts = | | 3019 | ((struct part_entry *)arg)[i].parts = |
3020 | pm_i->parts; | | 3020 | pm_i->parts; |
3021 | ((struct part_entry *)arg)[i].dev_ptr = pm_i; | | 3021 | ((struct part_entry *)arg)[i].dev_ptr = pm_i; |
3022 | ((struct part_entry *)arg)[i].id = ii; | | 3022 | ((struct part_entry *)arg)[i].id = ii; |
3023 | ((struct part_entry *)arg)[i].type = PM_PART; | | 3023 | ((struct part_entry *)arg)[i].type = PM_PART; |
3024 | } | | 3024 | } |
3025 | | | 3025 | |
3026 | for (ii = 0; secondary != NULL && | | 3026 | for (ii = 0; secondary != NULL && |
3027 | ii < secondary->num_part; ii++) { | | 3027 | ii < secondary->num_part; ii++) { |
3028 | if (!secondary->pscheme->get_part_info( | | 3028 | if (!secondary->pscheme->get_part_info( |
3029 | secondary, ii, &info)) | | 3029 | secondary, ii, &info)) |
3030 | continue; | | 3030 | continue; |
3031 | if (info.flags & (PTI_WHOLE_DISK| | | 3031 | if (info.flags & (PTI_WHOLE_DISK| |
3032 | PTI_PSCHEME_INTERNAL|PTI_RAW_PART)) | | 3032 | PTI_PSCHEME_INTERNAL|PTI_RAW_PART)) |
3033 | continue; | | 3033 | continue; |
3034 | if (info.fs_type == FS_UNUSED) | | 3034 | if (info.fs_type == FS_UNUSED) |
3035 | continue; | | 3035 | continue; |
3036 | if (i >= MAX_ENTRIES) | | 3036 | if (i >= MAX_ENTRIES) |
3037 | break; | | 3037 | break; |
3038 | i++; | | 3038 | i++; |
3039 | memset(&m->opts[i], 0, sizeof m->opts[i]); | | 3039 | memset(&m->opts[i], 0, sizeof m->opts[i]); |
3040 | m->opts[i].opt_action = pm_submenu; | | 3040 | m->opts[i].opt_action = pm_submenu; |
3041 | ((struct part_entry *)arg)[i].parts = secondary; | | 3041 | ((struct part_entry *)arg)[i].parts = secondary; |
3042 | ((struct part_entry *)arg)[i].dev_ptr = pm_i; | | 3042 | ((struct part_entry *)arg)[i].dev_ptr = pm_i; |
3043 | ((struct part_entry *)arg)[i].id = ii; | | 3043 | ((struct part_entry *)arg)[i].id = ii; |
3044 | ((struct part_entry *)arg)[i].type = PM_PART; | | 3044 | ((struct part_entry *)arg)[i].type = PM_PART; |
3045 | } | | 3045 | } |
3046 | } | | 3046 | } |
3047 | i++; | | 3047 | i++; |
3048 | } | | 3048 | } |
3049 | for (ii = 0; ii <= (size_t)i; ii++) { | | 3049 | for (ii = 0; ii <= (size_t)i; ii++) { |
3050 | m->opts[ii].opt_flags = OPT_EXIT; | | 3050 | m->opts[ii].opt_flags = OPT_EXIT; |
3051 | } | | 3051 | } |
3052 | if (have_cgd) { | | 3052 | if (have_cgd) { |
3053 | pm_upddevlist_adv(m, arg, &i, | | 3053 | pm_upddevlist_adv(m, arg, &i, |
3054 | &(pm_upddevlist_adv_t) {MSG_create_cgd, PM_CGD, | | 3054 | &(pm_upddevlist_adv_t) {MSG_create_cgd, PM_CGD, |
3055 | &cgds_t_info, 0, NULL}); | | 3055 | &cgds_t_info, 0, NULL}); |
3056 | } | | 3056 | } |
3057 | pm_upddevlist_adv(m, arg, &i, | | 3057 | pm_upddevlist_adv(m, arg, &i, |
3058 | &(pm_upddevlist_adv_t) {MSG_create_vnd, PM_VND, | | 3058 | &(pm_upddevlist_adv_t) {MSG_create_vnd, PM_VND, |
3059 | &vnds_t_info, 0, NULL}); | | 3059 | &vnds_t_info, 0, NULL}); |
3060 | if (have_lvm) { | | 3060 | if (have_lvm) { |
3061 | pm_upddevlist_adv(m, arg, &i, | | 3061 | pm_upddevlist_adv(m, arg, &i, |
3062 | &(pm_upddevlist_adv_t) {MSG_create_vg, PM_LVM, | | 3062 | &(pm_upddevlist_adv_t) {MSG_create_vg, PM_LVM, |
3063 | &lvms_t_info, 0, | | 3063 | &lvms_t_info, 0, |
3064 | &(pm_upddevlist_adv_t) {MSG_create_lv, PM_LVMLV, | | 3064 | &(pm_upddevlist_adv_t) {MSG_create_lv, PM_LVMLV, |
3065 | &lv_t_info, 0, | | 3065 | &lv_t_info, 0, |
3066 | NULL}}); | | 3066 | NULL}}); |
3067 | } | | 3067 | } |
3068 | if (have_raid) { | | 3068 | if (have_raid) { |
3069 | pm_upddevlist_adv(m, arg, &i, | | 3069 | pm_upddevlist_adv(m, arg, &i, |
3070 | &(pm_upddevlist_adv_t) {MSG_create_raid, PM_RAID, &raids_t_info, 0, NULL}); | | 3070 | &(pm_upddevlist_adv_t) {MSG_create_raid, PM_RAID, &raids_t_info, 0, NULL}); |
3071 | } | | 3071 | } |
3072 | | | 3072 | |
3073 | m->opts[i++] = (struct menu_ent) { | | 3073 | m->opts[i++] = (struct menu_ent) { |
3074 | .opt_name = MSG_updpmlist, | | 3074 | .opt_name = MSG_updpmlist, |
3075 | .opt_action = pm_upddevlist, | | 3075 | .opt_action = pm_upddevlist, |
3076 | }; | | 3076 | }; |
3077 | m->opts[i ] = (struct menu_ent) { | | 3077 | m->opts[i ] = (struct menu_ent) { |
3078 | .opt_name = MSG_savepm, | | 3078 | .opt_name = MSG_savepm, |
3079 | .opt_action = pm_commit, | | 3079 | .opt_action = pm_commit, |
3080 | }; | | 3080 | }; |
3081 | | | 3081 | |
3082 | if (pm_retvalue >= 0) | | 3082 | if (pm_retvalue >= 0) |
3083 | m->cursel = pm_retvalue - 1; | | 3083 | m->cursel = pm_retvalue - 1; |
3084 | return i; | | 3084 | return i; |
3085 | } | | 3085 | } |
3086 | | | 3086 | |
3087 | static void | | 3087 | static void |
3088 | pm_menuin(menudesc *m, void *arg) | | 3088 | pm_menuin(menudesc *m, void *arg) |
3089 | { | | 3089 | { |
3090 | if (pm_cursel > m->numopts) | | 3090 | if (pm_cursel > m->numopts) |
3091 | m->cursel = m->numopts; | | 3091 | m->cursel = m->numopts; |
3092 | else if (pm_cursel < 0) | | 3092 | else if (pm_cursel < 0) |
3093 | m->cursel = 0; | | 3093 | m->cursel = 0; |
3094 | else | | 3094 | else |
3095 | m->cursel = pm_cursel; | | 3095 | m->cursel = pm_cursel; |
3096 | } | | 3096 | } |
3097 | | | 3097 | |
3098 | static void | | 3098 | static void |
3099 | pm_menuout(menudesc *m, void *arg) | | 3099 | pm_menuout(menudesc *m, void *arg) |
3100 | { | | 3100 | { |
3101 | pm_cursel = m->cursel; | | 3101 | pm_cursel = m->cursel; |
3102 | } | | 3102 | } |
3103 | | | 3103 | |
3104 | /* Main partman function */ | | 3104 | /* Main partman function */ |
3105 | int | | 3105 | int |
3106 | partman(void) | | 3106 | partman(void) |
3107 | { | | 3107 | { |
3108 | int menu_no, menu_num_entries; | | 3108 | int menu_no, menu_num_entries; |
3109 | static int firstrun = 1; | | 3109 | static int firstrun = 1; |
3110 | menu_ent menu_entries[MAX_ENTRIES+6]; | | 3110 | menu_ent menu_entries[MAX_ENTRIES+6]; |
3111 | struct part_entry args[MAX_ENTRIES]; | | 3111 | struct part_entry args[MAX_ENTRIES]; |
3112 | | | 3112 | |
3113 | if (firstrun) { | | 3113 | if (firstrun) { |
3114 | check_available_binaries(); | | 3114 | check_available_binaries(); |
3115 | | | 3115 | |
3116 | if (!have_raid) | | 3116 | if (!have_raid) |
3117 | remove_raid_options(); | | 3117 | remove_raid_options(); |
3118 | else if (!(raids = calloc(MAX_RAID, sizeof(*raids)))) | | 3118 | else if (!(raids = calloc(MAX_RAID, sizeof(*raids)))) |
3119 | have_raid = 0; | | 3119 | have_raid = 0; |
3120 | | | 3120 | |
3121 | #define remove_vnd_options() (void)0 | | 3121 | #define remove_vnd_options() (void)0 |
3122 | if (!have_vnd) | | 3122 | if (!have_vnd) |
3123 | remove_vnd_options(); | | 3123 | remove_vnd_options(); |
3124 | else if (!(vnds = calloc(MAX_VND, sizeof(*vnds)))) | | 3124 | else if (!(vnds = calloc(MAX_VND, sizeof(*vnds)))) |
3125 | have_vnd = 0; | | 3125 | have_vnd = 0; |
3126 | | | 3126 | |
3127 | if (!have_cgd) | | 3127 | if (!have_cgd) |
3128 | remove_cgd_options(); | | 3128 | remove_cgd_options(); |
3129 | else if (!(cgds = calloc(MAX_CGD, sizeof(*cgds)))) | | 3129 | else if (!(cgds = calloc(MAX_CGD, sizeof(*cgds)))) |
3130 | have_cgd = 0; | | 3130 | have_cgd = 0; |
3131 | | | 3131 | |
3132 | if (!have_lvm) | | 3132 | if (!have_lvm) |
3133 | remove_lvm_options(); | | 3133 | remove_lvm_options(); |
3134 | else if (!(lvms = calloc(MAX_LVM_VG, sizeof(*lvms)))) | | 3134 | else if (!(lvms = calloc(MAX_LVM_VG, sizeof(*lvms)))) |
3135 | have_lvm = 0; | | 3135 | have_lvm = 0; |
3136 | | | 3136 | |
3137 | raids_t_info = (structinfo_t) { | | 3137 | raids_t_info = (structinfo_t) { |
3138 | .max = MAX_RAID, | | 3138 | .max = MAX_RAID, |
3139 | .entry_size = sizeof raids[0], | | 3139 | .entry_size = sizeof raids[0], |
3140 | .entry_first = &raids[0], | | 3140 | .entry_first = &raids[0], |
3141 | .entry_enabled = &(raids[0].enabled), | | 3141 | .entry_enabled = &(raids[0].enabled), |
3142 | .entry_blocked = &(raids[0].blocked), | | 3142 | .entry_blocked = &(raids[0].blocked), |
3143 | .entry_node = &(raids[0].node), | | 3143 | .entry_node = &(raids[0].node), |
3144 | }; | | 3144 | }; |
3145 | vnds_t_info = (structinfo_t) { | | 3145 | vnds_t_info = (structinfo_t) { |
3146 | .max = MAX_VND, | | 3146 | .max = MAX_VND, |
3147 | .entry_size = sizeof vnds[0], | | 3147 | .entry_size = sizeof vnds[0], |
3148 | .entry_first = &vnds[0], | | 3148 | .entry_first = &vnds[0], |
3149 | .entry_enabled = &(vnds[0].enabled), | | 3149 | .entry_enabled = &(vnds[0].enabled), |
3150 | .entry_blocked = &(vnds[0].blocked), | | 3150 | .entry_blocked = &(vnds[0].blocked), |
3151 | .entry_node = &(vnds[0].node), | | 3151 | .entry_node = &(vnds[0].node), |
3152 | }; | | 3152 | }; |
3153 | cgds_t_info = (structinfo_t) { | | 3153 | cgds_t_info = (structinfo_t) { |
3154 | .max = MAX_CGD, | | 3154 | .max = MAX_CGD, |
3155 | .entry_size = sizeof cgds[0], | | 3155 | .entry_size = sizeof cgds[0], |
3156 | .entry_first = &cgds[0], | | 3156 | .entry_first = &cgds[0], |
3157 | .entry_enabled = &(cgds[0].enabled), | | 3157 | .entry_enabled = &(cgds[0].enabled), |
3158 | .entry_blocked = &(cgds[0].blocked), | | 3158 | .entry_blocked = &(cgds[0].blocked), |
3159 | .entry_node = &(cgds[0].node), | | 3159 | .entry_node = &(cgds[0].node), |
3160 | }; | | 3160 | }; |
3161 | lvms_t_info = (structinfo_t) { | | 3161 | lvms_t_info = (structinfo_t) { |
3162 | .max = MAX_LVM_VG, | | 3162 | .max = MAX_LVM_VG, |
3163 | .entry_size = sizeof lvms[0], | | 3163 | .entry_size = sizeof lvms[0], |
3164 | .entry_first = &lvms[0], | | 3164 | .entry_first = &lvms[0], |
3165 | .entry_enabled = &(lvms[0].enabled), | | 3165 | .entry_enabled = &(lvms[0].enabled), |
3166 | .entry_blocked = &(lvms[0].blocked), | | 3166 | .entry_blocked = &(lvms[0].blocked), |
3167 | .entry_node = NULL, | | 3167 | .entry_node = NULL, |
3168 | }; | | 3168 | }; |
3169 | lv_t_info = (structinfo_t) { | | 3169 | lv_t_info = (structinfo_t) { |
3170 | .max = MAX_LVM_LV, | | 3170 | .max = MAX_LVM_LV, |
3171 | .entry_size = sizeof lvms[0].lv[0], | | 3171 | .entry_size = sizeof lvms[0].lv[0], |
3172 | .entry_first = &lvms[0].lv[0], | | 3172 | .entry_first = &lvms[0].lv[0], |
3173 | .entry_enabled = &(lvms[0].lv[0].size), | | 3173 | .entry_enabled = &(lvms[0].lv[0].size), |
3174 | .entry_blocked = &(lvms[0].lv[0].blocked), | | 3174 | .entry_blocked = &(lvms[0].lv[0].blocked), |
3175 | .parent_size = sizeof lvms[0], | | 3175 | .parent_size = sizeof lvms[0], |
3176 | }; | | 3176 | }; |
3177 | | | 3177 | |
3178 | pm_cursel = 0; | | 3178 | pm_cursel = 0; |
3179 | pm_changed = 0; | | 3179 | pm_changed = 0; |
3180 | firstrun = 0; | | 3180 | firstrun = 0; |
3181 | } | | 3181 | } |
3182 | | | 3182 | |
3183 | do { | | 3183 | do { |
3184 | menu_num_entries = pm_upddevlist(&(menudesc){.opts = menu_entries}, args); | | 3184 | menu_num_entries = pm_upddevlist(&(menudesc){.opts = menu_entries}, args); |
3185 | menu_no = new_menu(MSG_partman_header, | | 3185 | menu_no = new_menu(MSG_partman_header, |
3186 | menu_entries, menu_num_entries+1, 1, 1, 0, 75, /* Fixed width */ | | 3186 | menu_entries, menu_num_entries+1, 1, 1, 0, 75, /* Fixed width */ |
3187 | MC_ALWAYS_SCROLL | MC_NOBOX | MC_NOCLEAR, | | 3187 | MC_ALWAYS_SCROLL | MC_NOBOX | MC_NOCLEAR, |
3188 | pm_menuin, pm_menufmt, pm_menuout, NULL, MSG_finishpm); | | 3188 | pm_menuin, pm_menufmt, pm_menuout, NULL, MSG_finishpm); |
3189 | if (menu_no == -1) | | 3189 | if (menu_no == -1) |
3190 | pm_retvalue = -1; | | 3190 | pm_retvalue = -1; |
3191 | else { | | 3191 | else { |
3192 | pm_retvalue = 0; | | 3192 | pm_retvalue = 0; |
3193 | clear(); | | 3193 | clear(); |
3194 | refresh(); | | 3194 | refresh(); |
3195 | process_menu(menu_no, &args); | | 3195 | process_menu(menu_no, &args); |
3196 | free_menu(menu_no); | | 3196 | free_menu(menu_no); |
3197 | } | | 3197 | } |
3198 | | | 3198 | |
3199 | if (pm_retvalue == 0 && pm->parts != NULL) | | 3199 | if (pm_retvalue == 0 && pm->parts != NULL) |
3200 | if (pm_needsave()) | | 3200 | if (pm_needsave()) |
3201 | pm_commit(NULL, NULL); | | 3201 | pm_commit(NULL, NULL); |
3202 | | | 3202 | |
3203 | } while (pm_retvalue > 0); | | 3203 | } while (pm_retvalue > 0); |
3204 | | | 3204 | |
3205 | /* retvalue <0 - error, retvalue ==0 - user quits, retvalue >0 - all ok */ | | 3205 | /* retvalue <0 - error, retvalue ==0 - user quits, retvalue >0 - all ok */ |
3206 | return (pm_retvalue >= 0)?0:-1; | | 3206 | return (pm_retvalue >= 0)?0:-1; |
3207 | } | | 3207 | } |
3208 | | | 3208 | |
3209 | void | | 3209 | void |
3210 | update_wedges(const char *disk) | | 3210 | update_wedges(const char *disk) |
3211 | { | | 3211 | { |
3212 | check_available_binaries(); | | 3212 | check_available_binaries(); |
3213 | | | 3213 | |
3214 | if (!have_dk) | | 3214 | if (!have_dk) |
3215 | return; | | 3215 | return; |
3216 | | | 3216 | |
3217 | run_program(RUN_SILENT | RUN_ERROR_OK, | | 3217 | run_program(RUN_SILENT | RUN_ERROR_OK, |
3218 | "dkctl %s makewedges", disk); | | 3218 | "dkctl %s makewedges", disk); |
3219 | } | | 3219 | } |
3220 | | | 3220 | |
3221 | bool | | 3221 | bool |
3222 | pm_force_parts(struct pm_devs *my_pm) | | 3222 | pm_force_parts(struct pm_devs *my_pm) |
3223 | { | | 3223 | { |
3224 | if (my_pm == NULL) | | 3224 | if (my_pm == NULL) |
3225 | return false; | | 3225 | return false; |
3226 | if (my_pm->parts != NULL) | | 3226 | if (my_pm->parts != NULL) |
3227 | return true; | | 3227 | return true; |
3228 | | | 3228 | |
3229 | const struct disk_partitioning_scheme *ps = | | 3229 | const struct disk_partitioning_scheme *ps = |
3230 | select_part_scheme(my_pm, NULL, false, NULL); | | 3230 | select_part_scheme(my_pm, NULL, false, NULL); |
3231 | if (ps == NULL) | | 3231 | if (ps == NULL) |
3232 | return false; | | 3232 | return false; |
3233 | | | 3233 | |
3234 | struct disk_partitions *parts = | | 3234 | struct disk_partitions *parts = |
3235 | (*ps->create_new_for_disk)(my_pm->diskdev, 0, | | 3235 | (*ps->create_new_for_disk)(my_pm->diskdev, 0, |
3236 | my_pm->dlsize, false, NULL); | | 3236 | my_pm->dlsize, false, NULL); |
3237 | if (parts == NULL) | | 3237 | if (parts == NULL) |
3238 | return false; | | 3238 | return false; |
3239 | | | 3239 | |
3240 | my_pm->parts = parts; | | 3240 | my_pm->parts = parts; |
3241 | if (pm->dlsize > ps->size_limit) | | 3241 | if (pm->dlsize > ps->size_limit) |
3242 | pm->dlsize = ps->size_limit; | | 3242 | pm->dlsize = ps->size_limit; |
3243 | | | 3243 | |
3244 | return true; | | 3244 | return true; |
3245 | } | | 3245 | } |
3246 | | | 3246 | |
3247 | void | | 3247 | void |
3248 | pm_edit_partitions(struct part_entry *pe) | | 3248 | pm_edit_partitions(struct part_entry *pe) |
3249 | { | | 3249 | { |
3250 | struct pm_devs *my_pm = pm_from_pe(pe); | | 3250 | struct pm_devs *my_pm = pm_from_pe(pe); |
3251 | struct partition_usage_set pset = { 0 }; | | 3251 | struct partition_usage_set pset = { 0 }; |
3252 | struct disk_partitions *parts, *np; | | 3252 | struct disk_partitions *parts, *np; |
3253 | | | 3253 | |
3254 | if (!my_pm) | | 3254 | if (!my_pm) |
3255 | return; | | 3255 | return; |
3256 | | | 3256 | |
3257 | if (!pm_force_parts(my_pm)) | | 3257 | if (!pm_force_parts(my_pm)) |
3258 | return; | | 3258 | return; |
3259 | parts = my_pm->parts; | | 3259 | parts = my_pm->parts; |
3260 | | | 3260 | |
3261 | clear(); | | 3261 | clear(); |
3262 | refresh(); | | 3262 | refresh(); |
3263 | | | 3263 | |
3264 | if (my_pm->parts->pscheme->secondary_scheme != NULL) { | | 3264 | if (my_pm->parts->pscheme->secondary_scheme != NULL) { |
3265 | if (!edit_outer_parts(my_pm->parts)) | | 3265 | if (!edit_outer_parts(my_pm->parts)) |
3266 | goto done; | | 3266 | goto done; |
3267 | np = get_inner_parts(parts); | | 3267 | np = get_inner_parts(parts); |
3268 | if (np != NULL) | | 3268 | if (np != NULL) |
3269 | parts = np; | | 3269 | parts = np; |
3270 | } | | 3270 | } |
3271 | | | 3271 | |
3272 | if (parts != NULL) { | | 3272 | if (parts != NULL) { |
3273 | usage_set_from_parts(&pset, parts); | | 3273 | usage_set_from_parts(&pset, parts); |
3274 | edit_and_check_label(my_pm, &pset, false); | | 3274 | edit_and_check_label(my_pm, &pset, false); |
3275 | free_usage_set(&pset); | | 3275 | free_usage_set(&pset); |
3276 | } | | 3276 | } |
3277 | | | 3277 | |
3278 | done: | | 3278 | done: |
3279 | pm_partusage(my_pm, -1, -1); | | 3279 | pm_partusage(my_pm, -1, -1); |
3280 | my_pm->unsaved = true; | | 3280 | my_pm->unsaved = true; |
3281 | pm_retvalue = 1; | | 3281 | pm_retvalue = 1; |
3282 | } | | 3282 | } |
3283 | | | 3283 | |
3284 | part_id | | 3284 | part_id |
3285 | pm_whole_disk(struct part_entry *pe, int t) | | 3285 | pm_whole_disk(struct part_entry *pe, int t) |
3286 | { | | 3286 | { |
3287 | struct pm_devs *my_pm = pm_from_pe(pe); | | 3287 | struct pm_devs *my_pm = pm_from_pe(pe); |
3288 | struct disk_partitions *parts, *outer; | | 3288 | struct disk_partitions *parts, *outer; |
3289 | struct disk_part_info info, oinfo; | | 3289 | struct disk_part_info info, oinfo; |
3290 | struct disk_part_free_space space; | | 3290 | struct disk_part_free_space space; |
3291 | daddr_t align; | | 3291 | daddr_t align; |
3292 | int fst; | | 3292 | int fst; |
3293 | struct partition_usage_set pset = { 0 }; | | 3293 | struct partition_usage_set pset = { 0 }; |
3294 | part_id new_part, id; | | 3294 | part_id new_part, id; |
3295 | size_t i, cnt; | | 3295 | size_t i, cnt; |
3296 | | | 3296 | |
3297 | if (!my_pm) | | 3297 | if (!my_pm) |
3298 | return NO_PART; | | 3298 | return NO_PART; |
3299 | | | 3299 | |
3300 | if (!pm_force_parts(my_pm)) | | 3300 | if (!pm_force_parts(my_pm)) |
3301 | return NO_PART; | | 3301 | return NO_PART; |
3302 | | | 3302 | |
3303 | parts = my_pm->parts; | | 3303 | parts = my_pm->parts; |
3304 | parts->pscheme->delete_all_partitions(parts); | | 3304 | parts->pscheme->delete_all_partitions(parts); |
3305 | if (parts->pscheme->secondary_scheme != NULL) { | | 3305 | if (parts->pscheme->secondary_scheme != NULL) { |
3306 | outer = parts; | | 3306 | outer = parts; |
3307 | parts = parts->pscheme->secondary_partitions(outer, | | 3307 | parts = parts->pscheme->secondary_partitions(outer, |
3308 | 0, true); | | 3308 | 0, true); |
3309 | if (parts == NULL) { | | 3309 | if (parts == NULL) { |
3310 | parts = outer; | | 3310 | parts = outer; |
3311 | } else { | | 3311 | } else { |
3312 | if (outer->pscheme->write_to_disk(outer)) | | 3312 | if (outer->pscheme->write_to_disk(outer)) |
3313 | my_pm->parts = parts; | | 3313 | my_pm->parts = parts; |
3314 | } | | 3314 | } |
3315 | } | | 3315 | } |
3316 | | | 3316 | |
3317 | align = parts->pscheme->get_part_alignment(parts); | | 3317 | align = parts->pscheme->get_part_alignment(parts); |
3318 | | | 3318 | |
3319 | memset(&info, 0, sizeof info); | | 3319 | memset(&info, 0, sizeof info); |
3320 | switch (t) { | | 3320 | switch (t) { |
3321 | case SY_NEWRAID: | | 3321 | case SY_NEWRAID: |
3322 | fst = FS_RAID; | | 3322 | fst = FS_RAID; |
3323 | break; | | 3323 | break; |
3324 | case SY_NEWLVM: | | 3324 | case SY_NEWLVM: |
3325 | fst = FS_BSDFFS; | | 3325 | fst = FS_BSDFFS; |
3326 | break; | | 3326 | break; |
3327 | case SY_NEWCGD: | | 3327 | case SY_NEWCGD: |
3328 | fst = FS_CGD; | | 3328 | fst = FS_CGD; |
3329 | break; | | 3329 | break; |
3330 | default: | | 3330 | default: |
3331 | assert(false); | | 3331 | assert(false); |
3332 | return NO_PART; | | 3332 | return NO_PART; |
3333 | } | | 3333 | } |
3334 | info.nat_type = parts->pscheme->get_fs_part_type(PT_root, fst, 0); | | 3334 | info.nat_type = parts->pscheme->get_fs_part_type(PT_root, fst, 0); |
3335 | if (info.nat_type != NULL && parts->pscheme->get_default_fstype != NULL) | | 3335 | if (info.nat_type != NULL && parts->pscheme->get_default_fstype != NULL) |
3336 | parts->pscheme->get_default_fstype(info.nat_type, | | 3336 | parts->pscheme->get_default_fstype(info.nat_type, |
3337 | &info.fs_type, &info.fs_sub_type); | | 3337 | &info.fs_type, &info.fs_sub_type); |
3338 | if (parts->pscheme->get_free_spaces(parts, &space, 1, | | 3338 | if (parts->pscheme->get_free_spaces(parts, &space, 1, |
3339 | 5*align, align, -1, -1) != 1) | | 3339 | 5*align, align, -1, -1) != 1) |
3340 | return NO_PART; | | 3340 | return NO_PART; |
3341 | info.start = space.start; | | 3341 | info.start = space.start; |
3342 | info.size = space.size; | | 3342 | info.size = space.size; |
3343 | new_part = parts->pscheme->add_partition(parts, &info, NULL); | | 3343 | new_part = parts->pscheme->add_partition(parts, &info, NULL); |
3344 | if (new_part == NO_PART) | | 3344 | if (new_part == NO_PART) |
3345 | return NO_PART; | | 3345 | return NO_PART; |
3346 | | | 3346 | |
3347 | parts->pscheme->get_part_info(parts, new_part, &oinfo); | | 3347 | parts->pscheme->get_part_info(parts, new_part, &oinfo); |
3348 | | | 3348 | |
3349 | clear(); | | 3349 | clear(); |
3350 | refresh(); | | 3350 | refresh(); |
3351 | | | 3351 | |
3352 | usage_set_from_parts(&pset, parts); | | 3352 | usage_set_from_parts(&pset, parts); |
3353 | edit_and_check_label(my_pm, &pset, false); | | 3353 | edit_and_check_label(my_pm, &pset, false); |
3354 | free_usage_set(&pset); | | 3354 | free_usage_set(&pset); |
3355 | | | 3355 | |
3356 | /* | | 3356 | /* |
3357 | * Try to match our new partition after user edit | | 3357 | * Try to match our new partition after user edit |
3358 | */ | | 3358 | */ |
3359 | new_part = NO_PART; | | 3359 | new_part = NO_PART; |
3360 | for (cnt = i = 0; i < parts->num_part; i++) { | | 3360 | for (cnt = i = 0; i < parts->num_part; i++) { |
3361 | if (!parts->pscheme->get_part_info(parts,i, &info)) | | 3361 | if (!parts->pscheme->get_part_info(parts,i, &info)) |
3362 | continue; | | 3362 | continue; |
3363 | if (info.flags & (PTI_SEC_CONTAINER|PTI_WHOLE_DISK| | | 3363 | if (info.flags & (PTI_SEC_CONTAINER|PTI_WHOLE_DISK| |
3364 | PTI_PSCHEME_INTERNAL|PTI_RAW_PART)) | | 3364 | PTI_PSCHEME_INTERNAL|PTI_RAW_PART)) |
3365 | continue; | | 3365 | continue; |
3366 | if (info.nat_type != oinfo.nat_type) | | 3366 | if (info.nat_type != oinfo.nat_type) |
3367 | continue; | | 3367 | continue; |
3368 | if (new_part == NO_PART) | | 3368 | if (new_part == NO_PART) |
3369 | new_part = i; | | 3369 | new_part = i; |
3370 | cnt++; | | 3370 | cnt++; |
3371 | } | | 3371 | } |
3372 | if (cnt > 1) { | | 3372 | if (cnt > 1) { |
3373 | /* multiple matches, retry matching with start */ | | 3373 | /* multiple matches, retry matching with start */ |
3374 | id = NO_PART; | | 3374 | id = NO_PART; |
3375 | for (cnt = i = 0; i < parts->num_part; i++) { | | 3375 | for (cnt = i = 0; i < parts->num_part; i++) { |
3376 | if (!parts->pscheme->get_part_info(parts, i, &info)) | | 3376 | if (!parts->pscheme->get_part_info(parts, i, &info)) |
3377 | continue; | | 3377 | continue; |
3378 | if (info.flags & (PTI_SEC_CONTAINER|PTI_WHOLE_DISK| | | 3378 | if (info.flags & (PTI_SEC_CONTAINER|PTI_WHOLE_DISK| |
3379 | PTI_PSCHEME_INTERNAL|PTI_RAW_PART)) | | 3379 | PTI_PSCHEME_INTERNAL|PTI_RAW_PART)) |
3380 | continue; | | 3380 | continue; |
3381 | if (info.nat_type != oinfo.nat_type) | | 3381 | if (info.nat_type != oinfo.nat_type) |
3382 | continue; | | 3382 | continue; |
3383 | if (info.start != oinfo.start) | | 3383 | if (info.start != oinfo.start) |
3384 | continue; | | 3384 | continue; |
3385 | if (id == NO_PART) | | 3385 | if (id == NO_PART) |
3386 | id = i; | | 3386 | id = i; |
3387 | cnt++; | | 3387 | cnt++; |
3388 | } | | 3388 | } |
3389 | if (id != NO_PART) | | 3389 | if (id != NO_PART) |
3390 | new_part = id; | | 3390 | new_part = id; |
3391 | } | | 3391 | } |
3392 | | | 3392 | |
3393 | clear(); | | 3393 | clear(); |
3394 | refresh(); | | 3394 | refresh(); |
3395 | | | 3395 | |
3396 | pm_partusage(my_pm, -1, -1); | | 3396 | pm_partusage(my_pm, -1, -1); |
3397 | my_pm->unsaved = true; | | 3397 | my_pm->unsaved = true; |
3398 | pm_retvalue = 1; | | 3398 | pm_retvalue = 1; |
3399 | | | 3399 | |
3400 | return new_part; | | 3400 | return new_part; |
3401 | } | | 3401 | } |
3402 | | | 3402 | |
3403 | struct pm_devs * | | 3403 | struct pm_devs * |
3404 | pm_from_pe(struct part_entry *pe) | | 3404 | pm_from_pe(struct part_entry *pe) |
3405 | { | | 3405 | { |
3406 | switch (pe->type) { | | 3406 | switch (pe->type) { |
3407 | case PM_DISK: | | 3407 | case PM_DISK: |
3408 | return pe->dev_ptr; | | 3408 | return pe->dev_ptr; |
3409 | default: | | 3409 | default: |
3410 | assert(false); | | 3410 | assert(false); |
3411 | } | | 3411 | } |
3412 | return NULL; | | 3412 | return NULL; |
3413 | } | | 3413 | } |