btrfs-progs: separate command and implementation of chunk-recover code
[platform/upstream/btrfs-progs.git] / cmds-rescue.c
1 /*
2  * Copyright (C) 2013 SUSE.  All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License v2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public
14  * License along with this program; if not, write to the
15  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16  * Boston, MA 021110-1307, USA.
17  */
18
19 #include "kerncompat.h"
20
21 #include <getopt.h>
22 #include "commands.h"
23 #include "utils.h"
24
25 static const char * const rescue_cmd_group_usage[] = {
26         "btrfs rescue <command> [options] <path>",
27         NULL
28 };
29
30 int btrfs_recover_chunk_tree(char *path, int verbose, int yes);
31
32 const char * const cmd_chunk_recover_usage[] = {
33         "btrfs rescue chunk-recover [options] <device>",
34         "Recover the chunk tree by scanning the devices one by one.",
35         "",
36         "-y     Assume an answer of `yes' to all questions",
37         "-v     Verbose mode",
38         "-h     Help",
39         NULL
40 };
41
42 int cmd_chunk_recover(int argc, char *argv[])
43 {
44         int ret = 0;
45         char *file;
46         int yes = 0;
47         int verbose = 0;
48
49         while (1) {
50                 int c = getopt(argc, argv, "yvh");
51                 if (c < 0)
52                         break;
53                 switch (c) {
54                 case 'y':
55                         yes = 1;
56                         break;
57                 case 'v':
58                         verbose = 1;
59                         break;
60                 case 'h':
61                 default:
62                         usage(cmd_chunk_recover_usage);
63                 }
64         }
65
66         argc = argc - optind;
67         if (argc == 0)
68                 usage(cmd_chunk_recover_usage);
69
70         file = argv[optind];
71
72         ret = check_mounted(file);
73         if (ret) {
74                 fprintf(stderr, "the device is busy\n");
75                 return ret;
76         }
77
78         ret = btrfs_recover_chunk_tree(file, verbose, yes);
79         if (!ret) {
80                 fprintf(stdout, "Recover the chunk tree successfully.\n");
81         } else if (ret > 0) {
82                 ret = 0;
83                 fprintf(stdout, "Abort to rebuild the on-disk chunk tree.\n");
84         } else {
85                 fprintf(stdout, "Fail to recover the chunk tree.\n");
86         }
87         return ret;
88 }
89
90 const struct cmd_group rescue_cmd_group = {
91         rescue_cmd_group_usage, NULL, {
92                 { "chunk-recover", cmd_chunk_recover, cmd_chunk_recover_usage, NULL, 0},
93                 { 0, 0, 0, 0, 0 }
94         }
95 };
96
97 int cmd_rescue(int argc, char **argv)
98 {
99         return handle_command_group(&rescue_cmd_group, argc, argv);
100 }