xref: /dragonfly/sbin/hammer2/cmd_pfs.c (revision 6a3cbbc2)
1 /*
2  * Copyright (c) 2011-2012 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@dragonflybsd.org>
6  * by Venkatesh Srinivas <vsrinivas@dragonflybsd.org>
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 #include "hammer2.h"
37 
38 int
39 cmd_pfs_list(int ac, const char **av)
40 {
41 	hammer2_ioc_pfs_t pfs;
42 	int ecode = 0;
43 	int count = 0;
44 	int fd;
45 	int i;
46 	char *pfs_id_str = NULL;
47 
48 	for (i = 0; i < ac; ++i) {
49 		if ((fd = hammer2_ioctl_handle(av[i])) < 0)
50 			return(1);
51 		bzero(&pfs, sizeof(pfs));
52 
53 		while ((pfs.name_key = pfs.name_next) != (hammer2_key_t)-1) {
54 			if (ioctl(fd, HAMMER2IOC_PFS_GET, &pfs) < 0) {
55 				perror("ioctl");
56 				ecode = 1;
57 				break;
58 			}
59 			if (count == 0) {
60 				printf("Type        "
61 				       "ClusterId (pfs_clid)                 "
62 				       "Label\n");
63 			}
64 			switch(pfs.pfs_type) {
65 			case HAMMER2_PFSTYPE_NONE:
66 				printf("NONE        ");
67 				break;
68 			case HAMMER2_PFSTYPE_CACHE:
69 				printf("CACHE       ");
70 				break;
71 			case HAMMER2_PFSTYPE_SLAVE:
72 				printf("SLAVE       ");
73 				break;
74 			case HAMMER2_PFSTYPE_SOFT_SLAVE:
75 				printf("SOFT_SLAVE  ");
76 				break;
77 			case HAMMER2_PFSTYPE_SOFT_MASTER:
78 				printf("SOFT_MASTER ");
79 				break;
80 			case HAMMER2_PFSTYPE_MASTER:
81 				switch (pfs.pfs_subtype) {
82 				case HAMMER2_PFSSUBTYPE_NONE:
83 					printf("MASTER      ");
84 					break;
85 				case HAMMER2_PFSSUBTYPE_SNAPSHOT:
86 					printf("SNAPSHOT    ");
87 					break;
88 				case HAMMER2_PFSSUBTYPE_AUTOSNAP:
89 					printf("AUTOSNAP    ");
90 					break;
91 				default:
92 					printf("MASTER(sub?)");
93 					break;
94 				}
95 				break;
96 			default:
97 				printf("%02x          ", pfs.pfs_type);
98 				break;
99 			}
100 			hammer2_uuid_to_str(&pfs.pfs_clid, &pfs_id_str);
101 			printf("%s ", pfs_id_str);
102 			free(pfs_id_str);
103 			pfs_id_str = NULL;
104 			printf("%s\n", pfs.name);
105 			++count;
106 		}
107 		close(fd);
108 	}
109 
110 	return (ecode);
111 }
112 
113 int
114 cmd_pfs_getid(const char *sel_path, const char *name, int privateid)
115 {
116 	hammer2_ioc_pfs_t pfs;
117 	int ecode = 0;
118 	int fd;
119 	char *pfs_id_str = NULL;
120 
121 	if ((fd = hammer2_ioctl_handle(sel_path)) < 0)
122 		return(1);
123 	bzero(&pfs, sizeof(pfs));
124 
125 	snprintf(pfs.name, sizeof(pfs.name), "%s", name);
126 	if (ioctl(fd, HAMMER2IOC_PFS_LOOKUP, &pfs) < 0) {
127 		perror("ioctl");
128 		ecode = 1;
129 	} else {
130 		if (privateid)
131 			hammer2_uuid_to_str(&pfs.pfs_fsid, &pfs_id_str);
132 		else
133 			hammer2_uuid_to_str(&pfs.pfs_clid, &pfs_id_str);
134 		printf("%s\n", pfs_id_str);
135 		free(pfs_id_str);
136 		pfs_id_str = NULL;
137 	}
138 	close(fd);
139 	return (ecode);
140 }
141 
142 
143 int
144 cmd_pfs_create(const char *sel_path, const char *name,
145 	       uint8_t pfs_type, const char *uuid_str)
146 {
147 	hammer2_ioc_pfs_t pfs;
148 	int ecode = 0;
149 	int fd;
150 	uint32_t status;
151 
152 	/*
153 	 * Default to MASTER if no uuid was specified.
154 	 * Default to SLAVE if a uuid was specified.
155 	 *
156 	 * When adding masters to a cluster, the new PFS must be added as
157 	 * a slave and then upgraded to ensure proper synchronization.
158 	 */
159 	if (pfs_type == HAMMER2_PFSTYPE_NONE) {
160 		if (uuid_str)
161 			pfs_type = HAMMER2_PFSTYPE_SLAVE;
162 		else
163 			pfs_type = HAMMER2_PFSTYPE_MASTER;
164 	}
165 
166 	if ((fd = hammer2_ioctl_handle(sel_path)) < 0)
167 		return(1);
168 	bzero(&pfs, sizeof(pfs));
169 	snprintf(pfs.name, sizeof(pfs.name), "%s", name);
170 	pfs.pfs_type = pfs_type;
171 	if (uuid_str) {
172 		uuid_from_string(uuid_str, &pfs.pfs_clid, &status);
173 	} else {
174 		uuid_create(&pfs.pfs_clid, &status);
175 	}
176 	if (status == uuid_s_ok)
177 		uuid_create(&pfs.pfs_fsid, &status);
178 	if (status == uuid_s_ok) {
179 		if (ioctl(fd, HAMMER2IOC_PFS_CREATE, &pfs) < 0) {
180 			if (errno == EEXIST) {
181 				fprintf(stderr,
182 					"NOTE: Typically the same name is "
183 					"used for cluster elements on "
184 					"different mounts,\n"
185 					"      but cluster elements on the "
186 					"same mount require unique names.\n"
187 					"pfs-create %s: already present\n",
188 					name);
189 			} else {
190 				perror("ioctl");
191 			}
192 			ecode = 1;
193 		}
194 	} else {
195 		fprintf(stderr, "hammer2: pfs_create: badly formed uuid\n");
196 		ecode = 1;
197 	}
198 	close(fd);
199 	return (ecode);
200 }
201 
202 int
203 cmd_pfs_delete(const char *sel_path, const char *name)
204 {
205 	hammer2_ioc_pfs_t pfs;
206 	int ecode = 0;
207 	int fd;
208 
209 	if ((fd = hammer2_ioctl_handle(sel_path)) < 0)
210 		return(1);
211 	bzero(&pfs, sizeof(pfs));
212 	snprintf(pfs.name, sizeof(pfs.name), "%s", name);
213 
214 	if (ioctl(fd, HAMMER2IOC_PFS_DELETE, &pfs) < 0) {
215 		fprintf(stderr, "hammer2: pfs_delete(%s): %s\n",
216 			name, strerror(errno));
217 		ecode = 1;
218 	}
219 	close(fd);
220 
221 	return (ecode);
222 }
223