/*
 * resync raid
 */
int
meta_raid_resync(
	mdsetname_t		*sp,
	mdname_t		*raidnp,
	daddr_t			size,
	md_error_t		*ep
)
{
	char			*miscname;
	md_resync_ioctl_t	ri;

	/* should have a set */
	assert(sp != NULL);
	assert(sp->setno == MD_MIN2SET(meta_getminor(raidnp->dev)));

	/* make sure we have a raid */
	if ((miscname = metagetmiscname(raidnp, ep)) == NULL)
		return (-1);
	if (strcmp(miscname, MD_RAID) != 0) {
		return (mdmderror(ep, MDE_NOT_RAID, meta_getminor(raidnp->dev),
		    raidnp->cname));
	}

	/* start resync */
	(void) memset(&ri, 0, sizeof (ri));
	MD_SETDRIVERNAME(&ri, MD_RAID, sp->setno);
	ri.ri_mnum = meta_getminor(raidnp->dev);
	ri.ri_copysize = size;
	if (metaioctl(MD_IOCSETSYNC, &ri, &ri.mde, raidnp->cname) != 0)
		return (mdstealerror(ep, &ri.mde));

	/* return success */
	return (0);
}
Exemple #2
0
int
md_probe_ioctl(mdnamelist_t *nlp, int ndevs, char *drvname, boolean_e verbose)
{
	mdnamelist_t	*p;
	mdname_t	*np;
	md_probedev_t	probe_ioc,
			*iocp;
	int		i,
			retval = 0;
	/*
	 * Allocate space for all the metadevices and fill in
	 * the minor numbers.
	 */

	memset(&probe_ioc, 0, sizeof (probe_ioc));
	iocp = &probe_ioc;

	if ((iocp->mnum_list = (uintptr_t)calloc(ndevs, sizeof (minor_t)))
	    == 0) {
		monitord_print(0, "md_probe_ioctl: calloc");
		return (-1);
	}

	(void) strcpy(iocp->test_name, MD_PROBE_OPEN_T);
	MD_SETDRIVERNAME(&probe_ioc, drvname, sp->setno);

	if (verbose == True) {
		monitord_print(6, "\n\nmd_probe_ioctl: %s: %s\n",
		    (strcmp(sp->setname, MD_LOCAL_NAME) == 0) ?
		    gettext("local_set") :
		    sp->setname, iocp->md_driver.md_drivername);
	}

	iocp->nmdevs = ndevs;
	if (verbose == True)
		monitord_print(6, "...ndevs 0x%x\n", ndevs);

	for (p = nlp, i = 0; p; p = p->next, i++) {
		np = p->namep;
		((minor_t *)(uintptr_t)iocp->mnum_list)[i] =
		    meta_getminor(np->dev);
		if (verbose == True)
			monitord_print(6, "...%s 0x%lx\n", np->cname,
			    ((minor_t *)(uintptr_t)iocp->mnum_list)[i]);
	}


	if (issue_ioctl == True) {
		if (metaioctl(MD_IOCPROBE_DEV, iocp, &(iocp->mde), NULL) != 0)
			retval = -1;
	}
	return (retval);
}
static void
metahalt()
{
	mdsetname_t	*sp;
	md_error_t status = mdnullerror;

	(void) init_metalib();
	if ((sp = metasetname(MD_LOCAL_NAME, &status)) == NULL) {
		return;
	}
	if (meta_lock(sp, TRUE, &status)) {
		return;
	}
	if (metaioctl(MD_HALT, NULL, &status, NULL) != 0) {
		debug_printf("metahalt(): errno %d\n",
			status.info.md_error_info_t_u.sys_error.errnum);
	}
	(void) meta_unlock(sp, &status);
	reset_metalib(&status);
}
Exemple #4
0
/*
 * grow generic device
 */
int
meta_concat_generic(
	mdsetname_t		*sp,
	mdname_t		*namep,
	u_longlong_t		big_or_little,
	md_error_t		*ep
)
{
	md_grow_params_t	mgp;
	char			*miscname;

	/* should have a set */
	assert(sp != NULL);
	assert(sp->setno == MD_MIN2SET(meta_getminor(namep->dev)));

	/* get type */
	if ((miscname = metagetmiscname(namep, ep)) == NULL)
		return (-1);

	/* grow device */
	(void) memset(&mgp, 0, sizeof (mgp));
	if (big_or_little & MD_64BIT_META_DEV)
		mgp.options = MD_CRO_64BIT;
	else
		mgp.options = MD_CRO_32BIT;

	mgp.mnum = meta_getminor(namep->dev);
	MD_SETDRIVERNAME(&mgp, miscname, sp->setno);
	if (metaioctl(MD_IOCGROW, &mgp, &mgp.mde, namep->cname) != 0)
		return (mdstealerror(ep, &mgp.mde));

	/* clear cache */
	meta_invalidate_name(namep);

	/* return success */
	return (0);
}
Exemple #5
0
/* ARGSUSED */
int
main(void)
{

	int		i;
	int		mdmn_door_handle;
	pid_t		pid;
	int		size;
	md_error_t	ep = mdnullerror;
	struct rlimit	rl;

	/*
	 * Get the locale set up before calling any other routines
	 * with messages to ouput.  Just in case we're not in a build
	 * environment, make sure that TEXT_DOMAIN gets set to
	 * something.
	 */
#if !defined(TEXT_DOMAIN)
#define	TEXT_DOMAIN "SYS_TEST"
#endif
	(void) setlocale(LC_ALL, "");
	(void) textdomain(TEXT_DOMAIN);

	openlog("mddoors", LOG_PID, LOG_DAEMON);

	/* here beginneth the daemonizing code */
	pid = fork();
	if (pid < 0) {
		syslog(LOG_DAEMON | LOG_ERR, gettext("Cannot fork"));
		exit(1);
	}

	if (pid) {
		exit(0);
	}

	/*
	 * Only one daemon can run at a time.
	 * If another instance is already running, this is not an error.
	 */
	if ((pid = enter_daemon_lock()) != getpid()) {
		exit(0);
	}

	rl.rlim_max = 0;
	(void) getrlimit(RLIMIT_NOFILE, &rl);
	if ((size = rl.rlim_max) == 0) {
		syslog(LOG_DAEMON | LOG_ERR, gettext("Cannot getrlimit"));
		exit(1);
	}

	for (i = 0; i < size; i++) {
		if (i == daemon_lock_fd)
			continue;
		(void) close(i);
	}


	i = open("/dev/null", 2);
	(void) dup2(i, 1);
	(void) dup2(i, 2);
	(void) setsid();

	/* here endeth the daemonizing code */

	/* Block out the usual signals so we don't get killed unintentionally */
	(void) signal(SIGHUP, SIG_IGN);
	(void) signal(SIGINT, SIG_IGN);
	(void) signal(SIGQUIT, SIG_IGN);
	(void) signal(SIGTERM, SIG_IGN);

	(void) atexit(daemon_cleanup);

	/* Resume any previously blocked resync */
	meta_mirror_resync_unblock_all();

	/*
	 * At this point we are single threaded.
	 * We give mdmn_send_message() a chance to initialize safely.
	 */
	(void) mdmn_send_message(0, 0, 0, 0, 0, 0, 0, 0);

	/* setup the door handle */
	mdmn_door_handle = door_create(door2rpc, NULL,
	    DOOR_REFUSE_DESC | DOOR_NO_CANCEL);
	if (mdmn_door_handle == -1) {
		perror(gettext("door_create failed"));
		syslog(LOG_DAEMON | LOG_ERR, gettext("door_create failed"));
		exit(1);
	}

	if (metaioctl(MD_MN_SET_DOORH, &mdmn_door_handle, &ep,
	    "mddoors") != 0) {
		syslog(LOG_DAEMON | LOG_DEBUG, gettext(
		    "Couldn't set door handle"));
		exit(1);
	}

	(void) pause();
	syslog(LOG_DAEMON | LOG_ERR, gettext(
	    "Unexpected exit from pause()"));
	return (1);
}
Exemple #6
0
int
main(int argc, char **argv)
{
	char		c;
	char		*sname = MD_LOCAL_NAME;
	mddevopts_t	options = 0;
	md_error_t	status = mdnullerror;
	md_error_t	*ep = &status;
	mdsetname_t	*sp = NULL;
	mdsetname_t	*local_sp = NULL;
	char		*argname;
	int		todo = 0;
	int		ret = 0;
	int		md_upgd_stat = 0;
	int		error;
	md_set_desc	*sd;

	/*
	 * Get the locale set up before calling any other routines
	 * with messages to ouput.  Just in case we're not in a build
	 * environment, make sure that TEXT_DOMAIN gets set to
	 * something.
	 */
#if !defined(TEXT_DOMAIN)
#define	TEXT_DOMAIN "SYS_TEST"
#endif
	(void) setlocale(LC_ALL, "");
	(void) textdomain(TEXT_DOMAIN);

	if ((sdssc_bind_library() == SDSSC_OKAY) &&
	    (sdssc_cmd_proxy(argc, argv, SDSSC_PROXY_PRIMARY,
	    &error) == SDSSC_PROXY_DONE))
		exit(error);

	openlog("metadevadm", LOG_ODELAY, LOG_USER);

	/* initialize */
	if (md_init(argc, argv, 0, 1, ep) != 0 ||
	    meta_check_root(ep) != 0) {
		closelog();
		mde_perror(ep, "");
		md_exit(sp, 1);
	}

	/* parse args */
	optind = 1;
	opterr = 1;
	while ((c = getopt(argc, argv, "vlhnrs:u:")) != -1) {
		switch (c) {
		case 'v':
			options |= DEV_VERBOSE;
			break;
		case 'n':
			options |= DEV_NOACTION;
			break;
		case 'r':
			options |= DEV_RELOAD;
			todo = 1;
			break;
		case 's':
			sname = optarg;
			break;
		case 'u':
			todo = 1;
			options |= DEV_UPDATE;
			argname = optarg;
			if (argname == NULL) {
				usage("metadevadm");
				closelog();
				md_exit(sp, 0);
			}
			break;
		case 'l':
			options |= DEV_LOG;
			break;
		case 'h':
		default:
			usage("metadevadm");
			closelog();
			md_exit(sp, 0);
		}
	}

	if ((sp = metasetname(sname, ep)) == NULL) {
		mde_perror(ep, "");
		closelog();
		md_exit(sp, 1);
	}

	if (!metaislocalset(sp)) {
		if ((sd = metaget_setdesc(sp, ep)) == NULL) {
			mde_perror(ep, "");
			closelog();
			md_exit(sp, 1);
		}
		if (MD_MNSET_DESC(sd)) {
			(void) printf("%s\n", gettext("metadevadm cannot be "
			    "run on multi-owner disksets\n"));
			closelog();
			md_exit(sp, 0);
		}
	}

	if ((options & DEV_VERBOSE) && (todo != 1)) {
		usage("metadevadm");
		closelog();
		md_exit(sp, 0);
	}

	if ((options & DEV_NOACTION) && (todo != 1)) {
		usage("metadevadm");
		closelog();
		md_exit(sp, 0);
	}

	if (todo == 0) {
		usage("metadevadm");
		closelog();
		md_exit(sp, 0);
	}

	if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) {
		mde_perror(ep, "");
		closelog();
		md_exit(local_sp, 1);
	}

	/* lock the local set */
	if (meta_lock(local_sp, TRUE, ep) != 0) {
		mde_perror(ep, "");
		closelog();
		md_exit(local_sp, 1);
	}

	/* grab set lock */
	if (meta_lock(sp, TRUE, ep)) {
		mde_perror(ep, "");
		closelog();
		md_exit(local_sp, 1);
	}

	/* check for ownership */
	if (meta_check_ownership(sp, ep) != 0) {
		/*
		 * If the set is not owned by this node then only update the
		 * local set's replica.
		 */
		options |= DEV_LOCAL_SET;
	}

	/*
	 * check for upgrade. If upgrade in progress then just exit.
	 */
	if (metaioctl(MD_UPGRADE_STAT, &md_upgd_stat, ep, NULL) != 0) {
			mde_perror(ep, "");
			closelog();
			(void) meta_unlock(sp, ep);
			md_exit(local_sp, 1);
	}
	if (md_upgd_stat == 0) {
		ret = meta_fixdevid(sp, options, argname, ep);
		if (ret == METADEVADM_ERR) {
			/*
			 * If the call failed, for a DEV_RELOAD still need to
			 * update the .conf file to provide the latest devid
			 * information so exit later.
			 */
			if (options & DEV_UPDATE) {
				closelog();
				(void) meta_unlock(sp, ep);
				md_exit(local_sp, 1);
			}
		}
	}

	/*
	 * Sync replica list in kernel to replica list in conf files.
	 * This will update driver name and minor number in conf file
	 * if reload was run.  Will update device id in conf file if
	 * update was run.
	 */
	meta_sync_db_locations(sp, ep);
	closelog();
	(void) meta_unlock(sp, ep);
	md_exit(local_sp, ret);
	return (0);
}