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.
27 #include <sys/types.h>
29 #include <sys/mnttab.h>
43 #include <sys/nsctl/rdc_io.h>
44 #include <sys/nsctl/rdc_ioctl.h>
45 #include <sys/nsctl/rdc_prot.h>
47 #include <sys/nsctl/cfg.h>
49 #include <sys/unistat/spcs_s.h>
50 #include <sys/unistat/spcs_s_u.h>
51 #include <sys/unistat/spcs_errors.h>
56 int maxqfbas
= MAXQFBAS
;
57 int maxqitems
= MAXQITEMS
;
58 int autosync
= AUTOSYNC
;
59 int asyncthr
= ASYNCTHR
;
65 char target
[NSC_MAXPATH
];
74 for (s
= target
; i
< NSC_MAXPATH
&& (*s
= *device
++); i
++) {
75 if (*s
== 'r' && rdsk
== 0 && strncmp(device
, "dsk/", 4) == 0)
82 mntref
.mnt_special
= target
;
83 mntref
.mnt_mountp
= NULL
;
84 mntref
.mnt_fstype
= NULL
;
85 mntref
.mnt_mntopts
= NULL
;
86 mntref
.mnt_time
= NULL
;
88 mntfp
= fopen(MNTTAB
, "r");
92 gettext("can not check volume %s against mount table"),
94 /* Assume the worst, that it is mounted */
98 if (getmntany(mntfp
, &mntent
, &mntref
) != -1) {
99 /* found something before EOF */
100 (void) fclose(mntfp
);
104 (void) fclose(mntfp
);
109 /* Needs to match parsing code in rdcboot.c and rdcadm.c */
111 rdc_decode_flag(int flag
, int options
)
117 if (options
& RDC_OPT_FULL
)
118 (void) strcpy(str
, "-m");
120 (void) strcpy(str
, "-u");
121 if (options
& RDC_OPT_REVERSE
)
122 (void) strcat(str
, " -r");
125 case (RDC_CMD_DISABLE
):
126 (void) strcpy(str
, "-d");
129 case (RDC_CMD_ENABLE
):
130 if (options
& RDC_OPT_SETBMP
)
131 (void) strcpy(str
, "-e");
133 (void) strcpy(str
, "-E");
137 (void) strcpy(str
, "-l");
140 case (RDC_CMD_HEALTH
):
141 (void) strcpy(str
, "-H");
145 (void) strcpy(str
, "-w");
148 case (RDC_CMD_RECONFIG
):
149 (void) strcpy(str
, "-R ...");
152 case (RDC_CMD_TUNABLE
):
153 (void) strcpy(str
, "");
154 if (maxqfbas
!= MAXQFBAS
)
155 (void) strcat(str
, " -F");
156 if (maxqitems
!= MAXQITEMS
)
157 (void) strcat(str
, " -W");
158 if (autosync
!= AUTOSYNC
)
159 (void) strcat(str
, " -a");
160 if (asyncthr
!= ASYNCTHR
)
161 (void) strcat(str
, " -A");
162 if (qblock
!= QBLOCK
)
163 (void) strcat(str
, " -D");
166 case (RDC_CMD_SUSPEND
):
167 (void) strcpy(str
, "-s");
170 case (RDC_CMD_RESUME
):
171 (void) strcpy(str
, "-r");
174 case (RDC_CMD_RESET
):
175 (void) strcpy(str
, "-R");
179 (void) strcpy(str
, "-q a");
183 (void) strcpy(str
, "-q d");
187 (void) strcpy(str
, "-q r");
191 (void) strcpy(str
, gettext("unknown"));
200 rdc_msg(char *prefix
, spcs_s_info_t
*status
, char *string
, va_list ap
)
203 (void) fprintf(stderr
, "Remote Mirror: %s\n", prefix
);
204 spcs_s_report(*status
, stderr
);
206 (void) fprintf(stderr
, "%s: %s: ", program
, prefix
);
209 if (string
&& *string
!= '\0') {
210 (void) vfprintf(stderr
, string
, ap
);
213 (void) fprintf(stderr
, "\n");
217 rdc_err(spcs_s_info_t
*status
, char *string
, ...)
220 va_start(ap
, string
);
222 rdc_msg(gettext("Error"), status
, string
, ap
);
229 rdc_warn(spcs_s_info_t
*status
, char *string
, ...)
232 va_start(ap
, string
);
234 rdc_msg(gettext("warning"), status
, string
, ap
);
240 rdc_get_maxsets(void)
242 rdc_status_t rdc_status
;
243 spcs_s_info_t ustatus
;
247 ustatus
= spcs_s_ucreate();
249 rc
= RDC_IOCTL(RDC_STATUS
, &rdc_status
, 0, 0, 0, 0, ustatus
);
250 if (rc
== SPCS_S_ERROR
) {
251 rdc_err(&ustatus
, gettext("statistics error"));
254 spcs_s_ufree(&ustatus
);
255 return (rdc_status
.maxsets
);
259 * Look up a set in libcfg to find the setnumber.
262 * - a valid cfg handle
266 * tohost - secondary hostname
267 * tofile - secondary volume
270 * set number if found, otherwise -1 for an error
273 find_setnumber_in_libcfg(CFGFILE
*cfg
, char *ctag
, char *tohost
, char *tofile
)
277 char *buf
, *secondary
, *shost
;
284 rdc_warn(NULL
, "cfg is NULL while looking up set number");
289 entries
= cfg_get_section(cfg
, &entry
, "sndr");
292 for (setnumber
= 1; setnumber
<= entries
; setnumber
++) {
293 buf
= entry
[setnumber
- 1];
295 (void) strtok(buf
, " "); /* phost */
296 (void) strtok(NULL
, " "); /* primary */
297 (void) strtok(NULL
, " "); /* pbitmap */
298 shost
= strtok(NULL
, " ");
299 secondary
= strtok(NULL
, " ");
302 (void) strtok(NULL
, " "); /* sbitmap */
303 (void) strtok(NULL
, " "); /* type */
304 (void) strtok(NULL
, " "); /* mode */
305 (void) strtok(NULL
, " "); /* group */
306 cnode
= strtok(NULL
, " ");
308 if (ctag
&& strcmp(cnode
, ctag
) != 0) {
309 /* filter this out */
315 /* Check secondary volume name first, will get less hits */
316 if (strcmp(secondary
, tofile
) != 0) {
321 if (strcmp(shost
, tohost
) == 0) {
323 rc
= setnumber
- offset
;
330 while (setnumber
< entries
)
331 free(entry
[setnumber
++]);
339 get_group_diskq(CFGFILE
*cfg
, char *group
, char *diskq
)
342 char key
[CFG_MAX_KEY
];
343 char buf
[CFG_MAX_BUF
];
348 bzero(&key
, sizeof (key
));
349 bzero(&buf
, sizeof (buf
));
350 (void) sprintf(key
, "sndr.set%d.group", i
);
351 if (cfg_get_cstring(cfg
, key
, &buf
, sizeof (buf
)) < 0)
353 if (strncmp(group
, buf
, sizeof (buf
)) == 0) {
354 (void) sprintf(key
, "sndr.set%d.diskq", i
);
355 if (cfg_get_cstring(cfg
, key
, diskq
, CFG_MAX_BUF
) < 0) {
356 rdc_warn(NULL
, gettext("unable to retrieve "
357 "group %s's disk queue"), group
);
364 get_cfg_setid(CFGFILE
*cfg
, char *ctag
, char *tohost
, char *tofile
)
368 char key
[CFG_MAX_KEY
];
373 if ((cfg
= cfg_open(NULL
)) == NULL
) {
374 return (-1); /* message printed by caller */
376 if (!cfg_lock(cfg
, CFG_RDLOCK
)) {
381 setnum
= find_setnumber_in_libcfg(cfg
, ctag
, tohost
, tofile
);
385 (void) snprintf(key
, CFG_MAX_KEY
, "sndr.set%d.options", setnum
);
386 if (cfg_get_single_option(cfg
, CFG_SEC_CONF
, key
, "setid",
387 setid
, sizeof (setid
)) < 0) {
391 spcs_log("sndr", NULL
,
392 gettext("%s unable to get unique setid "
393 "for %s:%s"), program
, tohost
, tofile
);
400 return (atoi(setid
));
405 get_new_cfg_setid(CFGFILE
*cfg
)
408 char buf
[CFG_MAX_BUF
];
411 /* If in a Sun Cluster, SetIDs need to have a ctag */
412 if ((ctag
= cfg_get_resource(cfg
)) != NULL
) {
414 cfg_resource(cfg
, "setid-ctag");
417 if (cfg_get_cstring(cfg
, "setid.set1.value", buf
, CFG_MAX_BUF
) < 0) {
419 if (cfg_put_cstring(cfg
, "setid", "1", CFG_MAX_BUF
) < 0) {
420 rdc_err(NULL
, "Unable to store new setid");
430 bzero(&buf
, CFG_MAX_BUF
);
431 (void) snprintf(buf
, sizeof (buf
), "%d", setid
);
432 if (cfg_put_cstring(cfg
, "setid.set1.value", buf
, CFG_MAX_BUF
) < 0) {
433 rdc_err(NULL
, "Unable to store new setid");
436 /* Restore old ctag if in a Sun Cluster */
438 cfg_resource(cfg
, ctag
);
452 (void) sigfillset(&allsigs
);
453 if (sigprocmask(SIG_BLOCK
, &allsigs
, &origmask
) < 0)
454 rdc_warn(NULL
, gettext("Unable to block signals"));
460 if (sigprocmask(SIG_SETMASK
, &origmask
, NULL
) < 0)
461 rdc_warn(NULL
, gettext("Unable to unblock signals"));