17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM * CDDL HEADER START
37836SJohn.Forte@Sun.COM *
47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM *
87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM * and limitations under the License.
127836SJohn.Forte@Sun.COM *
137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM *
197836SJohn.Forte@Sun.COM * CDDL HEADER END
207836SJohn.Forte@Sun.COM */
21*11576SSurya.Prakki@Sun.COM
227836SJohn.Forte@Sun.COM /*
23*11576SSurya.Prakki@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
247836SJohn.Forte@Sun.COM * Use is subject to license terms.
257836SJohn.Forte@Sun.COM */
267836SJohn.Forte@Sun.COM
277836SJohn.Forte@Sun.COM #include <sys/types.h>
287836SJohn.Forte@Sun.COM #include <sys/wait.h>
297836SJohn.Forte@Sun.COM #include <stdio.h>
307836SJohn.Forte@Sun.COM #include <errno.h>
317836SJohn.Forte@Sun.COM #include <limits.h>
327836SJohn.Forte@Sun.COM #include <fcntl.h>
337836SJohn.Forte@Sun.COM #include <strings.h>
347836SJohn.Forte@Sun.COM #include <stdlib.h>
357836SJohn.Forte@Sun.COM #include <unistd.h>
367836SJohn.Forte@Sun.COM #include <pthread.h>
377836SJohn.Forte@Sun.COM #include <thread.h>
387836SJohn.Forte@Sun.COM
397836SJohn.Forte@Sun.COM #include <locale.h>
407836SJohn.Forte@Sun.COM #include <langinfo.h>
417836SJohn.Forte@Sun.COM #include <libintl.h>
427836SJohn.Forte@Sun.COM #include <stdarg.h>
437836SJohn.Forte@Sun.COM
447836SJohn.Forte@Sun.COM #include <sys/nsctl/rdc_io.h>
457836SJohn.Forte@Sun.COM #include <sys/nsctl/rdc_ioctl.h>
467836SJohn.Forte@Sun.COM #include <sys/nsctl/rdc_prot.h>
477836SJohn.Forte@Sun.COM
487836SJohn.Forte@Sun.COM #include <sys/nsctl/cfg.h>
497836SJohn.Forte@Sun.COM
507836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s.h>
517836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s_u.h>
527836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_errors.h>
537836SJohn.Forte@Sun.COM
547836SJohn.Forte@Sun.COM #include <sys/nsctl/librdc.h>
557836SJohn.Forte@Sun.COM
567836SJohn.Forte@Sun.COM #include "rdcadm.h"
577836SJohn.Forte@Sun.COM
587836SJohn.Forte@Sun.COM
597836SJohn.Forte@Sun.COM #define RDCADM "/usr/sbin/sndradm"
607836SJohn.Forte@Sun.COM #define IIADM "/usr/sbin/iiadm"
617836SJohn.Forte@Sun.COM
627836SJohn.Forte@Sun.COM #define UPDATE "update"
637836SJohn.Forte@Sun.COM #define NOUPDATE "noupdate"
647836SJohn.Forte@Sun.COM
657836SJohn.Forte@Sun.COM #define RESYNC_SLEEP (3 * 60) /* Three minutes */
667836SJohn.Forte@Sun.COM #define MAIN_SLEEP (5 * 60) /* Five minutes */
677836SJohn.Forte@Sun.COM #define CFG_WAIT_SLEEP (5) /* 5 sec */
687836SJohn.Forte@Sun.COM
697836SJohn.Forte@Sun.COM #define MAXHOSTS 1024
707836SJohn.Forte@Sun.COM mutex_t cfglock = DEFAULTMUTEX;
717836SJohn.Forte@Sun.COM #define LOCKCFG() (void) mutex_lock(&cfglock);
727836SJohn.Forte@Sun.COM #define UNLOCKCFG() (void) mutex_unlock(&cfglock);
737836SJohn.Forte@Sun.COM
747836SJohn.Forte@Sun.COM typedef struct host_list_s {
757836SJohn.Forte@Sun.COM char *hosts[MAXHOSTS];
767836SJohn.Forte@Sun.COM int numhosts;
777836SJohn.Forte@Sun.COM int configured[MAXHOSTS];
787836SJohn.Forte@Sun.COM mutex_t hosts_mutex;
797836SJohn.Forte@Sun.COM } host_list_t;
807836SJohn.Forte@Sun.COM
817836SJohn.Forte@Sun.COM host_list_t *host_list;
827836SJohn.Forte@Sun.COM
837836SJohn.Forte@Sun.COM extern char *basename(char *);
847836SJohn.Forte@Sun.COM int rdc_maxsets;
857836SJohn.Forte@Sun.COM char *program;
867836SJohn.Forte@Sun.COM
877836SJohn.Forte@Sun.COM static int clustered = 0;
887836SJohn.Forte@Sun.COM
897836SJohn.Forte@Sun.COM int isnewhost(char *host);
907836SJohn.Forte@Sun.COM void *wait_sync_event();
917836SJohn.Forte@Sun.COM void *wait_link_down(void *host);
927836SJohn.Forte@Sun.COM void rdc_sync(char *tohost);
937836SJohn.Forte@Sun.COM void remove_from_hostlist(char *host);
947836SJohn.Forte@Sun.COM void sync_start(char *master);
957836SJohn.Forte@Sun.COM void sync_complete(char *master);
967836SJohn.Forte@Sun.COM void cleanup_hostlist();
977836SJohn.Forte@Sun.COM void group_start(char *group);
987836SJohn.Forte@Sun.COM void group_complete(char *group);
997836SJohn.Forte@Sun.COM
1007836SJohn.Forte@Sun.COM
1017836SJohn.Forte@Sun.COM void
init_host_list(void)1027836SJohn.Forte@Sun.COM init_host_list(void)
1037836SJohn.Forte@Sun.COM {
1047836SJohn.Forte@Sun.COM host_list = calloc(1, sizeof (host_list_t));
1057836SJohn.Forte@Sun.COM if (host_list == NULL) {
1067836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
1077836SJohn.Forte@Sun.COM gettext("host list not initialized, cannot run"));
1087836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("host list not initialized, cannot run"));
1097836SJohn.Forte@Sun.COM }
1107836SJohn.Forte@Sun.COM (void) mutex_init(&host_list->hosts_mutex, USYNC_THREAD, NULL);
1117836SJohn.Forte@Sun.COM }
1127836SJohn.Forte@Sun.COM
1137836SJohn.Forte@Sun.COM /* ARGSUSED */
1147836SJohn.Forte@Sun.COM #ifdef lint
1157836SJohn.Forte@Sun.COM void
sndrsyncd_lintmain(argc,argv)1167836SJohn.Forte@Sun.COM sndrsyncd_lintmain(argc, argv)
1177836SJohn.Forte@Sun.COM #else
1187836SJohn.Forte@Sun.COM int
1197836SJohn.Forte@Sun.COM main(argc, argv)
1207836SJohn.Forte@Sun.COM #endif
1217836SJohn.Forte@Sun.COM int argc;
1227836SJohn.Forte@Sun.COM char **argv;
1237836SJohn.Forte@Sun.COM {
1247836SJohn.Forte@Sun.COM rdc_status_t *rdc_info;
1257836SJohn.Forte@Sun.COM int size;
1267836SJohn.Forte@Sun.COM int i;
1277836SJohn.Forte@Sun.COM pid_t pid;
1287836SJohn.Forte@Sun.COM spcs_s_info_t ustatus;
1297836SJohn.Forte@Sun.COM int rc, trc;
1307836SJohn.Forte@Sun.COM int first = 0;
1317836SJohn.Forte@Sun.COM char *required;
1327836SJohn.Forte@Sun.COM
1337836SJohn.Forte@Sun.COM (void) setlocale(LC_ALL, "");
1347836SJohn.Forte@Sun.COM (void) textdomain("rdc");
1357836SJohn.Forte@Sun.COM
1367836SJohn.Forte@Sun.COM ustatus = spcs_s_ucreate();
1377836SJohn.Forte@Sun.COM
1387836SJohn.Forte@Sun.COM program = basename(argv[0]);
1397836SJohn.Forte@Sun.COM
1407836SJohn.Forte@Sun.COM init_host_list();
1417836SJohn.Forte@Sun.COM
1427836SJohn.Forte@Sun.COM rc = rdc_check_release(&required);
1437836SJohn.Forte@Sun.COM if (rc < 0) {
1447836SJohn.Forte@Sun.COM rdc_err(NULL,
1457836SJohn.Forte@Sun.COM gettext("unable to determine the current "
1467836SJohn.Forte@Sun.COM "Solaris release: %s\n"), strerror(errno));
1477836SJohn.Forte@Sun.COM /* NOTREACHED */
1487836SJohn.Forte@Sun.COM } else if (rc == FALSE) {
1497836SJohn.Forte@Sun.COM rdc_err(NULL,
1507836SJohn.Forte@Sun.COM gettext("incorrect Solaris release (requires %s)\n"),
1517836SJohn.Forte@Sun.COM required);
1527836SJohn.Forte@Sun.COM /* NOTREACHED */
1537836SJohn.Forte@Sun.COM }
1547836SJohn.Forte@Sun.COM
1557836SJohn.Forte@Sun.COM clustered = cfg_iscluster();
1567836SJohn.Forte@Sun.COM if (clustered < 0) {
1577836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("unable to ascertain environment"));
1587836SJohn.Forte@Sun.COM }
1597836SJohn.Forte@Sun.COM
1607836SJohn.Forte@Sun.COM rdc_maxsets = rdc_get_maxsets();
1617836SJohn.Forte@Sun.COM if (rdc_maxsets == -1) {
1627836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
1637836SJohn.Forte@Sun.COM gettext("%s: unable to get maxsets value from kernel"),
1647836SJohn.Forte@Sun.COM program);
1657836SJohn.Forte@Sun.COM rdc_err(NULL,
1667836SJohn.Forte@Sun.COM gettext("unable to get maxsets value from kernel"));
1677836SJohn.Forte@Sun.COM }
1687836SJohn.Forte@Sun.COM size = sizeof (rdc_status_t) + (sizeof (rdc_set_t) * (rdc_maxsets - 1));
1697836SJohn.Forte@Sun.COM rdc_info = malloc(size);
1707836SJohn.Forte@Sun.COM if (rdc_info == NULL) {
1717836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
1727836SJohn.Forte@Sun.COM gettext("%s: unable to allocate %ld bytes"),
1737836SJohn.Forte@Sun.COM program, size);
1747836SJohn.Forte@Sun.COM rdc_err(NULL,
1757836SJohn.Forte@Sun.COM gettext("unable to allocate %ld bytes"), size);
1767836SJohn.Forte@Sun.COM }
1777836SJohn.Forte@Sun.COM bzero(rdc_info, size);
1787836SJohn.Forte@Sun.COM
1797836SJohn.Forte@Sun.COM rdc_info->nset = rdc_maxsets;
1807836SJohn.Forte@Sun.COM
1817836SJohn.Forte@Sun.COM /*
1827836SJohn.Forte@Sun.COM * Fork off a child that becomes the daemon.
1837836SJohn.Forte@Sun.COM */
1847836SJohn.Forte@Sun.COM if ((pid = fork()) > 0)
1857836SJohn.Forte@Sun.COM exit(0);
1867836SJohn.Forte@Sun.COM else if (pid < 0) {
1877836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
1887836SJohn.Forte@Sun.COM gettext("%s: cannot fork: %s"),
1897836SJohn.Forte@Sun.COM program, strerror(errno));
1907836SJohn.Forte@Sun.COM rdc_err(NULL, gettext("cannot fork: %s\n"),
1917836SJohn.Forte@Sun.COM strerror(errno));
1927836SJohn.Forte@Sun.COM }
1937836SJohn.Forte@Sun.COM
1947836SJohn.Forte@Sun.COM /*
1957836SJohn.Forte@Sun.COM * In child - become daemon.
1967836SJohn.Forte@Sun.COM */
1977836SJohn.Forte@Sun.COM
1987836SJohn.Forte@Sun.COM for (i = 0; i < 3; i++)
1997836SJohn.Forte@Sun.COM (void) close(i);
2007836SJohn.Forte@Sun.COM
2017836SJohn.Forte@Sun.COM (void) open("/dev/console", O_WRONLY|O_APPEND);
2027836SJohn.Forte@Sun.COM (void) dup(0);
2037836SJohn.Forte@Sun.COM (void) dup(0);
2047836SJohn.Forte@Sun.COM (void) close(0);
2057836SJohn.Forte@Sun.COM
2067836SJohn.Forte@Sun.COM (void) setpgrp();
2077836SJohn.Forte@Sun.COM
2087836SJohn.Forte@Sun.COM (void) setlocale(LC_ALL, "");
2097836SJohn.Forte@Sun.COM (void) textdomain("rdc");
2107836SJohn.Forte@Sun.COM
2117836SJohn.Forte@Sun.COM /* launch a thread to wait for sync start and sync stop events */
2127836SJohn.Forte@Sun.COM
2137836SJohn.Forte@Sun.COM if ((trc = thr_create(NULL, 0, wait_sync_event, NULL,
2147836SJohn.Forte@Sun.COM THR_BOUND|THR_DETACHED, NULL)) != 0) {
2157836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
2167836SJohn.Forte@Sun.COM gettext("%s: unable to create thread wait_sync_event"),
2177836SJohn.Forte@Sun.COM program);
2187836SJohn.Forte@Sun.COM rdc_warn(NULL,
2197836SJohn.Forte@Sun.COM gettext("%s unable to create thread wait_sync_event"),
2207836SJohn.Forte@Sun.COM program);
2217836SJohn.Forte@Sun.COM } else {
2227836SJohn.Forte@Sun.COM #ifdef DEBUG
2237836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
2247836SJohn.Forte@Sun.COM gettext("%s: thread wait_sync_event started"), program);
2257836SJohn.Forte@Sun.COM #endif
2267836SJohn.Forte@Sun.COM ;
2277836SJohn.Forte@Sun.COM }
2287836SJohn.Forte@Sun.COM
2297836SJohn.Forte@Sun.COM for (;;) {
2307836SJohn.Forte@Sun.COM if (!first) {
2317836SJohn.Forte@Sun.COM first++;
2327836SJohn.Forte@Sun.COM (void) sleep(15);
2337836SJohn.Forte@Sun.COM } else
2347836SJohn.Forte@Sun.COM (void) sleep(MAIN_SLEEP);
2357836SJohn.Forte@Sun.COM
2367836SJohn.Forte@Sun.COM bzero(rdc_info, size);
2377836SJohn.Forte@Sun.COM rdc_info->nset = rdc_maxsets;
2387836SJohn.Forte@Sun.COM if (RDC_IOCTL(RDC_STATUS, rdc_info, 0, 0, 0, 0, ustatus)
2397836SJohn.Forte@Sun.COM != SPCS_S_OK) {
2407836SJohn.Forte@Sun.COM spcs_log("sndr", &ustatus,
2417836SJohn.Forte@Sun.COM gettext("%s: status ioctl"),
2427836SJohn.Forte@Sun.COM program);
2437836SJohn.Forte@Sun.COM rdc_warn(&ustatus, gettext("status ioctl"));
2447836SJohn.Forte@Sun.COM continue;
2457836SJohn.Forte@Sun.COM }
2467836SJohn.Forte@Sun.COM
2477836SJohn.Forte@Sun.COM cleanup_hostlist(rdc_info); /* remove non-existent hosts */
2487836SJohn.Forte@Sun.COM
2497836SJohn.Forte@Sun.COM /*
2507836SJohn.Forte@Sun.COM * Check all enabled sets to see if a new remote host has
2517836SJohn.Forte@Sun.COM * appeared.
2527836SJohn.Forte@Sun.COM */
2537836SJohn.Forte@Sun.COM for (i = 0; i < rdc_maxsets; i++) {
2547836SJohn.Forte@Sun.COM if (!(rdc_info->rdc_set[i].flags & RDC_ENABLED))
2557836SJohn.Forte@Sun.COM continue;
2567836SJohn.Forte@Sun.COM /* spawn a new thread for each new host found */
2577836SJohn.Forte@Sun.COM if (isnewhost(rdc_info->rdc_set[i].secondary.intf)) {
2587836SJohn.Forte@Sun.COM /*
2597836SJohn.Forte@Sun.COM * right now, we could be here before
2607836SJohn.Forte@Sun.COM * the database did the write for this set
2617836SJohn.Forte@Sun.COM * I could check the lock on the database
2627836SJohn.Forte@Sun.COM * but I am just going to give up some time here
2637836SJohn.Forte@Sun.COM * instead. Why do the allocations etc, etc
2647836SJohn.Forte@Sun.COM * if the set is enabled in the kernel and not
2657836SJohn.Forte@Sun.COM * in the config, we know that this set has the
2667836SJohn.Forte@Sun.COM * lock. Why bother adding more contention to
2677836SJohn.Forte@Sun.COM * the lock.
2687836SJohn.Forte@Sun.COM * this is a daemon, afterall. its got time
2697836SJohn.Forte@Sun.COM */
2707836SJohn.Forte@Sun.COM (void) sleep(CFG_WAIT_SLEEP);
2717836SJohn.Forte@Sun.COM
2727836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
2737836SJohn.Forte@Sun.COM gettext("%s: new host found (%s) starting "
2747836SJohn.Forte@Sun.COM "its autosync thread"), program,
2757836SJohn.Forte@Sun.COM rdc_info->rdc_set[i].secondary.intf);
2767836SJohn.Forte@Sun.COM
2777836SJohn.Forte@Sun.COM trc = thr_create(NULL, 0, wait_link_down,
2787836SJohn.Forte@Sun.COM (void *) rdc_info->rdc_set[i].\
2797836SJohn.Forte@Sun.COM secondary.intf, THR_BOUND|THR_DETACHED, NULL);
2807836SJohn.Forte@Sun.COM
2817836SJohn.Forte@Sun.COM if (trc != 0) {
2827836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
2837836SJohn.Forte@Sun.COM gettext(
2847836SJohn.Forte@Sun.COM "%s create new autosync "
2857836SJohn.Forte@Sun.COM "thread failed"), program);
2867836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext(
2877836SJohn.Forte@Sun.COM "%s create new autosync "
2887836SJohn.Forte@Sun.COM "thread failed"), program);
2897836SJohn.Forte@Sun.COM }
2907836SJohn.Forte@Sun.COM }
2917836SJohn.Forte@Sun.COM }
2927836SJohn.Forte@Sun.COM }
2937836SJohn.Forte@Sun.COM /* NOTREACHED */
2947836SJohn.Forte@Sun.COM }
2957836SJohn.Forte@Sun.COM
2967836SJohn.Forte@Sun.COM
2977836SJohn.Forte@Sun.COM /*
2987836SJohn.Forte@Sun.COM * The kernel wakes up this function every time it detects the link to the
2997836SJohn.Forte@Sun.COM * specified host has dropped.
3007836SJohn.Forte@Sun.COM */
3017836SJohn.Forte@Sun.COM void *
wait_link_down(void * thehost)3027836SJohn.Forte@Sun.COM wait_link_down(void *thehost)
3037836SJohn.Forte@Sun.COM {
3047836SJohn.Forte@Sun.COM char *host = (char *)thehost;
3057836SJohn.Forte@Sun.COM char tmphost[MAX_RDC_HOST_SIZE] = { '\0' };
3067836SJohn.Forte@Sun.COM spcs_s_info_t ustatus;
3077836SJohn.Forte@Sun.COM
3087836SJohn.Forte@Sun.COM if (host)
309*11576SSurya.Prakki@Sun.COM (void) strncpy(tmphost, host, MAX_RDC_HOST_SIZE);
3107836SJohn.Forte@Sun.COM
3117836SJohn.Forte@Sun.COM ustatus = spcs_s_ucreate();
3127836SJohn.Forte@Sun.COM
3137836SJohn.Forte@Sun.COM /* Never give up */
3147836SJohn.Forte@Sun.COM for (;;) {
3157836SJohn.Forte@Sun.COM #ifdef DEBUG
3167836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
3177836SJohn.Forte@Sun.COM gettext("%s: awaiting link down ioctl for %s"),
3187836SJohn.Forte@Sun.COM program, host[0] == '\0' ? tmphost : host);
3197836SJohn.Forte@Sun.COM #endif
3207836SJohn.Forte@Sun.COM if (RDC_IOCTL(RDC_LINK_DOWN, host, 0, 0, 0, 0, ustatus)
3217836SJohn.Forte@Sun.COM != SPCS_S_OK) {
3227836SJohn.Forte@Sun.COM spcs_log("sndr", &ustatus,
3237836SJohn.Forte@Sun.COM gettext("%s: link down ioctl"),
3247836SJohn.Forte@Sun.COM program);
3257836SJohn.Forte@Sun.COM rdc_warn(&ustatus, gettext("link down ioctl"));
3267836SJohn.Forte@Sun.COM continue;
3277836SJohn.Forte@Sun.COM }
3287836SJohn.Forte@Sun.COM #ifdef DEBUG
3297836SJohn.Forte@Sun.COM
3307836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
3317836SJohn.Forte@Sun.COM gettext("%s: received link down ioctl for %s"),
3327836SJohn.Forte@Sun.COM program, host[0] == '\0' ? tmphost : host);
3337836SJohn.Forte@Sun.COM #endif
3347836SJohn.Forte@Sun.COM rdc_sync(host[0] == '\0' ? tmphost : host);
3357836SJohn.Forte@Sun.COM }
3367836SJohn.Forte@Sun.COM /* LINTED */
3377836SJohn.Forte@Sun.COM }
3387836SJohn.Forte@Sun.COM
3397836SJohn.Forte@Sun.COM
3407836SJohn.Forte@Sun.COM /*
3417836SJohn.Forte@Sun.COM * Called when the link to the specified host has dropped.
3427836SJohn.Forte@Sun.COM * For all Remote Mirror sets using the link that have autosync on,
3437836SJohn.Forte@Sun.COM * issue rdcadm -u commands until they complete successfully.
3447836SJohn.Forte@Sun.COM */
3457836SJohn.Forte@Sun.COM void
rdc_sync(char * tohost)3467836SJohn.Forte@Sun.COM rdc_sync(char *tohost)
3477836SJohn.Forte@Sun.COM {
3487836SJohn.Forte@Sun.COM rdc_set_t *rdc_set = NULL;
3497836SJohn.Forte@Sun.COM int *sync_done = NULL;
3507836SJohn.Forte@Sun.COM int sets = 0;
3517836SJohn.Forte@Sun.COM int syncs_done = 0;
3527836SJohn.Forte@Sun.COM char cmd[256];
3537836SJohn.Forte@Sun.COM rdc_config_t parms = { 0 };
3547836SJohn.Forte@Sun.COM spcs_s_info_t ustatus;
3557836SJohn.Forte@Sun.COM int i;
3567836SJohn.Forte@Sun.COM int setnumber;
3577836SJohn.Forte@Sun.COM int numfound = 0;
3587836SJohn.Forte@Sun.COM char buf[CFG_MAX_BUF];
3597836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
3607836SJohn.Forte@Sun.COM CFGFILE *cfg = NULL;
3617836SJohn.Forte@Sun.COM int size;
3627836SJohn.Forte@Sun.COM int first = 0;
3637836SJohn.Forte@Sun.COM int death = 0;
3647836SJohn.Forte@Sun.COM int cfglocked = 0;
3657836SJohn.Forte@Sun.COM
3667836SJohn.Forte@Sun.COM ustatus = spcs_s_ucreate();
3677836SJohn.Forte@Sun.COM
3687836SJohn.Forte@Sun.COM size = sizeof (rdc_set_t) * rdc_maxsets;
3697836SJohn.Forte@Sun.COM rdc_set = malloc(size);
3707836SJohn.Forte@Sun.COM if (rdc_set == NULL) {
3717836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
3727836SJohn.Forte@Sun.COM gettext("%s: unable to allocate %ld bytes"),
3737836SJohn.Forte@Sun.COM program, size);
3747836SJohn.Forte@Sun.COM rdc_warn(NULL,
3757836SJohn.Forte@Sun.COM gettext("unable to allocate %ld bytes"), size);
3767836SJohn.Forte@Sun.COM goto done;
3777836SJohn.Forte@Sun.COM }
3787836SJohn.Forte@Sun.COM bzero(rdc_set, size);
3797836SJohn.Forte@Sun.COM size = sizeof (int) * rdc_maxsets;
3807836SJohn.Forte@Sun.COM sync_done = malloc(size);
3817836SJohn.Forte@Sun.COM if (sync_done == NULL) {
3827836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
3837836SJohn.Forte@Sun.COM gettext("%s: unable to allocate %ld bytes"),
3847836SJohn.Forte@Sun.COM program, size);
3857836SJohn.Forte@Sun.COM rdc_warn(NULL,
3867836SJohn.Forte@Sun.COM gettext("unable to allocate %ld bytes"), size);
3877836SJohn.Forte@Sun.COM goto done;
3887836SJohn.Forte@Sun.COM }
3897836SJohn.Forte@Sun.COM bzero(sync_done, size);
3907836SJohn.Forte@Sun.COM
3917836SJohn.Forte@Sun.COM /*
3927836SJohn.Forte@Sun.COM * Get all sndr entries with shost matching tohost, and save the
3937836SJohn.Forte@Sun.COM * details in an array.
3947836SJohn.Forte@Sun.COM */
3957836SJohn.Forte@Sun.COM for (i = 0; i < rdc_maxsets; i++) {
3967836SJohn.Forte@Sun.COM setnumber = i + 1;
3977836SJohn.Forte@Sun.COM bzero(buf, sizeof (buf));
3987836SJohn.Forte@Sun.COM bzero(key, sizeof (key));
3997836SJohn.Forte@Sun.COM
4007836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d.shost",
4017836SJohn.Forte@Sun.COM setnumber);
4027836SJohn.Forte@Sun.COM
4037836SJohn.Forte@Sun.COM if (!cfglocked) {
4047836SJohn.Forte@Sun.COM LOCKCFG();
4057836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL) {
4067836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
4077836SJohn.Forte@Sun.COM gettext("%s: error opening config"),
4087836SJohn.Forte@Sun.COM program);
4097836SJohn.Forte@Sun.COM
4107836SJohn.Forte@Sun.COM rdc_warn(NULL,
4117836SJohn.Forte@Sun.COM gettext("error opening config"));
4127836SJohn.Forte@Sun.COM UNLOCKCFG();
4137836SJohn.Forte@Sun.COM goto done;
4147836SJohn.Forte@Sun.COM }
4157836SJohn.Forte@Sun.COM
4167836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_RDLOCK)) {
4177836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
4187836SJohn.Forte@Sun.COM gettext("%s: error locking config"),
4197836SJohn.Forte@Sun.COM program);
4207836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("error locking config"));
4217836SJohn.Forte@Sun.COM goto done;
4227836SJohn.Forte@Sun.COM }
4237836SJohn.Forte@Sun.COM }
4247836SJohn.Forte@Sun.COM
4257836SJohn.Forte@Sun.COM cfglocked = 1;
4267836SJohn.Forte@Sun.COM
4277836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
4287836SJohn.Forte@Sun.COM if (numfound == 0) /* no matching hosts */
4297836SJohn.Forte@Sun.COM death = 1; /* thread will exit */
4307836SJohn.Forte@Sun.COM break;
4317836SJohn.Forte@Sun.COM }
4327836SJohn.Forte@Sun.COM if (strcmp(buf, tohost) != 0)
4337836SJohn.Forte@Sun.COM continue;
4347836SJohn.Forte@Sun.COM
4357836SJohn.Forte@Sun.COM numfound++;
436*11576SSurya.Prakki@Sun.COM (void) strncpy(rdc_set[sets].secondary.intf, buf,
437*11576SSurya.Prakki@Sun.COM MAX_RDC_HOST_SIZE);
4387836SJohn.Forte@Sun.COM
4397836SJohn.Forte@Sun.COM /* Got a matching entry */
4407836SJohn.Forte@Sun.COM
4417836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d.phost",
4427836SJohn.Forte@Sun.COM setnumber);
4437836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
4447836SJohn.Forte@Sun.COM break;
445*11576SSurya.Prakki@Sun.COM (void) strncpy(rdc_set[sets].primary.intf, buf,
446*11576SSurya.Prakki@Sun.COM MAX_RDC_HOST_SIZE);
4477836SJohn.Forte@Sun.COM
4487836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d.primary",
4497836SJohn.Forte@Sun.COM setnumber);
4507836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
4517836SJohn.Forte@Sun.COM break;
452*11576SSurya.Prakki@Sun.COM (void) strncpy(rdc_set[sets].primary.file, buf, NSC_MAXPATH);
4537836SJohn.Forte@Sun.COM
4547836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d.secondary",
4557836SJohn.Forte@Sun.COM setnumber);
4567836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
4577836SJohn.Forte@Sun.COM break;
458*11576SSurya.Prakki@Sun.COM (void) strncpy(rdc_set[sets].secondary.file, buf, NSC_MAXPATH);
4597836SJohn.Forte@Sun.COM
4607836SJohn.Forte@Sun.COM parms.command = RDC_CMD_STATUS;
4617836SJohn.Forte@Sun.COM bcopy((void *)(&rdc_set[sets]), (void *)(&parms.rdc_set[0]),
4627836SJohn.Forte@Sun.COM sizeof (rdc_set_t));
4637836SJohn.Forte@Sun.COM
4647836SJohn.Forte@Sun.COM /*
4657836SJohn.Forte@Sun.COM * release cfg before diving into the kernel
4667836SJohn.Forte@Sun.COM * this prevents a possible deadlock when doing
4677836SJohn.Forte@Sun.COM * a reverse sync whick will wake up the sync_event
4687836SJohn.Forte@Sun.COM * thread which will try and iiadm -c and hang
4697836SJohn.Forte@Sun.COM * because we still have the cfg_lock. the timed
4707836SJohn.Forte@Sun.COM * wait cv in the kernel will fail the sync and things
4717836SJohn.Forte@Sun.COM * will undeadlock.
4727836SJohn.Forte@Sun.COM */
4737836SJohn.Forte@Sun.COM
4747836SJohn.Forte@Sun.COM cfg_close(cfg);
4757836SJohn.Forte@Sun.COM cfg = NULL;
4767836SJohn.Forte@Sun.COM cfglocked = 0;
4777836SJohn.Forte@Sun.COM UNLOCKCFG();
4787836SJohn.Forte@Sun.COM
4797836SJohn.Forte@Sun.COM if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus) < 0) {
4807836SJohn.Forte@Sun.COM continue;
4817836SJohn.Forte@Sun.COM }
4827836SJohn.Forte@Sun.COM if ((parms.rdc_set[0].autosync == 0) ||
4837836SJohn.Forte@Sun.COM (!(parms.rdc_set[0].flags & RDC_LOGGING))) {
4847836SJohn.Forte@Sun.COM continue;
4857836SJohn.Forte@Sun.COM }
4867836SJohn.Forte@Sun.COM
4877836SJohn.Forte@Sun.COM /* Found a suitable set with autosync on, in logging mode */
4887836SJohn.Forte@Sun.COM sets++;
4897836SJohn.Forte@Sun.COM }
4907836SJohn.Forte@Sun.COM
4917836SJohn.Forte@Sun.COM if (cfg) {
4927836SJohn.Forte@Sun.COM cfg_close(cfg);
4937836SJohn.Forte@Sun.COM cfg = NULL;
4947836SJohn.Forte@Sun.COM UNLOCKCFG();
4957836SJohn.Forte@Sun.COM }
4967836SJohn.Forte@Sun.COM
4977836SJohn.Forte@Sun.COM if (sets == 0) {
4987836SJohn.Forte@Sun.COM #ifdef DEBUG
4997836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
5007836SJohn.Forte@Sun.COM gettext("%s: no sets requiring autosync found for %s"),
5017836SJohn.Forte@Sun.COM program, tohost);
5027836SJohn.Forte@Sun.COM #endif
5037836SJohn.Forte@Sun.COM if (death) {
5047836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
5057836SJohn.Forte@Sun.COM gettext("%s: autosync thread stopping for %s "
5067836SJohn.Forte@Sun.COM "(host deconfigured)"), program, tohost);
5077836SJohn.Forte@Sun.COM }
5087836SJohn.Forte@Sun.COM goto done;
5097836SJohn.Forte@Sun.COM }
5107836SJohn.Forte@Sun.COM
5117836SJohn.Forte@Sun.COM /* Keep issuing rdcadm -u commands until they have all completed */
5127836SJohn.Forte@Sun.COM for (;;) {
5137836SJohn.Forte@Sun.COM if (!first)
5147836SJohn.Forte@Sun.COM first++;
5157836SJohn.Forte@Sun.COM else
5167836SJohn.Forte@Sun.COM (void) sleep(RESYNC_SLEEP);
5177836SJohn.Forte@Sun.COM
5187836SJohn.Forte@Sun.COM /* Issue rdcadm -u commands for all remaining sets */
5197836SJohn.Forte@Sun.COM for (i = 0; i < sets; i++) {
5207836SJohn.Forte@Sun.COM if (sync_done[i])
5217836SJohn.Forte@Sun.COM continue;
5227836SJohn.Forte@Sun.COM
5237836SJohn.Forte@Sun.COM /*
5247836SJohn.Forte@Sun.COM * Need to check if autosync was turned off for a set
5257836SJohn.Forte@Sun.COM * while we were sleeping. We could have the case where
5267836SJohn.Forte@Sun.COM * an update sync failed and autosync was disabled
5277836SJohn.Forte@Sun.COM * while we were sleeping and didn't detect the disable.
5287836SJohn.Forte@Sun.COM * See BugID 4814213.
5297836SJohn.Forte@Sun.COM */
5307836SJohn.Forte@Sun.COM parms.command = RDC_CMD_STATUS;
5317836SJohn.Forte@Sun.COM bcopy((void *)(&rdc_set[i]),
5327836SJohn.Forte@Sun.COM (void *)(&parms.rdc_set[0]), sizeof (rdc_set_t));
5337836SJohn.Forte@Sun.COM if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0,
5347836SJohn.Forte@Sun.COM ustatus) < 0) {
5357836SJohn.Forte@Sun.COM spcs_log("sndr", &ustatus, gettext("%s: "
5367836SJohn.Forte@Sun.COM "status not available for %s:%s, stopping "
5377836SJohn.Forte@Sun.COM "this autosync attempt"), program, tohost,
5387836SJohn.Forte@Sun.COM rdc_set[i].secondary.file);
5397836SJohn.Forte@Sun.COM sync_done[i] = 1;
5407836SJohn.Forte@Sun.COM syncs_done++;
5417836SJohn.Forte@Sun.COM continue;
5427836SJohn.Forte@Sun.COM }
5437836SJohn.Forte@Sun.COM if (!(parms.rdc_set[0].autosync)) {
5447836SJohn.Forte@Sun.COM #ifdef DEBUG
5457836SJohn.Forte@Sun.COM spcs_log("sndr", NULL, gettext("%s: autosync disabled during sleep, "
5467836SJohn.Forte@Sun.COM "stopping attempt for set %s:%s"), program, tohost,
5477836SJohn.Forte@Sun.COM rdc_set[i].secondary.file);
5487836SJohn.Forte@Sun.COM #endif
5497836SJohn.Forte@Sun.COM sync_done[i] = 1;
5507836SJohn.Forte@Sun.COM syncs_done++;
5517836SJohn.Forte@Sun.COM continue;
5527836SJohn.Forte@Sun.COM }
5537836SJohn.Forte@Sun.COM
5547836SJohn.Forte@Sun.COM (void) sprintf(cmd, "%s -un %s:%s", RDCADM, tohost,
5557836SJohn.Forte@Sun.COM rdc_set[i].secondary.file);
5567836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
5577836SJohn.Forte@Sun.COM gettext("%s: issuing update sync for %s:%s"),
5587836SJohn.Forte@Sun.COM program, tohost, rdc_set[i].secondary.file);
5597836SJohn.Forte@Sun.COM (void) system(cmd);
5607836SJohn.Forte@Sun.COM }
5617836SJohn.Forte@Sun.COM
5627836SJohn.Forte@Sun.COM /* Issue rdcadm -w commands to wait for updates to finish */
5637836SJohn.Forte@Sun.COM for (i = 0; i < sets; i++) {
5647836SJohn.Forte@Sun.COM if (sync_done[i])
5657836SJohn.Forte@Sun.COM continue;
5667836SJohn.Forte@Sun.COM
5677836SJohn.Forte@Sun.COM (void) sprintf(cmd, "%s -wn %s:%s", RDCADM, tohost,
5687836SJohn.Forte@Sun.COM rdc_set[i].secondary.file);
5697836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
5707836SJohn.Forte@Sun.COM gettext("%s: issuing wait for %s:%s"),
5717836SJohn.Forte@Sun.COM program, tohost, rdc_set[i].secondary.file);
5727836SJohn.Forte@Sun.COM
5737836SJohn.Forte@Sun.COM (void) system(cmd);
5747836SJohn.Forte@Sun.COM
5757836SJohn.Forte@Sun.COM parms.command = RDC_CMD_STATUS;
5767836SJohn.Forte@Sun.COM bcopy((void *)(&rdc_set[i]),
5777836SJohn.Forte@Sun.COM (void *)(&parms.rdc_set[0]), sizeof (rdc_set_t));
5787836SJohn.Forte@Sun.COM
5797836SJohn.Forte@Sun.COM if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0,
5807836SJohn.Forte@Sun.COM ustatus) < 0) {
5817836SJohn.Forte@Sun.COM spcs_log("sndr", &ustatus,
5827836SJohn.Forte@Sun.COM gettext("%s: status not available for "
5837836SJohn.Forte@Sun.COM "%s:%s, stopping this autosync attempt"),
5847836SJohn.Forte@Sun.COM program, tohost, rdc_set[i].secondary.file);
5857836SJohn.Forte@Sun.COM sync_done[i] = 1;
5867836SJohn.Forte@Sun.COM syncs_done++;
5877836SJohn.Forte@Sun.COM continue;
5887836SJohn.Forte@Sun.COM }
5897836SJohn.Forte@Sun.COM /* Check if completed OK, failed or autosync off */
5907836SJohn.Forte@Sun.COM if (!(parms.rdc_set[0].autosync) ||
5917836SJohn.Forte@Sun.COM !(parms.rdc_set[0].flags & RDC_LOGGING) &&
5927836SJohn.Forte@Sun.COM !(parms.rdc_set[0].flags & RDC_SYNCING)) {
5937836SJohn.Forte@Sun.COM sync_done[i] = 1;
5947836SJohn.Forte@Sun.COM syncs_done++;
5957836SJohn.Forte@Sun.COM }
5967836SJohn.Forte@Sun.COM }
5977836SJohn.Forte@Sun.COM
5987836SJohn.Forte@Sun.COM if (syncs_done == sets)
5997836SJohn.Forte@Sun.COM break; /* All completed OK */
6007836SJohn.Forte@Sun.COM }
6017836SJohn.Forte@Sun.COM
6027836SJohn.Forte@Sun.COM done:
6037836SJohn.Forte@Sun.COM if (cfg) {
6047836SJohn.Forte@Sun.COM cfg_close(cfg);
6057836SJohn.Forte@Sun.COM UNLOCKCFG();
6067836SJohn.Forte@Sun.COM }
6077836SJohn.Forte@Sun.COM spcs_s_ufree(&ustatus);
6087836SJohn.Forte@Sun.COM if (sync_done)
6097836SJohn.Forte@Sun.COM free(sync_done);
6107836SJohn.Forte@Sun.COM if (rdc_set)
6117836SJohn.Forte@Sun.COM free(rdc_set);
6127836SJohn.Forte@Sun.COM if (death) { /* bye bye */
6137836SJohn.Forte@Sun.COM /*
6147836SJohn.Forte@Sun.COM * if perhaps we lost some race, lets remove this entry from
6157836SJohn.Forte@Sun.COM * the list. Then, if something did go wrong, and we did kill
6167836SJohn.Forte@Sun.COM * a valid thread, it will be detected on the next go around
6177836SJohn.Forte@Sun.COM * of the thread who is looking for new hosts to spawn threads
6187836SJohn.Forte@Sun.COM */
6197836SJohn.Forte@Sun.COM
6207836SJohn.Forte@Sun.COM remove_from_hostlist(tohost);
6217836SJohn.Forte@Sun.COM thr_exit(0);
6227836SJohn.Forte@Sun.COM }
6237836SJohn.Forte@Sun.COM
6247836SJohn.Forte@Sun.COM (void) sleep(RESYNC_SLEEP);
6257836SJohn.Forte@Sun.COM }
6267836SJohn.Forte@Sun.COM
6277836SJohn.Forte@Sun.COM /*
6287836SJohn.Forte@Sun.COM * Wait for notification by the kernel of a sync start or a sync completed OK
6297836SJohn.Forte@Sun.COM */
6307836SJohn.Forte@Sun.COM void *
wait_sync_event()6317836SJohn.Forte@Sun.COM wait_sync_event()
6327836SJohn.Forte@Sun.COM {
6337836SJohn.Forte@Sun.COM spcs_s_info_t ustatus;
6347836SJohn.Forte@Sun.COM char master[NSC_MAXPATH];
6357836SJohn.Forte@Sun.COM char group[NSC_MAXPATH];
6367836SJohn.Forte@Sun.COM int state;
6377836SJohn.Forte@Sun.COM
6387836SJohn.Forte@Sun.COM ustatus = spcs_s_ucreate();
6397836SJohn.Forte@Sun.COM
6407836SJohn.Forte@Sun.COM master[0] = '\0';
6417836SJohn.Forte@Sun.COM group[0] = '\0';
6427836SJohn.Forte@Sun.COM
6437836SJohn.Forte@Sun.COM /* Never give up */
6447836SJohn.Forte@Sun.COM for (;;) {
6457836SJohn.Forte@Sun.COM /* Kernel tells us which volume and group the event is for */
6467836SJohn.Forte@Sun.COM state = RDC_IOCTL(RDC_SYNC_EVENT, master, group, 0, 0, 0,
6477836SJohn.Forte@Sun.COM ustatus);
6487836SJohn.Forte@Sun.COM if (state < SPCS_S_OK) {
6497836SJohn.Forte@Sun.COM if (errno != EAGAIN) {
6507836SJohn.Forte@Sun.COM spcs_log("sndr", &ustatus,
6517836SJohn.Forte@Sun.COM gettext("%s: update ioctl"),
6527836SJohn.Forte@Sun.COM program);
6537836SJohn.Forte@Sun.COM rdc_warn(&ustatus, gettext("update ioctl"));
6547836SJohn.Forte@Sun.COM continue;
6557836SJohn.Forte@Sun.COM }
6567836SJohn.Forte@Sun.COM master[0] = '\0';
6577836SJohn.Forte@Sun.COM continue;
6587836SJohn.Forte@Sun.COM }
6597836SJohn.Forte@Sun.COM
6607836SJohn.Forte@Sun.COM /*
6617836SJohn.Forte@Sun.COM * If target is mounted at the start of a sync or reverse sync,
6627836SJohn.Forte@Sun.COM * return a negative ack.
6637836SJohn.Forte@Sun.COM */
6647836SJohn.Forte@Sun.COM if ((state == RDC_SYNC_START || state == RDC_RSYNC_START) &&
6657836SJohn.Forte@Sun.COM mounted(master)) {
6667836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
6677836SJohn.Forte@Sun.COM gettext("%s: %s has a file system mounted"),
6687836SJohn.Forte@Sun.COM program, master);
6697836SJohn.Forte@Sun.COM rdc_warn(NULL,
6707836SJohn.Forte@Sun.COM gettext("%s has a file system mounted"),
6717836SJohn.Forte@Sun.COM master);
6727836SJohn.Forte@Sun.COM master[0] = '\0'; /* negative ack */
6737836SJohn.Forte@Sun.COM continue;
6747836SJohn.Forte@Sun.COM }
6757836SJohn.Forte@Sun.COM
6767836SJohn.Forte@Sun.COM switch (state) {
6777836SJohn.Forte@Sun.COM case RDC_SYNC_START:
6787836SJohn.Forte@Sun.COM if (group[0])
6797836SJohn.Forte@Sun.COM group_start(group);
6807836SJohn.Forte@Sun.COM else
6817836SJohn.Forte@Sun.COM sync_start(master);
6827836SJohn.Forte@Sun.COM break;
6837836SJohn.Forte@Sun.COM
6847836SJohn.Forte@Sun.COM case RDC_SYNC_DONE:
6857836SJohn.Forte@Sun.COM if (group[0])
6867836SJohn.Forte@Sun.COM group_complete(group);
6877836SJohn.Forte@Sun.COM else
6887836SJohn.Forte@Sun.COM sync_complete(master);
6897836SJohn.Forte@Sun.COM break;
6907836SJohn.Forte@Sun.COM
6917836SJohn.Forte@Sun.COM default:
6927836SJohn.Forte@Sun.COM break;
6937836SJohn.Forte@Sun.COM }
6947836SJohn.Forte@Sun.COM }
6957836SJohn.Forte@Sun.COM /* LINTED */
6967836SJohn.Forte@Sun.COM }
6977836SJohn.Forte@Sun.COM
6987836SJohn.Forte@Sun.COM
6997836SJohn.Forte@Sun.COM /*
7007836SJohn.Forte@Sun.COM * A sync has completed OK to a volume not belonging to a group.
7017836SJohn.Forte@Sun.COM * Set the state of the ndr_ii config entry to "update".
7027836SJohn.Forte@Sun.COM */
7037836SJohn.Forte@Sun.COM void
sync_complete(char * master)7047836SJohn.Forte@Sun.COM sync_complete(char *master)
7057836SJohn.Forte@Sun.COM {
7067836SJohn.Forte@Sun.COM CFGFILE *cfg = NULL;
7077836SJohn.Forte@Sun.COM char buf[CFG_MAX_BUF];
7087836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
7097836SJohn.Forte@Sun.COM int i;
7107836SJohn.Forte@Sun.COM int setnumber;
7117836SJohn.Forte@Sun.COM int sev;
7127836SJohn.Forte@Sun.COM
7137836SJohn.Forte@Sun.COM LOCKCFG();
7147836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL) {
7157836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
7167836SJohn.Forte@Sun.COM gettext("%s: error opening config"),
7177836SJohn.Forte@Sun.COM program);
7187836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("error opening config"));
7197836SJohn.Forte@Sun.COM UNLOCKCFG();
7207836SJohn.Forte@Sun.COM return;
7217836SJohn.Forte@Sun.COM }
7227836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_WRLOCK)) {
7237836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
7247836SJohn.Forte@Sun.COM gettext("%s: error locking config"),
7257836SJohn.Forte@Sun.COM program);
7267836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("error locking config"));
7277836SJohn.Forte@Sun.COM cfg_close(cfg);
7287836SJohn.Forte@Sun.COM UNLOCKCFG();
7297836SJohn.Forte@Sun.COM return;
7307836SJohn.Forte@Sun.COM }
7317836SJohn.Forte@Sun.COM
7327836SJohn.Forte@Sun.COM /* get ndr_ii entries until a match is found */
7337836SJohn.Forte@Sun.COM for (i = 0; ; i++) {
7347836SJohn.Forte@Sun.COM setnumber = i + 1;
7357836SJohn.Forte@Sun.COM
7367836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary",
7377836SJohn.Forte@Sun.COM setnumber);
7387836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
7397836SJohn.Forte@Sun.COM break;
7407836SJohn.Forte@Sun.COM if (strcmp(buf, master) != 0)
7417836SJohn.Forte@Sun.COM continue;
7427836SJohn.Forte@Sun.COM
7437836SJohn.Forte@Sun.COM /* Found the matching entry */
7447836SJohn.Forte@Sun.COM
7457836SJohn.Forte@Sun.COM /*
7467836SJohn.Forte@Sun.COM * Set state to "update" so that starting another sync will
7477836SJohn.Forte@Sun.COM * cause a new Point-in-Time Copy snapshot to be taken.
7487836SJohn.Forte@Sun.COM */
7497836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state",
7507836SJohn.Forte@Sun.COM setnumber);
7517836SJohn.Forte@Sun.COM if ((cfg_put_cstring(cfg, key, UPDATE, strlen(UPDATE)) < 0) ||
7527836SJohn.Forte@Sun.COM (cfg_commit(cfg) < 0)) {
7537836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
7547836SJohn.Forte@Sun.COM gettext("%s: unable to update \"%s\" "
7557836SJohn.Forte@Sun.COM "in configuration storage: %s"),
7567836SJohn.Forte@Sun.COM program, buf, cfg_error(&sev));
7577836SJohn.Forte@Sun.COM rdc_warn(NULL,
7587836SJohn.Forte@Sun.COM gettext("unable to update \"%s\" "
7597836SJohn.Forte@Sun.COM "in configuration storage: %s"),
7607836SJohn.Forte@Sun.COM buf, cfg_error(&sev));
7617836SJohn.Forte@Sun.COM }
7627836SJohn.Forte@Sun.COM break;
7637836SJohn.Forte@Sun.COM }
7647836SJohn.Forte@Sun.COM
7657836SJohn.Forte@Sun.COM cfg_close(cfg);
7667836SJohn.Forte@Sun.COM UNLOCKCFG();
7677836SJohn.Forte@Sun.COM }
7687836SJohn.Forte@Sun.COM
7697836SJohn.Forte@Sun.COM
7707836SJohn.Forte@Sun.COM /*
7717836SJohn.Forte@Sun.COM * Starting a sync to the specified master volume.
7727836SJohn.Forte@Sun.COM * Check the ndr_ii config entries to see if a Point-in-Time Copy
7737836SJohn.Forte@Sun.COM * snapshot should be taken.
7747836SJohn.Forte@Sun.COM */
7757836SJohn.Forte@Sun.COM void
sync_start(char * master)7767836SJohn.Forte@Sun.COM sync_start(char *master)
7777836SJohn.Forte@Sun.COM {
7787836SJohn.Forte@Sun.COM char cmd[256];
7797836SJohn.Forte@Sun.COM char buf[CFG_MAX_BUF];
7807836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
7817836SJohn.Forte@Sun.COM CFGFILE *cfg = NULL;
7827836SJohn.Forte@Sun.COM int i;
7837836SJohn.Forte@Sun.COM int setnumber;
7847836SJohn.Forte@Sun.COM int found;
7857836SJohn.Forte@Sun.COM int sev;
7867836SJohn.Forte@Sun.COM char shadow[NSC_MAXPATH];
7877836SJohn.Forte@Sun.COM char bitmap[NSC_MAXPATH];
7887836SJohn.Forte@Sun.COM char *ctag = NULL;
7897836SJohn.Forte@Sun.COM
7907836SJohn.Forte@Sun.COM LOCKCFG();
7917836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL) {
7927836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
7937836SJohn.Forte@Sun.COM gettext("%s: error opening config"),
7947836SJohn.Forte@Sun.COM program);
7957836SJohn.Forte@Sun.COM rdc_warn(NULL,
7967836SJohn.Forte@Sun.COM gettext("error opening config"));
7977836SJohn.Forte@Sun.COM UNLOCKCFG();
7987836SJohn.Forte@Sun.COM return;
7997836SJohn.Forte@Sun.COM }
8007836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_RDLOCK)) {
8017836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
8027836SJohn.Forte@Sun.COM gettext("%s: error locking config"),
8037836SJohn.Forte@Sun.COM program);
8047836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("error locking config"));
8057836SJohn.Forte@Sun.COM cfg_close(cfg);
8067836SJohn.Forte@Sun.COM UNLOCKCFG();
8077836SJohn.Forte@Sun.COM return;
8087836SJohn.Forte@Sun.COM }
8097836SJohn.Forte@Sun.COM
8107836SJohn.Forte@Sun.COM found = 0;
8117836SJohn.Forte@Sun.COM /* get ndr_ii entries until a match is found */
8127836SJohn.Forte@Sun.COM for (i = 0; ; i++) {
8137836SJohn.Forte@Sun.COM setnumber = i + 1;
8147836SJohn.Forte@Sun.COM
8157836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary",
8167836SJohn.Forte@Sun.COM setnumber);
8177836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
8187836SJohn.Forte@Sun.COM break;
8197836SJohn.Forte@Sun.COM if (strcmp(buf, master) != 0)
8207836SJohn.Forte@Sun.COM continue;
8217836SJohn.Forte@Sun.COM
8227836SJohn.Forte@Sun.COM /* Got a matching entry */
8237836SJohn.Forte@Sun.COM
8247836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ndr_ii.set%d.shadow",
8257836SJohn.Forte@Sun.COM setnumber);
8267836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
8277836SJohn.Forte@Sun.COM break;
828*11576SSurya.Prakki@Sun.COM (void) strncpy(shadow, buf, NSC_MAXPATH);
8297836SJohn.Forte@Sun.COM
8307836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ndr_ii.set%d.bitmap",
8317836SJohn.Forte@Sun.COM setnumber);
8327836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
8337836SJohn.Forte@Sun.COM break;
834*11576SSurya.Prakki@Sun.COM (void) strncpy(bitmap, buf, NSC_MAXPATH);
8357836SJohn.Forte@Sun.COM
8367836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state",
8377836SJohn.Forte@Sun.COM setnumber);
8387836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
8397836SJohn.Forte@Sun.COM break;
8407836SJohn.Forte@Sun.COM
8417836SJohn.Forte@Sun.COM /*
8427836SJohn.Forte@Sun.COM * If an PIT snapshot has already been taken, and syncing did
8437836SJohn.Forte@Sun.COM * not complete, the state will be "noupdate", to indicate we
8447836SJohn.Forte@Sun.COM * should not take another one at this point.
8457836SJohn.Forte@Sun.COM */
8467836SJohn.Forte@Sun.COM if (strcmp(buf, NOUPDATE) != 0)
8477836SJohn.Forte@Sun.COM found = 1;
8487836SJohn.Forte@Sun.COM
8497836SJohn.Forte@Sun.COM break;
8507836SJohn.Forte@Sun.COM }
8517836SJohn.Forte@Sun.COM
8527836SJohn.Forte@Sun.COM if (!found) {
8537836SJohn.Forte@Sun.COM cfg_close(cfg);
8547836SJohn.Forte@Sun.COM UNLOCKCFG();
8557836SJohn.Forte@Sun.COM return;
8567836SJohn.Forte@Sun.COM }
8577836SJohn.Forte@Sun.COM
8587836SJohn.Forte@Sun.COM found = 0;
8597836SJohn.Forte@Sun.COM /* get ii entries until a match is found */
8607836SJohn.Forte@Sun.COM for (i = 0; ; i++) {
8617836SJohn.Forte@Sun.COM setnumber = i + 1;
8627836SJohn.Forte@Sun.COM
8637836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ii.set%d.shadow",
8647836SJohn.Forte@Sun.COM setnumber);
8657836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
8667836SJohn.Forte@Sun.COM break;
8677836SJohn.Forte@Sun.COM if (strcmp(buf, shadow) != 0)
8687836SJohn.Forte@Sun.COM continue;
8697836SJohn.Forte@Sun.COM
8707836SJohn.Forte@Sun.COM /* Matching shadow found, so ii already enabled */
8717836SJohn.Forte@Sun.COM found = 1;
8727836SJohn.Forte@Sun.COM break;
8737836SJohn.Forte@Sun.COM }
8747836SJohn.Forte@Sun.COM
8757836SJohn.Forte@Sun.COM if (found) {
8767836SJohn.Forte@Sun.COM /* Already PIT enabled, so just take a snapshot */
8777836SJohn.Forte@Sun.COM
8787836SJohn.Forte@Sun.COM /* Get cluster tag of matching entry */
8797836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ii.set%d.cnode", setnumber);
8807836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) >= 0)
8817836SJohn.Forte@Sun.COM if ((strlen(buf) == 0) || (buf[0] == '-'))
8827836SJohn.Forte@Sun.COM ctag = "-C local";
8837836SJohn.Forte@Sun.COM else
8847836SJohn.Forte@Sun.COM ctag = "";
8857836SJohn.Forte@Sun.COM (void) sprintf(cmd, "%s %s -u s %s", IIADM, ctag, shadow);
8867836SJohn.Forte@Sun.COM } else {
8877836SJohn.Forte@Sun.COM /*
8887836SJohn.Forte@Sun.COM * If clustered, need to enable PIT Copy sets in the same
8897836SJohn.Forte@Sun.COM * cluster as the Remote Mirror set
8907836SJohn.Forte@Sun.COM */
8917836SJohn.Forte@Sun.COM
8927836SJohn.Forte@Sun.COM if (clustered) {
8937836SJohn.Forte@Sun.COM /* Find a RM set with master as the local volume */
8947836SJohn.Forte@Sun.COM
8957836SJohn.Forte@Sun.COM for (i = 0; i < rdc_maxsets; i++) {
8967836SJohn.Forte@Sun.COM setnumber = i + 1;
8977836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
8987836SJohn.Forte@Sun.COM "sndr.set%d.phost", setnumber);
8997836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf,
9007836SJohn.Forte@Sun.COM CFG_MAX_BUF) < 0)
9017836SJohn.Forte@Sun.COM break;
9027836SJohn.Forte@Sun.COM
9037836SJohn.Forte@Sun.COM if (self_check(buf))
9047836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
9057836SJohn.Forte@Sun.COM "sndr.set%d.primary", setnumber);
9067836SJohn.Forte@Sun.COM else
9077836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
9087836SJohn.Forte@Sun.COM "sndr.set%d.secondary", setnumber);
9097836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf,
9107836SJohn.Forte@Sun.COM CFG_MAX_BUF) < 0)
9117836SJohn.Forte@Sun.COM break;
9127836SJohn.Forte@Sun.COM
9137836SJohn.Forte@Sun.COM if (strcmp(buf, master) != 0)
9147836SJohn.Forte@Sun.COM continue;
9157836SJohn.Forte@Sun.COM
9167836SJohn.Forte@Sun.COM /* Get cluster tag of matching entry */
9177836SJohn.Forte@Sun.COM
9187836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
9197836SJohn.Forte@Sun.COM "sndr.set%d.cnode", setnumber);
9207836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf,
9217836SJohn.Forte@Sun.COM CFG_MAX_BUF) < 0)
9227836SJohn.Forte@Sun.COM break;
9237836SJohn.Forte@Sun.COM if ((strlen(buf) == 0) || (buf[0] == '-'))
9247836SJohn.Forte@Sun.COM ctag = strdup("local");
9257836SJohn.Forte@Sun.COM else
9267836SJohn.Forte@Sun.COM ctag = strdup(buf);
9277836SJohn.Forte@Sun.COM break;
9287836SJohn.Forte@Sun.COM }
9297836SJohn.Forte@Sun.COM }
9307836SJohn.Forte@Sun.COM
9317836SJohn.Forte@Sun.COM /* Not already enabled, so enable a dependent */
9327836SJohn.Forte@Sun.COM if (ctag) {
9337836SJohn.Forte@Sun.COM (void) sprintf(cmd, "%s -C %s -e dep %s %s %s", IIADM,
9347836SJohn.Forte@Sun.COM ctag, master, shadow, bitmap);
9357836SJohn.Forte@Sun.COM free(ctag);
9367836SJohn.Forte@Sun.COM } else
9377836SJohn.Forte@Sun.COM (void) sprintf(cmd, "%s -e dep %s %s %s", IIADM, master,
9387836SJohn.Forte@Sun.COM shadow, bitmap);
9397836SJohn.Forte@Sun.COM }
9407836SJohn.Forte@Sun.COM
9417836SJohn.Forte@Sun.COM cfg_close(cfg);
9427836SJohn.Forte@Sun.COM
9437836SJohn.Forte@Sun.COM if (system(cmd) != 0) {
9447836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
9457836SJohn.Forte@Sun.COM gettext("Point-in-Time Copy snapshot failed for %s %s %s."
9467836SJohn.Forte@Sun.COM " Please check validity of ndr_ii entry"),
9477836SJohn.Forte@Sun.COM master, shadow, bitmap);
9487836SJohn.Forte@Sun.COM cfg_close(cfg);
9497836SJohn.Forte@Sun.COM UNLOCKCFG();
9507836SJohn.Forte@Sun.COM return;
9517836SJohn.Forte@Sun.COM }
9527836SJohn.Forte@Sun.COM
9537836SJohn.Forte@Sun.COM /*
9547836SJohn.Forte@Sun.COM * PIT Copy enable or update was fine, so update the ndr_ii entry
9557836SJohn.Forte@Sun.COM * to "noupdate", to prevent invalid point in time copies.
9567836SJohn.Forte@Sun.COM */
9577836SJohn.Forte@Sun.COM
9587836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL) {
9597836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
9607836SJohn.Forte@Sun.COM gettext("%s: error opening config"),
9617836SJohn.Forte@Sun.COM program);
9627836SJohn.Forte@Sun.COM rdc_warn(NULL,
9637836SJohn.Forte@Sun.COM gettext("error opening config"));
9647836SJohn.Forte@Sun.COM UNLOCKCFG();
9657836SJohn.Forte@Sun.COM return;
9667836SJohn.Forte@Sun.COM }
9677836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_WRLOCK)) {
9687836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
9697836SJohn.Forte@Sun.COM gettext("%s: error locking config"),
9707836SJohn.Forte@Sun.COM program);
9717836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("error locking config"));
9727836SJohn.Forte@Sun.COM cfg_close(cfg);
9737836SJohn.Forte@Sun.COM UNLOCKCFG();
9747836SJohn.Forte@Sun.COM return;
9757836SJohn.Forte@Sun.COM }
9767836SJohn.Forte@Sun.COM
9777836SJohn.Forte@Sun.COM /* get ndr_ii entries until a match is found */
9787836SJohn.Forte@Sun.COM for (i = 0; ; i++) {
9797836SJohn.Forte@Sun.COM setnumber = i + 1;
9807836SJohn.Forte@Sun.COM
9817836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ndr_ii.set%d.shadow",
9827836SJohn.Forte@Sun.COM setnumber);
9837836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
9847836SJohn.Forte@Sun.COM break;
9857836SJohn.Forte@Sun.COM if (strcmp(buf, shadow) != 0)
9867836SJohn.Forte@Sun.COM continue;
9877836SJohn.Forte@Sun.COM
9887836SJohn.Forte@Sun.COM /* Found the matching entry */
9897836SJohn.Forte@Sun.COM
9907836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state",
9917836SJohn.Forte@Sun.COM setnumber);
9927836SJohn.Forte@Sun.COM if ((cfg_put_cstring(cfg, key, NOUPDATE,
9937836SJohn.Forte@Sun.COM strlen(NOUPDATE)) < 0) || (cfg_commit(cfg) < 0)) {
9947836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
9957836SJohn.Forte@Sun.COM gettext("%s: unable to update \"%s\" "
9967836SJohn.Forte@Sun.COM "in configuration storage: %s"),
9977836SJohn.Forte@Sun.COM program, buf, cfg_error(&sev));
9987836SJohn.Forte@Sun.COM rdc_warn(NULL,
9997836SJohn.Forte@Sun.COM gettext("unable to update \"%s\" "
10007836SJohn.Forte@Sun.COM "in configuration storage: %s"),
10017836SJohn.Forte@Sun.COM buf, cfg_error(&sev));
10027836SJohn.Forte@Sun.COM }
10037836SJohn.Forte@Sun.COM break;
10047836SJohn.Forte@Sun.COM }
10057836SJohn.Forte@Sun.COM cfg_close(cfg);
10067836SJohn.Forte@Sun.COM UNLOCKCFG();
10077836SJohn.Forte@Sun.COM }
10087836SJohn.Forte@Sun.COM
10097836SJohn.Forte@Sun.COM void
cleanup_hostlist(rdc_status_t * rdc_info)10107836SJohn.Forte@Sun.COM cleanup_hostlist(rdc_status_t *rdc_info)
10117836SJohn.Forte@Sun.COM {
10127836SJohn.Forte@Sun.COM int i, j, k;
10137836SJohn.Forte@Sun.COM char *host, *exhost;
10147836SJohn.Forte@Sun.COM
10157836SJohn.Forte@Sun.COM
10167836SJohn.Forte@Sun.COM (void) mutex_lock(&host_list->hosts_mutex);
10177836SJohn.Forte@Sun.COM for (i = 0; i < host_list->numhosts; i++) {
10187836SJohn.Forte@Sun.COM int found = 0;
10197836SJohn.Forte@Sun.COM for (j = 0; (j < rdc_maxsets) && !found; j++) {
10207836SJohn.Forte@Sun.COM if (!rdc_info->rdc_set[j].flags & RDC_ENABLED)
10217836SJohn.Forte@Sun.COM continue;
10227836SJohn.Forte@Sun.COM if ((!host_list->configured[i]) ||
10237836SJohn.Forte@Sun.COM (host_list->hosts[i] == '\0')) {
10247836SJohn.Forte@Sun.COM (void) mutex_unlock(&host_list->hosts_mutex);
10257836SJohn.Forte@Sun.COM return;
10267836SJohn.Forte@Sun.COM }
10277836SJohn.Forte@Sun.COM
10287836SJohn.Forte@Sun.COM host = rdc_info->rdc_set[j].secondary.intf;
10297836SJohn.Forte@Sun.COM if (strcmp(host_list->hosts[i], host) == 0)
10307836SJohn.Forte@Sun.COM found++;
10317836SJohn.Forte@Sun.COM }
10327836SJohn.Forte@Sun.COM if (j == rdc_maxsets) {
10337836SJohn.Forte@Sun.COM /*
10347836SJohn.Forte@Sun.COM * this set is not in the kernel, so remove from list
10357836SJohn.Forte@Sun.COM */
10367836SJohn.Forte@Sun.COM exhost = host_list->hosts[i];
10377836SJohn.Forte@Sun.COM if (exhost) {
10387836SJohn.Forte@Sun.COM free(exhost);
10397836SJohn.Forte@Sun.COM exhost = NULL;
10407836SJohn.Forte@Sun.COM }
10417836SJohn.Forte@Sun.COM
10427836SJohn.Forte@Sun.COM k = i;
10437836SJohn.Forte@Sun.COM while (k < host_list->numhosts) {
10447836SJohn.Forte@Sun.COM host_list->hosts[k] = k < host_list->numhosts - 1 ?
10457836SJohn.Forte@Sun.COM host_list->hosts[k+1] : NULL;
10467836SJohn.Forte@Sun.COM k++;
10477836SJohn.Forte@Sun.COM }
10487836SJohn.Forte@Sun.COM host_list->numhosts--;
10497836SJohn.Forte@Sun.COM
10507836SJohn.Forte@Sun.COM bcopy(&host_list->configured[i+1],
10517836SJohn.Forte@Sun.COM &host_list->configured[i],
10527836SJohn.Forte@Sun.COM (MAXHOSTS - i + 1) * sizeof (int));
10537836SJohn.Forte@Sun.COM host_list->configured[MAXHOSTS - 1] = 0;
10547836SJohn.Forte@Sun.COM }
10557836SJohn.Forte@Sun.COM }
10567836SJohn.Forte@Sun.COM (void) mutex_unlock(&host_list->hosts_mutex);
10577836SJohn.Forte@Sun.COM }
10587836SJohn.Forte@Sun.COM
10597836SJohn.Forte@Sun.COM /*
10607836SJohn.Forte@Sun.COM * explicity remove a host from the host list
10617836SJohn.Forte@Sun.COM * also update the configured array
10627836SJohn.Forte@Sun.COM * called in rdc_sync, just before exiting a thread.
10637836SJohn.Forte@Sun.COM */
10647836SJohn.Forte@Sun.COM void
remove_from_hostlist(char * host)10657836SJohn.Forte@Sun.COM remove_from_hostlist(char *host)
10667836SJohn.Forte@Sun.COM {
10677836SJohn.Forte@Sun.COM int i, k;
10687836SJohn.Forte@Sun.COM char *exhost;
10697836SJohn.Forte@Sun.COM
10707836SJohn.Forte@Sun.COM /* why bother? */
10717836SJohn.Forte@Sun.COM if ((!host) || (host[0] == '\0'))
10727836SJohn.Forte@Sun.COM return;
10737836SJohn.Forte@Sun.COM
10747836SJohn.Forte@Sun.COM (void) mutex_lock(&host_list->hosts_mutex);
10757836SJohn.Forte@Sun.COM for (i = 0; i < host_list->numhosts; i++) {
10767836SJohn.Forte@Sun.COM if (strcmp(host, host_list->hosts[i]) == 0) { /* found it */
10777836SJohn.Forte@Sun.COM exhost = host_list->hosts[i];
10787836SJohn.Forte@Sun.COM if (exhost) {
10797836SJohn.Forte@Sun.COM free(exhost);
10807836SJohn.Forte@Sun.COM exhost = NULL;
10817836SJohn.Forte@Sun.COM }
10827836SJohn.Forte@Sun.COM k = i;
10837836SJohn.Forte@Sun.COM while (k < host_list->numhosts) {
10847836SJohn.Forte@Sun.COM host_list->hosts[k] = k < host_list->numhosts - 1 ?
10857836SJohn.Forte@Sun.COM host_list->hosts[k+1] : NULL;
10867836SJohn.Forte@Sun.COM k++;
10877836SJohn.Forte@Sun.COM }
10887836SJohn.Forte@Sun.COM host_list->numhosts--;
10897836SJohn.Forte@Sun.COM bcopy(&host_list->configured[i+1],
10907836SJohn.Forte@Sun.COM &host_list->configured[i],
10917836SJohn.Forte@Sun.COM (MAXHOSTS - i + 1) * sizeof (int));
10927836SJohn.Forte@Sun.COM host_list->configured[MAXHOSTS - 1] = 0;
10937836SJohn.Forte@Sun.COM }
10947836SJohn.Forte@Sun.COM
10957836SJohn.Forte@Sun.COM }
10967836SJohn.Forte@Sun.COM (void) mutex_unlock(&host_list->hosts_mutex);
10977836SJohn.Forte@Sun.COM }
10987836SJohn.Forte@Sun.COM /*
10997836SJohn.Forte@Sun.COM * Check to see if this host isn't in our list, so needs a new rdcsyncd proc
11007836SJohn.Forte@Sun.COM */
11017836SJohn.Forte@Sun.COM int
isnewhost(char * host)11027836SJohn.Forte@Sun.COM isnewhost(char *host)
11037836SJohn.Forte@Sun.COM {
11047836SJohn.Forte@Sun.COM int i;
11057836SJohn.Forte@Sun.COM int new;
11067836SJohn.Forte@Sun.COM
11077836SJohn.Forte@Sun.COM if (self_check(host)) {
11087836SJohn.Forte@Sun.COM return (0);
11097836SJohn.Forte@Sun.COM }
11107836SJohn.Forte@Sun.COM
11117836SJohn.Forte@Sun.COM (void) mutex_lock(&host_list->hosts_mutex);
11127836SJohn.Forte@Sun.COM new = 1;
11137836SJohn.Forte@Sun.COM for (i = 0; i < MAXHOSTS; i++) {
11147836SJohn.Forte@Sun.COM if (host_list->configured[i] == 0) {
11157836SJohn.Forte@Sun.COM host_list->configured[i] = 1;
11167836SJohn.Forte@Sun.COM host_list->hosts[i] = strdup(host);
11177836SJohn.Forte@Sun.COM host_list->numhosts++;
11187836SJohn.Forte@Sun.COM break;
11197836SJohn.Forte@Sun.COM }
11207836SJohn.Forte@Sun.COM if (strcmp(host, host_list->hosts[i]) == 0) {
11217836SJohn.Forte@Sun.COM new = 0;
11227836SJohn.Forte@Sun.COM break;
11237836SJohn.Forte@Sun.COM }
11247836SJohn.Forte@Sun.COM }
11257836SJohn.Forte@Sun.COM (void) mutex_unlock(&host_list->hosts_mutex);
11267836SJohn.Forte@Sun.COM if (i == MAXHOSTS)
11277836SJohn.Forte@Sun.COM new = 0;
11287836SJohn.Forte@Sun.COM return (new);
11297836SJohn.Forte@Sun.COM }
11307836SJohn.Forte@Sun.COM
11317836SJohn.Forte@Sun.COM
11327836SJohn.Forte@Sun.COM /*
11337836SJohn.Forte@Sun.COM * Look for a matching volume name in our remembered list.
11347836SJohn.Forte@Sun.COM */
11357836SJohn.Forte@Sun.COM int
volume_match(char * buf,char ** volume_list,int volumes)11367836SJohn.Forte@Sun.COM volume_match(char *buf, char **volume_list, int volumes)
11377836SJohn.Forte@Sun.COM {
11387836SJohn.Forte@Sun.COM int i;
11397836SJohn.Forte@Sun.COM char *vol;
11407836SJohn.Forte@Sun.COM
11417836SJohn.Forte@Sun.COM for (i = 0; i < volumes; i++) {
11427836SJohn.Forte@Sun.COM vol = volume_list[i];
11437836SJohn.Forte@Sun.COM if (strcmp(buf, vol) == 0) {
11447836SJohn.Forte@Sun.COM return (1);
11457836SJohn.Forte@Sun.COM }
11467836SJohn.Forte@Sun.COM }
11477836SJohn.Forte@Sun.COM return (0);
11487836SJohn.Forte@Sun.COM }
11497836SJohn.Forte@Sun.COM
11507836SJohn.Forte@Sun.COM
11517836SJohn.Forte@Sun.COM /*
11527836SJohn.Forte@Sun.COM * A sync has completed to a group. We can only update the ndr_ii entries
11537836SJohn.Forte@Sun.COM * if all the members of the group have completed their syncs OK.
11547836SJohn.Forte@Sun.COM * It would be bad to allow some members of the group to have PIT Copy snapshots
11557836SJohn.Forte@Sun.COM * taken and others not, as they need to be consistent.
11567836SJohn.Forte@Sun.COM */
11577836SJohn.Forte@Sun.COM void
group_complete(char * group)11587836SJohn.Forte@Sun.COM group_complete(char *group)
11597836SJohn.Forte@Sun.COM {
11607836SJohn.Forte@Sun.COM char **volumes = NULL;
11617836SJohn.Forte@Sun.COM spcs_s_info_t ustatus;
11627836SJohn.Forte@Sun.COM rdc_config_t parms = { 0 };
11637836SJohn.Forte@Sun.COM char buf[CFG_MAX_BUF];
11647836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
11657836SJohn.Forte@Sun.COM CFGFILE *cfg = NULL;
11667836SJohn.Forte@Sun.COM int i;
11677836SJohn.Forte@Sun.COM int setnumber;
11687836SJohn.Forte@Sun.COM int found;
11697836SJohn.Forte@Sun.COM int replicating = 0;
11707836SJohn.Forte@Sun.COM char primary[NSC_MAXPATH];
11717836SJohn.Forte@Sun.COM char secondary[NSC_MAXPATH];
11727836SJohn.Forte@Sun.COM char phost[MAX_RDC_HOST_SIZE];
11737836SJohn.Forte@Sun.COM char shost[MAX_RDC_HOST_SIZE];
11747836SJohn.Forte@Sun.COM rdc_set_t *rdc_set;
11757836SJohn.Forte@Sun.COM int sev;
11767836SJohn.Forte@Sun.COM char *local_file;
11777836SJohn.Forte@Sun.COM int size;
11787836SJohn.Forte@Sun.COM
11797836SJohn.Forte@Sun.COM ustatus = spcs_s_ucreate();
11807836SJohn.Forte@Sun.COM
11817836SJohn.Forte@Sun.COM size = sizeof (char *) * rdc_maxsets;
11827836SJohn.Forte@Sun.COM volumes = malloc(size);
11837836SJohn.Forte@Sun.COM if (volumes == NULL) {
11847836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
11857836SJohn.Forte@Sun.COM gettext("%s: unable to allocate %ld bytes"),
11867836SJohn.Forte@Sun.COM program, size);
11877836SJohn.Forte@Sun.COM rdc_warn(NULL,
11887836SJohn.Forte@Sun.COM gettext("unable to allocate %ld bytes"), size);
11897836SJohn.Forte@Sun.COM goto done;
11907836SJohn.Forte@Sun.COM }
11917836SJohn.Forte@Sun.COM bzero(volumes, size);
11927836SJohn.Forte@Sun.COM
11937836SJohn.Forte@Sun.COM /*
11947836SJohn.Forte@Sun.COM * If all members of this group are replicating
11957836SJohn.Forte@Sun.COM * set ii_ndr state to "update". Otherwise leave them alone.
11967836SJohn.Forte@Sun.COM */
11977836SJohn.Forte@Sun.COM LOCKCFG();
11987836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL) {
11997836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
12007836SJohn.Forte@Sun.COM gettext("%s: error opening lconfig"),
12017836SJohn.Forte@Sun.COM program);
12027836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("error opening config"));
12037836SJohn.Forte@Sun.COM UNLOCKCFG();
12047836SJohn.Forte@Sun.COM goto done;
12057836SJohn.Forte@Sun.COM }
12067836SJohn.Forte@Sun.COM
12077836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_RDLOCK)) {
12087836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
12097836SJohn.Forte@Sun.COM gettext("%s: error locking config"),
12107836SJohn.Forte@Sun.COM program);
12117836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("error locking config"));
12127836SJohn.Forte@Sun.COM goto done;
12137836SJohn.Forte@Sun.COM }
12147836SJohn.Forte@Sun.COM
12157836SJohn.Forte@Sun.COM found = 0;
12167836SJohn.Forte@Sun.COM
12177836SJohn.Forte@Sun.COM /* get all RM entries, with a matching group, that are replicating */
12187836SJohn.Forte@Sun.COM for (i = 0; i < rdc_maxsets; i++) {
12197836SJohn.Forte@Sun.COM setnumber = i + 1;
12207836SJohn.Forte@Sun.COM
12217836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
12227836SJohn.Forte@Sun.COM "sndr.set%d.group", setnumber);
12237836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
12247836SJohn.Forte@Sun.COM break;
12257836SJohn.Forte@Sun.COM
12267836SJohn.Forte@Sun.COM if (strcmp(buf, group) != 0)
12277836SJohn.Forte@Sun.COM continue;
12287836SJohn.Forte@Sun.COM
12297836SJohn.Forte@Sun.COM /* Found a matching entry */
12307836SJohn.Forte@Sun.COM
12317836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
12327836SJohn.Forte@Sun.COM "sndr.set%d.primary", setnumber);
12337836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, primary, sizeof (primary)) < 0)
12347836SJohn.Forte@Sun.COM break;
1235*11576SSurya.Prakki@Sun.COM (void) strcpy(parms.rdc_set->primary.file, primary);
12367836SJohn.Forte@Sun.COM
12377836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
12387836SJohn.Forte@Sun.COM "sndr.set%d.phost", setnumber);
12397836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, phost, sizeof (phost)) < 0)
12407836SJohn.Forte@Sun.COM break;
1241*11576SSurya.Prakki@Sun.COM (void) strcpy(parms.rdc_set->primary.intf, phost);
12427836SJohn.Forte@Sun.COM
12437836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
12447836SJohn.Forte@Sun.COM "sndr.set%d.secondary", setnumber);
12457836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, secondary,
12467836SJohn.Forte@Sun.COM sizeof (secondary)) < 0)
12477836SJohn.Forte@Sun.COM break;
1248*11576SSurya.Prakki@Sun.COM (void) strcpy(parms.rdc_set->secondary.file, secondary);
12497836SJohn.Forte@Sun.COM
12507836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
12517836SJohn.Forte@Sun.COM "sndr.set%d.shost", setnumber);
12527836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, shost, sizeof (shost)) < 0)
12537836SJohn.Forte@Sun.COM break;
1254*11576SSurya.Prakki@Sun.COM (void) strcpy(parms.rdc_set->secondary.intf, shost);
12557836SJohn.Forte@Sun.COM
12567836SJohn.Forte@Sun.COM parms.command = RDC_CMD_STATUS;
12577836SJohn.Forte@Sun.COM if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus) < 0) {
12587836SJohn.Forte@Sun.COM continue;
12597836SJohn.Forte@Sun.COM }
12607836SJohn.Forte@Sun.COM
12617836SJohn.Forte@Sun.COM /* We found a matching set */
12627836SJohn.Forte@Sun.COM found++;
12637836SJohn.Forte@Sun.COM
12647836SJohn.Forte@Sun.COM if (self_check(phost))
12657836SJohn.Forte@Sun.COM local_file = primary;
12667836SJohn.Forte@Sun.COM else
12677836SJohn.Forte@Sun.COM local_file = secondary;
12687836SJohn.Forte@Sun.COM
12697836SJohn.Forte@Sun.COM rdc_set = &parms.rdc_set[0];
12707836SJohn.Forte@Sun.COM if (!(rdc_set->flags & RDC_LOGGING) &&
12717836SJohn.Forte@Sun.COM !(rdc_set->flags & RDC_SYNCING)) {
12727836SJohn.Forte@Sun.COM volumes[replicating] = strdup(local_file);
12737836SJohn.Forte@Sun.COM if (volumes[replicating] == NULL) {
12747836SJohn.Forte@Sun.COM size = strlen(local_file);
12757836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
12767836SJohn.Forte@Sun.COM gettext("%s: unable to allocate %ld bytes"),
12777836SJohn.Forte@Sun.COM program, size);
12787836SJohn.Forte@Sun.COM rdc_warn(NULL,
12797836SJohn.Forte@Sun.COM gettext("unable to allocate %ld bytes"),
12807836SJohn.Forte@Sun.COM size);
12817836SJohn.Forte@Sun.COM goto done;
12827836SJohn.Forte@Sun.COM }
12837836SJohn.Forte@Sun.COM /* We remember all replicating sets */
12847836SJohn.Forte@Sun.COM replicating++;
12857836SJohn.Forte@Sun.COM } else
12867836SJohn.Forte@Sun.COM break; /* Not all replicating, so done */
12877836SJohn.Forte@Sun.COM }
12887836SJohn.Forte@Sun.COM
12897836SJohn.Forte@Sun.COM if (found != replicating)
12907836SJohn.Forte@Sun.COM goto done;
12917836SJohn.Forte@Sun.COM
12927836SJohn.Forte@Sun.COM /* All replicating, so update ndr_ii state fields */
12937836SJohn.Forte@Sun.COM
12947836SJohn.Forte@Sun.COM cfg_unlock(cfg);
12957836SJohn.Forte@Sun.COM
12967836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_WRLOCK)) {
12977836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
12987836SJohn.Forte@Sun.COM gettext("%s: error locking lconfig"),
12997836SJohn.Forte@Sun.COM program);
13007836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("error locking config"));
13017836SJohn.Forte@Sun.COM goto done;
13027836SJohn.Forte@Sun.COM }
13037836SJohn.Forte@Sun.COM
13047836SJohn.Forte@Sun.COM /*
13057836SJohn.Forte@Sun.COM * Search through the ndr_ii entries for entries
13067836SJohn.Forte@Sun.COM * that match the saved secondary volume names.
13077836SJohn.Forte@Sun.COM * Set state to "update".
13087836SJohn.Forte@Sun.COM */
13097836SJohn.Forte@Sun.COM
13107836SJohn.Forte@Sun.COM for (i = 0; ; i++) {
13117836SJohn.Forte@Sun.COM setnumber = i + 1;
13127836SJohn.Forte@Sun.COM
13137836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary",
13147836SJohn.Forte@Sun.COM setnumber);
13157836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
13167836SJohn.Forte@Sun.COM break;
13177836SJohn.Forte@Sun.COM
13187836SJohn.Forte@Sun.COM if (!volume_match(buf, volumes, found)) {
13197836SJohn.Forte@Sun.COM continue;
13207836SJohn.Forte@Sun.COM }
13217836SJohn.Forte@Sun.COM
13227836SJohn.Forte@Sun.COM /* Got a matching entry */
13237836SJohn.Forte@Sun.COM
13247836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
13257836SJohn.Forte@Sun.COM "ndr_ii.set%d.state", setnumber);
13267836SJohn.Forte@Sun.COM if ((cfg_put_cstring(cfg, key, UPDATE, strlen(UPDATE)) < 0) ||
13277836SJohn.Forte@Sun.COM (cfg_commit(cfg) < 0)) {
13287836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
13297836SJohn.Forte@Sun.COM gettext("%s: unable to update \"%s\" "
13307836SJohn.Forte@Sun.COM "in configuration storage: %s"),
13317836SJohn.Forte@Sun.COM program, buf, cfg_error(&sev));
13327836SJohn.Forte@Sun.COM rdc_warn(NULL,
13337836SJohn.Forte@Sun.COM gettext("unable to update \"%s\" "
13347836SJohn.Forte@Sun.COM "in configuration storage: %s"),
13357836SJohn.Forte@Sun.COM buf, cfg_error(&sev));
13367836SJohn.Forte@Sun.COM }
13377836SJohn.Forte@Sun.COM }
13387836SJohn.Forte@Sun.COM
13397836SJohn.Forte@Sun.COM
13407836SJohn.Forte@Sun.COM done:
13417836SJohn.Forte@Sun.COM if (cfg) {
13427836SJohn.Forte@Sun.COM cfg_close(cfg);
13437836SJohn.Forte@Sun.COM UNLOCKCFG();
13447836SJohn.Forte@Sun.COM }
13457836SJohn.Forte@Sun.COM spcs_s_ufree(&ustatus);
13467836SJohn.Forte@Sun.COM if (volumes) {
13477836SJohn.Forte@Sun.COM for (i = 0; i < replicating; i++)
13487836SJohn.Forte@Sun.COM free(volumes[i]);
13497836SJohn.Forte@Sun.COM free(volumes);
13507836SJohn.Forte@Sun.COM }
13517836SJohn.Forte@Sun.COM }
13527836SJohn.Forte@Sun.COM
13537836SJohn.Forte@Sun.COM
13547836SJohn.Forte@Sun.COM /*
13557836SJohn.Forte@Sun.COM * Sync started to a member of a group.
13567836SJohn.Forte@Sun.COM * If all members of the group are in ndr_ii state "update" then take an PIT
13577836SJohn.Forte@Sun.COM * snapshot on all of them. This will provide a consistent point-in-time
13587836SJohn.Forte@Sun.COM * copy until whatever syncs take place are all completed.
13597836SJohn.Forte@Sun.COM */
13607836SJohn.Forte@Sun.COM void
group_start(char * group)13617836SJohn.Forte@Sun.COM group_start(char *group)
13627836SJohn.Forte@Sun.COM {
13637836SJohn.Forte@Sun.COM char **masters = NULL;
13647836SJohn.Forte@Sun.COM char **shadows = NULL;
13657836SJohn.Forte@Sun.COM char **bitmaps = NULL;
13667836SJohn.Forte@Sun.COM char cmd[256];
13677836SJohn.Forte@Sun.COM char buf[CFG_MAX_BUF];
13687836SJohn.Forte@Sun.COM char key[CFG_MAX_KEY];
13697836SJohn.Forte@Sun.COM CFGFILE *cfg = NULL;
13707836SJohn.Forte@Sun.COM int i;
13717836SJohn.Forte@Sun.COM int j;
13727836SJohn.Forte@Sun.COM int setnumber;
13737836SJohn.Forte@Sun.COM int found;
13747836SJohn.Forte@Sun.COM int sndr_sets = 0;
13757836SJohn.Forte@Sun.COM int update_needed = 0;
13767836SJohn.Forte@Sun.COM int sev;
13777836SJohn.Forte@Sun.COM char *ctag = NULL;
13787836SJohn.Forte@Sun.COM int commit = 0;
13797836SJohn.Forte@Sun.COM int size;
13807836SJohn.Forte@Sun.COM
13817836SJohn.Forte@Sun.COM size = sizeof (char *) * rdc_maxsets;
13827836SJohn.Forte@Sun.COM masters = malloc(size);
13837836SJohn.Forte@Sun.COM if (masters == NULL) {
13847836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
13857836SJohn.Forte@Sun.COM gettext("%s: unable to allocate %ld bytes"),
13867836SJohn.Forte@Sun.COM program, size);
13877836SJohn.Forte@Sun.COM rdc_warn(NULL,
13887836SJohn.Forte@Sun.COM gettext("unable to allocate %ld bytes"), size);
13897836SJohn.Forte@Sun.COM goto done;
13907836SJohn.Forte@Sun.COM }
13917836SJohn.Forte@Sun.COM bzero(masters, size);
13927836SJohn.Forte@Sun.COM shadows = malloc(size);
13937836SJohn.Forte@Sun.COM if (shadows == NULL) {
13947836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
13957836SJohn.Forte@Sun.COM gettext("%s: unable to allocate %ld bytes"),
13967836SJohn.Forte@Sun.COM program, size);
13977836SJohn.Forte@Sun.COM rdc_warn(NULL,
13987836SJohn.Forte@Sun.COM gettext("unable to allocate %ld bytes"), size);
13997836SJohn.Forte@Sun.COM goto done;
14007836SJohn.Forte@Sun.COM }
14017836SJohn.Forte@Sun.COM bzero(shadows, size);
14027836SJohn.Forte@Sun.COM bitmaps = malloc(size);
14037836SJohn.Forte@Sun.COM if (bitmaps == NULL) {
14047836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
14057836SJohn.Forte@Sun.COM gettext("%s: unable to allocate %ld bytes"),
14067836SJohn.Forte@Sun.COM program, size);
14077836SJohn.Forte@Sun.COM rdc_warn(NULL,
14087836SJohn.Forte@Sun.COM gettext("unable to allocate %ld bytes"), size);
14097836SJohn.Forte@Sun.COM goto done;
14107836SJohn.Forte@Sun.COM }
14117836SJohn.Forte@Sun.COM bzero(bitmaps, size);
14127836SJohn.Forte@Sun.COM
14137836SJohn.Forte@Sun.COM LOCKCFG();
14147836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL) {
14157836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
14167836SJohn.Forte@Sun.COM gettext("%s: error opening config"),
14177836SJohn.Forte@Sun.COM program);
14187836SJohn.Forte@Sun.COM rdc_warn(NULL,
14197836SJohn.Forte@Sun.COM gettext("error opening config"));
14207836SJohn.Forte@Sun.COM UNLOCKCFG();
14217836SJohn.Forte@Sun.COM goto done;
14227836SJohn.Forte@Sun.COM }
14237836SJohn.Forte@Sun.COM
14247836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_WRLOCK)) {
14257836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
14267836SJohn.Forte@Sun.COM gettext("%s: error locking config"),
14277836SJohn.Forte@Sun.COM program);
14287836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("error locking config"));
14297836SJohn.Forte@Sun.COM goto done;
14307836SJohn.Forte@Sun.COM }
14317836SJohn.Forte@Sun.COM
14327836SJohn.Forte@Sun.COM /* Now get all Remote Mirror entries with a matching group */
14337836SJohn.Forte@Sun.COM for (i = 0; i < rdc_maxsets; i++) {
14347836SJohn.Forte@Sun.COM setnumber = i + 1;
14357836SJohn.Forte@Sun.COM
14367836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
14377836SJohn.Forte@Sun.COM "sndr.set%d.group", setnumber);
14387836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
14397836SJohn.Forte@Sun.COM break;
14407836SJohn.Forte@Sun.COM
14417836SJohn.Forte@Sun.COM if (strcmp(buf, group) != 0)
14427836SJohn.Forte@Sun.COM continue;
14437836SJohn.Forte@Sun.COM
14447836SJohn.Forte@Sun.COM /* Found a matching entry */
14457836SJohn.Forte@Sun.COM
14467836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
14477836SJohn.Forte@Sun.COM "sndr.set%d.phost", setnumber);
14487836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0)
14497836SJohn.Forte@Sun.COM break;
14507836SJohn.Forte@Sun.COM
14517836SJohn.Forte@Sun.COM if (self_check(buf)) {
14527836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d.primary",
14537836SJohn.Forte@Sun.COM setnumber);
14547836SJohn.Forte@Sun.COM } else {
14557836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
14567836SJohn.Forte@Sun.COM "sndr.set%d.secondary", setnumber);
14577836SJohn.Forte@Sun.COM }
14587836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0)
14597836SJohn.Forte@Sun.COM break;
14607836SJohn.Forte@Sun.COM
14617836SJohn.Forte@Sun.COM masters[sndr_sets] = strdup(buf);
14627836SJohn.Forte@Sun.COM if (masters[sndr_sets] == NULL) {
14637836SJohn.Forte@Sun.COM size = strlen(buf);
14647836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
14657836SJohn.Forte@Sun.COM gettext("%s: unable to allocate %ld bytes"),
14667836SJohn.Forte@Sun.COM program, size);
14677836SJohn.Forte@Sun.COM rdc_warn(NULL,
14687836SJohn.Forte@Sun.COM gettext("unable to allocate %ld bytes"), size);
14697836SJohn.Forte@Sun.COM goto done;
14707836SJohn.Forte@Sun.COM }
14717836SJohn.Forte@Sun.COM sndr_sets++;
14727836SJohn.Forte@Sun.COM
14737836SJohn.Forte@Sun.COM if (ctag == NULL && clustered) {
14747836SJohn.Forte@Sun.COM /* Get cluster tag of matching entry */
14757836SJohn.Forte@Sun.COM
14767836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "sndr.set%d.cnode",
14777836SJohn.Forte@Sun.COM setnumber);
14787836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) >= 0)
14797836SJohn.Forte@Sun.COM ctag = strdup(buf);
14807836SJohn.Forte@Sun.COM }
14817836SJohn.Forte@Sun.COM }
14827836SJohn.Forte@Sun.COM
14837836SJohn.Forte@Sun.COM /*
14847836SJohn.Forte@Sun.COM * Search through the ndr_ii entries for entries
14857836SJohn.Forte@Sun.COM * that match the saved local volume names and are in "update" state.
14867836SJohn.Forte@Sun.COM */
14877836SJohn.Forte@Sun.COM
14887836SJohn.Forte@Sun.COM update_needed = 0;
14897836SJohn.Forte@Sun.COM
14907836SJohn.Forte@Sun.COM for (i = 0; ; i++) {
14917836SJohn.Forte@Sun.COM setnumber = i + 1;
14927836SJohn.Forte@Sun.COM
14937836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary",
14947836SJohn.Forte@Sun.COM setnumber);
14957836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
14967836SJohn.Forte@Sun.COM break;
14977836SJohn.Forte@Sun.COM
14987836SJohn.Forte@Sun.COM if (!volume_match(buf, masters, sndr_sets))
14997836SJohn.Forte@Sun.COM continue;
15007836SJohn.Forte@Sun.COM
15017836SJohn.Forte@Sun.COM /* Got a matching entry */
15027836SJohn.Forte@Sun.COM
15037836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ndr_ii.set%d.shadow",
15047836SJohn.Forte@Sun.COM setnumber);
15057836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
15067836SJohn.Forte@Sun.COM break;
15077836SJohn.Forte@Sun.COM shadows[update_needed] = strdup(buf);
15087836SJohn.Forte@Sun.COM if (shadows[update_needed] == NULL) {
15097836SJohn.Forte@Sun.COM size = strlen(buf);
15107836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
15117836SJohn.Forte@Sun.COM gettext("%s: unable to allocate %ld bytes"),
15127836SJohn.Forte@Sun.COM program, size);
15137836SJohn.Forte@Sun.COM rdc_warn(NULL,
15147836SJohn.Forte@Sun.COM gettext("unable to allocate %ld bytes"), size);
15157836SJohn.Forte@Sun.COM goto done;
15167836SJohn.Forte@Sun.COM }
15177836SJohn.Forte@Sun.COM
15187836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ndr_ii.set%d.bitmap",
15197836SJohn.Forte@Sun.COM setnumber);
15207836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
15217836SJohn.Forte@Sun.COM break;
15227836SJohn.Forte@Sun.COM }
15237836SJohn.Forte@Sun.COM bitmaps[update_needed] = strdup(buf);
15247836SJohn.Forte@Sun.COM if (bitmaps[update_needed] == NULL) {
15257836SJohn.Forte@Sun.COM size = strlen(buf);
15267836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
15277836SJohn.Forte@Sun.COM gettext("%s: unable to allocate %ld bytes"),
15287836SJohn.Forte@Sun.COM program, size);
15297836SJohn.Forte@Sun.COM rdc_warn(NULL,
15307836SJohn.Forte@Sun.COM gettext("unable to allocate %ld bytes"), size);
15317836SJohn.Forte@Sun.COM goto done;
15327836SJohn.Forte@Sun.COM }
15337836SJohn.Forte@Sun.COM
15347836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state",
15357836SJohn.Forte@Sun.COM setnumber);
15367836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
15377836SJohn.Forte@Sun.COM break;
15387836SJohn.Forte@Sun.COM }
15397836SJohn.Forte@Sun.COM if (strcmp(buf, UPDATE) != 0) {
15407836SJohn.Forte@Sun.COM break;
15417836SJohn.Forte@Sun.COM }
15427836SJohn.Forte@Sun.COM
15437836SJohn.Forte@Sun.COM update_needed++;
15447836SJohn.Forte@Sun.COM }
15457836SJohn.Forte@Sun.COM
15467836SJohn.Forte@Sun.COM if (update_needed != sndr_sets) {
15477836SJohn.Forte@Sun.COM #ifdef DEBUG
15487836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
15497836SJohn.Forte@Sun.COM gettext("%s: group sync: no Point-in-Time Copy snapshot "
15507836SJohn.Forte@Sun.COM "for %s"), program, group);
15517836SJohn.Forte@Sun.COM #endif
15527836SJohn.Forte@Sun.COM goto done;
15537836SJohn.Forte@Sun.COM }
15547836SJohn.Forte@Sun.COM
15557836SJohn.Forte@Sun.COM /* All RM sets in the group have an ndr_ii entry in "update" state */
15567836SJohn.Forte@Sun.COM
15577836SJohn.Forte@Sun.COM /* Issue PIT Copy snapshot commands for all sets in the group */
15587836SJohn.Forte@Sun.COM for (j = 0; j < sndr_sets; j++) {
15597836SJohn.Forte@Sun.COM found = 0;
15607836SJohn.Forte@Sun.COM
15617836SJohn.Forte@Sun.COM /* get ii entries until a match is found */
15627836SJohn.Forte@Sun.COM for (i = 0; ; i++) {
15637836SJohn.Forte@Sun.COM setnumber = i + 1;
15647836SJohn.Forte@Sun.COM
15657836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ii.set%d.shadow",
15667836SJohn.Forte@Sun.COM setnumber);
15677836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
15687836SJohn.Forte@Sun.COM break;
15697836SJohn.Forte@Sun.COM if (strcmp(buf, shadows[j]) != 0)
15707836SJohn.Forte@Sun.COM continue;
15717836SJohn.Forte@Sun.COM
15727836SJohn.Forte@Sun.COM /* Matching shadow found, so ii already enabled */
15737836SJohn.Forte@Sun.COM found = 1;
15747836SJohn.Forte@Sun.COM break;
15757836SJohn.Forte@Sun.COM }
15767836SJohn.Forte@Sun.COM
15777836SJohn.Forte@Sun.COM if (commit)
15787836SJohn.Forte@Sun.COM if (cfg_commit(cfg) < 0)
15797836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("commit config error"));
15807836SJohn.Forte@Sun.COM cfg_close(cfg);
15817836SJohn.Forte@Sun.COM
15827836SJohn.Forte@Sun.COM if (found) {
15837836SJohn.Forte@Sun.COM (void) sprintf(cmd, "%s -u s %s", IIADM, shadows[j]);
15847836SJohn.Forte@Sun.COM } else {
15857836SJohn.Forte@Sun.COM if (ctag) {
15867836SJohn.Forte@Sun.COM (void) sprintf(cmd, "%s -C %s -e dep %s %s %s",
15877836SJohn.Forte@Sun.COM IIADM, ctag, masters[j], shadows[j],
15887836SJohn.Forte@Sun.COM bitmaps[j]);
15897836SJohn.Forte@Sun.COM free(ctag);
15907836SJohn.Forte@Sun.COM ctag = NULL;
15917836SJohn.Forte@Sun.COM } else
15927836SJohn.Forte@Sun.COM (void) sprintf(cmd, "%s -e dep %s %s %s", IIADM,
15937836SJohn.Forte@Sun.COM masters[j], shadows[j], bitmaps[j]);
15947836SJohn.Forte@Sun.COM }
15957836SJohn.Forte@Sun.COM
15967836SJohn.Forte@Sun.COM if (system(cmd) != 0) {
15977836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
15987836SJohn.Forte@Sun.COM gettext("%s: group sync: Point-in-Time Copy"
15997836SJohn.Forte@Sun.COM " snapshot failed for %s"),
16007836SJohn.Forte@Sun.COM program, masters[j]);
16017836SJohn.Forte@Sun.COM
16027836SJohn.Forte@Sun.COM goto done;
16037836SJohn.Forte@Sun.COM }
16047836SJohn.Forte@Sun.COM
16057836SJohn.Forte@Sun.COM if ((cfg = cfg_open(NULL)) == NULL) {
16067836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
16077836SJohn.Forte@Sun.COM gettext("%s: error opening config"),
16087836SJohn.Forte@Sun.COM program);
16097836SJohn.Forte@Sun.COM rdc_warn(NULL,
16107836SJohn.Forte@Sun.COM gettext("error opening config"));
16117836SJohn.Forte@Sun.COM goto done;
16127836SJohn.Forte@Sun.COM }
16137836SJohn.Forte@Sun.COM if (!cfg_lock(cfg, CFG_WRLOCK)) {
16147836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
16157836SJohn.Forte@Sun.COM gettext("%s: error locking config"),
16167836SJohn.Forte@Sun.COM program);
16177836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("error locking config"));
16187836SJohn.Forte@Sun.COM goto done;
16197836SJohn.Forte@Sun.COM }
16207836SJohn.Forte@Sun.COM commit = 0;
16217836SJohn.Forte@Sun.COM
16227836SJohn.Forte@Sun.COM /* PIT enable or update was fine, so update the ndr_ii entry */
16237836SJohn.Forte@Sun.COM
16247836SJohn.Forte@Sun.COM /* get ndr_ii entries until a match is found */
16257836SJohn.Forte@Sun.COM for (i = 0; ; i++) {
16267836SJohn.Forte@Sun.COM setnumber = i + 1;
16277836SJohn.Forte@Sun.COM
16287836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key),
16297836SJohn.Forte@Sun.COM "ndr_ii.set%d.shadow", setnumber);
16307836SJohn.Forte@Sun.COM if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0)
16317836SJohn.Forte@Sun.COM break;
16327836SJohn.Forte@Sun.COM if (strcmp(buf, shadows[j]) != 0)
16337836SJohn.Forte@Sun.COM continue;
16347836SJohn.Forte@Sun.COM
16357836SJohn.Forte@Sun.COM /* Found the matching entry */
16367836SJohn.Forte@Sun.COM
16377836SJohn.Forte@Sun.COM (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state",
16387836SJohn.Forte@Sun.COM setnumber);
16397836SJohn.Forte@Sun.COM if (cfg_put_cstring(cfg, key, NOUPDATE,
16407836SJohn.Forte@Sun.COM strlen(NOUPDATE)) < 0) {
16417836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
16427836SJohn.Forte@Sun.COM gettext("%s: unable to update \"%s\" "
16437836SJohn.Forte@Sun.COM "in configuration storage: %s"),
16447836SJohn.Forte@Sun.COM program, buf, cfg_error(&sev));
16457836SJohn.Forte@Sun.COM rdc_warn(NULL,
16467836SJohn.Forte@Sun.COM gettext("unable to update \"%s\" "
16477836SJohn.Forte@Sun.COM "in configuration storage: %s"),
16487836SJohn.Forte@Sun.COM buf, cfg_error(&sev));
16497836SJohn.Forte@Sun.COM } else
16507836SJohn.Forte@Sun.COM commit = 1;
16517836SJohn.Forte@Sun.COM break;
16527836SJohn.Forte@Sun.COM }
16537836SJohn.Forte@Sun.COM }
16547836SJohn.Forte@Sun.COM
16557836SJohn.Forte@Sun.COM if (commit)
16567836SJohn.Forte@Sun.COM if (cfg_commit(cfg) < 0)
16577836SJohn.Forte@Sun.COM rdc_warn(NULL, gettext("commit config error"));
16587836SJohn.Forte@Sun.COM
16597836SJohn.Forte@Sun.COM spcs_log("sndr", NULL,
16607836SJohn.Forte@Sun.COM gettext("%s: group sync: Point-in-Time Copy snapshots completed "
16617836SJohn.Forte@Sun.COM "for %s"), program, group);
16627836SJohn.Forte@Sun.COM
16637836SJohn.Forte@Sun.COM done:
16647836SJohn.Forte@Sun.COM if (ctag)
16657836SJohn.Forte@Sun.COM free(ctag);
16667836SJohn.Forte@Sun.COM
16677836SJohn.Forte@Sun.COM if (cfg) {
16687836SJohn.Forte@Sun.COM cfg_close(cfg);
16697836SJohn.Forte@Sun.COM UNLOCKCFG();
16707836SJohn.Forte@Sun.COM }
16717836SJohn.Forte@Sun.COM
16727836SJohn.Forte@Sun.COM if (masters) {
16737836SJohn.Forte@Sun.COM for (i = 0; i < sndr_sets; i++) {
16747836SJohn.Forte@Sun.COM if (masters[i])
16757836SJohn.Forte@Sun.COM free(masters[i]);
16767836SJohn.Forte@Sun.COM }
16777836SJohn.Forte@Sun.COM free(masters);
16787836SJohn.Forte@Sun.COM }
16797836SJohn.Forte@Sun.COM
16807836SJohn.Forte@Sun.COM if (shadows) {
16817836SJohn.Forte@Sun.COM for (i = 0; i < update_needed; i++) {
16827836SJohn.Forte@Sun.COM if (shadows[i])
16837836SJohn.Forte@Sun.COM free(shadows[i]);
16847836SJohn.Forte@Sun.COM }
16857836SJohn.Forte@Sun.COM free(shadows);
16867836SJohn.Forte@Sun.COM }
16877836SJohn.Forte@Sun.COM
16887836SJohn.Forte@Sun.COM if (bitmaps) {
16897836SJohn.Forte@Sun.COM for (i = 0; i < update_needed; i++) {
16907836SJohn.Forte@Sun.COM if (bitmaps[i])
16917836SJohn.Forte@Sun.COM free(bitmaps[i]);
16927836SJohn.Forte@Sun.COM }
16937836SJohn.Forte@Sun.COM free(bitmaps);
16947836SJohn.Forte@Sun.COM }
16957836SJohn.Forte@Sun.COM }
1696