4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 #include <sys/types.h>
31 #include <sys/mnttab.h>
45 #include <sys/utsname.h>
47 #include <sys/nsctl/rdc_io.h>
48 #include <sys/nsctl/rdc_ioctl.h>
49 #include <sys/nsctl/rdc_prot.h>
51 #include <sys/nsctl/cfg.h>
52 #include <sys/nsctl/cfg_cluster.h>
54 #include <sys/unistat/spcs_s.h>
55 #include <sys/unistat/spcs_s_u.h>
56 #include <sys/unistat/spcs_errors.h>
61 * Special re-use of sndrboot to fix SNDR set IDs during post-patch processing
63 #define RDC_CMD_FIXSETIDS 0xFEEDFACE
66 * config file user level Dual copy pair structure
68 typedef struct _sd_dual_pair
{
69 char fhost
[MAX_RDC_HOST_SIZE
]; /* Hostname for primary device */
70 char fnetaddr
[RDC_MAXADDR
]; /* Host netaddr for primary device */
71 char ffile
[NSC_MAXPATH
]; /* Primary device */
72 char fbitmap
[NSC_MAXPATH
]; /* Primary bitmap device */
73 char thost
[MAX_RDC_HOST_SIZE
]; /* Hostname for secondary device */
74 char tnetaddr
[RDC_MAXADDR
]; /* Host netaddr for secondary device */
75 char tfile
[NSC_MAXPATH
]; /* Secondary device */
76 char tbitmap
[NSC_MAXPATH
]; /* Secondary bitmap device */
77 char directfile
[NSC_MAXPATH
]; /* Local FCAL direct IO volume */
78 char diskqueue
[NSC_MAXPATH
]; /* Disk Queue volume */
79 char group
[NSC_MAXPATH
]; /* Group name */
80 char lhost
[MAX_RDC_HOST_SIZE
]; /* Logical hostname for cluster */
81 int doasync
; /* Device is in sync/async mode */
82 int setid
; /* unique setid of this set */
85 #include <sys/socket.h>
86 #include <netinet/in.h>
87 #include <arpa/inet.h>
88 #include <netinet/tcp.h>
89 #include <rpc/rpc_com.h>
92 #include <sys/nsctl/librdc.h>
96 int parseopts(int, char **, int *);
97 static int rdc_operation(char *, char *, char *, char *, char *, char *, int,
98 char *, char *, char *, int, char *, int setid
);
99 static int read_libcfg(int);
100 static void usage(void);
102 extern char *basename(char *);
105 static _sd_dual_pair_t
*pair_list
;
108 struct netbuf svaddr
;
110 struct netconfig nconf
;
111 struct netconfig
*conf
;
112 struct knetconfig knconf
;
113 static int clustered
= 0;
114 static int proto_test
= 0;
118 sndrboot_lintmain(int argc
, char *argv
[])
121 main(int argc
, char *argv
[])
124 char fromhost
[MAX_RDC_HOST_SIZE
];
125 char tohost
[MAX_RDC_HOST_SIZE
];
126 char fromfile
[NSC_MAXPATH
];
127 char tofile
[NSC_MAXPATH
];
128 char frombitmap
[NSC_MAXPATH
];
129 char tobitmap
[NSC_MAXPATH
];
130 char directfile
[NSC_MAXPATH
];
131 char diskqueue
[NSC_MAXPATH
];
132 char group
[NSC_MAXPATH
];
133 char lhost
[MAX_RDC_HOST_SIZE
];
142 (void) setlocale(LC_ALL
, "");
143 (void) textdomain("rdc");
145 program
= basename(argv
[0]);
147 rc
= rdc_check_release(&required
);
150 gettext("unable to determine the current "
151 "Solaris release: %s\n"), strerror(errno
));
152 } else if (rc
== FALSE
) {
154 gettext("incorrect Solaris release (requires %s)\n"),
158 rdc_maxsets
= rdc_get_maxsets();
159 if (rdc_maxsets
== -1) {
160 spcs_log("sndr", NULL
,
161 gettext("%s unable to get maxsets value from kernel"),
165 gettext("unable to get maxsets value from kernel"));
168 pair_list
= calloc(rdc_maxsets
, sizeof (*pair_list
));
169 if (pair_list
== NULL
) {
172 "unable to allocate pair_list"
173 " array for %d sets"),
177 if (parseopts(argc
, argv
, &flag
))
179 pairs
= read_libcfg(flag
);
181 if (flag
== RDC_CMD_FIXSETIDS
) {
183 spcs_log("sndr", NULL
, gettext("Fixed %d Remote Mirror"
186 rdc_warn(NULL
, gettext("Fixed %d Remote Mirror set "
196 gettext("Config contains no dual copy sets"));
204 if (pid
== -1) { /* error forking */
209 if (pid
> 0) /* this is parent process */
213 * At this point, this is the child process. Do the operation
216 (void) strncpy(fromfile
,
217 pair_list
[pairs
].ffile
, NSC_MAXPATH
);
218 (void) strncpy(tofile
,
219 pair_list
[pairs
].tfile
, NSC_MAXPATH
);
220 (void) strncpy(frombitmap
,
221 pair_list
[pairs
].fbitmap
, NSC_MAXPATH
);
222 (void) strncpy(fromhost
,
223 pair_list
[pairs
].fhost
, MAX_RDC_HOST_SIZE
);
224 (void) strncpy(tohost
,
225 pair_list
[pairs
].thost
, MAX_RDC_HOST_SIZE
);
226 (void) strncpy(tobitmap
,
227 pair_list
[pairs
].tbitmap
, NSC_MAXPATH
);
228 (void) strncpy(directfile
,
229 pair_list
[pairs
].directfile
, NSC_MAXPATH
);
230 (void) strncpy(diskqueue
,
231 pair_list
[pairs
].diskqueue
, NSC_MAXPATH
);
232 (void) strncpy(group
,
233 pair_list
[pairs
].group
, NSC_MAXPATH
);
234 (void) strncpy(lhost
,
235 pair_list
[pairs
].lhost
, MAX_RDC_HOST_SIZE
);
237 doasync
= pair_list
[pairs
].doasync
;
238 setid
= pair_list
[pairs
].setid
;
239 if (rdc_operation(fromhost
, fromfile
, frombitmap
,
240 tohost
, tofile
, tobitmap
, flag
, directfile
, group
,
241 diskqueue
, doasync
, lhost
, setid
)
249 while ((wait((int *)0) > 0))
255 rdc_operation(fromhost
, fromfile
, frombitmap
, tohost
, tofile
,
256 tobitmap
, flag
, directfile
, group
, diskqueue
, doasync
,
258 char *fromhost
, *fromfile
, *frombitmap
;
259 char *tohost
, *tofile
, *tobitmap
;
262 char *group
, *diskqueue
;
266 const int getaddr
= (flag
== RDC_CMD_RESUME
);
267 const int rpcbind
= !getaddr
;
270 spcs_s_info_t ustatus
;
272 char fromname
[MAXHOSTNAMELEN
], toname
[MAXHOSTNAMELEN
];
277 bzero(&fromname
, MAXHOSTNAMELEN
);
278 bzero(&toname
, MAXHOSTNAMELEN
);
280 hp
= gethost_byname(fromhost
);
282 spcs_log("sndr", NULL
,
283 gettext("%s gethost_byname failed for %s"),
286 if (strcmp(hp
->h_name
, fromhost
) == 0)
287 (void) strncpy(fromname
, hp
->h_name
, MAXHOSTNAMELEN
);
289 for (i
= 0; hp
->h_aliases
[i
] != NULL
; i
++) {
290 if (strcmp(hp
->h_aliases
[i
], fromhost
) == 0)
291 (void) strncpy(fromname
, hp
->h_aliases
[i
],
295 if (fromname
[0] == '\0') {
296 spcs_log("sndr", NULL
,
297 gettext("%s host %s is not local"),
299 rdc_err(NULL
, gettext("Host %s is not local"),
302 hp
= gethost_byname(tohost
);
304 spcs_log("sndr", NULL
,
305 gettext("%s gethost_byname failed for %s"),
308 if (strcmp(hp
->h_name
, tohost
) == 0)
309 (void) strncpy(toname
, hp
->h_name
, MAXHOSTNAMELEN
);
311 for (i
= 0; hp
->h_aliases
[i
] != NULL
; i
++) {
312 if (strcmp(hp
->h_aliases
[i
], tohost
) == 0)
313 (void) strncpy(toname
, hp
->h_aliases
[i
],
317 if (toname
[0] == '\0') {
318 spcs_log("sndr", NULL
,
319 gettext("%s host %s is not local"),
321 rdc_err(NULL
, gettext("Host %s is not local"),
325 if (self_check(fromname
) && self_check(toname
)) {
326 spcs_log("sndr", NULL
,
327 gettext("%s Both %s and %s are local"),
328 program
, fromhost
, tohost
);
329 rdc_err(NULL
, gettext("Both %s and %s are local"),
334 * Now build up the address for each host including port and transport
337 svp
= get_addr(toname
, RDC_PROGRAM
, RDC_VERS_MIN
,
338 &conf
, proto_test
?NC_UDP
: NULL
, "rdc", &tinfo
, rpcbind
);
342 (void) printf("get_addr failed for Ver 4 %s\n", toname
);
344 spcs_log("sndr", NULL
,
345 gettext("%s get_addr failed for Ver 4"),
351 bzero(&svaddr
, sizeof (svaddr
));
354 parms
.rdc_set
->secondary
.addr
.len
= svaddr
.len
;
355 parms
.rdc_set
->secondary
.addr
.maxlen
= svaddr
.maxlen
;
356 parms
.rdc_set
->secondary
.addr
.buf
= (void *)svaddr
.buf
;
359 (void) fprintf(stderr
,
360 "secondary buf %x len %d\n", svaddr
.buf
, svaddr
.len
);
362 for (i
= 0; i
< svaddr
.len
; i
++)
363 (void) printf("%u ", svaddr
.buf
[i
]);
368 svp
= get_addr(fromname
, RDC_PROGRAM
, RDC_VERS_MIN
,
369 &conf
, proto_test
?NC_UDP
: NULL
, "rdc", &tinfo
, rpcbind
);
372 (void) printf("get_addr failed for Ver 4 %s\n",
382 parms
.rdc_set
->primary
.addr
.len
= svaddr
.len
;
383 parms
.rdc_set
->primary
.addr
.maxlen
= svaddr
.maxlen
;
384 parms
.rdc_set
->primary
.addr
.buf
=
388 (void) fprintf(stderr
, "primary buf %x len %d\n",
389 svaddr
.buf
, svaddr
.len
);
390 for (i
= 0; i
< svaddr
.len
; i
++)
391 (void) printf("%u ", svaddr
.buf
[i
]);
396 (void) convert_nconf_to_knconf(conf
, &knconf
);
398 (void) printf("knconf %x %s %s %x\n", knconf
.knc_semantics
,
399 knconf
.knc_protofmly
, knconf
.knc_proto
, knconf
.knc_rdev
);
401 parms
.rdc_set
->netconfig
= &knconf
;
403 parms
.rdc_set
->netconfig
= NULL
;
405 if (!clustered
&& !self_check(fromname
) && !self_check(toname
)) {
406 spcs_log("sndr", NULL
,
407 gettext("%s Neither %s nor %s is local"),
408 program
, fromhost
, tohost
);
409 rdc_err(NULL
, gettext("Neither %s nor %s is local"),
412 (void) strncpy(parms
.rdc_set
->primary
.intf
, fromhost
,
414 (void) strncpy(parms
.rdc_set
->primary
.file
, fromfile
, NSC_MAXPATH
);
415 (void) strncpy(parms
.rdc_set
->primary
.bitmap
, frombitmap
, NSC_MAXPATH
);
417 (void) strncpy(parms
.rdc_set
->secondary
.intf
, tohost
,
419 (void) strncpy(parms
.rdc_set
->secondary
.file
, tofile
, NSC_MAXPATH
);
420 (void) strncpy(parms
.rdc_set
->secondary
.bitmap
, tobitmap
, NSC_MAXPATH
);
422 (void) strncpy(parms
.rdc_set
->group_name
, group
, NSC_MAXPATH
);
423 (void) strncpy(parms
.rdc_set
->disk_queue
, diskqueue
, NSC_MAXPATH
);
425 parms
.rdc_set
->maxqfbas
= maxqfbas
;
426 parms
.rdc_set
->maxqitems
= maxqitems
;
427 parms
.rdc_set
->autosync
= autosync
;
428 parms
.rdc_set
->asyncthr
= asyncthr
;
429 parms
.rdc_set
->setid
= setid
;
431 /* gethostid(3c) is defined to return a 32bit value */
432 parms
.rdc_set
->syshostid
= (int32_t)gethostid();
436 parms
.command
= flag
;
438 if (flag
== RDC_CMD_RESUME
) {
440 parms
.options
|= RDC_OPT_ASYNC
;
442 parms
.options
|= RDC_OPT_SYNC
;
447 if (strcmp(ctag
, "-") == 0)
451 (void) fprintf(stderr
, "logical hostname: %s\n", lhost
);
454 if (strcmp(lhost
, fromname
) == 0) {
455 parms
.options
|= RDC_OPT_PRIMARY
;
456 (void) strncpy(parms
.rdc_set
->direct_file
, directfile
,
460 parms
.options
|= RDC_OPT_SECONDARY
;
461 parms
.rdc_set
->direct_file
[0] = 0; /* no fcal direct */
466 * If not clustered, don't resume sndr sets with lhost
468 if ((flag
== RDC_CMD_RESUME
) && lhost
&& strlen(lhost
))
471 if (self_check(fromname
)) {
472 parms
.options
|= RDC_OPT_PRIMARY
;
473 (void) strncpy(parms
.rdc_set
->direct_file
, directfile
,
476 parms
.options
|= RDC_OPT_SECONDARY
;
477 parms
.rdc_set
->direct_file
[0] = 0; /* no fcal direct */
481 ustatus
= spcs_s_ucreate();
484 ret
= RDC_IOCTL(RDC_CONFIG
, &parms
, NULL
, 0, 0, 0, ustatus
);
485 if (ret
!= SPCS_S_OK
) {
487 /* Surpress error messages for suspend on cluster elements */
488 if ((flag
== RDC_CMD_SUSPEND
) && (errno
== RDC_EALREADY
) &&
489 !clustered
&& lhost
&& strlen(lhost
)) {
490 spcs_s_ufree(&ustatus
);
494 (void) fprintf(stderr
,
495 gettext("Remote Mirror: %s %s %s %s %s %s\n"),
497 frombitmap
, tohost
, tofile
, tobitmap
);
499 if (errno
== RDC_EEINVAL
) {
500 spcs_log("sndr", NULL
,
501 gettext("%s %s %s %s %s %s %s %s\n%s"),
502 program
, rdc_decode_flag(flag
, parms
.options
),
503 fromhost
, fromfile
, frombitmap
,
504 tohost
, tofile
, tobitmap
,
505 gettext("invalid command option"));
507 gettext("Remote Mirror: invalid command option "
508 "'%s'"), rdc_decode_flag(flag
,
511 spcs_log("sndr", &ustatus
,
512 gettext("%s %s %s %s %s %s %s %s"),
513 program
, rdc_decode_flag(flag
, parms
.options
),
514 fromhost
, fromfile
, frombitmap
,
515 tohost
, tofile
, tobitmap
);
516 rdc_err(&ustatus
, 0);
520 spcs_log("sndr", NULL
,
521 gettext("%s %s %s %s %s %s %s %s\nSuccessful"),
522 program
, rdc_decode_flag(flag
, parms
.options
),
523 fromhost
, fromfile
, frombitmap
, tohost
, tofile
, tobitmap
);
525 spcs_s_ufree(&ustatus
);
529 * assign setid's to any existing
530 * sets without setids, making sure of course NOT to re-use a setid
533 update_setids(CFGFILE
*cfg
, int *no_id
, int highest
)
536 char buf
[CFG_MAX_BUF
];
537 char key
[CFG_MAX_KEY
];
540 /* If in a Sun Cluster, SetIDs need to have a ctag */
541 if ((ctag
= cfg_get_resource(cfg
)) != NULL
) {
543 cfg_resource(cfg
, "setid-ctag");
547 * Paranoia. IF there are any sets with setids, we don't
548 * want to re-use their number.
550 if (highest
> get_new_cfg_setid(cfg
)) {
551 bzero(&buf
, sizeof (buf
));
552 (void) sprintf(buf
, "%d", highest
);
553 if (cfg_put_cstring(cfg
, "setid.set1.value", buf
,
555 rdc_warn(NULL
, gettext("sndrboot: Unable to store "
559 for (setid
= 0; no_id
[setid
]; setid
++) {
560 bzero(&buf
, sizeof (buf
));
561 bzero(&key
, sizeof (key
));
562 (void) sprintf(buf
, "%d", get_new_cfg_setid(cfg
));
563 (void) sprintf(key
, "sndr.set%d.options", no_id
[setid
]);
564 if (cfg_put_options(cfg
, CFG_SEC_CONF
, key
, "setid", buf
) < 0)
565 rdc_warn(NULL
, gettext("sndrboot: Unable to store "
568 pair_list
[no_id
[setid
] - 1].setid
= atoi(buf
);
571 /* Restore old ctag if in a Sun Cluster */
573 cfg_resource(cfg
, ctag
);
577 if (cfg_commit(cfg
) < 0)
578 rdc_err(NULL
, gettext("sndrboot: Failed to commit setids"));
584 * this is called when the option lghn is no available in libdscfg
585 * that should only happen on an upgrade.
586 * cfg write lock must be held across this function
589 get_lghn(CFGFILE
*cfg
, char *ctag
, int setnum
, int flag
)
592 char rsgrp
[SCCONF_MAXSTRINGLEN
];
593 char cmd
[SCCONF_MAXSTRINGLEN
];
594 static char lhostname
[MAX_RDC_HOST_SIZE
];
595 char key
[CFG_MAX_KEY
];
601 bzero(&lhostname
, sizeof (lhostname
));
603 (void) sprintf(rsgrp
, "%s-stor-rg", ctag
);
605 rc
= snprintf(cmd
, SCCONF_MAXSTRINGLEN
,
606 "/usr/cluster/bin/scrgadm -pvv | fgrep HostnameList \
607 | fgrep %s | fgrep value | awk -F: '{ print $4 }'", rsgrp
);
611 rdc_err(NULL
, gettext("Error getting scrgadm output"));
614 pipe
= popen(cmd
, "r");
617 rdc_err(NULL
, gettext("Error opening pipe"));
619 rc
= fscanf(pipe
, "%s", lhostname
);
623 rdc_err(NULL
, gettext("Unable to get logical host"));
626 /* not really failing, but suspend does not have the config lock */
627 if (flag
== RDC_CMD_SUSPEND
)
630 bzero(&key
, sizeof (key
));
631 (void) snprintf(key
, sizeof (key
), "sndr.set%d.options", setnum
);
632 if (cfg_put_options(cfg
, CFG_SEC_CONF
, key
, "lghn", lhostname
) < 0)
633 rdc_warn(NULL
, gettext("sndrboot: Unable to store logical "
634 "host name in configuration database"));
636 if (cfg_commit(cfg
) < 0)
638 gettext("sndrboot: Failed to commit logical host name"));
648 * DESCRIPTION: Read the relevant config info via libcfg
651 * int i Number of pairs of devices
653 * Side Effects: The 0 to i-1 entries in the pair_list are filled.
657 read_libcfg(int flag
)
659 char fromhost
[MAX_RDC_HOST_SIZE
];
660 char fromfile
[NSC_MAXPATH
];
661 char frombitmap
[NSC_MAXPATH
];
662 char tohost
[MAX_RDC_HOST_SIZE
];
663 char tofile
[NSC_MAXPATH
];
664 char tobitmap
[NSC_MAXPATH
];
665 char directfile
[NSC_MAXPATH
];
666 char diskqueue
[NSC_MAXPATH
];
667 char group
[NSC_MAXPATH
];
668 char lhost
[MAX_RDC_HOST_SIZE
];
675 char buf
[CFG_MAX_BUF
];
676 char key
[CFG_MAX_KEY
];
677 char dummy
[NSC_MAXPATH
];
685 if ((cfg
= cfg_open("")) == NULL
)
686 rdc_err(NULL
, gettext("Error opening config"));
689 * If RDC_CMD_FIXSETIDS, we were called during post-patch install
690 * Acquire a write-lock on the cfg_lock(), so the code can attempt
693 if (flag
== RDC_CMD_FIXSETIDS
) {
694 if (!cfg_lock(cfg
, CFG_WRLOCK
))
695 rdc_err(NULL
, gettext("Error write locking config"));
696 cfg_resource(cfg
, NULL
);
698 if (!cfg_lock(cfg
, CFG_RDLOCK
))
699 rdc_err(NULL
, gettext("Error locking config"));
700 cfg_resource(cfg
, ctag
);
703 if ((numsets
= cfg_get_num_entries(cfg
, "sndr")) < 0)
704 rdc_err(NULL
, gettext("Unable to get set info from config"));
706 no_id
= (int *)calloc(numsets
+ 1, sizeof (int));
708 rdc_err(NULL
, gettext("No memory"));
711 (void) snprintf(lghn
, sizeof (lghn
), "lghn");
713 for (i
= 0; i
< rdc_maxsets
; i
++) {
716 bzero(buf
, CFG_MAX_BUF
);
717 (void) snprintf(key
, sizeof (key
), "sndr.set%d", setnumber
);
718 if (cfg_get_cstring(cfg
, key
, buf
, CFG_MAX_BUF
) < 0)
721 rc
= sscanf(buf
, "%s %s %s %s %s %s %s %s %s %s %s %s",
722 fromhost
, fromfile
, frombitmap
, tohost
, tofile
, tobitmap
,
723 directfile
, sync
, group
, dummy
, dummy
, diskqueue
);
725 rdc_err(NULL
, gettext("cfg input error (%d)"), rc
);
727 if (strcmp(directfile
, "ip") == 0)
728 (void) strcpy(directfile
, "");
730 if (strcmp(group
, "-") == 0)
731 (void) strcpy(group
, "");
733 if (strcmp(diskqueue
, "-") == 0)
734 (void) strcpy(diskqueue
, "");
736 (void) snprintf(key
, sizeof (key
),
737 "sndr.set%d.options", setnumber
);
739 if (cfg_get_single_option(cfg
, CFG_SEC_CONF
, key
,
740 lghn
, lhost
, MAX_RDC_HOST_SIZE
) < 0)
742 get_lghn(cfg
, ctag
, setnumber
, flag
));
744 if (strcmp(sync
, "sync") == 0)
746 else if (strcmp(sync
, "async") == 0)
751 gettext("Set %s:%s neither sync nor async"),
755 (void) strncpy(pair_list
[i
].fhost
, fromhost
,
757 (void) strncpy(pair_list
[i
].ffile
, fromfile
, NSC_MAXPATH
);
758 (void) strncpy(pair_list
[i
].fbitmap
, frombitmap
, NSC_MAXPATH
);
759 (void) strncpy(pair_list
[i
].thost
, tohost
, MAX_RDC_HOST_SIZE
);
760 (void) strncpy(pair_list
[i
].tfile
, tofile
, NSC_MAXPATH
);
761 (void) strncpy(pair_list
[i
].tbitmap
, tobitmap
, NSC_MAXPATH
);
762 (void) strncpy(pair_list
[i
].directfile
, directfile
,
764 (void) strncpy(pair_list
[i
].diskqueue
, diskqueue
,
766 (void) strncpy(pair_list
[i
].group
, group
, NSC_MAXPATH
);
767 (void) strncpy(pair_list
[i
].lhost
, lhost
, MAX_RDC_HOST_SIZE
);
768 pair_list
[i
].doasync
= doasync
;
770 if (cfg_get_single_option(cfg
, CFG_SEC_CONF
, key
, "setid",
771 setid
, sizeof (setid
)) < 0) {
772 no_id
[j
++] = setnumber
;
774 pair_list
[i
].setid
= atoi(setid
);
776 if (pair_list
[i
].setid
> highest
)
777 highest
= pair_list
[i
].setid
;
779 if (gethost_netaddrs(fromhost
, tohost
,
780 (char *)pair_list
[i
].fnetaddr
,
781 (char *)pair_list
[i
].tnetaddr
) < 0) {
783 spcs_log("sndr", NULL
,
784 gettext("%s unable to determine IP addresses "
785 "for hosts %s %s"), program
, fromhost
, tohost
);
786 rdc_err(NULL
, gettext("unable to determine IP "
787 "addresses for hosts %s, %s"), fromhost
, tohost
);
791 * fix any lost set ids if possible, also deal with upgrade
793 if (j
> 0 && flag
== RDC_CMD_FIXSETIDS
) {
794 (void) update_setids(cfg
, no_id
, highest
);
795 i
= j
; /* Set number of fixups */
804 parseopts(argc
, argv
, flag
)
813 while ((c
= getopt(argc
, argv
, "C:Urs")) != -1) {
815 while ((c
= getopt(argc
, argv
, "C:rs")) != -1) {
830 *flag
= RDC_CMD_RESUME
;
835 *flag
= RDC_CMD_SUSPEND
;
843 * Special fix to address no SetIds in AVS 3.1 to 3.2 install + patch
844 * Adjust set IDs, if someone invokes the following invalid command
846 * /use/sbin/sndrboot -C post-patch-setids -r -s
848 * Command will be called in post-install of the patch containing fix
851 if (clustered
&& (strcmp(ctag
, "post-patch-setids") == 0) &&
853 *flag
= RDC_CMD_FIXSETIDS
;
858 rdc_warn(NULL
, gettext("Invalid argument combination"));
862 if (!*flag
|| errflag
) {
873 (void) fprintf(stderr
, gettext("usage:\n"));
874 (void) fprintf(stderr
,
875 gettext("\t%s -r [-C tag]\t\t"
876 "resume\n"), program
);
878 (void) fprintf(stderr
,
879 gettext("\t%s -s [-C tag]\t\t"
880 "suspend\n"), program
);