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
usage(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
is_chr_dev(char * dev,char * op)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
main(int argc,char * argv[])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
_nsc_gmem(void)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
show_maps(char * addr,int len)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