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