xref: /dragonfly/sbin/hammer/cmd_volume.c (revision e10ffbc2)
1 /*
2  * Copyright (c) 2009 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com> and
6  * Michael Neumann <mneumann@ntecs.de>
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  * 3. Neither the name of The DragonFly Project nor the names of its
19  *    contributors may be used to endorse or promote products derived
20  *    from this software without specific, prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
26  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  */
36 /*
37  * Volume operations:
38  *
39  *   - volume-add: Add new volume to HAMMER filesystem
40  *   - volume-del: Remove volume from HAMMER filesystem
41  *   - volume-list: List volumes making up a HAMMER filesystem
42  *   - volume-blkdevs: List volumes making up a HAMMER filesystem
43  *     in blkdevs format
44  */
45 
46 #include "hammer.h"
47 
48 /*
49  * volume-add <device> <filesystem>
50  */
51 void
52 hammer_cmd_volume_add(char **av, int ac)
53 {
54 	struct hammer_ioc_volume ioc;
55 	volume_info_t volume;
56 	int fd;
57 	const char *device, *filesystem;
58 
59 	if (ac != 2) {
60 		errx(1, "hammer volume-add <device> <filesystem>");
61 		/* not reached */
62 	}
63 
64 	device = av[0];
65 	filesystem = av[1];
66 
67         fd = open(filesystem, O_RDONLY);
68 	if (fd < 0) {
69 		err(1, "hammer volume-add: unable to access %s", filesystem);
70 		/* not reached */
71 	}
72 
73 	/*
74 	 * Initialize and check the device
75 	 */
76 	volume = init_volume(device, O_RDONLY, -1);
77 	assert(volume->vol_no == -1);
78 	if (is_regfile(volume)) {
79 		errx(1, "Not a block device: %s", device);
80 		/* not reached */
81 	}
82 	close(volume->fd);
83 
84 	/*
85 	 * volume-add ioctl
86 	 */
87 	bzero(&ioc, sizeof(ioc));
88 	strncpy(ioc.device_name, device, sizeof(ioc.device_name) - 1);
89 	ioc.vol_size = volume->size;
90 	ioc.boot_area_size = init_boot_area_size(0, ioc.vol_size);
91 	ioc.memory_log_size = init_memory_log_size(0, ioc.vol_size);
92 
93 	if (ioctl(fd, HAMMERIOC_ADD_VOLUME, &ioc) < 0) {
94 		err(1, "hammer volume-add ioctl");
95 		/* not reached */
96 	}
97 
98 	close(fd);
99 	hammer_cmd_volume_list(av + 1, ac - 1);
100 }
101 
102 /*
103  * volume-del <device> <filesystem>
104  */
105 void
106 hammer_cmd_volume_del(char **av, int ac)
107 {
108 	struct hammer_ioc_volume ioc;
109 	int fd, retried = 0;
110 	const char *device, *filesystem;
111 
112 	if (ac != 2) {
113 		errx(1, "hammer volume-del <device> <filesystem>");
114 		/* not reached */
115 	}
116 
117 	device = av[0];
118 	filesystem = av[1];
119 
120         fd = open(filesystem, O_RDONLY);
121 	if (fd < 0) {
122 		err(1, "hammer volume-del: unable to access %s", filesystem);
123 		/* not reached */
124 	}
125 
126 	/*
127 	 * volume-del ioctl
128 	 */
129 	bzero(&ioc, sizeof(ioc));
130 	strncpy(ioc.device_name, device, sizeof(ioc.device_name) - 1);
131 	if (ForceOpt)
132 		ioc.flag |= HAMMER_IOC_VOLUME_REBLOCK;
133 retry:
134 	if (ioctl(fd, HAMMERIOC_DEL_VOLUME, &ioc) < 0) {
135 		if ((errno == ENOTEMPTY) && (retried++ == 0)) {
136 			printf("%s is not empty, ", device);
137 			printf("do you want to reblock %s? [y/n] ", device);
138 			fflush(stdout);
139 			if (getyn() == 1) {
140 				ioc.flag |= HAMMER_IOC_VOLUME_REBLOCK;
141 				goto retry;
142 			}
143 		}
144 		err(1, "hammer volume-del ioctl");
145 		/* not reached */
146 	}
147 
148 	close(fd);
149 	hammer_cmd_volume_list(av + 1, ac - 1);
150 }
151 
152 /*
153  * volume-list <filesystem>
154  */
155 void
156 hammer_cmd_volume_list(char **av, int ac)
157 {
158 	struct hammer_ioc_volume_list ioc;
159 	char *device_name;
160 	int vol_no, i;
161 
162 	if (ac < 1) {
163 		errx(1, "hammer volume-list <filesystem>");
164 		/* not reached */
165 	}
166 
167 	if (hammer_fs_to_vol(av[0], &ioc) == -1) {
168 		errx(1, "hammer volume-list: failed");
169 		/* not reached */
170 	}
171 
172 	for (i = 0; i < ioc.nvols; i++) {
173 		device_name = ioc.vols[i].device_name;
174 		vol_no = ioc.vols[i].vol_no;
175 		if (VerboseOpt) {
176 			printf("%d\t%s%s\n", vol_no, device_name,
177 				(vol_no == HAMMER_ROOT_VOLNO ?
178 				" (Root Volume)" : ""));
179 		} else {
180 			printf("%s\n", device_name);
181 		}
182 	}
183 
184 	free(ioc.vols);
185 }
186 
187 /*
188  * volume-blkdevs <filesystem>
189  */
190 void
191 hammer_cmd_volume_blkdevs(char **av, int ac)
192 {
193 	struct hammer_ioc_volume_list ioc;
194 	int i;
195 
196 	if (ac < 1) {
197 		errx(1, "hammer volume-blkdevs <filesystem>");
198 		/* not reached */
199 	}
200 
201 	if (hammer_fs_to_vol(av[0], &ioc) == -1) {
202 		errx(1, "hammer volume-list: failed");
203 		/* not reached */
204 	}
205 
206 	for (i = 0; i < ioc.nvols; i++) {
207 		printf("%s", ioc.vols[i].device_name);
208 		if (i != ioc.nvols - 1)
209 			printf(":");
210 	}
211 	printf("\n");
212 
213 	free(ioc.vols);
214 }
215