Exemplo n.º 1
0
/*
 * XXX - ZFS mounts not detected. Needs to come in as a feature.
 * Currently only /etc/mnttab entries are being checked
 */
int
fdisk_mounted_logical_drives(ext_part_t *epp)
{
	char *part_str, *canonp;
	char compare_pdev_str[PATH_MAX];
	char compare_sdev_str[PATH_MAX];
	FILE *fp;
	struct mnttab mt;
	int part;
	int look_for_mounted_slices = 0;
	uint32_t begsec, numsec;

	/*
	 * Do not check for mounted logical drives for
	 * devices other than /dev/rdsk/
	 */
	if (strstr(epp->device_name, DEFAULT_PATH_PREFIX) == NULL) {
		return (0);
	}

	if ((fp = fopen(MNTTAB, "r")) == NULL) {
		return (ENOENT);
	}

	canonp = epp->device_name + strlen(DEFAULT_PATH_PREFIX);
	(void) snprintf(compare_pdev_str, PATH_MAX, "%s%s", "/dev/dsk/",
	    canonp);
	part_str = strrchr(compare_pdev_str, 'p');
	*(part_str + 1) = '\0';
	(void) strcpy(compare_sdev_str, compare_pdev_str);
	part_str = strrchr(compare_sdev_str, 'p');
	*part_str = 's';

	if (fdisk_get_solaris_part(epp, &part, &begsec, &numsec) ==
	    FDISK_SUCCESS) {
		if (part > FD_NUMPART) {
			/*
			 * Solaris partition is on a logical drive. Look for
			 * mounted slices.
			 */
			look_for_mounted_slices = 1;
		}
	}

	while (getmntent(fp, &mt) == 0) {
		if (strstr(mt.mnt_special, compare_pdev_str) == NULL) {
			if (strstr(mt.mnt_special, compare_sdev_str) == NULL) {
				continue;
			} else {
				if (look_for_mounted_slices) {
					return (FDISK_EMOUNTED);
				}
			}
		}

		/*
		 * Get the partition number that is mounted, which would be
		 * found just beyond the last 'p' in the device string.
		 * For example, in /dev/dsk/c0t0d0p12, partition number 12
		 * is just beyond the last 'p'.
		 */
		part_str = strrchr(mt.mnt_special, 'p');
		if (part_str != NULL) {
			part_str++;
			part = atoi(part_str);
			/* Extended partition numbers start from 5 */
			if (part >= 5) {
				return (FDISK_EMOUNTED);
			}
		}
	}
	return (0);
}
Exemplo n.º 2
0
static int
get_start_sector(ig_device_t *device)
{
	uint32_t		secnum = 0, numsec = 0;
	int			i, pno, rval, log_part = 0;
	struct mboot		*mboot;
	struct ipart		*part;
	ext_part_t		*epp;
	struct part_info	dkpi;
	struct extpart_info	edkpi;

	if (is_efi(device->type)) {
		struct dk_gpt *vtoc;

		if (efi_alloc_and_read(device->disk_fd, &vtoc) < 0)
			return (BC_ERROR);

		device->start_sector = vtoc->efi_parts[device->slice].p_start;
		/* GPT doesn't use traditional slice letters */
		device->slice = 0xff;
		device->partition = 0;

		efi_free(vtoc);
		goto found_part;
	}

	mboot = (struct mboot *)device->boot_sector;

	if (is_bootpar(device->type)) {
		if (find_x86_bootpar(mboot, &pno, &secnum) != BC_SUCCESS) {
			(void) fprintf(stderr, NOBOOTPAR);
			return (BC_ERROR);
		} else {
			device->start_sector = secnum;
			device->partition = pno;
			goto found_part;
		}
	}

	/*
	 * Search for Solaris fdisk partition
	 * Get the solaris partition information from the device
	 * and compare the offset of S2 with offset of solaris partition
	 * from fdisk partition table.
	 */
	if (ioctl(device->part_fd, DKIOCEXTPARTINFO, &edkpi) < 0) {
		if (ioctl(device->part_fd, DKIOCPARTINFO, &dkpi) < 0) {
			(void) fprintf(stderr, PART_FAIL);
			return (BC_ERROR);
		} else {
			edkpi.p_start = dkpi.p_start;
		}
	}

	for (i = 0; i < FD_NUMPART; i++) {
		part = (struct ipart *)mboot->parts + i;

		if (part->relsect == 0) {
			(void) fprintf(stderr, BAD_PART, i);
			return (BC_ERROR);
		}

		if (edkpi.p_start >= part->relsect &&
		    edkpi.p_start < (part->relsect + part->numsect)) {
			/* Found the partition */
			break;
		}
	}

	if (i == FD_NUMPART) {
		/* No solaris fdisk partitions (primary or logical) */
		(void) fprintf(stderr, NOSOLPAR);
		return (BC_ERROR);
	}

	/*
	 * We have found a Solaris fdisk partition (primary or extended)
	 * Handle the simple case first: Solaris in a primary partition
	 */
	if (!fdisk_is_dos_extended(part->systid)) {
		device->start_sector = part->relsect;
		device->partition = i;
		goto found_part;
	}

	/*
	 * Solaris in a logical partition. Find that partition in the
	 * extended part.
	 */
	if ((rval = libfdisk_init(&epp, device->path_p0, NULL, FDISK_READ_DISK))
	    != FDISK_SUCCESS) {
		switch (rval) {
			/*
			 * The first 3 cases are not an error per-se, just that
			 * there is no Solaris logical partition
			 */
			case FDISK_EBADLOGDRIVE:
			case FDISK_ENOLOGDRIVE:
			case FDISK_EBADMAGIC:
				(void) fprintf(stderr, NOSOLPAR);
				return (BC_ERROR);
			case FDISK_ENOVGEOM:
				(void) fprintf(stderr, NO_VIRT_GEOM);
				return (BC_ERROR);
			case FDISK_ENOPGEOM:
				(void) fprintf(stderr, NO_PHYS_GEOM);
				return (BC_ERROR);
			case FDISK_ENOLGEOM:
				(void) fprintf(stderr, NO_LABEL_GEOM);
				return (BC_ERROR);
			default:
				(void) fprintf(stderr, LIBFDISK_INIT_FAIL);
				return (BC_ERROR);
		}
	}

	rval = fdisk_get_solaris_part(epp, &pno, &secnum, &numsec);
	libfdisk_fini(&epp);
	if (rval != FDISK_SUCCESS) {
		/* No solaris logical partition */
		(void) fprintf(stderr, NOSOLPAR);
		return (BC_ERROR);
	}

	device->start_sector = secnum;
	device->partition = pno - 1;
	log_part = 1;

found_part:
	/* get confirmation for -m */
	if (write_mbr && !force_mbr) {
		(void) fprintf(stdout, MBOOT_PROMPT);
		if (!yes()) {
			write_mbr = 0;
			(void) fprintf(stdout, MBOOT_NOT_UPDATED);
			return (BC_ERROR);
		}
	}

	/*
	 * Currently if Solaris is in an extended partition we need to
	 * write GRUB to the MBR. Check for this.
	 */
	if (log_part && !write_mbr) {
		(void) fprintf(stdout, gettext("Installing Solaris on an "
		    "extended partition... forcing MBR update\n"));
		write_mbr = 1;
	}

	/*
	 * warn, if Solaris in primary partition and GRUB not in MBR and
	 * partition is not active
	 */
	if (!log_part && part->bootid != 128 && !write_mbr) {
		(void) fprintf(stdout, SOLPAR_INACTIVE, device->partition + 1);
	}

	return (BC_SUCCESS);
}