1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/stat.h> 29 #include <strings.h> 30 #include <stdlib.h> 31 #include <unistd.h> 32 #include <errno.h> 33 #include <stdio.h> 34 #include <locale.h> 35 36 #include <nsctl.h> 37 #define __NSC_GEN__ 38 #include <sys/nsctl/nsc_gen.h> 39 #include <sys/nsctl/nsc_mem.h> 40 41 42 /* 43 * Private functions from libsd. 44 */ 45 extern int nsc_nvclean(int); 46 extern int nsc_gmem_data(char *); 47 extern int nsc_gmem_sizes(int *); 48 49 /* 50 * Local functions. 51 */ 52 static int _nsc_gmem(void); 53 static void show_maps(char *, int); 54 55 56 static void 57 usage(void) 58 { 59 (void) fprintf(stderr, gettext("usage: nscadm [-h] command\n")); 60 (void) fprintf(stderr, gettext("valid commands:\n")); 61 (void) fprintf(stderr, gettext(" freeze <device>\n")); 62 (void) fprintf(stderr, gettext(" unfreeze <device>\n")); 63 (void) fprintf(stderr, gettext(" isfrozen <device>\n")); 64 } 65 66 static void 67 is_chr_dev(char *dev, char *op) 68 { 69 struct stat sbuf; 70 if (stat(dev, &sbuf) < 0) { 71 (void) fprintf(stderr, gettext("nscadm: ")); 72 perror(op); 73 exit(255); 74 } 75 if (!S_ISCHR(sbuf.st_mode)) { 76 (void) fprintf(stderr, gettext("nscadm: %s: not a valid device " 77 "<%s>\n"), op, dev); 78 exit(255); 79 } 80 } 81 82 int 83 main(int argc, char *argv[]) 84 { 85 extern int optind, opterr; 86 int opt, rc; 87 88 (void) setlocale(LC_ALL, ""); 89 (void) textdomain("nscadm"); 90 91 rc = 0; 92 opterr = 0; 93 94 while ((opt = getopt(argc, argv, "h")) != -1) { 95 switch (opt) { 96 case 'h': 97 usage(); 98 exit(0); 99 break; 100 default: 101 usage(); 102 exit(255); 103 break; 104 } 105 } 106 107 if (optind == argc) { 108 usage(); 109 exit(255); 110 } 111 112 if (strcoll(argv[optind], gettext("freeze")) == 0 || 113 strcmp(argv[optind], "freeze") == 0) { 114 if (argc - optind != 2) { 115 usage(); 116 exit(255); 117 } 118 119 is_chr_dev(argv[optind+1], "freeze"); 120 rc = nsc_isfrozen(argv[optind+1]); 121 if (rc < 0) { 122 perror(gettext("nscadm: freeze")); 123 exit(255); 124 } else if (rc != 0) { 125 rc = nsc_freeze(argv[optind+1]); 126 if (rc < 0) { 127 perror(gettext("nscadm: freeze")); 128 exit(255); 129 } 130 } else { 131 (void) fprintf(stderr, gettext("nscadm: device <%s> is " 132 "already frozen\n"), argv[optind+1]); 133 exit(255); 134 } 135 136 (void) printf(gettext("nscadm: device <%s> frozen\n"), 137 argv[optind+1]); 138 } else if (strcoll(argv[optind], gettext("unfreeze")) == 0 || 139 strcmp(argv[optind], "unfreeze") == 0) { 140 if (argc - optind != 2) { 141 usage(); 142 exit(255); 143 } 144 145 is_chr_dev(argv[optind+1], "unfreeze"); 146 rc = nsc_isfrozen(argv[optind+1]); 147 if (rc < 0) { 148 perror(gettext("nscadm: unfreeze")); 149 exit(255); 150 } else if (rc == 0) { 151 rc = nsc_unfreeze(argv[optind+1]); 152 if (rc < 0) { 153 perror(gettext("nscadm: unfreeze")); 154 exit(255); 155 } 156 } else { 157 (void) fprintf(stderr, 158 gettext("nscadm: device <%s> is not " 159 "frozen\n"), argv[optind+1]); 160 exit(255); 161 } 162 163 (void) printf(gettext("nscadm: device <%s> unfrozen\n"), 164 argv[optind+1]); 165 } else if (strcoll(argv[optind], gettext("isfrozen")) == 0 || 166 strcmp(argv[optind], "isfrozen") == 0) { 167 if (argc - optind != 2) { 168 usage(); 169 exit(255); 170 } 171 172 is_chr_dev(argv[optind+1], "isfrozen"); 173 rc = nsc_isfrozen(argv[optind+1]); 174 if (rc < 0) { 175 perror(gettext("nscadm: isfrozen")); 176 exit(255); 177 } 178 179 (void) printf(gettext("nscadm: device <%s> is %sfrozen\n"), 180 argv[optind+1], rc ? gettext("not ") : ""); 181 #ifdef DEBUG 182 } else if (strcoll(argv[optind], gettext("nvclean")) == 0 || 183 strcmp(argv[optind], "nvclean") == 0) { 184 rc = nsc_nvclean(0); 185 if (rc < 0) { 186 perror(gettext("nscadm: nvclean")); 187 exit(255); 188 } 189 } else if (strcoll(argv[optind], gettext("nvclean_force")) == 0 || 190 strcmp(argv[optind], "nvclean_force") == 0) { 191 rc = nsc_nvclean(1); 192 if (rc < 0) { 193 perror(gettext("nscadm: nvclean_force")); 194 exit(255); 195 } 196 #endif /* DEBUG */ 197 } else if (strcoll(argv[optind], gettext("gmem")) == 0 || 198 strcmp(argv[optind], "gmem") == 0) { 199 rc = _nsc_gmem(); 200 if (rc < 0) { 201 perror(gettext("nscadm: gmem")); 202 exit(255); 203 } 204 } else { 205 usage(); 206 exit(255); 207 } 208 209 return (rc); 210 } 211 212 213 static int 214 _nsc_gmem(void) 215 { 216 char *addr; 217 int size; 218 int rc = 0; 219 220 rc = nsc_gmem_sizes(&size); 221 222 if (rc < 0) 223 return (rc); 224 225 (void) printf(gettext("size %d\n"), size); 226 227 if ((addr = (char *)malloc(size * 2)) == NULL) { 228 errno = ENOMEM; 229 return (-1); 230 } 231 232 rc = nsc_gmem_data(addr); 233 234 if (rc < 0) { 235 free(addr); 236 return (rc); 237 } 238 239 (void) printf(gettext("Global map entries:\n")); 240 show_maps(addr, size); 241 242 (void) printf(gettext("\nGlobal NVMEM map entries:\n")); 243 show_maps(addr + size, size); 244 245 free(addr); 246 return (0); 247 } 248 249 250 static void 251 show_maps(char *addr, int len) 252 { 253 /* LINTED alignment of cast ok */ 254 nsc_rmhdr_t *rhp = (nsc_rmhdr_t *)addr; 255 nsc_rmmap_t *rmap; 256 char tname[_NSC_MAXNAME + 1]; 257 int i; 258 259 (void) printf( 260 gettext("magic 0x%x ver %d size %d dirty (nvmem systems): %d\n"), 261 rhp->magic, rhp->ver, rhp->size, rhp->rh_dirty); 262 263 for (i = 0, rmap = rhp->map; 264 /* LINTED alignment of cast ok */ 265 rmap < (nsc_rmmap_t *)(addr + len); ++i, ++rmap) { 266 if (!rmap->name[0]) 267 continue; 268 (void) strncpy(tname, rmap->name, _NSC_MAXNAME); 269 (void) strcpy(&tname[strlen(tname)], " "); 270 tname[_NSC_MAXNAME] = '\0'; 271 (void) printf(gettext( 272 "%d:\tname %s\toffset 0x%x size 0x%x inuse 0x%x\n"), 273 i, tname, rmap->offset, rmap->size, rmap->inuse); 274 } 275 } 276