1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte /* 22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*fcf3ce44SJohn Forte * Use is subject to license terms. 24*fcf3ce44SJohn Forte */ 25*fcf3ce44SJohn Forte 26*fcf3ce44SJohn Forte #include <sys/types.h> 27*fcf3ce44SJohn Forte #include <sys/stat.h> 28*fcf3ce44SJohn Forte #include <sys/mkdev.h> 29*fcf3ce44SJohn Forte #include <sys/param.h> 30*fcf3ce44SJohn Forte #include <sys/wait.h> 31*fcf3ce44SJohn Forte #include <fcntl.h> 32*fcf3ce44SJohn Forte #include <stdarg.h> 33*fcf3ce44SJohn Forte #include <stdlib.h> 34*fcf3ce44SJohn Forte #include <strings.h> 35*fcf3ce44SJohn Forte #include <errno.h> 36*fcf3ce44SJohn Forte #include <stdio.h> 37*fcf3ce44SJohn Forte #include <locale.h> 38*fcf3ce44SJohn Forte #include <unistd.h> 39*fcf3ce44SJohn Forte #include <search.h> 40*fcf3ce44SJohn Forte #include <libgen.h> 41*fcf3ce44SJohn Forte #include <nsctl.h> 42*fcf3ce44SJohn Forte 43*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s.h> 44*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_u.h> 45*fcf3ce44SJohn Forte #include <sys/unistat/spcs_errors.h> 46*fcf3ce44SJohn Forte 47*fcf3ce44SJohn Forte #include <sys/nsctl/sv.h> 48*fcf3ce44SJohn Forte #include <sys/nsctl/sv_impl.h> 49*fcf3ce44SJohn Forte 50*fcf3ce44SJohn Forte #include <sys/nsctl/cfg.h> 51*fcf3ce44SJohn Forte #include <sys/nsctl/nsc_hash.h> 52*fcf3ce44SJohn Forte 53*fcf3ce44SJohn Forte #include "../sv/svadm.h" 54*fcf3ce44SJohn Forte 55*fcf3ce44SJohn Forte 56*fcf3ce44SJohn Forte static int sv_max_devices; 57*fcf3ce44SJohn Forte 58*fcf3ce44SJohn Forte 59*fcf3ce44SJohn Forte /* 60*fcf3ce44SJohn Forte * support for the special cluster tag "local" to be used with -C in a 61*fcf3ce44SJohn Forte * cluster for local volumes. 62*fcf3ce44SJohn Forte */ 63*fcf3ce44SJohn Forte 64*fcf3ce44SJohn Forte #define SV_LOCAL_TAG "local" 65*fcf3ce44SJohn Forte 66*fcf3ce44SJohn Forte static int sv_islocal; 67*fcf3ce44SJohn Forte 68*fcf3ce44SJohn Forte /* 69*fcf3ce44SJohn Forte * libcfg access. 70*fcf3ce44SJohn Forte */ 71*fcf3ce44SJohn Forte 72*fcf3ce44SJohn Forte static CFGFILE *cfg; /* libcfg file pointer */ 73*fcf3ce44SJohn Forte static int cfg_changed; /* set to 1 if we need to commit changes */ 74*fcf3ce44SJohn Forte 75*fcf3ce44SJohn Forte static char *cfg_cluster_tag; /* local cluster tag */ 76*fcf3ce44SJohn Forte 77*fcf3ce44SJohn Forte static char *implicit_tag; /* implicit cluster tag */ 78*fcf3ce44SJohn Forte 79*fcf3ce44SJohn Forte 80*fcf3ce44SJohn Forte /* 81*fcf3ce44SJohn Forte * Print width for print_sv() output. 82*fcf3ce44SJohn Forte */ 83*fcf3ce44SJohn Forte 84*fcf3ce44SJohn Forte #define STATWIDTH (SV_MAXPATH / 2) 85*fcf3ce44SJohn Forte 86*fcf3ce44SJohn Forte /* 87*fcf3ce44SJohn Forte * Pathnames. 88*fcf3ce44SJohn Forte */ 89*fcf3ce44SJohn Forte 90*fcf3ce44SJohn Forte static const caddr_t sv_rpath = SV_DEVICE; 91*fcf3ce44SJohn Forte 92*fcf3ce44SJohn Forte /* 93*fcf3ce44SJohn Forte * Functions. 94*fcf3ce44SJohn Forte */ 95*fcf3ce44SJohn Forte 96*fcf3ce44SJohn Forte static int read_config_file(const caddr_t, sv_name_t []); 97*fcf3ce44SJohn Forte static int enable_dev(sv_name_t *); 98*fcf3ce44SJohn Forte static int disable_dev(const caddr_t); 99*fcf3ce44SJohn Forte static void error(spcs_s_info_t *, caddr_t, ...); 100*fcf3ce44SJohn Forte static void create_cfg_hash(); 101*fcf3ce44SJohn Forte static int find_in_hash(char *path); 102*fcf3ce44SJohn Forte static void destroy_hashtable(); 103*fcf3ce44SJohn Forte static void remove_from_cfgfile(char *path, int setnumber); 104*fcf3ce44SJohn Forte 105*fcf3ce44SJohn Forte static caddr_t program; 106*fcf3ce44SJohn Forte 107*fcf3ce44SJohn Forte static void 108*fcf3ce44SJohn Forte sv_cfg_open(CFGLOCK mode) 109*fcf3ce44SJohn Forte { 110*fcf3ce44SJohn Forte if (cfg != NULL) 111*fcf3ce44SJohn Forte return; 112*fcf3ce44SJohn Forte 113*fcf3ce44SJohn Forte cfg = cfg_open(NULL); 114*fcf3ce44SJohn Forte if (cfg == NULL) { 115*fcf3ce44SJohn Forte error(NULL, gettext("unable to access the configuration")); 116*fcf3ce44SJohn Forte /* NOTREACHED */ 117*fcf3ce44SJohn Forte } 118*fcf3ce44SJohn Forte 119*fcf3ce44SJohn Forte if (cfg_cluster_tag && *cfg_cluster_tag) { 120*fcf3ce44SJohn Forte cfg_resource(cfg, cfg_cluster_tag); 121*fcf3ce44SJohn Forte } else { 122*fcf3ce44SJohn Forte cfg_resource(cfg, NULL); 123*fcf3ce44SJohn Forte } 124*fcf3ce44SJohn Forte if (!cfg_lock(cfg, mode)) { 125*fcf3ce44SJohn Forte error(NULL, gettext("unable to lock the configuration")); 126*fcf3ce44SJohn Forte /* NOTREACHED */ 127*fcf3ce44SJohn Forte } 128*fcf3ce44SJohn Forte } 129*fcf3ce44SJohn Forte 130*fcf3ce44SJohn Forte 131*fcf3ce44SJohn Forte static void 132*fcf3ce44SJohn Forte sv_cfg_close(void) 133*fcf3ce44SJohn Forte { 134*fcf3ce44SJohn Forte if (cfg == NULL) 135*fcf3ce44SJohn Forte return; 136*fcf3ce44SJohn Forte 137*fcf3ce44SJohn Forte if (cfg_changed) { 138*fcf3ce44SJohn Forte (void) cfg_commit(cfg); 139*fcf3ce44SJohn Forte cfg_changed = 0; 140*fcf3ce44SJohn Forte } 141*fcf3ce44SJohn Forte 142*fcf3ce44SJohn Forte cfg_close(cfg); 143*fcf3ce44SJohn Forte cfg = NULL; 144*fcf3ce44SJohn Forte } 145*fcf3ce44SJohn Forte 146*fcf3ce44SJohn Forte 147*fcf3ce44SJohn Forte 148*fcf3ce44SJohn Forte static void 149*fcf3ce44SJohn Forte usage(void) 150*fcf3ce44SJohn Forte { 151*fcf3ce44SJohn Forte (void) fprintf(stderr, gettext("usage:\n")); 152*fcf3ce44SJohn Forte 153*fcf3ce44SJohn Forte (void) fprintf(stderr, gettext( 154*fcf3ce44SJohn Forte "\t%s -h help\n"), program); 155*fcf3ce44SJohn Forte 156*fcf3ce44SJohn Forte (void) fprintf(stderr, gettext( 157*fcf3ce44SJohn Forte "\t%s [-C tag] display status\n"), 158*fcf3ce44SJohn Forte program); 159*fcf3ce44SJohn Forte 160*fcf3ce44SJohn Forte (void) fprintf(stderr, gettext( 161*fcf3ce44SJohn Forte "\t%s [-C tag] -i display " 162*fcf3ce44SJohn Forte "extended status\n"), program); 163*fcf3ce44SJohn Forte 164*fcf3ce44SJohn Forte (void) fprintf(stderr, gettext( 165*fcf3ce44SJohn Forte "\t%s [-C tag] -v display " 166*fcf3ce44SJohn Forte "version number\n"), program); 167*fcf3ce44SJohn Forte 168*fcf3ce44SJohn Forte (void) fprintf(stderr, gettext( 169*fcf3ce44SJohn Forte "\t%s [-C tag] -e { -f file | volume } enable\n"), program); 170*fcf3ce44SJohn Forte 171*fcf3ce44SJohn Forte (void) fprintf(stderr, gettext( 172*fcf3ce44SJohn Forte "\t%s [-C tag] -d { -f file | volume } disable\n"), program); 173*fcf3ce44SJohn Forte 174*fcf3ce44SJohn Forte (void) fprintf(stderr, gettext( 175*fcf3ce44SJohn Forte "\t%s [-C tag] -r { -f file | volume } reconfigure\n"), program); 176*fcf3ce44SJohn Forte 177*fcf3ce44SJohn Forte sv_cfg_close(); 178*fcf3ce44SJohn Forte } 179*fcf3ce44SJohn Forte 180*fcf3ce44SJohn Forte static void 181*fcf3ce44SJohn Forte message(caddr_t prefix, spcs_s_info_t *status, caddr_t string, va_list ap) 182*fcf3ce44SJohn Forte { 183*fcf3ce44SJohn Forte (void) fprintf(stderr, "%s: %s: ", program, prefix); 184*fcf3ce44SJohn Forte (void) vfprintf(stderr, string, ap); 185*fcf3ce44SJohn Forte (void) fprintf(stderr, "\n"); 186*fcf3ce44SJohn Forte 187*fcf3ce44SJohn Forte if (status) { 188*fcf3ce44SJohn Forte spcs_s_report(*status, stderr); 189*fcf3ce44SJohn Forte spcs_s_ufree(status); 190*fcf3ce44SJohn Forte } 191*fcf3ce44SJohn Forte } 192*fcf3ce44SJohn Forte 193*fcf3ce44SJohn Forte 194*fcf3ce44SJohn Forte static void 195*fcf3ce44SJohn Forte error(spcs_s_info_t *status, caddr_t string, ...) 196*fcf3ce44SJohn Forte { 197*fcf3ce44SJohn Forte va_list ap; 198*fcf3ce44SJohn Forte va_start(ap, string); 199*fcf3ce44SJohn Forte 200*fcf3ce44SJohn Forte message(gettext("error"), status, string, ap); 201*fcf3ce44SJohn Forte 202*fcf3ce44SJohn Forte va_end(ap); 203*fcf3ce44SJohn Forte 204*fcf3ce44SJohn Forte sv_cfg_close(); 205*fcf3ce44SJohn Forte exit(1); 206*fcf3ce44SJohn Forte } 207*fcf3ce44SJohn Forte 208*fcf3ce44SJohn Forte 209*fcf3ce44SJohn Forte static void 210*fcf3ce44SJohn Forte warn(spcs_s_info_t *status, caddr_t string, ...) 211*fcf3ce44SJohn Forte { 212*fcf3ce44SJohn Forte va_list ap; 213*fcf3ce44SJohn Forte va_start(ap, string); 214*fcf3ce44SJohn Forte 215*fcf3ce44SJohn Forte message(gettext("warning"), status, string, ap); 216*fcf3ce44SJohn Forte 217*fcf3ce44SJohn Forte va_end(ap); 218*fcf3ce44SJohn Forte } 219*fcf3ce44SJohn Forte 220*fcf3ce44SJohn Forte 221*fcf3ce44SJohn Forte static void 222*fcf3ce44SJohn Forte sv_get_maxdevs(void) 223*fcf3ce44SJohn Forte { 224*fcf3ce44SJohn Forte sv_name_t svn[1]; 225*fcf3ce44SJohn Forte sv_list_t svl; 226*fcf3ce44SJohn Forte int fd; 227*fcf3ce44SJohn Forte 228*fcf3ce44SJohn Forte if (sv_max_devices > 0) 229*fcf3ce44SJohn Forte return; 230*fcf3ce44SJohn Forte 231*fcf3ce44SJohn Forte fd = open(sv_rpath, O_RDONLY); 232*fcf3ce44SJohn Forte if (fd < 0) 233*fcf3ce44SJohn Forte error(NULL, gettext("unable to open %s: %s"), 234*fcf3ce44SJohn Forte sv_rpath, strerror(errno)); 235*fcf3ce44SJohn Forte 236*fcf3ce44SJohn Forte bzero(&svl, sizeof (svl)); 237*fcf3ce44SJohn Forte bzero(&svn[0], sizeof (svn)); 238*fcf3ce44SJohn Forte 239*fcf3ce44SJohn Forte svl.svl_names = &svn[0]; 240*fcf3ce44SJohn Forte svl.svl_error = spcs_s_ucreate(); 241*fcf3ce44SJohn Forte 242*fcf3ce44SJohn Forte if (ioctl(fd, SVIOC_LIST, &svl) < 0) { 243*fcf3ce44SJohn Forte (void) close(fd); 244*fcf3ce44SJohn Forte error(&svl.svl_error, gettext("unable to get max devs")); 245*fcf3ce44SJohn Forte } 246*fcf3ce44SJohn Forte 247*fcf3ce44SJohn Forte spcs_s_ufree(&svl.svl_error); 248*fcf3ce44SJohn Forte sv_max_devices = svl.svl_maxdevs; 249*fcf3ce44SJohn Forte 250*fcf3ce44SJohn Forte (void) close(fd); 251*fcf3ce44SJohn Forte } 252*fcf3ce44SJohn Forte 253*fcf3ce44SJohn Forte 254*fcf3ce44SJohn Forte static sv_name_t * 255*fcf3ce44SJohn Forte sv_alloc_svnames(void) 256*fcf3ce44SJohn Forte { 257*fcf3ce44SJohn Forte sv_name_t *svn = NULL; 258*fcf3ce44SJohn Forte 259*fcf3ce44SJohn Forte sv_get_maxdevs(); 260*fcf3ce44SJohn Forte 261*fcf3ce44SJohn Forte svn = calloc(sv_max_devices, sizeof (*svn)); 262*fcf3ce44SJohn Forte if (svn == NULL) { 263*fcf3ce44SJohn Forte error(NULL, "unable to allocate %ld bytes of memory", 264*fcf3ce44SJohn Forte sv_max_devices * sizeof (*svn)); 265*fcf3ce44SJohn Forte } 266*fcf3ce44SJohn Forte 267*fcf3ce44SJohn Forte return (svn); 268*fcf3ce44SJohn Forte } 269*fcf3ce44SJohn Forte 270*fcf3ce44SJohn Forte 271*fcf3ce44SJohn Forte static void 272*fcf3ce44SJohn Forte sv_check_dgislocal(char *dgname) 273*fcf3ce44SJohn Forte { 274*fcf3ce44SJohn Forte char *othernode; 275*fcf3ce44SJohn Forte int rc; 276*fcf3ce44SJohn Forte 277*fcf3ce44SJohn Forte /* 278*fcf3ce44SJohn Forte * check where this disk service is mastered 279*fcf3ce44SJohn Forte */ 280*fcf3ce44SJohn Forte 281*fcf3ce44SJohn Forte rc = cfg_dgname_islocal(dgname, &othernode); 282*fcf3ce44SJohn Forte if (rc < 0) { 283*fcf3ce44SJohn Forte error(NULL, gettext("unable to find " 284*fcf3ce44SJohn Forte "disk service, %s: %s"), dgname, strerror(errno)); 285*fcf3ce44SJohn Forte } 286*fcf3ce44SJohn Forte 287*fcf3ce44SJohn Forte if (rc == 0) { 288*fcf3ce44SJohn Forte error(NULL, gettext("disk service, %s, is " 289*fcf3ce44SJohn Forte "active on node \"%s\"\nPlease re-issue " 290*fcf3ce44SJohn Forte "the command on that node"), dgname, othernode); 291*fcf3ce44SJohn Forte } 292*fcf3ce44SJohn Forte } 293*fcf3ce44SJohn Forte 294*fcf3ce44SJohn Forte 295*fcf3ce44SJohn Forte /* 296*fcf3ce44SJohn Forte * Carry out cluster based checks for a specified volume, or just 297*fcf3ce44SJohn Forte * global options. 298*fcf3ce44SJohn Forte */ 299*fcf3ce44SJohn Forte static void 300*fcf3ce44SJohn Forte sv_check_cluster(char *path) 301*fcf3ce44SJohn Forte { 302*fcf3ce44SJohn Forte char dgname[CFG_MAX_BUF]; 303*fcf3ce44SJohn Forte static int sv_iscluster = -1; /* set to 1 if running in a cluster */ 304*fcf3ce44SJohn Forte 305*fcf3ce44SJohn Forte /* 306*fcf3ce44SJohn Forte * Find out if we are running in a cluster 307*fcf3ce44SJohn Forte */ 308*fcf3ce44SJohn Forte if (sv_iscluster == -1) { 309*fcf3ce44SJohn Forte if ((sv_iscluster = cfg_iscluster()) < 0) { 310*fcf3ce44SJohn Forte error(NULL, gettext("unable to ascertain environment")); 311*fcf3ce44SJohn Forte } 312*fcf3ce44SJohn Forte } 313*fcf3ce44SJohn Forte 314*fcf3ce44SJohn Forte if (!sv_iscluster && cfg_cluster_tag != NULL) { 315*fcf3ce44SJohn Forte error(NULL, gettext("-C is not valid when not in a cluster")); 316*fcf3ce44SJohn Forte } 317*fcf3ce44SJohn Forte 318*fcf3ce44SJohn Forte if (!sv_iscluster || sv_islocal || path == NULL) { 319*fcf3ce44SJohn Forte return; 320*fcf3ce44SJohn Forte } 321*fcf3ce44SJohn Forte 322*fcf3ce44SJohn Forte 323*fcf3ce44SJohn Forte /* 324*fcf3ce44SJohn Forte * Cluster-only checks on pathname 325*fcf3ce44SJohn Forte */ 326*fcf3ce44SJohn Forte if (cfg_dgname(path, dgname, sizeof (dgname)) == NULL) { 327*fcf3ce44SJohn Forte error(NULL, gettext("unable to determine " 328*fcf3ce44SJohn Forte "disk group name for %s"), path); 329*fcf3ce44SJohn Forte return; 330*fcf3ce44SJohn Forte } 331*fcf3ce44SJohn Forte 332*fcf3ce44SJohn Forte if (cfg_cluster_tag != NULL) { 333*fcf3ce44SJohn Forte /* 334*fcf3ce44SJohn Forte * Do dgislocal check now in case path did not contain 335*fcf3ce44SJohn Forte * a dgname. 336*fcf3ce44SJohn Forte * 337*fcf3ce44SJohn Forte * E.g. adding a /dev/did/ device to a disk service. 338*fcf3ce44SJohn Forte */ 339*fcf3ce44SJohn Forte 340*fcf3ce44SJohn Forte sv_check_dgislocal(cfg_cluster_tag); 341*fcf3ce44SJohn Forte } 342*fcf3ce44SJohn Forte 343*fcf3ce44SJohn Forte if (strcmp(dgname, "") == 0) 344*fcf3ce44SJohn Forte return; /* NULL dgname is valid */ 345*fcf3ce44SJohn Forte 346*fcf3ce44SJohn Forte if (cfg_cluster_tag == NULL) { 347*fcf3ce44SJohn Forte /* 348*fcf3ce44SJohn Forte * Implicitly set the cluster tag to dgname 349*fcf3ce44SJohn Forte */ 350*fcf3ce44SJohn Forte 351*fcf3ce44SJohn Forte sv_check_dgislocal(dgname); 352*fcf3ce44SJohn Forte 353*fcf3ce44SJohn Forte if (implicit_tag) { 354*fcf3ce44SJohn Forte free(implicit_tag); 355*fcf3ce44SJohn Forte implicit_tag = NULL; 356*fcf3ce44SJohn Forte } 357*fcf3ce44SJohn Forte 358*fcf3ce44SJohn Forte implicit_tag = strdup(dgname); 359*fcf3ce44SJohn Forte if (implicit_tag == NULL) { 360*fcf3ce44SJohn Forte error(NULL, 361*fcf3ce44SJohn Forte gettext("unable to allocate memory " 362*fcf3ce44SJohn Forte "for cluster tag")); 363*fcf3ce44SJohn Forte } 364*fcf3ce44SJohn Forte } else { 365*fcf3ce44SJohn Forte /* 366*fcf3ce44SJohn Forte * Check dgname and cluster tag from -C are the same. 367*fcf3ce44SJohn Forte */ 368*fcf3ce44SJohn Forte 369*fcf3ce44SJohn Forte if (strcmp(dgname, cfg_cluster_tag) != 0) { 370*fcf3ce44SJohn Forte error(NULL, 371*fcf3ce44SJohn Forte gettext("-C (%s) does not match disk group " 372*fcf3ce44SJohn Forte "name (%s) for %s"), cfg_cluster_tag, 373*fcf3ce44SJohn Forte dgname, path); 374*fcf3ce44SJohn Forte } 375*fcf3ce44SJohn Forte 376*fcf3ce44SJohn Forte /* 377*fcf3ce44SJohn Forte * sv_check_dgislocal(cfg_cluster_tag) was called above. 378*fcf3ce44SJohn Forte */ 379*fcf3ce44SJohn Forte } 380*fcf3ce44SJohn Forte } 381*fcf3ce44SJohn Forte 382*fcf3ce44SJohn Forte 383*fcf3ce44SJohn Forte static void 384*fcf3ce44SJohn Forte print_version(void) 385*fcf3ce44SJohn Forte { 386*fcf3ce44SJohn Forte sv_version_t svv; 387*fcf3ce44SJohn Forte int fd; 388*fcf3ce44SJohn Forte 389*fcf3ce44SJohn Forte bzero(&svv, sizeof (svv)); 390*fcf3ce44SJohn Forte svv.svv_error = spcs_s_ucreate(); 391*fcf3ce44SJohn Forte 392*fcf3ce44SJohn Forte fd = open(sv_rpath, O_RDONLY); 393*fcf3ce44SJohn Forte if (fd < 0) { 394*fcf3ce44SJohn Forte warn(NULL, gettext("unable to open %s: %s"), 395*fcf3ce44SJohn Forte sv_rpath, strerror(errno)); 396*fcf3ce44SJohn Forte return; 397*fcf3ce44SJohn Forte } 398*fcf3ce44SJohn Forte 399*fcf3ce44SJohn Forte if (ioctl(fd, SVIOC_VERSION, &svv) != 0) { 400*fcf3ce44SJohn Forte error(&svv.svv_error, 401*fcf3ce44SJohn Forte gettext("unable to read the version number")); 402*fcf3ce44SJohn Forte /* NOTREACHED */ 403*fcf3ce44SJohn Forte } 404*fcf3ce44SJohn Forte 405*fcf3ce44SJohn Forte spcs_s_ufree(&svv.svv_error); 406*fcf3ce44SJohn Forte #ifdef DEBUG 407*fcf3ce44SJohn Forte (void) printf(gettext("Storage Volume version %d.%d.%d.%d\n"), 408*fcf3ce44SJohn Forte svv.svv_major_rev, svv.svv_minor_rev, 409*fcf3ce44SJohn Forte svv.svv_micro_rev, svv.svv_baseline_rev); 410*fcf3ce44SJohn Forte #else 411*fcf3ce44SJohn Forte if (svv.svv_micro_rev) { 412*fcf3ce44SJohn Forte (void) printf(gettext("Storage Volume version %d.%d.%d\n"), 413*fcf3ce44SJohn Forte svv.svv_major_rev, svv.svv_minor_rev, svv.svv_micro_rev); 414*fcf3ce44SJohn Forte } else { 415*fcf3ce44SJohn Forte (void) printf(gettext("Storage Volume version %d.%d\n"), 416*fcf3ce44SJohn Forte svv.svv_major_rev, svv.svv_minor_rev); 417*fcf3ce44SJohn Forte } 418*fcf3ce44SJohn Forte #endif 419*fcf3ce44SJohn Forte 420*fcf3ce44SJohn Forte (void) close(fd); 421*fcf3ce44SJohn Forte } 422*fcf3ce44SJohn Forte 423*fcf3ce44SJohn Forte int 424*fcf3ce44SJohn Forte main(int argc, char *argv[]) 425*fcf3ce44SJohn Forte { 426*fcf3ce44SJohn Forte extern int optind; 427*fcf3ce44SJohn Forte extern char *optarg; 428*fcf3ce44SJohn Forte char *conf_file = NULL; 429*fcf3ce44SJohn Forte int enable, disable, compare, print, version; 430*fcf3ce44SJohn Forte int opt, Cflag, fflag, iflag; 431*fcf3ce44SJohn Forte int rc; 432*fcf3ce44SJohn Forte 433*fcf3ce44SJohn Forte (void) setlocale(LC_ALL, ""); 434*fcf3ce44SJohn Forte (void) textdomain("svadm"); 435*fcf3ce44SJohn Forte 436*fcf3ce44SJohn Forte program = strdup(basename(argv[0])); 437*fcf3ce44SJohn Forte 438*fcf3ce44SJohn Forte Cflag = fflag = iflag = 0; 439*fcf3ce44SJohn Forte compare = enable = disable = version = 0; 440*fcf3ce44SJohn Forte 441*fcf3ce44SJohn Forte print = 1; 442*fcf3ce44SJohn Forte 443*fcf3ce44SJohn Forte while ((opt = getopt(argc, argv, "C:def:hirv")) != EOF) { 444*fcf3ce44SJohn Forte switch (opt) { 445*fcf3ce44SJohn Forte 446*fcf3ce44SJohn Forte case 'C': 447*fcf3ce44SJohn Forte if (Cflag) { 448*fcf3ce44SJohn Forte warn(NULL, 449*fcf3ce44SJohn Forte gettext("-C specified multiple times")); 450*fcf3ce44SJohn Forte usage(); 451*fcf3ce44SJohn Forte exit(2); 452*fcf3ce44SJohn Forte /* NOTREACHED */ 453*fcf3ce44SJohn Forte } 454*fcf3ce44SJohn Forte 455*fcf3ce44SJohn Forte Cflag++; 456*fcf3ce44SJohn Forte cfg_cluster_tag = optarg; 457*fcf3ce44SJohn Forte break; 458*fcf3ce44SJohn Forte 459*fcf3ce44SJohn Forte case 'e': 460*fcf3ce44SJohn Forte print = 0; 461*fcf3ce44SJohn Forte enable++; 462*fcf3ce44SJohn Forte break; 463*fcf3ce44SJohn Forte 464*fcf3ce44SJohn Forte case 'd': 465*fcf3ce44SJohn Forte print = 0; 466*fcf3ce44SJohn Forte disable++; 467*fcf3ce44SJohn Forte break; 468*fcf3ce44SJohn Forte 469*fcf3ce44SJohn Forte case 'f': 470*fcf3ce44SJohn Forte fflag++; 471*fcf3ce44SJohn Forte conf_file = optarg; 472*fcf3ce44SJohn Forte break; 473*fcf3ce44SJohn Forte 474*fcf3ce44SJohn Forte case 'i': 475*fcf3ce44SJohn Forte iflag++; 476*fcf3ce44SJohn Forte break; 477*fcf3ce44SJohn Forte 478*fcf3ce44SJohn Forte case 'r': 479*fcf3ce44SJohn Forte /* Compare running system with sv.cf */ 480*fcf3ce44SJohn Forte print = 0; 481*fcf3ce44SJohn Forte compare++; 482*fcf3ce44SJohn Forte break; 483*fcf3ce44SJohn Forte 484*fcf3ce44SJohn Forte case 'v': 485*fcf3ce44SJohn Forte print = 0; 486*fcf3ce44SJohn Forte version++; 487*fcf3ce44SJohn Forte break; 488*fcf3ce44SJohn Forte 489*fcf3ce44SJohn Forte case 'h': 490*fcf3ce44SJohn Forte usage(); 491*fcf3ce44SJohn Forte exit(0); 492*fcf3ce44SJohn Forte 493*fcf3ce44SJohn Forte default: 494*fcf3ce44SJohn Forte usage(); 495*fcf3ce44SJohn Forte exit(2); 496*fcf3ce44SJohn Forte /* NOTREACHED */ 497*fcf3ce44SJohn Forte } 498*fcf3ce44SJohn Forte } 499*fcf3ce44SJohn Forte 500*fcf3ce44SJohn Forte 501*fcf3ce44SJohn Forte /* 502*fcf3ce44SJohn Forte * Usage checks 503*fcf3ce44SJohn Forte */ 504*fcf3ce44SJohn Forte 505*fcf3ce44SJohn Forte if ((enable + disable + compare) > 1) { 506*fcf3ce44SJohn Forte warn(NULL, gettext("-d, -e and -r are mutually exclusive")); 507*fcf3ce44SJohn Forte usage(); 508*fcf3ce44SJohn Forte exit(2); 509*fcf3ce44SJohn Forte } 510*fcf3ce44SJohn Forte 511*fcf3ce44SJohn Forte if (fflag && (print || version)) { 512*fcf3ce44SJohn Forte warn(NULL, gettext("-f is only valid with -d, -e or -r")); 513*fcf3ce44SJohn Forte usage(); 514*fcf3ce44SJohn Forte exit(2); 515*fcf3ce44SJohn Forte } 516*fcf3ce44SJohn Forte 517*fcf3ce44SJohn Forte if (fflag && optind != argc) { 518*fcf3ce44SJohn Forte usage(); 519*fcf3ce44SJohn Forte exit(2); 520*fcf3ce44SJohn Forte } 521*fcf3ce44SJohn Forte 522*fcf3ce44SJohn Forte if (print || version) { 523*fcf3ce44SJohn Forte /* check for no more args */ 524*fcf3ce44SJohn Forte 525*fcf3ce44SJohn Forte if (optind != argc) { 526*fcf3ce44SJohn Forte usage(); 527*fcf3ce44SJohn Forte exit(2); 528*fcf3ce44SJohn Forte } 529*fcf3ce44SJohn Forte } else { 530*fcf3ce44SJohn Forte /* check for inline args */ 531*fcf3ce44SJohn Forte 532*fcf3ce44SJohn Forte if (!fflag && (argc - optind) != 1) { 533*fcf3ce44SJohn Forte usage(); 534*fcf3ce44SJohn Forte exit(2); 535*fcf3ce44SJohn Forte } 536*fcf3ce44SJohn Forte } 537*fcf3ce44SJohn Forte 538*fcf3ce44SJohn Forte if (!print && iflag) { 539*fcf3ce44SJohn Forte usage(); 540*fcf3ce44SJohn Forte exit(2); 541*fcf3ce44SJohn Forte } 542*fcf3ce44SJohn Forte 543*fcf3ce44SJohn Forte 544*fcf3ce44SJohn Forte /* 545*fcf3ce44SJohn Forte * Check for the special cluster tag and convert into the 546*fcf3ce44SJohn Forte * internal representation. 547*fcf3ce44SJohn Forte */ 548*fcf3ce44SJohn Forte 549*fcf3ce44SJohn Forte if (cfg_cluster_tag != NULL && 550*fcf3ce44SJohn Forte strcmp(cfg_cluster_tag, SV_LOCAL_TAG) == 0) { 551*fcf3ce44SJohn Forte cfg_cluster_tag = "-"; 552*fcf3ce44SJohn Forte sv_islocal = 1; 553*fcf3ce44SJohn Forte } 554*fcf3ce44SJohn Forte 555*fcf3ce44SJohn Forte 556*fcf3ce44SJohn Forte /* 557*fcf3ce44SJohn Forte * Process commands 558*fcf3ce44SJohn Forte */ 559*fcf3ce44SJohn Forte 560*fcf3ce44SJohn Forte if (optind != argc) { 561*fcf3ce44SJohn Forte /* deal with inline volume argument */ 562*fcf3ce44SJohn Forte 563*fcf3ce44SJohn Forte rc = 0; 564*fcf3ce44SJohn Forte if (enable) 565*fcf3ce44SJohn Forte rc = enable_one_sv(argv[optind]); 566*fcf3ce44SJohn Forte else if (disable) 567*fcf3ce44SJohn Forte rc = disable_one_sv(argv[optind]); 568*fcf3ce44SJohn Forte else /* if (compare) */ 569*fcf3ce44SJohn Forte compare_one_sv(argv[optind]); 570*fcf3ce44SJohn Forte 571*fcf3ce44SJohn Forte if (rc != 0) 572*fcf3ce44SJohn Forte return (1); 573*fcf3ce44SJohn Forte 574*fcf3ce44SJohn Forte return (0); 575*fcf3ce44SJohn Forte } 576*fcf3ce44SJohn Forte 577*fcf3ce44SJohn Forte rc = 0; 578*fcf3ce44SJohn Forte if (enable) 579*fcf3ce44SJohn Forte rc = enable_sv(conf_file); 580*fcf3ce44SJohn Forte else if (disable) 581*fcf3ce44SJohn Forte rc = disable_sv(conf_file); 582*fcf3ce44SJohn Forte else if (compare) 583*fcf3ce44SJohn Forte compare_sv(conf_file); 584*fcf3ce44SJohn Forte else if (print) 585*fcf3ce44SJohn Forte print_sv(iflag); 586*fcf3ce44SJohn Forte else /* if (version) */ 587*fcf3ce44SJohn Forte print_version(); 588*fcf3ce44SJohn Forte 589*fcf3ce44SJohn Forte if (rc != 0) 590*fcf3ce44SJohn Forte return (1); 591*fcf3ce44SJohn Forte 592*fcf3ce44SJohn Forte return (0); 593*fcf3ce44SJohn Forte } 594*fcf3ce44SJohn Forte 595*fcf3ce44SJohn Forte 596*fcf3ce44SJohn Forte 597*fcf3ce44SJohn Forte /* LINT - not static as fwcadm uses it */ 598*fcf3ce44SJohn Forte static int 599*fcf3ce44SJohn Forte enable_sv(char *conf_file) 600*fcf3ce44SJohn Forte { 601*fcf3ce44SJohn Forte int index; 602*fcf3ce44SJohn Forte sv_name_t *svn; 603*fcf3ce44SJohn Forte int cnt; 604*fcf3ce44SJohn Forte int rc, ret; 605*fcf3ce44SJohn Forte 606*fcf3ce44SJohn Forte svn = sv_alloc_svnames(); 607*fcf3ce44SJohn Forte 608*fcf3ce44SJohn Forte index = read_config_file(conf_file, svn); 609*fcf3ce44SJohn Forte 610*fcf3ce44SJohn Forte rc = ret = 0; 611*fcf3ce44SJohn Forte 612*fcf3ce44SJohn Forte for (cnt = 0; cnt < index; cnt++) { 613*fcf3ce44SJohn Forte 614*fcf3ce44SJohn Forte /* 615*fcf3ce44SJohn Forte * Check for more data. 616*fcf3ce44SJohn Forte */ 617*fcf3ce44SJohn Forte if (svn[cnt].svn_path[0] == '\0') { 618*fcf3ce44SJohn Forte /* 619*fcf3ce44SJohn Forte * This was set when reading sv.conf. After the last 620*fcf3ce44SJohn Forte * line svn_path was set to \0, so we are finished. 621*fcf3ce44SJohn Forte * We shouldn't get here, but put this in just in 622*fcf3ce44SJohn Forte * case. 623*fcf3ce44SJohn Forte */ 624*fcf3ce44SJohn Forte break; 625*fcf3ce44SJohn Forte } 626*fcf3ce44SJohn Forte rc = enable_dev(&svn[cnt]); 627*fcf3ce44SJohn Forte if (rc && !ret) 628*fcf3ce44SJohn Forte ret = rc; 629*fcf3ce44SJohn Forte } 630*fcf3ce44SJohn Forte 631*fcf3ce44SJohn Forte sv_cfg_close(); 632*fcf3ce44SJohn Forte 633*fcf3ce44SJohn Forte return (ret); 634*fcf3ce44SJohn Forte } 635*fcf3ce44SJohn Forte 636*fcf3ce44SJohn Forte 637*fcf3ce44SJohn Forte /* LINT - not static as fwcadm uses it */ 638*fcf3ce44SJohn Forte static int 639*fcf3ce44SJohn Forte enable_one_sv(caddr_t path) 640*fcf3ce44SJohn Forte { 641*fcf3ce44SJohn Forte sv_name_t svn; 642*fcf3ce44SJohn Forte int rc; 643*fcf3ce44SJohn Forte 644*fcf3ce44SJohn Forte sv_get_maxdevs(); 645*fcf3ce44SJohn Forte 646*fcf3ce44SJohn Forte bzero(&svn, sizeof (svn)); 647*fcf3ce44SJohn Forte (void) strncpy(svn.svn_path, path, sizeof (svn.svn_path)); 648*fcf3ce44SJohn Forte svn.svn_mode = (NSC_DEVICE | NSC_CACHE); 649*fcf3ce44SJohn Forte 650*fcf3ce44SJohn Forte /* force NULL termination */ 651*fcf3ce44SJohn Forte svn.svn_path[sizeof (svn.svn_path) - 1] = '\0'; 652*fcf3ce44SJohn Forte 653*fcf3ce44SJohn Forte rc = enable_dev(&svn); 654*fcf3ce44SJohn Forte sv_cfg_close(); 655*fcf3ce44SJohn Forte 656*fcf3ce44SJohn Forte return (rc); 657*fcf3ce44SJohn Forte } 658*fcf3ce44SJohn Forte 659*fcf3ce44SJohn Forte 660*fcf3ce44SJohn Forte static int 661*fcf3ce44SJohn Forte enable_dev(sv_name_t *svn) 662*fcf3ce44SJohn Forte { 663*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 664*fcf3ce44SJohn Forte struct stat stb; 665*fcf3ce44SJohn Forte sv_conf_t svc; 666*fcf3ce44SJohn Forte int fd; 667*fcf3ce44SJohn Forte int sev; 668*fcf3ce44SJohn Forte int rc; 669*fcf3ce44SJohn Forte char *lcltag; 670*fcf3ce44SJohn Forte char *altname; 671*fcf3ce44SJohn Forte 672*fcf3ce44SJohn Forte sv_check_cluster(svn->svn_path); 673*fcf3ce44SJohn Forte sv_cfg_open(CFG_WRLOCK); 674*fcf3ce44SJohn Forte 675*fcf3ce44SJohn Forte bzero(&svc, sizeof (svc)); 676*fcf3ce44SJohn Forte 677*fcf3ce44SJohn Forte if (stat(svn->svn_path, &stb) != 0) { 678*fcf3ce44SJohn Forte warn(NULL, gettext("unable to access %s: %s"), 679*fcf3ce44SJohn Forte svn->svn_path, strerror(errno)); 680*fcf3ce44SJohn Forte return (1); 681*fcf3ce44SJohn Forte } 682*fcf3ce44SJohn Forte 683*fcf3ce44SJohn Forte if (!S_ISCHR(stb.st_mode)) { 684*fcf3ce44SJohn Forte warn(NULL, gettext("%s is not a character device - ignored"), 685*fcf3ce44SJohn Forte svn->svn_path); 686*fcf3ce44SJohn Forte return (1); 687*fcf3ce44SJohn Forte } 688*fcf3ce44SJohn Forte 689*fcf3ce44SJohn Forte svc.svc_major = major(stb.st_rdev); 690*fcf3ce44SJohn Forte svc.svc_minor = minor(stb.st_rdev); 691*fcf3ce44SJohn Forte (void) strncpy(svc.svc_path, svn->svn_path, sizeof (svc.svc_path)); 692*fcf3ce44SJohn Forte 693*fcf3ce44SJohn Forte fd = open(sv_rpath, O_RDONLY); 694*fcf3ce44SJohn Forte if (fd < 0) { 695*fcf3ce44SJohn Forte warn(NULL, gettext("unable to open %s: %s"), 696*fcf3ce44SJohn Forte svn->svn_path, strerror(errno)); 697*fcf3ce44SJohn Forte return (1); 698*fcf3ce44SJohn Forte } 699*fcf3ce44SJohn Forte 700*fcf3ce44SJohn Forte svc.svc_flag = svn->svn_mode; 701*fcf3ce44SJohn Forte svc.svc_error = spcs_s_ucreate(); 702*fcf3ce44SJohn Forte 703*fcf3ce44SJohn Forte /* first, check for duplicates */ 704*fcf3ce44SJohn Forte rc = cfg_get_canonical_name(cfg, svn->svn_path, &altname); 705*fcf3ce44SJohn Forte if (rc < 0) { 706*fcf3ce44SJohn Forte spcs_log("sv", NULL, gettext("Unable to parse config file")); 707*fcf3ce44SJohn Forte warn(NULL, gettext("Unable to parse config file")); 708*fcf3ce44SJohn Forte (void) close(fd); 709*fcf3ce44SJohn Forte return (1); 710*fcf3ce44SJohn Forte } 711*fcf3ce44SJohn Forte if (rc) { 712*fcf3ce44SJohn Forte error(NULL, gettext("'%s' has already been configured as " 713*fcf3ce44SJohn Forte "'%s'. Re-enter command with the latter name."), 714*fcf3ce44SJohn Forte svn->svn_path, altname); 715*fcf3ce44SJohn Forte } 716*fcf3ce44SJohn Forte 717*fcf3ce44SJohn Forte /* secondly, try to insert it into the dsvol config */ 718*fcf3ce44SJohn Forte if (implicit_tag && *implicit_tag) { 719*fcf3ce44SJohn Forte lcltag = implicit_tag; 720*fcf3ce44SJohn Forte } else if (cfg_cluster_tag && *cfg_cluster_tag) { 721*fcf3ce44SJohn Forte lcltag = cfg_cluster_tag; 722*fcf3ce44SJohn Forte } else { 723*fcf3ce44SJohn Forte lcltag = "-"; 724*fcf3ce44SJohn Forte } 725*fcf3ce44SJohn Forte rc = cfg_add_user(cfg, svn->svn_path, lcltag, "sv"); 726*fcf3ce44SJohn Forte if (CFG_USER_ERR == rc) { 727*fcf3ce44SJohn Forte spcs_log("sv", NULL, 728*fcf3ce44SJohn Forte gettext("%s: unable to put %s into dsvol cfg"), 729*fcf3ce44SJohn Forte program, svn->svn_path); 730*fcf3ce44SJohn Forte warn(NULL, gettext("unable to put %s into dsvol cfg"), 731*fcf3ce44SJohn Forte svn->svn_path); 732*fcf3ce44SJohn Forte (void) close(fd); 733*fcf3ce44SJohn Forte return (1); 734*fcf3ce44SJohn Forte } 735*fcf3ce44SJohn Forte cfg_changed = 1; 736*fcf3ce44SJohn Forte 737*fcf3ce44SJohn Forte if (CFG_USER_OK == rc) { 738*fcf3ce44SJohn Forte /* success */ 739*fcf3ce44SJohn Forte (void) close(fd); 740*fcf3ce44SJohn Forte return (0); 741*fcf3ce44SJohn Forte } 742*fcf3ce44SJohn Forte 743*fcf3ce44SJohn Forte if (ioctl(fd, SVIOC_ENABLE, &svc) < 0) { 744*fcf3ce44SJohn Forte if ((CFG_USER_REPEAT == rc) && (SV_EENABLED == errno)) { 745*fcf3ce44SJohn Forte /* it's ok -- we were just double-checking */ 746*fcf3ce44SJohn Forte (void) close(fd); 747*fcf3ce44SJohn Forte return (0); 748*fcf3ce44SJohn Forte } 749*fcf3ce44SJohn Forte 750*fcf3ce44SJohn Forte spcs_log("sv", &svc.svc_error, 751*fcf3ce44SJohn Forte gettext("%s: unable to enable %s"), 752*fcf3ce44SJohn Forte program, svn->svn_path); 753*fcf3ce44SJohn Forte 754*fcf3ce44SJohn Forte warn(&svc.svc_error, gettext("unable to enable %s"), 755*fcf3ce44SJohn Forte svn->svn_path); 756*fcf3ce44SJohn Forte 757*fcf3ce44SJohn Forte /* remove it from dsvol, if we're the ones who put it in */ 758*fcf3ce44SJohn Forte if (CFG_USER_FIRST == rc) { 759*fcf3ce44SJohn Forte (void) cfg_rem_user(cfg, svn->svn_path, lcltag, "sv"); 760*fcf3ce44SJohn Forte } 761*fcf3ce44SJohn Forte (void) close(fd); 762*fcf3ce44SJohn Forte return (1); 763*fcf3ce44SJohn Forte } 764*fcf3ce44SJohn Forte 765*fcf3ce44SJohn Forte spcs_log("sv", NULL, gettext("%s: enabled %s"), 766*fcf3ce44SJohn Forte program, svn->svn_path); 767*fcf3ce44SJohn Forte 768*fcf3ce44SJohn Forte if (implicit_tag != NULL) { 769*fcf3ce44SJohn Forte #ifdef DEBUG 770*fcf3ce44SJohn Forte if (cfg_cluster_tag != NULL) { 771*fcf3ce44SJohn Forte error(NULL, 772*fcf3ce44SJohn Forte gettext("enable_dev: -C %s AND implicit_tag %s!"), 773*fcf3ce44SJohn Forte cfg_cluster_tag, implicit_tag); 774*fcf3ce44SJohn Forte } 775*fcf3ce44SJohn Forte #endif 776*fcf3ce44SJohn Forte 777*fcf3ce44SJohn Forte (void) snprintf(buf, sizeof (buf), "%s - %s", 778*fcf3ce44SJohn Forte svc.svc_path, implicit_tag); 779*fcf3ce44SJohn Forte } else { 780*fcf3ce44SJohn Forte (void) strcpy(buf, svc.svc_path); 781*fcf3ce44SJohn Forte } 782*fcf3ce44SJohn Forte 783*fcf3ce44SJohn Forte rc = 0; 784*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, "sv", buf, sizeof (buf)) < 0) { 785*fcf3ce44SJohn Forte warn(NULL, 786*fcf3ce44SJohn Forte gettext("unable to add %s to configuration storage: %s"), 787*fcf3ce44SJohn Forte svc.svc_path, cfg_error(&sev)); 788*fcf3ce44SJohn Forte rc = 1; 789*fcf3ce44SJohn Forte } 790*fcf3ce44SJohn Forte 791*fcf3ce44SJohn Forte cfg_changed = 1; 792*fcf3ce44SJohn Forte spcs_s_ufree(&svc.svc_error); 793*fcf3ce44SJohn Forte (void) close(fd); 794*fcf3ce44SJohn Forte 795*fcf3ce44SJohn Forte return (rc); 796*fcf3ce44SJohn Forte } 797*fcf3ce44SJohn Forte 798*fcf3ce44SJohn Forte 799*fcf3ce44SJohn Forte /* 800*fcf3ce44SJohn Forte * This routine parses the config file passed in via conf_file and 801*fcf3ce44SJohn Forte * stores the data in the svn array. The return value is the number 802*fcf3ce44SJohn Forte * of entries read from conf_file. If an error occurs the error() 803*fcf3ce44SJohn Forte * routine is called (which exits the program). 804*fcf3ce44SJohn Forte */ 805*fcf3ce44SJohn Forte static int 806*fcf3ce44SJohn Forte read_config_file(const caddr_t conf_file, sv_name_t svn[]) 807*fcf3ce44SJohn Forte { 808*fcf3ce44SJohn Forte char line[1024], rdev[1024], junk[1024]; 809*fcf3ce44SJohn Forte struct stat stb; 810*fcf3ce44SJohn Forte int lineno; 811*fcf3ce44SJohn Forte int cnt, i; 812*fcf3ce44SJohn Forte int index = 0; /* Current location in svn array */ 813*fcf3ce44SJohn Forte sv_name_t *cur_svn; /* Pointer to svn[index] */ 814*fcf3ce44SJohn Forte FILE *fp; 815*fcf3ce44SJohn Forte 816*fcf3ce44SJohn Forte if (access(conf_file, R_OK) != 0 || 817*fcf3ce44SJohn Forte stat(conf_file, &stb) != 0 || 818*fcf3ce44SJohn Forte !S_ISREG(stb.st_mode)) { 819*fcf3ce44SJohn Forte error(NULL, gettext("cannot read config file %s"), conf_file); 820*fcf3ce44SJohn Forte } 821*fcf3ce44SJohn Forte 822*fcf3ce44SJohn Forte if ((fp = fopen(conf_file, "r")) == NULL) { 823*fcf3ce44SJohn Forte error(NULL, gettext("unable to open config file %s: %s"), 824*fcf3ce44SJohn Forte conf_file, strerror(errno)); 825*fcf3ce44SJohn Forte } 826*fcf3ce44SJohn Forte 827*fcf3ce44SJohn Forte lineno = 0; 828*fcf3ce44SJohn Forte 829*fcf3ce44SJohn Forte while (fgets(line, sizeof (line), fp) != NULL) { 830*fcf3ce44SJohn Forte lineno++; 831*fcf3ce44SJohn Forte 832*fcf3ce44SJohn Forte i = strlen(line); 833*fcf3ce44SJohn Forte 834*fcf3ce44SJohn Forte if (i < 1) 835*fcf3ce44SJohn Forte continue; 836*fcf3ce44SJohn Forte 837*fcf3ce44SJohn Forte if (line[i-1] == '\n') 838*fcf3ce44SJohn Forte line[i-1] = '\0'; 839*fcf3ce44SJohn Forte else if (i == (sizeof (line) - 1)) { 840*fcf3ce44SJohn Forte warn(NULL, gettext( 841*fcf3ce44SJohn Forte "line %d: line too long -- should be less than %d characters"), 842*fcf3ce44SJohn Forte lineno, (sizeof (line) - 1)); 843*fcf3ce44SJohn Forte warn(NULL, gettext("line %d: ignored"), lineno); 844*fcf3ce44SJohn Forte } 845*fcf3ce44SJohn Forte 846*fcf3ce44SJohn Forte /* 847*fcf3ce44SJohn Forte * check for comment line. 848*fcf3ce44SJohn Forte */ 849*fcf3ce44SJohn Forte if (line[0] == '#') 850*fcf3ce44SJohn Forte continue; 851*fcf3ce44SJohn Forte 852*fcf3ce44SJohn Forte cnt = sscanf(line, "%s %s", rdev, junk); 853*fcf3ce44SJohn Forte 854*fcf3ce44SJohn Forte if (cnt != 1 && cnt != 2) { 855*fcf3ce44SJohn Forte if (cnt > 0) { 856*fcf3ce44SJohn Forte warn(NULL, gettext("line %d: invalid format"), 857*fcf3ce44SJohn Forte lineno); 858*fcf3ce44SJohn Forte warn(NULL, gettext("line %d: ignored"), lineno); 859*fcf3ce44SJohn Forte } 860*fcf3ce44SJohn Forte continue; 861*fcf3ce44SJohn Forte } 862*fcf3ce44SJohn Forte 863*fcf3ce44SJohn Forte rdev[sizeof (rdev) - 1] = '\0'; 864*fcf3ce44SJohn Forte 865*fcf3ce44SJohn Forte cur_svn = &svn[index]; /* For easier reading below */ 866*fcf3ce44SJohn Forte 867*fcf3ce44SJohn Forte if (strlen(rdev) >= sizeof (cur_svn->svn_path)) { 868*fcf3ce44SJohn Forte warn(NULL, gettext( 869*fcf3ce44SJohn Forte "line %d: raw device name (%s) longer than %d characters"), 870*fcf3ce44SJohn Forte lineno, rdev, 871*fcf3ce44SJohn Forte (sizeof (cur_svn->svn_path) - 1)); 872*fcf3ce44SJohn Forte warn(NULL, gettext("line %d: ignored"), lineno); 873*fcf3ce44SJohn Forte continue; 874*fcf3ce44SJohn Forte } 875*fcf3ce44SJohn Forte 876*fcf3ce44SJohn Forte (void) strcpy(cur_svn->svn_path, rdev); 877*fcf3ce44SJohn Forte cur_svn->svn_mode = (NSC_DEVICE | NSC_CACHE); 878*fcf3ce44SJohn Forte 879*fcf3ce44SJohn Forte index++; 880*fcf3ce44SJohn Forte } 881*fcf3ce44SJohn Forte 882*fcf3ce44SJohn Forte /* Set the last path to NULL */ 883*fcf3ce44SJohn Forte svn[index].svn_path[0] = '\0'; 884*fcf3ce44SJohn Forte 885*fcf3ce44SJohn Forte (void) fclose(fp); 886*fcf3ce44SJohn Forte 887*fcf3ce44SJohn Forte return (index); 888*fcf3ce44SJohn Forte } 889*fcf3ce44SJohn Forte 890*fcf3ce44SJohn Forte 891*fcf3ce44SJohn Forte /* 892*fcf3ce44SJohn Forte * Disable the device from the kernel configuration. 893*fcf3ce44SJohn Forte * 894*fcf3ce44SJohn Forte * RETURN: 895*fcf3ce44SJohn Forte * 0 on success 896*fcf3ce44SJohn Forte * non-zero on failure. 897*fcf3ce44SJohn Forte * 898*fcf3ce44SJohn Forte * Failures are reported to the user. 899*fcf3ce44SJohn Forte */ 900*fcf3ce44SJohn Forte static int 901*fcf3ce44SJohn Forte disable_dev(const caddr_t path) 902*fcf3ce44SJohn Forte { 903*fcf3ce44SJohn Forte struct stat stb; 904*fcf3ce44SJohn Forte sv_conf_t svc; 905*fcf3ce44SJohn Forte int fd; 906*fcf3ce44SJohn Forte 907*fcf3ce44SJohn Forte sv_check_cluster(path); 908*fcf3ce44SJohn Forte 909*fcf3ce44SJohn Forte if (stat(path, &stb) < 0) { 910*fcf3ce44SJohn Forte svc.svc_major = (major_t)-1; 911*fcf3ce44SJohn Forte svc.svc_minor = (minor_t)-1; 912*fcf3ce44SJohn Forte } else { 913*fcf3ce44SJohn Forte svc.svc_major = major(stb.st_rdev); 914*fcf3ce44SJohn Forte svc.svc_minor = minor(stb.st_rdev); 915*fcf3ce44SJohn Forte } 916*fcf3ce44SJohn Forte 917*fcf3ce44SJohn Forte if ((fd = open(sv_rpath, O_RDONLY)) < 0) { 918*fcf3ce44SJohn Forte warn(NULL, gettext("unable to open %s: %s"), 919*fcf3ce44SJohn Forte sv_rpath, strerror(errno)); 920*fcf3ce44SJohn Forte return (-1); 921*fcf3ce44SJohn Forte } 922*fcf3ce44SJohn Forte 923*fcf3ce44SJohn Forte (void) strcpy(svc.svc_path, path); 924*fcf3ce44SJohn Forte svc.svc_error = spcs_s_ucreate(); 925*fcf3ce44SJohn Forte 926*fcf3ce44SJohn Forte /* 927*fcf3ce44SJohn Forte * Issue the ioctl to attempt to disable this device. Note that all 928*fcf3ce44SJohn Forte * the libdscfg details are handled elsewhere. 929*fcf3ce44SJohn Forte */ 930*fcf3ce44SJohn Forte if (ioctl(fd, SVIOC_DISABLE, &svc) < 0) { 931*fcf3ce44SJohn Forte if (errno != SV_EDISABLED) { 932*fcf3ce44SJohn Forte spcs_log("sv", &svc.svc_error, 933*fcf3ce44SJohn Forte gettext("%s: unable to disable %s"), 934*fcf3ce44SJohn Forte program, path); 935*fcf3ce44SJohn Forte 936*fcf3ce44SJohn Forte warn(&svc.svc_error, 937*fcf3ce44SJohn Forte gettext("unable to disable %s"), path); 938*fcf3ce44SJohn Forte (void) close(fd); 939*fcf3ce44SJohn Forte return (-1); 940*fcf3ce44SJohn Forte } 941*fcf3ce44SJohn Forte } 942*fcf3ce44SJohn Forte 943*fcf3ce44SJohn Forte spcs_log("sv", NULL, gettext("%s: disabled %s"), program, path); 944*fcf3ce44SJohn Forte 945*fcf3ce44SJohn Forte spcs_s_ufree(&svc.svc_error); 946*fcf3ce44SJohn Forte (void) close(fd); 947*fcf3ce44SJohn Forte 948*fcf3ce44SJohn Forte return (0); 949*fcf3ce44SJohn Forte } 950*fcf3ce44SJohn Forte 951*fcf3ce44SJohn Forte 952*fcf3ce44SJohn Forte static void 953*fcf3ce44SJohn Forte print_cluster_tag(const int setnumber) 954*fcf3ce44SJohn Forte { 955*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 956*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 957*fcf3ce44SJohn Forte 958*fcf3ce44SJohn Forte bzero(buf, sizeof (buf)); 959*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sv.set%d.cnode", setnumber); 960*fcf3ce44SJohn Forte 961*fcf3ce44SJohn Forte (void) cfg_get_cstring(cfg, key, buf, sizeof (buf)); 962*fcf3ce44SJohn Forte 963*fcf3ce44SJohn Forte if (*buf != '\0') { 964*fcf3ce44SJohn Forte if (strcmp(buf, "-") == 0) { 965*fcf3ce44SJohn Forte (void) printf(" [%s]", gettext("local to node")); 966*fcf3ce44SJohn Forte } else { 967*fcf3ce44SJohn Forte (void) printf(" [%s: %s]", gettext("cluster"), buf); 968*fcf3ce44SJohn Forte } 969*fcf3ce44SJohn Forte } 970*fcf3ce44SJohn Forte } 971*fcf3ce44SJohn Forte 972*fcf3ce44SJohn Forte 973*fcf3ce44SJohn Forte /* LINT - not static as fwcadm uses it */ 974*fcf3ce44SJohn Forte static void 975*fcf3ce44SJohn Forte print_sv(int verbose) 976*fcf3ce44SJohn Forte { 977*fcf3ce44SJohn Forte sv_name_t *svn, *svn_system; /* Devices in system */ 978*fcf3ce44SJohn Forte sv_list_t svl_system; 979*fcf3ce44SJohn Forte int fd, i; 980*fcf3ce44SJohn Forte int setnumber; 981*fcf3ce44SJohn Forte 982*fcf3ce44SJohn Forte sv_check_cluster(NULL); 983*fcf3ce44SJohn Forte sv_cfg_open(CFG_RDLOCK); 984*fcf3ce44SJohn Forte 985*fcf3ce44SJohn Forte svn_system = sv_alloc_svnames(); 986*fcf3ce44SJohn Forte 987*fcf3ce44SJohn Forte if ((fd = open(sv_rpath, O_RDONLY)) < 0) { 988*fcf3ce44SJohn Forte (void) printf(gettext("unable to open %s: %s"), 989*fcf3ce44SJohn Forte sv_rpath, strerror(errno)); 990*fcf3ce44SJohn Forte return; 991*fcf3ce44SJohn Forte } 992*fcf3ce44SJohn Forte 993*fcf3ce44SJohn Forte /* Grab the system list from the driver */ 994*fcf3ce44SJohn Forte svl_system.svl_count = sv_max_devices; 995*fcf3ce44SJohn Forte svl_system.svl_names = &svn_system[0]; 996*fcf3ce44SJohn Forte svl_system.svl_error = spcs_s_ucreate(); 997*fcf3ce44SJohn Forte 998*fcf3ce44SJohn Forte if (ioctl(fd, SVIOC_LIST, &svl_system) < 0) { 999*fcf3ce44SJohn Forte error(&svl_system.svl_error, gettext("unable to get list")); 1000*fcf3ce44SJohn Forte } 1001*fcf3ce44SJohn Forte 1002*fcf3ce44SJohn Forte spcs_s_ufree(&svl_system.svl_error); 1003*fcf3ce44SJohn Forte (void) close(fd); 1004*fcf3ce44SJohn Forte 1005*fcf3ce44SJohn Forte /* 1006*fcf3ce44SJohn Forte * We build a hashmap out of the entries from the config file to make 1007*fcf3ce44SJohn Forte * searching faster. We end up taking a performance hit when the # of 1008*fcf3ce44SJohn Forte * volumes is small, but for larger configurations it's a 1009*fcf3ce44SJohn Forte * HUGE improvement. 1010*fcf3ce44SJohn Forte */ 1011*fcf3ce44SJohn Forte 1012*fcf3ce44SJohn Forte /* build the hashtable */ 1013*fcf3ce44SJohn Forte cfg_rewind(cfg, CFG_SEC_CONF); 1014*fcf3ce44SJohn Forte create_cfg_hash(); 1015*fcf3ce44SJohn Forte 1016*fcf3ce44SJohn Forte /* 1017*fcf3ce44SJohn Forte * For each volume found from the kernel, print out 1018*fcf3ce44SJohn Forte * info about it from the kernel. 1019*fcf3ce44SJohn Forte */ 1020*fcf3ce44SJohn Forte for (i = 0; i < svl_system.svl_count; i++) { 1021*fcf3ce44SJohn Forte if (*svn_system[i].svn_path == '\0') { 1022*fcf3ce44SJohn Forte break; 1023*fcf3ce44SJohn Forte } 1024*fcf3ce44SJohn Forte 1025*fcf3ce44SJohn Forte svn = &svn_system[i]; 1026*fcf3ce44SJohn Forte if (svn->svn_mode == 0) { 1027*fcf3ce44SJohn Forte #ifdef DEBUG 1028*fcf3ce44SJohn Forte (void) printf(gettext("%s [kernel guard]\n"), 1029*fcf3ce44SJohn Forte svn->svn_path); 1030*fcf3ce44SJohn Forte #endif 1031*fcf3ce44SJohn Forte continue; 1032*fcf3ce44SJohn Forte } 1033*fcf3ce44SJohn Forte /* get sv entry from the hashtable */ 1034*fcf3ce44SJohn Forte if ((setnumber = find_in_hash(svn->svn_path)) != -1) { 1035*fcf3ce44SJohn Forte (void) printf("%-*s", STATWIDTH, svn->svn_path); 1036*fcf3ce44SJohn Forte 1037*fcf3ce44SJohn Forte if (verbose) { 1038*fcf3ce44SJohn Forte print_cluster_tag(setnumber); 1039*fcf3ce44SJohn Forte } 1040*fcf3ce44SJohn Forte 1041*fcf3ce44SJohn Forte (void) printf("\n"); 1042*fcf3ce44SJohn Forte 1043*fcf3ce44SJohn Forte } else { 1044*fcf3ce44SJohn Forte /* 1045*fcf3ce44SJohn Forte * We didn't find the entry in the hashtable. Let 1046*fcf3ce44SJohn Forte * the user know that the persistent storage is 1047*fcf3ce44SJohn Forte * inconsistent with the kernel configuration. 1048*fcf3ce44SJohn Forte */ 1049*fcf3ce44SJohn Forte if (cfg_cluster_tag == NULL) 1050*fcf3ce44SJohn Forte warn(NULL, gettext( 1051*fcf3ce44SJohn Forte "%s is configured, but not in the " 1052*fcf3ce44SJohn Forte "config storage"), svn->svn_path); 1053*fcf3ce44SJohn Forte } 1054*fcf3ce44SJohn Forte } 1055*fcf3ce44SJohn Forte 1056*fcf3ce44SJohn Forte /* free up the hashtable */ 1057*fcf3ce44SJohn Forte destroy_hashtable(); 1058*fcf3ce44SJohn Forte 1059*fcf3ce44SJohn Forte sv_cfg_close(); 1060*fcf3ce44SJohn Forte } 1061*fcf3ce44SJohn Forte 1062*fcf3ce44SJohn Forte 1063*fcf3ce44SJohn Forte /* LINT - not static as fwcadm uses it */ 1064*fcf3ce44SJohn Forte static int 1065*fcf3ce44SJohn Forte disable_sv(char *conf_file) 1066*fcf3ce44SJohn Forte { 1067*fcf3ce44SJohn Forte sv_name_t *svn, *svn_system; /* Devices in system */ 1068*fcf3ce44SJohn Forte sv_list_t svl_system; 1069*fcf3ce44SJohn Forte int fd, i, setnumber; 1070*fcf3ce44SJohn Forte int rc, ret; 1071*fcf3ce44SJohn Forte 1072*fcf3ce44SJohn Forte svn_system = sv_alloc_svnames(); 1073*fcf3ce44SJohn Forte 1074*fcf3ce44SJohn Forte rc = ret = 0; 1075*fcf3ce44SJohn Forte 1076*fcf3ce44SJohn Forte if (conf_file == NULL) { 1077*fcf3ce44SJohn Forte if ((fd = open(sv_rpath, O_RDONLY)) < 0) { 1078*fcf3ce44SJohn Forte (void) printf(gettext("unable to open %s: %s"), 1079*fcf3ce44SJohn Forte sv_rpath, strerror(errno)); 1080*fcf3ce44SJohn Forte return (1); 1081*fcf3ce44SJohn Forte } 1082*fcf3ce44SJohn Forte 1083*fcf3ce44SJohn Forte /* Grab the system list from the driver */ 1084*fcf3ce44SJohn Forte svl_system.svl_count = sv_max_devices; 1085*fcf3ce44SJohn Forte svl_system.svl_names = &svn_system[0]; 1086*fcf3ce44SJohn Forte svl_system.svl_error = spcs_s_ucreate(); 1087*fcf3ce44SJohn Forte 1088*fcf3ce44SJohn Forte if (ioctl(fd, SVIOC_LIST, &svl_system) < 0) { 1089*fcf3ce44SJohn Forte error(&(svl_system.svl_error), 1090*fcf3ce44SJohn Forte gettext("unable to get list")); 1091*fcf3ce44SJohn Forte } 1092*fcf3ce44SJohn Forte 1093*fcf3ce44SJohn Forte spcs_s_ufree(&(svl_system.svl_error)); 1094*fcf3ce44SJohn Forte (void) close(fd); 1095*fcf3ce44SJohn Forte } else { 1096*fcf3ce44SJohn Forte svl_system.svl_count = read_config_file(conf_file, svn_system); 1097*fcf3ce44SJohn Forte } 1098*fcf3ce44SJohn Forte 1099*fcf3ce44SJohn Forte 1100*fcf3ce44SJohn Forte for (i = 0; i < svl_system.svl_count; i++) { 1101*fcf3ce44SJohn Forte if (*svn_system[i].svn_path == '\0') 1102*fcf3ce44SJohn Forte break; 1103*fcf3ce44SJohn Forte 1104*fcf3ce44SJohn Forte svn = &svn_system[i]; 1105*fcf3ce44SJohn Forte 1106*fcf3ce44SJohn Forte sv_check_cluster(svn->svn_path); 1107*fcf3ce44SJohn Forte sv_cfg_open(CFG_WRLOCK); 1108*fcf3ce44SJohn Forte create_cfg_hash(); 1109*fcf3ce44SJohn Forte rc = 0; 1110*fcf3ce44SJohn Forte if ((setnumber = find_in_hash(svn->svn_path)) != -1) { 1111*fcf3ce44SJohn Forte if ((rc = disable_dev(svn->svn_path)) != -1) { 1112*fcf3ce44SJohn Forte remove_from_cfgfile(svn->svn_path, setnumber); 1113*fcf3ce44SJohn Forte } else if (errno == SV_ENODEV) { 1114*fcf3ce44SJohn Forte remove_from_cfgfile(svn->svn_path, setnumber); 1115*fcf3ce44SJohn Forte } 1116*fcf3ce44SJohn Forte } else { 1117*fcf3ce44SJohn Forte /* warn the user that we didn't find it in cfg file */ 1118*fcf3ce44SJohn Forte warn(NULL, gettext( 1119*fcf3ce44SJohn Forte "%s was not found in the config storage"), 1120*fcf3ce44SJohn Forte svn->svn_path); 1121*fcf3ce44SJohn Forte /* try to disable anyway */ 1122*fcf3ce44SJohn Forte (void) disable_dev(svn->svn_path); 1123*fcf3ce44SJohn Forte rc = 1; 1124*fcf3ce44SJohn Forte } 1125*fcf3ce44SJohn Forte 1126*fcf3ce44SJohn Forte sv_cfg_close(); 1127*fcf3ce44SJohn Forte destroy_hashtable(); 1128*fcf3ce44SJohn Forte 1129*fcf3ce44SJohn Forte if (rc && !ret) 1130*fcf3ce44SJohn Forte ret = rc; 1131*fcf3ce44SJohn Forte } 1132*fcf3ce44SJohn Forte 1133*fcf3ce44SJohn Forte return (ret); 1134*fcf3ce44SJohn Forte } 1135*fcf3ce44SJohn Forte 1136*fcf3ce44SJohn Forte 1137*fcf3ce44SJohn Forte /* LINT - not static as fwcadm uses it */ 1138*fcf3ce44SJohn Forte static int 1139*fcf3ce44SJohn Forte disable_one_sv(char *path) 1140*fcf3ce44SJohn Forte { 1141*fcf3ce44SJohn Forte int setnumber; 1142*fcf3ce44SJohn Forte int rc; 1143*fcf3ce44SJohn Forte 1144*fcf3ce44SJohn Forte sv_get_maxdevs(); 1145*fcf3ce44SJohn Forte sv_check_cluster(path); 1146*fcf3ce44SJohn Forte sv_cfg_open(CFG_WRLOCK); 1147*fcf3ce44SJohn Forte 1148*fcf3ce44SJohn Forte create_cfg_hash(); 1149*fcf3ce44SJohn Forte if ((setnumber = find_in_hash(path)) != -1) { 1150*fcf3ce44SJohn Forte /* remove from kernel */ 1151*fcf3ce44SJohn Forte if ((rc = disable_dev(path)) == 0) { 1152*fcf3ce44SJohn Forte /* remove the cfgline */ 1153*fcf3ce44SJohn Forte remove_from_cfgfile(path, setnumber); 1154*fcf3ce44SJohn Forte } else if (errno == SV_ENODEV) { 1155*fcf3ce44SJohn Forte remove_from_cfgfile(path, setnumber); 1156*fcf3ce44SJohn Forte } 1157*fcf3ce44SJohn Forte } else { 1158*fcf3ce44SJohn Forte /* warn the user that we didn't find it in cfg file */ 1159*fcf3ce44SJohn Forte warn(NULL, 1160*fcf3ce44SJohn Forte gettext("%s was not found in the config storage"), path); 1161*fcf3ce44SJohn Forte /* still attempt to remove */ 1162*fcf3ce44SJohn Forte (void) disable_dev(path); 1163*fcf3ce44SJohn Forte rc = 1; 1164*fcf3ce44SJohn Forte } 1165*fcf3ce44SJohn Forte destroy_hashtable(); 1166*fcf3ce44SJohn Forte 1167*fcf3ce44SJohn Forte sv_cfg_close(); 1168*fcf3ce44SJohn Forte return (rc); 1169*fcf3ce44SJohn Forte } 1170*fcf3ce44SJohn Forte 1171*fcf3ce44SJohn Forte 1172*fcf3ce44SJohn Forte static void 1173*fcf3ce44SJohn Forte compare_tag(char *path) 1174*fcf3ce44SJohn Forte { 1175*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF], vol[CFG_MAX_BUF], cnode[CFG_MAX_BUF]; 1176*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 1177*fcf3ce44SJohn Forte int found, setnumber, i; 1178*fcf3ce44SJohn Forte char *tag; 1179*fcf3ce44SJohn Forte 1180*fcf3ce44SJohn Forte sv_check_cluster(path); 1181*fcf3ce44SJohn Forte cfg_resource(cfg, (char *)NULL); /* reset */ 1182*fcf3ce44SJohn Forte cfg_rewind(cfg, CFG_SEC_CONF); 1183*fcf3ce44SJohn Forte 1184*fcf3ce44SJohn Forte #ifdef DEBUG 1185*fcf3ce44SJohn Forte if (cfg_cluster_tag != NULL && implicit_tag != NULL) { 1186*fcf3ce44SJohn Forte error(NULL, gettext("compare_tag: -C %s AND implicit_tag %s!"), 1187*fcf3ce44SJohn Forte cfg_cluster_tag, implicit_tag); 1188*fcf3ce44SJohn Forte } 1189*fcf3ce44SJohn Forte #endif 1190*fcf3ce44SJohn Forte 1191*fcf3ce44SJohn Forte if (cfg_cluster_tag != NULL) 1192*fcf3ce44SJohn Forte tag = cfg_cluster_tag; 1193*fcf3ce44SJohn Forte else if (implicit_tag != NULL) 1194*fcf3ce44SJohn Forte tag = implicit_tag; 1195*fcf3ce44SJohn Forte else 1196*fcf3ce44SJohn Forte tag = "-"; 1197*fcf3ce44SJohn Forte 1198*fcf3ce44SJohn Forte found = 0; 1199*fcf3ce44SJohn Forte for (i = 0; i < sv_max_devices; i++) { 1200*fcf3ce44SJohn Forte setnumber = i + 1; 1201*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sv.set%d", setnumber); 1202*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) { 1203*fcf3ce44SJohn Forte break; 1204*fcf3ce44SJohn Forte } 1205*fcf3ce44SJohn Forte 1206*fcf3ce44SJohn Forte if (sscanf(buf, "%s - %s", vol, cnode) != 2) { 1207*fcf3ce44SJohn Forte continue; 1208*fcf3ce44SJohn Forte } 1209*fcf3ce44SJohn Forte 1210*fcf3ce44SJohn Forte if (strcmp(path, vol) == 0) { 1211*fcf3ce44SJohn Forte found = 1; 1212*fcf3ce44SJohn Forte break; 1213*fcf3ce44SJohn Forte } 1214*fcf3ce44SJohn Forte } 1215*fcf3ce44SJohn Forte 1216*fcf3ce44SJohn Forte if (!found) { 1217*fcf3ce44SJohn Forte warn(NULL, gettext("unable to find %s in the configuration"), 1218*fcf3ce44SJohn Forte path); 1219*fcf3ce44SJohn Forte return; 1220*fcf3ce44SJohn Forte } 1221*fcf3ce44SJohn Forte 1222*fcf3ce44SJohn Forte /* have name match, compare cnode to new tag */ 1223*fcf3ce44SJohn Forte 1224*fcf3ce44SJohn Forte if (strcmp(tag, cnode) == 0) { 1225*fcf3ce44SJohn Forte /* cluster tags match */ 1226*fcf3ce44SJohn Forte return; 1227*fcf3ce44SJohn Forte } 1228*fcf3ce44SJohn Forte 1229*fcf3ce44SJohn Forte /* need to change the cluster tag */ 1230*fcf3ce44SJohn Forte 1231*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sv.set%d.cnode", setnumber); 1232*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, tag, strlen(tag)) < 0) { 1233*fcf3ce44SJohn Forte warn(NULL, 1234*fcf3ce44SJohn Forte gettext("unable to change cluster tag for %s"), path); 1235*fcf3ce44SJohn Forte return; 1236*fcf3ce44SJohn Forte } 1237*fcf3ce44SJohn Forte 1238*fcf3ce44SJohn Forte cfg_changed = 1; 1239*fcf3ce44SJohn Forte 1240*fcf3ce44SJohn Forte /* change "-" tags to "" for display purposes */ 1241*fcf3ce44SJohn Forte 1242*fcf3ce44SJohn Forte if (strcmp(tag, "-") == 0) 1243*fcf3ce44SJohn Forte tag = ""; 1244*fcf3ce44SJohn Forte 1245*fcf3ce44SJohn Forte if (strcmp(cnode, "-") == 0) 1246*fcf3ce44SJohn Forte (void) strcpy(cnode, ""); 1247*fcf3ce44SJohn Forte 1248*fcf3ce44SJohn Forte (void) printf( 1249*fcf3ce44SJohn Forte gettext("%s: changed cluster tag for %s from \"%s\" to \"%s\"\n"), 1250*fcf3ce44SJohn Forte program, path, cnode, tag); 1251*fcf3ce44SJohn Forte 1252*fcf3ce44SJohn Forte spcs_log("sv", NULL, 1253*fcf3ce44SJohn Forte gettext("%s: changed cluster tag for %s from \"%s\" to \"%s\""), 1254*fcf3ce44SJohn Forte program, path, cnode, tag); 1255*fcf3ce44SJohn Forte } 1256*fcf3ce44SJohn Forte 1257*fcf3ce44SJohn Forte 1258*fcf3ce44SJohn Forte /* LINT - not static as fwcadm uses it */ 1259*fcf3ce44SJohn Forte static void 1260*fcf3ce44SJohn Forte compare_sv(char *conf_file) 1261*fcf3ce44SJohn Forte { 1262*fcf3ce44SJohn Forte sv_name_t *svn_config; /* Devices in config file */ 1263*fcf3ce44SJohn Forte sv_name_t *svn_system; /* Devices in system */ 1264*fcf3ce44SJohn Forte sv_name_t *enable; /* Devices that need enabled */ 1265*fcf3ce44SJohn Forte sv_list_t svl_system; 1266*fcf3ce44SJohn Forte int config_cnt; 1267*fcf3ce44SJohn Forte int sys_cnt = 0; 1268*fcf3ce44SJohn Forte int setnumber, i, j; 1269*fcf3ce44SJohn Forte int index = 0; /* Index in enable[] */ 1270*fcf3ce44SJohn Forte int found; 1271*fcf3ce44SJohn Forte int fd0; 1272*fcf3ce44SJohn Forte 1273*fcf3ce44SJohn Forte svn_config = sv_alloc_svnames(); 1274*fcf3ce44SJohn Forte svn_system = sv_alloc_svnames(); 1275*fcf3ce44SJohn Forte enable = sv_alloc_svnames(); 1276*fcf3ce44SJohn Forte 1277*fcf3ce44SJohn Forte bzero(svn_system, sizeof (svn_system)); 1278*fcf3ce44SJohn Forte bzero(&svl_system, sizeof (svl_system)); 1279*fcf3ce44SJohn Forte bzero(enable, sizeof (enable)); 1280*fcf3ce44SJohn Forte 1281*fcf3ce44SJohn Forte /* 1282*fcf3ce44SJohn Forte * Read the configuration file 1283*fcf3ce44SJohn Forte * The return value is the number of entries 1284*fcf3ce44SJohn Forte */ 1285*fcf3ce44SJohn Forte config_cnt = read_config_file(conf_file, svn_config); 1286*fcf3ce44SJohn Forte 1287*fcf3ce44SJohn Forte if ((fd0 = open(sv_rpath, O_RDONLY)) < 0) 1288*fcf3ce44SJohn Forte error(NULL, gettext("unable to open %s: %s"), 1289*fcf3ce44SJohn Forte sv_rpath, strerror(errno)); 1290*fcf3ce44SJohn Forte 1291*fcf3ce44SJohn Forte /* Grab the system list from the driver */ 1292*fcf3ce44SJohn Forte svl_system.svl_count = sv_max_devices; 1293*fcf3ce44SJohn Forte svl_system.svl_names = &svn_system[0]; 1294*fcf3ce44SJohn Forte svl_system.svl_error = spcs_s_ucreate(); 1295*fcf3ce44SJohn Forte 1296*fcf3ce44SJohn Forte if (ioctl(fd0, SVIOC_LIST, &svl_system) < 0) { 1297*fcf3ce44SJohn Forte error(&svl_system.svl_error, gettext("unable to get list")); 1298*fcf3ce44SJohn Forte } 1299*fcf3ce44SJohn Forte 1300*fcf3ce44SJohn Forte spcs_s_ufree(&svl_system.svl_error); 1301*fcf3ce44SJohn Forte (void) close(fd0); 1302*fcf3ce44SJohn Forte 1303*fcf3ce44SJohn Forte /* 1304*fcf3ce44SJohn Forte * Count the number of devices in the system. 1305*fcf3ce44SJohn Forte * The last entry in the array has '\0' for a path name. 1306*fcf3ce44SJohn Forte */ 1307*fcf3ce44SJohn Forte for (j = 0; j < sv_max_devices; j++) { 1308*fcf3ce44SJohn Forte if (svn_system[j].svn_path[0] != '\0') { 1309*fcf3ce44SJohn Forte sys_cnt++; 1310*fcf3ce44SJohn Forte } else { 1311*fcf3ce44SJohn Forte break; 1312*fcf3ce44SJohn Forte } 1313*fcf3ce44SJohn Forte } 1314*fcf3ce44SJohn Forte /* 1315*fcf3ce44SJohn Forte * Compare the configuration array with the system array. 1316*fcf3ce44SJohn Forte * Mark any differences and disable conflicting devices. 1317*fcf3ce44SJohn Forte */ 1318*fcf3ce44SJohn Forte for (i = 0; i < config_cnt; i++) { 1319*fcf3ce44SJohn Forte found = 0; 1320*fcf3ce44SJohn Forte for (j = 0; j < sys_cnt; j++) { 1321*fcf3ce44SJohn Forte if (svn_system[j].svn_path[0] == '\0' || 1322*fcf3ce44SJohn Forte svn_system[j].svn_mode == 0) 1323*fcf3ce44SJohn Forte continue; 1324*fcf3ce44SJohn Forte 1325*fcf3ce44SJohn Forte /* Check to see if path matches */ 1326*fcf3ce44SJohn Forte if (strcmp(svn_system[j].svn_path, 1327*fcf3ce44SJohn Forte svn_config[i].svn_path) == 0) { 1328*fcf3ce44SJohn Forte /* Found a match */ 1329*fcf3ce44SJohn Forte svn_system[j].svn_path[0] = '\0'; 1330*fcf3ce44SJohn Forte found++; 1331*fcf3ce44SJohn Forte break; 1332*fcf3ce44SJohn Forte } 1333*fcf3ce44SJohn Forte } 1334*fcf3ce44SJohn Forte 1335*fcf3ce44SJohn Forte if (!found) { 1336*fcf3ce44SJohn Forte /* Minor number not in system = > enable device */ 1337*fcf3ce44SJohn Forte enable[index].svn_mode = svn_config[i].svn_mode; 1338*fcf3ce44SJohn Forte (void) strcpy(enable[index].svn_path, 1339*fcf3ce44SJohn Forte svn_config[i].svn_path); 1340*fcf3ce44SJohn Forte index++; 1341*fcf3ce44SJohn Forte } 1342*fcf3ce44SJohn Forte } 1343*fcf3ce44SJohn Forte 1344*fcf3ce44SJohn Forte /* Disable any devices that weren't in the config file */ 1345*fcf3ce44SJohn Forte for (j = 0; j < sys_cnt; j++) { 1346*fcf3ce44SJohn Forte sv_check_cluster(NULL); 1347*fcf3ce44SJohn Forte sv_cfg_open(CFG_WRLOCK); 1348*fcf3ce44SJohn Forte create_cfg_hash(); 1349*fcf3ce44SJohn Forte if (svn_system[j].svn_path[0] != '\0' && 1350*fcf3ce44SJohn Forte svn_system[j].svn_mode != 0) { 1351*fcf3ce44SJohn Forte (void) printf(gettext("%s: disabling sv: %s\n"), 1352*fcf3ce44SJohn Forte program, svn_system[j].svn_path); 1353*fcf3ce44SJohn Forte if (disable_dev(svn_system[j].svn_path) == 0) { 1354*fcf3ce44SJohn Forte setnumber = 1355*fcf3ce44SJohn Forte find_in_hash(svn_system[j].svn_path); 1356*fcf3ce44SJohn Forte if (setnumber != -1) { 1357*fcf3ce44SJohn Forte /* the volume was found in cfg store */ 1358*fcf3ce44SJohn Forte remove_from_cfgfile( 1359*fcf3ce44SJohn Forte svn_system[j].svn_path, setnumber); 1360*fcf3ce44SJohn Forte } 1361*fcf3ce44SJohn Forte } 1362*fcf3ce44SJohn Forte } 1363*fcf3ce44SJohn Forte sv_cfg_close(); 1364*fcf3ce44SJohn Forte destroy_hashtable(); 1365*fcf3ce44SJohn Forte } 1366*fcf3ce44SJohn Forte 1367*fcf3ce44SJohn Forte while (index) { 1368*fcf3ce44SJohn Forte /* 1369*fcf3ce44SJohn Forte * Config file doesn't match system => enable the devices 1370*fcf3ce44SJohn Forte * in enable[] 1371*fcf3ce44SJohn Forte */ 1372*fcf3ce44SJohn Forte index--; 1373*fcf3ce44SJohn Forte (void) printf(gettext("%s: enabling new sv: %s\n"), 1374*fcf3ce44SJohn Forte program, enable[index].svn_path); 1375*fcf3ce44SJohn Forte (void) enable_dev(&enable[index]); 1376*fcf3ce44SJohn Forte } 1377*fcf3ce44SJohn Forte 1378*fcf3ce44SJohn Forte /* 1379*fcf3ce44SJohn Forte * Search for entries where the cluster tag has changed. 1380*fcf3ce44SJohn Forte */ 1381*fcf3ce44SJohn Forte sv_check_cluster(NULL); 1382*fcf3ce44SJohn Forte sv_cfg_open(CFG_WRLOCK); 1383*fcf3ce44SJohn Forte 1384*fcf3ce44SJohn Forte for (i = 0; i < sv_max_devices; i++) { 1385*fcf3ce44SJohn Forte if (svn_config[i].svn_path[0] == '\0') 1386*fcf3ce44SJohn Forte break; 1387*fcf3ce44SJohn Forte 1388*fcf3ce44SJohn Forte compare_tag(svn_config[i].svn_path); 1389*fcf3ce44SJohn Forte } 1390*fcf3ce44SJohn Forte 1391*fcf3ce44SJohn Forte sv_cfg_close(); 1392*fcf3ce44SJohn Forte } 1393*fcf3ce44SJohn Forte 1394*fcf3ce44SJohn Forte 1395*fcf3ce44SJohn Forte /* 1396*fcf3ce44SJohn Forte * We assume that the volume is already enabled and we can only 1397*fcf3ce44SJohn Forte * be changing the cluster tag. Anything else is an error. 1398*fcf3ce44SJohn Forte */ 1399*fcf3ce44SJohn Forte /* LINT - not static as fwcadm uses it */ 1400*fcf3ce44SJohn Forte static void 1401*fcf3ce44SJohn Forte compare_one_sv(char *path) 1402*fcf3ce44SJohn Forte { 1403*fcf3ce44SJohn Forte sv_get_maxdevs(); 1404*fcf3ce44SJohn Forte sv_check_cluster(NULL); 1405*fcf3ce44SJohn Forte sv_cfg_open(CFG_WRLOCK); 1406*fcf3ce44SJohn Forte 1407*fcf3ce44SJohn Forte compare_tag(path); 1408*fcf3ce44SJohn Forte 1409*fcf3ce44SJohn Forte sv_cfg_close(); 1410*fcf3ce44SJohn Forte } 1411*fcf3ce44SJohn Forte 1412*fcf3ce44SJohn Forte /* 1413*fcf3ce44SJohn Forte * Read all sets from the libdscfg configuration file, and store everything in 1414*fcf3ce44SJohn Forte * the hashfile. 1415*fcf3ce44SJohn Forte * 1416*fcf3ce44SJohn Forte * We assume that the config file has been opened & rewound for us. We store 1417*fcf3ce44SJohn Forte * the volume name as the key, and the setnumber where we found it as the data. 1418*fcf3ce44SJohn Forte * 1419*fcf3ce44SJohn Forte * The caller can pass in a pointer to the maximum number of volumes, or 1420*fcf3ce44SJohn Forte * a pointer to NULL, specifying we want 'all' the volumes. The table is 1421*fcf3ce44SJohn Forte * searched using find_in_hash. 1422*fcf3ce44SJohn Forte */ 1423*fcf3ce44SJohn Forte static void 1424*fcf3ce44SJohn Forte create_cfg_hash() 1425*fcf3ce44SJohn Forte { 1426*fcf3ce44SJohn Forte char key[CFG_MAX_KEY], buf[CFG_MAX_BUF]; 1427*fcf3ce44SJohn Forte char vol[CFG_MAX_BUF], cnode[CFG_MAX_BUF]; 1428*fcf3ce44SJohn Forte int setnumber; 1429*fcf3ce44SJohn Forte ENTRY item; 1430*fcf3ce44SJohn Forte 1431*fcf3ce44SJohn Forte if (hcreate((size_t)sv_max_devices) == 0) 1432*fcf3ce44SJohn Forte error(NULL, gettext("unable to create hash table")); 1433*fcf3ce44SJohn Forte 1434*fcf3ce44SJohn Forte for (setnumber = 1; /* CSTYLED */; setnumber++) { 1435*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sv.set%d", setnumber); 1436*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) 1437*fcf3ce44SJohn Forte break; 1438*fcf3ce44SJohn Forte 1439*fcf3ce44SJohn Forte if (sscanf(buf, "%s - %s", vol, cnode) != 2) { 1440*fcf3ce44SJohn Forte continue; 1441*fcf3ce44SJohn Forte } 1442*fcf3ce44SJohn Forte 1443*fcf3ce44SJohn Forte item.key = strdup(vol); 1444*fcf3ce44SJohn Forte item.data = (void *)setnumber; 1445*fcf3ce44SJohn Forte if (hsearch(item, ENTER) == NULL) { 1446*fcf3ce44SJohn Forte error(NULL, 1447*fcf3ce44SJohn Forte gettext("unable to add entry to hash table")); 1448*fcf3ce44SJohn Forte } 1449*fcf3ce44SJohn Forte } 1450*fcf3ce44SJohn Forte } 1451*fcf3ce44SJohn Forte 1452*fcf3ce44SJohn Forte /* 1453*fcf3ce44SJohn Forte * Function to search the hash for a specific volume. If it is found, 1454*fcf3ce44SJohn Forte * we return the set number. If it isn't found, we return -1 1455*fcf3ce44SJohn Forte */ 1456*fcf3ce44SJohn Forte static int 1457*fcf3ce44SJohn Forte find_in_hash(char *path) 1458*fcf3ce44SJohn Forte { 1459*fcf3ce44SJohn Forte ENTRY *found_entry, item; 1460*fcf3ce44SJohn Forte int retval = -1; 1461*fcf3ce44SJohn Forte 1462*fcf3ce44SJohn Forte item.key = path; 1463*fcf3ce44SJohn Forte 1464*fcf3ce44SJohn Forte if ((found_entry = hsearch(item, FIND)) != NULL) { 1465*fcf3ce44SJohn Forte retval = (int)found_entry->data; 1466*fcf3ce44SJohn Forte } 1467*fcf3ce44SJohn Forte 1468*fcf3ce44SJohn Forte return (retval); 1469*fcf3ce44SJohn Forte } 1470*fcf3ce44SJohn Forte 1471*fcf3ce44SJohn Forte /* 1472*fcf3ce44SJohn Forte * Just a wrapper to destory the hashtable. At some point in the future we 1473*fcf3ce44SJohn Forte * might want to do something more.... For instance, verify that the cfg 1474*fcf3ce44SJohn Forte * database and the kernel configuration match (?) Just an idea. 1475*fcf3ce44SJohn Forte */ 1476*fcf3ce44SJohn Forte static void 1477*fcf3ce44SJohn Forte destroy_hashtable() 1478*fcf3ce44SJohn Forte { 1479*fcf3ce44SJohn Forte hdestroy(); 1480*fcf3ce44SJohn Forte } 1481*fcf3ce44SJohn Forte 1482*fcf3ce44SJohn Forte /* 1483*fcf3ce44SJohn Forte * This function will remove a particular set from the config file. 1484*fcf3ce44SJohn Forte * 1485*fcf3ce44SJohn Forte * We make a whole host of assumptions: 1486*fcf3ce44SJohn Forte * o the hashfile is up to date; 1487*fcf3ce44SJohn Forte * o The config file has been opened with a WRLOCK for us. 1488*fcf3ce44SJohn Forte */ 1489*fcf3ce44SJohn Forte static void 1490*fcf3ce44SJohn Forte remove_from_cfgfile(char *path, int setnumber) 1491*fcf3ce44SJohn Forte { 1492*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 1493*fcf3ce44SJohn Forte int sev; 1494*fcf3ce44SJohn Forte char *lcltag; 1495*fcf3ce44SJohn Forte 1496*fcf3ce44SJohn Forte /* attempt to remove the volume from config storage */ 1497*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sv.set%d", setnumber); 1498*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, NULL, 0) < 0) { 1499*fcf3ce44SJohn Forte warn(NULL, gettext("unable to remove %s from " 1500*fcf3ce44SJohn Forte "config storage: %s"), path, cfg_error(&sev)); 1501*fcf3ce44SJohn Forte } else { 1502*fcf3ce44SJohn Forte if (implicit_tag && *implicit_tag) { 1503*fcf3ce44SJohn Forte lcltag = implicit_tag; 1504*fcf3ce44SJohn Forte } else if (cfg_cluster_tag && *cfg_cluster_tag) { 1505*fcf3ce44SJohn Forte lcltag = cfg_cluster_tag; 1506*fcf3ce44SJohn Forte } else { 1507*fcf3ce44SJohn Forte lcltag = "-"; 1508*fcf3ce44SJohn Forte } 1509*fcf3ce44SJohn Forte if (cfg_rem_user(cfg, path, lcltag, "sv") != CFG_USER_LAST) { 1510*fcf3ce44SJohn Forte warn(NULL, gettext("unable to remove %s from dsvol"), 1511*fcf3ce44SJohn Forte path); 1512*fcf3ce44SJohn Forte } 1513*fcf3ce44SJohn Forte cfg_changed = 1; 1514*fcf3ce44SJohn Forte } 1515*fcf3ce44SJohn Forte } 1516