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