Exemplo n.º 1
0
/*
 * - given a pathname, determine the pathname to actually check
 * - if a directory
 *   - if it is in mnttab, set devstr to the special (block) name
 *   - if it is in vfstab, set devstr to the special (block) name
 *   - if it has not been found, bail
 * - a file is used as-is, clear rflag
 * - a device is converted to block version (so can search mnttab)
 */
static void
derive_devstr(const caddr_t dev, caddr_t devstr, size_t str_size)
{
	mode_t mode;
	struct stat statb;

	if (stat(dev, &statb) < 0) {
		exitstat = EXNOSTAT;
		errexit("fsck: could not stat %s: %s", dev, strerror(errno));
	}

	mode = statb.st_mode & S_IFMT;
	switch (mode) {
	case S_IFDIR:
		/*
		 * The check_*() routines update devstr with the name.
		 */
		devstr[0] = '\0';
		if (!(check_mnttab(dev, devstr, str_size) ||
		    check_vfstab(dev, devstr, str_size))) {
			exitstat = EXBADPARM;
			errexit(
		    "fsck: could not find mountpoint %s in mnttab nor vfstab",
			    dev);
		}
		break;
	case S_IFREG:
		rflag = 0;
		break;
	case S_IFCHR:
	case S_IFBLK:
		(void) strlcpy(devstr, unrawname(dev), str_size);
		break;
	default:
		exitstat = EXBADPARM;
		errexit("fsck: %s must be a mountpoint, device, or file", dev);
		/* NOTREACHED */
	}
}
Exemplo n.º 2
0
int				/* fd if successful, -1 if error */
get_blk_device(
	struct sam_fs_part *fsp,
	int oflags,
	int maxdevretry)
{
	int fd;
	int retrycnt = 0;
	struct dk_cinfo dkcinfo;
	struct vtoc vtoc;
	char *devrname;

	if (check_mnttab(fsp->pt_name)) {
		error(0, 0, catgets(catfd, SET, 13422, "device %s is mounted."),
		    fsp->pt_name);
		return (-1);
	}

	if ((devrname = getfullrawname(fsp->pt_name)) == NULL) {
		error(0, 0,
		    catgets(catfd, SET, 1606,
		    "malloc: %s"), "getfullrawname");
		return (-1);
	}
	if (*devrname == '\0') {
		error(0, errno, "%s", fsp->pt_name);
		error(0, 0,
		    catgets(catfd, SET, 1998,
		    "Raw device not found for eq (%d)"),
		    fsp->pt_eq);
		free(devrname);
		return (-1);
	}
	/*
	 * Oracle RAC (oban) devices under SunCluster initialize at the
	 * same time as QFS filesystems are mounted. We loop waiting
	 * for the devices to become available (maximum of maxdevretry
	 * tries).
	 */
	while ((fd = open(devrname, oflags)) < 0) {
		if ((retrycnt >= maxdevretry) ||
		    ((strncmp(devrname, "/dev/md/", 8) != 0))) {
			error(0, errno, "%s", devrname);
			error(0, 0, catgets(catfd, SET, 1856,
			    "Open failed on (%s), retries=%d"),
			    devrname, retrycnt);
			free(devrname);
			return (-1);
		}
		retrycnt++;
		sleep(2);
	}
	if (retrycnt > 0) {
		printf("%s: %d retries on %s (max=%d).\n",
		    program_name, retrycnt, devrname, maxdevretry);
	}

	if (ioctl(fd, DKIOCINFO, &dkcinfo) < 0) {
		error(0, errno, "%s", devrname);
		error(0, 0,
		    catgets(catfd, SET, 1443,
		    "Ioctl(DKIOCINFO) failed on (%s)"),
		    devrname);
		free(devrname);
		return (-1);
	}
	if (ioctl(fd, DKIOCGVTOC, &vtoc) >= 0) {
		/*
		 * Size of partition is returned in units of 512
		 * byte sectors.
		 */
		fsp->pt_size = (unsigned long)
		    vtoc.v_part[dkcinfo.dki_partition].p_size;
		if (fsp->pt_size == 0) {
			error(0, 0,
			    catgets(catfd, SET, 1909,
			    "Partition %d is undefined on (%s)"),
			    dkcinfo.dki_partition, devrname);
			free(devrname);
			return (-1);
		}
	} else if (is_efi_present()) {
		int part;
		int saved_errno;
		struct dk_gpt *efi_vtoc;

		saved_errno = errno;
		if ((part = call_efi_alloc_and_read(fd, &efi_vtoc)) >= 0) {
			fsp->pt_size = efi_vtoc->efi_parts[part].p_size;
			call_efi_free(efi_vtoc);
			if (fsp->pt_size == 0) {
				error(0, 0, catgets(catfd, SET, 1909,
				    "Partition %d is undefined on (%s)"),
				    part, devrname);
				free(devrname);
				return (-1);
			}
		} else {
			error(0, saved_errno, "%s", devrname);
			error(0, 0, catgets(catfd, SET, 13030,
			    "Could not read VTOC or EFI label on %s: %d"),
			    devrname, part);
			free(devrname);
			return (-1);
		}
	} else {
		error(0, errno, "%s", devrname);
		error(0, 0,
		    catgets(catfd, SET, 1442,
		    "Ioctl(DKIOCGVTOC) failed on (%s)"),
		    devrname);
		free(devrname);
		return (-1);
	}
	free(devrname);
	return (fd);
}