source: mainline/uspace/app/fdisk/fdisk.c@ 28ed0d9

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

Delegate disks to volsrv and labels to vbd.

  • Property mode set to 100644
File size: 13.2 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;
45static fdisk_t *fdisk;
46
47/** Device menu actions */
48typedef enum {
49 /** Create label */
50 devac_create_label,
51 /** Delete label */
52 devac_delete_label,
53 /** Create partition */
54 devac_create_part,
55 /** Delete partition */
56 devac_delete_part,
57 /** Exit */
58 devac_exit
59} devac_t;
60
61/** Device selection */
62static int fdsk_dev_sel_choice(service_id_t *rsvcid)
63{
64 fdisk_dev_list_t *devlist = NULL;
65 fdisk_dev_info_t *info;
66 nchoice_t *choice = NULL;
67 char *svcname = NULL;
68 fdisk_cap_t cap;
69 fdisk_dev_info_t *sdev;
70 char *scap = NULL;
71 char *dtext = NULL;
72 service_id_t svcid;
73 void *sel;
74 int ndevs;
75 int rc;
76
77 rc = nchoice_create(&choice);
78 if (rc != EOK) {
79 assert(rc == ENOMEM);
80 printf("Out of memory.\n");
81 goto error;
82 }
83
84 rc = nchoice_set_prompt(choice, "Select device");
85 if (rc != EOK) {
86 assert(rc == ENOMEM);
87 printf("Out of memory.\n");
88 goto error;
89 }
90
91 rc = fdisk_dev_list_get(fdisk, &devlist);
92 if (rc != EOK) {
93 printf("Error getting device list.\n");
94 goto error;
95 }
96
97 info = fdisk_dev_first(devlist);
98 ndevs = 0;
99 while (info != NULL) {
100 ++ndevs;
101
102 rc = fdisk_dev_info_get_svcname(info, &svcname);
103 if (rc != EOK) {
104 printf("Error getting device service name.\n");
105 goto error;
106 }
107
108 rc = fdisk_dev_info_capacity(info, &cap);
109 if (rc != EOK) {
110 printf("Error getting device capacity.\n");
111 goto error;
112 }
113
114 rc = fdisk_cap_format(&cap, &scap);
115 if (rc != EOK) {
116 assert(rc == ENOMEM);
117 printf("Out of memory.\n");
118 goto error;
119 }
120
121 rc = asprintf(&dtext, "%s (%s)", svcname, scap);
122 if (rc < 0) {
123 rc = ENOMEM;
124 printf("Out of memory.\n");
125 goto error;
126 }
127
128 free(svcname);
129 svcname = NULL;
130 free(scap);
131 scap = NULL;
132
133 rc = nchoice_add(choice, dtext, info);
134 if (rc != EOK) {
135 assert(rc == ENOMEM);
136 printf("Out of memory.\n");
137 goto error;
138 }
139
140 free(dtext);
141 dtext = NULL;
142
143 info = fdisk_dev_next(info);
144 }
145
146 if (ndevs == 0) {
147 printf("No disk devices found.\n");
148 rc = ENOENT;
149 goto error;
150 }
151
152 rc = nchoice_add(choice, "Exit", NULL);
153 if (rc != EOK) {
154 assert(rc == ENOMEM);
155 printf("Out of memory.\n");
156 goto error;
157 }
158
159 rc = nchoice_get(choice, &sel);
160 if (rc != EOK) {
161 printf("Error getting user selection.\n");
162 return rc;
163 }
164
165 sdev = (fdisk_dev_info_t *)sel;
166 if (sdev != NULL) {
167 fdisk_dev_info_get_svcid(sdev, &svcid);
168 } else {
169 svcid = 0;
170 }
171
172 fdisk_dev_list_free(devlist);
173
174 nchoice_destroy(choice);
175 *rsvcid = svcid;
176 return EOK;
177error:
178 if (devlist != NULL)
179 fdisk_dev_list_free(devlist);
180 if (choice != NULL)
181 nchoice_destroy(choice);
182 free(dtext);
183 free(svcname);
184 free(scap);
185 return rc;
186}
187
188static int fdsk_create_label(fdisk_dev_t *dev)
189{
190 nchoice_t *choice = NULL;
191 void *sel;
192 char *sltype = NULL;
193 int i;
194 int rc;
195
196 rc = nchoice_create(&choice);
197 if (rc != EOK) {
198 assert(rc == ENOMEM);
199 printf("Out of memory.\n");
200 goto error;
201 }
202
203 rc = nchoice_set_prompt(choice, "Select label type");
204 if (rc != EOK) {
205 assert(rc == ENOMEM);
206 printf("Out of memory.\n");
207 goto error;
208 }
209
210 for (i = 0; i < LT_LIMIT; i++) {
211 rc = fdisk_ltype_format(i, &sltype);
212 if (rc != EOK)
213 goto error;
214
215 rc = nchoice_add(choice, sltype, (void *)(uintptr_t)i);
216 if (rc != EOK) {
217 assert(rc == ENOMEM);
218 printf("Out of memory.\n");
219 goto error;
220 }
221
222 free(sltype);
223 sltype = NULL;
224 }
225
226 rc = nchoice_get(choice, &sel);
227 if (rc != EOK) {
228 printf("Error getting user selection.\n");
229 goto error;
230 }
231
232 rc = fdisk_label_create(dev, (label_type_t)sel);
233 if (rc != EOK) {
234 printf("Error creating label.\n");
235 goto error;
236 }
237
238 nchoice_destroy(choice);
239 return EOK;
240error:
241 free(sltype);
242 if (choice != NULL)
243 nchoice_destroy(choice);
244 return rc;
245}
246
247static int fdsk_delete_label(fdisk_dev_t *dev)
248{
249 int rc;
250
251 rc = fdisk_label_destroy(dev);
252 if (rc != EOK) {
253 printf("Error deleting label.\n");
254 return rc;
255 }
256
257 return EOK;
258}
259
260static int fdsk_select_fstype(fdisk_fstype_t *fstype)
261{
262 nchoice_t *choice = NULL;
263 void *sel;
264 char *sfstype;
265 int i;
266 int rc;
267
268 rc = nchoice_create(&choice);
269 if (rc != EOK) {
270 assert(rc == ENOMEM);
271 printf("Out of memory.\n");
272 goto error;
273 }
274
275 rc = nchoice_set_prompt(choice, "Select file system type");
276 if (rc != EOK) {
277 assert(rc == ENOMEM);
278 printf("Out of memory.\n");
279 goto error;
280 }
281
282 for (i = FDFS_CREATE_LO; i < FDFS_CREATE_HI; i++) {
283 rc = fdisk_fstype_format(i, &sfstype);
284 if (rc != EOK)
285 goto error;
286
287 rc = nchoice_add(choice, sfstype, (void *)(uintptr_t)i);
288 if (rc != EOK) {
289 assert(rc == ENOMEM);
290 printf("Out of memory.\n");
291 goto error;
292 }
293
294 free(sfstype);
295 sfstype = NULL;
296 }
297
298 rc = nchoice_get(choice, &sel);
299 if (rc != EOK) {
300 printf("Error getting user selection.\n");
301 goto error;
302 }
303
304 nchoice_destroy(choice);
305 *fstype = (fdisk_fstype_t)sel;
306 return EOK;
307error:
308 free(sfstype);
309 if (choice != NULL)
310 nchoice_destroy(choice);
311 return rc;
312}
313
314static int fdsk_create_part(fdisk_dev_t *dev)
315{
316 int rc;
317 fdisk_part_spec_t pspec;
318 fdisk_cap_t cap;
319 fdisk_fstype_t fstype;
320 tinput_t *tinput = NULL;
321 char *scap;
322
323 tinput = tinput_new();
324 if (tinput == NULL) {
325 rc = ENOMEM;
326 goto error;
327 }
328
329 rc = tinput_set_prompt(tinput, "?> ");
330 if (rc != EOK)
331 goto error;
332
333 while (true) {
334 printf("Enter capacity of new partition.\n");
335 rc = tinput_read(tinput, &scap);
336 if (rc != EOK)
337 goto error;
338
339 rc = fdisk_cap_parse(scap, &cap);
340 if (rc == EOK)
341 break;
342 }
343
344 tinput_destroy(tinput);
345
346 rc = fdsk_select_fstype(&fstype);
347 if (rc != EOK)
348 goto error;
349
350 fdisk_pspec_init(&pspec);
351 pspec.capacity = cap;
352 pspec.fstype = fstype;
353
354 rc = fdisk_part_create(dev, &pspec, NULL);
355 if (rc != EOK) {
356 printf("Error creating partition.\n");
357 goto error;
358 }
359
360 return EOK;
361error:
362 if (tinput != NULL)
363 tinput_destroy(tinput);
364 return rc;
365}
366
367static int fdsk_delete_part(fdisk_dev_t *dev)
368{
369 nchoice_t *choice = NULL;
370 fdisk_part_t *part;
371 fdisk_part_info_t pinfo;
372 char *scap = NULL;
373 char *sfstype = NULL;
374 char *sdesc = NULL;
375 void *sel;
376 int rc;
377
378 rc = nchoice_create(&choice);
379 if (rc != EOK) {
380 assert(rc == ENOMEM);
381 printf("Out of memory.\n");
382 goto error;
383 }
384
385 rc = nchoice_set_prompt(choice, "Select partition to delete");
386 if (rc != EOK) {
387 assert(rc == ENOMEM);
388 printf("Out of memory.\n");
389 goto error;
390 }
391
392 part = fdisk_part_first(dev);
393 while (part != NULL) {
394 rc = fdisk_part_get_info(part, &pinfo);
395 if (rc != EOK) {
396 printf("Error getting partition information.\n");
397 goto error;
398 }
399
400 rc = fdisk_cap_format(&pinfo.capacity, &scap);
401 if (rc != EOK) {
402 printf("Out of memory.\n");
403 goto error;
404 }
405
406 rc = fdisk_fstype_format(pinfo.fstype, &sfstype);
407 if (rc != EOK) {
408 printf("Out of memory.\n");
409 goto error;
410 }
411
412 rc = asprintf(&sdesc, "%s, %s", scap, sfstype);
413 if (rc < 0) {
414 rc = ENOMEM;
415 goto error;
416 }
417
418 rc = nchoice_add(choice, sdesc, (void *)part);
419 if (rc != EOK) {
420 assert(rc == ENOMEM);
421 printf("Out of memory.\n");
422 goto error;
423 }
424
425 free(scap);
426 scap = NULL;
427 free(sfstype);
428 sfstype = NULL;
429 free(sdesc);
430 sdesc = NULL;
431
432 part = fdisk_part_next(part);
433 }
434
435 rc = nchoice_get(choice, &sel);
436 if (rc != EOK) {
437 printf("Error getting user selection.\n");
438 goto error;
439 }
440
441 rc = fdisk_part_destroy((fdisk_part_t *)sel);
442 if (rc != EOK) {
443 printf("Error deleting partition.\n");
444 return rc;
445 }
446
447 nchoice_destroy(choice);
448 return EOK;
449error:
450 free(scap);
451 free(sfstype);
452 free(sdesc);
453
454 if (choice != NULL)
455 nchoice_destroy(choice);
456 return rc;
457}
458
459/** Device menu */
460static int fdsk_dev_menu(fdisk_dev_t *dev)
461{
462 nchoice_t *choice = NULL;
463 fdisk_label_info_t linfo;
464 fdisk_part_t *part;
465 fdisk_part_info_t pinfo;
466 fdisk_cap_t cap;
467 char *sltype = NULL;
468 char *sdcap = NULL;
469 char *scap = NULL;
470 char *sfstype = NULL;
471 char *svcname = NULL;
472 int rc;
473 int npart;
474 void *sel;
475
476 rc = nchoice_create(&choice);
477 if (rc != EOK) {
478 assert(rc == ENOMEM);
479 printf("Out of memory.\n");
480 goto error;
481 }
482
483 rc = nchoice_set_prompt(choice, "Select action");
484 if (rc != EOK) {
485 assert(rc == ENOMEM);
486 printf("Out of memory.\n");
487 goto error;
488 }
489
490 rc = fdisk_dev_capacity(dev, &cap);
491 if (rc != EOK) {
492 printf("Error getting device capacity.\n");
493 goto error;
494 }
495
496 rc = fdisk_cap_format(&cap, &sdcap);
497 if (rc != EOK) {
498 printf("Out of memory.\n");
499 goto error;
500 }
501
502 rc = fdisk_dev_get_svcname(dev, &svcname);
503 if (rc != EOK) {
504 printf("Error getting device service name.\n");
505 goto error;
506 }
507
508 printf("Device: %s, %s\n", sdcap, svcname);
509 free(sdcap);
510 sdcap = NULL;
511
512 rc = fdisk_label_get_info(dev, &linfo);
513 if (rc != EOK) {
514 printf("Error getting label information.\n");
515 goto error;
516 }
517
518 switch (linfo.dcnt) {
519 case dc_empty:
520 printf("Disk is empty.\n");
521 break;
522 case dc_label:
523 rc = fdisk_ltype_format(linfo.ltype, &sltype);
524 if (rc != EOK) {
525 assert(rc == ENOMEM);
526 printf("Out of memory.\n");
527 goto error;
528 }
529
530 printf("Label type: %s\n", sltype);
531 free(sltype);
532 sltype = NULL;
533 break;
534 case dc_fs:
535 printf("Disk contains a file system.\n");
536 break;
537 case dc_unknown:
538 printf("Disk contains unknown data.\n");
539 break;
540 }
541
542 part = fdisk_part_first(dev);
543 npart = 0;
544 while (part != NULL) {
545 ++npart;
546 rc = fdisk_part_get_info(part, &pinfo);
547 if (rc != EOK) {
548 printf("Error getting partition information.\n");
549 goto error;
550 }
551
552 rc = fdisk_cap_format(&pinfo.capacity, &scap);
553 if (rc != EOK) {
554 printf("Out of memory.\n");
555 goto error;
556 }
557
558 rc = fdisk_fstype_format(pinfo.fstype, &sfstype);
559 if (rc != EOK) {
560 printf("Out of memory.\n");
561 goto error;
562 }
563
564 printf("Partition %d: %s, %s\n", npart, scap, sfstype);
565 free(scap);
566 scap = NULL;
567 free(sfstype);
568 sfstype = NULL;
569
570 part = fdisk_part_next(part);
571 }
572
573 rc = nchoice_set_prompt(choice, "Select action");
574 if (rc != EOK) {
575 assert(rc == ENOMEM);
576 printf("Out of memory.\n");
577 goto error;
578 }
579
580 if (linfo.dcnt == dc_label) {
581 rc = nchoice_add(choice, "Create partition",
582 (void *)devac_create_part);
583 if (rc != EOK) {
584 assert(rc == ENOMEM);
585 printf("Out of memory.\n");
586 goto error;
587 }
588 }
589
590 if (npart > 0) {
591 rc = nchoice_add(choice, "Delete partition",
592 (void *)devac_delete_part);
593 if (rc != EOK) {
594 assert(rc == ENOMEM);
595 printf("Out of memory.\n");
596 goto error;
597 }
598 }
599
600 if (linfo.dcnt == dc_empty) {
601 rc = nchoice_add(choice, "Create label",
602 (void *)devac_create_label);
603 if (rc != EOK) {
604 assert(rc == ENOMEM);
605 printf("Out of memory.\n");
606 goto error;
607 }
608 } else {
609 rc = nchoice_add(choice, "Delete label",
610 (void *)devac_delete_label);
611 if (rc != EOK) {
612 assert(rc == ENOMEM);
613 printf("Out of memory.\n");
614 goto error;
615 }
616 }
617
618 rc = nchoice_add(choice, "Exit", (void *)devac_exit);
619 if (rc != EOK) {
620 assert(rc == ENOMEM);
621 printf("Out of memory.\n");
622 goto error;
623 }
624
625 rc = nchoice_get(choice, &sel);
626 if (rc != EOK) {
627 printf("Error getting user selection.\n");
628 return rc;
629 }
630
631 switch ((devac_t)sel) {
632 case devac_create_label:
633 (void) fdsk_create_label(dev);
634 break;
635 case devac_delete_label:
636 (void) fdsk_delete_label(dev);
637 break;
638 case devac_create_part:
639 (void) fdsk_create_part(dev);
640 break;
641 case devac_delete_part:
642 (void) fdsk_delete_part(dev);
643 break;
644 case devac_exit:
645 quit = true;
646 break;
647 }
648
649 nchoice_destroy(choice);
650 return EOK;
651error:
652 free(sdcap);
653 free(scap);
654 free(sfstype);
655 free(svcname);
656 if (choice != NULL)
657 nchoice_destroy(choice);
658 return rc;
659}
660
661int main(int argc, char *argv[])
662{
663 service_id_t svcid;
664 fdisk_dev_t *dev;
665 int rc;
666
667 rc = fdisk_create(&fdisk);
668 if (rc != EOK) {
669 printf("Error initializing Fdisk.\n");
670 return 1;
671 }
672
673 rc = fdsk_dev_sel_choice(&svcid);
674 if (rc != EOK)
675 return 1;
676
677 if (svcid == 0)
678 return 0;
679
680 rc = fdisk_dev_open(fdisk, svcid, &dev);
681 if (rc != EOK) {
682 printf("Error opening device.\n");
683 return 1;
684 }
685
686 while (!quit) {
687 rc = fdsk_dev_menu(dev);
688 if (rc != EOK) {
689 fdisk_dev_close(dev);
690 return 1;
691 }
692 }
693
694 fdisk_dev_close(dev);
695 fdisk_destroy(fdisk);
696
697 return 0;
698}
699
700
701/** @}
702 */
Note: See TracBrowser for help on using the repository browser.