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/wait.h> 28*fcf3ce44SJohn Forte #include <stdio.h> 29*fcf3ce44SJohn Forte #include <errno.h> 30*fcf3ce44SJohn Forte #include <limits.h> 31*fcf3ce44SJohn Forte #include <fcntl.h> 32*fcf3ce44SJohn Forte #include <strings.h> 33*fcf3ce44SJohn Forte #include <stdlib.h> 34*fcf3ce44SJohn Forte #include <unistd.h> 35*fcf3ce44SJohn Forte #include <pthread.h> 36*fcf3ce44SJohn Forte #include <thread.h> 37*fcf3ce44SJohn Forte 38*fcf3ce44SJohn Forte #include <locale.h> 39*fcf3ce44SJohn Forte #include <langinfo.h> 40*fcf3ce44SJohn Forte #include <libintl.h> 41*fcf3ce44SJohn Forte #include <stdarg.h> 42*fcf3ce44SJohn Forte 43*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_io.h> 44*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_ioctl.h> 45*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_prot.h> 46*fcf3ce44SJohn Forte 47*fcf3ce44SJohn Forte #include <sys/nsctl/cfg.h> 48*fcf3ce44SJohn Forte 49*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s.h> 50*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_u.h> 51*fcf3ce44SJohn Forte #include <sys/unistat/spcs_errors.h> 52*fcf3ce44SJohn Forte 53*fcf3ce44SJohn Forte #include <sys/nsctl/librdc.h> 54*fcf3ce44SJohn Forte 55*fcf3ce44SJohn Forte #include "rdcadm.h" 56*fcf3ce44SJohn Forte 57*fcf3ce44SJohn Forte 58*fcf3ce44SJohn Forte #define RDCADM "/usr/sbin/sndradm" 59*fcf3ce44SJohn Forte #define IIADM "/usr/sbin/iiadm" 60*fcf3ce44SJohn Forte 61*fcf3ce44SJohn Forte #define UPDATE "update" 62*fcf3ce44SJohn Forte #define NOUPDATE "noupdate" 63*fcf3ce44SJohn Forte 64*fcf3ce44SJohn Forte #define RESYNC_SLEEP (3 * 60) /* Three minutes */ 65*fcf3ce44SJohn Forte #define MAIN_SLEEP (5 * 60) /* Five minutes */ 66*fcf3ce44SJohn Forte #define CFG_WAIT_SLEEP (5) /* 5 sec */ 67*fcf3ce44SJohn Forte 68*fcf3ce44SJohn Forte #define MAXHOSTS 1024 69*fcf3ce44SJohn Forte mutex_t cfglock = DEFAULTMUTEX; 70*fcf3ce44SJohn Forte #define LOCKCFG() (void) mutex_lock(&cfglock); 71*fcf3ce44SJohn Forte #define UNLOCKCFG() (void) mutex_unlock(&cfglock); 72*fcf3ce44SJohn Forte 73*fcf3ce44SJohn Forte typedef struct host_list_s { 74*fcf3ce44SJohn Forte char *hosts[MAXHOSTS]; 75*fcf3ce44SJohn Forte int numhosts; 76*fcf3ce44SJohn Forte int configured[MAXHOSTS]; 77*fcf3ce44SJohn Forte mutex_t hosts_mutex; 78*fcf3ce44SJohn Forte } host_list_t; 79*fcf3ce44SJohn Forte 80*fcf3ce44SJohn Forte host_list_t *host_list; 81*fcf3ce44SJohn Forte 82*fcf3ce44SJohn Forte extern char *basename(char *); 83*fcf3ce44SJohn Forte int rdc_maxsets; 84*fcf3ce44SJohn Forte char *program; 85*fcf3ce44SJohn Forte 86*fcf3ce44SJohn Forte static int clustered = 0; 87*fcf3ce44SJohn Forte 88*fcf3ce44SJohn Forte int isnewhost(char *host); 89*fcf3ce44SJohn Forte void *wait_sync_event(); 90*fcf3ce44SJohn Forte void *wait_link_down(void *host); 91*fcf3ce44SJohn Forte void rdc_sync(char *tohost); 92*fcf3ce44SJohn Forte void remove_from_hostlist(char *host); 93*fcf3ce44SJohn Forte void sync_start(char *master); 94*fcf3ce44SJohn Forte void sync_complete(char *master); 95*fcf3ce44SJohn Forte void cleanup_hostlist(); 96*fcf3ce44SJohn Forte void group_start(char *group); 97*fcf3ce44SJohn Forte void group_complete(char *group); 98*fcf3ce44SJohn Forte 99*fcf3ce44SJohn Forte 100*fcf3ce44SJohn Forte void 101*fcf3ce44SJohn Forte init_host_list(void) 102*fcf3ce44SJohn Forte { 103*fcf3ce44SJohn Forte host_list = calloc(1, sizeof (host_list_t)); 104*fcf3ce44SJohn Forte if (host_list == NULL) { 105*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 106*fcf3ce44SJohn Forte gettext("host list not initialized, cannot run")); 107*fcf3ce44SJohn Forte rdc_err(NULL, gettext("host list not initialized, cannot run")); 108*fcf3ce44SJohn Forte } 109*fcf3ce44SJohn Forte (void) mutex_init(&host_list->hosts_mutex, USYNC_THREAD, NULL); 110*fcf3ce44SJohn Forte } 111*fcf3ce44SJohn Forte 112*fcf3ce44SJohn Forte /* ARGSUSED */ 113*fcf3ce44SJohn Forte #ifdef lint 114*fcf3ce44SJohn Forte void 115*fcf3ce44SJohn Forte sndrsyncd_lintmain(argc, argv) 116*fcf3ce44SJohn Forte #else 117*fcf3ce44SJohn Forte int 118*fcf3ce44SJohn Forte main(argc, argv) 119*fcf3ce44SJohn Forte #endif 120*fcf3ce44SJohn Forte int argc; 121*fcf3ce44SJohn Forte char **argv; 122*fcf3ce44SJohn Forte { 123*fcf3ce44SJohn Forte rdc_status_t *rdc_info; 124*fcf3ce44SJohn Forte int size; 125*fcf3ce44SJohn Forte int i; 126*fcf3ce44SJohn Forte pid_t pid; 127*fcf3ce44SJohn Forte spcs_s_info_t ustatus; 128*fcf3ce44SJohn Forte int rc, trc; 129*fcf3ce44SJohn Forte int first = 0; 130*fcf3ce44SJohn Forte char *required; 131*fcf3ce44SJohn Forte 132*fcf3ce44SJohn Forte (void) setlocale(LC_ALL, ""); 133*fcf3ce44SJohn Forte (void) textdomain("rdc"); 134*fcf3ce44SJohn Forte 135*fcf3ce44SJohn Forte ustatus = spcs_s_ucreate(); 136*fcf3ce44SJohn Forte 137*fcf3ce44SJohn Forte program = basename(argv[0]); 138*fcf3ce44SJohn Forte 139*fcf3ce44SJohn Forte init_host_list(); 140*fcf3ce44SJohn Forte 141*fcf3ce44SJohn Forte rc = rdc_check_release(&required); 142*fcf3ce44SJohn Forte if (rc < 0) { 143*fcf3ce44SJohn Forte rdc_err(NULL, 144*fcf3ce44SJohn Forte gettext("unable to determine the current " 145*fcf3ce44SJohn Forte "Solaris release: %s\n"), strerror(errno)); 146*fcf3ce44SJohn Forte /* NOTREACHED */ 147*fcf3ce44SJohn Forte } else if (rc == FALSE) { 148*fcf3ce44SJohn Forte rdc_err(NULL, 149*fcf3ce44SJohn Forte gettext("incorrect Solaris release (requires %s)\n"), 150*fcf3ce44SJohn Forte required); 151*fcf3ce44SJohn Forte /* NOTREACHED */ 152*fcf3ce44SJohn Forte } 153*fcf3ce44SJohn Forte 154*fcf3ce44SJohn Forte clustered = cfg_iscluster(); 155*fcf3ce44SJohn Forte if (clustered < 0) { 156*fcf3ce44SJohn Forte rdc_err(NULL, gettext("unable to ascertain environment")); 157*fcf3ce44SJohn Forte } 158*fcf3ce44SJohn Forte 159*fcf3ce44SJohn Forte rdc_maxsets = rdc_get_maxsets(); 160*fcf3ce44SJohn Forte if (rdc_maxsets == -1) { 161*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 162*fcf3ce44SJohn Forte gettext("%s: unable to get maxsets value from kernel"), 163*fcf3ce44SJohn Forte program); 164*fcf3ce44SJohn Forte rdc_err(NULL, 165*fcf3ce44SJohn Forte gettext("unable to get maxsets value from kernel")); 166*fcf3ce44SJohn Forte } 167*fcf3ce44SJohn Forte size = sizeof (rdc_status_t) + (sizeof (rdc_set_t) * (rdc_maxsets - 1)); 168*fcf3ce44SJohn Forte rdc_info = malloc(size); 169*fcf3ce44SJohn Forte if (rdc_info == NULL) { 170*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 171*fcf3ce44SJohn Forte gettext("%s: unable to allocate %ld bytes"), 172*fcf3ce44SJohn Forte program, size); 173*fcf3ce44SJohn Forte rdc_err(NULL, 174*fcf3ce44SJohn Forte gettext("unable to allocate %ld bytes"), size); 175*fcf3ce44SJohn Forte } 176*fcf3ce44SJohn Forte bzero(rdc_info, size); 177*fcf3ce44SJohn Forte 178*fcf3ce44SJohn Forte rdc_info->nset = rdc_maxsets; 179*fcf3ce44SJohn Forte 180*fcf3ce44SJohn Forte /* 181*fcf3ce44SJohn Forte * Fork off a child that becomes the daemon. 182*fcf3ce44SJohn Forte */ 183*fcf3ce44SJohn Forte if ((pid = fork()) > 0) 184*fcf3ce44SJohn Forte exit(0); 185*fcf3ce44SJohn Forte else if (pid < 0) { 186*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 187*fcf3ce44SJohn Forte gettext("%s: cannot fork: %s"), 188*fcf3ce44SJohn Forte program, strerror(errno)); 189*fcf3ce44SJohn Forte rdc_err(NULL, gettext("cannot fork: %s\n"), 190*fcf3ce44SJohn Forte strerror(errno)); 191*fcf3ce44SJohn Forte } 192*fcf3ce44SJohn Forte 193*fcf3ce44SJohn Forte /* 194*fcf3ce44SJohn Forte * In child - become daemon. 195*fcf3ce44SJohn Forte */ 196*fcf3ce44SJohn Forte 197*fcf3ce44SJohn Forte for (i = 0; i < 3; i++) 198*fcf3ce44SJohn Forte (void) close(i); 199*fcf3ce44SJohn Forte 200*fcf3ce44SJohn Forte (void) open("/dev/console", O_WRONLY|O_APPEND); 201*fcf3ce44SJohn Forte (void) dup(0); 202*fcf3ce44SJohn Forte (void) dup(0); 203*fcf3ce44SJohn Forte (void) close(0); 204*fcf3ce44SJohn Forte 205*fcf3ce44SJohn Forte (void) setpgrp(); 206*fcf3ce44SJohn Forte 207*fcf3ce44SJohn Forte (void) setlocale(LC_ALL, ""); 208*fcf3ce44SJohn Forte (void) textdomain("rdc"); 209*fcf3ce44SJohn Forte 210*fcf3ce44SJohn Forte /* launch a thread to wait for sync start and sync stop events */ 211*fcf3ce44SJohn Forte 212*fcf3ce44SJohn Forte if ((trc = thr_create(NULL, 0, wait_sync_event, NULL, 213*fcf3ce44SJohn Forte THR_BOUND|THR_DETACHED, NULL)) != 0) { 214*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 215*fcf3ce44SJohn Forte gettext("%s: unable to create thread wait_sync_event"), 216*fcf3ce44SJohn Forte program); 217*fcf3ce44SJohn Forte rdc_warn(NULL, 218*fcf3ce44SJohn Forte gettext("%s unable to create thread wait_sync_event"), 219*fcf3ce44SJohn Forte program); 220*fcf3ce44SJohn Forte } else { 221*fcf3ce44SJohn Forte #ifdef DEBUG 222*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 223*fcf3ce44SJohn Forte gettext("%s: thread wait_sync_event started"), program); 224*fcf3ce44SJohn Forte #endif 225*fcf3ce44SJohn Forte ; 226*fcf3ce44SJohn Forte } 227*fcf3ce44SJohn Forte 228*fcf3ce44SJohn Forte for (;;) { 229*fcf3ce44SJohn Forte if (!first) { 230*fcf3ce44SJohn Forte first++; 231*fcf3ce44SJohn Forte (void) sleep(15); 232*fcf3ce44SJohn Forte } else 233*fcf3ce44SJohn Forte (void) sleep(MAIN_SLEEP); 234*fcf3ce44SJohn Forte 235*fcf3ce44SJohn Forte bzero(rdc_info, size); 236*fcf3ce44SJohn Forte rdc_info->nset = rdc_maxsets; 237*fcf3ce44SJohn Forte if (RDC_IOCTL(RDC_STATUS, rdc_info, 0, 0, 0, 0, ustatus) 238*fcf3ce44SJohn Forte != SPCS_S_OK) { 239*fcf3ce44SJohn Forte spcs_log("sndr", &ustatus, 240*fcf3ce44SJohn Forte gettext("%s: status ioctl"), 241*fcf3ce44SJohn Forte program); 242*fcf3ce44SJohn Forte rdc_warn(&ustatus, gettext("status ioctl")); 243*fcf3ce44SJohn Forte continue; 244*fcf3ce44SJohn Forte } 245*fcf3ce44SJohn Forte 246*fcf3ce44SJohn Forte cleanup_hostlist(rdc_info); /* remove non-existent hosts */ 247*fcf3ce44SJohn Forte 248*fcf3ce44SJohn Forte /* 249*fcf3ce44SJohn Forte * Check all enabled sets to see if a new remote host has 250*fcf3ce44SJohn Forte * appeared. 251*fcf3ce44SJohn Forte */ 252*fcf3ce44SJohn Forte for (i = 0; i < rdc_maxsets; i++) { 253*fcf3ce44SJohn Forte if (!(rdc_info->rdc_set[i].flags & RDC_ENABLED)) 254*fcf3ce44SJohn Forte continue; 255*fcf3ce44SJohn Forte /* spawn a new thread for each new host found */ 256*fcf3ce44SJohn Forte if (isnewhost(rdc_info->rdc_set[i].secondary.intf)) { 257*fcf3ce44SJohn Forte /* 258*fcf3ce44SJohn Forte * right now, we could be here before 259*fcf3ce44SJohn Forte * the database did the write for this set 260*fcf3ce44SJohn Forte * I could check the lock on the database 261*fcf3ce44SJohn Forte * but I am just going to give up some time here 262*fcf3ce44SJohn Forte * instead. Why do the allocations etc, etc 263*fcf3ce44SJohn Forte * if the set is enabled in the kernel and not 264*fcf3ce44SJohn Forte * in the config, we know that this set has the 265*fcf3ce44SJohn Forte * lock. Why bother adding more contention to 266*fcf3ce44SJohn Forte * the lock. 267*fcf3ce44SJohn Forte * this is a daemon, afterall. its got time 268*fcf3ce44SJohn Forte */ 269*fcf3ce44SJohn Forte (void) sleep(CFG_WAIT_SLEEP); 270*fcf3ce44SJohn Forte 271*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 272*fcf3ce44SJohn Forte gettext("%s: new host found (%s) starting " 273*fcf3ce44SJohn Forte "its autosync thread"), program, 274*fcf3ce44SJohn Forte rdc_info->rdc_set[i].secondary.intf); 275*fcf3ce44SJohn Forte 276*fcf3ce44SJohn Forte trc = thr_create(NULL, 0, wait_link_down, 277*fcf3ce44SJohn Forte (void *) rdc_info->rdc_set[i].\ 278*fcf3ce44SJohn Forte secondary.intf, THR_BOUND|THR_DETACHED, NULL); 279*fcf3ce44SJohn Forte 280*fcf3ce44SJohn Forte if (trc != 0) { 281*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 282*fcf3ce44SJohn Forte gettext( 283*fcf3ce44SJohn Forte "%s create new autosync " 284*fcf3ce44SJohn Forte "thread failed"), program); 285*fcf3ce44SJohn Forte rdc_warn(NULL, gettext( 286*fcf3ce44SJohn Forte "%s create new autosync " 287*fcf3ce44SJohn Forte "thread failed"), program); 288*fcf3ce44SJohn Forte } 289*fcf3ce44SJohn Forte } 290*fcf3ce44SJohn Forte } 291*fcf3ce44SJohn Forte } 292*fcf3ce44SJohn Forte /* NOTREACHED */ 293*fcf3ce44SJohn Forte } 294*fcf3ce44SJohn Forte 295*fcf3ce44SJohn Forte 296*fcf3ce44SJohn Forte /* 297*fcf3ce44SJohn Forte * The kernel wakes up this function every time it detects the link to the 298*fcf3ce44SJohn Forte * specified host has dropped. 299*fcf3ce44SJohn Forte */ 300*fcf3ce44SJohn Forte void * 301*fcf3ce44SJohn Forte wait_link_down(void *thehost) 302*fcf3ce44SJohn Forte { 303*fcf3ce44SJohn Forte char *host = (char *)thehost; 304*fcf3ce44SJohn Forte char tmphost[MAX_RDC_HOST_SIZE] = { '\0' }; 305*fcf3ce44SJohn Forte spcs_s_info_t ustatus; 306*fcf3ce44SJohn Forte 307*fcf3ce44SJohn Forte if (host) 308*fcf3ce44SJohn Forte strncpy(tmphost, host, MAX_RDC_HOST_SIZE); 309*fcf3ce44SJohn Forte 310*fcf3ce44SJohn Forte ustatus = spcs_s_ucreate(); 311*fcf3ce44SJohn Forte 312*fcf3ce44SJohn Forte /* Never give up */ 313*fcf3ce44SJohn Forte for (;;) { 314*fcf3ce44SJohn Forte #ifdef DEBUG 315*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 316*fcf3ce44SJohn Forte gettext("%s: awaiting link down ioctl for %s"), 317*fcf3ce44SJohn Forte program, host[0] == '\0' ? tmphost : host); 318*fcf3ce44SJohn Forte #endif 319*fcf3ce44SJohn Forte if (RDC_IOCTL(RDC_LINK_DOWN, host, 0, 0, 0, 0, ustatus) 320*fcf3ce44SJohn Forte != SPCS_S_OK) { 321*fcf3ce44SJohn Forte spcs_log("sndr", &ustatus, 322*fcf3ce44SJohn Forte gettext("%s: link down ioctl"), 323*fcf3ce44SJohn Forte program); 324*fcf3ce44SJohn Forte rdc_warn(&ustatus, gettext("link down ioctl")); 325*fcf3ce44SJohn Forte continue; 326*fcf3ce44SJohn Forte } 327*fcf3ce44SJohn Forte #ifdef DEBUG 328*fcf3ce44SJohn Forte 329*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 330*fcf3ce44SJohn Forte gettext("%s: received link down ioctl for %s"), 331*fcf3ce44SJohn Forte program, host[0] == '\0' ? tmphost : host); 332*fcf3ce44SJohn Forte #endif 333*fcf3ce44SJohn Forte rdc_sync(host[0] == '\0' ? tmphost : host); 334*fcf3ce44SJohn Forte } 335*fcf3ce44SJohn Forte /* LINTED */ 336*fcf3ce44SJohn Forte } 337*fcf3ce44SJohn Forte 338*fcf3ce44SJohn Forte 339*fcf3ce44SJohn Forte /* 340*fcf3ce44SJohn Forte * Called when the link to the specified host has dropped. 341*fcf3ce44SJohn Forte * For all Remote Mirror sets using the link that have autosync on, 342*fcf3ce44SJohn Forte * issue rdcadm -u commands until they complete successfully. 343*fcf3ce44SJohn Forte */ 344*fcf3ce44SJohn Forte void 345*fcf3ce44SJohn Forte rdc_sync(char *tohost) 346*fcf3ce44SJohn Forte { 347*fcf3ce44SJohn Forte rdc_set_t *rdc_set = NULL; 348*fcf3ce44SJohn Forte int *sync_done = NULL; 349*fcf3ce44SJohn Forte int sets = 0; 350*fcf3ce44SJohn Forte int syncs_done = 0; 351*fcf3ce44SJohn Forte char cmd[256]; 352*fcf3ce44SJohn Forte rdc_config_t parms = { 0 }; 353*fcf3ce44SJohn Forte spcs_s_info_t ustatus; 354*fcf3ce44SJohn Forte int i; 355*fcf3ce44SJohn Forte int setnumber; 356*fcf3ce44SJohn Forte int numfound = 0; 357*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 358*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 359*fcf3ce44SJohn Forte CFGFILE *cfg = NULL; 360*fcf3ce44SJohn Forte int size; 361*fcf3ce44SJohn Forte int first = 0; 362*fcf3ce44SJohn Forte int death = 0; 363*fcf3ce44SJohn Forte int cfglocked = 0; 364*fcf3ce44SJohn Forte 365*fcf3ce44SJohn Forte ustatus = spcs_s_ucreate(); 366*fcf3ce44SJohn Forte 367*fcf3ce44SJohn Forte size = sizeof (rdc_set_t) * rdc_maxsets; 368*fcf3ce44SJohn Forte rdc_set = malloc(size); 369*fcf3ce44SJohn Forte if (rdc_set == NULL) { 370*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 371*fcf3ce44SJohn Forte gettext("%s: unable to allocate %ld bytes"), 372*fcf3ce44SJohn Forte program, size); 373*fcf3ce44SJohn Forte rdc_warn(NULL, 374*fcf3ce44SJohn Forte gettext("unable to allocate %ld bytes"), size); 375*fcf3ce44SJohn Forte goto done; 376*fcf3ce44SJohn Forte } 377*fcf3ce44SJohn Forte bzero(rdc_set, size); 378*fcf3ce44SJohn Forte size = sizeof (int) * rdc_maxsets; 379*fcf3ce44SJohn Forte sync_done = malloc(size); 380*fcf3ce44SJohn Forte if (sync_done == NULL) { 381*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 382*fcf3ce44SJohn Forte gettext("%s: unable to allocate %ld bytes"), 383*fcf3ce44SJohn Forte program, size); 384*fcf3ce44SJohn Forte rdc_warn(NULL, 385*fcf3ce44SJohn Forte gettext("unable to allocate %ld bytes"), size); 386*fcf3ce44SJohn Forte goto done; 387*fcf3ce44SJohn Forte } 388*fcf3ce44SJohn Forte bzero(sync_done, size); 389*fcf3ce44SJohn Forte 390*fcf3ce44SJohn Forte /* 391*fcf3ce44SJohn Forte * Get all sndr entries with shost matching tohost, and save the 392*fcf3ce44SJohn Forte * details in an array. 393*fcf3ce44SJohn Forte */ 394*fcf3ce44SJohn Forte for (i = 0; i < rdc_maxsets; i++) { 395*fcf3ce44SJohn Forte setnumber = i + 1; 396*fcf3ce44SJohn Forte bzero(buf, sizeof (buf)); 397*fcf3ce44SJohn Forte bzero(key, sizeof (key)); 398*fcf3ce44SJohn Forte 399*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d.shost", 400*fcf3ce44SJohn Forte setnumber); 401*fcf3ce44SJohn Forte 402*fcf3ce44SJohn Forte if (!cfglocked) { 403*fcf3ce44SJohn Forte LOCKCFG(); 404*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) { 405*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 406*fcf3ce44SJohn Forte gettext("%s: error opening config"), 407*fcf3ce44SJohn Forte program); 408*fcf3ce44SJohn Forte 409*fcf3ce44SJohn Forte rdc_warn(NULL, 410*fcf3ce44SJohn Forte gettext("error opening config")); 411*fcf3ce44SJohn Forte UNLOCKCFG(); 412*fcf3ce44SJohn Forte goto done; 413*fcf3ce44SJohn Forte } 414*fcf3ce44SJohn Forte 415*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_RDLOCK)) { 416*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 417*fcf3ce44SJohn Forte gettext("%s: error locking config"), 418*fcf3ce44SJohn Forte program); 419*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("error locking config")); 420*fcf3ce44SJohn Forte goto done; 421*fcf3ce44SJohn Forte } 422*fcf3ce44SJohn Forte } 423*fcf3ce44SJohn Forte 424*fcf3ce44SJohn Forte cfglocked = 1; 425*fcf3ce44SJohn Forte 426*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { 427*fcf3ce44SJohn Forte if (numfound == 0) /* no matching hosts */ 428*fcf3ce44SJohn Forte death = 1; /* thread will exit */ 429*fcf3ce44SJohn Forte break; 430*fcf3ce44SJohn Forte } 431*fcf3ce44SJohn Forte if (strcmp(buf, tohost) != 0) 432*fcf3ce44SJohn Forte continue; 433*fcf3ce44SJohn Forte 434*fcf3ce44SJohn Forte numfound++; 435*fcf3ce44SJohn Forte strncpy(rdc_set[sets].secondary.intf, buf, MAX_RDC_HOST_SIZE); 436*fcf3ce44SJohn Forte 437*fcf3ce44SJohn Forte /* Got a matching entry */ 438*fcf3ce44SJohn Forte 439*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d.phost", 440*fcf3ce44SJohn Forte setnumber); 441*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 442*fcf3ce44SJohn Forte break; 443*fcf3ce44SJohn Forte strncpy(rdc_set[sets].primary.intf, buf, MAX_RDC_HOST_SIZE); 444*fcf3ce44SJohn Forte 445*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d.primary", 446*fcf3ce44SJohn Forte setnumber); 447*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 448*fcf3ce44SJohn Forte break; 449*fcf3ce44SJohn Forte strncpy(rdc_set[sets].primary.file, buf, NSC_MAXPATH); 450*fcf3ce44SJohn Forte 451*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d.secondary", 452*fcf3ce44SJohn Forte setnumber); 453*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 454*fcf3ce44SJohn Forte break; 455*fcf3ce44SJohn Forte strncpy(rdc_set[sets].secondary.file, buf, NSC_MAXPATH); 456*fcf3ce44SJohn Forte 457*fcf3ce44SJohn Forte parms.command = RDC_CMD_STATUS; 458*fcf3ce44SJohn Forte bcopy((void *)(&rdc_set[sets]), (void *)(&parms.rdc_set[0]), 459*fcf3ce44SJohn Forte sizeof (rdc_set_t)); 460*fcf3ce44SJohn Forte 461*fcf3ce44SJohn Forte /* 462*fcf3ce44SJohn Forte * release cfg before diving into the kernel 463*fcf3ce44SJohn Forte * this prevents a possible deadlock when doing 464*fcf3ce44SJohn Forte * a reverse sync whick will wake up the sync_event 465*fcf3ce44SJohn Forte * thread which will try and iiadm -c and hang 466*fcf3ce44SJohn Forte * because we still have the cfg_lock. the timed 467*fcf3ce44SJohn Forte * wait cv in the kernel will fail the sync and things 468*fcf3ce44SJohn Forte * will undeadlock. 469*fcf3ce44SJohn Forte */ 470*fcf3ce44SJohn Forte 471*fcf3ce44SJohn Forte cfg_close(cfg); 472*fcf3ce44SJohn Forte cfg = NULL; 473*fcf3ce44SJohn Forte cfglocked = 0; 474*fcf3ce44SJohn Forte UNLOCKCFG(); 475*fcf3ce44SJohn Forte 476*fcf3ce44SJohn Forte if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus) < 0) { 477*fcf3ce44SJohn Forte continue; 478*fcf3ce44SJohn Forte } 479*fcf3ce44SJohn Forte if ((parms.rdc_set[0].autosync == 0) || 480*fcf3ce44SJohn Forte (!(parms.rdc_set[0].flags & RDC_LOGGING))) { 481*fcf3ce44SJohn Forte continue; 482*fcf3ce44SJohn Forte } 483*fcf3ce44SJohn Forte 484*fcf3ce44SJohn Forte /* Found a suitable set with autosync on, in logging mode */ 485*fcf3ce44SJohn Forte sets++; 486*fcf3ce44SJohn Forte } 487*fcf3ce44SJohn Forte 488*fcf3ce44SJohn Forte if (cfg) { 489*fcf3ce44SJohn Forte cfg_close(cfg); 490*fcf3ce44SJohn Forte cfg = NULL; 491*fcf3ce44SJohn Forte UNLOCKCFG(); 492*fcf3ce44SJohn Forte } 493*fcf3ce44SJohn Forte 494*fcf3ce44SJohn Forte if (sets == 0) { 495*fcf3ce44SJohn Forte #ifdef DEBUG 496*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 497*fcf3ce44SJohn Forte gettext("%s: no sets requiring autosync found for %s"), 498*fcf3ce44SJohn Forte program, tohost); 499*fcf3ce44SJohn Forte #endif 500*fcf3ce44SJohn Forte if (death) { 501*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 502*fcf3ce44SJohn Forte gettext("%s: autosync thread stopping for %s " 503*fcf3ce44SJohn Forte "(host deconfigured)"), program, tohost); 504*fcf3ce44SJohn Forte } 505*fcf3ce44SJohn Forte goto done; 506*fcf3ce44SJohn Forte } 507*fcf3ce44SJohn Forte 508*fcf3ce44SJohn Forte /* Keep issuing rdcadm -u commands until they have all completed */ 509*fcf3ce44SJohn Forte for (;;) { 510*fcf3ce44SJohn Forte if (!first) 511*fcf3ce44SJohn Forte first++; 512*fcf3ce44SJohn Forte else 513*fcf3ce44SJohn Forte (void) sleep(RESYNC_SLEEP); 514*fcf3ce44SJohn Forte 515*fcf3ce44SJohn Forte /* Issue rdcadm -u commands for all remaining sets */ 516*fcf3ce44SJohn Forte for (i = 0; i < sets; i++) { 517*fcf3ce44SJohn Forte if (sync_done[i]) 518*fcf3ce44SJohn Forte continue; 519*fcf3ce44SJohn Forte 520*fcf3ce44SJohn Forte /* 521*fcf3ce44SJohn Forte * Need to check if autosync was turned off for a set 522*fcf3ce44SJohn Forte * while we were sleeping. We could have the case where 523*fcf3ce44SJohn Forte * an update sync failed and autosync was disabled 524*fcf3ce44SJohn Forte * while we were sleeping and didn't detect the disable. 525*fcf3ce44SJohn Forte * See BugID 4814213. 526*fcf3ce44SJohn Forte */ 527*fcf3ce44SJohn Forte parms.command = RDC_CMD_STATUS; 528*fcf3ce44SJohn Forte bcopy((void *)(&rdc_set[i]), 529*fcf3ce44SJohn Forte (void *)(&parms.rdc_set[0]), sizeof (rdc_set_t)); 530*fcf3ce44SJohn Forte if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, 531*fcf3ce44SJohn Forte ustatus) < 0) { 532*fcf3ce44SJohn Forte spcs_log("sndr", &ustatus, gettext("%s: " 533*fcf3ce44SJohn Forte "status not available for %s:%s, stopping " 534*fcf3ce44SJohn Forte "this autosync attempt"), program, tohost, 535*fcf3ce44SJohn Forte rdc_set[i].secondary.file); 536*fcf3ce44SJohn Forte sync_done[i] = 1; 537*fcf3ce44SJohn Forte syncs_done++; 538*fcf3ce44SJohn Forte continue; 539*fcf3ce44SJohn Forte } 540*fcf3ce44SJohn Forte if (!(parms.rdc_set[0].autosync)) { 541*fcf3ce44SJohn Forte #ifdef DEBUG 542*fcf3ce44SJohn Forte spcs_log("sndr", NULL, gettext("%s: autosync disabled during sleep, " 543*fcf3ce44SJohn Forte "stopping attempt for set %s:%s"), program, tohost, 544*fcf3ce44SJohn Forte rdc_set[i].secondary.file); 545*fcf3ce44SJohn Forte #endif 546*fcf3ce44SJohn Forte sync_done[i] = 1; 547*fcf3ce44SJohn Forte syncs_done++; 548*fcf3ce44SJohn Forte continue; 549*fcf3ce44SJohn Forte } 550*fcf3ce44SJohn Forte 551*fcf3ce44SJohn Forte (void) sprintf(cmd, "%s -un %s:%s", RDCADM, tohost, 552*fcf3ce44SJohn Forte rdc_set[i].secondary.file); 553*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 554*fcf3ce44SJohn Forte gettext("%s: issuing update sync for %s:%s"), 555*fcf3ce44SJohn Forte program, tohost, rdc_set[i].secondary.file); 556*fcf3ce44SJohn Forte (void) system(cmd); 557*fcf3ce44SJohn Forte } 558*fcf3ce44SJohn Forte 559*fcf3ce44SJohn Forte /* Issue rdcadm -w commands to wait for updates to finish */ 560*fcf3ce44SJohn Forte for (i = 0; i < sets; i++) { 561*fcf3ce44SJohn Forte if (sync_done[i]) 562*fcf3ce44SJohn Forte continue; 563*fcf3ce44SJohn Forte 564*fcf3ce44SJohn Forte (void) sprintf(cmd, "%s -wn %s:%s", RDCADM, tohost, 565*fcf3ce44SJohn Forte rdc_set[i].secondary.file); 566*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 567*fcf3ce44SJohn Forte gettext("%s: issuing wait for %s:%s"), 568*fcf3ce44SJohn Forte program, tohost, rdc_set[i].secondary.file); 569*fcf3ce44SJohn Forte 570*fcf3ce44SJohn Forte (void) system(cmd); 571*fcf3ce44SJohn Forte 572*fcf3ce44SJohn Forte parms.command = RDC_CMD_STATUS; 573*fcf3ce44SJohn Forte bcopy((void *)(&rdc_set[i]), 574*fcf3ce44SJohn Forte (void *)(&parms.rdc_set[0]), sizeof (rdc_set_t)); 575*fcf3ce44SJohn Forte 576*fcf3ce44SJohn Forte if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, 577*fcf3ce44SJohn Forte ustatus) < 0) { 578*fcf3ce44SJohn Forte spcs_log("sndr", &ustatus, 579*fcf3ce44SJohn Forte gettext("%s: status not available for " 580*fcf3ce44SJohn Forte "%s:%s, stopping this autosync attempt"), 581*fcf3ce44SJohn Forte program, tohost, rdc_set[i].secondary.file); 582*fcf3ce44SJohn Forte sync_done[i] = 1; 583*fcf3ce44SJohn Forte syncs_done++; 584*fcf3ce44SJohn Forte continue; 585*fcf3ce44SJohn Forte } 586*fcf3ce44SJohn Forte /* Check if completed OK, failed or autosync off */ 587*fcf3ce44SJohn Forte if (!(parms.rdc_set[0].autosync) || 588*fcf3ce44SJohn Forte !(parms.rdc_set[0].flags & RDC_LOGGING) && 589*fcf3ce44SJohn Forte !(parms.rdc_set[0].flags & RDC_SYNCING)) { 590*fcf3ce44SJohn Forte sync_done[i] = 1; 591*fcf3ce44SJohn Forte syncs_done++; 592*fcf3ce44SJohn Forte } 593*fcf3ce44SJohn Forte } 594*fcf3ce44SJohn Forte 595*fcf3ce44SJohn Forte if (syncs_done == sets) 596*fcf3ce44SJohn Forte break; /* All completed OK */ 597*fcf3ce44SJohn Forte } 598*fcf3ce44SJohn Forte 599*fcf3ce44SJohn Forte done: 600*fcf3ce44SJohn Forte if (cfg) { 601*fcf3ce44SJohn Forte cfg_close(cfg); 602*fcf3ce44SJohn Forte UNLOCKCFG(); 603*fcf3ce44SJohn Forte } 604*fcf3ce44SJohn Forte spcs_s_ufree(&ustatus); 605*fcf3ce44SJohn Forte if (sync_done) 606*fcf3ce44SJohn Forte free(sync_done); 607*fcf3ce44SJohn Forte if (rdc_set) 608*fcf3ce44SJohn Forte free(rdc_set); 609*fcf3ce44SJohn Forte if (death) { /* bye bye */ 610*fcf3ce44SJohn Forte /* 611*fcf3ce44SJohn Forte * if perhaps we lost some race, lets remove this entry from 612*fcf3ce44SJohn Forte * the list. Then, if something did go wrong, and we did kill 613*fcf3ce44SJohn Forte * a valid thread, it will be detected on the next go around 614*fcf3ce44SJohn Forte * of the thread who is looking for new hosts to spawn threads 615*fcf3ce44SJohn Forte */ 616*fcf3ce44SJohn Forte 617*fcf3ce44SJohn Forte remove_from_hostlist(tohost); 618*fcf3ce44SJohn Forte thr_exit(0); 619*fcf3ce44SJohn Forte } 620*fcf3ce44SJohn Forte 621*fcf3ce44SJohn Forte (void) sleep(RESYNC_SLEEP); 622*fcf3ce44SJohn Forte } 623*fcf3ce44SJohn Forte 624*fcf3ce44SJohn Forte /* 625*fcf3ce44SJohn Forte * Wait for notification by the kernel of a sync start or a sync completed OK 626*fcf3ce44SJohn Forte */ 627*fcf3ce44SJohn Forte void * 628*fcf3ce44SJohn Forte wait_sync_event() 629*fcf3ce44SJohn Forte { 630*fcf3ce44SJohn Forte spcs_s_info_t ustatus; 631*fcf3ce44SJohn Forte char master[NSC_MAXPATH]; 632*fcf3ce44SJohn Forte char group[NSC_MAXPATH]; 633*fcf3ce44SJohn Forte int state; 634*fcf3ce44SJohn Forte 635*fcf3ce44SJohn Forte ustatus = spcs_s_ucreate(); 636*fcf3ce44SJohn Forte 637*fcf3ce44SJohn Forte master[0] = '\0'; 638*fcf3ce44SJohn Forte group[0] = '\0'; 639*fcf3ce44SJohn Forte 640*fcf3ce44SJohn Forte /* Never give up */ 641*fcf3ce44SJohn Forte for (;;) { 642*fcf3ce44SJohn Forte /* Kernel tells us which volume and group the event is for */ 643*fcf3ce44SJohn Forte state = RDC_IOCTL(RDC_SYNC_EVENT, master, group, 0, 0, 0, 644*fcf3ce44SJohn Forte ustatus); 645*fcf3ce44SJohn Forte if (state < SPCS_S_OK) { 646*fcf3ce44SJohn Forte if (errno != EAGAIN) { 647*fcf3ce44SJohn Forte spcs_log("sndr", &ustatus, 648*fcf3ce44SJohn Forte gettext("%s: update ioctl"), 649*fcf3ce44SJohn Forte program); 650*fcf3ce44SJohn Forte rdc_warn(&ustatus, gettext("update ioctl")); 651*fcf3ce44SJohn Forte continue; 652*fcf3ce44SJohn Forte } 653*fcf3ce44SJohn Forte master[0] = '\0'; 654*fcf3ce44SJohn Forte continue; 655*fcf3ce44SJohn Forte } 656*fcf3ce44SJohn Forte 657*fcf3ce44SJohn Forte /* 658*fcf3ce44SJohn Forte * If target is mounted at the start of a sync or reverse sync, 659*fcf3ce44SJohn Forte * return a negative ack. 660*fcf3ce44SJohn Forte */ 661*fcf3ce44SJohn Forte if ((state == RDC_SYNC_START || state == RDC_RSYNC_START) && 662*fcf3ce44SJohn Forte mounted(master)) { 663*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 664*fcf3ce44SJohn Forte gettext("%s: %s has a file system mounted"), 665*fcf3ce44SJohn Forte program, master); 666*fcf3ce44SJohn Forte rdc_warn(NULL, 667*fcf3ce44SJohn Forte gettext("%s has a file system mounted"), 668*fcf3ce44SJohn Forte master); 669*fcf3ce44SJohn Forte master[0] = '\0'; /* negative ack */ 670*fcf3ce44SJohn Forte continue; 671*fcf3ce44SJohn Forte } 672*fcf3ce44SJohn Forte 673*fcf3ce44SJohn Forte switch (state) { 674*fcf3ce44SJohn Forte case RDC_SYNC_START: 675*fcf3ce44SJohn Forte if (group[0]) 676*fcf3ce44SJohn Forte group_start(group); 677*fcf3ce44SJohn Forte else 678*fcf3ce44SJohn Forte sync_start(master); 679*fcf3ce44SJohn Forte break; 680*fcf3ce44SJohn Forte 681*fcf3ce44SJohn Forte case RDC_SYNC_DONE: 682*fcf3ce44SJohn Forte if (group[0]) 683*fcf3ce44SJohn Forte group_complete(group); 684*fcf3ce44SJohn Forte else 685*fcf3ce44SJohn Forte sync_complete(master); 686*fcf3ce44SJohn Forte break; 687*fcf3ce44SJohn Forte 688*fcf3ce44SJohn Forte default: 689*fcf3ce44SJohn Forte break; 690*fcf3ce44SJohn Forte } 691*fcf3ce44SJohn Forte } 692*fcf3ce44SJohn Forte /* LINTED */ 693*fcf3ce44SJohn Forte } 694*fcf3ce44SJohn Forte 695*fcf3ce44SJohn Forte 696*fcf3ce44SJohn Forte /* 697*fcf3ce44SJohn Forte * A sync has completed OK to a volume not belonging to a group. 698*fcf3ce44SJohn Forte * Set the state of the ndr_ii config entry to "update". 699*fcf3ce44SJohn Forte */ 700*fcf3ce44SJohn Forte void 701*fcf3ce44SJohn Forte sync_complete(char *master) 702*fcf3ce44SJohn Forte { 703*fcf3ce44SJohn Forte CFGFILE *cfg = NULL; 704*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 705*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 706*fcf3ce44SJohn Forte int i; 707*fcf3ce44SJohn Forte int setnumber; 708*fcf3ce44SJohn Forte int sev; 709*fcf3ce44SJohn Forte 710*fcf3ce44SJohn Forte LOCKCFG(); 711*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) { 712*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 713*fcf3ce44SJohn Forte gettext("%s: error opening config"), 714*fcf3ce44SJohn Forte program); 715*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("error opening config")); 716*fcf3ce44SJohn Forte UNLOCKCFG(); 717*fcf3ce44SJohn Forte return; 718*fcf3ce44SJohn Forte } 719*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_WRLOCK)) { 720*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 721*fcf3ce44SJohn Forte gettext("%s: error locking config"), 722*fcf3ce44SJohn Forte program); 723*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("error locking config")); 724*fcf3ce44SJohn Forte cfg_close(cfg); 725*fcf3ce44SJohn Forte UNLOCKCFG(); 726*fcf3ce44SJohn Forte return; 727*fcf3ce44SJohn Forte } 728*fcf3ce44SJohn Forte 729*fcf3ce44SJohn Forte /* get ndr_ii entries until a match is found */ 730*fcf3ce44SJohn Forte for (i = 0; ; i++) { 731*fcf3ce44SJohn Forte setnumber = i + 1; 732*fcf3ce44SJohn Forte 733*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary", 734*fcf3ce44SJohn Forte setnumber); 735*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 736*fcf3ce44SJohn Forte break; 737*fcf3ce44SJohn Forte if (strcmp(buf, master) != 0) 738*fcf3ce44SJohn Forte continue; 739*fcf3ce44SJohn Forte 740*fcf3ce44SJohn Forte /* Found the matching entry */ 741*fcf3ce44SJohn Forte 742*fcf3ce44SJohn Forte /* 743*fcf3ce44SJohn Forte * Set state to "update" so that starting another sync will 744*fcf3ce44SJohn Forte * cause a new Point-in-Time Copy snapshot to be taken. 745*fcf3ce44SJohn Forte */ 746*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state", 747*fcf3ce44SJohn Forte setnumber); 748*fcf3ce44SJohn Forte if ((cfg_put_cstring(cfg, key, UPDATE, strlen(UPDATE)) < 0) || 749*fcf3ce44SJohn Forte (cfg_commit(cfg) < 0)) { 750*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 751*fcf3ce44SJohn Forte gettext("%s: unable to update \"%s\" " 752*fcf3ce44SJohn Forte "in configuration storage: %s"), 753*fcf3ce44SJohn Forte program, buf, cfg_error(&sev)); 754*fcf3ce44SJohn Forte rdc_warn(NULL, 755*fcf3ce44SJohn Forte gettext("unable to update \"%s\" " 756*fcf3ce44SJohn Forte "in configuration storage: %s"), 757*fcf3ce44SJohn Forte buf, cfg_error(&sev)); 758*fcf3ce44SJohn Forte } 759*fcf3ce44SJohn Forte break; 760*fcf3ce44SJohn Forte } 761*fcf3ce44SJohn Forte 762*fcf3ce44SJohn Forte cfg_close(cfg); 763*fcf3ce44SJohn Forte UNLOCKCFG(); 764*fcf3ce44SJohn Forte } 765*fcf3ce44SJohn Forte 766*fcf3ce44SJohn Forte 767*fcf3ce44SJohn Forte /* 768*fcf3ce44SJohn Forte * Starting a sync to the specified master volume. 769*fcf3ce44SJohn Forte * Check the ndr_ii config entries to see if a Point-in-Time Copy 770*fcf3ce44SJohn Forte * snapshot should be taken. 771*fcf3ce44SJohn Forte */ 772*fcf3ce44SJohn Forte void 773*fcf3ce44SJohn Forte sync_start(char *master) 774*fcf3ce44SJohn Forte { 775*fcf3ce44SJohn Forte char cmd[256]; 776*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 777*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 778*fcf3ce44SJohn Forte CFGFILE *cfg = NULL; 779*fcf3ce44SJohn Forte int i; 780*fcf3ce44SJohn Forte int setnumber; 781*fcf3ce44SJohn Forte int found; 782*fcf3ce44SJohn Forte int sev; 783*fcf3ce44SJohn Forte char shadow[NSC_MAXPATH]; 784*fcf3ce44SJohn Forte char bitmap[NSC_MAXPATH]; 785*fcf3ce44SJohn Forte char *ctag = NULL; 786*fcf3ce44SJohn Forte 787*fcf3ce44SJohn Forte LOCKCFG(); 788*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) { 789*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 790*fcf3ce44SJohn Forte gettext("%s: error opening config"), 791*fcf3ce44SJohn Forte program); 792*fcf3ce44SJohn Forte rdc_warn(NULL, 793*fcf3ce44SJohn Forte gettext("error opening config")); 794*fcf3ce44SJohn Forte UNLOCKCFG(); 795*fcf3ce44SJohn Forte return; 796*fcf3ce44SJohn Forte } 797*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_RDLOCK)) { 798*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 799*fcf3ce44SJohn Forte gettext("%s: error locking config"), 800*fcf3ce44SJohn Forte program); 801*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("error locking config")); 802*fcf3ce44SJohn Forte cfg_close(cfg); 803*fcf3ce44SJohn Forte UNLOCKCFG(); 804*fcf3ce44SJohn Forte return; 805*fcf3ce44SJohn Forte } 806*fcf3ce44SJohn Forte 807*fcf3ce44SJohn Forte found = 0; 808*fcf3ce44SJohn Forte /* get ndr_ii entries until a match is found */ 809*fcf3ce44SJohn Forte for (i = 0; ; i++) { 810*fcf3ce44SJohn Forte setnumber = i + 1; 811*fcf3ce44SJohn Forte 812*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary", 813*fcf3ce44SJohn Forte setnumber); 814*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 815*fcf3ce44SJohn Forte break; 816*fcf3ce44SJohn Forte if (strcmp(buf, master) != 0) 817*fcf3ce44SJohn Forte continue; 818*fcf3ce44SJohn Forte 819*fcf3ce44SJohn Forte /* Got a matching entry */ 820*fcf3ce44SJohn Forte 821*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ndr_ii.set%d.shadow", 822*fcf3ce44SJohn Forte setnumber); 823*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 824*fcf3ce44SJohn Forte break; 825*fcf3ce44SJohn Forte strncpy(shadow, buf, NSC_MAXPATH); 826*fcf3ce44SJohn Forte 827*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ndr_ii.set%d.bitmap", 828*fcf3ce44SJohn Forte setnumber); 829*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 830*fcf3ce44SJohn Forte break; 831*fcf3ce44SJohn Forte strncpy(bitmap, buf, NSC_MAXPATH); 832*fcf3ce44SJohn Forte 833*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state", 834*fcf3ce44SJohn Forte setnumber); 835*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 836*fcf3ce44SJohn Forte break; 837*fcf3ce44SJohn Forte 838*fcf3ce44SJohn Forte /* 839*fcf3ce44SJohn Forte * If an PIT snapshot has already been taken, and syncing did 840*fcf3ce44SJohn Forte * not complete, the state will be "noupdate", to indicate we 841*fcf3ce44SJohn Forte * should not take another one at this point. 842*fcf3ce44SJohn Forte */ 843*fcf3ce44SJohn Forte if (strcmp(buf, NOUPDATE) != 0) 844*fcf3ce44SJohn Forte found = 1; 845*fcf3ce44SJohn Forte 846*fcf3ce44SJohn Forte break; 847*fcf3ce44SJohn Forte } 848*fcf3ce44SJohn Forte 849*fcf3ce44SJohn Forte if (!found) { 850*fcf3ce44SJohn Forte cfg_close(cfg); 851*fcf3ce44SJohn Forte UNLOCKCFG(); 852*fcf3ce44SJohn Forte return; 853*fcf3ce44SJohn Forte } 854*fcf3ce44SJohn Forte 855*fcf3ce44SJohn Forte found = 0; 856*fcf3ce44SJohn Forte /* get ii entries until a match is found */ 857*fcf3ce44SJohn Forte for (i = 0; ; i++) { 858*fcf3ce44SJohn Forte setnumber = i + 1; 859*fcf3ce44SJohn Forte 860*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ii.set%d.shadow", 861*fcf3ce44SJohn Forte setnumber); 862*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 863*fcf3ce44SJohn Forte break; 864*fcf3ce44SJohn Forte if (strcmp(buf, shadow) != 0) 865*fcf3ce44SJohn Forte continue; 866*fcf3ce44SJohn Forte 867*fcf3ce44SJohn Forte /* Matching shadow found, so ii already enabled */ 868*fcf3ce44SJohn Forte found = 1; 869*fcf3ce44SJohn Forte break; 870*fcf3ce44SJohn Forte } 871*fcf3ce44SJohn Forte 872*fcf3ce44SJohn Forte if (found) { 873*fcf3ce44SJohn Forte /* Already PIT enabled, so just take a snapshot */ 874*fcf3ce44SJohn Forte 875*fcf3ce44SJohn Forte /* Get cluster tag of matching entry */ 876*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ii.set%d.cnode", setnumber); 877*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) >= 0) 878*fcf3ce44SJohn Forte if ((strlen(buf) == 0) || (buf[0] == '-')) 879*fcf3ce44SJohn Forte ctag = "-C local"; 880*fcf3ce44SJohn Forte else 881*fcf3ce44SJohn Forte ctag = ""; 882*fcf3ce44SJohn Forte (void) sprintf(cmd, "%s %s -u s %s", IIADM, ctag, shadow); 883*fcf3ce44SJohn Forte } else { 884*fcf3ce44SJohn Forte /* 885*fcf3ce44SJohn Forte * If clustered, need to enable PIT Copy sets in the same 886*fcf3ce44SJohn Forte * cluster as the Remote Mirror set 887*fcf3ce44SJohn Forte */ 888*fcf3ce44SJohn Forte 889*fcf3ce44SJohn Forte if (clustered) { 890*fcf3ce44SJohn Forte /* Find a RM set with master as the local volume */ 891*fcf3ce44SJohn Forte 892*fcf3ce44SJohn Forte for (i = 0; i < rdc_maxsets; i++) { 893*fcf3ce44SJohn Forte setnumber = i + 1; 894*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 895*fcf3ce44SJohn Forte "sndr.set%d.phost", setnumber); 896*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, 897*fcf3ce44SJohn Forte CFG_MAX_BUF) < 0) 898*fcf3ce44SJohn Forte break; 899*fcf3ce44SJohn Forte 900*fcf3ce44SJohn Forte if (self_check(buf)) 901*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 902*fcf3ce44SJohn Forte "sndr.set%d.primary", setnumber); 903*fcf3ce44SJohn Forte else 904*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 905*fcf3ce44SJohn Forte "sndr.set%d.secondary", setnumber); 906*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, 907*fcf3ce44SJohn Forte CFG_MAX_BUF) < 0) 908*fcf3ce44SJohn Forte break; 909*fcf3ce44SJohn Forte 910*fcf3ce44SJohn Forte if (strcmp(buf, master) != 0) 911*fcf3ce44SJohn Forte continue; 912*fcf3ce44SJohn Forte 913*fcf3ce44SJohn Forte /* Get cluster tag of matching entry */ 914*fcf3ce44SJohn Forte 915*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 916*fcf3ce44SJohn Forte "sndr.set%d.cnode", setnumber); 917*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, 918*fcf3ce44SJohn Forte CFG_MAX_BUF) < 0) 919*fcf3ce44SJohn Forte break; 920*fcf3ce44SJohn Forte if ((strlen(buf) == 0) || (buf[0] == '-')) 921*fcf3ce44SJohn Forte ctag = strdup("local"); 922*fcf3ce44SJohn Forte else 923*fcf3ce44SJohn Forte ctag = strdup(buf); 924*fcf3ce44SJohn Forte break; 925*fcf3ce44SJohn Forte } 926*fcf3ce44SJohn Forte } 927*fcf3ce44SJohn Forte 928*fcf3ce44SJohn Forte /* Not already enabled, so enable a dependent */ 929*fcf3ce44SJohn Forte if (ctag) { 930*fcf3ce44SJohn Forte (void) sprintf(cmd, "%s -C %s -e dep %s %s %s", IIADM, 931*fcf3ce44SJohn Forte ctag, master, shadow, bitmap); 932*fcf3ce44SJohn Forte free(ctag); 933*fcf3ce44SJohn Forte } else 934*fcf3ce44SJohn Forte (void) sprintf(cmd, "%s -e dep %s %s %s", IIADM, master, 935*fcf3ce44SJohn Forte shadow, bitmap); 936*fcf3ce44SJohn Forte } 937*fcf3ce44SJohn Forte 938*fcf3ce44SJohn Forte cfg_close(cfg); 939*fcf3ce44SJohn Forte 940*fcf3ce44SJohn Forte if (system(cmd) != 0) { 941*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 942*fcf3ce44SJohn Forte gettext("Point-in-Time Copy snapshot failed for %s %s %s." 943*fcf3ce44SJohn Forte " Please check validity of ndr_ii entry"), 944*fcf3ce44SJohn Forte master, shadow, bitmap); 945*fcf3ce44SJohn Forte cfg_close(cfg); 946*fcf3ce44SJohn Forte UNLOCKCFG(); 947*fcf3ce44SJohn Forte return; 948*fcf3ce44SJohn Forte } 949*fcf3ce44SJohn Forte 950*fcf3ce44SJohn Forte /* 951*fcf3ce44SJohn Forte * PIT Copy enable or update was fine, so update the ndr_ii entry 952*fcf3ce44SJohn Forte * to "noupdate", to prevent invalid point in time copies. 953*fcf3ce44SJohn Forte */ 954*fcf3ce44SJohn Forte 955*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) { 956*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 957*fcf3ce44SJohn Forte gettext("%s: error opening config"), 958*fcf3ce44SJohn Forte program); 959*fcf3ce44SJohn Forte rdc_warn(NULL, 960*fcf3ce44SJohn Forte gettext("error opening config")); 961*fcf3ce44SJohn Forte UNLOCKCFG(); 962*fcf3ce44SJohn Forte return; 963*fcf3ce44SJohn Forte } 964*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_WRLOCK)) { 965*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 966*fcf3ce44SJohn Forte gettext("%s: error locking config"), 967*fcf3ce44SJohn Forte program); 968*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("error locking config")); 969*fcf3ce44SJohn Forte cfg_close(cfg); 970*fcf3ce44SJohn Forte UNLOCKCFG(); 971*fcf3ce44SJohn Forte return; 972*fcf3ce44SJohn Forte } 973*fcf3ce44SJohn Forte 974*fcf3ce44SJohn Forte /* get ndr_ii entries until a match is found */ 975*fcf3ce44SJohn Forte for (i = 0; ; i++) { 976*fcf3ce44SJohn Forte setnumber = i + 1; 977*fcf3ce44SJohn Forte 978*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ndr_ii.set%d.shadow", 979*fcf3ce44SJohn Forte setnumber); 980*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 981*fcf3ce44SJohn Forte break; 982*fcf3ce44SJohn Forte if (strcmp(buf, shadow) != 0) 983*fcf3ce44SJohn Forte continue; 984*fcf3ce44SJohn Forte 985*fcf3ce44SJohn Forte /* Found the matching entry */ 986*fcf3ce44SJohn Forte 987*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state", 988*fcf3ce44SJohn Forte setnumber); 989*fcf3ce44SJohn Forte if ((cfg_put_cstring(cfg, key, NOUPDATE, 990*fcf3ce44SJohn Forte strlen(NOUPDATE)) < 0) || (cfg_commit(cfg) < 0)) { 991*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 992*fcf3ce44SJohn Forte gettext("%s: unable to update \"%s\" " 993*fcf3ce44SJohn Forte "in configuration storage: %s"), 994*fcf3ce44SJohn Forte program, buf, cfg_error(&sev)); 995*fcf3ce44SJohn Forte rdc_warn(NULL, 996*fcf3ce44SJohn Forte gettext("unable to update \"%s\" " 997*fcf3ce44SJohn Forte "in configuration storage: %s"), 998*fcf3ce44SJohn Forte buf, cfg_error(&sev)); 999*fcf3ce44SJohn Forte } 1000*fcf3ce44SJohn Forte break; 1001*fcf3ce44SJohn Forte } 1002*fcf3ce44SJohn Forte cfg_close(cfg); 1003*fcf3ce44SJohn Forte UNLOCKCFG(); 1004*fcf3ce44SJohn Forte } 1005*fcf3ce44SJohn Forte 1006*fcf3ce44SJohn Forte void 1007*fcf3ce44SJohn Forte cleanup_hostlist(rdc_status_t *rdc_info) 1008*fcf3ce44SJohn Forte { 1009*fcf3ce44SJohn Forte int i, j, k; 1010*fcf3ce44SJohn Forte char *host, *exhost; 1011*fcf3ce44SJohn Forte 1012*fcf3ce44SJohn Forte 1013*fcf3ce44SJohn Forte (void) mutex_lock(&host_list->hosts_mutex); 1014*fcf3ce44SJohn Forte for (i = 0; i < host_list->numhosts; i++) { 1015*fcf3ce44SJohn Forte int found = 0; 1016*fcf3ce44SJohn Forte for (j = 0; (j < rdc_maxsets) && !found; j++) { 1017*fcf3ce44SJohn Forte if (!rdc_info->rdc_set[j].flags & RDC_ENABLED) 1018*fcf3ce44SJohn Forte continue; 1019*fcf3ce44SJohn Forte if ((!host_list->configured[i]) || 1020*fcf3ce44SJohn Forte (host_list->hosts[i] == '\0')) { 1021*fcf3ce44SJohn Forte (void) mutex_unlock(&host_list->hosts_mutex); 1022*fcf3ce44SJohn Forte return; 1023*fcf3ce44SJohn Forte } 1024*fcf3ce44SJohn Forte 1025*fcf3ce44SJohn Forte host = rdc_info->rdc_set[j].secondary.intf; 1026*fcf3ce44SJohn Forte if (strcmp(host_list->hosts[i], host) == 0) 1027*fcf3ce44SJohn Forte found++; 1028*fcf3ce44SJohn Forte } 1029*fcf3ce44SJohn Forte if (j == rdc_maxsets) { 1030*fcf3ce44SJohn Forte /* 1031*fcf3ce44SJohn Forte * this set is not in the kernel, so remove from list 1032*fcf3ce44SJohn Forte */ 1033*fcf3ce44SJohn Forte exhost = host_list->hosts[i]; 1034*fcf3ce44SJohn Forte if (exhost) { 1035*fcf3ce44SJohn Forte free(exhost); 1036*fcf3ce44SJohn Forte exhost = NULL; 1037*fcf3ce44SJohn Forte } 1038*fcf3ce44SJohn Forte 1039*fcf3ce44SJohn Forte k = i; 1040*fcf3ce44SJohn Forte while (k < host_list->numhosts) { 1041*fcf3ce44SJohn Forte host_list->hosts[k] = k < host_list->numhosts - 1 ? 1042*fcf3ce44SJohn Forte host_list->hosts[k+1] : NULL; 1043*fcf3ce44SJohn Forte k++; 1044*fcf3ce44SJohn Forte } 1045*fcf3ce44SJohn Forte host_list->numhosts--; 1046*fcf3ce44SJohn Forte 1047*fcf3ce44SJohn Forte bcopy(&host_list->configured[i+1], 1048*fcf3ce44SJohn Forte &host_list->configured[i], 1049*fcf3ce44SJohn Forte (MAXHOSTS - i + 1) * sizeof (int)); 1050*fcf3ce44SJohn Forte host_list->configured[MAXHOSTS - 1] = 0; 1051*fcf3ce44SJohn Forte } 1052*fcf3ce44SJohn Forte } 1053*fcf3ce44SJohn Forte (void) mutex_unlock(&host_list->hosts_mutex); 1054*fcf3ce44SJohn Forte } 1055*fcf3ce44SJohn Forte 1056*fcf3ce44SJohn Forte /* 1057*fcf3ce44SJohn Forte * explicity remove a host from the host list 1058*fcf3ce44SJohn Forte * also update the configured array 1059*fcf3ce44SJohn Forte * called in rdc_sync, just before exiting a thread. 1060*fcf3ce44SJohn Forte */ 1061*fcf3ce44SJohn Forte void 1062*fcf3ce44SJohn Forte remove_from_hostlist(char *host) 1063*fcf3ce44SJohn Forte { 1064*fcf3ce44SJohn Forte int i, k; 1065*fcf3ce44SJohn Forte char *exhost; 1066*fcf3ce44SJohn Forte 1067*fcf3ce44SJohn Forte /* why bother? */ 1068*fcf3ce44SJohn Forte if ((!host) || (host[0] == '\0')) 1069*fcf3ce44SJohn Forte return; 1070*fcf3ce44SJohn Forte 1071*fcf3ce44SJohn Forte (void) mutex_lock(&host_list->hosts_mutex); 1072*fcf3ce44SJohn Forte for (i = 0; i < host_list->numhosts; i++) { 1073*fcf3ce44SJohn Forte if (strcmp(host, host_list->hosts[i]) == 0) { /* found it */ 1074*fcf3ce44SJohn Forte exhost = host_list->hosts[i]; 1075*fcf3ce44SJohn Forte if (exhost) { 1076*fcf3ce44SJohn Forte free(exhost); 1077*fcf3ce44SJohn Forte exhost = NULL; 1078*fcf3ce44SJohn Forte } 1079*fcf3ce44SJohn Forte k = i; 1080*fcf3ce44SJohn Forte while (k < host_list->numhosts) { 1081*fcf3ce44SJohn Forte host_list->hosts[k] = k < host_list->numhosts - 1 ? 1082*fcf3ce44SJohn Forte host_list->hosts[k+1] : NULL; 1083*fcf3ce44SJohn Forte k++; 1084*fcf3ce44SJohn Forte } 1085*fcf3ce44SJohn Forte host_list->numhosts--; 1086*fcf3ce44SJohn Forte bcopy(&host_list->configured[i+1], 1087*fcf3ce44SJohn Forte &host_list->configured[i], 1088*fcf3ce44SJohn Forte (MAXHOSTS - i + 1) * sizeof (int)); 1089*fcf3ce44SJohn Forte host_list->configured[MAXHOSTS - 1] = 0; 1090*fcf3ce44SJohn Forte } 1091*fcf3ce44SJohn Forte 1092*fcf3ce44SJohn Forte } 1093*fcf3ce44SJohn Forte (void) mutex_unlock(&host_list->hosts_mutex); 1094*fcf3ce44SJohn Forte } 1095*fcf3ce44SJohn Forte /* 1096*fcf3ce44SJohn Forte * Check to see if this host isn't in our list, so needs a new rdcsyncd proc 1097*fcf3ce44SJohn Forte */ 1098*fcf3ce44SJohn Forte int 1099*fcf3ce44SJohn Forte isnewhost(char *host) 1100*fcf3ce44SJohn Forte { 1101*fcf3ce44SJohn Forte int i; 1102*fcf3ce44SJohn Forte int new; 1103*fcf3ce44SJohn Forte 1104*fcf3ce44SJohn Forte if (self_check(host)) { 1105*fcf3ce44SJohn Forte return (0); 1106*fcf3ce44SJohn Forte } 1107*fcf3ce44SJohn Forte 1108*fcf3ce44SJohn Forte (void) mutex_lock(&host_list->hosts_mutex); 1109*fcf3ce44SJohn Forte new = 1; 1110*fcf3ce44SJohn Forte for (i = 0; i < MAXHOSTS; i++) { 1111*fcf3ce44SJohn Forte if (host_list->configured[i] == 0) { 1112*fcf3ce44SJohn Forte host_list->configured[i] = 1; 1113*fcf3ce44SJohn Forte host_list->hosts[i] = strdup(host); 1114*fcf3ce44SJohn Forte host_list->numhosts++; 1115*fcf3ce44SJohn Forte break; 1116*fcf3ce44SJohn Forte } 1117*fcf3ce44SJohn Forte if (strcmp(host, host_list->hosts[i]) == 0) { 1118*fcf3ce44SJohn Forte new = 0; 1119*fcf3ce44SJohn Forte break; 1120*fcf3ce44SJohn Forte } 1121*fcf3ce44SJohn Forte } 1122*fcf3ce44SJohn Forte (void) mutex_unlock(&host_list->hosts_mutex); 1123*fcf3ce44SJohn Forte if (i == MAXHOSTS) 1124*fcf3ce44SJohn Forte new = 0; 1125*fcf3ce44SJohn Forte return (new); 1126*fcf3ce44SJohn Forte } 1127*fcf3ce44SJohn Forte 1128*fcf3ce44SJohn Forte 1129*fcf3ce44SJohn Forte /* 1130*fcf3ce44SJohn Forte * Look for a matching volume name in our remembered list. 1131*fcf3ce44SJohn Forte */ 1132*fcf3ce44SJohn Forte int 1133*fcf3ce44SJohn Forte volume_match(char *buf, char **volume_list, int volumes) 1134*fcf3ce44SJohn Forte { 1135*fcf3ce44SJohn Forte int i; 1136*fcf3ce44SJohn Forte char *vol; 1137*fcf3ce44SJohn Forte 1138*fcf3ce44SJohn Forte for (i = 0; i < volumes; i++) { 1139*fcf3ce44SJohn Forte vol = volume_list[i]; 1140*fcf3ce44SJohn Forte if (strcmp(buf, vol) == 0) { 1141*fcf3ce44SJohn Forte return (1); 1142*fcf3ce44SJohn Forte } 1143*fcf3ce44SJohn Forte } 1144*fcf3ce44SJohn Forte return (0); 1145*fcf3ce44SJohn Forte } 1146*fcf3ce44SJohn Forte 1147*fcf3ce44SJohn Forte 1148*fcf3ce44SJohn Forte /* 1149*fcf3ce44SJohn Forte * A sync has completed to a group. We can only update the ndr_ii entries 1150*fcf3ce44SJohn Forte * if all the members of the group have completed their syncs OK. 1151*fcf3ce44SJohn Forte * It would be bad to allow some members of the group to have PIT Copy snapshots 1152*fcf3ce44SJohn Forte * taken and others not, as they need to be consistent. 1153*fcf3ce44SJohn Forte */ 1154*fcf3ce44SJohn Forte void 1155*fcf3ce44SJohn Forte group_complete(char *group) 1156*fcf3ce44SJohn Forte { 1157*fcf3ce44SJohn Forte char **volumes = NULL; 1158*fcf3ce44SJohn Forte spcs_s_info_t ustatus; 1159*fcf3ce44SJohn Forte rdc_config_t parms = { 0 }; 1160*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 1161*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 1162*fcf3ce44SJohn Forte CFGFILE *cfg = NULL; 1163*fcf3ce44SJohn Forte int i; 1164*fcf3ce44SJohn Forte int setnumber; 1165*fcf3ce44SJohn Forte int found; 1166*fcf3ce44SJohn Forte int replicating = 0; 1167*fcf3ce44SJohn Forte char primary[NSC_MAXPATH]; 1168*fcf3ce44SJohn Forte char secondary[NSC_MAXPATH]; 1169*fcf3ce44SJohn Forte char phost[MAX_RDC_HOST_SIZE]; 1170*fcf3ce44SJohn Forte char shost[MAX_RDC_HOST_SIZE]; 1171*fcf3ce44SJohn Forte rdc_set_t *rdc_set; 1172*fcf3ce44SJohn Forte int sev; 1173*fcf3ce44SJohn Forte char *local_file; 1174*fcf3ce44SJohn Forte int size; 1175*fcf3ce44SJohn Forte 1176*fcf3ce44SJohn Forte ustatus = spcs_s_ucreate(); 1177*fcf3ce44SJohn Forte 1178*fcf3ce44SJohn Forte size = sizeof (char *) * rdc_maxsets; 1179*fcf3ce44SJohn Forte volumes = malloc(size); 1180*fcf3ce44SJohn Forte if (volumes == NULL) { 1181*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1182*fcf3ce44SJohn Forte gettext("%s: unable to allocate %ld bytes"), 1183*fcf3ce44SJohn Forte program, size); 1184*fcf3ce44SJohn Forte rdc_warn(NULL, 1185*fcf3ce44SJohn Forte gettext("unable to allocate %ld bytes"), size); 1186*fcf3ce44SJohn Forte goto done; 1187*fcf3ce44SJohn Forte } 1188*fcf3ce44SJohn Forte bzero(volumes, size); 1189*fcf3ce44SJohn Forte 1190*fcf3ce44SJohn Forte /* 1191*fcf3ce44SJohn Forte * If all members of this group are replicating 1192*fcf3ce44SJohn Forte * set ii_ndr state to "update". Otherwise leave them alone. 1193*fcf3ce44SJohn Forte */ 1194*fcf3ce44SJohn Forte LOCKCFG(); 1195*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) { 1196*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1197*fcf3ce44SJohn Forte gettext("%s: error opening lconfig"), 1198*fcf3ce44SJohn Forte program); 1199*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("error opening config")); 1200*fcf3ce44SJohn Forte UNLOCKCFG(); 1201*fcf3ce44SJohn Forte goto done; 1202*fcf3ce44SJohn Forte } 1203*fcf3ce44SJohn Forte 1204*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_RDLOCK)) { 1205*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1206*fcf3ce44SJohn Forte gettext("%s: error locking config"), 1207*fcf3ce44SJohn Forte program); 1208*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("error locking config")); 1209*fcf3ce44SJohn Forte goto done; 1210*fcf3ce44SJohn Forte } 1211*fcf3ce44SJohn Forte 1212*fcf3ce44SJohn Forte found = 0; 1213*fcf3ce44SJohn Forte 1214*fcf3ce44SJohn Forte /* get all RM entries, with a matching group, that are replicating */ 1215*fcf3ce44SJohn Forte for (i = 0; i < rdc_maxsets; i++) { 1216*fcf3ce44SJohn Forte setnumber = i + 1; 1217*fcf3ce44SJohn Forte 1218*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 1219*fcf3ce44SJohn Forte "sndr.set%d.group", setnumber); 1220*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 1221*fcf3ce44SJohn Forte break; 1222*fcf3ce44SJohn Forte 1223*fcf3ce44SJohn Forte if (strcmp(buf, group) != 0) 1224*fcf3ce44SJohn Forte continue; 1225*fcf3ce44SJohn Forte 1226*fcf3ce44SJohn Forte /* Found a matching entry */ 1227*fcf3ce44SJohn Forte 1228*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 1229*fcf3ce44SJohn Forte "sndr.set%d.primary", setnumber); 1230*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, primary, sizeof (primary)) < 0) 1231*fcf3ce44SJohn Forte break; 1232*fcf3ce44SJohn Forte strcpy(parms.rdc_set->primary.file, primary); 1233*fcf3ce44SJohn Forte 1234*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 1235*fcf3ce44SJohn Forte "sndr.set%d.phost", setnumber); 1236*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, phost, sizeof (phost)) < 0) 1237*fcf3ce44SJohn Forte break; 1238*fcf3ce44SJohn Forte strcpy(parms.rdc_set->primary.intf, phost); 1239*fcf3ce44SJohn Forte 1240*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 1241*fcf3ce44SJohn Forte "sndr.set%d.secondary", setnumber); 1242*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, secondary, 1243*fcf3ce44SJohn Forte sizeof (secondary)) < 0) 1244*fcf3ce44SJohn Forte break; 1245*fcf3ce44SJohn Forte strcpy(parms.rdc_set->secondary.file, secondary); 1246*fcf3ce44SJohn Forte 1247*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 1248*fcf3ce44SJohn Forte "sndr.set%d.shost", setnumber); 1249*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, shost, sizeof (shost)) < 0) 1250*fcf3ce44SJohn Forte break; 1251*fcf3ce44SJohn Forte strcpy(parms.rdc_set->secondary.intf, shost); 1252*fcf3ce44SJohn Forte 1253*fcf3ce44SJohn Forte parms.command = RDC_CMD_STATUS; 1254*fcf3ce44SJohn Forte if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus) < 0) { 1255*fcf3ce44SJohn Forte continue; 1256*fcf3ce44SJohn Forte } 1257*fcf3ce44SJohn Forte 1258*fcf3ce44SJohn Forte /* We found a matching set */ 1259*fcf3ce44SJohn Forte found++; 1260*fcf3ce44SJohn Forte 1261*fcf3ce44SJohn Forte if (self_check(phost)) 1262*fcf3ce44SJohn Forte local_file = primary; 1263*fcf3ce44SJohn Forte else 1264*fcf3ce44SJohn Forte local_file = secondary; 1265*fcf3ce44SJohn Forte 1266*fcf3ce44SJohn Forte rdc_set = &parms.rdc_set[0]; 1267*fcf3ce44SJohn Forte if (!(rdc_set->flags & RDC_LOGGING) && 1268*fcf3ce44SJohn Forte !(rdc_set->flags & RDC_SYNCING)) { 1269*fcf3ce44SJohn Forte volumes[replicating] = strdup(local_file); 1270*fcf3ce44SJohn Forte if (volumes[replicating] == NULL) { 1271*fcf3ce44SJohn Forte size = strlen(local_file); 1272*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1273*fcf3ce44SJohn Forte gettext("%s: unable to allocate %ld bytes"), 1274*fcf3ce44SJohn Forte program, size); 1275*fcf3ce44SJohn Forte rdc_warn(NULL, 1276*fcf3ce44SJohn Forte gettext("unable to allocate %ld bytes"), 1277*fcf3ce44SJohn Forte size); 1278*fcf3ce44SJohn Forte goto done; 1279*fcf3ce44SJohn Forte } 1280*fcf3ce44SJohn Forte /* We remember all replicating sets */ 1281*fcf3ce44SJohn Forte replicating++; 1282*fcf3ce44SJohn Forte } else 1283*fcf3ce44SJohn Forte break; /* Not all replicating, so done */ 1284*fcf3ce44SJohn Forte } 1285*fcf3ce44SJohn Forte 1286*fcf3ce44SJohn Forte if (found != replicating) 1287*fcf3ce44SJohn Forte goto done; 1288*fcf3ce44SJohn Forte 1289*fcf3ce44SJohn Forte /* All replicating, so update ndr_ii state fields */ 1290*fcf3ce44SJohn Forte 1291*fcf3ce44SJohn Forte cfg_unlock(cfg); 1292*fcf3ce44SJohn Forte 1293*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_WRLOCK)) { 1294*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1295*fcf3ce44SJohn Forte gettext("%s: error locking lconfig"), 1296*fcf3ce44SJohn Forte program); 1297*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("error locking config")); 1298*fcf3ce44SJohn Forte goto done; 1299*fcf3ce44SJohn Forte } 1300*fcf3ce44SJohn Forte 1301*fcf3ce44SJohn Forte /* 1302*fcf3ce44SJohn Forte * Search through the ndr_ii entries for entries 1303*fcf3ce44SJohn Forte * that match the saved secondary volume names. 1304*fcf3ce44SJohn Forte * Set state to "update". 1305*fcf3ce44SJohn Forte */ 1306*fcf3ce44SJohn Forte 1307*fcf3ce44SJohn Forte for (i = 0; ; i++) { 1308*fcf3ce44SJohn Forte setnumber = i + 1; 1309*fcf3ce44SJohn Forte 1310*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary", 1311*fcf3ce44SJohn Forte setnumber); 1312*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 1313*fcf3ce44SJohn Forte break; 1314*fcf3ce44SJohn Forte 1315*fcf3ce44SJohn Forte if (!volume_match(buf, volumes, found)) { 1316*fcf3ce44SJohn Forte continue; 1317*fcf3ce44SJohn Forte } 1318*fcf3ce44SJohn Forte 1319*fcf3ce44SJohn Forte /* Got a matching entry */ 1320*fcf3ce44SJohn Forte 1321*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 1322*fcf3ce44SJohn Forte "ndr_ii.set%d.state", setnumber); 1323*fcf3ce44SJohn Forte if ((cfg_put_cstring(cfg, key, UPDATE, strlen(UPDATE)) < 0) || 1324*fcf3ce44SJohn Forte (cfg_commit(cfg) < 0)) { 1325*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1326*fcf3ce44SJohn Forte gettext("%s: unable to update \"%s\" " 1327*fcf3ce44SJohn Forte "in configuration storage: %s"), 1328*fcf3ce44SJohn Forte program, buf, cfg_error(&sev)); 1329*fcf3ce44SJohn Forte rdc_warn(NULL, 1330*fcf3ce44SJohn Forte gettext("unable to update \"%s\" " 1331*fcf3ce44SJohn Forte "in configuration storage: %s"), 1332*fcf3ce44SJohn Forte buf, cfg_error(&sev)); 1333*fcf3ce44SJohn Forte } 1334*fcf3ce44SJohn Forte } 1335*fcf3ce44SJohn Forte 1336*fcf3ce44SJohn Forte 1337*fcf3ce44SJohn Forte done: 1338*fcf3ce44SJohn Forte if (cfg) { 1339*fcf3ce44SJohn Forte cfg_close(cfg); 1340*fcf3ce44SJohn Forte UNLOCKCFG(); 1341*fcf3ce44SJohn Forte } 1342*fcf3ce44SJohn Forte spcs_s_ufree(&ustatus); 1343*fcf3ce44SJohn Forte if (volumes) { 1344*fcf3ce44SJohn Forte for (i = 0; i < replicating; i++) 1345*fcf3ce44SJohn Forte free(volumes[i]); 1346*fcf3ce44SJohn Forte free(volumes); 1347*fcf3ce44SJohn Forte } 1348*fcf3ce44SJohn Forte } 1349*fcf3ce44SJohn Forte 1350*fcf3ce44SJohn Forte 1351*fcf3ce44SJohn Forte /* 1352*fcf3ce44SJohn Forte * Sync started to a member of a group. 1353*fcf3ce44SJohn Forte * If all members of the group are in ndr_ii state "update" then take an PIT 1354*fcf3ce44SJohn Forte * snapshot on all of them. This will provide a consistent point-in-time 1355*fcf3ce44SJohn Forte * copy until whatever syncs take place are all completed. 1356*fcf3ce44SJohn Forte */ 1357*fcf3ce44SJohn Forte void 1358*fcf3ce44SJohn Forte group_start(char *group) 1359*fcf3ce44SJohn Forte { 1360*fcf3ce44SJohn Forte char **masters = NULL; 1361*fcf3ce44SJohn Forte char **shadows = NULL; 1362*fcf3ce44SJohn Forte char **bitmaps = NULL; 1363*fcf3ce44SJohn Forte char cmd[256]; 1364*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 1365*fcf3ce44SJohn Forte char key[CFG_MAX_KEY]; 1366*fcf3ce44SJohn Forte CFGFILE *cfg = NULL; 1367*fcf3ce44SJohn Forte int i; 1368*fcf3ce44SJohn Forte int j; 1369*fcf3ce44SJohn Forte int setnumber; 1370*fcf3ce44SJohn Forte int found; 1371*fcf3ce44SJohn Forte int sndr_sets = 0; 1372*fcf3ce44SJohn Forte int update_needed = 0; 1373*fcf3ce44SJohn Forte int sev; 1374*fcf3ce44SJohn Forte char *ctag = NULL; 1375*fcf3ce44SJohn Forte int commit = 0; 1376*fcf3ce44SJohn Forte int size; 1377*fcf3ce44SJohn Forte 1378*fcf3ce44SJohn Forte size = sizeof (char *) * rdc_maxsets; 1379*fcf3ce44SJohn Forte masters = malloc(size); 1380*fcf3ce44SJohn Forte if (masters == NULL) { 1381*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1382*fcf3ce44SJohn Forte gettext("%s: unable to allocate %ld bytes"), 1383*fcf3ce44SJohn Forte program, size); 1384*fcf3ce44SJohn Forte rdc_warn(NULL, 1385*fcf3ce44SJohn Forte gettext("unable to allocate %ld bytes"), size); 1386*fcf3ce44SJohn Forte goto done; 1387*fcf3ce44SJohn Forte } 1388*fcf3ce44SJohn Forte bzero(masters, size); 1389*fcf3ce44SJohn Forte shadows = malloc(size); 1390*fcf3ce44SJohn Forte if (shadows == NULL) { 1391*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1392*fcf3ce44SJohn Forte gettext("%s: unable to allocate %ld bytes"), 1393*fcf3ce44SJohn Forte program, size); 1394*fcf3ce44SJohn Forte rdc_warn(NULL, 1395*fcf3ce44SJohn Forte gettext("unable to allocate %ld bytes"), size); 1396*fcf3ce44SJohn Forte goto done; 1397*fcf3ce44SJohn Forte } 1398*fcf3ce44SJohn Forte bzero(shadows, size); 1399*fcf3ce44SJohn Forte bitmaps = malloc(size); 1400*fcf3ce44SJohn Forte if (bitmaps == NULL) { 1401*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1402*fcf3ce44SJohn Forte gettext("%s: unable to allocate %ld bytes"), 1403*fcf3ce44SJohn Forte program, size); 1404*fcf3ce44SJohn Forte rdc_warn(NULL, 1405*fcf3ce44SJohn Forte gettext("unable to allocate %ld bytes"), size); 1406*fcf3ce44SJohn Forte goto done; 1407*fcf3ce44SJohn Forte } 1408*fcf3ce44SJohn Forte bzero(bitmaps, size); 1409*fcf3ce44SJohn Forte 1410*fcf3ce44SJohn Forte LOCKCFG(); 1411*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) { 1412*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1413*fcf3ce44SJohn Forte gettext("%s: error opening config"), 1414*fcf3ce44SJohn Forte program); 1415*fcf3ce44SJohn Forte rdc_warn(NULL, 1416*fcf3ce44SJohn Forte gettext("error opening config")); 1417*fcf3ce44SJohn Forte UNLOCKCFG(); 1418*fcf3ce44SJohn Forte goto done; 1419*fcf3ce44SJohn Forte } 1420*fcf3ce44SJohn Forte 1421*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_WRLOCK)) { 1422*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1423*fcf3ce44SJohn Forte gettext("%s: error locking config"), 1424*fcf3ce44SJohn Forte program); 1425*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("error locking config")); 1426*fcf3ce44SJohn Forte goto done; 1427*fcf3ce44SJohn Forte } 1428*fcf3ce44SJohn Forte 1429*fcf3ce44SJohn Forte /* Now get all Remote Mirror entries with a matching group */ 1430*fcf3ce44SJohn Forte for (i = 0; i < rdc_maxsets; i++) { 1431*fcf3ce44SJohn Forte setnumber = i + 1; 1432*fcf3ce44SJohn Forte 1433*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 1434*fcf3ce44SJohn Forte "sndr.set%d.group", setnumber); 1435*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 1436*fcf3ce44SJohn Forte break; 1437*fcf3ce44SJohn Forte 1438*fcf3ce44SJohn Forte if (strcmp(buf, group) != 0) 1439*fcf3ce44SJohn Forte continue; 1440*fcf3ce44SJohn Forte 1441*fcf3ce44SJohn Forte /* Found a matching entry */ 1442*fcf3ce44SJohn Forte 1443*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 1444*fcf3ce44SJohn Forte "sndr.set%d.phost", setnumber); 1445*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) 1446*fcf3ce44SJohn Forte break; 1447*fcf3ce44SJohn Forte 1448*fcf3ce44SJohn Forte if (self_check(buf)) { 1449*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d.primary", 1450*fcf3ce44SJohn Forte setnumber); 1451*fcf3ce44SJohn Forte } else { 1452*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 1453*fcf3ce44SJohn Forte "sndr.set%d.secondary", setnumber); 1454*fcf3ce44SJohn Forte } 1455*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) 1456*fcf3ce44SJohn Forte break; 1457*fcf3ce44SJohn Forte 1458*fcf3ce44SJohn Forte masters[sndr_sets] = strdup(buf); 1459*fcf3ce44SJohn Forte if (masters[sndr_sets] == NULL) { 1460*fcf3ce44SJohn Forte size = strlen(buf); 1461*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1462*fcf3ce44SJohn Forte gettext("%s: unable to allocate %ld bytes"), 1463*fcf3ce44SJohn Forte program, size); 1464*fcf3ce44SJohn Forte rdc_warn(NULL, 1465*fcf3ce44SJohn Forte gettext("unable to allocate %ld bytes"), size); 1466*fcf3ce44SJohn Forte goto done; 1467*fcf3ce44SJohn Forte } 1468*fcf3ce44SJohn Forte sndr_sets++; 1469*fcf3ce44SJohn Forte 1470*fcf3ce44SJohn Forte if (ctag == NULL && clustered) { 1471*fcf3ce44SJohn Forte /* Get cluster tag of matching entry */ 1472*fcf3ce44SJohn Forte 1473*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "sndr.set%d.cnode", 1474*fcf3ce44SJohn Forte setnumber); 1475*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) >= 0) 1476*fcf3ce44SJohn Forte ctag = strdup(buf); 1477*fcf3ce44SJohn Forte } 1478*fcf3ce44SJohn Forte } 1479*fcf3ce44SJohn Forte 1480*fcf3ce44SJohn Forte /* 1481*fcf3ce44SJohn Forte * Search through the ndr_ii entries for entries 1482*fcf3ce44SJohn Forte * that match the saved local volume names and are in "update" state. 1483*fcf3ce44SJohn Forte */ 1484*fcf3ce44SJohn Forte 1485*fcf3ce44SJohn Forte update_needed = 0; 1486*fcf3ce44SJohn Forte 1487*fcf3ce44SJohn Forte for (i = 0; ; i++) { 1488*fcf3ce44SJohn Forte setnumber = i + 1; 1489*fcf3ce44SJohn Forte 1490*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary", 1491*fcf3ce44SJohn Forte setnumber); 1492*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 1493*fcf3ce44SJohn Forte break; 1494*fcf3ce44SJohn Forte 1495*fcf3ce44SJohn Forte if (!volume_match(buf, masters, sndr_sets)) 1496*fcf3ce44SJohn Forte continue; 1497*fcf3ce44SJohn Forte 1498*fcf3ce44SJohn Forte /* Got a matching entry */ 1499*fcf3ce44SJohn Forte 1500*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ndr_ii.set%d.shadow", 1501*fcf3ce44SJohn Forte setnumber); 1502*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 1503*fcf3ce44SJohn Forte break; 1504*fcf3ce44SJohn Forte shadows[update_needed] = strdup(buf); 1505*fcf3ce44SJohn Forte if (shadows[update_needed] == NULL) { 1506*fcf3ce44SJohn Forte size = strlen(buf); 1507*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1508*fcf3ce44SJohn Forte gettext("%s: unable to allocate %ld bytes"), 1509*fcf3ce44SJohn Forte program, size); 1510*fcf3ce44SJohn Forte rdc_warn(NULL, 1511*fcf3ce44SJohn Forte gettext("unable to allocate %ld bytes"), size); 1512*fcf3ce44SJohn Forte goto done; 1513*fcf3ce44SJohn Forte } 1514*fcf3ce44SJohn Forte 1515*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ndr_ii.set%d.bitmap", 1516*fcf3ce44SJohn Forte setnumber); 1517*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { 1518*fcf3ce44SJohn Forte break; 1519*fcf3ce44SJohn Forte } 1520*fcf3ce44SJohn Forte bitmaps[update_needed] = strdup(buf); 1521*fcf3ce44SJohn Forte if (bitmaps[update_needed] == NULL) { 1522*fcf3ce44SJohn Forte size = strlen(buf); 1523*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1524*fcf3ce44SJohn Forte gettext("%s: unable to allocate %ld bytes"), 1525*fcf3ce44SJohn Forte program, size); 1526*fcf3ce44SJohn Forte rdc_warn(NULL, 1527*fcf3ce44SJohn Forte gettext("unable to allocate %ld bytes"), size); 1528*fcf3ce44SJohn Forte goto done; 1529*fcf3ce44SJohn Forte } 1530*fcf3ce44SJohn Forte 1531*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state", 1532*fcf3ce44SJohn Forte setnumber); 1533*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { 1534*fcf3ce44SJohn Forte break; 1535*fcf3ce44SJohn Forte } 1536*fcf3ce44SJohn Forte if (strcmp(buf, UPDATE) != 0) { 1537*fcf3ce44SJohn Forte break; 1538*fcf3ce44SJohn Forte } 1539*fcf3ce44SJohn Forte 1540*fcf3ce44SJohn Forte update_needed++; 1541*fcf3ce44SJohn Forte } 1542*fcf3ce44SJohn Forte 1543*fcf3ce44SJohn Forte if (update_needed != sndr_sets) { 1544*fcf3ce44SJohn Forte #ifdef DEBUG 1545*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1546*fcf3ce44SJohn Forte gettext("%s: group sync: no Point-in-Time Copy snapshot " 1547*fcf3ce44SJohn Forte "for %s"), program, group); 1548*fcf3ce44SJohn Forte #endif 1549*fcf3ce44SJohn Forte goto done; 1550*fcf3ce44SJohn Forte } 1551*fcf3ce44SJohn Forte 1552*fcf3ce44SJohn Forte /* All RM sets in the group have an ndr_ii entry in "update" state */ 1553*fcf3ce44SJohn Forte 1554*fcf3ce44SJohn Forte /* Issue PIT Copy snapshot commands for all sets in the group */ 1555*fcf3ce44SJohn Forte for (j = 0; j < sndr_sets; j++) { 1556*fcf3ce44SJohn Forte found = 0; 1557*fcf3ce44SJohn Forte 1558*fcf3ce44SJohn Forte /* get ii entries until a match is found */ 1559*fcf3ce44SJohn Forte for (i = 0; ; i++) { 1560*fcf3ce44SJohn Forte setnumber = i + 1; 1561*fcf3ce44SJohn Forte 1562*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ii.set%d.shadow", 1563*fcf3ce44SJohn Forte setnumber); 1564*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 1565*fcf3ce44SJohn Forte break; 1566*fcf3ce44SJohn Forte if (strcmp(buf, shadows[j]) != 0) 1567*fcf3ce44SJohn Forte continue; 1568*fcf3ce44SJohn Forte 1569*fcf3ce44SJohn Forte /* Matching shadow found, so ii already enabled */ 1570*fcf3ce44SJohn Forte found = 1; 1571*fcf3ce44SJohn Forte break; 1572*fcf3ce44SJohn Forte } 1573*fcf3ce44SJohn Forte 1574*fcf3ce44SJohn Forte if (commit) 1575*fcf3ce44SJohn Forte if (cfg_commit(cfg) < 0) 1576*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("commit config error")); 1577*fcf3ce44SJohn Forte cfg_close(cfg); 1578*fcf3ce44SJohn Forte 1579*fcf3ce44SJohn Forte if (found) { 1580*fcf3ce44SJohn Forte (void) sprintf(cmd, "%s -u s %s", IIADM, shadows[j]); 1581*fcf3ce44SJohn Forte } else { 1582*fcf3ce44SJohn Forte if (ctag) { 1583*fcf3ce44SJohn Forte (void) sprintf(cmd, "%s -C %s -e dep %s %s %s", 1584*fcf3ce44SJohn Forte IIADM, ctag, masters[j], shadows[j], 1585*fcf3ce44SJohn Forte bitmaps[j]); 1586*fcf3ce44SJohn Forte free(ctag); 1587*fcf3ce44SJohn Forte ctag = NULL; 1588*fcf3ce44SJohn Forte } else 1589*fcf3ce44SJohn Forte (void) sprintf(cmd, "%s -e dep %s %s %s", IIADM, 1590*fcf3ce44SJohn Forte masters[j], shadows[j], bitmaps[j]); 1591*fcf3ce44SJohn Forte } 1592*fcf3ce44SJohn Forte 1593*fcf3ce44SJohn Forte if (system(cmd) != 0) { 1594*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1595*fcf3ce44SJohn Forte gettext("%s: group sync: Point-in-Time Copy" 1596*fcf3ce44SJohn Forte " snapshot failed for %s"), 1597*fcf3ce44SJohn Forte program, masters[j]); 1598*fcf3ce44SJohn Forte 1599*fcf3ce44SJohn Forte goto done; 1600*fcf3ce44SJohn Forte } 1601*fcf3ce44SJohn Forte 1602*fcf3ce44SJohn Forte if ((cfg = cfg_open(NULL)) == NULL) { 1603*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1604*fcf3ce44SJohn Forte gettext("%s: error opening config"), 1605*fcf3ce44SJohn Forte program); 1606*fcf3ce44SJohn Forte rdc_warn(NULL, 1607*fcf3ce44SJohn Forte gettext("error opening config")); 1608*fcf3ce44SJohn Forte goto done; 1609*fcf3ce44SJohn Forte } 1610*fcf3ce44SJohn Forte if (!cfg_lock(cfg, CFG_WRLOCK)) { 1611*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1612*fcf3ce44SJohn Forte gettext("%s: error locking config"), 1613*fcf3ce44SJohn Forte program); 1614*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("error locking config")); 1615*fcf3ce44SJohn Forte goto done; 1616*fcf3ce44SJohn Forte } 1617*fcf3ce44SJohn Forte commit = 0; 1618*fcf3ce44SJohn Forte 1619*fcf3ce44SJohn Forte /* PIT enable or update was fine, so update the ndr_ii entry */ 1620*fcf3ce44SJohn Forte 1621*fcf3ce44SJohn Forte /* get ndr_ii entries until a match is found */ 1622*fcf3ce44SJohn Forte for (i = 0; ; i++) { 1623*fcf3ce44SJohn Forte setnumber = i + 1; 1624*fcf3ce44SJohn Forte 1625*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), 1626*fcf3ce44SJohn Forte "ndr_ii.set%d.shadow", setnumber); 1627*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) 1628*fcf3ce44SJohn Forte break; 1629*fcf3ce44SJohn Forte if (strcmp(buf, shadows[j]) != 0) 1630*fcf3ce44SJohn Forte continue; 1631*fcf3ce44SJohn Forte 1632*fcf3ce44SJohn Forte /* Found the matching entry */ 1633*fcf3ce44SJohn Forte 1634*fcf3ce44SJohn Forte (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state", 1635*fcf3ce44SJohn Forte setnumber); 1636*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, key, NOUPDATE, 1637*fcf3ce44SJohn Forte strlen(NOUPDATE)) < 0) { 1638*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1639*fcf3ce44SJohn Forte gettext("%s: unable to update \"%s\" " 1640*fcf3ce44SJohn Forte "in configuration storage: %s"), 1641*fcf3ce44SJohn Forte program, buf, cfg_error(&sev)); 1642*fcf3ce44SJohn Forte rdc_warn(NULL, 1643*fcf3ce44SJohn Forte gettext("unable to update \"%s\" " 1644*fcf3ce44SJohn Forte "in configuration storage: %s"), 1645*fcf3ce44SJohn Forte buf, cfg_error(&sev)); 1646*fcf3ce44SJohn Forte } else 1647*fcf3ce44SJohn Forte commit = 1; 1648*fcf3ce44SJohn Forte break; 1649*fcf3ce44SJohn Forte } 1650*fcf3ce44SJohn Forte } 1651*fcf3ce44SJohn Forte 1652*fcf3ce44SJohn Forte if (commit) 1653*fcf3ce44SJohn Forte if (cfg_commit(cfg) < 0) 1654*fcf3ce44SJohn Forte rdc_warn(NULL, gettext("commit config error")); 1655*fcf3ce44SJohn Forte 1656*fcf3ce44SJohn Forte spcs_log("sndr", NULL, 1657*fcf3ce44SJohn Forte gettext("%s: group sync: Point-in-Time Copy snapshots completed " 1658*fcf3ce44SJohn Forte "for %s"), program, group); 1659*fcf3ce44SJohn Forte 1660*fcf3ce44SJohn Forte done: 1661*fcf3ce44SJohn Forte if (ctag) 1662*fcf3ce44SJohn Forte free(ctag); 1663*fcf3ce44SJohn Forte 1664*fcf3ce44SJohn Forte if (cfg) { 1665*fcf3ce44SJohn Forte cfg_close(cfg); 1666*fcf3ce44SJohn Forte UNLOCKCFG(); 1667*fcf3ce44SJohn Forte } 1668*fcf3ce44SJohn Forte 1669*fcf3ce44SJohn Forte if (masters) { 1670*fcf3ce44SJohn Forte for (i = 0; i < sndr_sets; i++) { 1671*fcf3ce44SJohn Forte if (masters[i]) 1672*fcf3ce44SJohn Forte free(masters[i]); 1673*fcf3ce44SJohn Forte } 1674*fcf3ce44SJohn Forte free(masters); 1675*fcf3ce44SJohn Forte } 1676*fcf3ce44SJohn Forte 1677*fcf3ce44SJohn Forte if (shadows) { 1678*fcf3ce44SJohn Forte for (i = 0; i < update_needed; i++) { 1679*fcf3ce44SJohn Forte if (shadows[i]) 1680*fcf3ce44SJohn Forte free(shadows[i]); 1681*fcf3ce44SJohn Forte } 1682*fcf3ce44SJohn Forte free(shadows); 1683*fcf3ce44SJohn Forte } 1684*fcf3ce44SJohn Forte 1685*fcf3ce44SJohn Forte if (bitmaps) { 1686*fcf3ce44SJohn Forte for (i = 0; i < update_needed; i++) { 1687*fcf3ce44SJohn Forte if (bitmaps[i]) 1688*fcf3ce44SJohn Forte free(bitmaps[i]); 1689*fcf3ce44SJohn Forte } 1690*fcf3ce44SJohn Forte free(bitmaps); 1691*fcf3ce44SJohn Forte } 1692*fcf3ce44SJohn Forte } 1693