installgrub.c (14d44f22) | installgrub.c (1a902ef8) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 7 unchanged lines hidden (view full) --- 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21/* 22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2012 Milan Jurik. All rights reserved. | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 7 unchanged lines hidden (view full) --- 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21/* 22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2012 Milan Jurik. All rights reserved. |
24 * Copyright 2012 Nexenta Systems, Inc. All rights reserved. | 24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved. |
25 */ 26 27#include <stdio.h> 28#include <stdlib.h> 29#include <libgen.h> 30#include <malloc.h> 31#include <string.h> 32#include <fcntl.h> --- 10 unchanged lines hidden (view full) --- 43#include <sys/mnttab.h> 44#include <sys/dktp/fdisk.h> 45#include <sys/dkio.h> 46#include <sys/vtoc.h> 47#include <sys/types.h> 48#include <sys/stat.h> 49#include <sys/multiboot.h> 50#include <sys/sysmacros.h> | 25 */ 26 27#include <stdio.h> 28#include <stdlib.h> 29#include <libgen.h> 30#include <malloc.h> 31#include <string.h> 32#include <fcntl.h> --- 10 unchanged lines hidden (view full) --- 43#include <sys/mnttab.h> 44#include <sys/dktp/fdisk.h> 45#include <sys/dkio.h> 46#include <sys/vtoc.h> 47#include <sys/types.h> 48#include <sys/stat.h> 49#include <sys/multiboot.h> 50#include <sys/sysmacros.h> |
51#include <sys/efi_partition.h> |
|
51 | 52 |
53#include <libnvpair.h> 54#include <libfstyp.h> 55 |
|
52#include "message.h" 53#include "installgrub.h" 54#include "./../common/bblk_einfo.h" 55#include "./../common/boot_utils.h" 56#include "./../common/mboot_extra.h" 57 58#ifndef TEXT_DOMAIN 59#define TEXT_DOMAIN "SUNW_OST_OSCMD" --- 42 unchanged lines hidden (view full) --- 102static int find_x86_bootpar(struct mboot *, int *, uint32_t *); 103static int copy_stage2_to_pcfs(ig_data_t *); 104static int write_stage2(ig_data_t *); 105static int write_stage1(ig_data_t *); 106static void usage(char *); 107static int read_stage1_from_file(char *, ig_data_t *); 108static int read_stage2_from_file(char *, ig_data_t *); 109static int read_stage1_from_disk(int, char *); | 56#include "message.h" 57#include "installgrub.h" 58#include "./../common/bblk_einfo.h" 59#include "./../common/boot_utils.h" 60#include "./../common/mboot_extra.h" 61 62#ifndef TEXT_DOMAIN 63#define TEXT_DOMAIN "SUNW_OST_OSCMD" --- 42 unchanged lines hidden (view full) --- 106static int find_x86_bootpar(struct mboot *, int *, uint32_t *); 107static int copy_stage2_to_pcfs(ig_data_t *); 108static int write_stage2(ig_data_t *); 109static int write_stage1(ig_data_t *); 110static void usage(char *); 111static int read_stage1_from_file(char *, ig_data_t *); 112static int read_stage2_from_file(char *, ig_data_t *); 113static int read_stage1_from_disk(int, char *); |
110static int read_stage2_from_disk(int, ig_stage2_t *); | 114static int read_stage2_from_disk(int, ig_stage2_t *, int); |
111static int prepare_stage1(ig_data_t *); 112static int prepare_stage2(ig_data_t *, char *); 113static void prepare_fake_multiboot(ig_stage2_t *); 114static void add_stage2_einfo(ig_stage2_t *, char *updt_str); 115static boolean_t is_update_necessary(ig_data_t *, char *); 116 117extern int read_stage2_blocklist(int, unsigned int *); 118 --- 265 unchanged lines hidden (view full) --- 384 } 385 386 if (is_bootpar(device->type)) { 387 (void) fprintf(stderr, gettext("Versioning not supported on " 388 "PCFS\n")); 389 goto out_dev; 390 } 391 | 115static int prepare_stage1(ig_data_t *); 116static int prepare_stage2(ig_data_t *, char *); 117static void prepare_fake_multiboot(ig_stage2_t *); 118static void add_stage2_einfo(ig_stage2_t *, char *updt_str); 119static boolean_t is_update_necessary(ig_data_t *, char *); 120 121extern int read_stage2_blocklist(int, unsigned int *); 122 --- 265 unchanged lines hidden (view full) --- 388 } 389 390 if (is_bootpar(device->type)) { 391 (void) fprintf(stderr, gettext("Versioning not supported on " 392 "PCFS\n")); 393 goto out_dev; 394 } 395 |
392 ret = read_stage2_from_disk(device->part_fd, stage2); | 396 ret = read_stage2_from_disk(device->part_fd, stage2, device->type); |
393 if (ret == BC_ERROR) { 394 (void) fprintf(stderr, gettext("Error reading stage2 from " 395 "%s\n"), device_path); 396 goto out_dev; 397 } 398 399 if (ret == BC_NOEXTRA) { 400 (void) fprintf(stdout, gettext("No multiboot header found on " --- 81 unchanged lines hidden (view full) --- 482 } 483 484 if (is_bootpar(curr_device->type) || is_bootpar(attach_device->type)) { 485 (void) fprintf(stderr, gettext("boot block mirroring is not " 486 "supported on PCFS\n")); 487 goto out_devs; 488 } 489 | 397 if (ret == BC_ERROR) { 398 (void) fprintf(stderr, gettext("Error reading stage2 from " 399 "%s\n"), device_path); 400 goto out_dev; 401 } 402 403 if (ret == BC_NOEXTRA) { 404 (void) fprintf(stdout, gettext("No multiboot header found on " --- 81 unchanged lines hidden (view full) --- 486 } 487 488 if (is_bootpar(curr_device->type) || is_bootpar(attach_device->type)) { 489 (void) fprintf(stderr, gettext("boot block mirroring is not " 490 "supported on PCFS\n")); 491 goto out_devs; 492 } 493 |
490 ret = read_stage2_from_disk(curr_device->part_fd, stage2_curr); | 494 ret = read_stage2_from_disk(curr_device->part_fd, stage2_curr, 495 curr_device->type); |
491 if (ret == BC_ERROR) { 492 BOOT_DEBUG("Error reading first stage2 blocks from %s\n", 493 curr_device->path); 494 retval = BC_ERROR; 495 goto out_devs; 496 } 497 498 if (ret == BC_NOEXTRA) { --- 119 unchanged lines hidden (view full) --- 618} 619 620/* 621 * open the device and fill the various members of ig_device_t. 622 */ 623static int 624init_device(ig_device_t *device, char *path) 625{ | 496 if (ret == BC_ERROR) { 497 BOOT_DEBUG("Error reading first stage2 blocks from %s\n", 498 curr_device->path); 499 retval = BC_ERROR; 500 goto out_devs; 501 } 502 503 if (ret == BC_NOEXTRA) { --- 119 unchanged lines hidden (view full) --- 623} 624 625/* 626 * open the device and fill the various members of ig_device_t. 627 */ 628static int 629init_device(ig_device_t *device, char *path) 630{ |
631 struct dk_gpt *vtoc; 632 fstyp_handle_t fhdl; 633 const char *fident; 634 |
|
626 bzero(device, sizeof (*device)); 627 device->part_fd = -1; 628 device->disk_fd = -1; 629 device->path_p0 = NULL; 630 631 device->path = strdup(path); 632 if (device->path == NULL) { 633 perror(gettext("Memory allocation failed")); --- 16 unchanged lines hidden (view full) --- 650 /* read in the device boot sector. */ 651 if (read(device->disk_fd, device->boot_sector, SECTOR_SIZE) 652 != SECTOR_SIZE) { 653 (void) fprintf(stderr, gettext("Error reading boot sector\n")); 654 perror("read"); 655 return (BC_ERROR); 656 } 657 | 635 bzero(device, sizeof (*device)); 636 device->part_fd = -1; 637 device->disk_fd = -1; 638 device->path_p0 = NULL; 639 640 device->path = strdup(path); 641 if (device->path == NULL) { 642 perror(gettext("Memory allocation failed")); --- 16 unchanged lines hidden (view full) --- 659 /* read in the device boot sector. */ 660 if (read(device->disk_fd, device->boot_sector, SECTOR_SIZE) 661 != SECTOR_SIZE) { 662 (void) fprintf(stderr, gettext("Error reading boot sector\n")); 663 perror("read"); 664 return (BC_ERROR); 665 } 666 |
667 if (efi_alloc_and_read(device->disk_fd, &vtoc) > 0) { 668 device->type = IG_DEV_EFI; 669 efi_free(vtoc); 670 } 671 |
|
658 if (get_raw_partition_fd(device) != BC_SUCCESS) 659 return (BC_ERROR); 660 | 672 if (get_raw_partition_fd(device) != BC_SUCCESS) 673 return (BC_ERROR); 674 |
675 if (fstyp_init(device->part_fd, 0, NULL, &fhdl) != 0) 676 return (BC_ERROR); 677 678 if (fstyp_ident(fhdl, "zfs", &fident) != 0) { 679 fstyp_fini(fhdl); 680 (void) fprintf(stderr, gettext("Booting of EFI labeled disks " 681 "is only supported with ZFS\n")); 682 return (BC_ERROR); 683 } 684 fstyp_fini(fhdl); 685 |
|
661 if (get_start_sector(device) != BC_SUCCESS) 662 return (BC_ERROR); 663 664 return (BC_SUCCESS); 665} 666 667static void 668cleanup_device(ig_device_t *device) --- 27 unchanged lines hidden (view full) --- 696 uint32_t secnum = 0, numsec = 0; 697 int i, pno, rval, log_part = 0; 698 struct mboot *mboot; 699 struct ipart *part; 700 ext_part_t *epp; 701 struct part_info dkpi; 702 struct extpart_info edkpi; 703 | 686 if (get_start_sector(device) != BC_SUCCESS) 687 return (BC_ERROR); 688 689 return (BC_SUCCESS); 690} 691 692static void 693cleanup_device(ig_device_t *device) --- 27 unchanged lines hidden (view full) --- 721 uint32_t secnum = 0, numsec = 0; 722 int i, pno, rval, log_part = 0; 723 struct mboot *mboot; 724 struct ipart *part; 725 ext_part_t *epp; 726 struct part_info dkpi; 727 struct extpart_info edkpi; 728 |
729 if (is_efi(device->type)) { 730 struct dk_gpt *vtoc; 731 732 if (efi_alloc_and_read(device->disk_fd, &vtoc) <= 0) 733 return (BC_ERROR); 734 735 device->start_sector = vtoc->efi_parts[device->slice].p_start; 736 /* GPT doesn't use traditional slice letters */ 737 device->slice = 0xff; 738 device->partition = 0; 739 740 efi_free(vtoc); 741 goto found_part; 742 } 743 |
|
704 mboot = (struct mboot *)device->boot_sector; 705 706 if (is_bootpar(device->type)) { 707 if (find_x86_bootpar(mboot, &pno, &secnum) != BC_SUCCESS) { 708 (void) fprintf(stderr, NOBOOTPAR); 709 return (BC_ERROR); 710 } else { 711 device->start_sector = secnum; --- 242 unchanged lines hidden (view full) --- 954 return (BC_SUCCESS); 955 } 956 957 /* 958 * For disk, write stage2 starting at STAGE2_BLKOFF sector. 959 * Note that we use stage2->buf rather than stage2->file, because we 960 * may have extended information after the latter. 961 */ | 744 mboot = (struct mboot *)device->boot_sector; 745 746 if (is_bootpar(device->type)) { 747 if (find_x86_bootpar(mboot, &pno, &secnum) != BC_SUCCESS) { 748 (void) fprintf(stderr, NOBOOTPAR); 749 return (BC_ERROR); 750 } else { 751 device->start_sector = secnum; --- 242 unchanged lines hidden (view full) --- 994 return (BC_SUCCESS); 995 } 996 997 /* 998 * For disk, write stage2 starting at STAGE2_BLKOFF sector. 999 * Note that we use stage2->buf rather than stage2->file, because we 1000 * may have extended information after the latter. 1001 */ |
962 offset = STAGE2_BLKOFF * SECTOR_SIZE; | 1002 offset = STAGE2_BLKOFF(device->type) * SECTOR_SIZE; 1003 |
963 if (write_out(device->part_fd, stage2->buf, stage2->buf_size, 964 offset) != BC_SUCCESS) { 965 perror("write"); 966 return (BC_ERROR); 967 } 968 969 /* Simulate the "old" installgrub output. */ 970 (void) fprintf(stdout, WRITE_STAGE2_DISK, device->partition, | 1004 if (write_out(device->part_fd, stage2->buf, stage2->buf_size, 1005 offset) != BC_SUCCESS) { 1006 perror("write"); 1007 return (BC_ERROR); 1008 } 1009 1010 /* Simulate the "old" installgrub output. */ 1011 (void) fprintf(stdout, WRITE_STAGE2_DISK, device->partition, |
971 (stage2->buf_size / SECTOR_SIZE) + 1, STAGE2_BLKOFF, | 1012 (stage2->buf_size / SECTOR_SIZE) + 1, STAGE2_BLKOFF(device->type), |
972 stage2->first_sector); 973 974 return (BC_SUCCESS); 975} 976 977static int 978write_stage1(ig_data_t *install) 979{ --- 177 unchanged lines hidden (view full) --- 1157 if (read_in(dev_fd, stage1_buf, SECTOR_SIZE, 0) != BC_SUCCESS) { 1158 perror(gettext("Unable to read stage1 from disk")); 1159 return (BC_ERROR); 1160 } 1161 return (BC_SUCCESS); 1162} 1163 1164static int | 1013 stage2->first_sector); 1014 1015 return (BC_SUCCESS); 1016} 1017 1018static int 1019write_stage1(ig_data_t *install) 1020{ --- 177 unchanged lines hidden (view full) --- 1198 if (read_in(dev_fd, stage1_buf, SECTOR_SIZE, 0) != BC_SUCCESS) { 1199 perror(gettext("Unable to read stage1 from disk")); 1200 return (BC_ERROR); 1201 } 1202 return (BC_SUCCESS); 1203} 1204 1205static int |
1165read_stage2_from_disk(int dev_fd, ig_stage2_t *stage2) | 1206read_stage2_from_disk(int dev_fd, ig_stage2_t *stage2, int type) |
1166{ 1167 uint32_t size; 1168 uint32_t buf_size; 1169 uint32_t mboot_off; 1170 multiboot_header_t *mboot; 1171 1172 assert(stage2 != NULL); 1173 assert(dev_fd != -1); 1174 1175 if (read_in(dev_fd, mboot_scan, sizeof (mboot_scan), | 1207{ 1208 uint32_t size; 1209 uint32_t buf_size; 1210 uint32_t mboot_off; 1211 multiboot_header_t *mboot; 1212 1213 assert(stage2 != NULL); 1214 assert(dev_fd != -1); 1215 1216 if (read_in(dev_fd, mboot_scan, sizeof (mboot_scan), |
1176 STAGE2_BLKOFF * SECTOR_SIZE) != BC_SUCCESS) { | 1217 STAGE2_BLKOFF(type) * SECTOR_SIZE) != BC_SUCCESS) { |
1177 perror(gettext("Error reading stage2 sectors")); 1178 return (BC_ERROR); 1179 } 1180 1181 /* No multiboot means no chance of knowing stage2 size */ 1182 if (find_multiboot(mboot_scan, sizeof (mboot_scan), &mboot_off) 1183 != BC_SUCCESS) { 1184 BOOT_DEBUG("Unable to find multiboot header\n"); --- 19 unchanged lines hidden (view full) --- 1204 1205 stage2->buf = malloc(buf_size); 1206 if (stage2->buf == NULL) { 1207 perror(gettext("Memory allocation failed")); 1208 return (BC_ERROR); 1209 } 1210 stage2->buf_size = buf_size; 1211 | 1218 perror(gettext("Error reading stage2 sectors")); 1219 return (BC_ERROR); 1220 } 1221 1222 /* No multiboot means no chance of knowing stage2 size */ 1223 if (find_multiboot(mboot_scan, sizeof (mboot_scan), &mboot_off) 1224 != BC_SUCCESS) { 1225 BOOT_DEBUG("Unable to find multiboot header\n"); --- 19 unchanged lines hidden (view full) --- 1245 1246 stage2->buf = malloc(buf_size); 1247 if (stage2->buf == NULL) { 1248 perror(gettext("Memory allocation failed")); 1249 return (BC_ERROR); 1250 } 1251 stage2->buf_size = buf_size; 1252 |
1212 if (read_in(dev_fd, stage2->buf, buf_size, STAGE2_BLKOFF * | 1253 if (read_in(dev_fd, stage2->buf, buf_size, STAGE2_BLKOFF(type) * |
1213 SECTOR_SIZE) != BC_SUCCESS) { 1214 perror("read"); 1215 free(stage2->buf); 1216 return (BC_ERROR); 1217 } 1218 1219 /* Update pointers. */ 1220 stage2->file = stage2->buf; --- 17 unchanged lines hidden (view full) --- 1238 int dev_fd = device->part_fd; 1239 1240 assert(data != NULL); 1241 assert(device->part_fd != -1); 1242 1243 bzero(&stage2_disk, sizeof (ig_stage2_t)); 1244 1245 /* Gather stage2 (if present) from the target device. */ | 1254 SECTOR_SIZE) != BC_SUCCESS) { 1255 perror("read"); 1256 free(stage2->buf); 1257 return (BC_ERROR); 1258 } 1259 1260 /* Update pointers. */ 1261 stage2->file = stage2->buf; --- 17 unchanged lines hidden (view full) --- 1279 int dev_fd = device->part_fd; 1280 1281 assert(data != NULL); 1282 assert(device->part_fd != -1); 1283 1284 bzero(&stage2_disk, sizeof (ig_stage2_t)); 1285 1286 /* Gather stage2 (if present) from the target device. */ |
1246 if (read_stage2_from_disk(dev_fd, &stage2_disk) != BC_SUCCESS) { | 1287 if (read_stage2_from_disk(dev_fd, &stage2_disk, device->type) 1288 != BC_SUCCESS) { |
1247 BOOT_DEBUG("Unable to read stage2 from %s\n", device->path); 1248 BOOT_DEBUG("No multiboot wrapped stage2 on %s\n", device->path); 1249 return (B_TRUE); 1250 } 1251 1252 /* 1253 * Look for the extended information structure in the extra payload 1254 * area. --- 107 unchanged lines hidden (view full) --- 1362 START_SEG(pos) = (ushort_t)(install_addr >> 4); 1363 NUM_BLOCK(pos) = blocklist[i + 1]; 1364 install_addr += blocklist[i + 1] * SECTOR_SIZE; 1365 pos -= 8; 1366 i += 2; 1367 } 1368 } else { 1369 /* Solaris VTOC */ | 1289 BOOT_DEBUG("Unable to read stage2 from %s\n", device->path); 1290 BOOT_DEBUG("No multiboot wrapped stage2 on %s\n", device->path); 1291 return (B_TRUE); 1292 } 1293 1294 /* 1295 * Look for the extended information structure in the extra payload 1296 * area. --- 107 unchanged lines hidden (view full) --- 1404 START_SEG(pos) = (ushort_t)(install_addr >> 4); 1405 NUM_BLOCK(pos) = blocklist[i + 1]; 1406 install_addr += blocklist[i + 1] * SECTOR_SIZE; 1407 pos -= 8; 1408 i += 2; 1409 } 1410 } else { 1411 /* Solaris VTOC */ |
1370 stage2->first_sector = device->start_sector + STAGE2_BLKOFF; | 1412 stage2->first_sector = device->start_sector + 1413 STAGE2_BLKOFF(device->type); |
1371 BOOT_DEBUG("stage2 first sector: %d\n", stage2->first_sector); 1372 /* 1373 * In a solaris partition, stage2 is written to contiguous 1374 * blocks. So we update the starting block only. 1375 */ 1376 *((ulong_t *)(stage2->file + STAGE2_BLOCKLIST)) = 1377 stage2->first_sector + 1; 1378 } --- 57 unchanged lines hidden (view full) --- 1436 /* For disk, remember slice and return whole fdisk partition */ 1437 raw = strdup(device->path); 1438 if (raw == NULL) { 1439 perror(gettext("Memory allocation failed")); 1440 return (NULL); 1441 } 1442 1443 len = strlen(raw); | 1414 BOOT_DEBUG("stage2 first sector: %d\n", stage2->first_sector); 1415 /* 1416 * In a solaris partition, stage2 is written to contiguous 1417 * blocks. So we update the starting block only. 1418 */ 1419 *((ulong_t *)(stage2->file + STAGE2_BLOCKLIST)) = 1420 stage2->first_sector + 1; 1421 } --- 57 unchanged lines hidden (view full) --- 1479 /* For disk, remember slice and return whole fdisk partition */ 1480 raw = strdup(device->path); 1481 if (raw == NULL) { 1482 perror(gettext("Memory allocation failed")); 1483 return (NULL); 1484 } 1485 1486 len = strlen(raw); |
1444 if (raw[len - 2] != 's' || raw[len - 1] == '2') { | 1487 if (!is_efi(device->type) && 1488 (raw[len - 2] != 's' || raw[len - 1] == '2')) { |
1445 (void) fprintf(stderr, NOT_ROOT_SLICE); 1446 free(raw); 1447 return (NULL); 1448 } 1449 device->slice = atoi(&raw[len - 1]); 1450 | 1489 (void) fprintf(stderr, NOT_ROOT_SLICE); 1490 free(raw); 1491 return (NULL); 1492 } 1493 device->slice = atoi(&raw[len - 1]); 1494 |
1451 raw[len - 2] = 's'; 1452 raw[len - 1] = '2'; | 1495 if (!is_efi(device->type)) { 1496 raw[len - 2] = 's'; 1497 raw[len - 1] = '2'; 1498 } |
1453 1454 return (raw); 1455} 1456 1457static int 1458get_raw_partition_fd(ig_device_t *device) 1459{ 1460 struct stat stat = {0}; --- 107 unchanged lines hidden --- | 1499 1500 return (raw); 1501} 1502 1503static int 1504get_raw_partition_fd(ig_device_t *device) 1505{ 1506 struct stat stat = {0}; --- 107 unchanged lines hidden --- |