source: mainline/uspace/app/fdisk/fdisk.c@ 1356f85a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1356f85a was 8227d63, checked in by Jiri Svoboda <jiri@…>, 10 years ago

UI for creating and deleting partitions.

  • Property mode set to 100644
File size: 13.0 KB
Line 
1/*
2 * Copyright (c) 2015 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup fdisk
30 * @brief Disk management tool
31 * @{
32 */
33/**
34 * @file
35 */
36
37#include <errno.h>
38#include <nchoice.h>
39#include <stdbool.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <fdisk.h>
43
44static bool quit = false;
45
46/** Device menu actions */
47typedef enum {
48 /** Create label */
49 devac_create_label,
50 /** Delete label */
51 devac_delete_label,
52 /** Create partition */
53 devac_create_part,
54 /** Delete partition */
55 devac_delete_part,
56 /** Exit */
57 devac_exit
58} devac_t;
59
60/** Device selection */
61static int fdsk_dev_sel_choice(service_id_t *rsvcid)
62{
63 fdisk_dev_list_t *devlist = NULL;
64 fdisk_dev_info_t *info;
65 nchoice_t *choice = NULL;
66 char *svcname = NULL;
67 fdisk_cap_t cap;
68 fdisk_dev_info_t *sdev;
69 char *scap = NULL;
70 char *dtext = NULL;
71 service_id_t svcid;
72 void *sel;
73 int ndevs;
74 int rc;
75
76 rc = nchoice_create(&choice);
77 if (rc != EOK) {
78 assert(rc == ENOMEM);
79 printf("Out of memory.\n");
80 goto error;
81 }
82
83 rc = nchoice_set_prompt(choice, "Select device");
84 if (rc != EOK) {
85 assert(rc == ENOMEM);
86 printf("Out of memory.\n");
87 goto error;
88 }
89
90 rc = fdisk_dev_list_get(&devlist);
91 if (rc != EOK) {
92 printf("Error getting device list.\n");
93 goto error;
94 }
95
96 info = fdisk_dev_first(devlist);
97 ndevs = 0;
98 while (info != NULL) {
99 ++ndevs;
100
101 rc = fdisk_dev_info_get_svcname(info, &svcname);
102 if (rc != EOK) {
103 printf("Error getting device service name.\n");
104 goto error;
105 }
106
107 rc = fdisk_dev_info_capacity(info, &cap);
108 if (rc != EOK) {
109 printf("Error getting device capacity.\n");
110 goto error;
111 }
112
113 rc = fdisk_cap_format(&cap, &scap);
114 if (rc != EOK) {
115 assert(rc == ENOMEM);
116 printf("Out of memory.\n");
117 goto error;
118 }
119
120 rc = asprintf(&dtext, "%s (%s)", svcname, scap);
121 if (rc < 0) {
122 rc = ENOMEM;
123 printf("Out of memory.\n");
124 goto error;
125 }
126
127 free(svcname);
128 svcname = NULL;
129 free(scap);
130 scap = NULL;
131
132 rc = nchoice_add(choice, dtext, info);
133 if (rc != EOK) {
134 assert(rc == ENOMEM);
135 printf("Out of memory.\n");
136 goto error;
137 }
138
139 free(dtext);
140 dtext = NULL;
141
142 info = fdisk_dev_next(info);
143 }
144
145 if (ndevs == 0) {
146 printf("No disk devices found.\n");
147 rc = ENOENT;
148 goto error;
149 }
150
151 rc = nchoice_add(choice, "Exit", NULL);
152 if (rc != EOK) {
153 assert(rc == ENOMEM);
154 printf("Out of memory.\n");
155 goto error;
156 }
157
158 rc = nchoice_get(choice, &sel);
159 if (rc != EOK) {
160 printf("Error getting user selection.\n");
161 return rc;
162 }
163
164 sdev = (fdisk_dev_info_t *)sel;
165 if (sdev != NULL) {
166 fdisk_dev_info_get_svcid(sdev, &svcid);
167 } else {
168 svcid = 0;
169 }
170
171 fdisk_dev_list_free(devlist);
172
173 nchoice_destroy(choice);
174 *rsvcid = svcid;
175 return EOK;
176error:
177 if (devlist != NULL)
178 fdisk_dev_list_free(devlist);
179 if (choice != NULL)
180 nchoice_destroy(choice);
181 free(dtext);
182 free(svcname);
183 free(scap);
184 return rc;
185}
186
187static int fdsk_create_label(fdisk_dev_t *dev)
188{
189 nchoice_t *choice = NULL;
190 void *sel;
191 char *sltype = NULL;
192 int i;
193 int rc;
194
195 rc = nchoice_create(&choice);
196 if (rc != EOK) {
197 assert(rc == ENOMEM);
198 printf("Out of memory.\n");
199 goto error;
200 }
201
202 rc = nchoice_set_prompt(choice, "Select label type");
203 if (rc != EOK) {
204 assert(rc == ENOMEM);
205 printf("Out of memory.\n");
206 goto error;
207 }
208
209 for (i = FDL_CREATE_LO; i < FDL_CREATE_HI; i++) {
210 rc = fdisk_ltype_format(i, &sltype);
211 if (rc != EOK)
212 goto error;
213
214 rc = nchoice_add(choice, sltype, (void *)(uintptr_t)i);
215 if (rc != EOK) {
216 assert(rc == ENOMEM);
217 printf("Out of memory.\n");
218 goto error;
219 }
220
221 free(sltype);
222 sltype = NULL;
223 }
224
225 rc = nchoice_get(choice, &sel);
226 if (rc != EOK) {
227 printf("Error getting user selection.\n");
228 goto error;
229 }
230
231 rc = fdisk_label_create(dev, (fdisk_label_type_t)sel);
232 if (rc != EOK) {
233 printf("Error creating label.\n");
234 goto error;
235 }
236
237 nchoice_destroy(choice);
238 return EOK;
239error:
240 free(sltype);
241 if (choice != NULL)
242 nchoice_destroy(choice);
243 return rc;
244}
245
246static int fdsk_delete_label(fdisk_dev_t *dev)
247{
248 int rc;
249
250 rc = fdisk_label_destroy(dev);
251 if (rc != EOK) {
252 printf("Error deleting label.\n");
253 return rc;
254 }
255
256 return EOK;
257}
258
259static int fdsk_select_fstype(fdisk_fstype_t *fstype)
260{
261 nchoice_t *choice = NULL;
262 void *sel;
263 char *sfstype;
264 int i;
265 int rc;
266
267 rc = nchoice_create(&choice);
268 if (rc != EOK) {
269 assert(rc == ENOMEM);
270 printf("Out of memory.\n");
271 goto error;
272 }
273
274 rc = nchoice_set_prompt(choice, "Select file system type");
275 if (rc != EOK) {
276 assert(rc == ENOMEM);
277 printf("Out of memory.\n");
278 goto error;
279 }
280
281 for (i = FDFS_CREATE_LO; i < FDFS_CREATE_HI; i++) {
282 rc = fdisk_fstype_format(i, &sfstype);
283 if (rc != EOK)
284 goto error;
285
286 rc = nchoice_add(choice, sfstype, (void *)(uintptr_t)i);
287 if (rc != EOK) {
288 assert(rc == ENOMEM);
289 printf("Out of memory.\n");
290 goto error;
291 }
292
293 free(sfstype);
294 sfstype = NULL;
295 }
296
297 rc = nchoice_get(choice, &sel);
298 if (rc != EOK) {
299 printf("Error getting user selection.\n");
300 goto error;
301 }
302
303 nchoice_destroy(choice);
304 *fstype = (fdisk_fstype_t)sel;
305 return EOK;
306error:
307 free(sfstype);
308 if (choice != NULL)
309 nchoice_destroy(choice);
310 return rc;
311}
312
313static int fdsk_create_part(fdisk_dev_t *dev)
314{
315 int rc;
316 fdisk_part_spec_t pspec;
317 fdisk_cap_t cap;
318 fdisk_fstype_t fstype;
319 tinput_t *tinput = NULL;
320 char *scap;
321
322 tinput = tinput_new();
323 if (tinput == NULL) {
324 rc = ENOMEM;
325 goto error;
326 }
327
328 rc = tinput_set_prompt(tinput, "?> ");
329 if (rc != EOK)
330 goto error;
331
332 while (true) {
333 printf("Enter capacity of new partition.\n");
334 rc = tinput_read(tinput, &scap);
335 if (rc != EOK)
336 goto error;
337
338 rc = fdisk_cap_parse(scap, &cap);
339 if (rc == EOK)
340 break;
341 }
342
343 tinput_destroy(tinput);
344
345 rc = fdsk_select_fstype(&fstype);
346 if (rc != EOK)
347 goto error;
348
349 fdisk_pspec_init(&pspec);
350 pspec.capacity = cap;
351 pspec.fstype = fstype;
352
353 rc = fdisk_part_create(dev, &pspec, NULL);
354 if (rc != EOK) {
355 printf("Error creating partition.\n");
356 goto error;
357 }
358
359 return EOK;
360error:
361 if (tinput != NULL)
362 tinput_destroy(tinput);
363 return rc;
364}
365
366static int fdsk_delete_part(fdisk_dev_t *dev)
367{
368 nchoice_t *choice = NULL;
369 fdisk_part_t *part;
370 fdisk_part_info_t pinfo;
371 char *scap = NULL;
372 char *sfstype = NULL;
373 char *sdesc = NULL;
374 void *sel;
375 int rc;
376
377 rc = nchoice_create(&choice);
378 if (rc != EOK) {
379 assert(rc == ENOMEM);
380 printf("Out of memory.\n");
381 goto error;
382 }
383
384 rc = nchoice_set_prompt(choice, "Select partition to delete");
385 if (rc != EOK) {
386 assert(rc == ENOMEM);
387 printf("Out of memory.\n");
388 goto error;
389 }
390
391 part = fdisk_part_first(dev);
392 while (part != NULL) {
393 rc = fdisk_part_get_info(part, &pinfo);
394 if (rc != EOK) {
395 printf("Error getting partition information.\n");
396 goto error;
397 }
398
399 rc = fdisk_cap_format(&pinfo.capacity, &scap);
400 if (rc != EOK) {
401 printf("Out of memory.\n");
402 goto error;
403 }
404
405 rc = fdisk_fstype_format(pinfo.fstype, &sfstype);
406 if (rc != EOK) {
407 printf("Out of memory.\n");
408 goto error;
409 }
410
411 rc = asprintf(&sdesc, "%s, %s", scap, sfstype);
412 if (rc < 0) {
413 rc = ENOMEM;
414 goto error;
415 }
416
417 rc = nchoice_add(choice, sdesc, (void *)part);
418 if (rc != EOK) {
419 assert(rc == ENOMEM);
420 printf("Out of memory.\n");
421 goto error;
422 }
423
424 free(scap);
425 scap = NULL;
426 free(sfstype);
427 sfstype = NULL;
428 free(sdesc);
429 sdesc = NULL;
430
431 part = fdisk_part_next(part);
432 }
433
434 rc = nchoice_get(choice, &sel);
435 if (rc != EOK) {
436 printf("Error getting user selection.\n");
437 goto error;
438 }
439
440 rc = fdisk_part_destroy((fdisk_part_t *)sel);
441 if (rc != EOK) {
442 printf("Error deleting partition.\n");
443 return rc;
444 }
445
446 nchoice_destroy(choice);
447 return EOK;
448error:
449 free(scap);
450 free(sfstype);
451 free(sdesc);
452
453 if (choice != NULL)
454 nchoice_destroy(choice);
455 return rc;
456}
457
458/** Device menu */
459static int fdsk_dev_menu(fdisk_dev_t *dev)
460{
461 nchoice_t *choice = NULL;
462 fdisk_label_info_t linfo;
463 fdisk_part_t *part;
464 fdisk_part_info_t pinfo;
465 fdisk_cap_t cap;
466 char *sltype = NULL;
467 char *sdcap = NULL;
468 char *scap = NULL;
469 char *sfstype = NULL;
470 char *svcname = NULL;
471 int rc;
472 int npart;
473 void *sel;
474
475 rc = nchoice_create(&choice);
476 if (rc != EOK) {
477 assert(rc == ENOMEM);
478 printf("Out of memory.\n");
479 goto error;
480 }
481
482 rc = nchoice_set_prompt(choice, "Select action");
483 if (rc != EOK) {
484 assert(rc == ENOMEM);
485 printf("Out of memory.\n");
486 goto error;
487 }
488
489 rc = fdisk_dev_capacity(dev, &cap);
490 if (rc != EOK) {
491 printf("Error getting device capacity.\n");
492 goto error;
493 }
494
495 rc = fdisk_cap_format(&cap, &sdcap);
496 if (rc != EOK) {
497 printf("Out of memory.\n");
498 goto error;
499 }
500
501 rc = fdisk_dev_get_svcname(dev, &svcname);
502 if (rc != EOK) {
503 printf("Error getting device service name.\n");
504 goto error;
505 }
506
507 rc = fdisk_label_get_info(dev, &linfo);
508 if (rc != EOK) {
509 printf("Error getting label information.\n");
510 goto error;
511 }
512
513 rc = fdisk_ltype_format(linfo.ltype, &sltype);
514 if (rc != EOK) {
515 assert(rc == ENOMEM);
516 printf("Out of memory.\n");
517 goto error;
518 }
519
520 printf("Device: %s, %s\n", sdcap, svcname);
521 printf("Label type: %s\n", sltype);
522 free(sltype);
523 sltype = NULL;
524 free(sdcap);
525 sdcap = NULL;
526
527 part = fdisk_part_first(dev);
528 npart = 0;
529 while (part != NULL) {
530 ++npart;
531 rc = fdisk_part_get_info(part, &pinfo);
532 if (rc != EOK) {
533 printf("Error getting partition information.\n");
534 goto error;
535 }
536
537 rc = fdisk_cap_format(&pinfo.capacity, &scap);
538 if (rc != EOK) {
539 printf("Out of memory.\n");
540 goto error;
541 }
542
543 rc = fdisk_fstype_format(pinfo.fstype, &sfstype);
544 if (rc != EOK) {
545 printf("Out of memory.\n");
546 goto error;
547 }
548
549 printf("Partition %d: %s, %s\n", npart, scap, sfstype);
550 free(scap);
551 scap = NULL;
552 free(sfstype);
553 sfstype = NULL;
554
555 part = fdisk_part_next(part);
556 }
557
558 rc = nchoice_set_prompt(choice, "Select action");
559 if (rc != EOK) {
560 assert(rc == ENOMEM);
561 printf("Out of memory.\n");
562 goto error;
563 }
564
565 if (linfo.ltype != fdl_none) {
566 rc = nchoice_add(choice, "Create partition",
567 (void *)devac_create_part);
568 if (rc != EOK) {
569 assert(rc == ENOMEM);
570 printf("Out of memory.\n");
571 goto error;
572 }
573 }
574
575 if (npart > 0) {
576 rc = nchoice_add(choice, "Delete partition",
577 (void *)devac_delete_part);
578 if (rc != EOK) {
579 assert(rc == ENOMEM);
580 printf("Out of memory.\n");
581 goto error;
582 }
583 }
584
585 if (linfo.ltype == fdl_none) {
586 rc = nchoice_add(choice, "Create label",
587 (void *)devac_create_label);
588 if (rc != EOK) {
589 assert(rc == ENOMEM);
590 printf("Out of memory.\n");
591 goto error;
592 }
593 } else {
594 rc = nchoice_add(choice, "Delete label",
595 (void *)devac_delete_label);
596 if (rc != EOK) {
597 assert(rc == ENOMEM);
598 printf("Out of memory.\n");
599 goto error;
600 }
601 }
602
603 rc = nchoice_add(choice, "Exit", (void *)devac_exit);
604 if (rc != EOK) {
605 assert(rc == ENOMEM);
606 printf("Out of memory.\n");
607 goto error;
608 }
609
610 rc = nchoice_get(choice, &sel);
611 if (rc != EOK) {
612 printf("Error getting user selection.\n");
613 return rc;
614 }
615
616 switch ((devac_t)sel) {
617 case devac_create_label:
618 rc = fdsk_create_label(dev);
619 if (rc != EOK)
620 goto error;
621 break;
622 case devac_delete_label:
623 rc = fdsk_delete_label(dev);
624 if (rc != EOK)
625 goto error;
626 break;
627 case devac_create_part:
628 rc = fdsk_create_part(dev);
629 if (rc != EOK)
630 goto error;
631 break;
632 case devac_delete_part:
633 rc = fdsk_delete_part(dev);
634 if (rc != EOK)
635 goto error;
636 break;
637 case devac_exit:
638 quit = true;
639 break;
640 }
641
642 nchoice_destroy(choice);
643 return EOK;
644error:
645 free(sdcap);
646 free(scap);
647 free(sfstype);
648 free(svcname);
649 if (choice != NULL)
650 nchoice_destroy(choice);
651 return rc;
652}
653
654int main(int argc, char *argv[])
655{
656 service_id_t svcid;
657 fdisk_dev_t *dev;
658 int rc;
659
660 rc = fdsk_dev_sel_choice(&svcid);
661 if (rc != EOK)
662 return 1;
663
664 if (svcid == 0)
665 return 0;
666
667 rc = fdisk_dev_open(svcid, &dev);
668 if (rc != EOK) {
669 printf("Error opening device.\n");
670 return 1;
671 }
672
673 while (!quit) {
674 rc = fdsk_dev_menu(dev);
675 if (rc != EOK) {
676 fdisk_dev_close(dev);
677 return 1;
678 }
679 }
680
681 fdisk_dev_close(dev);
682
683 return 0;
684}
685
686
687/** @}
688 */
Note: See TracBrowser for help on using the repository browser.