btrfs-progs: Improvement for making btrfs image from source directory.
[platform/upstream/btrfs-progs.git] / btrfs-vol.c
1 /*
2  * Copyright (C) 2007 Oracle.  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 #define _GNU_SOURCE
20 #ifndef __CHECKER__
21 #include <sys/ioctl.h>
22 #include <sys/mount.h>
23 #include "ioctl.h"
24 #endif
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <getopt.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <dirent.h>
33 #include <uuid/uuid.h>
34 #include "kerncompat.h"
35 #include "ctree.h"
36 #include "transaction.h"
37 #include "utils.h"
38 #include "volumes.h"
39
40 #ifdef __CHECKER__
41 #define BLKGETSIZE64 0
42 #define BTRFS_IOC_SNAP_CREATE 0
43 #define BTRFS_IOC_ADD_DEV 0
44 #define BTRFS_IOC_RM_DEV 0
45 #define BTRFS_VOL_NAME_MAX 255
46 struct btrfs_ioctl_vol_args { char name[BTRFS_VOL_NAME_MAX]; };
47 static inline int ioctl(int fd, int define, void *arg) { return 0; }
48 #endif
49
50 static void print_usage(void)
51 {
52         fprintf(stderr, "usage: btrfs-vol [options] mount_point\n");
53         fprintf(stderr, "\t-a device add one device\n");
54         fprintf(stderr, "\t-b balance chunks across all devices\n");
55         fprintf(stderr, "\t-r device remove one device\n");
56         exit(1);
57 }
58
59 static struct option long_options[] = {
60         /* { "byte-count", 1, NULL, 'b' }, */
61         { "add", 1, NULL, 'a' },
62         { "balance", 0, NULL, 'b' },
63         { "remove", 1, NULL, 'r' },
64         { 0, 0, 0, 0}
65 };
66
67 int main(int ac, char **av)
68 {
69         struct stat st;
70         char *device = NULL;
71         char *mnt = NULL;
72         int ret;
73         int option_index = 0;
74         int cmd = 0;
75         int fd;
76         int devfd = 0;
77         DIR *dirstream;
78         struct btrfs_ioctl_vol_args args;
79         u64 dev_block_count = 0;
80
81         printf( "**\n"
82                 "** WARNING: this program is considered deprecated\n"
83                 "** Please consider to switch to the btrfs utility\n"
84                 "**\n");
85
86         while(1) {
87                 int c;
88                 c = getopt_long(ac, av, "a:br:", long_options,
89                                 &option_index);
90                 if (c < 0)
91                         break;
92                 switch(c) {
93                         case 'a':
94                                 device = strdup(optarg);
95                                 cmd = BTRFS_IOC_ADD_DEV;
96                                 break;
97                         case 'b':
98                                 cmd = BTRFS_IOC_BALANCE;
99                                 break;
100                         case 'r':
101                                 device = strdup(optarg);
102                                 cmd = BTRFS_IOC_RM_DEV;
103                                 break;
104                         default:
105                                 print_usage();
106                 }
107         }
108         ac = ac - optind;
109         if (ac == 0)
110                 print_usage();
111         mnt = av[optind];
112
113         if (device && strcmp(device, "missing") == 0 &&
114             cmd == BTRFS_IOC_RM_DEV) {
115                 fprintf(stderr, "removing missing devices from %s\n", mnt);
116         } else if (cmd != BTRFS_IOC_BALANCE) {
117                 if (cmd == BTRFS_IOC_ADD_DEV) {
118                         ret = check_mounted(device);
119                         if (ret < 0) {
120                                 fprintf(stderr,
121                                         "error checking %s mount status\n",
122                                         device);
123                                 exit(1);
124                         }
125                         if (ret == 1) {
126                                 fprintf(stderr, "%s is mounted\n", device);
127                                 exit(1);
128                         }
129                 }
130                 devfd = open(device, O_RDWR);
131                 if (devfd < 0) {
132                         fprintf(stderr, "Unable to open device %s\n", device);
133                         exit(1);
134                 }
135                 ret = fstat(devfd, &st);
136                 if (ret) {
137                         fprintf(stderr, "Unable to stat %s\n", device);
138                         exit(1);
139                 }
140                 if (!S_ISBLK(st.st_mode)) {
141                         fprintf(stderr, "%s is not a block device\n", device);
142                         exit(1);
143                 }
144         }
145         dirstream = opendir(mnt);
146         if (!dirstream) {
147                 fprintf(stderr, "Unable to open directory %s\n", mnt);
148                 exit(1);
149         }
150         if (cmd == BTRFS_IOC_ADD_DEV) {
151                 int mixed = 0;
152
153                 ret = btrfs_prepare_device(devfd, device, 1, &dev_block_count, &mixed);
154                 if (ret) {
155                         fprintf(stderr, "Unable to init %s\n", device);
156                         exit(1);
157                 }
158         }
159         fd = dirfd(dirstream);
160         if (device)
161                 strcpy(args.name, device);
162         else
163                 args.name[0] = '\0';
164
165         ret = ioctl(fd, cmd, &args);
166         printf("ioctl returns %d\n", ret);
167         return 0;
168 }
169