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 }