#if defined(_SUNOS_VTOC_16)
-#if defined(i386) || defined(__amd64)
+#if defined(i386) || defined(__amd64) || defined(__arm) || defined(__powerpc)
{ V_BOOT, V_UNMNT }, /* i - 8 */
{ V_ALTSCTR, 0 }, /* j - 9 */
int sector_size;
unsigned long long capacity_size;
- if (ioctl(fd, BLKSSZGET, §or_size) < 0)
- return (-1);
+ if (ioctl(fd, BLKSSZGET, §or_size) < 0)
+ return (-1);
if (ioctl(fd, BLKGETSIZE64, &capacity_size) < 0)
return (-1);
char *dev_path;
int rval = 0;
- memset(dki_info, 0, sizeof(*dki_info));
+ memset(dki_info, 0, sizeof (*dki_info));
path = calloc(PATH_MAX, 1);
if (path == NULL)
strcpy(dki_info->dki_cname, "sd");
dki_info->dki_ctype = DKC_SCSI_CCS;
rval = sscanf(dev_path, "/dev/%[a-zA-Z]%hu",
- dki_info->dki_dname,
- &dki_info->dki_partition);
+ dki_info->dki_dname,
+ &dki_info->dki_partition);
} else if ((strncmp(dev_path, "/dev/hd", 7) == 0)) {
strcpy(dki_info->dki_cname, "hd");
dki_info->dki_ctype = DKC_DIRECT;
rval = sscanf(dev_path, "/dev/%[a-zA-Z]%hu",
- dki_info->dki_dname,
- &dki_info->dki_partition);
+ dki_info->dki_dname,
+ &dki_info->dki_partition);
} else if ((strncmp(dev_path, "/dev/md", 7) == 0)) {
strcpy(dki_info->dki_cname, "pseudo");
dki_info->dki_ctype = DKC_MD;
rval = sscanf(dev_path, "/dev/%[a-zA-Z0-9]p%hu",
- dki_info->dki_dname,
- &dki_info->dki_partition);
+ dki_info->dki_dname,
+ &dki_info->dki_partition);
} else if ((strncmp(dev_path, "/dev/vd", 7) == 0)) {
strcpy(dki_info->dki_cname, "vd");
dki_info->dki_ctype = DKC_MD;
rval = sscanf(dev_path, "/dev/%[a-zA-Z]%hu",
- dki_info->dki_dname,
- &dki_info->dki_partition);
+ dki_info->dki_dname,
+ &dki_info->dki_partition);
} else if ((strncmp(dev_path, "/dev/dm-", 8) == 0)) {
strcpy(dki_info->dki_cname, "pseudo");
dki_info->dki_ctype = DKC_VBD;
rval = sscanf(dev_path, "/dev/%[a-zA-Z0-9-]p%hu",
- dki_info->dki_dname,
- &dki_info->dki_partition);
+ dki_info->dki_dname,
+ &dki_info->dki_partition);
} else if ((strncmp(dev_path, "/dev/ram", 8) == 0)) {
strcpy(dki_info->dki_cname, "pseudo");
dki_info->dki_ctype = DKC_PCMCIA_MEM;
rval = sscanf(dev_path, "/dev/%[a-zA-Z0-9]p%hu",
- dki_info->dki_dname,
- &dki_info->dki_partition);
+ dki_info->dki_dname,
+ &dki_info->dki_partition);
} else if ((strncmp(dev_path, "/dev/loop", 9) == 0)) {
strcpy(dki_info->dki_cname, "pseudo");
dki_info->dki_ctype = DKC_VBD;
rval = sscanf(dev_path, "/dev/%[a-zA-Z0-9]p%hu",
- dki_info->dki_dname,
- &dki_info->dki_partition);
+ dki_info->dki_dname,
+ &dki_info->dki_partition);
} else {
strcpy(dki_info->dki_dname, "unknown");
strcpy(dki_info->dki_cname, "unknown");
*/
if (read_disk_info(fd, &capacity, &lbsize) == -1) {
if (efi_debug)
- fprintf(stderr,"unable to read disk info: %d",errno);
+ fprintf(stderr, "unable to read disk info: %d", errno);
errno = EIO;
- return -1;
+ return (-1);
}
switch (cmd) {
if (lbsize == 0) {
if (efi_debug)
(void) fprintf(stderr, "DKIOCGETEFI assuming "
- "LBA %d bytes\n", DEV_BSIZE);
+ "LBA %d bytes\n", DEV_BSIZE);
lbsize = DEV_BSIZE;
}
if (error == -1) {
if (efi_debug)
(void) fprintf(stderr, "DKIOCGETEFI lseek "
- "error: %d\n", errno);
- return error;
+ "error: %d\n", errno);
+ return (error);
}
error = read(fd, data, dk_ioc->dki_length);
if (error == -1) {
if (efi_debug)
(void) fprintf(stderr, "DKIOCGETEFI read "
- "error: %d\n", errno);
- return error;
+ "error: %d\n", errno);
+ return (error);
}
if (error != dk_ioc->dki_length) {
if (efi_debug)
(void) fprintf(stderr, "DKIOCGETEFI short "
- "read of %d bytes\n", error);
+ "read of %d bytes\n", error);
errno = EIO;
- return -1;
+ return (-1);
}
error = 0;
break;
if (lbsize == 0) {
if (efi_debug)
(void) fprintf(stderr, "DKIOCSETEFI unknown "
- "LBA size\n");
+ "LBA size\n");
errno = EIO;
- return -1;
+ return (-1);
}
error = lseek(fd, dk_ioc->dki_lba * lbsize, SEEK_SET);
if (error == -1) {
if (efi_debug)
(void) fprintf(stderr, "DKIOCSETEFI lseek "
- "error: %d\n", errno);
- return error;
+ "error: %d\n", errno);
+ return (error);
}
error = write(fd, data, dk_ioc->dki_length);
if (error == -1) {
if (efi_debug)
(void) fprintf(stderr, "DKIOCSETEFI write "
- "error: %d\n", errno);
- return error;
+ "error: %d\n", errno);
+ return (error);
}
if (error != dk_ioc->dki_length) {
if (efi_debug)
(void) fprintf(stderr, "DKIOCSETEFI short "
- "write of %d bytes\n", error);
+ "write of %d bytes\n", error);
errno = EIO;
- return -1;
+ return (-1);
}
/* Sync the new EFI table to disk */
error = fsync(fd);
if (error == -1)
- return error;
+ return (error);
/* Ensure any local disk cache is also flushed */
if (ioctl(fd, BLKFLSBUF, 0) == -1)
- return error;
+ return (error);
error = 0;
break;
(void) fprintf(stderr, "unsupported ioctl()\n");
errno = EIO;
- return -1;
+ return (-1);
}
#else
dk_ioc->dki_data_64 = (uint64_t)(uintptr_t)data;
return (error);
}
-#if defined(__linux__)
-static int
+int
efi_rescan(int fd)
{
+#if defined(__linux__)
int retry = 5;
int error;
while ((error = ioctl(fd, BLKRRPART)) != 0) {
if (--retry == 0) {
(void) fprintf(stderr, "the kernel failed to rescan "
- "the partition table: %d\n", errno);
+ "the partition table: %d\n", errno);
return (-1);
}
}
+#endif
return (0);
}
-#endif
static int
check_label(int fd, dk_efi_t *dk_ioc)
efi->efi_gpt_HeaderCRC32 = 0;
len_t headerSize = (len_t)LE_32(efi->efi_gpt_HeaderSize);
- if(headerSize < EFI_MIN_LABEL_SIZE || headerSize > EFI_LABEL_SIZE) {
+ if (headerSize < EFI_MIN_LABEL_SIZE || headerSize > EFI_LABEL_SIZE) {
if (efi_debug)
(void) fprintf(stderr,
"Invalid EFI HeaderSize %llu. Assuming %d.\n",
* get the partition number for this file descriptor.
*/
if ((rval = efi_get_info(fd, &dki_info)) != 0)
- return rval;
+ return (rval);
if ((strncmp(dki_info.dki_cname, "pseudo", 7) == 0) &&
(strncmp(dki_info.dki_dname, "md", 3) == 0)) {
if (read_disk_info(fd, &capacity, &lbsize) == -1) {
if (efi_debug) {
(void) fprintf(stderr,
- "unable to read disk info: %d",
- errno);
+ "unable to read disk info: %d",
+ errno);
}
return (VT_EINVAL);
}
}
if (posix_memalign((void **)&dk_ioc.dki_data,
- disk_info.dki_lbsize, label_len))
+ disk_info.dki_lbsize, label_len))
return (VT_ERROR);
memset(dk_ioc.dki_data, 0, label_len);
struct dk_gpt *efi_label;
int rval;
int i;
- uint_t phy_last_slice = 0;
- diskaddr_t pl_start = 0;
- diskaddr_t pl_size;
+ uint_t resv_index = 0, data_index = 0;
+ diskaddr_t resv_start = 0, data_start = 0;
+ diskaddr_t difference;
rval = efi_alloc_and_read(fd, &efi_label);
if (rval < 0) {
return (rval);
}
- /* find the last physically non-zero partition */
- for (i = 0; i < efi_label->efi_nparts - 2; i ++) {
- if (pl_start < efi_label->efi_parts[i].p_start) {
- pl_start = efi_label->efi_parts[i].p_start;
- phy_last_slice = i;
- }
- }
- pl_size = efi_label->efi_parts[phy_last_slice].p_size;
-
/*
* If alter_lba is 1, we are using the backup label.
* Since we can locate the backup label by disk capacity,
return (VT_ENOSPC);
}
+ difference = efi_label->efi_last_lba - efi_label->efi_altern_lba;
+
+ /*
+ * Find the last physically non-zero partition.
+ * This is the reserved partition.
+ */
+ for (i = 0; i < efi_label->efi_nparts; i ++) {
+ if (resv_start < efi_label->efi_parts[i].p_start) {
+ resv_start = efi_label->efi_parts[i].p_start;
+ resv_index = i;
+ }
+ }
+
/*
- * If there is space between the last physically non-zero partition
- * and the reserved partition, just add the unallocated space to this
- * area. Otherwise, the unallocated space is added to the last
- * physically non-zero partition.
+ * Find the last physically non-zero partition before that.
+ * This is the data partition.
*/
- if (pl_start + pl_size - 1 == efi_label->efi_last_u_lba -
- EFI_MIN_RESV_SIZE) {
- efi_label->efi_parts[phy_last_slice].p_size +=
- efi_label->efi_last_lba - efi_label->efi_altern_lba;
+ for (i = 0; i < resv_index; i ++) {
+ if (data_start < efi_label->efi_parts[i].p_start) {
+ data_start = efi_label->efi_parts[i].p_start;
+ data_index = i;
+ }
}
/*
* here except fabricated devids (which get generated via
* efi_write()). So there is no need to copy data.
*/
- efi_label->efi_parts[efi_label->efi_nparts - 1].p_start +=
- efi_label->efi_last_lba - efi_label->efi_altern_lba;
- efi_label->efi_last_u_lba += efi_label->efi_last_lba
- - efi_label->efi_altern_lba;
+ efi_label->efi_parts[data_index].p_size += difference;
+ efi_label->efi_parts[resv_index].p_start += difference;
+ efi_label->efi_last_u_lba += difference;
rval = efi_write(fd, efi_label);
if (rval < 0) {
diskaddr_t lba_backup_gpt_hdr;
if ((rval = efi_get_info(fd, &dki_info)) != 0)
- return rval;
+ return (rval);
/* check if we are dealing wih a metadevice */
if ((strncmp(dki_info.dki_cname, "pseudo", 7) == 0) &&
*/
lba_backup_gpt_hdr = vtoc->efi_last_u_lba + 1 + nblocks;
if (posix_memalign((void **)&dk_ioc.dki_data,
- vtoc->efi_lbasize, dk_ioc.dki_length))
+ vtoc->efi_lbasize, dk_ioc.dki_length))
return (VT_ERROR);
memset(dk_ioc.dki_data, 0, dk_ioc.dki_length);
(void) write_pmbr(fd, vtoc);
free(dk_ioc.dki_data);
-#if defined(__linux__)
- rval = efi_rescan(fd);
- if (rval)
- return (VT_ERROR);
-#endif
-
return (0);
}