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