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 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Just in case we're not in a build environment, make sure that
29 * TEXT_DOMAIN gets set to something.
31 #if !defined(TEXT_DOMAIN)
32 #define TEXT_DOMAIN "SYS_TEST"
45 * There are too many external factors that affect the timing of the
46 * operations, so we set the timeout to a very large value, in this
47 * case 1 day, which should handle HW timeouts, large configurations,
48 * and other potential delays.
50 #define CL_LONG_TMO 86400L /* 1 day */
51 #define CL_MEDIUM_TMO 3600L /* 1 hour */
52 #define CL_SHORT_TMO 600L /* 10 minutes */
53 #define CL_DEF_TMO 10L /* 10 seconds */
55 static md_timeval32_t def_rpcb_timeout
= { MD_CLNT_CREATE_TOUT
, 0 };
66 * Data to be sent from med_clnt_create_timed to med_create_helper via
67 * meta_client_create_retry.
70 rpcprog_t mcd_program
; /* RPC program designation */
71 rpcvers_t mcd_version
; /* RPC version */
72 char *mcd_nettype
; /* Type of network to use for RPC */
76 * Perform the work of actually doing the clnt_create for
77 * meta_client_create_retry.
80 med_create_helper(char *hostname
, void *private, struct timeval
*time_out
)
82 med_create_data_t
*cd
= (med_create_data_t
*)private;
84 return (clnt_create_timed(hostname
, cd
->mcd_program
, cd
->mcd_version
,
85 cd
->mcd_nettype
, time_out
));
89 CLIENT
*med_clnt_create_timed(
94 const md_timeval32_t
*tp
97 med_create_data_t cd
; /* Create data. */
99 cd
.mcd_program
= prog
;
100 cd
.mcd_version
= vers
;
101 cd
.mcd_nettype
= nettype
;
102 return (meta_client_create_retry(hostname
, med_create_helper
,
103 (void *)&cd
, (time_t)tp
->tv_sec
, NULL
));
107 * Set the timeout value for this client handle.
119 (void) memset(&nto
, '\0', sizeof (nto
));
121 nto
.tv_sec
= time_out
;
123 if (clnt_control(clntp
, CLSET_TIMEOUT
, (char *)&nto
) != TRUE
)
124 return (mdrpcerror(ep
, clntp
, hostname
,
125 dgettext(TEXT_DOMAIN
, "metad client set timeout")));
131 * close RPC connection
139 if (hp
->hostname
!= NULL
) {
142 if (hp
->clntp
!= NULL
) {
143 auth_destroy(hp
->clntp
->cl_auth
);
144 clnt_destroy(hp
->clntp
);
150 * open RPC connection to rpc.medd
152 static med_handle_t
*
162 /* default to local host */
163 if ((hostname
== NULL
) || (*hostname
== '\0'))
166 /* open RPC connection */
167 assert(hostname
!= NULL
);
168 if ((clntp
= med_clnt_create_timed(hostname
, MED_PROG
, MED_VERS
,
169 "tcp", &def_rpcb_timeout
)) == NULL
) {
170 if (rpc_createerr
.cf_stat
!= RPC_PROGNOTREGISTERED
)
171 clnt_pcreateerror(hostname
);
172 (void) mdrpccreateerror(ep
, hostname
,
173 "medd med_clnt_create_timed");
176 auth_destroy(clntp
->cl_auth
);
177 clntp
->cl_auth
= authsys_create_default();
178 assert(clntp
->cl_auth
!= NULL
);
181 if (cl_sto_medd(clntp
, hostname
, time_out
, ep
) != 0)
184 /* return connection */
185 hp
= Zalloc(sizeof (*hp
));
186 hp
->hostname
= Strdup(hostname
);
193 * steal and convert med_err_t
203 size_t psize
= BUFSIZ
;
208 if (medep
->med_errno
== 0) {
209 /* assert(medep->name == NULL); */
215 if ((medep
->med_node
!= NULL
) && (medep
->med_node
[0] != '\0')) {
216 (void) snprintf(p
, psize
, "%s: ", medep
->med_node
);
217 p
= &buf
[strlen(buf
)];
218 psize
= buf
+ BUFSIZ
- p
;
221 if ((medep
->med_misc
!= NULL
) && (medep
->med_misc
[0] != '\0')) {
222 (void) snprintf(p
, psize
, "%s: ", medep
->med_misc
);
223 p
= &buf
[strlen(buf
)];
224 psize
= buf
+ BUFSIZ
- p
;
227 if (medep
->med_errno
< 0) {
228 if ((emsg
= med_errnum_to_str(medep
->med_errno
)) != NULL
)
229 (void) snprintf(p
, psize
, "%s", emsg
);
231 (void) snprintf(p
, psize
, dgettext(TEXT_DOMAIN
,
232 "unknown mediator errno %d\n"), medep
->med_errno
);
234 if ((emsg
= strerror(medep
->med_errno
)) != NULL
)
235 (void) snprintf(p
, psize
, "%s", emsg
);
237 (void) snprintf(p
, psize
, dgettext(TEXT_DOMAIN
,
238 "errno %d out of range"), medep
->med_errno
);
240 (void) mderror(ep
, MDE_MED_ERROR
, buf
);
242 /* cleanup, return success */
244 if (medep
->med_node
!= NULL
)
245 Free(medep
->med_node
);
246 if (medep
->med_misc
!= NULL
)
247 Free(medep
->med_misc
);
248 (void) memset(medep
, 0, sizeof (*medep
));
252 static med_handle_t
*
259 med_handle_t
*hp
= NULL
;
263 assert(mdhp
&& mdhp
->a_cnt
> 0);
265 /* Loop through the hosts listed */
266 i
= min(mdhp
->a_cnt
, MAX_HOST_ADDRS
) - 1;
267 for (; i
>= 0; i
--) {
270 if ((hp
= open_medd(hnm
, time_out
, ep
)) == NULL
) {
271 if (mdanyrpcerror(ep
) && i
!= 0) {
279 rpc_createerr
.cf_stat
= RPC_CANTSEND
;
280 rpc_createerr
.cf_error
.re_status
= 0;
281 (void) mdrpccreateerror(ep
, mdhp
->a_nm
[0],
282 dgettext(TEXT_DOMAIN
, "medd open wrap"));
288 setup_med_transtab(md_error_t
*ep
)
290 mddb_med_t_parm_t
*tp
= NULL
;
293 size_t alloc_size
= 0;
297 if ((tp
= Zalloc(sizeof (mddb_med_t_parm_t
))) == NULL
)
298 return (mdsyserror(ep
, ENOMEM
, "setup_med_transtab"));
300 if (metaioctl(MD_MED_GET_TLEN
, tp
, &tp
->med_tp_mde
, NULL
) != 0) {
301 err
= mdstealerror(ep
, &tp
->med_tp_mde
);
305 if (tp
->med_tp_setup
== 1)
308 alloc_size
= (sizeof (mddb_med_t_parm_t
) - sizeof (mddb_med_t_ent_t
)) +
309 (sizeof (mddb_med_t_ent_t
) * tp
->med_tp_nents
);
311 if ((tp
= Realloc(tp
, alloc_size
)) == NULL
) {
312 err
= mdsyserror(ep
, ENOMEM
, "setup_med_transtab");
316 if (metaioctl(MD_MED_GET_T
, tp
, &tp
->med_tp_mde
, NULL
) != 0) {
317 err
= mdstealerror(ep
, &tp
->med_tp_mde
);
321 for (i
= 0; i
< tp
->med_tp_nents
; i
++) {
322 if (meta_stat(tp
->med_tp_ents
[i
].med_te_nm
, &statb
) == -1) {
323 md_perror("setup_med_transtab(): stat():");
324 tp
->med_tp_ents
[i
].med_te_dev
= NODEV64
;
326 tp
->med_tp_ents
[i
].med_te_dev
=
327 meta_expldev(statb
.st_rdev
);
331 if (metaioctl(MD_MED_SET_T
, tp
, &tp
->med_tp_mde
, NULL
) != 0)
332 err
= mdstealerror(ep
, &tp
->med_tp_mde
);
344 * NULLPROC - just returns a response
359 if ((hp
= open_medd(hostname
, CL_DEF_TMO
, ep
)) == NULL
)
362 if (med_null_1(NULL
, &res
, hp
->clntp
) != RPC_SUCCESS
)
363 (void) mdrpcerror(ep
, hp
->clntp
, hostname
,
364 dgettext(TEXT_DOMAIN
, "medd nullproc"));
368 xdr_free(xdr_med_err_t
, (char *)&res
);
377 * Update the mediator information on the mediator.
378 * This function does the same functionality as
379 * clnt_med_upd_data() except that it takes different
380 * argument so that host which is just a mediator, can
381 * still update its mediator record.
384 clnt_user_med_upd_data(
394 med_upd_data_args_t args
;
399 (void) memset(&args
, 0, sizeof (args
));
400 (void) memset(&res
, 0, sizeof (res
));
404 args
.med
.med_caller
= Strdup(MED_MN_CALLER
);
406 args
.med
.med_caller
= Strdup(mynode());
408 args
.med
.med_setname
= Strdup(setname
);
409 args
.med
.med_setno
= setnum
;
410 args
.med_data
= *meddp
;
412 if ((hp
= open_medd_wrap(mdhp
, CL_DEF_TMO
, ep
)) == NULL
)
415 if (med_upd_data_1(&args
, &res
, hp
->clntp
) != RPC_SUCCESS
)
416 (void) mdrpcerror(ep
, hp
->clntp
, hp
->hostname
,
417 dgettext(TEXT_DOMAIN
, "medd get record"));
419 (void) meddstealerror(ep
, &res
);
423 xdr_free(xdr_med_upd_data_args_t
, (char *)&args
);
424 xdr_free(xdr_med_err_t
, (char *)&res
);
433 * Get the mediator information from the client.
434 * The code does same functinality as clnt_med_get_data()
435 * except that it takes different arguments so that
436 * host which doesn't have set information, can still
437 * get access to mediator information
440 clnt_user_med_get_data(
452 med_get_data_res_t res
;
456 (void) memset(&args
, 0, sizeof (args
));
457 (void) memset(&res
, 0, sizeof (res
));
461 args
.med
.med_caller
= Strdup(MED_MN_CALLER
);
463 args
.med
.med_caller
= Strdup(mynode());
465 args
.med
.med_setname
= Strdup(setname
);
466 args
.med
.med_setno
= setnum
;
468 if ((hp
= open_medd_wrap(mdhp
, CL_DEF_TMO
, ep
)) == NULL
)
471 if (med_get_data_1(&args
, &res
, hp
->clntp
) != RPC_SUCCESS
)
472 (void) mdrpcerror(ep
, hp
->clntp
, hp
->hostname
,
473 dgettext(TEXT_DOMAIN
, "medd get record"));
475 (void) meddstealerror(ep
, &res
.med_status
);
480 /* copy the mediator data in meddp */
481 (void) memmove(meddp
, &res
.med_data
, sizeof (med_data_t
));
485 xdr_free(xdr_med_args_t
, (char *)&args
);
486 xdr_free(xdr_med_get_data_res_t
, (char *)&res
);
493 * Update the mediator information on the mediator.
494 * *** This is not normally called from user code, the kernel does this! ***
505 med_upd_data_args_t args
;
511 (void) memset(&args
, 0, sizeof (args
));
512 (void) memset(&res
, 0, sizeof (res
));
515 if ((sd
= metaget_setdesc(sp
, ep
)) == NULL
)
518 if (MD_MNSET_DESC(sd
))
520 * In the MN diskset, use a generic nodename, multiowner, as
521 * the node initiating the RPC request. This allows
522 * any node to access mediator information.
524 * MN diskset reconfig cycle forces consistent
525 * view of set/node/drive/mediator information across all nodes
526 * in the MN diskset. This allows the relaxation of
527 * node name checking in rpc.metamedd for MN disksets.
529 * In the traditional diskset, only a calling node that is
530 * in the mediator record's diskset nodelist can access
533 args
.med
.med_caller
= Strdup(MED_MN_CALLER
);
535 args
.med
.med_caller
= Strdup(mynode());
536 args
.med
.med_setname
= Strdup(sp
->setname
);
537 args
.med
.med_setno
= sp
->setno
;
538 args
.med_data
= *meddp
;
541 if ((hp
= open_medd_wrap(mdhp
, CL_DEF_TMO
, ep
)) == NULL
)
544 if (med_upd_data_1(&args
, &res
, hp
->clntp
) != RPC_SUCCESS
)
545 (void) mdrpcerror(ep
, hp
->clntp
, hp
->hostname
,
546 dgettext(TEXT_DOMAIN
, "medd update data"));
548 (void) meddstealerror(ep
, &res
);
552 xdr_free(xdr_med_upd_data_args_t
, (char *)&args
);
553 xdr_free(xdr_med_err_t
, (char *)&res
);
562 * Get the mediator data for this client from the mediator
574 med_get_data_res_t res
;
580 (void) memset(&args
, 0, sizeof (args
));
581 (void) memset(&res
, 0, sizeof (res
));
584 if ((sd
= metaget_setdesc(sp
, ep
)) == NULL
)
587 if (MD_MNSET_DESC(sd
))
589 * In the MN diskset, use a generic nodename, multiowner, as
590 * the node initiating the RPC request. This allows
591 * any node to access mediator information.
593 * MN diskset reconfig cycle forces consistent
594 * view of set/node/drive/mediator information across all nodes
595 * in the MN diskset. This allows the relaxation of
596 * node name checking in rpc.metamedd for MN disksets.
598 * In the traditional diskset, only a calling node that is
599 * in the mediator record's diskset nodelist can access
602 args
.med
.med_caller
= Strdup(MED_MN_CALLER
);
604 args
.med
.med_caller
= Strdup(mynode());
605 args
.med
.med_setname
= Strdup(sp
->setname
);
606 args
.med
.med_setno
= sp
->setno
;
609 if ((hp
= open_medd_wrap(mdhp
, CL_DEF_TMO
, ep
)) == NULL
)
612 if (med_get_data_1(&args
, &res
, hp
->clntp
) != RPC_SUCCESS
)
613 (void) mdrpcerror(ep
, hp
->clntp
, hp
->hostname
,
614 dgettext(TEXT_DOMAIN
, "medd get data"));
616 (void) meddstealerror(ep
, &res
.med_status
);
621 /* do something with the results */
622 (void) memmove(meddp
, &res
.med_data
, sizeof (med_data_t
));
626 xdr_free(xdr_med_args_t
, (char *)&args
);
627 xdr_free(xdr_med_get_data_res_t
, (char *)&res
);
633 * Update the mediator record on the mediator.
644 med_upd_rec_args_t args
;
650 (void) memset(&args
, 0, sizeof (args
));
651 (void) memset(&res
, 0, sizeof (res
));
654 if ((sd
= metaget_setdesc(sp
, ep
)) == NULL
)
657 if (MD_MNSET_DESC(sd
))
659 * In the MN diskset, use a generic nodename, multiowner, as
660 * the node initiating the RPC request. This allows
661 * any node to access mediator information.
663 * MN diskset reconfig cycle forces consistent
664 * view of set/node/drive/mediator information across all nodes
665 * in the MN diskset. This allows the relaxation of
666 * node name checking in rpc.metamedd for MN disksets.
668 * In the traditional diskset, only a calling node that is
669 * in the mediator record's diskset nodelist can access
672 args
.med
.med_caller
= Strdup(MED_MN_CALLER
);
674 args
.med
.med_caller
= Strdup(mynode());
675 args
.med
.med_setname
= Strdup(sp
->setname
);
676 args
.med
.med_setno
= sp
->setno
;
678 args
.med_rec
= *medrp
; /* structure assignment */
681 if ((hp
= open_medd_wrap(mdhp
, CL_DEF_TMO
, ep
)) == NULL
)
684 if (med_upd_rec_1(&args
, &res
, hp
->clntp
) != RPC_SUCCESS
)
685 (void) mdrpcerror(ep
, hp
->clntp
, hp
->hostname
,
686 dgettext(TEXT_DOMAIN
, "medd update record"));
688 (void) meddstealerror(ep
, &res
);
692 xdr_free(xdr_med_upd_rec_args_t
, (char *)&args
);
693 xdr_free(xdr_med_err_t
, (char *)&res
);
702 * Get the mediator record for this client from the mediator
714 med_get_rec_res_t res
;
720 (void) memset(&args
, 0, sizeof (args
));
721 (void) memset(&res
, 0, sizeof (res
));
724 if ((sd
= metaget_setdesc(sp
, ep
)) == NULL
)
727 if (MD_MNSET_DESC(sd
))
729 * In the MN diskset, use a generic nodename, multiowner, as
730 * the node initiating the RPC request. This allows
731 * any node to access mediator information.
733 * MN diskset reconfig cycle forces consistent
734 * view of set/node/drive/mediator information across all nodes
735 * in the MN diskset. This allows the relaxation of
736 * node name checking in rpc.metamedd for MN disksets.
738 * In the traditional diskset, only a calling node that is
739 * in the mediator record's diskset nodelist can access
742 args
.med
.med_caller
= Strdup(MED_MN_CALLER
);
744 args
.med
.med_caller
= Strdup(mynode());
745 args
.med
.med_setname
= Strdup(sp
->setname
);
746 args
.med
.med_setno
= sp
->setno
;
749 if ((hp
= open_medd_wrap(mdhp
, CL_DEF_TMO
, ep
)) == NULL
)
752 if (med_get_rec_1(&args
, &res
, hp
->clntp
) != RPC_SUCCESS
)
753 (void) mdrpcerror(ep
, hp
->clntp
, hp
->hostname
,
754 dgettext(TEXT_DOMAIN
, "medd get record"));
756 (void) meddstealerror(ep
, &res
.med_status
);
761 /* do something with the results */
762 (void) memmove(medrp
, &res
.med_rec
, sizeof (med_rec_t
));
766 xdr_free(xdr_med_args_t
, (char *)&args
);
767 xdr_free(xdr_med_get_rec_res_t
, (char *)&res
);
773 * Get the name of the host from the mediator daemon.
788 (void) memset(&res
, 0, sizeof (res
));
793 if ((hp
= open_medd(hostname
, CL_DEF_TMO
, ep
)) == NULL
)
796 if (med_hostname_1(NULL
, &res
, hp
->clntp
) != RPC_SUCCESS
)
797 (void) mdrpcerror(ep
, hp
->clntp
, hostname
,
798 dgettext(TEXT_DOMAIN
, "medd hostname"));
800 (void) meddstealerror(ep
, &res
.med_status
);
805 /* do something with the results */
808 if (ret_hostname
!= NULL
)
809 *ret_hostname
= Strdup(res
.med_hnm
);
812 xdr_free(xdr_med_hnm_res_t
, (char *)&res
);
818 meta_med_hnm2ip(md_hi_arr_t
*mp
, md_error_t
*ep
)
823 if ((max_meds
= get_max_meds(ep
)) == 0)
826 for (i
= 0; i
< max_meds
; i
++) {
827 mp
->n_lst
[i
].a_flg
= 0;
828 /* See if this is the local host */
829 if (mp
->n_lst
[i
].a_cnt
> 0 &&
830 strcmp(mp
->n_lst
[i
].a_nm
[0], mynode()) == NULL
)
831 mp
->n_lst
[i
].a_flg
|= NMIP_F_LOCAL
;
833 for (j
= 0; j
< mp
->n_lst
[i
].a_cnt
; j
++) {
835 char *hnm
= mp
->n_lst
[i
].a_nm
[j
];
838 * Cluster nodename support
840 * See if the clustering code can give us an IP addr
841 * for the stored name. If not, find it the old way
842 * which will use the public interface.
844 if (sdssc_get_priv_ipaddr(mp
->n_lst
[i
].a_nm
[j
],
845 (struct in_addr
*)&mp
->n_lst
[i
].a_ip
[j
]) !=
847 if ((hp
= gethostbyname(hnm
)) == NULL
)
848 return (mdsyserror(ep
, EADDRNOTAVAIL
,
851 /* We only do INET addresses */
852 if (hp
->h_addrtype
!= AF_INET
)
853 return (mdsyserror(ep
, EPFNOSUPPORT
,
856 /* We take the first address only */
857 if (*hp
->h_addr_list
) {
858 (void) memmove(&mp
->n_lst
[i
].a_ip
[j
],
860 sizeof (struct in_addr
));
862 return (mdsyserror(ep
, EADDRNOTAVAIL
,
872 meta_h2hi(md_h_arr_t
*mdhp
, md_hi_arr_t
*mdhip
, md_error_t
*ep
)
877 if ((max_meds
= get_max_meds(ep
)) == 0)
880 mdhip
->n_cnt
= mdhp
->n_cnt
;
882 for (i
= 0; i
< max_meds
; i
++) {
883 mdhip
->n_lst
[i
].a_flg
= 0;
884 mdhip
->n_lst
[i
].a_cnt
= mdhp
->n_lst
[i
].a_cnt
;
885 if (mdhp
->n_lst
[i
].a_cnt
== 0)
887 for (j
= 0; j
< mdhp
->n_lst
[i
].a_cnt
; j
++)
888 (void) strcpy(mdhip
->n_lst
[i
].a_nm
[j
],
889 mdhp
->n_lst
[i
].a_nm
[j
]);
895 meta_hi2h(md_hi_arr_t
*mdhip
, md_h_arr_t
*mdhp
, md_error_t
*ep
)
900 if ((max_meds
= get_max_meds(ep
)) == 0)
903 mdhp
->n_cnt
= mdhip
->n_cnt
;
904 for (i
= 0; i
< max_meds
; i
++) {
905 mdhp
->n_lst
[i
].a_cnt
= mdhip
->n_lst
[i
].a_cnt
;
906 if (mdhip
->n_lst
[i
].a_cnt
== 0)
908 for (j
= 0; j
< mdhip
->n_lst
[i
].a_cnt
; j
++)
909 (void) strcpy(mdhp
->n_lst
[i
].a_nm
[j
],
910 mdhip
->n_lst
[i
].a_nm
[j
]);
927 if (metaislocalset(sp
))
930 if ((sd
= metaget_setdesc(sp
, ep
)) == NULL
)
933 if (setup_med_transtab(ep
))
936 if (meta_h2hi(&sd
->sd_med
, &cp
->c_med
, ep
))
939 /* Make sure the ip addresses are current */
940 if (meta_med_hnm2ip(&cp
->c_med
, ep
))
946 if ((max_meds
= get_max_meds(ep
)) == 0)
949 /* Make sure metamedd still running on host - only chk nodename */
950 for (i
= 0; i
< max_meds
; i
++) {
954 if (sd
->sd_med
.n_lst
[i
].a_cnt
== 0)
957 hnm
= sd
->sd_med
.n_lst
[i
].a_nm
[0];
959 if (clnt_med_hostname(hnm
, &hostname
, ep
))
960 return (mddserror(ep
, MDE_DS_NOMEDONHOST
, sp
->setno
,
961 hnm
, NULL
, sp
->setname
));
968 * This is a general routine to get mediator information from
969 * file /etc/lvm/meddb. Commands medstat and metainit use this
970 * routine to get mediator information from all mediator hosts or update
971 * its mediator record respectively.
974 meta_mediator_info_from_file(char *sname
, int verbose
, md_error_t
*ep
)
983 med_rec_t
*rec_buf
= NULL
;
987 med_data_t save_medd
;
989 uint_t latest_med_dat_cc
= 0;
996 /* Open the meddb file */
997 if ((fd
= open(MED_DB_FILE
, O_RDONLY
, 0)) == -1) {
1000 * During the start up of the SVM services, this function
1001 * will be called with an empty sname. In that case it is
1002 * entirely possible for the MED_DB_FILE not to exist.
1003 * If so, then no need to report an error.
1005 if (sname
!= NULL
) {
1006 (void) mdsyserror(ep
, errno
, MED_DB_FILE
);
1007 mde_perror(ep
, dgettext(TEXT_DOMAIN
,
1008 "Error in opening meddb file"));
1014 /* Initialize rec_size */
1015 rec_size
= roundup(sizeof (med_rec_t
), DEV_BSIZE
);
1017 /* Allocate a record buffer */
1018 if ((rec_buf
= malloc(rec_size
)) == NULL
) {
1019 (void) mdsyserror(ep
, errno
, MED_DB_FILE
);
1020 mde_perror(ep
, dgettext(TEXT_DOMAIN
,
1021 "Error in allocating memory"));
1025 /* read the file header */
1026 if ((read(fd
, rec_buf
, rec_size
)) != rec_size
) {
1027 (void) mdsyserror(ep
, EINVAL
, MED_DB_FILE
);
1028 mde_perror(ep
, dgettext(TEXT_DOMAIN
,
1029 "Error in reading mediator record"));
1033 dbhbr
= (med_db_hdr_t
*)rec_buf
;
1035 /* Number of records in the mediator file */
1036 c
= dbhbr
->med_dbh_nm
;
1038 for (i
= 0; i
< c
; i
++) {
1039 (void) memset(rec_buf
, 0, rec_size
);
1041 if (read(fd
, rec_buf
, rec_size
) == -1) {
1042 (void) mdsyserror(ep
, errno
, MED_DB_FILE
);
1043 mde_perror(ep
, dgettext(TEXT_DOMAIN
,
1044 "Error in reading mediator record"));
1048 medrecp
= (med_rec_t
*)rec_buf
;
1051 * For oban diskset first entry in the rec_nodes field is
1052 * "multiowner" and all other entries are empty.
1053 * Check if this is really multiowner diskset.
1056 if ((strcmp(medrecp
->med_rec_nodes
[0], MED_MN_CALLER
) == 0) &&
1057 (medrecp
->med_rec_nodes
[1][0] == '\0'))
1060 obandiskset
= FALSE
;
1062 if (sname
!= NULL
) {
1064 * Continue if the set name is not in our interest.
1065 * This is required when this routine is called
1069 if (strcmp(sname
, medrecp
->med_rec_snm
) != 0) {
1074 (void) printf("%8.8s\t\t%6.6s\t%6.6s\n",
1075 gettext("Mediator"), gettext("Status"),
1081 setname
= medrecp
->med_rec_snm
;
1083 setnum
= medrecp
->med_rec_sn
;
1084 (void) memset(&medd
, '\0', sizeof (medd
));
1085 (void) memset(&mdh
, '\0', sizeof (mdh
));
1086 (void) memset(&save_medd
, '\0', sizeof (save_medd
));
1087 latest_med_dat_cc
= 0;
1089 for (j
= 0; j
< MED_MAX_HOSTS
; j
++) {
1091 * It is possible for the n_lst[j] slot to be empty
1092 * if the mediator node has already been removed so
1093 * go to the next slot.
1095 if (medrecp
->med_rec_meds
.n_lst
[j
].a_cnt
== 0)
1097 mdh
= medrecp
->med_rec_meds
.n_lst
[j
];
1099 if ((sname
!= NULL
) && (verbose
))
1100 (void) printf("%-17.17s\t",
1101 medrecp
->med_rec_meds
.n_lst
[j
].a_nm
[0]);
1103 if (clnt_user_med_get_data(&mdh
, obandiskset
,
1104 setname
, setnum
, &medd
, ep
) == -1) {
1105 if (sname
== NULL
) {
1108 if (mdanyrpcerror(ep
)) {
1110 (void) printf("%s\n",
1114 } else if (mdiserror(ep
,
1117 (void) printf("%s\n",
1121 (void) printf("%s\n",
1125 if (mdiserror(ep
, MDE_MED_ERROR
))
1131 * Make sure this node has the correct value
1132 * for the mediator record. If not we want the
1133 * highest value from the other nodes. Save it
1134 * for updating once the loop through all the
1135 * mediator nodes has completed.
1137 if (sname
== NULL
) {
1138 if (latest_med_dat_cc
<
1142 (void) memcpy(&save_medd
, &medd
,
1149 if (medd
.med_dat_fl
& MED_DFL_GOLDEN
) {
1151 (void) printf("\t%s",
1156 (void) printf("\t%s",
1160 (void) printf("\n");
1165 if (sname
== NULL
) {
1168 * Mediators only become active when there are
1169 * replica updates to the sets and this can only
1170 * occur when there is a disk in the set.
1171 * If there are no disks found then the save_medd
1172 * structure will be empty. If save_medd is empty,
1173 * do not update the set.
1175 if (save_medd
.med_dat_sn
== 0)
1178 * Update the latest mediator information
1181 (void) strlcpy(mdh
.a_nm
[0], mynode(),
1182 sizeof (mdh
.a_nm
[0]));
1184 if (clnt_user_med_upd_data(&mdh
, obandiskset
,
1185 setname
, setnum
, &save_medd
, ep
) == -1) {
1187 * We had some errors while updaing the
1188 * record. This means this metaset is
1189 * not updated with latest mediator
1200 if (medok
< ((medrecp
->med_rec_meds
.n_cnt
/ 2) + 1))
1206 if ((sname
!= NULL
) && (isSetFound
== 0)) {
1207 (void) mderror(ep
, MDE_NO_SET
, sname
);
1211 if (rec_buf
!= NULL
)
1213 if (close(fd
) < 0) {
1214 (void) mdsyserror(ep
, errno
, MED_DB_FILE
);
1215 mde_perror(ep
, dgettext(TEXT_DOMAIN
,
1216 "Error in closing meddb file"));