]>
Commit | Line | Data |
---|---|---|
8adbcf0c KZ |
1 | |
2 | #include "fdiskP.h" | |
8ec0c305 | 3 | #include "cctype.h" |
8adbcf0c | 4 | |
aa36c2cf | 5 | |
5175ae87 KZ |
6 | /** |
7 | * SECTION: label | |
705854f3 KZ |
8 | * @title: Label |
9 | * @short_description: disk label (PT) specific data and functions | |
5175ae87 KZ |
10 | * |
11 | * The fdisk_new_context() initializes all label drivers, and allocate | |
29e204d1 | 12 | * per-label specific data struct. This concept can be used to store label specific |
5175ae87 | 13 | * settings to the label driver independently on the currently active label |
0e679d79 | 14 | * driver. Note that label struct cannot be deallocated, so there is no |
3c5ee57c KZ |
15 | * reference counting for fdisk_label objects. All is destroyed by |
16 | * fdisk_unref_context() only. | |
5175ae87 KZ |
17 | * |
18 | * Anyway, all label drives share in-memory first sector. The function | |
9e930041 | 19 | * fdisk_create_disklabel() overwrites this in-memory sector. But it's possible that |
dee59a1e KZ |
20 | * label driver also uses another buffers, for example GPT reads more sectors |
21 | * from the device. | |
5175ae87 KZ |
22 | * |
23 | * All label operations are in-memory only, except fdisk_write_disklabel(). | |
24 | * | |
25 | * All functions that use "struct fdisk_context" rather than "struct | |
26 | * fdisk_label" use the currently active label driver. | |
7ce10975 | 27 | */ |
0e679d79 KZ |
28 | |
29 | ||
7ce10975 KZ |
30 | int fdisk_probe_labels(struct fdisk_context *cxt) |
31 | { | |
32 | size_t i; | |
33 | ||
4e0e8253 | 34 | cxt->label = NULL; |
7ce10975 | 35 | |
0c5d095e | 36 | for (i = 0; i < cxt->nlabels; i++) { |
4e0e8253 | 37 | struct fdisk_label *lb = cxt->labels[i]; |
aa36c2cf | 38 | struct fdisk_label *org = fdisk_get_label(cxt, NULL); |
d71ef5a4 | 39 | int rc; |
4e0e8253 KZ |
40 | |
41 | if (!lb->op->probe) | |
7ce10975 | 42 | continue; |
7a188aed | 43 | if (lb->disabled) { |
d71bd2f0 | 44 | DBG(CXT, ul_debugobj(cxt, "%s: disabled -- ignore", lb->name)); |
7a188aed KZ |
45 | continue; |
46 | } | |
d71bd2f0 | 47 | DBG(CXT, ul_debugobj(cxt, "probing for %s", lb->name)); |
d71ef5a4 KZ |
48 | |
49 | cxt->label = lb; | |
9ffeb235 | 50 | rc = lb->op->probe(cxt); |
d71ef5a4 KZ |
51 | cxt->label = org; |
52 | ||
53 | if (rc != 1) { | |
4e0e8253 KZ |
54 | if (lb->op->deinit) |
55 | lb->op->deinit(lb); /* for sure */ | |
56 | continue; | |
57 | } | |
7ce10975 | 58 | |
6a632136 | 59 | __fdisk_switch_label(cxt, lb); |
7ce10975 KZ |
60 | return 0; |
61 | } | |
62 | ||
d71bd2f0 | 63 | DBG(CXT, ul_debugobj(cxt, "no label found")); |
7ce10975 KZ |
64 | return 1; /* not found */ |
65 | } | |
66 | ||
8adbcf0c | 67 | /** |
aa36c2cf KZ |
68 | * fdisk_label_get_name: |
69 | * @lb: label | |
8adbcf0c | 70 | * |
aa36c2cf | 71 | * Returns: label name |
8adbcf0c | 72 | */ |
eac3aac9 | 73 | const char *fdisk_label_get_name(const struct fdisk_label *lb) |
8adbcf0c | 74 | { |
aa36c2cf | 75 | return lb ? lb->name : NULL; |
8adbcf0c KZ |
76 | } |
77 | ||
4af064f3 KZ |
78 | /** |
79 | * fdisk_label_is_labeltype: | |
80 | * @lb: label | |
4af064f3 | 81 | * |
1753a234 | 82 | * Returns: FDISK_DISKLABEL_*. |
4af064f3 | 83 | */ |
eac3aac9 | 84 | int fdisk_label_get_type(const struct fdisk_label *lb) |
4af064f3 | 85 | { |
1753a234 | 86 | return lb->id; |
4af064f3 KZ |
87 | } |
88 | ||
72d2965c KZ |
89 | /** |
90 | * fdisk_label_require_geometry: | |
91 | * @lb: label | |
92 | * | |
93 | * Returns: 1 if label requires CHS geometry | |
94 | */ | |
eac3aac9 | 95 | int fdisk_label_require_geometry(const struct fdisk_label *lb) |
72d2965c KZ |
96 | { |
97 | assert(lb); | |
98 | ||
99 | return lb->flags & FDISK_LABEL_FL_REQUIRE_GEOMETRY ? 1 : 0; | |
100 | } | |
101 | ||
8adbcf0c | 102 | /** |
11ee1177 KZ |
103 | * fdisk_label_get_fields_ids |
104 | * @lb: label (or NULL for the current label) | |
705854f3 | 105 | * @cxt: context |
bd85d11f KZ |
106 | * @ids: returns allocated array with FDISK_FIELD_* IDs |
107 | * @nids: returns number of items in fields | |
8152753d | 108 | * |
11ee1177 KZ |
109 | * This function returns the default fields for the label. |
110 | * | |
111 | * Note that the set of the default fields depends on fdisk_enable_details() | |
112 | * function. If the details are enabled then this function usually returns more | |
113 | * fields. | |
d6faa8e0 | 114 | * |
705854f3 | 115 | * Returns: 0 on success, otherwise, a corresponding error. |
8152753d | 116 | */ |
11ee1177 | 117 | int fdisk_label_get_fields_ids( |
eac3aac9 | 118 | const struct fdisk_label *lb, |
11ee1177 KZ |
119 | struct fdisk_context *cxt, |
120 | int **ids, size_t *nids) | |
8152753d KZ |
121 | { |
122 | size_t i, n; | |
123 | int *c; | |
124 | ||
1c3c92cd | 125 | if (!cxt || (!lb && !cxt->label)) |
8152753d | 126 | return -EINVAL; |
1c3c92cd KZ |
127 | |
128 | lb = cxt->label; | |
11ee1177 | 129 | if (!lb->fields || !lb->nfields) |
8152753d | 130 | return -ENOSYS; |
11ee1177 | 131 | c = calloc(lb->nfields, sizeof(int)); |
8152753d KZ |
132 | if (!c) |
133 | return -ENOMEM; | |
11ee1177 KZ |
134 | for (n = 0, i = 0; i < lb->nfields; i++) { |
135 | int id = lb->fields[i].id; | |
d0059a24 | 136 | |
11ee1177 KZ |
137 | if ((fdisk_is_details(cxt) && |
138 | (lb->fields[i].flags & FDISK_FIELDFL_EYECANDY)) | |
6a632136 | 139 | || (!fdisk_is_details(cxt) && |
11ee1177 | 140 | (lb->fields[i].flags & FDISK_FIELDFL_DETAIL)) |
bd85d11f | 141 | || (id == FDISK_FIELD_SECTORS && |
6a632136 | 142 | fdisk_use_cylinders(cxt)) |
bd85d11f | 143 | || (id == FDISK_FIELD_CYLINDERS && |
11ee1177 | 144 | !fdisk_use_cylinders(cxt))) |
8152753d | 145 | continue; |
d0059a24 KZ |
146 | |
147 | c[n++] = id; | |
8152753d | 148 | } |
bd85d11f KZ |
149 | if (ids) |
150 | *ids = c; | |
1671b2ed KZ |
151 | else |
152 | free(c); | |
bd85d11f KZ |
153 | if (nids) |
154 | *nids = n; | |
8152753d KZ |
155 | return 0; |
156 | } | |
157 | ||
31ea7fa6 KZ |
158 | /** |
159 | * fdisk_label_get_fields_ids_all | |
160 | * @lb: label (or NULL for the current label) | |
161 | * @cxt: context | |
162 | * @ids: returns allocated array with FDISK_FIELD_* IDs | |
163 | * @nids: returns number of items in fields | |
164 | * | |
165 | * This function returns all fields for the label. | |
166 | * | |
167 | * Returns: 0 on success, otherwise, a corresponding error. | |
168 | */ | |
169 | int fdisk_label_get_fields_ids_all( | |
170 | const struct fdisk_label *lb, | |
171 | struct fdisk_context *cxt, | |
172 | int **ids, size_t *nids) | |
173 | { | |
174 | size_t i, n; | |
175 | int *c; | |
176 | ||
1c3c92cd | 177 | if (!cxt || (!lb && !cxt->label)) |
31ea7fa6 | 178 | return -EINVAL; |
1c3c92cd KZ |
179 | |
180 | lb = cxt->label; | |
31ea7fa6 KZ |
181 | if (!lb->fields || !lb->nfields) |
182 | return -ENOSYS; | |
183 | c = calloc(lb->nfields, sizeof(int)); | |
184 | if (!c) | |
185 | return -ENOMEM; | |
186 | for (n = 0, i = 0; i < lb->nfields; i++) | |
187 | c[n++] = lb->fields[i].id; | |
188 | if (ids) | |
189 | *ids = c; | |
190 | else | |
191 | free(c); | |
192 | if (nids) | |
193 | *nids = n; | |
194 | return 0; | |
195 | } | |
196 | ||
5175ae87 KZ |
197 | /** |
198 | * fdisk_label_get_field: | |
199 | * @lb: label | |
200 | * @id: FDISK_FIELD_* | |
201 | * | |
202 | * The field struct describes data stored in struct fdisk_partition. The info | |
203 | * about data is usable for example to generate human readable output (e.g. | |
0c07055c | 204 | * fdisk 'p'rint command). See fdisk_partition_to_string() and fdisk code. |
5175ae87 KZ |
205 | * |
206 | * Returns: pointer to static instance of the field. | |
207 | */ | |
eac3aac9 | 208 | const struct fdisk_field *fdisk_label_get_field(const struct fdisk_label *lb, int id) |
8152753d KZ |
209 | { |
210 | size_t i; | |
211 | ||
212 | assert(lb); | |
213 | assert(id > 0); | |
214 | ||
bd85d11f KZ |
215 | for (i = 0; i < lb->nfields; i++) { |
216 | if (lb->fields[i].id == id) | |
217 | return &lb->fields[i]; | |
8152753d KZ |
218 | } |
219 | ||
220 | return NULL; | |
221 | } | |
222 | ||
eac3aac9 KZ |
223 | /** |
224 | * fdisk_label_get_field_by_name | |
225 | * @lb: label | |
226 | * @name: field name | |
227 | * | |
228 | * Returns: pointer to static instance of the field. | |
229 | */ | |
230 | const struct fdisk_field *fdisk_label_get_field_by_name( | |
231 | const struct fdisk_label *lb, | |
232 | const char *name) | |
233 | { | |
234 | size_t i; | |
235 | ||
236 | assert(lb); | |
237 | assert(name); | |
238 | ||
239 | for (i = 0; i < lb->nfields; i++) { | |
8ec0c305 | 240 | if (lb->fields[i].name && c_strcasecmp(lb->fields[i].name, name) == 0) |
eac3aac9 KZ |
241 | return &lb->fields[i]; |
242 | } | |
243 | ||
244 | return NULL; | |
245 | } | |
246 | ||
11ee1177 KZ |
247 | /** |
248 | * fdisk_write_disklabel: | |
249 | * @cxt: fdisk context | |
250 | * | |
f1424a94 | 251 | * This function wipes the device (if enabled by fdisk_enable_wipe()) and then |
9335bfc8 | 252 | * it writes in-memory changes to disk. Be careful! |
11ee1177 | 253 | * |
705854f3 | 254 | * Returns: 0 on success, otherwise, a corresponding error. |
11ee1177 KZ |
255 | */ |
256 | int fdisk_write_disklabel(struct fdisk_context *cxt) | |
257 | { | |
258 | if (!cxt || !cxt->label || cxt->readonly) | |
259 | return -EINVAL; | |
260 | if (!cxt->label->op->write) | |
261 | return -ENOSYS; | |
6cbb7371 | 262 | |
131e38a2 | 263 | fdisk_do_wipe(cxt); |
11ee1177 KZ |
264 | return cxt->label->op->write(cxt); |
265 | } | |
266 | ||
8adbcf0c KZ |
267 | /** |
268 | * fdisk_verify_disklabel: | |
269 | * @cxt: fdisk context | |
270 | * | |
271 | * Verifies the partition table. | |
272 | * | |
c7fce443 | 273 | * Returns: 0 on success, <1 runtime or option errors, >0 number of detected issues |
8adbcf0c KZ |
274 | */ |
275 | int fdisk_verify_disklabel(struct fdisk_context *cxt) | |
276 | { | |
277 | if (!cxt || !cxt->label) | |
278 | return -EINVAL; | |
0c5d095e | 279 | if (!cxt->label->op->verify) |
8adbcf0c | 280 | return -ENOSYS; |
0b52b94c KZ |
281 | if (fdisk_missing_geometry(cxt)) |
282 | return -EINVAL; | |
8adbcf0c | 283 | |
9ffeb235 | 284 | return cxt->label->op->verify(cxt); |
8adbcf0c KZ |
285 | } |
286 | ||
3c5fb475 KZ |
287 | /** |
288 | * fdisk_list_disklabel: | |
289 | * @cxt: fdisk context | |
290 | * | |
6c89f750 | 291 | * Lists details about disklabel, but no partitions. |
8152753d | 292 | * |
5989556a KZ |
293 | * This function is based on fdisk_get_disklabel_item() and prints all label |
294 | * specific information by ASK interface (FDISK_ASKTYPE_INFO, aka fdisk_info()). | |
295 | * The function requires enabled "details" by fdisk_enable_details(). | |
296 | * | |
297 | * It's recommended to use fdisk_get_disklabel_item() if you need better | |
9e930041 | 298 | * control on output and formatting. |
3c5fb475 | 299 | * |
705854f3 | 300 | * Returns: 0 on success, otherwise, a corresponding error. |
3c5fb475 KZ |
301 | */ |
302 | int fdisk_list_disklabel(struct fdisk_context *cxt) | |
303 | { | |
5989556a KZ |
304 | int id = 0, rc = 0; |
305 | struct fdisk_labelitem item = { .id = id }; | |
306 | ||
3c5fb475 KZ |
307 | if (!cxt || !cxt->label) |
308 | return -EINVAL; | |
3c5fb475 | 309 | |
5989556a KZ |
310 | if (!cxt->display_details) |
311 | return 0; | |
312 | ||
313 | /* List all label items */ | |
314 | do { | |
315 | /* rc: < 0 error, 0 success, 1 unknown item, 2 out of range */ | |
316 | rc = fdisk_get_disklabel_item(cxt, id++, &item); | |
317 | if (rc != 0) | |
318 | continue; | |
319 | switch (item.type) { | |
320 | case 'j': | |
321 | fdisk_info(cxt, "%s: %ju", item.name, item.data.num64); | |
322 | break; | |
323 | case 's': | |
324 | if (item.data.str && item.name) | |
325 | fdisk_info(cxt, "%s: %s", item.name, item.data.str); | |
5989556a KZ |
326 | break; |
327 | } | |
40c9c3a6 | 328 | fdisk_reset_labelitem(&item); |
5989556a KZ |
329 | } while (rc == 0 || rc == 1); |
330 | ||
331 | return rc < 0 ? rc : 0; | |
3c5fb475 KZ |
332 | } |
333 | ||
7ce10975 KZ |
334 | /** |
335 | * fdisk_create_disklabel: | |
336 | * @cxt: fdisk context | |
337 | * @name: label name | |
338 | * | |
5175ae87 KZ |
339 | * Creates a new disk label of type @name. If @name is NULL, then it will |
340 | * create a default system label type, either SUN or DOS. The function | |
9e930041 | 341 | * automatically switches the current label driver to @name. The function |
5175ae87 KZ |
342 | * fdisk_get_label() returns the current label driver. |
343 | * | |
344 | * The function modifies in-memory data only. | |
7ce10975 | 345 | * |
705854f3 | 346 | * Returns: 0 on success, otherwise, a corresponding error. |
7ce10975 KZ |
347 | */ |
348 | int fdisk_create_disklabel(struct fdisk_context *cxt, const char *name) | |
349 | { | |
c9674e73 | 350 | int haslabel = 0, rc; |
8a9256f9 | 351 | struct fdisk_label *lb; |
1653f0b0 | 352 | |
7ce10975 KZ |
353 | if (!cxt) |
354 | return -EINVAL; | |
355 | ||
7ce10975 KZ |
356 | if (!name) { /* use default label creation */ |
357 | #ifdef __sparc__ | |
0c5d095e | 358 | name = "sun"; |
7ce10975 | 359 | #else |
0c5d095e | 360 | name = "dos"; |
7ce10975 | 361 | #endif |
7ce10975 KZ |
362 | } |
363 | ||
1653f0b0 | 364 | if (cxt->label) { |
0559e742 | 365 | fdisk_deinit_label(cxt->label); |
1653f0b0 KZ |
366 | haslabel = 1; |
367 | } | |
4e0e8253 | 368 | |
6a632136 | 369 | lb = fdisk_get_label(cxt, name); |
7a188aed | 370 | if (!lb || lb->disabled) |
7ce10975 | 371 | return -EINVAL; |
37204dc6 KZ |
372 | |
373 | if (!haslabel || (lb && cxt->label != lb)) | |
374 | fdisk_check_collisions(cxt); | |
375 | ||
8a9256f9 | 376 | if (!lb->op->create) |
7ce10975 KZ |
377 | return -ENOSYS; |
378 | ||
c9674e73 KZ |
379 | rc = __fdisk_switch_label(cxt, lb); |
380 | if (rc) | |
381 | return rc; | |
382 | ||
1c736ff3 | 383 | assert(cxt->label == lb); |
8a9256f9 | 384 | |
c9674e73 KZ |
385 | if (haslabel && !cxt->parent) { |
386 | rc = fdisk_reset_device_properties(cxt); | |
387 | if (rc) | |
388 | return rc; | |
389 | } | |
8a9256f9 | 390 | |
c9674e73 | 391 | DBG(CXT, ul_debugobj(cxt, "creating a new %s label", lb->name)); |
1c736ff3 | 392 | return lb->op->create(cxt); |
7ce10975 | 393 | } |
21fe3dde | 394 | |
5ab37600 KZ |
395 | /** |
396 | * fdisk_locate_disklabel: | |
397 | * @cxt: context | |
398 | * @n: N item | |
399 | * @name: return item name | |
400 | * @offset: return offset where is item | |
401 | * @size: of the item | |
402 | * | |
93737ad3 KZ |
403 | * Locate disklabel and returns info about @n item of the label. |
404 | * | |
405 | * For example GPT is composed from three items, PMBR and GPT, n=0 return | |
406 | * offset to PMBR and n=1 return offset to GPT Header and n=2 returns offset to | |
407 | * GPT array of partitions, n=3 and n=4 returns location of the backup GPT | |
408 | * label at the end of the disk. | |
409 | * | |
410 | * The function returns the current in-memory situation. It's possible that a | |
411 | * header location is modified by write operation, for example when enabled | |
412 | * minimization (see fdisk_gpt_enable_minimize()). In this case it's better to | |
413 | * call this function after fdisk_write_disklabel(). | |
414 | * | |
415 | * For more details see 'D' expert fdisk command. | |
5ab37600 | 416 | * |
9e930041 | 417 | * Returns: 0 on success, <0 on error, 1 no more items. |
5ab37600 | 418 | */ |
c0d20aae | 419 | int fdisk_locate_disklabel(struct fdisk_context *cxt, int n, const char **name, |
9bbcf43f | 420 | uint64_t *offset, size_t *size) |
c0d20aae KZ |
421 | { |
422 | if (!cxt || !cxt->label) | |
423 | return -EINVAL; | |
424 | if (!cxt->label->op->locate) | |
425 | return -ENOSYS; | |
426 | ||
d71bd2f0 | 427 | DBG(CXT, ul_debugobj(cxt, "locating %d chunk of %s.", n, cxt->label->name)); |
c0d20aae KZ |
428 | return cxt->label->op->locate(cxt, n, name, offset, size); |
429 | } | |
430 | ||
431 | ||
21fe3dde KZ |
432 | /** |
433 | * fdisk_get_disklabel_id: | |
434 | * @cxt: fdisk context | |
5175ae87 | 435 | * @id: returns pointer to allocated string (MBR Id or GPT dirk UUID) |
21fe3dde | 436 | * |
705854f3 | 437 | * Returns: 0 on success, otherwise, a corresponding error. |
21fe3dde KZ |
438 | */ |
439 | int fdisk_get_disklabel_id(struct fdisk_context *cxt, char **id) | |
440 | { | |
a50c8490 | 441 | struct fdisk_labelitem item = FDISK_LABELITEM_INIT; |
5989556a KZ |
442 | int rc; |
443 | ||
444 | if (!cxt || !cxt->label || !id) | |
21fe3dde | 445 | return -EINVAL; |
21fe3dde | 446 | |
d71bd2f0 | 447 | DBG(CXT, ul_debugobj(cxt, "asking for disk %s ID", cxt->label->name)); |
5989556a KZ |
448 | |
449 | rc = fdisk_get_disklabel_item(cxt, FDISK_LABELITEM_ID, &item); | |
40c9c3a6 | 450 | if (rc == 0) { |
5989556a | 451 | *id = item.data.str; |
40c9c3a6 KZ |
452 | item.data.str = NULL; |
453 | } | |
454 | fdisk_reset_labelitem(&item); | |
5989556a KZ |
455 | if (rc > 0) |
456 | rc = 0; | |
457 | return rc; | |
458 | } | |
459 | ||
460 | /** | |
461 | * fdisk_get_disklabel_item: | |
462 | * @cxt: fdisk context | |
f854eca3 | 463 | * @id: item ID (FDISK_LABELITEM_* or *_LABELITEM_*) |
5989556a KZ |
464 | * @item: specifies and returns the item |
465 | * | |
466 | * Note that @id is always in range 0..N. It's fine to use the function in loop | |
467 | * until it returns error or 2, the result in @item should be ignored when | |
40c9c3a6 | 468 | * function returns 1. Don't forget to use fdisk_reset_labelitem() or fdisk_unref_labelitem(). |
5989556a | 469 | * |
f854eca3 | 470 | * Returns: 0 on success, < 0 on error, 1 on unsupported item, 2 id out of range |
5989556a KZ |
471 | */ |
472 | int fdisk_get_disklabel_item(struct fdisk_context *cxt, int id, struct fdisk_labelitem *item) | |
473 | { | |
474 | if (!cxt || !cxt->label || !item) | |
475 | return -EINVAL; | |
476 | ||
40c9c3a6 | 477 | fdisk_reset_labelitem(item); |
5989556a KZ |
478 | item->id = id; |
479 | DBG(CXT, ul_debugobj(cxt, "asking for disk %s item %d", cxt->label->name, item->id)); | |
480 | ||
481 | if (!cxt->label->op->get_item) | |
482 | return -ENOSYS; | |
483 | ||
484 | return cxt->label->op->get_item(cxt, item); | |
21fe3dde | 485 | } |
35b1f0a4 KZ |
486 | |
487 | /** | |
5ab37600 | 488 | * fdisk_set_disklabel_id: |
35b1f0a4 KZ |
489 | * @cxt: fdisk context |
490 | * | |
705854f3 | 491 | * Returns: 0 on success, otherwise, a corresponding error. |
35b1f0a4 KZ |
492 | */ |
493 | int fdisk_set_disklabel_id(struct fdisk_context *cxt) | |
494 | { | |
495 | if (!cxt || !cxt->label) | |
496 | return -EINVAL; | |
497 | if (!cxt->label->op->set_id) | |
498 | return -ENOSYS; | |
499 | ||
d71bd2f0 | 500 | DBG(CXT, ul_debugobj(cxt, "setting %s disk ID", cxt->label->name)); |
e5f31446 KZ |
501 | return cxt->label->op->set_id(cxt, NULL); |
502 | } | |
503 | ||
504 | /** | |
505 | * fdisk_set_disklabel_id_from_string | |
506 | * @cxt: fdisk context | |
b7c015d1 | 507 | * @str: new Id |
e5f31446 KZ |
508 | * |
509 | * Returns: 0 on success, otherwise, a corresponding error. | |
f11fe35f KZ |
510 | * |
511 | * Since: 2.36 | |
e5f31446 KZ |
512 | */ |
513 | int fdisk_set_disklabel_id_from_string(struct fdisk_context *cxt, const char *str) | |
514 | { | |
515 | if (!cxt || !cxt->label || !str) | |
516 | return -EINVAL; | |
517 | if (!cxt->label->op->set_id) | |
518 | return -ENOSYS; | |
519 | ||
520 | DBG(CXT, ul_debugobj(cxt, "setting %s disk ID from '%s'", cxt->label->name, str)); | |
521 | return cxt->label->op->set_id(cxt, str); | |
35b1f0a4 | 522 | } |
171372d3 | 523 | |
171372d3 KZ |
524 | /** |
525 | * fdisk_set_partition_type: | |
526 | * @cxt: fdisk context | |
527 | * @partnum: partition number | |
528 | * @t: new type | |
529 | * | |
705854f3 | 530 | * Returns: 0 on success, < 0 on error. |
171372d3 | 531 | */ |
9ffeb235 KZ |
532 | int fdisk_set_partition_type(struct fdisk_context *cxt, |
533 | size_t partnum, | |
171372d3 KZ |
534 | struct fdisk_parttype *t) |
535 | { | |
ea50ba5b | 536 | if (!cxt || !cxt->label || !t) |
171372d3 KZ |
537 | return -EINVAL; |
538 | ||
b305ad40 KZ |
539 | |
540 | if (cxt->label->op->set_part) { | |
ecf40cda KZ |
541 | struct fdisk_partition *pa = fdisk_new_partition(); |
542 | int rc; | |
543 | ||
544 | if (!pa) | |
545 | return -ENOMEM; | |
546 | fdisk_partition_set_type(pa, t); | |
b305ad40 | 547 | |
ea50ba5b | 548 | DBG(CXT, ul_debugobj(cxt, "partition: %zd: set type", partnum)); |
ecf40cda KZ |
549 | rc = cxt->label->op->set_part(cxt, partnum, pa); |
550 | fdisk_unref_partition(pa); | |
551 | return rc; | |
ea50ba5b | 552 | } |
b305ad40 KZ |
553 | |
554 | return -ENOSYS; | |
171372d3 KZ |
555 | } |
556 | ||
4e0e8253 | 557 | |
fb1caca7 | 558 | /** |
a1ef792f | 559 | * fdisk_toggle_partition_flag: |
fb1caca7 KZ |
560 | * @cxt: fdisk context |
561 | * @partnum: partition number | |
705854f3 | 562 | * @flag: flag ID |
fb1caca7 | 563 | * |
705854f3 | 564 | * Returns: 0 on success, otherwise, a corresponding error. |
fb1caca7 | 565 | */ |
a1ef792f | 566 | int fdisk_toggle_partition_flag(struct fdisk_context *cxt, |
fb1caca7 KZ |
567 | size_t partnum, |
568 | unsigned long flag) | |
569 | { | |
570 | int rc; | |
571 | ||
572 | if (!cxt || !cxt->label) | |
573 | return -EINVAL; | |
574 | if (!cxt->label->op->part_toggle_flag) | |
575 | return -ENOSYS; | |
576 | ||
577 | rc = cxt->label->op->part_toggle_flag(cxt, partnum, flag); | |
578 | ||
d71bd2f0 | 579 | DBG(CXT, ul_debugobj(cxt, "partition: %zd: toggle: 0x%04lx [rc=%d]", partnum, flag, rc)); |
7845ca8d | 580 | return rc; |
47b8e7c0 KZ |
581 | } |
582 | ||
dd7ba604 KZ |
583 | /** |
584 | * fdisk_reorder_partitions | |
585 | * @cxt: fdisk context | |
586 | * | |
587 | * Sort partitions according to the partition start sector. | |
588 | * | |
dd49c7d6 | 589 | * Returns: 0 on success, 1 reorder unnecessary, otherwise a corresponding error. |
dd7ba604 KZ |
590 | */ |
591 | int fdisk_reorder_partitions(struct fdisk_context *cxt) | |
592 | { | |
f05a5bb2 PR |
593 | int rc; |
594 | ||
dd7ba604 KZ |
595 | if (!cxt || !cxt->label) |
596 | return -EINVAL; | |
597 | if (!cxt->label->op->reorder) | |
598 | return -ENOSYS; | |
599 | ||
f05a5bb2 PR |
600 | rc = cxt->label->op->reorder(cxt); |
601 | ||
602 | switch (rc) { | |
603 | case 0: | |
604 | fdisk_info(cxt, _("Partitions order fixed.")); | |
605 | break; | |
606 | case 1: | |
607 | fdisk_info(cxt, _("Nothing to do. Ordering is correct already.")); | |
608 | break; | |
609 | default: | |
610 | fdisk_warnx(cxt, _("Failed to fix partitions order.")); | |
611 | break; | |
612 | } | |
613 | ||
614 | return rc; | |
dd7ba604 KZ |
615 | } |
616 | ||
4e0e8253 KZ |
617 | /* |
618 | * Resets the current used label driver to initial state | |
619 | */ | |
0559e742 | 620 | void fdisk_deinit_label(struct fdisk_label *lb) |
4e0e8253 | 621 | { |
0559e742 | 622 | assert(lb); |
4e0e8253 | 623 | |
0559e742 KZ |
624 | /* private label information */ |
625 | if (lb->op->deinit) | |
626 | lb->op->deinit(lb); | |
4e0e8253 | 627 | } |
2e3b40d3 | 628 | |
5175ae87 KZ |
629 | /** |
630 | * fdisk_label_set_changed: | |
631 | * @lb: label | |
632 | * @changed: 0/1 | |
633 | * | |
634 | * Marks in-memory data as changed, to force fdisk_write_disklabel() to write | |
9e930041 | 635 | * to device. This should be unnecessary by default, the library keeps track |
5175ae87 KZ |
636 | * about changes. |
637 | */ | |
2e3b40d3 KZ |
638 | void fdisk_label_set_changed(struct fdisk_label *lb, int changed) |
639 | { | |
640 | assert(lb); | |
2e3b40d3 KZ |
641 | lb->changed = changed ? 1 : 0; |
642 | } | |
643 | ||
5175ae87 KZ |
644 | /** |
645 | * fdisk_label_is_changed: | |
646 | * @lb: label | |
647 | * | |
648 | * Returns: 1 if in-memory data has been changed. | |
649 | */ | |
eac3aac9 | 650 | int fdisk_label_is_changed(const struct fdisk_label *lb) |
2e3b40d3 | 651 | { |
2e3b40d3 KZ |
652 | return lb ? lb->changed : 0; |
653 | } | |
7a188aed | 654 | |
5175ae87 KZ |
655 | /** |
656 | * fdisk_label_set_disabled: | |
657 | * @lb: label | |
705854f3 | 658 | * @disabled: 0 or 1 |
5175ae87 | 659 | * |
705854f3 | 660 | * Mark label as disabled, then libfdisk is going to ignore the label when |
5175ae87 KZ |
661 | * probe device for labels. |
662 | */ | |
7a188aed KZ |
663 | void fdisk_label_set_disabled(struct fdisk_label *lb, int disabled) |
664 | { | |
665 | assert(lb); | |
666 | ||
88141067 | 667 | DBG(LABEL, ul_debug("%s label %s", |
7a188aed KZ |
668 | lb->name, |
669 | disabled ? "DISABLED" : "ENABLED")); | |
670 | lb->disabled = disabled ? 1 : 0; | |
671 | } | |
672 | ||
5175ae87 KZ |
673 | /** |
674 | * fdisk_label_is_disabled: | |
675 | * @lb: label | |
676 | * | |
677 | * Returns: 1 if label driver disabled. | |
678 | */ | |
eac3aac9 | 679 | int fdisk_label_is_disabled(const struct fdisk_label *lb) |
7a188aed KZ |
680 | { |
681 | assert(lb); | |
682 | return lb ? lb->disabled : 0; | |
683 | } | |
2dd2880f KZ |
684 | |
685 | /** | |
686 | * fdisk_label_get_geomrange_sectors: | |
687 | * @lb: label | |
688 | * @mi: minimal number | |
689 | * @ma: maximal number | |
690 | * | |
691 | * The function provides minimal and maximal geometry supported for the label, | |
f1424a94 | 692 | * if no range defined by library then returns -ENOSYS. |
2dd2880f | 693 | * |
ed930a9b KZ |
694 | * Since: 2.32 |
695 | * | |
2dd2880f KZ |
696 | * Returns: 0 on success, otherwise, a corresponding error. |
697 | */ | |
698 | int fdisk_label_get_geomrange_sectors(const struct fdisk_label *lb, | |
699 | fdisk_sector_t *mi, fdisk_sector_t *ma) | |
700 | { | |
701 | if (!lb || lb->geom_min.sectors == 0) | |
702 | return -ENOSYS; | |
703 | if (mi) | |
704 | *mi = lb->geom_min.sectors; | |
705 | if (ma) | |
706 | *ma = lb->geom_max.sectors; | |
707 | return 0; | |
708 | } | |
709 | ||
710 | /** | |
711 | * fdisk_label_get_geomrange_heads: | |
712 | * @lb: label | |
713 | * @mi: minimal number | |
714 | * @ma: maximal number | |
715 | * | |
716 | * The function provides minimal and maximal geometry supported for the label, | |
f1424a94 | 717 | * if no range defined by library then returns -ENOSYS. |
2dd2880f | 718 | * |
ed930a9b KZ |
719 | * Since: 2.32 |
720 | * | |
2dd2880f KZ |
721 | * Returns: 0 on success, otherwise, a corresponding error. |
722 | */ | |
723 | int fdisk_label_get_geomrange_heads(const struct fdisk_label *lb, | |
724 | unsigned int *mi, unsigned int *ma) | |
725 | { | |
726 | if (!lb || lb->geom_min.heads == 0) | |
727 | return -ENOSYS; | |
728 | if (mi) | |
729 | *mi = lb->geom_min.heads; | |
730 | if (ma) | |
731 | *ma = lb->geom_max.heads; | |
732 | return 0; | |
733 | } | |
734 | ||
735 | /** | |
736 | * fdisk_label_get_geomrange_cylinders: | |
737 | * @lb: label | |
738 | * @mi: minimal number | |
739 | * @ma: maximal number | |
740 | * | |
741 | * The function provides minimal and maximal geometry supported for the label, | |
f1424a94 | 742 | * if no range defined by library then returns -ENOSYS. |
2dd2880f | 743 | * |
ed930a9b KZ |
744 | * Since: 2.32 |
745 | * | |
2dd2880f KZ |
746 | * Returns: 0 on success, otherwise, a corresponding error. |
747 | */ | |
748 | int fdisk_label_get_geomrange_cylinders(const struct fdisk_label *lb, | |
749 | fdisk_sector_t *mi, fdisk_sector_t *ma) | |
750 | { | |
751 | if (!lb || lb->geom_min.cylinders == 0) | |
752 | return -ENOSYS; | |
753 | if (mi) | |
754 | *mi = lb->geom_min.cylinders; | |
755 | if (ma) | |
756 | *ma = lb->geom_max.cylinders; | |
757 | return 0; | |
758 | } | |
759 |