10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51623Stw21770 * Common Development and Distribution License (the "License").
61623Stw21770 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*8452SJohn.Wren.Kennedy@Sun.COM
220Sstevel@tonic-gate /*
237210Srayh * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #include <stdlib.h>
280Sstevel@tonic-gate #include <unistd.h>
290Sstevel@tonic-gate #include <wait.h>
300Sstevel@tonic-gate #include <sys/time.h>
310Sstevel@tonic-gate #include <syslog.h>
320Sstevel@tonic-gate
330Sstevel@tonic-gate #include <meta.h>
340Sstevel@tonic-gate #include <sys/lvm/mdio.h>
350Sstevel@tonic-gate #include <sys/lvm/md_mddb.h>
360Sstevel@tonic-gate #include <sys/lvm/md_mirror.h>
370Sstevel@tonic-gate
380Sstevel@tonic-gate #define MAX_N_ARGS 64
390Sstevel@tonic-gate #define MAX_ARG_LEN 1024
407210Srayh #define MAX_SLEEPS 99
417210Srayh #define SLEEP_MOD 5
420Sstevel@tonic-gate
430Sstevel@tonic-gate /* we reserve 1024 bytes for stdout and the same for stderr */
440Sstevel@tonic-gate #define MAX_OUT 1024
450Sstevel@tonic-gate #define MAX_ERR 1024
460Sstevel@tonic-gate #define JUNK 128 /* used to flush stdout and stderr */
470Sstevel@tonic-gate
480Sstevel@tonic-gate
490Sstevel@tonic-gate /*ARGSUSED*/
500Sstevel@tonic-gate void
mdmn_do_cmd(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)510Sstevel@tonic-gate mdmn_do_cmd(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
520Sstevel@tonic-gate {
530Sstevel@tonic-gate
540Sstevel@tonic-gate /*
550Sstevel@tonic-gate * We are given one string containing all the arguments
560Sstevel@tonic-gate * For execvp() we have to regenerate the arguments again
570Sstevel@tonic-gate */
580Sstevel@tonic-gate int arg; /* argument that is currently been built */
590Sstevel@tonic-gate int index; /* runs through arg above */
600Sstevel@tonic-gate int i; /* helper for for loop */
610Sstevel@tonic-gate char *argv[MAX_N_ARGS]; /* argument array for execvp */
620Sstevel@tonic-gate char *cp; /* runs through the given command line string */
630Sstevel@tonic-gate char *command = NULL; /* the command we call locally */
640Sstevel@tonic-gate int pout[2]; /* pipe for stdout */
650Sstevel@tonic-gate int perr[2]; /* pipe for stderr */
660Sstevel@tonic-gate pid_t pid; /* process id */
670Sstevel@tonic-gate
680Sstevel@tonic-gate cp = msg->msg_event_data;
690Sstevel@tonic-gate arg = 0;
700Sstevel@tonic-gate index = 0;
710Sstevel@tonic-gate
720Sstevel@tonic-gate /* init the args array alloc the first one and null out the rest */
730Sstevel@tonic-gate argv[0] = Malloc(MAX_ARG_LEN);
740Sstevel@tonic-gate for (i = 1; i < MAX_N_ARGS; i++) {
750Sstevel@tonic-gate argv[i] = NULL;
760Sstevel@tonic-gate }
770Sstevel@tonic-gate
780Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK; /* Ok state */;
790Sstevel@tonic-gate
800Sstevel@tonic-gate while (*cp != '\0') {
810Sstevel@tonic-gate if (arg == MAX_N_ARGS) {
820Sstevel@tonic-gate (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
830Sstevel@tonic-gate "PANIC: too many arguments specified\n"));
840Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_HANDLER_FAILED;
850Sstevel@tonic-gate goto out;
860Sstevel@tonic-gate }
870Sstevel@tonic-gate if (index == MAX_ARG_LEN) {
880Sstevel@tonic-gate (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
890Sstevel@tonic-gate "PANIC: argument too long\n"));
900Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_HANDLER_FAILED;
910Sstevel@tonic-gate goto out;
920Sstevel@tonic-gate }
930Sstevel@tonic-gate
940Sstevel@tonic-gate if ((*cp != ' ') && (*cp != '\t')) {
950Sstevel@tonic-gate /*
960Sstevel@tonic-gate * No space or tab: copy char into current
970Sstevel@tonic-gate * argv and advance both pointers
980Sstevel@tonic-gate */
990Sstevel@tonic-gate
1000Sstevel@tonic-gate argv[arg][index] = *cp;
1010Sstevel@tonic-gate cp++; /* next char in command line */
1020Sstevel@tonic-gate index++; /* next char in argument */
1030Sstevel@tonic-gate } else {
1040Sstevel@tonic-gate /*
1050Sstevel@tonic-gate * space or tab: terminate current argv,
1060Sstevel@tonic-gate * advance arg, reset pointer into arg,
1070Sstevel@tonic-gate * advance pointer in command line
1080Sstevel@tonic-gate */
1090Sstevel@tonic-gate argv[arg][index] = '\0';
1100Sstevel@tonic-gate arg++; /* next argument */
1110Sstevel@tonic-gate argv[arg] = Malloc(MAX_ARG_LEN);
1120Sstevel@tonic-gate cp++; /* next char in command line */
1130Sstevel@tonic-gate index = 0; /* starts at char 0 */
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate }
1160Sstevel@tonic-gate /* terminate the last real argument */
1170Sstevel@tonic-gate argv[arg][index] = '\0';
1180Sstevel@tonic-gate /* the last argument is an NULL pointer */
1190Sstevel@tonic-gate argv[++arg] = NULL;
1200Sstevel@tonic-gate if (pipe(pout) < 0) {
1210Sstevel@tonic-gate (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1220Sstevel@tonic-gate "PANIC: pipe failed\n"));
1230Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_HANDLER_FAILED;
1240Sstevel@tonic-gate goto out;
1250Sstevel@tonic-gate }
1260Sstevel@tonic-gate if (pipe(perr) < 0) {
1270Sstevel@tonic-gate (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1280Sstevel@tonic-gate "PANIC: pipe failed\n"));
1290Sstevel@tonic-gate (void) close(pout[0]);
1300Sstevel@tonic-gate (void) close(pout[1]);
1310Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_HANDLER_FAILED;
1320Sstevel@tonic-gate goto out;
1330Sstevel@tonic-gate }
1340Sstevel@tonic-gate command = Strdup(argv[0]);
1350Sstevel@tonic-gate (void) strcat(argv[0], ".rpc_call");
1360Sstevel@tonic-gate pid = fork1();
1370Sstevel@tonic-gate if (pid == (pid_t)-1) {
1380Sstevel@tonic-gate (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1390Sstevel@tonic-gate "PANIC: fork failed\n"));
1400Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_HANDLER_FAILED;
1410Sstevel@tonic-gate (void) close(pout[0]);
1420Sstevel@tonic-gate (void) close(pout[1]);
1430Sstevel@tonic-gate (void) close(perr[0]);
1440Sstevel@tonic-gate (void) close(perr[1]);
1450Sstevel@tonic-gate goto out;
1460Sstevel@tonic-gate } else if (pid == (pid_t)0) {
1470Sstevel@tonic-gate /* child */
1480Sstevel@tonic-gate (void) close(0);
1490Sstevel@tonic-gate /* close the reading channels of pout and perr */
1500Sstevel@tonic-gate (void) close(pout[0]);
1510Sstevel@tonic-gate (void) close(perr[0]);
1520Sstevel@tonic-gate /* redirect stdout */
1530Sstevel@tonic-gate if (dup2(pout[1], 1) < 0) {
1540Sstevel@tonic-gate (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1550Sstevel@tonic-gate "PANIC: dup2 failed\n"));
1560Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_HANDLER_FAILED;
1570Sstevel@tonic-gate return;
1580Sstevel@tonic-gate }
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate /* redirect stderr */
1610Sstevel@tonic-gate if (dup2(perr[1], 2) < 0) {
1620Sstevel@tonic-gate (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1630Sstevel@tonic-gate "PANIC: dup2 failed\n"));
1640Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_HANDLER_FAILED;
1650Sstevel@tonic-gate return;
1660Sstevel@tonic-gate }
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate (void) execvp(command, (char *const *)argv);
1690Sstevel@tonic-gate perror("execvp");
1700Sstevel@tonic-gate _exit(1);
1710Sstevel@tonic-gate } else {
1720Sstevel@tonic-gate /* parent process */
1730Sstevel@tonic-gate int stat_loc;
1740Sstevel@tonic-gate char *out, *err; /* for stdout and stderr of child */
1750Sstevel@tonic-gate int i; /* index into the aboves */
1760Sstevel@tonic-gate char junk[JUNK];
1770Sstevel@tonic-gate int out_done = 0;
1780Sstevel@tonic-gate int err_done = 0;
1790Sstevel@tonic-gate int out_read = 0;
1800Sstevel@tonic-gate int err_read = 0;
1810Sstevel@tonic-gate int maxfd;
1820Sstevel@tonic-gate fd_set rset;
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate /* close the writing channels of pout and perr */
1860Sstevel@tonic-gate (void) close(pout[1]);
1870Sstevel@tonic-gate (void) close(perr[1]);
1880Sstevel@tonic-gate resp->mmr_out = Malloc(MAX_OUT);
1890Sstevel@tonic-gate resp->mmr_err = Malloc(MAX_ERR);
1900Sstevel@tonic-gate resp->mmr_out_size = MAX_OUT;
1910Sstevel@tonic-gate resp->mmr_err_size = MAX_ERR;
1920Sstevel@tonic-gate out = resp->mmr_out;
1930Sstevel@tonic-gate err = resp->mmr_err;
1940Sstevel@tonic-gate FD_ZERO(&rset);
1950Sstevel@tonic-gate while ((out_done == 0) || (err_done == 0)) {
1960Sstevel@tonic-gate FD_SET(pout[0], &rset);
1970Sstevel@tonic-gate FD_SET(perr[0], &rset);
1980Sstevel@tonic-gate maxfd = max(pout[0], perr[0]) + 1;
1990Sstevel@tonic-gate (void) select(maxfd, &rset, NULL, NULL, NULL);
2000Sstevel@tonic-gate
2010Sstevel@tonic-gate /*
2020Sstevel@tonic-gate * Did the child produce some output to stdout?
2030Sstevel@tonic-gate * If so, read it until we either reach the end of the
2040Sstevel@tonic-gate * output or until we read MAX_OUT bytes.
2050Sstevel@tonic-gate * Whatever comes first.
2060Sstevel@tonic-gate * In case we already read MAX_OUT bytes we simply
2070Sstevel@tonic-gate * read away the output into a junk buffer.
2080Sstevel@tonic-gate * Just to make the child happy
2090Sstevel@tonic-gate */
2100Sstevel@tonic-gate if (FD_ISSET(pout[0], &rset)) {
2110Sstevel@tonic-gate if (MAX_OUT - out_read - 1 > 0) {
2120Sstevel@tonic-gate i = read(pout[0], out,
2137210Srayh MAX_OUT - out_read);
2140Sstevel@tonic-gate out_read += i;
2150Sstevel@tonic-gate out += i;
2160Sstevel@tonic-gate } else {
2170Sstevel@tonic-gate /* buffer full, empty stdout */
2180Sstevel@tonic-gate i = read(pout[0], junk, JUNK);
2190Sstevel@tonic-gate }
2200Sstevel@tonic-gate if (i == 0) {
2210Sstevel@tonic-gate /* stdout is closed by child */
2220Sstevel@tonic-gate out_done++;
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate }
2250Sstevel@tonic-gate /* same comment as above | sed -e 's/stdout/stderr/' */
2260Sstevel@tonic-gate if (FD_ISSET(perr[0], &rset)) {
2270Sstevel@tonic-gate if (MAX_ERR - err_read - 1 > 0) {
2280Sstevel@tonic-gate i = read(perr[0], err,
2297210Srayh MAX_ERR - err_read);
2300Sstevel@tonic-gate err_read += i;
2310Sstevel@tonic-gate err += i;
2320Sstevel@tonic-gate } else {
2330Sstevel@tonic-gate /* buffer full, empty stderr */
2340Sstevel@tonic-gate i = read(perr[0], junk, JUNK);
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate if (i == 0) {
2370Sstevel@tonic-gate /* stderr is closed by child */
2380Sstevel@tonic-gate err_done++;
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate }
2410Sstevel@tonic-gate }
2420Sstevel@tonic-gate resp->mmr_out[out_read] = '\0';
2430Sstevel@tonic-gate resp->mmr_err[err_read] = '\0';
2440Sstevel@tonic-gate
2450Sstevel@tonic-gate while (waitpid(pid, &stat_loc, 0) < 0) {
2460Sstevel@tonic-gate if (errno != EINTR) {
2470Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_HANDLER_FAILED;
2480Sstevel@tonic-gate break;
2490Sstevel@tonic-gate }
2500Sstevel@tonic-gate }
2510Sstevel@tonic-gate if (errno == 0)
2520Sstevel@tonic-gate resp->mmr_exitval = WEXITSTATUS(stat_loc);
2530Sstevel@tonic-gate
2540Sstevel@tonic-gate (void) close(pout[0]);
2550Sstevel@tonic-gate (void) close(perr[0]);
2560Sstevel@tonic-gate }
2570Sstevel@tonic-gate out:
2580Sstevel@tonic-gate for (i = 0; i < MAX_N_ARGS; i++) {
2590Sstevel@tonic-gate if (argv[i] != NULL) {
2600Sstevel@tonic-gate free(argv[i]);
2610Sstevel@tonic-gate }
2620Sstevel@tonic-gate }
2630Sstevel@tonic-gate if (command != NULL) {
2640Sstevel@tonic-gate Free(command);
2650Sstevel@tonic-gate }
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate
2680Sstevel@tonic-gate /*
2690Sstevel@tonic-gate * This is for checking if a metadevice is opened, and for
2700Sstevel@tonic-gate * locking in case it is not and for
2710Sstevel@tonic-gate * unlocking a locked device
2720Sstevel@tonic-gate */
2730Sstevel@tonic-gate /*ARGSUSED*/
2740Sstevel@tonic-gate void
mdmn_do_clu(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)2750Sstevel@tonic-gate mdmn_do_clu(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
2760Sstevel@tonic-gate {
2770Sstevel@tonic-gate if (msg->msg_type == MD_MN_MSG_CLU_CHECK) {
2780Sstevel@tonic-gate md_isopen_t *d;
2790Sstevel@tonic-gate int ret;
2800Sstevel@tonic-gate
2810Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK; /* Ok state */;
2820Sstevel@tonic-gate resp->mmr_out_size = 0;
2830Sstevel@tonic-gate resp->mmr_err_size = 0;
2840Sstevel@tonic-gate resp->mmr_out = NULL;
2850Sstevel@tonic-gate resp->mmr_err = NULL;
2860Sstevel@tonic-gate d = (md_isopen_t *)(void *)msg->msg_event_data;
2870Sstevel@tonic-gate ret = metaioctl(MD_IOCISOPEN, d, &(d->mde), NULL);
2880Sstevel@tonic-gate /*
2890Sstevel@tonic-gate * In case the ioctl succeeded, return the open state of
2900Sstevel@tonic-gate * the metadevice. Otherwise we return the error the ioctl
2910Sstevel@tonic-gate * produced. As this is not zero, no attempt is made to
2920Sstevel@tonic-gate * remove/rename the metadevice later
2930Sstevel@tonic-gate */
2940Sstevel@tonic-gate
2950Sstevel@tonic-gate if (ret == 0) {
2960Sstevel@tonic-gate resp->mmr_exitval = d->isopen;
2970Sstevel@tonic-gate } else {
2980Sstevel@tonic-gate /*
2990Sstevel@tonic-gate * When doing a metaclear, one node after the other
3000Sstevel@tonic-gate * does the two steps:
3010Sstevel@tonic-gate * - check on all nodes if this md is opened.
3020Sstevel@tonic-gate * - remove the md locally.
3030Sstevel@tonic-gate * When the 2nd node asks all nodes if the md is
3040Sstevel@tonic-gate * open it starts with the first node.
3050Sstevel@tonic-gate * As this already removed the md, the check
3060Sstevel@tonic-gate * returns MDE_UNIT_NOT_SETUP.
3070Sstevel@tonic-gate * In order to not keep the 2nd node from proceeding,
3080Sstevel@tonic-gate * we map this to an Ok.
3090Sstevel@tonic-gate */
3100Sstevel@tonic-gate if (mdismderror(&(d->mde), MDE_UNIT_NOT_SETUP)) {
3110Sstevel@tonic-gate mdclrerror(&(d->mde));
3120Sstevel@tonic-gate ret = 0;
3130Sstevel@tonic-gate }
3140Sstevel@tonic-gate
3150Sstevel@tonic-gate resp->mmr_exitval = ret;
3160Sstevel@tonic-gate }
3170Sstevel@tonic-gate }
3180Sstevel@tonic-gate }
3190Sstevel@tonic-gate
3200Sstevel@tonic-gate /* handler for MD_MN_MSG_REQUIRE_OWNER */
3210Sstevel@tonic-gate /*ARGSUSED*/
3220Sstevel@tonic-gate void
mdmn_do_req_owner(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)3230Sstevel@tonic-gate mdmn_do_req_owner(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
3240Sstevel@tonic-gate {
3250Sstevel@tonic-gate md_set_mmown_params_t setown;
3260Sstevel@tonic-gate md_mn_req_owner_t *d;
3270Sstevel@tonic-gate int ret, n = 0;
3280Sstevel@tonic-gate
3290Sstevel@tonic-gate resp->mmr_out_size = 0;
3300Sstevel@tonic-gate resp->mmr_err_size = 0;
3310Sstevel@tonic-gate resp->mmr_out = NULL;
3320Sstevel@tonic-gate resp->mmr_err = NULL;
3330Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
3340Sstevel@tonic-gate d = (md_mn_req_owner_t *)(void *)msg->msg_event_data;
3350Sstevel@tonic-gate
3360Sstevel@tonic-gate (void) memset(&setown, 0, sizeof (setown));
3370Sstevel@tonic-gate MD_SETDRIVERNAME(&setown, MD_MIRROR, MD_MIN2SET(d->mnum))
3380Sstevel@tonic-gate setown.d.mnum = d->mnum;
3390Sstevel@tonic-gate setown.d.owner = d->owner;
3400Sstevel@tonic-gate
3410Sstevel@tonic-gate /* Retry ownership change if we get EAGAIN returned */
3420Sstevel@tonic-gate while ((ret = metaioctl(MD_MN_SET_MM_OWNER, &setown, &setown.mde, NULL))
3430Sstevel@tonic-gate != 0) {
3440Sstevel@tonic-gate md_sys_error_t *ip =
3450Sstevel@tonic-gate &setown.mde.info.md_error_info_t_u.sys_error;
3460Sstevel@tonic-gate if (ip->errnum != EAGAIN) {
3470Sstevel@tonic-gate break;
3480Sstevel@tonic-gate }
3490Sstevel@tonic-gate if (n++ >= 10) {
3500Sstevel@tonic-gate break;
3510Sstevel@tonic-gate }
3520Sstevel@tonic-gate (void) sleep(1);
3530Sstevel@tonic-gate }
3540Sstevel@tonic-gate
3550Sstevel@tonic-gate resp->mmr_exitval = ret;
3560Sstevel@tonic-gate }
3570Sstevel@tonic-gate
3580Sstevel@tonic-gate /*
3590Sstevel@tonic-gate * handler for MD_MN_MSG_CHOOSE_OWNER
3600Sstevel@tonic-gate * This is called when a mirror resync has no owner. The master node generates
3610Sstevel@tonic-gate * this message which is not broadcast to the other nodes. The message is
3620Sstevel@tonic-gate * required as the kernel does not have access to the nodelist for the set.
3630Sstevel@tonic-gate */
3640Sstevel@tonic-gate /*ARGSUSED*/
3650Sstevel@tonic-gate void
mdmn_do_choose_owner(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)3660Sstevel@tonic-gate mdmn_do_choose_owner(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
3670Sstevel@tonic-gate {
3680Sstevel@tonic-gate md_mn_msg_chowner_t chownermsg;
3690Sstevel@tonic-gate md_mn_msg_chooseid_t *d;
3700Sstevel@tonic-gate int ret = 0;
3710Sstevel@tonic-gate int nodecnt;
3720Sstevel@tonic-gate int nodeno;
3730Sstevel@tonic-gate uint_t nodeid;
3740Sstevel@tonic-gate uint_t myflags;
3750Sstevel@tonic-gate set_t setno;
3760Sstevel@tonic-gate mdsetname_t *sp;
3770Sstevel@tonic-gate md_set_desc *sd;
3780Sstevel@tonic-gate md_mnnode_desc *nd;
3790Sstevel@tonic-gate md_error_t mde = mdnullerror;
3800Sstevel@tonic-gate md_mn_result_t *resp1 = NULL;
3810Sstevel@tonic-gate
3820Sstevel@tonic-gate resp->mmr_out_size = 0;
3830Sstevel@tonic-gate resp->mmr_err_size = 0;
3840Sstevel@tonic-gate resp->mmr_out = NULL;
3850Sstevel@tonic-gate resp->mmr_err = NULL;
3860Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
3870Sstevel@tonic-gate d = (md_mn_msg_chooseid_t *)(void *)msg->msg_event_data;
3880Sstevel@tonic-gate
3890Sstevel@tonic-gate /*
3900Sstevel@tonic-gate * The node to be chosen will be the resync count for the set
3910Sstevel@tonic-gate * modulo the number of live nodes in the set
3920Sstevel@tonic-gate */
3930Sstevel@tonic-gate setno = MD_MIN2SET(d->msg_chooseid_mnum);
3940Sstevel@tonic-gate if ((sp = metasetnosetname(setno, &mde)) == NULL) {
3950Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
3960Sstevel@tonic-gate "MD_MN_MSG_CHOOSE_OWNER: Invalid setno %d\n"), setno);
3970Sstevel@tonic-gate resp->mmr_exitval = 1;
3980Sstevel@tonic-gate return;
3990Sstevel@tonic-gate }
4000Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, &mde)) == NULL) {
4010Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
4020Sstevel@tonic-gate "MD_MN_MSG_CHOOSE_OWNER: Invalid set pointer\n"));
4030Sstevel@tonic-gate resp->mmr_exitval = 1;
4040Sstevel@tonic-gate return;
4050Sstevel@tonic-gate }
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate /* Count the number of live nodes */
4080Sstevel@tonic-gate nodecnt = 0;
4090Sstevel@tonic-gate nd = sd->sd_nodelist;
4100Sstevel@tonic-gate while (nd) {
4110Sstevel@tonic-gate if (nd->nd_flags & MD_MN_NODE_ALIVE)
4120Sstevel@tonic-gate nodecnt++;
4130Sstevel@tonic-gate nd = nd->nd_next;
4140Sstevel@tonic-gate }
4150Sstevel@tonic-gate nodeno = (d->msg_chooseid_rcnt%nodecnt);
4160Sstevel@tonic-gate
4170Sstevel@tonic-gate /*
4180Sstevel@tonic-gate * If we've been called with msg_chooseid_set_node set TRUE then we
4190Sstevel@tonic-gate * are simply re-setting the owner id to ensure consistency across
4200Sstevel@tonic-gate * the cluster.
4210Sstevel@tonic-gate * If the flag is reset (B_FALSE) we are requesting a new owner to be
4220Sstevel@tonic-gate * determined.
4230Sstevel@tonic-gate */
4240Sstevel@tonic-gate if (d->msg_chooseid_set_node) {
4250Sstevel@tonic-gate nodeid = d->msg_chooseid_rcnt;
4260Sstevel@tonic-gate } else {
4270Sstevel@tonic-gate /* scan the nodelist looking for the required node */
4280Sstevel@tonic-gate nodecnt = 0;
4290Sstevel@tonic-gate nd = sd->sd_nodelist;
4300Sstevel@tonic-gate while (nd) {
4310Sstevel@tonic-gate if (nd->nd_flags & MD_MN_NODE_ALIVE) {
4320Sstevel@tonic-gate if (nodecnt == nodeno)
4330Sstevel@tonic-gate break;
4340Sstevel@tonic-gate nodecnt++;
4350Sstevel@tonic-gate }
4360Sstevel@tonic-gate nd = nd->nd_next;
4370Sstevel@tonic-gate }
4380Sstevel@tonic-gate nodeid = nd->nd_nodeid;
4390Sstevel@tonic-gate }
4400Sstevel@tonic-gate
4410Sstevel@tonic-gate /* Send message to all nodes to make ownership change */
4420Sstevel@tonic-gate chownermsg.msg_chowner_mnum = d->msg_chooseid_mnum;
4430Sstevel@tonic-gate chownermsg.msg_chowner_nodeid = nodeid;
4440Sstevel@tonic-gate myflags = MD_MSGF_NO_LOG;
4450Sstevel@tonic-gate
4460Sstevel@tonic-gate /* inherit some flags from the parent message */
4470Sstevel@tonic-gate myflags |= msg->msg_flags & MD_MSGF_INHERIT_BITS;
4480Sstevel@tonic-gate
4490Sstevel@tonic-gate ret = mdmn_send_message(MD_MIN2SET(d->msg_chooseid_mnum),
450*8452SJohn.Wren.Kennedy@Sun.COM MD_MN_MSG_CHANGE_OWNER, myflags, 0, (char *)&chownermsg,
4510Sstevel@tonic-gate sizeof (chownermsg), &resp1, &mde);
4520Sstevel@tonic-gate if (resp1 != NULL)
4530Sstevel@tonic-gate free_result(resp1);
4540Sstevel@tonic-gate resp->mmr_exitval = ret;
4550Sstevel@tonic-gate }
4560Sstevel@tonic-gate
4570Sstevel@tonic-gate /*
4580Sstevel@tonic-gate * Handler for MD_MN_MSG_CHANGE_OWNER
4590Sstevel@tonic-gate * This is called when we are perfoming a resync and wish to change from
4600Sstevel@tonic-gate * no mirror owner to an owner chosen by the master.
4610Sstevel@tonic-gate * This mesage is only relevant for the new owner, the message will be
4620Sstevel@tonic-gate * ignored by all other nodes
4630Sstevel@tonic-gate */
4640Sstevel@tonic-gate /*ARGSUSED*/
4650Sstevel@tonic-gate void
mdmn_do_change_owner(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)4660Sstevel@tonic-gate mdmn_do_change_owner(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
4670Sstevel@tonic-gate {
4680Sstevel@tonic-gate md_set_mmown_params_t setown;
4690Sstevel@tonic-gate md_mn_msg_chowner_t *d;
4700Sstevel@tonic-gate int ret = 0;
4710Sstevel@tonic-gate set_t setno;
4720Sstevel@tonic-gate mdsetname_t *sp;
4730Sstevel@tonic-gate md_set_desc *sd;
4740Sstevel@tonic-gate md_error_t mde = mdnullerror;
4750Sstevel@tonic-gate
4760Sstevel@tonic-gate resp->mmr_out_size = 0;
4770Sstevel@tonic-gate resp->mmr_err_size = 0;
4780Sstevel@tonic-gate resp->mmr_out = NULL;
4790Sstevel@tonic-gate resp->mmr_err = NULL;
4800Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
4810Sstevel@tonic-gate d = (md_mn_msg_chowner_t *)(void *)msg->msg_event_data;
4820Sstevel@tonic-gate
4830Sstevel@tonic-gate setno = MD_MIN2SET(d->msg_chowner_mnum);
4840Sstevel@tonic-gate if ((sp = metasetnosetname(setno, &mde)) == NULL) {
4850Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
4860Sstevel@tonic-gate "MD_MN_MSG_CHANGE_OWNER: Invalid setno %d\n"), setno);
4870Sstevel@tonic-gate resp->mmr_exitval = 1;
4880Sstevel@tonic-gate return;
4890Sstevel@tonic-gate }
4900Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, &mde)) == NULL) {
4910Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
4920Sstevel@tonic-gate "MD_MN_MSG_CHANGE_OWNER: Invalid set pointer\n"));
4930Sstevel@tonic-gate resp->mmr_exitval = 1;
4940Sstevel@tonic-gate return;
4950Sstevel@tonic-gate }
4960Sstevel@tonic-gate
4970Sstevel@tonic-gate if (d->msg_chowner_nodeid == sd->sd_mn_mynode->nd_nodeid) {
4980Sstevel@tonic-gate /*
4990Sstevel@tonic-gate * If we are the chosen owner, issue ioctl to make the
5000Sstevel@tonic-gate * ownership change
5010Sstevel@tonic-gate */
5020Sstevel@tonic-gate (void) memset(&setown, 0, sizeof (md_set_mmown_params_t));
5030Sstevel@tonic-gate setown.d.mnum = d->msg_chowner_mnum;
5040Sstevel@tonic-gate setown.d.owner = d->msg_chowner_nodeid;
5050Sstevel@tonic-gate setown.d.flags = MD_MN_MM_SPAWN_THREAD;
5060Sstevel@tonic-gate MD_SETDRIVERNAME(&setown, MD_MIRROR,
5070Sstevel@tonic-gate MD_MIN2SET(d->msg_chowner_mnum));
5080Sstevel@tonic-gate
5090Sstevel@tonic-gate /*
5100Sstevel@tonic-gate * Single shot at changing the the owner, if it fails EAGAIN,
5110Sstevel@tonic-gate * another node must have become the owner while we are in the
5120Sstevel@tonic-gate * process of making this choice.
5130Sstevel@tonic-gate */
5140Sstevel@tonic-gate
5150Sstevel@tonic-gate ret = metaioctl(MD_MN_SET_MM_OWNER, &setown,
5160Sstevel@tonic-gate &(setown.mde), NULL);
5170Sstevel@tonic-gate if (ret == EAGAIN)
5180Sstevel@tonic-gate ret = 0;
5190Sstevel@tonic-gate }
5200Sstevel@tonic-gate resp->mmr_exitval = ret;
5210Sstevel@tonic-gate }
5220Sstevel@tonic-gate
5230Sstevel@tonic-gate /* handler for MD_MN_MSG_SUSPEND_WRITES */
5240Sstevel@tonic-gate /*ARGSUSED*/
5250Sstevel@tonic-gate void
mdmn_do_susp_write(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)5260Sstevel@tonic-gate mdmn_do_susp_write(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
5270Sstevel@tonic-gate {
5280Sstevel@tonic-gate /* Suspend writes to a region of a mirror */
5290Sstevel@tonic-gate md_suspend_wr_params_t suspwr_ioc;
5300Sstevel@tonic-gate md_mn_msg_suspwr_t *d;
5310Sstevel@tonic-gate int ret;
5320Sstevel@tonic-gate
5330Sstevel@tonic-gate resp->mmr_out_size = 0;
5340Sstevel@tonic-gate resp->mmr_err_size = 0;
5350Sstevel@tonic-gate resp->mmr_out = NULL;
5360Sstevel@tonic-gate resp->mmr_err = NULL;
5370Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
5380Sstevel@tonic-gate d = (md_mn_msg_suspwr_t *)(void *)msg->msg_event_data;
5390Sstevel@tonic-gate
5400Sstevel@tonic-gate (void) memset(&suspwr_ioc, 0, sizeof (md_suspend_wr_params_t));
5410Sstevel@tonic-gate MD_SETDRIVERNAME(&suspwr_ioc, MD_MIRROR,
5420Sstevel@tonic-gate MD_MIN2SET(d->msg_suspwr_mnum));
5430Sstevel@tonic-gate suspwr_ioc.mnum = d->msg_suspwr_mnum;
5440Sstevel@tonic-gate ret = metaioctl(MD_MN_SUSPEND_WRITES, &suspwr_ioc,
5450Sstevel@tonic-gate &(suspwr_ioc.mde), NULL);
5460Sstevel@tonic-gate resp->mmr_exitval = ret;
5470Sstevel@tonic-gate }
5480Sstevel@tonic-gate
5490Sstevel@tonic-gate /*
5500Sstevel@tonic-gate * handler for MD_MN_MSG_STATE_UPDATE_RESWR
5510Sstevel@tonic-gate * This functions update a submirror component state and then resumes writes
5520Sstevel@tonic-gate * to the mirror
5530Sstevel@tonic-gate */
5540Sstevel@tonic-gate /*ARGSUSED*/
5550Sstevel@tonic-gate void
mdmn_do_state_upd_reswr(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)5560Sstevel@tonic-gate mdmn_do_state_upd_reswr(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
5570Sstevel@tonic-gate {
5580Sstevel@tonic-gate /* Update the state of the component of a mirror */
5590Sstevel@tonic-gate md_set_state_params_t setstate_ioc;
5600Sstevel@tonic-gate md_mn_msg_stch_t *d;
5610Sstevel@tonic-gate int ret;
5620Sstevel@tonic-gate
5630Sstevel@tonic-gate resp->mmr_out_size = 0;
5640Sstevel@tonic-gate resp->mmr_err_size = 0;
5650Sstevel@tonic-gate resp->mmr_out = NULL;
5660Sstevel@tonic-gate resp->mmr_err = NULL;
5670Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
5680Sstevel@tonic-gate d = (md_mn_msg_stch_t *)(void *)msg->msg_event_data;
5690Sstevel@tonic-gate
5700Sstevel@tonic-gate (void) memset(&setstate_ioc, 0, sizeof (md_set_state_params_t));
5710Sstevel@tonic-gate MD_SETDRIVERNAME(&setstate_ioc, MD_MIRROR,
5720Sstevel@tonic-gate MD_MIN2SET(d->msg_stch_mnum));
5730Sstevel@tonic-gate setstate_ioc.mnum = d->msg_stch_mnum;
5740Sstevel@tonic-gate setstate_ioc.sm = d->msg_stch_sm;
5750Sstevel@tonic-gate setstate_ioc.comp = d->msg_stch_comp;
5760Sstevel@tonic-gate setstate_ioc.state = d->msg_stch_new_state;
5770Sstevel@tonic-gate setstate_ioc.hs_id = d->msg_stch_hs_id;
5780Sstevel@tonic-gate ret = metaioctl(MD_MN_SET_STATE, &setstate_ioc,
5790Sstevel@tonic-gate &(setstate_ioc.mde), NULL);
5800Sstevel@tonic-gate resp->mmr_exitval = ret;
5810Sstevel@tonic-gate }
5820Sstevel@tonic-gate
5830Sstevel@tonic-gate /*
5840Sstevel@tonic-gate * submessage generator for MD_MN_MSG_STATE_UPDATE and MD_MN_MSG_STATE_UPDATE2
5850Sstevel@tonic-gate * This generates 2 messages, the first is SUSPEND_WRITES and
5860Sstevel@tonic-gate * depending on the type of the original message the second one is
5870Sstevel@tonic-gate * either STATE_UPDATE_RESWR or STATE_UPDATE_RESWR2 which actually does
5880Sstevel@tonic-gate * the same, but runs on a higher class.
5890Sstevel@tonic-gate */
5900Sstevel@tonic-gate int
mdmn_smgen_state_upd(md_mn_msg_t * msg,md_mn_msg_t * msglist[])5910Sstevel@tonic-gate mdmn_smgen_state_upd(md_mn_msg_t *msg, md_mn_msg_t *msglist[])
5920Sstevel@tonic-gate {
5930Sstevel@tonic-gate md_mn_msg_t *nmsg;
5940Sstevel@tonic-gate md_mn_msg_stch_t *d;
5950Sstevel@tonic-gate md_mn_msg_stch_t *stch_data;
5960Sstevel@tonic-gate md_mn_msg_suspwr_t *suspwr_data;
5970Sstevel@tonic-gate
5980Sstevel@tonic-gate d = (md_mn_msg_stch_t *)(void *)msg->msg_event_data;
5990Sstevel@tonic-gate
6000Sstevel@tonic-gate nmsg = Zalloc(sizeof (md_mn_msg_t));
6010Sstevel@tonic-gate MSGID_COPY(&(msg->msg_msgid), &(nmsg->msg_msgid));
6020Sstevel@tonic-gate
6030Sstevel@tonic-gate nmsg->msg_flags = MD_MSGF_NO_LOG; /* Don't log submessages */
6040Sstevel@tonic-gate nmsg->msg_setno = msg->msg_setno;
6050Sstevel@tonic-gate nmsg->msg_type = MD_MN_MSG_SUSPEND_WRITES;
6060Sstevel@tonic-gate nmsg->msg_event_size = sizeof (md_mn_msg_suspwr_t);
6070Sstevel@tonic-gate nmsg->msg_event_data = Zalloc(sizeof (md_mn_msg_suspwr_t));
6080Sstevel@tonic-gate suspwr_data = (md_mn_msg_suspwr_t *)(void *)nmsg->msg_event_data;
6090Sstevel@tonic-gate suspwr_data->msg_suspwr_mnum = d->msg_stch_mnum;
6100Sstevel@tonic-gate msglist[0] = nmsg;
6110Sstevel@tonic-gate
6120Sstevel@tonic-gate nmsg = Zalloc(sizeof (md_mn_msg_t));
6130Sstevel@tonic-gate MSGID_COPY(&(msg->msg_msgid), &(nmsg->msg_msgid));
6140Sstevel@tonic-gate
6150Sstevel@tonic-gate nmsg->msg_flags = MD_MSGF_NO_LOG; /* Don't log submessages */
6160Sstevel@tonic-gate nmsg->msg_setno = msg->msg_setno;
6170Sstevel@tonic-gate if (msg->msg_type == MD_MN_MSG_STATE_UPDATE2) {
6180Sstevel@tonic-gate nmsg->msg_type = MD_MN_MSG_STATE_UPDATE_RESWR2;
6190Sstevel@tonic-gate } else {
6200Sstevel@tonic-gate nmsg->msg_type = MD_MN_MSG_STATE_UPDATE_RESWR;
6210Sstevel@tonic-gate }
6220Sstevel@tonic-gate nmsg->msg_event_size = sizeof (md_mn_msg_stch_t);
6230Sstevel@tonic-gate nmsg->msg_event_data = Zalloc(sizeof (md_mn_msg_stch_t));
6240Sstevel@tonic-gate stch_data = (md_mn_msg_stch_t *)(void *)nmsg->msg_event_data;
6250Sstevel@tonic-gate stch_data->msg_stch_mnum = d->msg_stch_mnum;
6260Sstevel@tonic-gate stch_data->msg_stch_sm = d->msg_stch_sm;
6270Sstevel@tonic-gate stch_data->msg_stch_comp = d->msg_stch_comp;
6280Sstevel@tonic-gate stch_data->msg_stch_new_state = d->msg_stch_new_state;
6290Sstevel@tonic-gate stch_data->msg_stch_hs_id = d->msg_stch_hs_id;
6300Sstevel@tonic-gate msglist[1] = nmsg;
6310Sstevel@tonic-gate return (2); /* Return the number of submessages generated */
6320Sstevel@tonic-gate }
6330Sstevel@tonic-gate
6340Sstevel@tonic-gate /*
6350Sstevel@tonic-gate * handler for MD_MN_MSG_ALLOCATE_HOTSPARE and MD_MN_MSG_ALLOCATE_HOTSPARE2
6360Sstevel@tonic-gate * This sends a message to all nodes requesting them to allocate a hotspare
6370Sstevel@tonic-gate * for the specified component. The component is specified by the mnum of
6380Sstevel@tonic-gate * the mirror, the submirror index and the component index.
6390Sstevel@tonic-gate */
6400Sstevel@tonic-gate /*ARGSUSED*/
6410Sstevel@tonic-gate void
mdmn_do_allocate_hotspare(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)6420Sstevel@tonic-gate mdmn_do_allocate_hotspare(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
6430Sstevel@tonic-gate {
6440Sstevel@tonic-gate /* Allocate a hotspare for a mirror component */
6450Sstevel@tonic-gate md_alloc_hotsp_params_t allochsp_ioc;
6460Sstevel@tonic-gate md_mn_msg_allochsp_t *d;
6470Sstevel@tonic-gate int ret;
6480Sstevel@tonic-gate
6490Sstevel@tonic-gate resp->mmr_out_size = 0;
6500Sstevel@tonic-gate resp->mmr_err_size = 0;
6510Sstevel@tonic-gate resp->mmr_out = NULL;
6520Sstevel@tonic-gate resp->mmr_err = NULL;
6530Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
6540Sstevel@tonic-gate d = (md_mn_msg_allochsp_t *)((void *)(msg->msg_event_data));
6550Sstevel@tonic-gate
6560Sstevel@tonic-gate (void) memset(&allochsp_ioc, 0,
6577210Srayh sizeof (md_alloc_hotsp_params_t));
6580Sstevel@tonic-gate MD_SETDRIVERNAME(&allochsp_ioc, MD_MIRROR,
6590Sstevel@tonic-gate MD_MIN2SET(d->msg_allochsp_mnum));
6600Sstevel@tonic-gate allochsp_ioc.mnum = d->msg_allochsp_mnum;
6610Sstevel@tonic-gate allochsp_ioc.sm = d->msg_allochsp_sm;
6620Sstevel@tonic-gate allochsp_ioc.comp = d->msg_allochsp_comp;
6630Sstevel@tonic-gate allochsp_ioc.hs_id = d->msg_allochsp_hs_id;
6640Sstevel@tonic-gate ret = metaioctl(MD_MN_ALLOCATE_HOTSPARE, &allochsp_ioc,
6650Sstevel@tonic-gate &(allochsp_ioc.mde), NULL);
6660Sstevel@tonic-gate resp->mmr_exitval = ret;
6670Sstevel@tonic-gate }
6680Sstevel@tonic-gate
6690Sstevel@tonic-gate /*
6700Sstevel@tonic-gate * handler for MD_MN_MSG_RESYNC_STARTING,MD_MN_MSG_RESYNC_FIRST,
6710Sstevel@tonic-gate * MD_MN_MSG_RESYNC_NEXT, MD_MN_MSG_RESYNC_FINISH, MD_MN_MSG_RESYNC_PHASE_DONE
6720Sstevel@tonic-gate */
6730Sstevel@tonic-gate /*ARGSUSED*/
6740Sstevel@tonic-gate void
mdmn_do_resync(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)6750Sstevel@tonic-gate mdmn_do_resync(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
6760Sstevel@tonic-gate {
6777210Srayh md_mn_msg_resync_t *d;
6787210Srayh md_mn_rs_params_t respar;
6797210Srayh mddb_setflags_config_t sf;
6807210Srayh md_error_t ep = mdnullerror;
6817210Srayh mdsetname_t *sp;
6827210Srayh int ret;
6837210Srayh int smi;
6847210Srayh int start_flag = 1;
6857210Srayh int sleep_count = 0;
6867210Srayh unsigned int sleep_time = 2;
6870Sstevel@tonic-gate
6880Sstevel@tonic-gate resp->mmr_out_size = 0;
6890Sstevel@tonic-gate resp->mmr_err_size = 0;
6900Sstevel@tonic-gate resp->mmr_out = NULL;
6910Sstevel@tonic-gate resp->mmr_err = NULL;
6920Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
6930Sstevel@tonic-gate d = (md_mn_msg_resync_t *)((void *)(msg->msg_event_data));
6940Sstevel@tonic-gate
6950Sstevel@tonic-gate (void) memset(&respar, 0, sizeof (respar));
6960Sstevel@tonic-gate MD_SETDRIVERNAME(&respar, MD_MIRROR,
6970Sstevel@tonic-gate MD_MIN2SET(d->msg_resync_mnum))
6980Sstevel@tonic-gate respar.msg_type = (int)msg->msg_type;
6990Sstevel@tonic-gate respar.mnum = d->msg_resync_mnum;
7000Sstevel@tonic-gate respar.rs_type = d->msg_resync_type;
7010Sstevel@tonic-gate respar.rs_start = d->msg_resync_start;
7020Sstevel@tonic-gate respar.rs_size = d->msg_resync_rsize;
7030Sstevel@tonic-gate respar.rs_done = d->msg_resync_done;
7040Sstevel@tonic-gate respar.rs_2_do = d->msg_resync_2_do;
7050Sstevel@tonic-gate respar.rs_originator = d->msg_originator;
7060Sstevel@tonic-gate respar.rs_flags = d->msg_resync_flags;
7070Sstevel@tonic-gate
7080Sstevel@tonic-gate for (smi = 0; smi < NMIRROR; smi++) {
7090Sstevel@tonic-gate respar.rs_sm_state[smi] = d->msg_sm_state[smi];
7100Sstevel@tonic-gate respar.rs_sm_flags[smi] = d->msg_sm_flags[smi];
7110Sstevel@tonic-gate }
7120Sstevel@tonic-gate
7137210Srayh /*
7147210Srayh * Prior to running the resync thread first check that the start_step
7157210Srayh * flag (MD_SET_MN_START_RC) added by metaclust's MC_START step has been
7167210Srayh * removed from the set record flags. Ordinarily, this would be removed
7177210Srayh * at MC_STEP4 in metaclust - need to ensure this has happened on all
7187210Srayh * nodes.
7197210Srayh */
7207210Srayh (void) memset(&sf, 0, sizeof (sf));
7217210Srayh sf.sf_setno = MD_MIN2SET(d->msg_resync_mnum);
7227210Srayh sf.sf_flags = MDDB_NM_GET;
7237210Srayh /* Use magic to help protect ioctl against attack. */
7247210Srayh sf.sf_magic = MDDB_SETFLAGS_MAGIC;
7257210Srayh if ((sp = metasetnosetname(sf.sf_setno, &ep)) == NULL) {
7267210Srayh syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
7277210Srayh "MDMN_DO_RESYNC: Invalid setno = %d\n"),
7287210Srayh sf.sf_setno);
7297210Srayh (void) mdstealerror(&(resp->mmr_ep), &ep);
7307210Srayh resp->mmr_exitval = -1;
7317210Srayh return;
7327210Srayh }
7337210Srayh
7347210Srayh /* start_flag always true initially */
7357210Srayh while (start_flag) {
7367210Srayh if (metaioctl(MD_MN_GET_SETFLAGS, &sf, &sf.sf_mde, NULL) != 0) {
7377210Srayh syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
7387210Srayh "MDMN_DO_RESYNC: Could not get start_step "
7397210Srayh "flag for set %s - returning\n"),
7407210Srayh sp->setname);
7417210Srayh (void) mdstealerror(&(resp->mmr_ep), &sf.sf_mde);
7427210Srayh resp->mmr_exitval = -1;
7437210Srayh return;
7447210Srayh }
7457210Srayh
7467210Srayh /* metaioctl returns successfully - is start flag cleared? */
7477210Srayh if (sf.sf_setflags & MD_SET_MN_START_RC) {
7487210Srayh start_flag = 1;
7497210Srayh (void) sleep(sleep_time);
7507210Srayh sleep_count++;
7517210Srayh if ((sleep_count == 1) ||
7527210Srayh (sleep_count % SLEEP_MOD) == 0) {
7537210Srayh syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
7547210Srayh "MDMN_DO_RESYNC: Waiting for start_step "
7557210Srayh "flag for set %s to be cleared\n"),
7567210Srayh sp->setname);
7577210Srayh }
7587210Srayh if (sleep_count == MAX_SLEEPS) {
7597210Srayh syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
7607210Srayh "MDMN_DO_RESYNC: Could not clear "
7617210Srayh "start_step flag for set %s "
7627210Srayh "- returning\n"), sp->setname);
7637210Srayh resp->mmr_exitval = -1;
7647210Srayh return;
7657210Srayh }
7667210Srayh } else {
7677210Srayh start_flag = 0;
7687210Srayh }
7697210Srayh }
7707210Srayh
7710Sstevel@tonic-gate ret = metaioctl(MD_MN_RESYNC, &respar, &respar.mde, NULL);
7727210Srayh if (ret) {
7737210Srayh (void) mdstealerror(&(resp->mmr_ep), &respar.mde);
7747210Srayh }
7750Sstevel@tonic-gate resp->mmr_exitval = ret;
7760Sstevel@tonic-gate }
7770Sstevel@tonic-gate
7780Sstevel@tonic-gate /*
7790Sstevel@tonic-gate * handler for MD_MN_MSG_SETSYNC
7800Sstevel@tonic-gate */
7810Sstevel@tonic-gate /*ARGSUSED*/
7820Sstevel@tonic-gate void
mdmn_do_setsync(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)7830Sstevel@tonic-gate mdmn_do_setsync(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
7840Sstevel@tonic-gate {
7850Sstevel@tonic-gate md_mn_msg_setsync_t *d;
7860Sstevel@tonic-gate md_resync_ioctl_t ri;
7870Sstevel@tonic-gate int ret;
7880Sstevel@tonic-gate
7890Sstevel@tonic-gate resp->mmr_out_size = 0;
7900Sstevel@tonic-gate resp->mmr_err_size = 0;
7910Sstevel@tonic-gate resp->mmr_out = NULL;
7920Sstevel@tonic-gate resp->mmr_err = NULL;
7930Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
7940Sstevel@tonic-gate d = (md_mn_msg_setsync_t *)((void *)(msg->msg_event_data));
7950Sstevel@tonic-gate
7960Sstevel@tonic-gate (void) memset(&ri, 0, sizeof (ri));
7970Sstevel@tonic-gate MD_SETDRIVERNAME(&ri, MD_MIRROR, MD_MIN2SET(d->setsync_mnum))
7980Sstevel@tonic-gate ri.ri_mnum = d->setsync_mnum;
7990Sstevel@tonic-gate ri.ri_copysize = d->setsync_copysize;
8000Sstevel@tonic-gate ri.ri_flags = d->setsync_flags;
8010Sstevel@tonic-gate
8020Sstevel@tonic-gate ret = metaioctl(MD_MN_SETSYNC, &ri, &ri.mde, NULL);
8030Sstevel@tonic-gate
8040Sstevel@tonic-gate resp->mmr_exitval = ret;
8050Sstevel@tonic-gate }
8060Sstevel@tonic-gate
8070Sstevel@tonic-gate /*
8080Sstevel@tonic-gate * handler for MD_MN_MSG_SET_CAP. As this handler can deal with both mirrors
8090Sstevel@tonic-gate * and soft partitions, the driver name that is required for the ioctl call
8100Sstevel@tonic-gate * is included in the message.
8110Sstevel@tonic-gate */
8120Sstevel@tonic-gate /*ARGSUSED*/
8130Sstevel@tonic-gate void
mdmn_do_set_cap(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)8140Sstevel@tonic-gate mdmn_do_set_cap(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
8150Sstevel@tonic-gate {
8160Sstevel@tonic-gate md_mn_msg_setcap_t *d;
8170Sstevel@tonic-gate md_mn_setcap_params_t setcap_ioc;
8180Sstevel@tonic-gate minor_t mnum;
8190Sstevel@tonic-gate int ret;
8200Sstevel@tonic-gate
8210Sstevel@tonic-gate resp->mmr_out_size = 0;
8220Sstevel@tonic-gate resp->mmr_err_size = 0;
8230Sstevel@tonic-gate resp->mmr_out = NULL;
8240Sstevel@tonic-gate resp->mmr_err = NULL;
8250Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
8260Sstevel@tonic-gate d = (md_mn_msg_setcap_t *)((void *)(msg->msg_event_data));
8270Sstevel@tonic-gate mnum = d->msg_setcap_mnum;
8280Sstevel@tonic-gate
8290Sstevel@tonic-gate (void) memset(&setcap_ioc, 0, sizeof (setcap_ioc));
8300Sstevel@tonic-gate
8310Sstevel@tonic-gate MD_SETDRIVERNAME(&setcap_ioc, d->msg_setcap_driver, MD_MIN2SET(mnum));
8320Sstevel@tonic-gate setcap_ioc.mnum = mnum;
8330Sstevel@tonic-gate setcap_ioc.sc_set = d->msg_setcap_set;
8340Sstevel@tonic-gate
8350Sstevel@tonic-gate ret = metaioctl(MD_MN_SET_CAP, &setcap_ioc, &setcap_ioc.mde, NULL);
8360Sstevel@tonic-gate
8370Sstevel@tonic-gate resp->mmr_exitval = ret;
8380Sstevel@tonic-gate }
8390Sstevel@tonic-gate
8400Sstevel@tonic-gate /*
8410Sstevel@tonic-gate * Dummy handler for various CLASS0 messages like
8420Sstevel@tonic-gate * MD_MN_MSG_VERBOSITY / MD_MN_MSG_RESUME / MD_MN_MSG_SUSPEND ...
8430Sstevel@tonic-gate */
8440Sstevel@tonic-gate /*ARGSUSED*/
8450Sstevel@tonic-gate void
mdmn_do_dummy(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)8460Sstevel@tonic-gate mdmn_do_dummy(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
8470Sstevel@tonic-gate {
8480Sstevel@tonic-gate resp->mmr_out_size = 0;
8490Sstevel@tonic-gate resp->mmr_err_size = 0;
8500Sstevel@tonic-gate resp->mmr_out = NULL;
8510Sstevel@tonic-gate resp->mmr_err = NULL;
8520Sstevel@tonic-gate resp->mmr_exitval = 0;
8530Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
8540Sstevel@tonic-gate }
8550Sstevel@tonic-gate
8560Sstevel@tonic-gate /*
8570Sstevel@tonic-gate * Overall description of mdcommd support that keeps all nodes in-sync
8580Sstevel@tonic-gate * with the ondisk diskset mddbs.
8590Sstevel@tonic-gate *
8600Sstevel@tonic-gate * All configuration changes to the mddb - addition/deletion of metadevices
8610Sstevel@tonic-gate * or replicas must use a CLASS1 message to block out these changes.
8620Sstevel@tonic-gate * Changes to the state of existing replicas do not need to block CLASS1
8630Sstevel@tonic-gate * since there is no conflict when just updating the state of a replica.
8640Sstevel@tonic-gate *
8650Sstevel@tonic-gate * Error encountered when master writes to mddbs:
8660Sstevel@tonic-gate * As the master updates parts of the mddbs, flags are updated describing
8670Sstevel@tonic-gate * what has been written. When all locks are dropped (either in
8680Sstevel@tonic-gate * mddb_setexit or mdioctl), a PARSE message will be generated to all
8690Sstevel@tonic-gate * nodes with an index list of known good mddbs and the parse flags.
8700Sstevel@tonic-gate * The master node ignore the parse message since it sent it.
8710Sstevel@tonic-gate * The slave nodes re-read in the changed part of the mddb using the list
8720Sstevel@tonic-gate * of known good replicas that was passed.
8730Sstevel@tonic-gate * PARSE message does not block CLASS1.
8740Sstevel@tonic-gate * The PARSE message must be the highest class message. Since this
8750Sstevel@tonic-gate * message could be sent on any ioctl, this PARSE message class must
8760Sstevel@tonic-gate * be higher than any other class message that could issue an ioctl.
8770Sstevel@tonic-gate *
8780Sstevel@tonic-gate * Master Slave1 Slave2
8790Sstevel@tonic-gate * Handles_error
8800Sstevel@tonic-gate * PARSE PARSE PARSE
8810Sstevel@tonic-gate *
8820Sstevel@tonic-gate *
8830Sstevel@tonic-gate * Add/Delete mddbs can occur from the following commands:
8840Sstevel@tonic-gate * metadb -s set_name -a/-d
8850Sstevel@tonic-gate * metaset -s set_name -a/-d disk
8860Sstevel@tonic-gate * metaset -s set_name -b
8870Sstevel@tonic-gate *
8880Sstevel@tonic-gate * The metadb/metaset command is run on the node executing the command
8890Sstevel@tonic-gate * and sends an ATTACH/DETACH message to the master node blocking CLASS1
8900Sstevel@tonic-gate * messages on all nodes until this message is finished. The master
8910Sstevel@tonic-gate * node generates 3 submessages of BLOCK, SM_ATTACH/SM_DETACH, UNBLOCK.
8920Sstevel@tonic-gate * The BLOCK message is only run on the master node and will BLOCK
8930Sstevel@tonic-gate * the PARSE messages from being sent to the nodes.
8940Sstevel@tonic-gate * The SM_ATTACH/SM_DETACH message is run on all nodes and actually adds or
8950Sstevel@tonic-gate * removes the replica(s) from the given disk slice.
8960Sstevel@tonic-gate * The UNBLOCK message is only run on the master node and allows the
8970Sstevel@tonic-gate * sending of PARSE messages.
8980Sstevel@tonic-gate *
8990Sstevel@tonic-gate * Master Slave1 Slave2
9000Sstevel@tonic-gate * Add mddb cmd
9010Sstevel@tonic-gate * ATTACH msg to master
9020Sstevel@tonic-gate * BLOCK
9030Sstevel@tonic-gate * ATTACH ATTACH ATTACH
9040Sstevel@tonic-gate * UNBLOCK
9050Sstevel@tonic-gate * PARSE PARSE PARSE
9060Sstevel@tonic-gate * ATTACH msg finished
9070Sstevel@tonic-gate *
9080Sstevel@tonic-gate * Add/Delete host side information from the following commands:
9090Sstevel@tonic-gate * metaset -s set_name -a/-d -h
9100Sstevel@tonic-gate *
9110Sstevel@tonic-gate * The metaset command is run on the node executing the command and
9120Sstevel@tonic-gate * sends a DB_NEWSIDE/DB_DELSIDE message and a MD_NEWSIDE/MD_DELSIDE
9130Sstevel@tonic-gate * message whenever a host is added to or deleted from the diskset.
9140Sstevel@tonic-gate *
9150Sstevel@tonic-gate * The side information contains the major name and minor number
9160Sstevel@tonic-gate * associated with a disk slice from a certain node's perspective
9170Sstevel@tonic-gate * in an (failed) effort to support clustered systems that don't have the
9180Sstevel@tonic-gate * same device name for a physical device. (The original designers of
9190Sstevel@tonic-gate * SVM eventually took the shortcut of assuming that all device names
9200Sstevel@tonic-gate * are the same on all systems, but left the side information in the
9210Sstevel@tonic-gate * mddb and namespace.) The side information is used for disk slices
9220Sstevel@tonic-gate * that contain mddbs and/or are components for metadevices.
9230Sstevel@tonic-gate *
9240Sstevel@tonic-gate * The DB_NEWSIDE/DELSIDE command adds or deletes the side information
9250Sstevel@tonic-gate * for each mddb for the host being added or deleted.
9260Sstevel@tonic-gate * The MD_ADDSIDE/MD_DELSIDE command adds or deletes the side information
9270Sstevel@tonic-gate * for all disk slice components that are in the namespace records for
9280Sstevel@tonic-gate * the host being added or deleted.
9290Sstevel@tonic-gate *
9300Sstevel@tonic-gate * The DB_NEWSIDE/DB_DELSIDE message does not change any mddb records
9310Sstevel@tonic-gate * and only needs to be executed on the master node since the slave
9320Sstevel@tonic-gate * nodes will be brought up to date by the PARSE message that is
9330Sstevel@tonic-gate * generated as a result of a change to the mddb.
9340Sstevel@tonic-gate * The MD_ADDSIDE/MD_DELSIDE message does modify the records in the mddb
9350Sstevel@tonic-gate * and needs to be run on all nodes. The message must block class1
9360Sstevel@tonic-gate * messages so that record changing commands don't interfere.
9370Sstevel@tonic-gate *
9380Sstevel@tonic-gate * Master Slave1 Slave2
9390Sstevel@tonic-gate * Add host
9400Sstevel@tonic-gate * DB_NEWSIDE msg to master
9410Sstevel@tonic-gate * DB_NEWSIDE
9420Sstevel@tonic-gate * PARSE PARSE PARSE
9430Sstevel@tonic-gate * DB_NEWSIDE msg finished
9440Sstevel@tonic-gate * MD_NEWSIDE msg to master
9450Sstevel@tonic-gate * MD_NEWSIDE MD_NEWSIDE MD_NEWSIDE
9460Sstevel@tonic-gate * MD_NEWSIDE msg finished
9470Sstevel@tonic-gate *
9480Sstevel@tonic-gate *
9490Sstevel@tonic-gate * Optimized resync record failure:
9500Sstevel@tonic-gate * When any node sees a failure to write an optimized resync record
9510Sstevel@tonic-gate * that node notifies the master node of the replica that failed.
9520Sstevel@tonic-gate * The master node handles the error and updates the rest of the
9530Sstevel@tonic-gate * nodes using a PARSE message. The PARSE message also calls
9540Sstevel@tonic-gate * fixoptrecord on each slave node causing each node to fix up
9550Sstevel@tonic-gate * the optimized resync records that are owned by that node (the mirror
9560Sstevel@tonic-gate * owner code also sets the optimized resync record owner). The master
9570Sstevel@tonic-gate * node will fix up all optimized resync records that have no owner or
9580Sstevel@tonic-gate * are owned by the master node.
9590Sstevel@tonic-gate *
9600Sstevel@tonic-gate * Master Slave1 Slave2
9610Sstevel@tonic-gate * Optimized Record Failure
9620Sstevel@tonic-gate * OPTRECERR msg to master
9630Sstevel@tonic-gate * Master handles opt rec failure
9640Sstevel@tonic-gate * PARSE PARSE PARSE
9650Sstevel@tonic-gate * OPTRECERR msg finished
9660Sstevel@tonic-gate * Slave rewrites optimized record
9670Sstevel@tonic-gate *
9680Sstevel@tonic-gate */
9690Sstevel@tonic-gate
9700Sstevel@tonic-gate /*
9710Sstevel@tonic-gate * Handler for MD_MN_MSG_MDDB_PARSE which send parse messages to the
9720Sstevel@tonic-gate * slave nodes in order to keep the incore view of the mddbs the
9730Sstevel@tonic-gate * same on all nodes.
9740Sstevel@tonic-gate *
9750Sstevel@tonic-gate * Since master node generated the mddb parse message, do nothing
9760Sstevel@tonic-gate * if this is the master node.
9770Sstevel@tonic-gate *
9780Sstevel@tonic-gate * If this is a slave node, send the parse message down to the kernel
9790Sstevel@tonic-gate * where this node will re-read in parts of the mddbs.
9800Sstevel@tonic-gate *
9810Sstevel@tonic-gate */
9820Sstevel@tonic-gate void
mdmn_do_mddb_parse(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)9830Sstevel@tonic-gate mdmn_do_mddb_parse(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
9840Sstevel@tonic-gate {
9850Sstevel@tonic-gate md_mn_msg_mddb_parse_t *d;
9860Sstevel@tonic-gate mddb_parse_parm_t mpp;
9870Sstevel@tonic-gate int ret = 0;
9880Sstevel@tonic-gate int i;
9890Sstevel@tonic-gate
9900Sstevel@tonic-gate resp->mmr_out_size = 0;
9910Sstevel@tonic-gate resp->mmr_err_size = 0;
9920Sstevel@tonic-gate resp->mmr_out = NULL;
9930Sstevel@tonic-gate resp->mmr_err = NULL;
9940Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
9950Sstevel@tonic-gate d = (md_mn_msg_mddb_parse_t *)((void *)(msg->msg_event_data));
9960Sstevel@tonic-gate
9970Sstevel@tonic-gate if (flags & MD_MSGF_ON_MASTER)
9980Sstevel@tonic-gate return;
9990Sstevel@tonic-gate
10000Sstevel@tonic-gate (void) memset(&mpp, 0, sizeof (mpp));
10010Sstevel@tonic-gate mpp.c_setno = msg->msg_setno;
10020Sstevel@tonic-gate mpp.c_parse_flags = d->msg_parse_flags;
10030Sstevel@tonic-gate for (i = 0; i < MDDB_NLB; i++) {
10040Sstevel@tonic-gate mpp.c_lb_flags[i] = d->msg_lb_flags[i];
10050Sstevel@tonic-gate }
10060Sstevel@tonic-gate ret = metaioctl(MD_MN_MDDB_PARSE, &mpp, &mpp.c_mde, NULL);
10070Sstevel@tonic-gate if (ret)
10080Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &mpp.c_mde);
10090Sstevel@tonic-gate
10100Sstevel@tonic-gate resp->mmr_exitval = ret;
10110Sstevel@tonic-gate }
10120Sstevel@tonic-gate
10130Sstevel@tonic-gate /*
10140Sstevel@tonic-gate * Handler for MD_MN_MSG_MDDB_BLOCK which blocks the generation
10150Sstevel@tonic-gate * of parse messages from this node.
10160Sstevel@tonic-gate *
10170Sstevel@tonic-gate * This is needed when attaching/detaching mddbs on the master and the
10180Sstevel@tonic-gate * slave node is unable to handle a parse message until the slave node
10190Sstevel@tonic-gate * has done the attach/detach of the mddbs. So, master node will block
10200Sstevel@tonic-gate * the parse messages, execute the attach/detach on all nodes and
10210Sstevel@tonic-gate * then unblock the parse messages which causes the parse message to
10220Sstevel@tonic-gate * be sent to all nodes.
10230Sstevel@tonic-gate */
10240Sstevel@tonic-gate /*ARGSUSED*/
10250Sstevel@tonic-gate void
mdmn_do_mddb_block(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)10260Sstevel@tonic-gate mdmn_do_mddb_block(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
10270Sstevel@tonic-gate {
10280Sstevel@tonic-gate md_mn_msg_mddb_block_t *d;
10290Sstevel@tonic-gate mddb_block_parm_t mbp;
10300Sstevel@tonic-gate int ret;
10310Sstevel@tonic-gate
10320Sstevel@tonic-gate resp->mmr_out_size = 0;
10330Sstevel@tonic-gate resp->mmr_err_size = 0;
10340Sstevel@tonic-gate resp->mmr_out = NULL;
10350Sstevel@tonic-gate resp->mmr_err = NULL;
10360Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
10370Sstevel@tonic-gate d = (md_mn_msg_mddb_block_t *)((void *)(msg->msg_event_data));
10380Sstevel@tonic-gate
10390Sstevel@tonic-gate (void) memset(&mbp, 0, sizeof (mbp));
10400Sstevel@tonic-gate mbp.c_setno = msg->msg_setno;
10410Sstevel@tonic-gate mbp.c_blk_flags = d->msg_block_flags;
10420Sstevel@tonic-gate ret = metaioctl(MD_MN_MDDB_BLOCK, &mbp, &mbp.c_mde, NULL);
10430Sstevel@tonic-gate if (ret)
10440Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &mbp.c_mde);
10450Sstevel@tonic-gate
10460Sstevel@tonic-gate resp->mmr_exitval = ret;
10470Sstevel@tonic-gate }
10480Sstevel@tonic-gate
10490Sstevel@tonic-gate /*
10500Sstevel@tonic-gate * Submessage generator for MD_MN_MSG_META_DB_ATTACH which generates
10510Sstevel@tonic-gate * a BLOCK message on the master node only, a MD_MN_MSG_SM_MDDB_ATTACH
10520Sstevel@tonic-gate * message on all nodes and then an UNBLOCK message on the master only.
10530Sstevel@tonic-gate */
10540Sstevel@tonic-gate int
mdmn_smgen_mddb_attach(md_mn_msg_t * msg,md_mn_msg_t * msglist[])10550Sstevel@tonic-gate mdmn_smgen_mddb_attach(md_mn_msg_t *msg, md_mn_msg_t *msglist[])
10560Sstevel@tonic-gate {
10570Sstevel@tonic-gate md_mn_msg_t *nmsg;
10580Sstevel@tonic-gate md_mn_msg_meta_db_attach_t *d;
10590Sstevel@tonic-gate md_mn_msg_meta_db_attach_t *attach_d;
10600Sstevel@tonic-gate md_mn_msg_mddb_block_t *block_d;
10610Sstevel@tonic-gate
10620Sstevel@tonic-gate d = (md_mn_msg_meta_db_attach_t *)(void *)msg->msg_event_data;
10630Sstevel@tonic-gate
10640Sstevel@tonic-gate nmsg = Zalloc(sizeof (md_mn_msg_t));
10650Sstevel@tonic-gate MSGID_COPY(&(msg->msg_msgid), &(nmsg->msg_msgid));
10660Sstevel@tonic-gate
10670Sstevel@tonic-gate nmsg->msg_flags = (MD_MSGF_NO_LOG | MD_MSGF_NO_BCAST);
10680Sstevel@tonic-gate nmsg->msg_setno = msg->msg_setno;
10690Sstevel@tonic-gate nmsg->msg_type = MD_MN_MSG_MDDB_BLOCK;
10700Sstevel@tonic-gate nmsg->msg_event_size = sizeof (md_mn_msg_mddb_block_t);
10710Sstevel@tonic-gate nmsg->msg_event_data = Zalloc(sizeof (md_mn_msg_mddb_block_t));
10720Sstevel@tonic-gate block_d = (md_mn_msg_mddb_block_t *)(void *)nmsg->msg_event_data;
10730Sstevel@tonic-gate block_d->msg_block_flags = MDDB_BLOCK_PARSE;
10740Sstevel@tonic-gate msglist[0] = nmsg;
10750Sstevel@tonic-gate
10760Sstevel@tonic-gate nmsg = Zalloc(sizeof (md_mn_msg_t));
10770Sstevel@tonic-gate MSGID_COPY(&(msg->msg_msgid), &(nmsg->msg_msgid));
10780Sstevel@tonic-gate
10790Sstevel@tonic-gate /* Don't log submessages and panic on inconsistent results */
10807210Srayh nmsg->msg_flags = MD_MSGF_NO_LOG |
10817210Srayh MD_MSGF_PANIC_WHEN_INCONSISTENT;
10820Sstevel@tonic-gate nmsg->msg_setno = msg->msg_setno;
10830Sstevel@tonic-gate nmsg->msg_type = MD_MN_MSG_SM_MDDB_ATTACH;
10840Sstevel@tonic-gate nmsg->msg_event_size = sizeof (md_mn_msg_meta_db_attach_t);
10850Sstevel@tonic-gate nmsg->msg_event_data = Zalloc(sizeof (md_mn_msg_meta_db_attach_t));
10860Sstevel@tonic-gate attach_d = (md_mn_msg_meta_db_attach_t *)
10877210Srayh (void *)nmsg->msg_event_data;
10880Sstevel@tonic-gate attach_d->msg_l_dev = d->msg_l_dev;
10890Sstevel@tonic-gate attach_d->msg_cnt = d->msg_cnt;
10900Sstevel@tonic-gate attach_d->msg_dbsize = d->msg_dbsize;
10910Sstevel@tonic-gate (void) strncpy(attach_d->msg_dname, d->msg_dname, 16);
10920Sstevel@tonic-gate attach_d->msg_splitname = d->msg_splitname;
10930Sstevel@tonic-gate attach_d->msg_options = d->msg_options;
10940Sstevel@tonic-gate msglist[1] = nmsg;
10950Sstevel@tonic-gate
10960Sstevel@tonic-gate nmsg = Zalloc(sizeof (md_mn_msg_t));
10970Sstevel@tonic-gate MSGID_COPY(&(msg->msg_msgid), &(nmsg->msg_msgid));
10980Sstevel@tonic-gate
10990Sstevel@tonic-gate nmsg->msg_flags = (MD_MSGF_NO_LOG | MD_MSGF_NO_BCAST);
11000Sstevel@tonic-gate nmsg->msg_setno = msg->msg_setno;
11010Sstevel@tonic-gate nmsg->msg_type = MD_MN_MSG_MDDB_BLOCK;
11020Sstevel@tonic-gate nmsg->msg_event_size = sizeof (md_mn_msg_mddb_block_t);
11030Sstevel@tonic-gate nmsg->msg_event_data = Zalloc(sizeof (md_mn_msg_mddb_block_t));
11040Sstevel@tonic-gate block_d = (md_mn_msg_mddb_block_t *)(void *)nmsg->msg_event_data;
11050Sstevel@tonic-gate block_d->msg_block_flags = MDDB_UNBLOCK_PARSE;
11060Sstevel@tonic-gate msglist[2] = nmsg;
11070Sstevel@tonic-gate
11080Sstevel@tonic-gate return (3); /* Return the number of submessages generated */
11090Sstevel@tonic-gate }
11100Sstevel@tonic-gate
11110Sstevel@tonic-gate /*
11120Sstevel@tonic-gate * Submessage generator for MD_MN_MSG_META_DB_DETACH which generates
11130Sstevel@tonic-gate * a BLOCK message on the master node only, a MD_MN_MSG_SM_MDDB_DETACH
11140Sstevel@tonic-gate * message on all nodes and then an UNBLOCK message on the master only.
11150Sstevel@tonic-gate */
11160Sstevel@tonic-gate int
mdmn_smgen_mddb_detach(md_mn_msg_t * msg,md_mn_msg_t * msglist[])11170Sstevel@tonic-gate mdmn_smgen_mddb_detach(md_mn_msg_t *msg, md_mn_msg_t *msglist[])
11180Sstevel@tonic-gate {
11190Sstevel@tonic-gate md_mn_msg_t *nmsg;
11200Sstevel@tonic-gate md_mn_msg_meta_db_detach_t *d;
11210Sstevel@tonic-gate md_mn_msg_meta_db_detach_t *detach_d;
11220Sstevel@tonic-gate md_mn_msg_mddb_block_t *block_d;
11230Sstevel@tonic-gate
11240Sstevel@tonic-gate d = (md_mn_msg_meta_db_detach_t *)(void *)msg->msg_event_data;
11250Sstevel@tonic-gate
11260Sstevel@tonic-gate nmsg = Zalloc(sizeof (md_mn_msg_t));
11270Sstevel@tonic-gate MSGID_COPY(&(msg->msg_msgid), &(nmsg->msg_msgid));
11280Sstevel@tonic-gate
11290Sstevel@tonic-gate nmsg->msg_flags = (MD_MSGF_NO_LOG | MD_MSGF_NO_BCAST);
11300Sstevel@tonic-gate nmsg->msg_setno = msg->msg_setno;
11310Sstevel@tonic-gate nmsg->msg_type = MD_MN_MSG_MDDB_BLOCK;
11320Sstevel@tonic-gate nmsg->msg_event_size = sizeof (md_mn_msg_mddb_block_t);
11330Sstevel@tonic-gate nmsg->msg_event_data = Zalloc(sizeof (md_mn_msg_mddb_block_t));
11340Sstevel@tonic-gate block_d = (md_mn_msg_mddb_block_t *)(void *)nmsg->msg_event_data;
11350Sstevel@tonic-gate block_d->msg_block_flags = MDDB_BLOCK_PARSE;
11360Sstevel@tonic-gate msglist[0] = nmsg;
11370Sstevel@tonic-gate
11380Sstevel@tonic-gate nmsg = Zalloc(sizeof (md_mn_msg_t));
11390Sstevel@tonic-gate MSGID_COPY(&(msg->msg_msgid), &(nmsg->msg_msgid));
11400Sstevel@tonic-gate
11410Sstevel@tonic-gate /* Don't log submessages and panic on inconsistent results */
11427210Srayh nmsg->msg_flags = MD_MSGF_NO_LOG |
11437210Srayh MD_MSGF_PANIC_WHEN_INCONSISTENT;
11440Sstevel@tonic-gate nmsg->msg_setno = msg->msg_setno;
11450Sstevel@tonic-gate nmsg->msg_type = MD_MN_MSG_SM_MDDB_DETACH;
11460Sstevel@tonic-gate nmsg->msg_event_size = sizeof (md_mn_msg_meta_db_detach_t);
11470Sstevel@tonic-gate nmsg->msg_event_data = Zalloc(sizeof (md_mn_msg_meta_db_detach_t));
11480Sstevel@tonic-gate detach_d = (md_mn_msg_meta_db_detach_t *)
11497210Srayh (void *)nmsg->msg_event_data;
11500Sstevel@tonic-gate detach_d->msg_splitname = d->msg_splitname;
11510Sstevel@tonic-gate msglist[1] = nmsg;
11520Sstevel@tonic-gate
11530Sstevel@tonic-gate nmsg = Zalloc(sizeof (md_mn_msg_t));
11540Sstevel@tonic-gate MSGID_COPY(&(msg->msg_msgid), &(nmsg->msg_msgid));
11550Sstevel@tonic-gate
11560Sstevel@tonic-gate nmsg->msg_flags = (MD_MSGF_NO_LOG | MD_MSGF_NO_BCAST);
11570Sstevel@tonic-gate nmsg->msg_setno = msg->msg_setno;
11580Sstevel@tonic-gate nmsg->msg_type = MD_MN_MSG_MDDB_BLOCK;
11590Sstevel@tonic-gate nmsg->msg_event_size = sizeof (md_mn_msg_mddb_block_t);
11600Sstevel@tonic-gate nmsg->msg_event_data = Zalloc(sizeof (md_mn_msg_mddb_block_t));
11610Sstevel@tonic-gate block_d = (md_mn_msg_mddb_block_t *)(void *)nmsg->msg_event_data;
11620Sstevel@tonic-gate block_d->msg_block_flags = MDDB_UNBLOCK_PARSE;
11630Sstevel@tonic-gate msglist[2] = nmsg;
11640Sstevel@tonic-gate
11650Sstevel@tonic-gate return (3); /* Return the number of submessages generated */
11660Sstevel@tonic-gate }
11670Sstevel@tonic-gate
11680Sstevel@tonic-gate /*
11690Sstevel@tonic-gate * Handler for MD_MN_MSG_SM_MDDB_ATTACH which is used to attach mddbs.
11700Sstevel@tonic-gate *
11710Sstevel@tonic-gate * Used when running:
11720Sstevel@tonic-gate * metadb -s set_name -a
11730Sstevel@tonic-gate * metaset -s set_name -a/-d disk
11740Sstevel@tonic-gate * metaset -s set_name -b
11750Sstevel@tonic-gate */
11760Sstevel@tonic-gate /*ARGSUSED*/
11770Sstevel@tonic-gate void
mdmn_do_sm_mddb_attach(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)11780Sstevel@tonic-gate mdmn_do_sm_mddb_attach(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
11790Sstevel@tonic-gate {
11800Sstevel@tonic-gate md_mn_msg_meta_db_attach_t *d;
11810Sstevel@tonic-gate struct mddb_config c;
11820Sstevel@tonic-gate int i;
11830Sstevel@tonic-gate int ret = 0;
11840Sstevel@tonic-gate md_error_t ep = mdnullerror;
11850Sstevel@tonic-gate char *name, *add_name;
11860Sstevel@tonic-gate mdname_t *np;
11870Sstevel@tonic-gate mdsetname_t *sp;
11880Sstevel@tonic-gate
11890Sstevel@tonic-gate resp->mmr_out_size = 0;
11900Sstevel@tonic-gate resp->mmr_err_size = 0;
11910Sstevel@tonic-gate resp->mmr_out = NULL;
11920Sstevel@tonic-gate resp->mmr_err = NULL;
11930Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
11940Sstevel@tonic-gate d = (md_mn_msg_meta_db_attach_t *)((void *)(msg->msg_event_data));
11950Sstevel@tonic-gate
11960Sstevel@tonic-gate (void) memset(&c, 0, sizeof (c));
11970Sstevel@tonic-gate c.c_setno = msg->msg_setno;
11980Sstevel@tonic-gate c.c_locator.l_dev = meta_cmpldev(d->msg_l_dev);
11990Sstevel@tonic-gate (void) strncpy(c.c_locator.l_driver, d->msg_dname,
12007210Srayh sizeof (c.c_locator.l_driver));
12010Sstevel@tonic-gate c.c_devname = d->msg_splitname;
12020Sstevel@tonic-gate c.c_locator.l_mnum = meta_getminor(d->msg_l_dev);
12030Sstevel@tonic-gate c.c_multi_node = 1;
12040Sstevel@tonic-gate if ((sp = metasetnosetname(c.c_setno, &ep)) == NULL) {
12050Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
12060Sstevel@tonic-gate resp->mmr_exitval = -1;
12070Sstevel@tonic-gate return;
12080Sstevel@tonic-gate }
12090Sstevel@tonic-gate (void) strcpy(c.c_setname, sp->setname);
12100Sstevel@tonic-gate c.c_sideno = getmyside(sp, &ep);
12110Sstevel@tonic-gate if (c.c_sideno == MD_SIDEWILD) {
12120Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
12130Sstevel@tonic-gate resp->mmr_exitval = -1;
12140Sstevel@tonic-gate return;
12150Sstevel@tonic-gate }
12160Sstevel@tonic-gate
12170Sstevel@tonic-gate name = splicename(&d->msg_splitname);
12181623Stw21770 np = metaname(&sp, name, LOGICAL_DEVICE, &ep);
12191623Stw21770 Free(name);
12201623Stw21770 if (np == NULL) {
12210Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
12220Sstevel@tonic-gate resp->mmr_exitval = -1;
12230Sstevel@tonic-gate return;
12240Sstevel@tonic-gate }
12250Sstevel@tonic-gate /*
12260Sstevel@tonic-gate * All nodes in MN diskset must do meta_check_replica
12270Sstevel@tonic-gate * since this causes the shared namespace to be
12280Sstevel@tonic-gate * populated by the md driver names while checking
12290Sstevel@tonic-gate * to see if this device is already in use as a
12300Sstevel@tonic-gate * metadevice.
12310Sstevel@tonic-gate */
12320Sstevel@tonic-gate if (meta_check_replica(sp, np, d->msg_options, 0,
12330Sstevel@tonic-gate (d->msg_cnt * d->msg_dbsize), &ep)) {
12340Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
12350Sstevel@tonic-gate resp->mmr_exitval = -1;
12360Sstevel@tonic-gate return;
12370Sstevel@tonic-gate }
12380Sstevel@tonic-gate
12390Sstevel@tonic-gate for (i = 0; i < d->msg_cnt; i++) {
12400Sstevel@tonic-gate c.c_locator.l_blkno = i * d->msg_dbsize + 16;
12410Sstevel@tonic-gate if (setup_med_cfg(sp, &c,
12420Sstevel@tonic-gate (d->msg_options & MDCHK_SET_FORCE), &ep)) {
12430Sstevel@tonic-gate ret = -1;
12440Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
12450Sstevel@tonic-gate break;
12460Sstevel@tonic-gate }
12470Sstevel@tonic-gate ret = metaioctl(MD_DB_NEWDEV, &c, &c.c_mde, NULL);
12480Sstevel@tonic-gate /* If newdev was successful, continue with attach */
12490Sstevel@tonic-gate if (ret == 0) {
12500Sstevel@tonic-gate if (meta_db_addsidenms(sp, np, c.c_locator.l_blkno,
12510Sstevel@tonic-gate DB_ADDSIDENMS_NO_BCAST, &ep)) {
12520Sstevel@tonic-gate ret = -1;
12530Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
12540Sstevel@tonic-gate break;
12550Sstevel@tonic-gate }
12560Sstevel@tonic-gate } else {
12570Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &c.c_mde);
12580Sstevel@tonic-gate break;
12590Sstevel@tonic-gate }
12600Sstevel@tonic-gate }
12610Sstevel@tonic-gate add_name = splicename(&d->msg_splitname);
12621623Stw21770 if ((np = metaname(&sp, add_name, LOGICAL_DEVICE, &ep)) != NULL) {
12630Sstevel@tonic-gate meta_invalidate_name(np);
12640Sstevel@tonic-gate } else {
12650Sstevel@tonic-gate ret = -1;
12660Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
12670Sstevel@tonic-gate }
12680Sstevel@tonic-gate Free(add_name);
12690Sstevel@tonic-gate
12700Sstevel@tonic-gate resp->mmr_exitval = ret;
12710Sstevel@tonic-gate }
12720Sstevel@tonic-gate
12730Sstevel@tonic-gate /*
12740Sstevel@tonic-gate * Handler for MD_MN_MSG_SM_MDDB_DETACH which is used to detach mddbs.
12750Sstevel@tonic-gate *
12760Sstevel@tonic-gate * Used when running:
12770Sstevel@tonic-gate * metadb -s set_name -d
12780Sstevel@tonic-gate * metaset -s set_name -a/-d disk
12790Sstevel@tonic-gate * metaset -s set_name -b
12800Sstevel@tonic-gate */
12810Sstevel@tonic-gate /*ARGSUSED*/
12820Sstevel@tonic-gate void
mdmn_do_sm_mddb_detach(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)12830Sstevel@tonic-gate mdmn_do_sm_mddb_detach(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
12840Sstevel@tonic-gate {
12850Sstevel@tonic-gate md_mn_msg_meta_db_detach_t *d;
12860Sstevel@tonic-gate struct mddb_config c;
12870Sstevel@tonic-gate int i;
12880Sstevel@tonic-gate int ret = 0;
12890Sstevel@tonic-gate md_error_t ep = mdnullerror;
12900Sstevel@tonic-gate char *name, *del_name;
12910Sstevel@tonic-gate mdname_t *np;
12920Sstevel@tonic-gate mdsetname_t *sp;
12930Sstevel@tonic-gate
12940Sstevel@tonic-gate resp->mmr_out_size = 0;
12950Sstevel@tonic-gate resp->mmr_err_size = 0;
12960Sstevel@tonic-gate resp->mmr_out = NULL;
12970Sstevel@tonic-gate resp->mmr_err = NULL;
12980Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
12990Sstevel@tonic-gate d = (md_mn_msg_meta_db_detach_t *)((void *)(msg->msg_event_data));
13000Sstevel@tonic-gate
13010Sstevel@tonic-gate if ((sp = metasetnosetname(msg->msg_setno, &ep)) == NULL) {
13020Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
13030Sstevel@tonic-gate resp->mmr_exitval = -1;
13040Sstevel@tonic-gate return;
13050Sstevel@tonic-gate }
13060Sstevel@tonic-gate
13070Sstevel@tonic-gate (void) memset(&c, 0, sizeof (c));
13080Sstevel@tonic-gate c.c_setno = msg->msg_setno;
13090Sstevel@tonic-gate if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) {
13100Sstevel@tonic-gate resp->mmr_exitval = -1;
13110Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &c.c_mde);
13120Sstevel@tonic-gate return;
13130Sstevel@tonic-gate }
13140Sstevel@tonic-gate i = 0;
13150Sstevel@tonic-gate del_name = splicename(&d->msg_splitname);
13160Sstevel@tonic-gate while (i < c.c_dbcnt) {
13170Sstevel@tonic-gate c.c_id = i;
13180Sstevel@tonic-gate if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) {
13190Sstevel@tonic-gate ret = -1;
13200Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &c.c_mde);
13210Sstevel@tonic-gate break;
13220Sstevel@tonic-gate }
13230Sstevel@tonic-gate name = splicename(&c.c_devname);
13240Sstevel@tonic-gate if (strcmp(name, del_name) != 0) {
13250Sstevel@tonic-gate Free(name);
13260Sstevel@tonic-gate i++;
13270Sstevel@tonic-gate continue;
13280Sstevel@tonic-gate }
13290Sstevel@tonic-gate Free(name);
13300Sstevel@tonic-gate /* Found a match - delete mddb */
13310Sstevel@tonic-gate if (metaioctl(MD_DB_DELDEV, &c, &c.c_mde, NULL) != 0) {
13320Sstevel@tonic-gate ret = -1;
13330Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &c.c_mde);
13340Sstevel@tonic-gate break;
13350Sstevel@tonic-gate }
13360Sstevel@tonic-gate /* Not incrementing "i" intentionally (dbcnt is changed) */
13370Sstevel@tonic-gate }
13381623Stw21770 if ((np = metaname(&sp, del_name, LOGICAL_DEVICE, &ep)) != NULL) {
13390Sstevel@tonic-gate meta_invalidate_name(np);
13400Sstevel@tonic-gate } else {
13410Sstevel@tonic-gate ret = -1;
13420Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
13430Sstevel@tonic-gate }
13440Sstevel@tonic-gate Free(del_name);
13450Sstevel@tonic-gate
13460Sstevel@tonic-gate resp->mmr_exitval = ret;
13470Sstevel@tonic-gate }
13480Sstevel@tonic-gate
13490Sstevel@tonic-gate /*
13500Sstevel@tonic-gate * Handler for MD_MN_MSG_META_DB_NEWSIDE which is used to update the
13510Sstevel@tonic-gate * side information for each diskset mddb when a new host has been
13520Sstevel@tonic-gate * added to the diskset. The side information is the /dev/dsk/ctds name
13530Sstevel@tonic-gate * that the new node would use to access each mddb.
13540Sstevel@tonic-gate *
13550Sstevel@tonic-gate * Since this routine makes no changes to the records in the diskset mddb,
13560Sstevel@tonic-gate * this routine only needs to be run on the master node. The master node's
13570Sstevel@tonic-gate * kernel code will detect that portions of the mddb have changed and
13580Sstevel@tonic-gate * will send a parse message to all nodes to re-parse parts of the mddb.
13590Sstevel@tonic-gate *
13600Sstevel@tonic-gate * Used when running:
13610Sstevel@tonic-gate * metaset -s set_name -a -h new_hostname
13620Sstevel@tonic-gate */
13630Sstevel@tonic-gate /*ARGSUSED*/
13640Sstevel@tonic-gate void
mdmn_do_meta_db_newside(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)13650Sstevel@tonic-gate mdmn_do_meta_db_newside(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
13660Sstevel@tonic-gate {
13670Sstevel@tonic-gate md_mn_msg_meta_db_newside_t *d;
13680Sstevel@tonic-gate struct mddb_config c;
13690Sstevel@tonic-gate int ret = 0;
13700Sstevel@tonic-gate mdsetname_t *sp;
13710Sstevel@tonic-gate md_error_t ep = mdnullerror;
13720Sstevel@tonic-gate
13730Sstevel@tonic-gate resp->mmr_out_size = 0;
13740Sstevel@tonic-gate resp->mmr_err_size = 0;
13750Sstevel@tonic-gate resp->mmr_out = NULL;
13760Sstevel@tonic-gate resp->mmr_err = NULL;
13770Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
13780Sstevel@tonic-gate d = (md_mn_msg_meta_db_newside_t *)((void *)(msg->msg_event_data));
13790Sstevel@tonic-gate
13800Sstevel@tonic-gate (void) memset(&c, 0, sizeof (c));
13810Sstevel@tonic-gate c.c_setno = msg->msg_setno;
13820Sstevel@tonic-gate c.c_locator.l_dev = meta_cmpldev(d->msg_l_dev);
13830Sstevel@tonic-gate c.c_locator.l_blkno = d->msg_blkno;
13840Sstevel@tonic-gate (void) strncpy(c.c_locator.l_driver, d->msg_dname,
13857210Srayh sizeof (c.c_locator.l_driver));
13860Sstevel@tonic-gate c.c_devname = d->msg_splitname;
13870Sstevel@tonic-gate c.c_locator.l_mnum = d->msg_mnum;
13880Sstevel@tonic-gate c.c_multi_node = 1;
13890Sstevel@tonic-gate if ((sp = metasetnosetname(c.c_setno, &ep)) == NULL) {
13900Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
13910Sstevel@tonic-gate resp->mmr_exitval = -1;
13920Sstevel@tonic-gate return;
13930Sstevel@tonic-gate }
13940Sstevel@tonic-gate (void) strcpy(c.c_setname, sp->setname);
13950Sstevel@tonic-gate c.c_sideno = d->msg_sideno;
13960Sstevel@tonic-gate
13970Sstevel@tonic-gate if ((ret = metaioctl(MD_DB_NEWSIDE, &c, &c.c_mde, NULL)) != 0) {
13980Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &c.c_mde);
13990Sstevel@tonic-gate }
14000Sstevel@tonic-gate resp->mmr_exitval = ret;
14010Sstevel@tonic-gate }
14020Sstevel@tonic-gate
14030Sstevel@tonic-gate /*
14040Sstevel@tonic-gate * Handler for MD_MN_MSG_META_DB_DELSIDE which is used to remove the
14050Sstevel@tonic-gate * side information for each diskset mddb when a host has been
14060Sstevel@tonic-gate * deleted from the diskset. The side information is the /dev/dsk/ctds name
14070Sstevel@tonic-gate * that the node would use to access each mddb.
14080Sstevel@tonic-gate *
14090Sstevel@tonic-gate * Since this routine makes no changes to the records in the diskset mddb,
14100Sstevel@tonic-gate * this routine only needs to be run on the master node. The master node's
14110Sstevel@tonic-gate * kernel code will detect that portions of the mddb have changed and
14120Sstevel@tonic-gate * will send a parse message to all nodes to re-parse parts of the mddb.
14130Sstevel@tonic-gate *
14140Sstevel@tonic-gate * Used when running:
14150Sstevel@tonic-gate * metaset -s set_name -d -h hostname
14160Sstevel@tonic-gate */
14170Sstevel@tonic-gate /*ARGSUSED*/
14180Sstevel@tonic-gate void
mdmn_do_meta_db_delside(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)14190Sstevel@tonic-gate mdmn_do_meta_db_delside(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
14200Sstevel@tonic-gate {
14210Sstevel@tonic-gate md_mn_msg_meta_db_delside_t *d;
14220Sstevel@tonic-gate mddb_config_t c;
14230Sstevel@tonic-gate int ret = 0;
14240Sstevel@tonic-gate mdsetname_t *sp;
14250Sstevel@tonic-gate md_error_t ep = mdnullerror;
14260Sstevel@tonic-gate
14270Sstevel@tonic-gate resp->mmr_out_size = 0;
14280Sstevel@tonic-gate resp->mmr_err_size = 0;
14290Sstevel@tonic-gate resp->mmr_out = NULL;
14300Sstevel@tonic-gate resp->mmr_err = NULL;
14310Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
14320Sstevel@tonic-gate d = (md_mn_msg_meta_db_delside_t *)((void *)(msg->msg_event_data));
14330Sstevel@tonic-gate
14340Sstevel@tonic-gate (void) memset(&c, 0, sizeof (c));
14350Sstevel@tonic-gate c.c_setno = msg->msg_setno;
14360Sstevel@tonic-gate c.c_locator.l_dev = meta_cmpldev(d->msg_l_dev);
14370Sstevel@tonic-gate c.c_locator.l_blkno = d->msg_blkno;
14380Sstevel@tonic-gate c.c_multi_node = 1;
14390Sstevel@tonic-gate if ((sp = metasetnosetname(c.c_setno, &ep)) == NULL) {
14400Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
14410Sstevel@tonic-gate resp->mmr_exitval = -1;
14420Sstevel@tonic-gate return;
14430Sstevel@tonic-gate }
14440Sstevel@tonic-gate (void) strcpy(c.c_setname, sp->setname);
14450Sstevel@tonic-gate c.c_sideno = d->msg_sideno;
14460Sstevel@tonic-gate
14470Sstevel@tonic-gate if ((ret = metaioctl(MD_DB_DELSIDE, &c, &c.c_mde, NULL)) != 0) {
14480Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &c.c_mde);
14490Sstevel@tonic-gate }
14500Sstevel@tonic-gate resp->mmr_exitval = ret;
14510Sstevel@tonic-gate }
14520Sstevel@tonic-gate
14530Sstevel@tonic-gate /*
14540Sstevel@tonic-gate * Handler for MD_MN_MSG_META_MD_ADDSIDE which is used to add the
14550Sstevel@tonic-gate * side information for each diskset metadevice component (if that
14560Sstevel@tonic-gate * component is a disk) when a host has been added to the diskset.
14570Sstevel@tonic-gate * The side information is the /dev/dsk/ctds name that the node would
14580Sstevel@tonic-gate * use to access the metadevice component.
14590Sstevel@tonic-gate *
14600Sstevel@tonic-gate * This routine makes changes to the mddb records and must be run
14610Sstevel@tonic-gate * on all nodes.
14620Sstevel@tonic-gate *
14630Sstevel@tonic-gate * Used when running:
14640Sstevel@tonic-gate * metaset -s set_name -a -h new_hostname
14650Sstevel@tonic-gate */
14660Sstevel@tonic-gate /*ARGSUSED*/
14670Sstevel@tonic-gate void
mdmn_do_meta_md_addside(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)14680Sstevel@tonic-gate mdmn_do_meta_md_addside(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
14690Sstevel@tonic-gate {
14700Sstevel@tonic-gate md_mn_msg_meta_md_addside_t *d;
14710Sstevel@tonic-gate mdnm_params_t nm;
14720Sstevel@tonic-gate mdsetname_t *sp;
14730Sstevel@tonic-gate char *cname, *dname;
14740Sstevel@tonic-gate minor_t mnum;
14750Sstevel@tonic-gate int done, i;
14760Sstevel@tonic-gate md_error_t ep = mdnullerror;
14770Sstevel@tonic-gate
14780Sstevel@tonic-gate resp->mmr_out_size = 0;
14790Sstevel@tonic-gate resp->mmr_err_size = 0;
14800Sstevel@tonic-gate resp->mmr_out = NULL;
14810Sstevel@tonic-gate resp->mmr_err = NULL;
14820Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
14830Sstevel@tonic-gate d = (md_mn_msg_meta_md_addside_t *)((void *)(msg->msg_event_data));
14840Sstevel@tonic-gate
14850Sstevel@tonic-gate (void) memset(&nm, 0, sizeof (nm));
14860Sstevel@tonic-gate if ((sp = metasetnosetname(msg->msg_setno, &ep)) == NULL) {
14870Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
14880Sstevel@tonic-gate resp->mmr_exitval = -1;
14890Sstevel@tonic-gate return;
14900Sstevel@tonic-gate }
14910Sstevel@tonic-gate /* While loop continues until IOCNXTKEY_NM gives nm.key of KEYWILD */
14920Sstevel@tonic-gate /*CONSTCOND*/
14930Sstevel@tonic-gate while (1) {
14942079Sstevep char *drvnm = NULL;
14952079Sstevep
14960Sstevel@tonic-gate nm.mde = mdnullerror;
14970Sstevel@tonic-gate nm.setno = msg->msg_setno;
14980Sstevel@tonic-gate nm.side = d->msg_otherside;
14990Sstevel@tonic-gate if (metaioctl(MD_IOCNXTKEY_NM, &nm, &nm.mde, NULL) != 0) {
15000Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &nm.mde);
15010Sstevel@tonic-gate resp->mmr_exitval = -1;
15020Sstevel@tonic-gate return;
15030Sstevel@tonic-gate }
15040Sstevel@tonic-gate
15050Sstevel@tonic-gate /* Normal exit path is to eventually get a KEYWILD */
15060Sstevel@tonic-gate if (nm.key == MD_KEYWILD) {
15070Sstevel@tonic-gate resp->mmr_exitval = 0;
15080Sstevel@tonic-gate return;
15090Sstevel@tonic-gate }
15100Sstevel@tonic-gate
15112079Sstevep /*
15122079Sstevep * Okay we have a valid key
15132079Sstevep * Let's see if it is hsp or not
15142079Sstevep */
15152079Sstevep nm.devname = (uintptr_t)meta_getnmentbykey(msg->msg_setno,
15167210Srayh d->msg_otherside, nm.key, &drvnm, NULL, NULL, &ep);
15172079Sstevep if (nm.devname == NULL || drvnm == NULL) {
15182079Sstevep if (nm.devname)
15192079Sstevep Free((void *)(uintptr_t)nm.devname);
15202079Sstevep if (drvnm)
15212079Sstevep Free((void *)(uintptr_t)drvnm);
15220Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
15230Sstevel@tonic-gate resp->mmr_exitval = -1;
15240Sstevel@tonic-gate return;
15250Sstevel@tonic-gate }
15262079Sstevep
15272079Sstevep /*
15282079Sstevep * If it is hsp add here
15292079Sstevep */
15302079Sstevep if (strcmp(drvnm, MD_HOTSPARES) == 0) {
15312079Sstevep if (add_name(sp, d->msg_sideno, nm.key, MD_HOTSPARES,
15322079Sstevep minor(NODEV), (char *)(uintptr_t)nm.devname,
15332079Sstevep NULL, NULL, &ep) == -1) {
15342079Sstevep Free((void *)(uintptr_t)nm.devname);
15352079Sstevep Free((void *)(uintptr_t)drvnm);
15362079Sstevep (void) mdstealerror(&(resp->mmr_ep), &ep);
15372079Sstevep resp->mmr_exitval = -1;
15382079Sstevep return;
15392079Sstevep } else {
15402079Sstevep Free((void *)(uintptr_t)nm.devname);
15412079Sstevep Free((void *)(uintptr_t)drvnm);
15422079Sstevep continue;
15432079Sstevep }
15442079Sstevep }
15452079Sstevep
15460Sstevel@tonic-gate nm.side = d->msg_sideno;
154762Sjeanm if ((done = meta_getside_devinfo(sp,
154862Sjeanm (char *)(uintptr_t)nm.devname,
15490Sstevel@tonic-gate d->msg_sideno, &cname, &dname, &mnum, &ep)) == -1) {
15500Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
155162Sjeanm Free((void *)(uintptr_t)nm.devname);
15520Sstevel@tonic-gate resp->mmr_exitval = -1;
15530Sstevel@tonic-gate return;
15540Sstevel@tonic-gate }
15552079Sstevep
155662Sjeanm Free((void *)(uintptr_t)nm.devname);
15572079Sstevep Free((void *)(uintptr_t)drvnm);
15582079Sstevep
15590Sstevel@tonic-gate if (done != 1) {
15600Sstevel@tonic-gate Free(cname);
15610Sstevel@tonic-gate Free(dname);
15620Sstevel@tonic-gate resp->mmr_exitval = -1;
15630Sstevel@tonic-gate return;
15640Sstevel@tonic-gate }
15650Sstevel@tonic-gate
15660Sstevel@tonic-gate /*
15670Sstevel@tonic-gate * The device reference count can be greater than 1 if
15680Sstevel@tonic-gate * more than one softpart is configured on top of the
15690Sstevel@tonic-gate * same device. If this is the case then we want to
15700Sstevel@tonic-gate * increment the count to sync up with the other sides.
15710Sstevel@tonic-gate */
15720Sstevel@tonic-gate for (i = 0; i < nm.ref_count; i++) {
15730Sstevel@tonic-gate if (add_name(sp, d->msg_sideno, nm.key, dname, mnum,
15741945Sjeanm cname, NULL, NULL, &ep) == -1) {
15750Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
15760Sstevel@tonic-gate Free(cname);
15770Sstevel@tonic-gate Free(dname);
15780Sstevel@tonic-gate resp->mmr_exitval = -1;
15790Sstevel@tonic-gate return;
15800Sstevel@tonic-gate }
15810Sstevel@tonic-gate }
15820Sstevel@tonic-gate Free(cname);
15830Sstevel@tonic-gate Free(dname);
15840Sstevel@tonic-gate }
15850Sstevel@tonic-gate
15860Sstevel@tonic-gate /*NOTREACHED*/
15870Sstevel@tonic-gate }
15880Sstevel@tonic-gate /*
15890Sstevel@tonic-gate * Handler for MD_MN_MSG_META_MD_DELSIDE which is used to delete the
15900Sstevel@tonic-gate * side information for each diskset metadevice component (if that
15910Sstevel@tonic-gate * component is a disk) when a host has been removed from the diskset.
15920Sstevel@tonic-gate * The side information is the /dev/dsk/ctds name that the node would
15930Sstevel@tonic-gate * use to access the metadevice component.
15940Sstevel@tonic-gate *
15950Sstevel@tonic-gate * This routine makes changes to the mddb records and must be run
15960Sstevel@tonic-gate * on all nodes.
15970Sstevel@tonic-gate *
15980Sstevel@tonic-gate * Used when running:
15990Sstevel@tonic-gate * metaset -s set_name -d -h hostname
16000Sstevel@tonic-gate */
16010Sstevel@tonic-gate /*ARGSUSED*/
16020Sstevel@tonic-gate void
mdmn_do_meta_md_delside(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)16030Sstevel@tonic-gate mdmn_do_meta_md_delside(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
16040Sstevel@tonic-gate {
16050Sstevel@tonic-gate md_mn_msg_meta_md_delside_t *d;
16060Sstevel@tonic-gate mdnm_params_t nm;
16070Sstevel@tonic-gate mdsetname_t *sp;
16080Sstevel@tonic-gate md_error_t ep = mdnullerror;
16090Sstevel@tonic-gate int i;
16100Sstevel@tonic-gate
16110Sstevel@tonic-gate resp->mmr_out_size = 0;
16120Sstevel@tonic-gate resp->mmr_err_size = 0;
16130Sstevel@tonic-gate resp->mmr_out = NULL;
16140Sstevel@tonic-gate resp->mmr_err = NULL;
16150Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
16160Sstevel@tonic-gate d = (md_mn_msg_meta_md_delside_t *)((void *)(msg->msg_event_data));
16170Sstevel@tonic-gate
16180Sstevel@tonic-gate if ((sp = metasetnosetname(msg->msg_setno, &ep)) == NULL) {
16190Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
16200Sstevel@tonic-gate resp->mmr_exitval = -1;
16210Sstevel@tonic-gate return;
16220Sstevel@tonic-gate }
16230Sstevel@tonic-gate
16240Sstevel@tonic-gate (void) memset(&nm, 0, sizeof (nm));
16250Sstevel@tonic-gate nm.key = MD_KEYWILD;
16260Sstevel@tonic-gate /*CONSTCOND*/
16270Sstevel@tonic-gate while (1) {
16280Sstevel@tonic-gate nm.mde = mdnullerror;
16290Sstevel@tonic-gate nm.setno = msg->msg_setno;
16300Sstevel@tonic-gate nm.side = MD_SIDEWILD;
16310Sstevel@tonic-gate if (metaioctl(MD_IOCNXTKEY_NM, &nm, &nm.mde, NULL) != 0) {
16320Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &nm.mde);
16330Sstevel@tonic-gate resp->mmr_exitval = -1;
16340Sstevel@tonic-gate return;
16350Sstevel@tonic-gate }
16360Sstevel@tonic-gate
16370Sstevel@tonic-gate /* Normal exit path is to eventually get a KEYWILD */
16380Sstevel@tonic-gate if (nm.key == MD_KEYWILD) {
16390Sstevel@tonic-gate resp->mmr_exitval = 0;
16400Sstevel@tonic-gate return;
16410Sstevel@tonic-gate }
16420Sstevel@tonic-gate
16430Sstevel@tonic-gate /*
16440Sstevel@tonic-gate * The device reference count can be greater than 1 if
16450Sstevel@tonic-gate * more than one softpart is configured on top of the
16460Sstevel@tonic-gate * same device. If this is the case then we want to
16470Sstevel@tonic-gate * decrement the count to zero so the entry can be
16480Sstevel@tonic-gate * actually removed.
16490Sstevel@tonic-gate */
16500Sstevel@tonic-gate for (i = 0; i < nm.ref_count; i++) {
16510Sstevel@tonic-gate if (del_name(sp, d->msg_sideno, nm.key, &ep) == -1) {
16520Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &ep);
16530Sstevel@tonic-gate resp->mmr_exitval = -1;
16540Sstevel@tonic-gate return;
16550Sstevel@tonic-gate }
16560Sstevel@tonic-gate }
16570Sstevel@tonic-gate }
16580Sstevel@tonic-gate
16590Sstevel@tonic-gate /*NOTREACHED*/
16600Sstevel@tonic-gate }
16610Sstevel@tonic-gate
16620Sstevel@tonic-gate /*
16630Sstevel@tonic-gate * Handler for MD_MN_MSG_MDDB_OPTRECERR which is used to notify
16640Sstevel@tonic-gate * the master node that a node has seen an error when attempting to
16650Sstevel@tonic-gate * write to the optimized resync records that reside on 2 of the diskset
16660Sstevel@tonic-gate * mddbs. Master node will mark the failed replica in error and this
16670Sstevel@tonic-gate * will send a parse message to all nodes to re-read parts of the mddb
16680Sstevel@tonic-gate * and to fix their optimized resync records based on this information.
16690Sstevel@tonic-gate */
16700Sstevel@tonic-gate /*ARGSUSED*/
16710Sstevel@tonic-gate void
mdmn_do_mddb_optrecerr(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)16720Sstevel@tonic-gate mdmn_do_mddb_optrecerr(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
16730Sstevel@tonic-gate {
16740Sstevel@tonic-gate md_mn_msg_mddb_optrecerr_t *d;
16750Sstevel@tonic-gate mddb_optrec_parm_t mop;
16760Sstevel@tonic-gate int ret;
16770Sstevel@tonic-gate int i;
16780Sstevel@tonic-gate
16790Sstevel@tonic-gate resp->mmr_out_size = 0;
16800Sstevel@tonic-gate resp->mmr_err_size = 0;
16810Sstevel@tonic-gate resp->mmr_out = NULL;
16820Sstevel@tonic-gate resp->mmr_err = NULL;
16830Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
16840Sstevel@tonic-gate d = (md_mn_msg_mddb_optrecerr_t *)((void *)(msg->msg_event_data));
16850Sstevel@tonic-gate
16860Sstevel@tonic-gate (void) memset(&mop, 0, sizeof (mop));
16870Sstevel@tonic-gate mop.c_setno = msg->msg_setno;
16880Sstevel@tonic-gate for (i = 0; i < 2; i++) {
16890Sstevel@tonic-gate mop.c_recerr[i] = d->msg_recerr[i];
16900Sstevel@tonic-gate }
16910Sstevel@tonic-gate ret = metaioctl(MD_MN_MDDB_OPTRECFIX, &mop, &mop.c_mde, NULL);
16920Sstevel@tonic-gate if (ret)
16930Sstevel@tonic-gate (void) mdstealerror(&(resp->mmr_ep), &mop.c_mde);
16940Sstevel@tonic-gate
16950Sstevel@tonic-gate resp->mmr_exitval = ret;
16960Sstevel@tonic-gate }
16970Sstevel@tonic-gate
16980Sstevel@tonic-gate int
mdmn_smgen_test6(md_mn_msg_t * msg,md_mn_msg_t ** msglist)16990Sstevel@tonic-gate mdmn_smgen_test6(md_mn_msg_t *msg, md_mn_msg_t **msglist)
17000Sstevel@tonic-gate {
17010Sstevel@tonic-gate md_mn_msg_t *nmsg;
17020Sstevel@tonic-gate
17030Sstevel@tonic-gate nmsg = Zalloc(sizeof (md_mn_msg_t));
17040Sstevel@tonic-gate MSGID_COPY(&(msg->msg_msgid), &(nmsg->msg_msgid));
17050Sstevel@tonic-gate
17060Sstevel@tonic-gate nmsg->msg_flags = MD_MSGF_NO_LOG; /* Don't log submessages */
17070Sstevel@tonic-gate nmsg->msg_setno = msg->msg_setno;
17080Sstevel@tonic-gate nmsg->msg_type = MD_MN_MSG_TEST2;
17090Sstevel@tonic-gate nmsg->msg_event_size = sizeof ("test2");
17100Sstevel@tonic-gate nmsg->msg_event_data = Strdup("test2");
17110Sstevel@tonic-gate msglist[0] = nmsg;
17120Sstevel@tonic-gate
17130Sstevel@tonic-gate nmsg = Zalloc(sizeof (md_mn_msg_t));
17140Sstevel@tonic-gate MSGID_COPY(&(msg->msg_msgid), &(nmsg->msg_msgid));
17150Sstevel@tonic-gate
17160Sstevel@tonic-gate nmsg->msg_flags = MD_MSGF_NO_LOG; /* Don't log submessages */
17170Sstevel@tonic-gate nmsg->msg_setno = msg->msg_setno;
17180Sstevel@tonic-gate nmsg->msg_type = MD_MN_MSG_TEST2;
17190Sstevel@tonic-gate nmsg->msg_event_size = sizeof ("test2");
17200Sstevel@tonic-gate nmsg->msg_event_data = Strdup("test2");
17210Sstevel@tonic-gate msglist[1] = nmsg;
17220Sstevel@tonic-gate
17230Sstevel@tonic-gate nmsg = Zalloc(sizeof (md_mn_msg_t));
17240Sstevel@tonic-gate MSGID_COPY(&(msg->msg_msgid), &(nmsg->msg_msgid));
17250Sstevel@tonic-gate
17260Sstevel@tonic-gate nmsg->msg_flags = MD_MSGF_NO_LOG; /* Don't log submessages */
17270Sstevel@tonic-gate nmsg->msg_setno = msg->msg_setno;
17280Sstevel@tonic-gate nmsg->msg_type = MD_MN_MSG_TEST3;
17290Sstevel@tonic-gate nmsg->msg_event_size = sizeof ("test3");
17300Sstevel@tonic-gate nmsg->msg_event_data = Strdup("test3");
17310Sstevel@tonic-gate msglist[2] = nmsg;
17320Sstevel@tonic-gate
17330Sstevel@tonic-gate nmsg = Zalloc(sizeof (md_mn_msg_t));
17340Sstevel@tonic-gate MSGID_COPY(&(msg->msg_msgid), &(nmsg->msg_msgid));
17350Sstevel@tonic-gate
17360Sstevel@tonic-gate nmsg->msg_flags = MD_MSGF_NO_LOG; /* Don't log submessages */
17370Sstevel@tonic-gate nmsg->msg_setno = msg->msg_setno;
17380Sstevel@tonic-gate nmsg->msg_type = MD_MN_MSG_TEST4;
17390Sstevel@tonic-gate nmsg->msg_event_size = sizeof ("test4");
17400Sstevel@tonic-gate nmsg->msg_event_data = Strdup("test4");
17410Sstevel@tonic-gate msglist[3] = nmsg;
17420Sstevel@tonic-gate
17430Sstevel@tonic-gate return (4); /* Return the number of submessages generated */
17440Sstevel@tonic-gate }
17450Sstevel@tonic-gate
17460Sstevel@tonic-gate /*
17470Sstevel@tonic-gate * This is to send an MD_IOCSET ioctl to all nodes to create a soft
17480Sstevel@tonic-gate * partition.
17490Sstevel@tonic-gate */
17500Sstevel@tonic-gate /*ARGSUSED*/
17510Sstevel@tonic-gate void
mdmn_do_iocset(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)17520Sstevel@tonic-gate mdmn_do_iocset(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
17530Sstevel@tonic-gate {
17540Sstevel@tonic-gate md_mn_msg_iocset_t *d;
17550Sstevel@tonic-gate int ret;
17560Sstevel@tonic-gate set_t setno;
17570Sstevel@tonic-gate mdsetname_t *sp;
17580Sstevel@tonic-gate mdname_t *np;
17590Sstevel@tonic-gate md_error_t mde = mdnullerror;
17600Sstevel@tonic-gate
17610Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK; /* Ok state */;
17620Sstevel@tonic-gate resp->mmr_out_size = 0;
17630Sstevel@tonic-gate resp->mmr_err_size = 0;
17640Sstevel@tonic-gate resp->mmr_out = NULL;
17650Sstevel@tonic-gate resp->mmr_err = NULL;
17660Sstevel@tonic-gate d = (md_mn_msg_iocset_t *)(void *)msg->msg_event_data;
17670Sstevel@tonic-gate
17680Sstevel@tonic-gate setno = MD_MIN2SET(d->iocset_params.mnum);
17690Sstevel@tonic-gate if ((sp = metasetnosetname(setno, &mde)) == NULL) {
17700Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
17710Sstevel@tonic-gate "MD_MN_MSG_IOCSET: Invalid setno %d\n"), setno);
17720Sstevel@tonic-gate resp->mmr_exitval = 1;
17730Sstevel@tonic-gate return;
17740Sstevel@tonic-gate }
17750Sstevel@tonic-gate
17761623Stw21770 /*
17771623Stw21770 * Device should be in the namespace already
17781623Stw21770 */
17790Sstevel@tonic-gate if ((np = metamnumname(&sp, d->iocset_params.mnum, 1, &mde)) == NULL) {
17800Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
17810Sstevel@tonic-gate "MD_MN_MSG_IOCSET: Invalid mnum %d\n"),
17820Sstevel@tonic-gate d->iocset_params.mnum);
17830Sstevel@tonic-gate resp->mmr_exitval = 1;
17840Sstevel@tonic-gate return;
17850Sstevel@tonic-gate }
17860Sstevel@tonic-gate
17871623Stw21770 /*
17881623Stw21770 * Create unit structure
17891623Stw21770 */
179062Sjeanm d->iocset_params.mdp = (uintptr_t)&d->unit; /* set pointer to unit */
17910Sstevel@tonic-gate ret = metaioctl(MD_IOCSET, &(d->iocset_params), &mde, np->cname);
17920Sstevel@tonic-gate resp->mmr_exitval = ret;
17930Sstevel@tonic-gate }
17940Sstevel@tonic-gate
17950Sstevel@tonic-gate /*
17960Sstevel@tonic-gate * This is to update the status of a softpart
17970Sstevel@tonic-gate */
17980Sstevel@tonic-gate /*ARGSUSED*/
17990Sstevel@tonic-gate void
mdmn_do_sp_setstat(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)18000Sstevel@tonic-gate mdmn_do_sp_setstat(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
18010Sstevel@tonic-gate {
18020Sstevel@tonic-gate md_mn_msg_sp_setstat_t *d;
18030Sstevel@tonic-gate int ret;
18040Sstevel@tonic-gate set_t setno;
18050Sstevel@tonic-gate mdsetname_t *sp;
18060Sstevel@tonic-gate minor_t mnum;
18070Sstevel@tonic-gate md_error_t mde = mdnullerror;
18080Sstevel@tonic-gate
18090Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK; /* Ok state */;
18100Sstevel@tonic-gate resp->mmr_out_size = 0;
18110Sstevel@tonic-gate resp->mmr_err_size = 0;
18120Sstevel@tonic-gate resp->mmr_out = NULL;
18130Sstevel@tonic-gate resp->mmr_err = NULL;
18140Sstevel@tonic-gate d = (md_mn_msg_sp_setstat_t *)(void *)msg->msg_event_data;
18150Sstevel@tonic-gate
18160Sstevel@tonic-gate mnum = d->sp_setstat_mnum;
18170Sstevel@tonic-gate setno = MD_MIN2SET(mnum);
18180Sstevel@tonic-gate if ((sp = metasetnosetname(setno, &mde)) == NULL) {
18190Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
18200Sstevel@tonic-gate "MD_MN_MSG_IOCSET: Invalid setno %d\n"), setno);
18210Sstevel@tonic-gate resp->mmr_exitval = 1;
18220Sstevel@tonic-gate return;
18230Sstevel@tonic-gate }
18240Sstevel@tonic-gate
18250Sstevel@tonic-gate ret = meta_sp_setstatus(sp, &mnum, 1, d->sp_setstat_status, &mde);
18260Sstevel@tonic-gate resp->mmr_exitval = ret;
18270Sstevel@tonic-gate }
18280Sstevel@tonic-gate
18290Sstevel@tonic-gate /*
18300Sstevel@tonic-gate * This is to add a key to the namespace
18310Sstevel@tonic-gate */
18320Sstevel@tonic-gate /*ARGSUSED*/
18330Sstevel@tonic-gate void
mdmn_do_addkeyname(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)18340Sstevel@tonic-gate mdmn_do_addkeyname(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
18350Sstevel@tonic-gate {
18360Sstevel@tonic-gate md_mn_msg_addkeyname_t *d;
18370Sstevel@tonic-gate int ret;
18380Sstevel@tonic-gate set_t setno;
18390Sstevel@tonic-gate mdsetname_t *sp;
18400Sstevel@tonic-gate md_error_t mde = mdnullerror;
18410Sstevel@tonic-gate mdname_t *compnp;
18420Sstevel@tonic-gate
18430Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK; /* Ok state */;
18440Sstevel@tonic-gate resp->mmr_out_size = 0;
18450Sstevel@tonic-gate resp->mmr_err_size = 0;
18460Sstevel@tonic-gate resp->mmr_out = NULL;
18470Sstevel@tonic-gate resp->mmr_err = NULL;
18480Sstevel@tonic-gate d = (md_mn_msg_addkeyname_t *)(void *)msg->msg_event_data;
18490Sstevel@tonic-gate
18500Sstevel@tonic-gate setno = d->addkeyname_setno;
18510Sstevel@tonic-gate if ((sp = metasetnosetname(setno, &mde)) == NULL) {
18520Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
18530Sstevel@tonic-gate "MD_MN_ADDKEYNAME: Invalid setno %d\n"), setno);
18540Sstevel@tonic-gate resp->mmr_exitval = -1;
18550Sstevel@tonic-gate return;
18560Sstevel@tonic-gate }
18570Sstevel@tonic-gate
18581623Stw21770 compnp = metaname(&sp, d->addkeyname_name, UNKNOWN, &mde);
18590Sstevel@tonic-gate if (compnp != NULL) {
18600Sstevel@tonic-gate ret = add_key_name(sp, compnp, NULL, &mde);
18610Sstevel@tonic-gate if (ret < 0)
18620Sstevel@tonic-gate resp->mmr_exitval = -1;
18630Sstevel@tonic-gate else
18640Sstevel@tonic-gate resp->mmr_exitval = compnp->key;
18650Sstevel@tonic-gate } else {
18660Sstevel@tonic-gate resp->mmr_exitval = -1;
18670Sstevel@tonic-gate }
18680Sstevel@tonic-gate }
18690Sstevel@tonic-gate
18700Sstevel@tonic-gate /*
18710Sstevel@tonic-gate * This is to delete a key from the namespace
18720Sstevel@tonic-gate */
18730Sstevel@tonic-gate /*ARGSUSED*/
18740Sstevel@tonic-gate void
mdmn_do_delkeyname(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)18750Sstevel@tonic-gate mdmn_do_delkeyname(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
18760Sstevel@tonic-gate {
18770Sstevel@tonic-gate md_mn_msg_delkeyname_t *d;
18780Sstevel@tonic-gate int ret;
18790Sstevel@tonic-gate set_t setno;
18800Sstevel@tonic-gate mdsetname_t *sp;
18810Sstevel@tonic-gate md_error_t mde = mdnullerror;
18820Sstevel@tonic-gate mdname_t *compnp;
18830Sstevel@tonic-gate
18840Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK; /* Ok state */;
18850Sstevel@tonic-gate resp->mmr_out_size = 0;
18860Sstevel@tonic-gate resp->mmr_err_size = 0;
18870Sstevel@tonic-gate resp->mmr_out = NULL;
18880Sstevel@tonic-gate resp->mmr_err = NULL;
18890Sstevel@tonic-gate d = (md_mn_msg_delkeyname_t *)(void *)msg->msg_event_data;
18900Sstevel@tonic-gate
18910Sstevel@tonic-gate setno = d->delkeyname_setno;
18920Sstevel@tonic-gate if ((sp = metasetnosetname(setno, &mde)) == NULL) {
18930Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
18940Sstevel@tonic-gate "MD_MN_DELKEYNAME: Invalid setno %d\n"), setno);
18950Sstevel@tonic-gate resp->mmr_exitval = -1;
18960Sstevel@tonic-gate return;
18970Sstevel@tonic-gate }
18980Sstevel@tonic-gate
18990Sstevel@tonic-gate compnp = metadevname(&sp, d->delkeyname_dev, &mde);
19000Sstevel@tonic-gate if (compnp != NULL) {
19010Sstevel@tonic-gate /*
19020Sstevel@tonic-gate * Reset the key value for the name. This is required because
19030Sstevel@tonic-gate * any previous call of del_key_name for the same component
19040Sstevel@tonic-gate * will have resulted in the key value being reset to MD_KEYBAD
19050Sstevel@tonic-gate * even though there may still be references to this component.
19060Sstevel@tonic-gate */
19070Sstevel@tonic-gate compnp->key = d->delkeyname_key;
19080Sstevel@tonic-gate ret = del_key_name(sp, compnp, &mde);
19090Sstevel@tonic-gate resp->mmr_exitval = ret;
19100Sstevel@tonic-gate } else {
19110Sstevel@tonic-gate resp->mmr_exitval = -1;
19120Sstevel@tonic-gate }
19130Sstevel@tonic-gate }
19140Sstevel@tonic-gate
19150Sstevel@tonic-gate /*
19160Sstevel@tonic-gate * This is to get the value of tstate from the master node. We use this
19170Sstevel@tonic-gate * to get the ABR state of a metadevice from the master.
19180Sstevel@tonic-gate */
19190Sstevel@tonic-gate /*ARGSUSED*/
19200Sstevel@tonic-gate void
mdmn_do_get_tstate(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)19210Sstevel@tonic-gate mdmn_do_get_tstate(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
19220Sstevel@tonic-gate {
19230Sstevel@tonic-gate md_mn_msg_gettstate_t *d;
19240Sstevel@tonic-gate int ret;
19250Sstevel@tonic-gate uint_t tstate;
19260Sstevel@tonic-gate md_error_t mde = mdnullerror;
19270Sstevel@tonic-gate
19280Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK; /* Ok state */;
19290Sstevel@tonic-gate resp->mmr_out_size = 0;
19300Sstevel@tonic-gate resp->mmr_err_size = 0;
19310Sstevel@tonic-gate resp->mmr_out = NULL;
19320Sstevel@tonic-gate resp->mmr_err = NULL;
19330Sstevel@tonic-gate d = (md_mn_msg_gettstate_t *)(void *)msg->msg_event_data;
19340Sstevel@tonic-gate
19350Sstevel@tonic-gate ret = meta_get_tstate(d->gettstate_dev, &tstate, &mde);
19360Sstevel@tonic-gate if (ret != 0) {
19370Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
19380Sstevel@tonic-gate "MD_MN_GET_TSTATE: Invalid dev %llx\n"), d->gettstate_dev);
19390Sstevel@tonic-gate tstate = 0;
19400Sstevel@tonic-gate }
19410Sstevel@tonic-gate resp->mmr_exitval = tstate;
19420Sstevel@tonic-gate }
19430Sstevel@tonic-gate
19440Sstevel@tonic-gate /*
19450Sstevel@tonic-gate * This is to get the mirror ABR state and the state of its submirrors from
19460Sstevel@tonic-gate * the master node. We need this to ensure consistent output from metastat
19470Sstevel@tonic-gate * when a new node joins the cluster during a resync. Without this the
19480Sstevel@tonic-gate * submirror status will be incorrect until the whole resync is complete which
19490Sstevel@tonic-gate * may take days for very large metadevices.
19500Sstevel@tonic-gate */
19510Sstevel@tonic-gate /*ARGSUSED*/
19520Sstevel@tonic-gate void
mdmn_do_get_mirstate(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)19530Sstevel@tonic-gate mdmn_do_get_mirstate(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
19540Sstevel@tonic-gate {
19550Sstevel@tonic-gate md_mn_msg_mir_state_t *d;
19560Sstevel@tonic-gate md_mn_msg_mir_state_res_t *res; /* Results */
19570Sstevel@tonic-gate set_t setno;
19580Sstevel@tonic-gate mdsetname_t *sp; /* Set name */
19590Sstevel@tonic-gate mdname_t *mirnp; /* Mirror name */
19600Sstevel@tonic-gate md_error_t mde = mdnullerror;
19610Sstevel@tonic-gate mm_unit_t *mm; /* Mirror */
19620Sstevel@tonic-gate int smi;
19630Sstevel@tonic-gate uint_t tstate;
19640Sstevel@tonic-gate
19650Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
19660Sstevel@tonic-gate resp->mmr_out_size = sizeof (md_mn_msg_mir_state_res_t);
19670Sstevel@tonic-gate resp->mmr_err_size = 0;
19680Sstevel@tonic-gate resp->mmr_out = Malloc(resp->mmr_out_size);
19690Sstevel@tonic-gate resp->mmr_err = NULL;
19700Sstevel@tonic-gate d = (md_mn_msg_mir_state_t *)(void *)msg->msg_event_data;
19710Sstevel@tonic-gate res = (md_mn_msg_mir_state_res_t *)(void *)resp->mmr_out;
19720Sstevel@tonic-gate
19730Sstevel@tonic-gate /* Validate set information from minor number */
19740Sstevel@tonic-gate setno = MD_MIN2SET(d->mir_state_mnum);
19750Sstevel@tonic-gate sp = metasetnosetname(setno, &mde);
19760Sstevel@tonic-gate if (sp == NULL) {
19770Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
19780Sstevel@tonic-gate "MD_MN_GET_MIRROR_STATE: Invalid set %d\n"), setno);
19790Sstevel@tonic-gate resp->mmr_exitval = 1; /* Failure */
19800Sstevel@tonic-gate Free(resp->mmr_out);
19810Sstevel@tonic-gate resp->mmr_out_size = 0;
19820Sstevel@tonic-gate return;
19830Sstevel@tonic-gate }
19840Sstevel@tonic-gate
19850Sstevel@tonic-gate /* Construct mirror name from minor number */
19860Sstevel@tonic-gate mirnp = metamnumname(&sp, d->mir_state_mnum, 0, &mde);
19870Sstevel@tonic-gate if (mirnp == NULL) {
19880Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
19890Sstevel@tonic-gate "MD_MN_GET_MIRROR_STATE: Invalid minor %lx\n"),
19900Sstevel@tonic-gate d->mir_state_mnum);
19910Sstevel@tonic-gate resp->mmr_exitval = 2; /* Failure */
19920Sstevel@tonic-gate Free(resp->mmr_out);
19930Sstevel@tonic-gate resp->mmr_out_size = 0;
19940Sstevel@tonic-gate return;
19950Sstevel@tonic-gate }
19960Sstevel@tonic-gate
19970Sstevel@tonic-gate /* Get common mirror structure */
19980Sstevel@tonic-gate mm = (mm_unit_t *)meta_get_mdunit(sp, mirnp, &mde);
19990Sstevel@tonic-gate if (mm == NULL) {
20000Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
20010Sstevel@tonic-gate "MD_MN_GET_MIRROR_STATE: Invalid mirror minor %x\n"),
20020Sstevel@tonic-gate d->mir_state_mnum);
20030Sstevel@tonic-gate resp->mmr_exitval = 3; /* Failure */
20040Sstevel@tonic-gate Free(resp->mmr_out);
20050Sstevel@tonic-gate resp->mmr_out_size = 0;
20060Sstevel@tonic-gate return;
20070Sstevel@tonic-gate }
20080Sstevel@tonic-gate
20090Sstevel@tonic-gate if (meta_get_tstate(d->mir_state_mnum, &tstate, &mde) != 0) {
20100Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
20110Sstevel@tonic-gate "MD_MN_GET_MIRROR_STATE: Invalid minor %lx\n"),
20120Sstevel@tonic-gate d->mir_state_mnum);
20130Sstevel@tonic-gate resp->mmr_exitval = 4; /* Failure */
20140Sstevel@tonic-gate Free(resp->mmr_out);
20150Sstevel@tonic-gate resp->mmr_out_size = 0;
20160Sstevel@tonic-gate return;
20170Sstevel@tonic-gate }
20180Sstevel@tonic-gate /*
20190Sstevel@tonic-gate * Fill in the sm_state/sm_flags value in the results structure which
20200Sstevel@tonic-gate * gets passed back to the message originator
20210Sstevel@tonic-gate */
20220Sstevel@tonic-gate resp->mmr_exitval = 0;
20230Sstevel@tonic-gate for (smi = 0; (smi < NMIRROR); smi++) {
20240Sstevel@tonic-gate mm_submirror_t *mmsp = &mm->un_sm[smi];
20250Sstevel@tonic-gate res->sm_state[smi] = mmsp->sm_state;
20260Sstevel@tonic-gate res->sm_flags[smi] = mmsp->sm_flags;
20270Sstevel@tonic-gate }
20280Sstevel@tonic-gate /* Returm value of tstate for mirror */
20290Sstevel@tonic-gate res->mir_tstate = tstate;
20300Sstevel@tonic-gate }
20310Sstevel@tonic-gate
20320Sstevel@tonic-gate /*
20330Sstevel@tonic-gate * This is to issue an ioctl to call poke_hotspares
20340Sstevel@tonic-gate */
20350Sstevel@tonic-gate /*ARGSUSED*/
20360Sstevel@tonic-gate void
mdmn_do_poke_hotspares(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)20370Sstevel@tonic-gate mdmn_do_poke_hotspares(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
20380Sstevel@tonic-gate {
20390Sstevel@tonic-gate
20400Sstevel@tonic-gate md_mn_poke_hotspares_t pokehsp;
20410Sstevel@tonic-gate md_mn_msg_pokehsp_t *d;
20420Sstevel@tonic-gate
20430Sstevel@tonic-gate resp->mmr_out_size = 0;
20440Sstevel@tonic-gate resp->mmr_err_size = 0;
20450Sstevel@tonic-gate resp->mmr_out = NULL;
20460Sstevel@tonic-gate resp->mmr_err = NULL;
20470Sstevel@tonic-gate resp->mmr_comm_state = MDMNE_ACK;
20480Sstevel@tonic-gate d = (md_mn_msg_pokehsp_t *)(void *)msg->msg_event_data;
20490Sstevel@tonic-gate
20500Sstevel@tonic-gate (void) memset(&pokehsp, 0, sizeof (pokehsp));
20510Sstevel@tonic-gate MD_SETDRIVERNAME(&pokehsp, MD_MIRROR, d->pokehsp_setno);
20520Sstevel@tonic-gate
20530Sstevel@tonic-gate resp->mmr_exitval = metaioctl(MD_MN_POKE_HOTSPARES, &pokehsp,
20540Sstevel@tonic-gate &pokehsp.mde, NULL);
20550Sstevel@tonic-gate }
20561623Stw21770
20571623Stw21770 /*
20581623Stw21770 * Called to create a softpart during a metarecover operation
20591623Stw21770 */
20601623Stw21770 /*ARGSUSED*/
20611623Stw21770 void
mdmn_do_addmdname(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)20621623Stw21770 mdmn_do_addmdname(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
20631623Stw21770 {
20641623Stw21770 md_mn_msg_addmdname_t *d;
20651623Stw21770 md_error_t mde = mdnullerror;
20661623Stw21770 mdsetname_t *sp;
20671623Stw21770 int init = 0;
20681623Stw21770 mdkey_t key;
20691623Stw21770 minor_t mnum;
20701623Stw21770
20711623Stw21770 resp->mmr_comm_state = MDMNE_ACK; /* Ok state */;
20721623Stw21770 resp->mmr_out_size = 0;
20731623Stw21770 resp->mmr_err_size = 0;
20741623Stw21770 resp->mmr_out = NULL;
20751623Stw21770 resp->mmr_err = NULL;
20761623Stw21770 d = (md_mn_msg_addmdname_t *)(void *)msg->msg_event_data;
20771623Stw21770
20781623Stw21770 if ((sp = metasetnosetname(d->addmdname_setno, &mde)) == NULL) {
20791623Stw21770 syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
20801623Stw21770 "MD_MN_MSG_ADDMDNAME: Invalid setno %d\n"),
20811623Stw21770 d->addmdname_setno);
20821623Stw21770 resp->mmr_exitval = 1;
20831623Stw21770 return;
20841623Stw21770 }
20851623Stw21770
20861623Stw21770 /*
20871623Stw21770 * If device node does not exist then init it
20881623Stw21770 */
20891623Stw21770 if (!is_existing_meta_hsp(sp, d->addmdname_name)) {
20907210Srayh if ((key = meta_init_make_device(&sp, d->addmdname_name,
20917210Srayh &mde)) <= 0) {
20927210Srayh syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
20937210Srayh "MD_MN_MSG_ADDMDNAME: Invalid name %s\n"),
20947210Srayh d->addmdname_name);
20957210Srayh resp->mmr_exitval = 1;
20967210Srayh return;
20971623Stw21770 }
20981623Stw21770
20991623Stw21770 init = 1;
21001623Stw21770 }
21011623Stw21770
21021623Stw21770 /*
21031623Stw21770 * We should have it
21041623Stw21770 */
21051623Stw21770 if (metaname(&sp, d->addmdname_name, META_DEVICE, &mde) == NULL) {
21061623Stw21770
21077210Srayh if (init) {
21087210Srayh if (meta_getnmentbykey(sp->setno, MD_SIDEWILD,
21097210Srayh key, NULL, &mnum, NULL, &mde) != NULL) {
21107210Srayh (void) metaioctl(
21117210Srayh MD_IOCREM_DEV, &mnum, &mde, NULL);
21127210Srayh }
21137210Srayh (void) del_self_name(sp, key, &mde);
21141623Stw21770 }
21151623Stw21770
21167210Srayh resp->mmr_exitval = 1;
21177210Srayh return;
21181623Stw21770 }
21191623Stw21770
21201623Stw21770 resp->mmr_exitval = 0;
21211623Stw21770 }
2122*8452SJohn.Wren.Kennedy@Sun.COM
2123*8452SJohn.Wren.Kennedy@Sun.COM /*
2124*8452SJohn.Wren.Kennedy@Sun.COM * This is used to issue a MD_MN_RR_DIRTY ioctl to the mirror.
2125*8452SJohn.Wren.Kennedy@Sun.COM */
2126*8452SJohn.Wren.Kennedy@Sun.COM /*ARGSUSED*/
2127*8452SJohn.Wren.Kennedy@Sun.COM void
mdmn_do_mark_dirty(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)2128*8452SJohn.Wren.Kennedy@Sun.COM mdmn_do_mark_dirty(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
2129*8452SJohn.Wren.Kennedy@Sun.COM {
2130*8452SJohn.Wren.Kennedy@Sun.COM md_mn_msg_rr_dirty_t *d;
2131*8452SJohn.Wren.Kennedy@Sun.COM md_mn_rr_dirty_params_t rp;
2132*8452SJohn.Wren.Kennedy@Sun.COM int ret;
2133*8452SJohn.Wren.Kennedy@Sun.COM
2134*8452SJohn.Wren.Kennedy@Sun.COM resp->mmr_out_size = 0;
2135*8452SJohn.Wren.Kennedy@Sun.COM resp->mmr_err_size = 0;
2136*8452SJohn.Wren.Kennedy@Sun.COM resp->mmr_out = NULL;
2137*8452SJohn.Wren.Kennedy@Sun.COM resp->mmr_err = NULL;
2138*8452SJohn.Wren.Kennedy@Sun.COM resp->mmr_comm_state = MDMNE_ACK;
2139*8452SJohn.Wren.Kennedy@Sun.COM d = (md_mn_msg_rr_dirty_t *)((void *)(msg->msg_event_data));
2140*8452SJohn.Wren.Kennedy@Sun.COM
2141*8452SJohn.Wren.Kennedy@Sun.COM (void) memset(&rp, 0, sizeof (rp));
2142*8452SJohn.Wren.Kennedy@Sun.COM MD_SETDRIVERNAME(&rp, MD_MIRROR, MD_MIN2SET(d->rr_mnum))
2143*8452SJohn.Wren.Kennedy@Sun.COM rp.rr_mnum = d->rr_mnum;
2144*8452SJohn.Wren.Kennedy@Sun.COM rp.rr_nodeid = d->rr_nodeid;
2145*8452SJohn.Wren.Kennedy@Sun.COM rp.rr_start = (ushort_t)((d->rr_range >> 16) & 0xffff);
2146*8452SJohn.Wren.Kennedy@Sun.COM rp.rr_end = (ushort_t)(d->rr_range & 0xffff);
2147*8452SJohn.Wren.Kennedy@Sun.COM
2148*8452SJohn.Wren.Kennedy@Sun.COM ret = metaioctl(MD_MN_RR_DIRTY, &rp, &rp.mde, NULL);
2149*8452SJohn.Wren.Kennedy@Sun.COM
2150*8452SJohn.Wren.Kennedy@Sun.COM resp->mmr_exitval = ret;
2151*8452SJohn.Wren.Kennedy@Sun.COM }
2152*8452SJohn.Wren.Kennedy@Sun.COM
2153*8452SJohn.Wren.Kennedy@Sun.COM /*
2154*8452SJohn.Wren.Kennedy@Sun.COM * This is used to issue a MD_MN_RR_CLEAN ioctl to the mirror.
2155*8452SJohn.Wren.Kennedy@Sun.COM */
2156*8452SJohn.Wren.Kennedy@Sun.COM /*ARGSUSED*/
2157*8452SJohn.Wren.Kennedy@Sun.COM void
mdmn_do_mark_clean(md_mn_msg_t * msg,uint_t flags,md_mn_result_t * resp)2158*8452SJohn.Wren.Kennedy@Sun.COM mdmn_do_mark_clean(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *resp)
2159*8452SJohn.Wren.Kennedy@Sun.COM {
2160*8452SJohn.Wren.Kennedy@Sun.COM md_mn_msg_rr_clean_t *d;
2161*8452SJohn.Wren.Kennedy@Sun.COM md_mn_rr_clean_params_t *rcp;
2162*8452SJohn.Wren.Kennedy@Sun.COM int ret;
2163*8452SJohn.Wren.Kennedy@Sun.COM
2164*8452SJohn.Wren.Kennedy@Sun.COM resp->mmr_out_size = 0;
2165*8452SJohn.Wren.Kennedy@Sun.COM resp->mmr_err_size = 0;
2166*8452SJohn.Wren.Kennedy@Sun.COM resp->mmr_out = NULL;
2167*8452SJohn.Wren.Kennedy@Sun.COM resp->mmr_err = NULL;
2168*8452SJohn.Wren.Kennedy@Sun.COM resp->mmr_comm_state = MDMNE_ACK;
2169*8452SJohn.Wren.Kennedy@Sun.COM d = (md_mn_msg_rr_clean_t *)((void *)(msg->msg_event_data));
2170*8452SJohn.Wren.Kennedy@Sun.COM
2171*8452SJohn.Wren.Kennedy@Sun.COM rcp = Zalloc(sizeof (struct md_mn_rr_clean_params) +
2172*8452SJohn.Wren.Kennedy@Sun.COM MDMN_MSG_RR_CLEAN_DATA_BYTES(d));
2173*8452SJohn.Wren.Kennedy@Sun.COM MD_SETDRIVERNAME(rcp, MD_MIRROR, MD_MIN2SET(d->rr_mnum))
2174*8452SJohn.Wren.Kennedy@Sun.COM rcp->rr_mnum = d->rr_mnum;
2175*8452SJohn.Wren.Kennedy@Sun.COM rcp->rr_nodeid = d->rr_nodeid;
2176*8452SJohn.Wren.Kennedy@Sun.COM rcp->rr_start_size = d->rr_start_size;
2177*8452SJohn.Wren.Kennedy@Sun.COM (void) memcpy(MDMN_RR_CLEAN_PARAMS_DATA(rcp), MDMN_MSG_RR_CLEAN_DATA(d),
2178*8452SJohn.Wren.Kennedy@Sun.COM MDMN_MSG_RR_CLEAN_DATA_BYTES(d));
2179*8452SJohn.Wren.Kennedy@Sun.COM
2180*8452SJohn.Wren.Kennedy@Sun.COM ret = metaioctl(MD_MN_RR_CLEAN, rcp, &rcp->mde, NULL);
2181*8452SJohn.Wren.Kennedy@Sun.COM
2182*8452SJohn.Wren.Kennedy@Sun.COM Free(rcp);
2183*8452SJohn.Wren.Kennedy@Sun.COM
2184*8452SJohn.Wren.Kennedy@Sun.COM resp->mmr_exitval = ret;
2185*8452SJohn.Wren.Kennedy@Sun.COM }
2186