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