Esempio n. 1
0
/*
 * Is a file system currently mounted on this disk drive?
 */
int
meta_check_drivemounted(
	mdsetname_t	*sp,
	mddrivename_t	*dnp,
	md_error_t	*ep
)
{
	FILE		*mfp;
	struct mnttab	m;
	int		rval = 0;
	char		mountp[MNT_LINE_MAX];
	char		mnt_special[MNT_LINE_MAX];

	/* should have a set */
	assert(sp != NULL);

	/* look in mnttab */
	if ((mfp = open_mnttab()) == NULL)
		return (mdsyserror(ep, errno, MNTTAB));
	while ((getmntent(mfp, &m) == 0) && (rval == 0)) {
		char		**fstype = skip_these_mntents;
		int		skipit = 0;
		mdname_t	*mnp;

		if ((m.mnt_special == NULL) || (m.mnt_mountp == NULL))
			continue;

		if (m.mnt_mountp[0] != '/')
			continue;

		while (*fstype != NULL)
			if (strcmp(m.mnt_fstype, *fstype++) == 0) {
				skipit++;
				break;
			}

		if (skipit == 1)
			continue;

		(void) strcpy(mountp, m.mnt_mountp);
		(void) strcpy(mnt_special, m.mnt_special);
		if ((mnp = metaname(&sp, mnt_special,
		    LOGICAL_DEVICE, ep)) == NULL) {
			mdclrerror(ep);
			continue;
		}
		if (strcmp(dnp->cname, mnp->drivenamep->cname) == 0) {
			rval = mduseerror(ep, MDE_IS_MOUNTED, NODEV64,
			    mountp, dnp->cname);
		}
	}

	/* return success */
	return (rval);
}
Esempio n. 2
0
/*
 * Return the current root filesystem block device name. This is only valid
 * when root is either a slice, a stripe or a mirror.
 */
mdname_t *
meta_get_current_root_dev(
    mdsetname_t	*sp,
    md_error_t	*ep
)
{
    md_stripe_t	*stripep;
    md_mirror_t	*mirrorp;
    md_row_t	*rp;
    md_comp_t	*cp;
    mdname_t	*rootnp;
    void		*curroot;
    char		*miscname;
    int		smi;

    if ((curroot = meta_get_current_root(ep)) == NULL)
        return (NULL);
    if ((rootnp = metaname(&sp, curroot, UNKNOWN, ep)) == NULL)
        return (NULL);
    if (metaismeta(rootnp)) {
        if ((miscname = metagetmiscname(rootnp, ep)) == NULL)
            return (NULL);
        if ((strcmp(miscname, MD_MIRROR) == 0) &&
                ((mirrorp = meta_get_mirror(sp, rootnp, ep)) != NULL)) {
            for (smi = 0; smi < NMIRROR; smi++) {
                md_submirror_t *mdsp =
                    &mirrorp->submirrors[smi];
                rootnp = mdsp->submirnamep;
                /* skip unused submirrors */
                if (rootnp == NULL) {
                    assert(mdsp->state == SMS_UNUSED);
                    continue;
                }
                if ((miscname = metagetmiscname(rootnp, ep))
                        == NULL) {
                    (void) mdmderror(ep, MDE_UNKNOWN_TYPE,
                                     meta_getminor(rootnp->dev),
                                     rootnp->cname);
                    return (NULL);
                }
                break;
            }
        }
        if ((strcmp(miscname, MD_STRIPE) == 0) &&
                ((stripep = meta_get_stripe(sp, rootnp, ep)) != NULL)) {
            rp = &stripep->rows.rows_val[0];
            cp = &rp->comps.comps_val[0];
            if (metachkcomp(cp->compnamep, ep) == 0)
                return (cp->compnamep);
        }
        /* Root is not a single stripe metadevice */
        (void) mddeverror(ep, MDE_INV_ROOT, rootnp->dev, rootnp->cname);
        return (NULL);
    } else return (rootnp);
}
Esempio n. 3
0
/*
 * clear metadevice or hotspare pool
 */
static int
clear_name(
	mdsetname_t	**spp,
	char		*uname,
	mdcmdopts_t	options,
	md_error_t	*ep
)
{

	/* clear hotspare pool */
	if (is_existing_hsp(*spp, uname)) {
		mdhspname_t	*hspnp;

		/* get hotspare pool name */
		if ((hspnp = metahspname(spp, uname, ep)) == NULL)
			return (-1);
		assert(*spp != NULL);

		/* grab set lock */
		if (meta_lock(*spp, TRUE, ep))
			return (-1);

		/* check for ownership */
		if (meta_check_ownership(*spp, ep) != 0)
			return (-1);

		/* clear hotspare pool */
		return (meta_hsp_reset(*spp, hspnp, options, ep));
	}

	/* clear metadevice */
	else {
		mdname_t	*np;

		/* check for ownership */
		if (meta_check_ownership(*spp, ep) != 0)
			return (-1);

		/* get metadevice name */
		if (((np = metaname(spp, uname, META_DEVICE, ep)) == NULL) ||
		    (metachkmeta(np, ep) != 0)) {
			return (-1);
		}
		assert(*spp != NULL);

		/* grab set lock */
		if (meta_lock(*spp, TRUE, ep))
			return (-1);

		/* clear metadevice */
		return (meta_reset_by_name(*spp, np, options, ep));
	}
}
Esempio n. 4
0
/*
 * check whether device is swapped on
 */
static int
meta_check_swapped(
	mdsetname_t		*sp,
	mdname_t		*np,
	md_error_t		*ep
)
{
	struct swaptable	*swtp;
	int			nswap;
	int			i;
	int			rval = 0;

	/* should have a set */
	assert(sp != NULL);

	/* get swap info */
	if (get_swapinfo(&swtp, &nswap, ep) != 0)
		return (-1);

	/* look for match */
	for (i = 0; ((i < nswap) && (rval == 0)); ++i) {
		mdname_t	*snp;

		if ((snp = metaname(&sp, swtp->swt_ent[i].ste_path,
		    UNKNOWN, ep)) == NULL) {
			mdclrerror(ep);
			continue;
		}
		if (np->dev == snp->dev) {
			rval = mddeverror(ep, MDE_IS_SWAPPED,
			    np->dev, np->cname);
		} else { /* not swap - does it overlap */
			rval = meta_check_overlap(snp->cname, np, 0, -1,
			    snp, 0, -1, ep);
			if (rval != 0) {
				(void) mdoverlaperror(ep, MDE_OVERLAP_SWAP,
				    np->cname, NULL, snp->cname);
			}
		}
	}
	free_swapinfo(swtp);

	/* return success */
	return (rval);
}
Esempio n. 5
0
/*
 * check whether device is a dump device
 */
static int
meta_check_dump(
	mdsetname_t	*sp,
	mdname_t	*np,
	md_error_t	*ep
)
{
	int		rval = 0;
	int		dump_fd;
	char		device[MAXPATHLEN];


	if ((dump_fd = open("/dev/dump", O_RDONLY)) < 0)
		return (mdsyserror(ep, errno, "/dev/dump"));

	if (ioctl(dump_fd, DIOCGETDEV, device) != -1) {
		mdname_t	*dump_np;

		if ((dump_np = metaname(&sp, device, UNKNOWN, ep)) == NULL) {
			mdclrerror(ep);
			(void) close(dump_fd);
			return (0);
		}

		if (np->dev == dump_np->dev) {
			rval = mddeverror(ep, MDE_IS_DUMP,
			    np->dev, np->cname);
		} else { /* not a dump device - but does it overlap? */
			rval = meta_check_overlap(dump_np->cname, np, 0, -1,
			    dump_np, 0, -1, ep);
			if (rval != 0) {
				(void) mdoverlaperror(ep, MDE_OVERLAP_DUMP,
				    np->cname, NULL, dump_np->cname);
			}
		}
	}
	(void) close(dump_fd);
	return (rval);
}
Esempio n. 6
0
/*
 * Is a driver currently swapped on?
 */
int
meta_check_driveswapped(
	mdsetname_t		*sp,
	mddrivename_t		*dnp,
	md_error_t		*ep
)
{
	struct swaptable	*swtp;
	int			nswap;
	int			i;
	int			rval = 0;

	/* should have a set */
	assert(sp != NULL);

	/* get swap info */
	if (get_swapinfo(&swtp, &nswap, ep) != 0)
		return (-1);

	/* look for match */
	for (i = 0; (i < nswap); ++i) {
		mdname_t	*snp;

		if ((snp = metaname(&sp, swtp->swt_ent[i].ste_path,
		    LOGICAL_DEVICE, ep)) == NULL) {
			mdclrerror(ep);
			continue;
		}

		if (strcmp(dnp->cname, snp->drivenamep->cname) == 0) {
			rval = mddeverror(ep, MDE_IS_SWAPPED, NODEV64,
			    dnp->cname);
		}
	}
	free_swapinfo(swtp);

	/* return success */
	return (rval);
}
Esempio n. 7
0
/*
 * check whether device is mounted
 */
static int
meta_check_mounted(
	mdsetname_t	*sp,
	mdname_t	*np,
	md_error_t	*ep
)
{
	FILE		*mfp;
	struct mnttab	m;
	int		rval = 0;
	char		mountp[MNT_LINE_MAX];
	char		mnt_special[MNT_LINE_MAX];

	/* should have a set */
	assert(sp != NULL);

	/* look in mnttab */
	if ((mfp = open_mnttab()) == NULL)
		return (mdsyserror(ep, errno, MNTTAB));
	while ((getmntent(mfp, &m) == 0) && (rval == 0)) {
		char		**fstype = skip_these_mntents;
		int		skipit = 0;
		mdname_t	*mnp;

		if ((m.mnt_special == NULL) || (m.mnt_mountp == NULL))
			continue;

		if (m.mnt_mountp[0] != '/')
			continue;

		while (*fstype != NULL)
			if (strcmp(m.mnt_fstype, *fstype++) == 0) {
				skipit++;
				break;
			}

		if (skipit == 1)
			continue;

		(void) strcpy(mountp, m.mnt_mountp);
		(void) strcpy(mnt_special, m.mnt_special);

		if ((mnp = metaname(&sp, mnt_special, UNKNOWN, ep)) == NULL) {
			mdclrerror(ep);
			continue;
		}

		if (np->dev == mnp->dev) {
			rval = mduseerror(ep, MDE_IS_MOUNTED,
			    np->dev, mountp, np->cname);
		} else { /* device isn't in mnttab - does it overlap? */
			rval = meta_check_overlap(mnp->cname, np, 0, -1,
			    mnp, 0, -1, ep);
			if (rval != 0) {
				(void) mdoverlaperror(ep, MDE_OVERLAP_MOUNTED,
				    np->cname, mountp, mnp->cname);
			}
		}
	}

	/* return success */
	return (rval);
}
Esempio n. 8
0
int
get_mdcomponents(char *uname, svm_info_t **svmpp)
{

	svm_info_t	*svmp;
	md_error_t	status, *ep;
	mdname_t	*namep;
	mdnamelist_t	*nlp = NULL;
	mdnamelist_t	*p;
	mdsetname_t	*sp = NULL;
	char		*strp = NULL;
	int		rval, cnt;

	rval = RET_SUCCESS;
	cnt = 0;
	status = mdnullerror;
	ep = &status;
	svmp = *svmpp;

	(void) init_metalib();

	debug_printf("get_mdcomponents(): Enter unit name %s\n", uname);

	if (((namep = metaname(&sp, uname, META_DEVICE, ep)) == NULL) ||
					(metachkmeta(namep, ep) != 0)) {
		debug_printf("get_mdcomponents(): "
				"metaname or metachkmeta failed\n");
		mdclrerror(ep);
		return (RET_ERROR);
	}

	debug_printf("get_mdcomponents(): meta_getdevs %s\n", namep->cname);

	if ((meta_getdevs(sp, namep, &nlp, ep)) < 0) {
		debug_printf("get_mdcomponents(): "
				"comp %s - meta_getdevs failed\n", uname);
		metafreenamelist(nlp);
		mdclrerror(ep);
		return (RET_ERROR);
	}

	/* compute the number of devices */

	for (p = nlp, cnt = 0; p != NULL;  p = p->next, cnt++)
		;

	/*
	 * Need to add n -1 components since slvmp already has space
	 * for one device.
	 */

	svmp = (svm_info_t *)realloc(svmp, sizeof (svm_info_t) +
		(sizeof (char *) * (cnt - 1)));

	if (svmp == NULL) {
		debug_printf("get_mdcomponents(): realloc of svmp failed\n");
		metafreenamelist(nlp);
		return (RET_ERROR);
	}


	for (p = nlp, cnt = 0; p != NULL; p = p->next, cnt++) {
		mdname_t	*devnp = p->namep;

		if ((strp = strdup(devnp->cname)) == NULL) {
			rval = RET_ERROR;
			break;
		}
		svmp->md_comps[cnt] = strp;
	}

	/* count is set to the number of devices in the list */

	svmp->count = cnt;
	svmp->root_md = strdup(uname);
	if (rval == RET_SUCCESS && svmp->root_md != NULL) {
		debug_printf("get_mdcomponents(): root_md %s count %d \n",
			svmp->root_md, svmp->count);
		for (cnt = 0; cnt < svmp->count; cnt++)
			debug_printf("get_mdcomponents(): %s\n",
							svmp->md_comps[cnt]);
	} else {
		rval = RET_ERROR;
		svm_free(svmp);
		svmp = NULL;
		debug_printf("get_mdcomponents(): malloc failed\n");

	}


	metafreenamelist(nlp);
	*svmpp = svmp;
	return (rval);
}
Esempio n. 9
0
/*
 * This routine is called from preenlib the first time. It is then
 * recursively called through preen_subdev.
 *
 * The argument passed in (uname) starts with the special device from
 * /etc/vfstab. Recursive calls pass in the underlying physical device
 * names.
 */
void
preen_build_devs(
	char		*uname,		/* name of metadevice */
	struct dk_cinfo	*dkiop,		/* associated controller info */
	void		*dp		/* magic info */
)
{
	char		*setname = NULL;
	char		*tname = NULL;
	mdsetname_t	*sp;
	mdname_t	*namep;		/* metadevice name */
	mdnamelist_t	*nlp = NULL;	/* list of real devices */
	mdnamelist_t	*p;
	devid_nmlist_t	*nm_list = NULL;
	md_error_t	status = mdnullerror;
	md_error_t	*ep = &status;
	int		ep_valid = 0;	/* does ep contain a real error */
	struct stat	statb;
	static int	md_major = -1;
	side_t		sideno;

	/*
	 * The rest of the code in this library can't work within a
	 * non-global zone so we just return the top level metadevice back
	 * to be fscked.
	 */
	if (getzoneid() != GLOBAL_ZONEID) {
		preen_addunit(dp, dkiop->dki_dname, NULL, NULL,
		    dkiop->dki_unit);
		return;
	}

	if (stat(uname, &statb) != 0)
		return;

	if (md_major == -1 &&
		get_major_from_n2m(MD_MODULE, &md_major) != 0)
		return;

	/*
	 * If the path passed in is not a metadevice, then add that
	 * device to the list (preen_addunit) since it has to be a
	 * physical device.
	 */

	if (major(statb.st_rdev) != md_major) {
		preen_addunit(dp, dkiop->dki_dname, NULL, NULL,
		    dkiop->dki_unit);
		return;
	}
	/*
	 * Bind to the cluster library
	 */

	if (sdssc_bind_library() == SDSSC_ERROR)
		return;

	if (md_init_daemon("fsck", ep) != 0) {
		ep_valid = 1;
		goto out;
	}

	/*
	 * parse the path name to get the diskset name.
	 */
	parse_device(NULL, uname, &tname, &setname);
	Free(tname);
	if ((sp = metasetname(setname, ep)) == NULL) {
		ep_valid = 1;
		goto out;
	}

	/* check for ownership */
	if (meta_check_ownership(sp, ep) != 0) {
		/*
		 * Don't own the set but we are here implies
		 * that this is a clustered proxy device. Simply add
		 * the unit.
		 */
		preen_addunit(dp, dkiop->dki_dname, NULL, NULL,
		    dkiop->dki_unit);
		ep_valid = 1;
		goto out;
	}

	/*
	 * get list of underlying physical devices.
	 */
	if ((namep = metaname(&sp, uname, UNKNOWN, ep)) == NULL) {
		ep_valid = 1;
		goto out;
	}

	if (namep->dev == NODEV64) {
		goto out;
	}

	if (meta_getdevs(sp, namep, &nlp, ep) != 0) {
		ep_valid = 1;
		goto out;
	}

	if ((sideno = getmyside(sp, ep)) == MD_SIDEWILD) {
		ep_valid = 1;
		goto out;
	}

	/* gather and add the underlying devs */
	for (p = nlp; (p != NULL); p = p->next) {
		mdname_t	*devnp = p->namep;
		int		fd;
		struct dk_cinfo	cinfo;
		ddi_devid_t	md_did;
		char		*devname;
		char		*minor_name = NULL;
		char		mname[MAXPATHLEN];

		/*
		 * we don't want to use the rname anymore because
		 * that may have changed. Use the device id information
		 * to find the correct ctd name and open based on that.
		 * If there isn't a devid or we have a did device, then
		 * use the rname. In clustering, it's corrected for us.
		 * If no devid it's at least worth a try.
		 */
		if (((md_did = meta_getdidbykey(sp->setno, sideno,
		    devnp->key, ep)) == NULL) || ((minor_name =
		    meta_getdidminorbykey(sp->setno, sideno,
		    devnp->key, ep)) == NULL)) {
			devname = devnp->rname;
			if (md_did)
				Free(md_did);
		} else {
			if (strstr(minor_name, ",raw") == NULL) {
				(void) snprintf(mname, MAXPATHLEN, "%s,raw",
				    minor_name);
			} else {
				(void) snprintf(mname, MAXPATHLEN, "%s",
				    minor_name);
			}

			/*
			 * We need to make sure we call this with a specific
			 * mname (raw mname) so that we get the exact slice
			 * with the given device id. Otherwise we could try
			 * to open a slice that doesn't really exist.
			 */
			if (meta_deviceid_to_nmlist("/dev", md_did,
			    mname, &nm_list) != 0) {
				(void) mdsyserror(ep, errno, devnp->rname);
				ep_valid = 1;
				Free(md_did);
				Free(minor_name);
				goto out;
			}
			devname = Strdup(nm_list->devname);
			Free(md_did);
			Free(minor_name);
			devid_free_nmlist(nm_list);
		}
		/* get device name and (real) cinfo */
		if ((fd = open(devname, O_RDONLY, 0)) < 0) {
			(void) mdsyserror(ep, errno, devname);
			ep_valid = 1;
			/*
			 * We need to scan all sub devices even if some fail
			 * since exit here would end up in not finishing fsck
			 * on all devices and prevent us from going into
			 * multiuser mode.
			 */
			continue;
		}

		if (ioctl(fd, DKIOCINFO, &cinfo) != 0) {
			(void) mdsyserror(ep, errno, devname);
			(void) close(fd);
			ep_valid = 1;
			/* Continue here too. See comment from before */
			continue;
		}
		(void) close(fd);	/* sd/ssd bug */

		/*
		 * preen_subdev fails when the device name has been
		 * resolved to the physical layer. Hence it is added
		 * to preen_addunit.
		 */
		if (preen_subdev(devname, &cinfo, dp) != 0) {
			preen_addunit(dp, cinfo.dki_dname, NULL, NULL,
			    cinfo.dki_unit);
		}
	}

	/* cleanup, if we fail, just add this composite device to the list */
out:
	if (setname != NULL)
		Free(setname);
	if (ep_valid != 0) {
		mde_perror(&status, "");
		mdclrerror(&status);
	}
	metafreenamelist(nlp);
}