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