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 <fcntl.h> 30*fcf3ce44SJohn Forte #include <unistd.h> 31*fcf3ce44SJohn Forte #include <stropts.h> 32*fcf3ce44SJohn Forte #include <stdio.h> 33*fcf3ce44SJohn Forte #include <errno.h> 34*fcf3ce44SJohn Forte #include <libintl.h> 35*fcf3ce44SJohn Forte #include <locale.h> 36*fcf3ce44SJohn Forte #include <stdlib.h> 37*fcf3ce44SJohn Forte 38*fcf3ce44SJohn Forte #include <sys/nsctl/rdcerr.h> 39*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_ioctl.h> 40*fcf3ce44SJohn Forte #include <sys/nsctl/librdc.h> 41*fcf3ce44SJohn Forte #include <sys/nsctl/cfg.h> 42*fcf3ce44SJohn Forte #include <sys/nsctl/nsc_hash.h> 43*fcf3ce44SJohn Forte #include <sys/nsctl/sv.h> 44*fcf3ce44SJohn Forte 45*fcf3ce44SJohn Forte #include <sys/unistat/spcs_dtrinkets.h> 46*fcf3ce44SJohn Forte #include <sys/unistat/spcs_etrinkets.h> 47*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s.h> 48*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_u.h> 49*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_impl.h> 50*fcf3ce44SJohn Forte #include <sys/unistat/spcs_errors.h> 51*fcf3ce44SJohn Forte 52*fcf3ce44SJohn Forte typedef struct volcount_s { 53*fcf3ce44SJohn Forte int count; 54*fcf3ce44SJohn Forte } volcount_t; 55*fcf3ce44SJohn Forte 56*fcf3ce44SJohn Forte hash_node_t **volhash = NULL; 57*fcf3ce44SJohn Forte 58*fcf3ce44SJohn Forte char * 59*fcf3ce44SJohn Forte config2buf(char *buf, rdcconfig_t *rdc) 60*fcf3ce44SJohn Forte { 61*fcf3ce44SJohn Forte snprintf(buf, CFG_MAX_BUF, "%s %s %s %s %s %s %s %s %s %s %s", 62*fcf3ce44SJohn Forte rdc->phost, rdc->pfile, rdc->pbmp, rdc->shost, rdc->sfile, 63*fcf3ce44SJohn Forte rdc->sbmp, rdc->direct, rdc->mode, rdc->group ? rdc->group : "", 64*fcf3ce44SJohn Forte rdc->ctag ? rdc->ctag : "", rdc->options ? rdc->options : ""); 65*fcf3ce44SJohn Forte return (buf); 66*fcf3ce44SJohn Forte 67*fcf3ce44SJohn Forte } 68*fcf3ce44SJohn Forte 69*fcf3ce44SJohn Forte /* 70*fcf3ce44SJohn Forte * SV type functions. 71*fcf3ce44SJohn Forte */ 72*fcf3ce44SJohn Forte 73*fcf3ce44SJohn Forte static void 74*fcf3ce44SJohn Forte load_rdc_vols(CFGFILE *cfg) 75*fcf3ce44SJohn Forte { 76*fcf3ce44SJohn Forte int set; 77*fcf3ce44SJohn Forte char key[ CFG_MAX_KEY ]; 78*fcf3ce44SJohn Forte char buf[ CFG_MAX_BUF ]; 79*fcf3ce44SJohn Forte char *vol, *bmp, *host1, *host2; 80*fcf3ce44SJohn Forte volcount_t *volcount; 81*fcf3ce44SJohn Forte 82*fcf3ce44SJohn Forte if (volhash) { 83*fcf3ce44SJohn Forte return; 84*fcf3ce44SJohn Forte } 85*fcf3ce44SJohn Forte 86*fcf3ce44SJohn Forte cfg_rewind(cfg, CFG_SEC_CONF); 87*fcf3ce44SJohn Forte volhash = nsc_create_hash(); 88*fcf3ce44SJohn Forte for (set = 1; /*CSTYLED*/; set++) { 89*fcf3ce44SJohn Forte snprintf(key, CFG_MAX_KEY, "sndr.set%d", set); 90*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF)) { 91*fcf3ce44SJohn Forte break; 92*fcf3ce44SJohn Forte } 93*fcf3ce44SJohn Forte 94*fcf3ce44SJohn Forte host1 = strtok(buf, " "); 95*fcf3ce44SJohn Forte vol = strtok(NULL, " "); 96*fcf3ce44SJohn Forte bmp = strtok(NULL, " "); 97*fcf3ce44SJohn Forte 98*fcf3ce44SJohn Forte if (!self_check(host1)) { 99*fcf3ce44SJohn Forte /* next one had better be ours */ 100*fcf3ce44SJohn Forte host2 = strtok(NULL, " "); 101*fcf3ce44SJohn Forte vol = strtok(NULL, " "); 102*fcf3ce44SJohn Forte bmp = strtok(NULL, " "); 103*fcf3ce44SJohn Forte 104*fcf3ce44SJohn Forte if (!self_check(host2)) { 105*fcf3ce44SJohn Forte continue; 106*fcf3ce44SJohn Forte } 107*fcf3ce44SJohn Forte } 108*fcf3ce44SJohn Forte 109*fcf3ce44SJohn Forte /* primary vol may be used more than once */ 110*fcf3ce44SJohn Forte volcount = (volcount_t *)nsc_lookup(volhash, vol); 111*fcf3ce44SJohn Forte if (volcount) { 112*fcf3ce44SJohn Forte volcount->count++; 113*fcf3ce44SJohn Forte } else { 114*fcf3ce44SJohn Forte volcount = (volcount_t *)malloc(sizeof (volcount_t)); 115*fcf3ce44SJohn Forte volcount->count = 1; 116*fcf3ce44SJohn Forte nsc_insert_node(volhash, volcount, vol); 117*fcf3ce44SJohn Forte } 118*fcf3ce44SJohn Forte 119*fcf3ce44SJohn Forte /* bitmap ought to be only used once */ 120*fcf3ce44SJohn Forte volcount = (volcount_t *)nsc_lookup(volhash, bmp); 121*fcf3ce44SJohn Forte if (volcount) { 122*fcf3ce44SJohn Forte /* argh */ 123*fcf3ce44SJohn Forte volcount->count++; 124*fcf3ce44SJohn Forte } else { 125*fcf3ce44SJohn Forte volcount = (volcount_t *)malloc(sizeof (volcount_t)); 126*fcf3ce44SJohn Forte volcount->count = 1; 127*fcf3ce44SJohn Forte nsc_insert_node(volhash, volcount, bmp); 128*fcf3ce44SJohn Forte } 129*fcf3ce44SJohn Forte } 130*fcf3ce44SJohn Forte } 131*fcf3ce44SJohn Forte 132*fcf3ce44SJohn Forte int 133*fcf3ce44SJohn Forte sv_enable_one_nocfg(char *vol) 134*fcf3ce44SJohn Forte { 135*fcf3ce44SJohn Forte struct stat sb; 136*fcf3ce44SJohn Forte sv_conf_t svc; 137*fcf3ce44SJohn Forte int fd; 138*fcf3ce44SJohn Forte 139*fcf3ce44SJohn Forte bzero(&svc, sizeof (svc)); 140*fcf3ce44SJohn Forte if (stat(vol, &sb) != 0) { 141*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_OS, 0, "unable to stat %s", vol); 142*fcf3ce44SJohn Forte return (-1); 143*fcf3ce44SJohn Forte } 144*fcf3ce44SJohn Forte if (!S_ISCHR(sb.st_mode)) { 145*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL, "%s is not" 146*fcf3ce44SJohn Forte " a character device", vol); 147*fcf3ce44SJohn Forte return (-1); 148*fcf3ce44SJohn Forte } 149*fcf3ce44SJohn Forte 150*fcf3ce44SJohn Forte svc.svc_major = major(sb.st_rdev); 151*fcf3ce44SJohn Forte svc.svc_minor = minor(sb.st_rdev); 152*fcf3ce44SJohn Forte strncpy(svc.svc_path, vol, sizeof (svc.svc_path)); 153*fcf3ce44SJohn Forte 154*fcf3ce44SJohn Forte fd = open(SV_DEVICE, O_RDONLY); 155*fcf3ce44SJohn Forte if (fd < 0) { 156*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_OS, 0, 0); 157*fcf3ce44SJohn Forte return (-1); 158*fcf3ce44SJohn Forte } 159*fcf3ce44SJohn Forte 160*fcf3ce44SJohn Forte svc.svc_flag = (NSC_DEVICE | NSC_CACHE); 161*fcf3ce44SJohn Forte svc.svc_error = spcs_s_ucreate(); 162*fcf3ce44SJohn Forte 163*fcf3ce44SJohn Forte if (ioctl(fd, SVIOC_ENABLE, &svc) < 0) { 164*fcf3ce44SJohn Forte if (errno != SV_EENABLED) { 165*fcf3ce44SJohn Forte rdc_set_error(&svc.svc_error, RDC_INTERNAL, 166*fcf3ce44SJohn Forte RDC_NONFATAL, 0); 167*fcf3ce44SJohn Forte return (-1); 168*fcf3ce44SJohn Forte } 169*fcf3ce44SJohn Forte } 170*fcf3ce44SJohn Forte 171*fcf3ce44SJohn Forte spcs_log("sv", NULL, gettext("enabled %s"), svc.svc_path); 172*fcf3ce44SJohn Forte 173*fcf3ce44SJohn Forte close(fd); 174*fcf3ce44SJohn Forte return (1); 175*fcf3ce44SJohn Forte } 176*fcf3ce44SJohn Forte 177*fcf3ce44SJohn Forte int 178*fcf3ce44SJohn Forte sv_enable_nocfg(rdcconfig_t *rdc) 179*fcf3ce44SJohn Forte { 180*fcf3ce44SJohn Forte struct stat stbv; 181*fcf3ce44SJohn Forte struct stat stbb; 182*fcf3ce44SJohn Forte sv_conf_t svcv; 183*fcf3ce44SJohn Forte sv_conf_t svcb; 184*fcf3ce44SJohn Forte char vol[NSC_MAXPATH]; 185*fcf3ce44SJohn Forte char bmp[NSC_MAXPATH]; 186*fcf3ce44SJohn Forte int fd = -1; 187*fcf3ce44SJohn Forte 188*fcf3ce44SJohn Forte 189*fcf3ce44SJohn Forte if (self_check(rdc->phost)) { 190*fcf3ce44SJohn Forte strncpy(vol, rdc->pfile, NSC_MAXPATH); 191*fcf3ce44SJohn Forte strncpy(bmp, rdc->pbmp, NSC_MAXPATH); 192*fcf3ce44SJohn Forte } else { 193*fcf3ce44SJohn Forte strncpy(vol, rdc->sfile, NSC_MAXPATH); 194*fcf3ce44SJohn Forte strncpy(bmp, rdc->sbmp, NSC_MAXPATH); 195*fcf3ce44SJohn Forte } 196*fcf3ce44SJohn Forte 197*fcf3ce44SJohn Forte bzero(&svcv, sizeof (svcv)); 198*fcf3ce44SJohn Forte bzero(&svcb, sizeof (svcb)); 199*fcf3ce44SJohn Forte 200*fcf3ce44SJohn Forte if ((stat(vol, &stbv) != 0) || (stat(bmp, &stbb) != 0)) 201*fcf3ce44SJohn Forte return (-1); 202*fcf3ce44SJohn Forte 203*fcf3ce44SJohn Forte if ((!S_ISCHR(stbv.st_mode)) || (!S_ISCHR(stbb.st_mode))) 204*fcf3ce44SJohn Forte return (-1); 205*fcf3ce44SJohn Forte 206*fcf3ce44SJohn Forte svcv.svc_major = major(stbv.st_rdev); 207*fcf3ce44SJohn Forte svcb.svc_minor = minor(stbb.st_rdev); 208*fcf3ce44SJohn Forte 209*fcf3ce44SJohn Forte strncpy(svcv.svc_path, vol, sizeof (svcv.svc_path)); 210*fcf3ce44SJohn Forte strncpy(svcb.svc_path, bmp, sizeof (svcb.svc_path)); 211*fcf3ce44SJohn Forte 212*fcf3ce44SJohn Forte fd = open(SV_DEVICE, O_RDONLY); 213*fcf3ce44SJohn Forte if (fd < 0) 214*fcf3ce44SJohn Forte return (-1); 215*fcf3ce44SJohn Forte 216*fcf3ce44SJohn Forte /* SV enable the volume */ 217*fcf3ce44SJohn Forte svcv.svc_flag = (NSC_DEVICE | NSC_CACHE); 218*fcf3ce44SJohn Forte svcv.svc_error = spcs_s_ucreate(); 219*fcf3ce44SJohn Forte 220*fcf3ce44SJohn Forte if (ioctl(fd, SVIOC_ENABLE, &svcv) < 0) { 221*fcf3ce44SJohn Forte if (errno != SV_EENABLED) { 222*fcf3ce44SJohn Forte spcs_log("sv", &svcv.svc_error, 223*fcf3ce44SJohn Forte gettext("unable to enable %s"), 224*fcf3ce44SJohn Forte svcv.svc_path); 225*fcf3ce44SJohn Forte spcs_s_ufree(&svcv.svc_error); 226*fcf3ce44SJohn Forte return (-1); 227*fcf3ce44SJohn Forte } 228*fcf3ce44SJohn Forte } 229*fcf3ce44SJohn Forte 230*fcf3ce44SJohn Forte /* SV enable the bitmap disable the vol on error */ 231*fcf3ce44SJohn Forte svcb.svc_flag = (NSC_DEVICE | NSC_CACHE); 232*fcf3ce44SJohn Forte svcb.svc_error = spcs_s_ucreate(); 233*fcf3ce44SJohn Forte 234*fcf3ce44SJohn Forte if (ioctl(fd, SVIOC_ENABLE, &svcb) < 0) { 235*fcf3ce44SJohn Forte if (errno != SV_EENABLED) { 236*fcf3ce44SJohn Forte spcs_log("sv", &svcb.svc_error, 237*fcf3ce44SJohn Forte gettext("unable to enable %s"), 238*fcf3ce44SJohn Forte svcb.svc_path); 239*fcf3ce44SJohn Forte if (ioctl(fd, SVIOC_DISABLE, &svcv) < 0) 240*fcf3ce44SJohn Forte spcs_log("sv", &svcv.svc_error, 241*fcf3ce44SJohn Forte gettext("unable to disable %s"), 242*fcf3ce44SJohn Forte svcv.svc_path); 243*fcf3ce44SJohn Forte 244*fcf3ce44SJohn Forte spcs_s_ufree(&svcv.svc_error); 245*fcf3ce44SJohn Forte spcs_s_ufree(&svcb.svc_error); 246*fcf3ce44SJohn Forte return (-1); 247*fcf3ce44SJohn Forte } 248*fcf3ce44SJohn Forte } 249*fcf3ce44SJohn Forte 250*fcf3ce44SJohn Forte 251*fcf3ce44SJohn Forte spcs_log("sv", NULL, gettext("enabled %s"), svcv.svc_path); 252*fcf3ce44SJohn Forte spcs_log("sv", NULL, gettext("enabled %s"), svcb.svc_path); 253*fcf3ce44SJohn Forte spcs_s_ufree(&svcv.svc_error); 254*fcf3ce44SJohn Forte spcs_s_ufree(&svcb.svc_error); 255*fcf3ce44SJohn Forte 256*fcf3ce44SJohn Forte 257*fcf3ce44SJohn Forte if (fd >= 0) 258*fcf3ce44SJohn Forte (void) close(fd); 259*fcf3ce44SJohn Forte 260*fcf3ce44SJohn Forte return (1); 261*fcf3ce44SJohn Forte } 262*fcf3ce44SJohn Forte 263*fcf3ce44SJohn Forte int 264*fcf3ce44SJohn Forte do_autosv_enable(CFGFILE *cfg, rdcconfig_t *rdc) 265*fcf3ce44SJohn Forte { 266*fcf3ce44SJohn Forte char vol[NSC_MAXPATH]; 267*fcf3ce44SJohn Forte char bmp[NSC_MAXPATH]; 268*fcf3ce44SJohn Forte 269*fcf3ce44SJohn Forte cfg_load_svols(cfg); 270*fcf3ce44SJohn Forte cfg_load_dsvols(cfg); 271*fcf3ce44SJohn Forte cfg_load_shadows(cfg); 272*fcf3ce44SJohn Forte load_rdc_vols(cfg); 273*fcf3ce44SJohn Forte 274*fcf3ce44SJohn Forte if (self_check(rdc->phost)) { 275*fcf3ce44SJohn Forte strncpy(vol, rdc->pfile, NSC_MAXPATH); 276*fcf3ce44SJohn Forte strncpy(bmp, rdc->pbmp, NSC_MAXPATH); 277*fcf3ce44SJohn Forte } else { 278*fcf3ce44SJohn Forte strncpy(vol, rdc->sfile, NSC_MAXPATH); 279*fcf3ce44SJohn Forte strncpy(bmp, rdc->sbmp, NSC_MAXPATH); 280*fcf3ce44SJohn Forte } 281*fcf3ce44SJohn Forte if (nsc_lookup(volhash, vol) == NULL) { 282*fcf3ce44SJohn Forte if (cfg_vol_enable(cfg, vol, rdc->ctag, "sndr") < 0) { 283*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL, 284*fcf3ce44SJohn Forte "auto sv enable failed for %s", vol); 285*fcf3ce44SJohn Forte return (-1); 286*fcf3ce44SJohn Forte } 287*fcf3ce44SJohn Forte } 288*fcf3ce44SJohn Forte if (nsc_lookup(volhash, bmp) == NULL) { 289*fcf3ce44SJohn Forte if (cfg_vol_enable(cfg, bmp, rdc->ctag, "sndr") < 0) { 290*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL, 291*fcf3ce44SJohn Forte "auto sv enable failed for %s", vol); 292*fcf3ce44SJohn Forte return (-1); 293*fcf3ce44SJohn Forte } 294*fcf3ce44SJohn Forte } 295*fcf3ce44SJohn Forte 296*fcf3ce44SJohn Forte nsc_remove_all(volhash, free); 297*fcf3ce44SJohn Forte volhash = NULL; 298*fcf3ce44SJohn Forte 299*fcf3ce44SJohn Forte cfg_unload_shadows(); 300*fcf3ce44SJohn Forte cfg_unload_dsvols(); 301*fcf3ce44SJohn Forte cfg_unload_svols(); 302*fcf3ce44SJohn Forte 303*fcf3ce44SJohn Forte return (1); 304*fcf3ce44SJohn Forte } 305*fcf3ce44SJohn Forte 306*fcf3ce44SJohn Forte int 307*fcf3ce44SJohn Forte do_autosv_disable(CFGFILE *cfg, rdcconfig_t *rdc) 308*fcf3ce44SJohn Forte { 309*fcf3ce44SJohn Forte char vol[NSC_MAXPATH]; 310*fcf3ce44SJohn Forte char bmp[NSC_MAXPATH]; 311*fcf3ce44SJohn Forte volcount_t *vc; 312*fcf3ce44SJohn Forte 313*fcf3ce44SJohn Forte cfg_load_svols(cfg); 314*fcf3ce44SJohn Forte cfg_load_dsvols(cfg); 315*fcf3ce44SJohn Forte cfg_load_shadows(cfg); 316*fcf3ce44SJohn Forte load_rdc_vols(cfg); 317*fcf3ce44SJohn Forte 318*fcf3ce44SJohn Forte if (self_check(rdc->phost)) { 319*fcf3ce44SJohn Forte strncpy(vol, rdc->pfile, NSC_MAXPATH); 320*fcf3ce44SJohn Forte strncpy(bmp, rdc->pbmp, NSC_MAXPATH); 321*fcf3ce44SJohn Forte } else { 322*fcf3ce44SJohn Forte strncpy(vol, rdc->sfile, NSC_MAXPATH); 323*fcf3ce44SJohn Forte strncpy(bmp, rdc->sbmp, NSC_MAXPATH); 324*fcf3ce44SJohn Forte } 325*fcf3ce44SJohn Forte 326*fcf3ce44SJohn Forte vc = nsc_lookup(volhash, vol); 327*fcf3ce44SJohn Forte if (vc && (vc->count == 1)) { 328*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, vol, rdc->ctag, "sndr") < 0) 329*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL, 330*fcf3ce44SJohn Forte "auto sv disable failed for %s", vol); 331*fcf3ce44SJohn Forte } else if (!vc) { 332*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL, 333*fcf3ce44SJohn Forte "Unable to find %s in config", vol); 334*fcf3ce44SJohn Forte } 335*fcf3ce44SJohn Forte vc = nsc_lookup(volhash, bmp); 336*fcf3ce44SJohn Forte if (vc && (vc->count == 1)) { 337*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, bmp, rdc->ctag, "sndr") < 0) 338*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL, 339*fcf3ce44SJohn Forte "auto sv disable failed for %s", bmp); 340*fcf3ce44SJohn Forte 341*fcf3ce44SJohn Forte } else if (!vc) { 342*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL, 343*fcf3ce44SJohn Forte "Unable to find %s in config", bmp); 344*fcf3ce44SJohn Forte } 345*fcf3ce44SJohn Forte 346*fcf3ce44SJohn Forte return (1); 347*fcf3ce44SJohn Forte 348*fcf3ce44SJohn Forte } 349*fcf3ce44SJohn Forte 350*fcf3ce44SJohn Forte /* 351*fcf3ce44SJohn Forte * do sv enables for the appropriate vol 352*fcf3ce44SJohn Forte * and bitmap. If called without persistance 353*fcf3ce44SJohn Forte * it will follow a chain and sv enable all 354*fcf3ce44SJohn Forte * otherwise, it will enable only the one 355*fcf3ce44SJohn Forte * set. 356*fcf3ce44SJohn Forte */ 357*fcf3ce44SJohn Forte int 358*fcf3ce44SJohn Forte sv_enable(CFGFILE *cfg, rdcconfig_t *rdcs) 359*fcf3ce44SJohn Forte { 360*fcf3ce44SJohn Forte rdcconfig_t *rdcp = NULL; 361*fcf3ce44SJohn Forte 362*fcf3ce44SJohn Forte rdcp = rdcs; 363*fcf3ce44SJohn Forte if (!rdcp->persist) { 364*fcf3ce44SJohn Forte 365*fcf3ce44SJohn Forte return (sv_enable_nocfg(rdcp)); 366*fcf3ce44SJohn Forte 367*fcf3ce44SJohn Forte } else if (cfg == NULL) { 368*fcf3ce44SJohn Forte 369*fcf3ce44SJohn Forte return (-1); 370*fcf3ce44SJohn Forte 371*fcf3ce44SJohn Forte } 372*fcf3ce44SJohn Forte 373*fcf3ce44SJohn Forte do_autosv_enable(cfg, rdcp); 374*fcf3ce44SJohn Forte 375*fcf3ce44SJohn Forte return (1); 376*fcf3ce44SJohn Forte } 377*fcf3ce44SJohn Forte 378*fcf3ce44SJohn Forte int 379*fcf3ce44SJohn Forte sv_disable(CFGFILE *cfg, rdcconfig_t *rdcs) 380*fcf3ce44SJohn Forte { 381*fcf3ce44SJohn Forte rdcconfig_t *rdcp; 382*fcf3ce44SJohn Forte 383*fcf3ce44SJohn Forte rdcp = rdcs; 384*fcf3ce44SJohn Forte if (!rdcp->persist) { /* don't disable */ 385*fcf3ce44SJohn Forte 386*fcf3ce44SJohn Forte return (1); 387*fcf3ce44SJohn Forte 388*fcf3ce44SJohn Forte } else if (cfg == NULL) { 389*fcf3ce44SJohn Forte 390*fcf3ce44SJohn Forte return (-1); 391*fcf3ce44SJohn Forte 392*fcf3ce44SJohn Forte } 393*fcf3ce44SJohn Forte 394*fcf3ce44SJohn Forte do_autosv_disable(cfg, rdcp); 395*fcf3ce44SJohn Forte 396*fcf3ce44SJohn Forte return (1); 397*fcf3ce44SJohn Forte 398*fcf3ce44SJohn Forte } 399*fcf3ce44SJohn Forte 400*fcf3ce44SJohn Forte /* 401*fcf3ce44SJohn Forte * disable the appropriate bitmap in rdc 402*fcf3ce44SJohn Forte * and replace it with bitmap 403*fcf3ce44SJohn Forte */ 404*fcf3ce44SJohn Forte int 405*fcf3ce44SJohn Forte sv_reconfig(CFGFILE *cfg, rdcconfig_t *rdc, char *oldbmp, char *newbmp) 406*fcf3ce44SJohn Forte { 407*fcf3ce44SJohn Forte rdcconfig_t *rdcp; 408*fcf3ce44SJohn Forte int fail = 0; 409*fcf3ce44SJohn Forte 410*fcf3ce44SJohn Forte rdcp = rdc; 411*fcf3ce44SJohn Forte if (!rdcp->persist) { /* just enable, don't disable */ 412*fcf3ce44SJohn Forte 413*fcf3ce44SJohn Forte sv_enable_one_nocfg(newbmp); 414*fcf3ce44SJohn Forte 415*fcf3ce44SJohn Forte } else if (rdcp->persist) { /* do sv disable and enable */ 416*fcf3ce44SJohn Forte volcount_t *vc; 417*fcf3ce44SJohn Forte 418*fcf3ce44SJohn Forte cfg_load_svols(cfg); 419*fcf3ce44SJohn Forte cfg_load_dsvols(cfg); 420*fcf3ce44SJohn Forte cfg_load_shadows(cfg); 421*fcf3ce44SJohn Forte load_rdc_vols(cfg); 422*fcf3ce44SJohn Forte 423*fcf3ce44SJohn Forte vc = (volcount_t *)nsc_lookup(volhash, oldbmp); 424*fcf3ce44SJohn Forte if (vc && (vc->count == 1)) { 425*fcf3ce44SJohn Forte if (cfg_vol_disable(cfg, oldbmp, rdc->ctag, "sndr") < 0) 426*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL, 427*fcf3ce44SJohn Forte "auto sv disable failed for %s", oldbmp); 428*fcf3ce44SJohn Forte 429*fcf3ce44SJohn Forte } 430*fcf3ce44SJohn Forte if (nsc_lookup(volhash, newbmp) == NULL) { 431*fcf3ce44SJohn Forte if (cfg_vol_enable(cfg, 432*fcf3ce44SJohn Forte newbmp, rdc->ctag, "sndr") < 0) { 433*fcf3ce44SJohn Forte 434*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL, 435*fcf3ce44SJohn Forte "auto sv enable failed for %s", newbmp); 436*fcf3ce44SJohn Forte fail++; 437*fcf3ce44SJohn Forte } 438*fcf3ce44SJohn Forte } 439*fcf3ce44SJohn Forte nsc_remove_all(volhash, free); 440*fcf3ce44SJohn Forte volhash = NULL; 441*fcf3ce44SJohn Forte 442*fcf3ce44SJohn Forte cfg_unload_shadows(); 443*fcf3ce44SJohn Forte cfg_unload_dsvols(); 444*fcf3ce44SJohn Forte cfg_unload_svols(); 445*fcf3ce44SJohn Forte if (fail) 446*fcf3ce44SJohn Forte return (-1); 447*fcf3ce44SJohn Forte 448*fcf3ce44SJohn Forte } 449*fcf3ce44SJohn Forte return (1); 450*fcf3ce44SJohn Forte 451*fcf3ce44SJohn Forte } 452*fcf3ce44SJohn Forte 453*fcf3ce44SJohn Forte /* 454*fcf3ce44SJohn Forte * SNDR functions 455*fcf3ce44SJohn Forte */ 456*fcf3ce44SJohn Forte 457*fcf3ce44SJohn Forte /* 458*fcf3ce44SJohn Forte * add_to_rdc_cfg 459*fcf3ce44SJohn Forte * this adds the successfully created rdc sets to libdscfg, 460*fcf3ce44SJohn Forte * also, as auto_sv stuff is part of libdscfg, it does the 461*fcf3ce44SJohn Forte * auto_sv stuff and enables the correct volumes 462*fcf3ce44SJohn Forte */ 463*fcf3ce44SJohn Forte int 464*fcf3ce44SJohn Forte add_to_rdc_cfg(rdcconfig_t *rdcs) 465*fcf3ce44SJohn Forte { 466*fcf3ce44SJohn Forte CFGFILE *cfg; 467*fcf3ce44SJohn Forte rdcconfig_t *rdcp; 468*fcf3ce44SJohn Forte char *buf; 469*fcf3ce44SJohn Forte 470*fcf3ce44SJohn Forte 471*fcf3ce44SJohn Forte buf = calloc(CFG_MAX_BUF, sizeof (char)); 472*fcf3ce44SJohn Forte if (!buf) { 473*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_OS, RDC_FATAL, NULL); 474*fcf3ce44SJohn Forte return (NULL); 475*fcf3ce44SJohn Forte } 476*fcf3ce44SJohn Forte 477*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) { 478*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 479*fcf3ce44SJohn Forte return (-1); 480*fcf3ce44SJohn Forte } 481*fcf3ce44SJohn Forte if ((cfg_lock(cfg, CFG_WRLOCK)) < 0) { 482*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 483*fcf3ce44SJohn Forte return (-1); 484*fcf3ce44SJohn Forte } 485*fcf3ce44SJohn Forte 486*fcf3ce44SJohn Forte rdcp = rdcs; 487*fcf3ce44SJohn Forte while (rdcp) { 488*fcf3ce44SJohn Forte buf = config2buf(buf, rdcp); 489*fcf3ce44SJohn Forte if ((sv_enable(cfg, rdcp) < 0) || 490*fcf3ce44SJohn Forte (cfg_put_cstring(cfg, "sndr", buf, CFG_MAX_BUF) < 0)) { 491*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 492*fcf3ce44SJohn Forte free(buf); 493*fcf3ce44SJohn Forte return (-1); 494*fcf3ce44SJohn Forte } 495*fcf3ce44SJohn Forte rdcp = rdcp->next; 496*fcf3ce44SJohn Forte } 497*fcf3ce44SJohn Forte if (!cfg_commit(cfg)) { 498*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, NULL); 499*fcf3ce44SJohn Forte return (-1); 500*fcf3ce44SJohn Forte } 501*fcf3ce44SJohn Forte 502*fcf3ce44SJohn Forte cfg_close(cfg); 503*fcf3ce44SJohn Forte 504*fcf3ce44SJohn Forte return (0); 505*fcf3ce44SJohn Forte } 506*fcf3ce44SJohn Forte 507*fcf3ce44SJohn Forte int 508*fcf3ce44SJohn Forte cfg_lookup(CFGFILE *cfg, char *shost, char *sfile) 509*fcf3ce44SJohn Forte { 510*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 511*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 512*fcf3ce44SJohn Forte int setnum; 513*fcf3ce44SJohn Forte int numsets = 0; 514*fcf3ce44SJohn Forte 515*fcf3ce44SJohn Forte numsets = cfg_get_num_entries(cfg, "sndr"); 516*fcf3ce44SJohn Forte for (setnum = 1; setnum <= numsets; setnum++) { 517*fcf3ce44SJohn Forte bzero(key, CFG_MAX_KEY); 518*fcf3ce44SJohn Forte snprintf(key, CFG_MAX_KEY, "sndr.set%d.shost", setnum); 519*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { 520*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 521*fcf3ce44SJohn Forte return (-1); 522*fcf3ce44SJohn Forte } 523*fcf3ce44SJohn Forte if (strncmp(buf, shost, strlen(shost))) 524*fcf3ce44SJohn Forte continue; 525*fcf3ce44SJohn Forte 526*fcf3ce44SJohn Forte bzero(key, CFG_MAX_KEY); 527*fcf3ce44SJohn Forte snprintf(key, CFG_MAX_KEY, "sndr.set%d.secondary", setnum); 528*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { 529*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 530*fcf3ce44SJohn Forte return (-1); 531*fcf3ce44SJohn Forte } 532*fcf3ce44SJohn Forte if (strncmp(buf, sfile, strlen(sfile))) 533*fcf3ce44SJohn Forte continue; 534*fcf3ce44SJohn Forte break; 535*fcf3ce44SJohn Forte } 536*fcf3ce44SJohn Forte return (setnum); 537*fcf3ce44SJohn Forte } 538*fcf3ce44SJohn Forte 539*fcf3ce44SJohn Forte void 540*fcf3ce44SJohn Forte remove_from_rdc_cfg(rdcconfig_t *rdcs) 541*fcf3ce44SJohn Forte { 542*fcf3ce44SJohn Forte CFGFILE *cfg; 543*fcf3ce44SJohn Forte rdcconfig_t *rdcp; 544*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 545*fcf3ce44SJohn Forte 546*fcf3ce44SJohn Forte rdcp = rdcs; 547*fcf3ce44SJohn Forte cfg = cfg_open(NULL); 548*fcf3ce44SJohn Forte cfg_lock(cfg, CFG_WRLOCK); 549*fcf3ce44SJohn Forte 550*fcf3ce44SJohn Forte while (rdcp) { 551*fcf3ce44SJohn Forte snprintf(key, CFG_MAX_KEY, "sndr.set%d", 552*fcf3ce44SJohn Forte cfg_lookup(cfg, rdcp->shost, rdcp->sfile)); 553*fcf3ce44SJohn Forte if ((sv_disable(cfg, rdcp) < 0) || 554*fcf3ce44SJohn Forte (cfg_put_cstring(cfg, key, NULL, 0)) < 0) { 555*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 556*fcf3ce44SJohn Forte } 557*fcf3ce44SJohn Forte 558*fcf3ce44SJohn Forte rdcp = rdcp->next; 559*fcf3ce44SJohn Forte } 560*fcf3ce44SJohn Forte cfg_commit(cfg); 561*fcf3ce44SJohn Forte cfg_close(cfg); 562*fcf3ce44SJohn Forte } 563*fcf3ce44SJohn Forte /*ARGSUSED*/ 564*fcf3ce44SJohn Forte int 565*fcf3ce44SJohn Forte replace_entry(int offset, char *entry) 566*fcf3ce44SJohn Forte { 567*fcf3ce44SJohn Forte return (1); 568*fcf3ce44SJohn Forte } 569*fcf3ce44SJohn Forte 570*fcf3ce44SJohn Forte /* 571*fcf3ce44SJohn Forte * this will set the value at "field" in dscfg to the 572*fcf3ce44SJohn Forte * value contained in entry. 573*fcf3ce44SJohn Forte * for things like bitmap reconfigs, only pass one rdc 574*fcf3ce44SJohn Forte * not a chain 575*fcf3ce44SJohn Forte */ 576*fcf3ce44SJohn Forte int 577*fcf3ce44SJohn Forte replace_cfgfield(rdcconfig_t *rdc, char *field, char *entry) 578*fcf3ce44SJohn Forte { 579*fcf3ce44SJohn Forte CFGFILE *cfg; 580*fcf3ce44SJohn Forte rdcconfig_t *rdcp; 581*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 582*fcf3ce44SJohn Forte char newentry[CFG_MAX_BUF]; 583*fcf3ce44SJohn Forte char oldbmp[CFG_MAX_BUF]; 584*fcf3ce44SJohn Forte int setnum; 585*fcf3ce44SJohn Forte int ispbmp = 0; 586*fcf3ce44SJohn Forte int issbmp = 0; 587*fcf3ce44SJohn Forte 588*fcf3ce44SJohn Forte if (strncmp(field, "pbitmap", NSC_MAXPATH) == 0) 589*fcf3ce44SJohn Forte ispbmp++; 590*fcf3ce44SJohn Forte if (strncmp(field, "sbitmap", NSC_MAXPATH) == 0) 591*fcf3ce44SJohn Forte issbmp++; 592*fcf3ce44SJohn Forte 593*fcf3ce44SJohn Forte bzero(newentry, sizeof (newentry)); 594*fcf3ce44SJohn Forte if (!entry || strlen(entry) == 0) 595*fcf3ce44SJohn Forte *newentry = '-'; 596*fcf3ce44SJohn Forte else 597*fcf3ce44SJohn Forte strncpy(newentry, entry, CFG_MAX_BUF); 598*fcf3ce44SJohn Forte 599*fcf3ce44SJohn Forte 600*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) { 601*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 602*fcf3ce44SJohn Forte return (-1); 603*fcf3ce44SJohn Forte } 604*fcf3ce44SJohn Forte if ((cfg_lock(cfg, CFG_WRLOCK)) < 0) { 605*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 606*fcf3ce44SJohn Forte return (-1); 607*fcf3ce44SJohn Forte } 608*fcf3ce44SJohn Forte 609*fcf3ce44SJohn Forte rdcp = rdc; 610*fcf3ce44SJohn Forte while (rdcp) { 611*fcf3ce44SJohn Forte if ((setnum = cfg_lookup(cfg, rdcp->shost, rdcp->sfile)) < 0) { 612*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 613*fcf3ce44SJohn Forte return (-1); 614*fcf3ce44SJohn Forte } 615*fcf3ce44SJohn Forte snprintf(key, CFG_MAX_KEY, "sndr.set%d.%s", setnum, field); 616*fcf3ce44SJohn Forte if (!((ispbmp || issbmp) && 617*fcf3ce44SJohn Forte (cfg_get_cstring(cfg, key, oldbmp, CFG_MAX_BUF)) == 0)) { 618*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, "unable to get %s", 619*fcf3ce44SJohn Forte key); 620*fcf3ce44SJohn Forte } 621*fcf3ce44SJohn Forte if (((ispbmp && self_check(rdcp->phost)) || 622*fcf3ce44SJohn Forte (issbmp && self_check(rdcp->shost))) && 623*fcf3ce44SJohn Forte (sv_reconfig(cfg, rdcp, oldbmp, newentry) < 0)) { 624*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_INTERNAL, RDC_NONFATAL, 625*fcf3ce44SJohn Forte "unable to sv reconfig %s to %s", oldbmp, newentry); 626*fcf3ce44SJohn Forte return (-1); 627*fcf3ce44SJohn Forte } 628*fcf3ce44SJohn Forte 629*fcf3ce44SJohn Forte if ((cfg_put_cstring(cfg, key, newentry, CFG_MAX_BUF)) < 0) { 630*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 631*fcf3ce44SJohn Forte return (-1); 632*fcf3ce44SJohn Forte } 633*fcf3ce44SJohn Forte rdcp = rdcp->next; 634*fcf3ce44SJohn Forte } 635*fcf3ce44SJohn Forte cfg_commit(cfg); 636*fcf3ce44SJohn Forte cfg_close(cfg); 637*fcf3ce44SJohn Forte return (1); 638*fcf3ce44SJohn Forte } 639*fcf3ce44SJohn Forte 640*fcf3ce44SJohn Forte /* 641*fcf3ce44SJohn Forte * reverse_in_cfg 642*fcf3ce44SJohn Forte * used by RDC_OPT_REVERSE_ROLE 643*fcf3ce44SJohn Forte * swaps primary info and secondary info 644*fcf3ce44SJohn Forte */ 645*fcf3ce44SJohn Forte int 646*fcf3ce44SJohn Forte reverse_in_cfg(rdcconfig_t *rdc) 647*fcf3ce44SJohn Forte { 648*fcf3ce44SJohn Forte CFGFILE *cfg; 649*fcf3ce44SJohn Forte rdcconfig_t *rdcp = NULL; 650*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 651*fcf3ce44SJohn Forte int setnum; 652*fcf3ce44SJohn Forte 653*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) { 654*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 655*fcf3ce44SJohn Forte return (-1); 656*fcf3ce44SJohn Forte } 657*fcf3ce44SJohn Forte if ((cfg_lock(cfg, CFG_WRLOCK)) < 0) { 658*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 659*fcf3ce44SJohn Forte return (-1); 660*fcf3ce44SJohn Forte } 661*fcf3ce44SJohn Forte 662*fcf3ce44SJohn Forte rdcp = rdc; 663*fcf3ce44SJohn Forte while (rdcp) { 664*fcf3ce44SJohn Forte if ((setnum = cfg_lookup(cfg, rdcp->shost, rdcp->sfile)) < 0) { 665*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 666*fcf3ce44SJohn Forte goto badconfig; 667*fcf3ce44SJohn Forte } 668*fcf3ce44SJohn Forte bzero(key, CFG_MAX_KEY); 669*fcf3ce44SJohn Forte snprintf(key, CFG_MAX_KEY, "sndr.set%d.phost", setnum); 670*fcf3ce44SJohn Forte if ((cfg_put_cstring(cfg, key, rdcp->shost, CFG_MAX_BUF)) < 0) { 671*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 672*fcf3ce44SJohn Forte goto badconfig; 673*fcf3ce44SJohn Forte } 674*fcf3ce44SJohn Forte bzero(key, CFG_MAX_KEY); 675*fcf3ce44SJohn Forte snprintf(key, CFG_MAX_KEY, "sndr.set%d.primary", setnum); 676*fcf3ce44SJohn Forte if ((cfg_put_cstring(cfg, key, rdcp->sfile, CFG_MAX_BUF)) < 0) { 677*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 678*fcf3ce44SJohn Forte goto badconfig; 679*fcf3ce44SJohn Forte } 680*fcf3ce44SJohn Forte bzero(key, CFG_MAX_KEY); 681*fcf3ce44SJohn Forte snprintf(key, CFG_MAX_KEY, "sndr.set%d.pbitmap", setnum); 682*fcf3ce44SJohn Forte if ((cfg_put_cstring(cfg, key, rdcp->sbmp, CFG_MAX_BUF)) < 0) { 683*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 684*fcf3ce44SJohn Forte goto badconfig; 685*fcf3ce44SJohn Forte } 686*fcf3ce44SJohn Forte bzero(key, CFG_MAX_KEY); 687*fcf3ce44SJohn Forte snprintf(key, CFG_MAX_KEY, "sndr.set%d.shost", setnum); 688*fcf3ce44SJohn Forte if ((cfg_put_cstring(cfg, key, rdcp->phost, CFG_MAX_BUF)) < 0) { 689*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 690*fcf3ce44SJohn Forte goto badconfig; 691*fcf3ce44SJohn Forte } 692*fcf3ce44SJohn Forte bzero(key, CFG_MAX_KEY); 693*fcf3ce44SJohn Forte snprintf(key, CFG_MAX_KEY, "sndr.set%d.secondary", setnum); 694*fcf3ce44SJohn Forte if ((cfg_put_cstring(cfg, key, rdcp->pfile, CFG_MAX_BUF)) < 0) { 695*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 696*fcf3ce44SJohn Forte goto badconfig; 697*fcf3ce44SJohn Forte } 698*fcf3ce44SJohn Forte bzero(key, CFG_MAX_KEY); 699*fcf3ce44SJohn Forte snprintf(key, CFG_MAX_KEY, "sndr.set%d.sbitmap", setnum); 700*fcf3ce44SJohn Forte if ((cfg_put_cstring(cfg, key, rdcp->pbmp, CFG_MAX_BUF)) < 0) { 701*fcf3ce44SJohn Forte rdc_set_error(NULL, RDC_DSCFG, 0, 0); 702*fcf3ce44SJohn Forte goto badconfig; 703*fcf3ce44SJohn Forte } 704*fcf3ce44SJohn Forte rdcp = rdcp->next; 705*fcf3ce44SJohn Forte } 706*fcf3ce44SJohn Forte if (!cfg_commit(cfg)) { 707*fcf3ce44SJohn Forte cfg_close(cfg); 708*fcf3ce44SJohn Forte return (-1); 709*fcf3ce44SJohn Forte } 710*fcf3ce44SJohn Forte cfg_close(cfg); 711*fcf3ce44SJohn Forte return (0); 712*fcf3ce44SJohn Forte 713*fcf3ce44SJohn Forte badconfig: 714*fcf3ce44SJohn Forte cfg_close(cfg); 715*fcf3ce44SJohn Forte return (-1); 716*fcf3ce44SJohn Forte } 717