15 * If applicable, add the following below this CDDL HEADER, with the
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) 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
24 * Copyright 2017 Toomas Soome <tsoome@me.com>
25 */
26
27 #include <stdio.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <assert.h>
32 #include <locale.h>
33 #include <strings.h>
34 #include <libfdisk.h>
35
36 #include <sys/dktp/fdisk.h>
37 #include <sys/dkio.h>
38 #include <sys/vtoc.h>
39 #include <sys/multiboot.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <sys/sysmacros.h>
43 #include <sys/efi_partition.h>
44 #include <libfstyp.h>
45 #include <uuid/uuid.h>
46
47 #include "installboot.h"
48 #include "../../common/bblk_einfo.h"
49 #include "../../common/boot_utils.h"
50 #include "../../common/mboot_extra.h"
51 #include "getresponse.h"
52
53 #ifndef TEXT_DOMAIN
54 #define TEXT_DOMAIN "SUNW_OST_OSCMD"
76 * In case of pcfs, the stage2 location is 50 512B sectors from beginning
77 * of the disk, filling the space between MBR and first partition.
78 * This location assumes no other bootloader and the space is one cylinder,
79 * as first partition is starting from cylinder 1.
80 *
81 * In case of GPT partitioning and if file system is not zfs, the boot
82 * support is only possible with dedicated boot partition. For GPT,
83 * the current implementation is using BOOT partition, which must exist.
84 * BOOT partition does only contain raw boot blocks, without any file system.
85 *
86 * Loader stage2 is created with embedded version, by using fake multiboot (MB)
87 * header within first 32k and EINFO block is at the end of the actual
88 * boot block. MB header load_addr is set to 0 and load_end_addr is set to
89 * actual block end, so the EINFO size is (file size - load_end_addr).
90 * installboot does also store the illumos boot partition LBA to MB space,
91 * starting from bss_end_addr structure member location; stage2 will
92 * detect the partition and file system based on this value.
93 *
94 * Stored location values in MBR/stage2 also mean the bootblocks must be
95 * reinstalled in case the partition content is relocated.
96 */
97
98 static boolean_t write_mbr = B_FALSE;
99 static boolean_t force_mbr = B_FALSE;
100 static boolean_t force_update = B_FALSE;
101 static boolean_t do_getinfo = B_FALSE;
102 static boolean_t do_version = B_FALSE;
103 static boolean_t do_mirror_bblk = B_FALSE;
104 static boolean_t strip = B_FALSE;
105 static boolean_t verbose_dump = B_FALSE;
106
107 /* Versioning string, if present. */
108 static char *update_str;
109
110 /*
111 * Temporary buffer to store the first 32K of data looking for a multiboot
112 * signature.
113 */
114 char mboot_scan[MBOOT_SCAN_SIZE];
115
116 /* Function prototypes. */
117 static void check_options(char *);
118 static int get_start_sector(ib_device_t *);
119
120 static int read_stage1_from_file(char *, ib_data_t *);
121 static int read_bootblock_from_file(char *, ib_bootblock_t *);
122 static int read_bootblock_from_disk(ib_device_t *, ib_bootblock_t *, char **);
123 static void add_bootblock_einfo(ib_bootblock_t *, char *);
124 static int prepare_stage1(ib_data_t *);
125 static int prepare_bootblock(ib_data_t *, char *);
126 static int write_stage1(ib_data_t *);
927 return (BC_ERROR);
928 }
929 device->stage.path = ptr;
930 device->stage.fd = open_device(ptr);
931 device->stage.id = i + 1;
932 device->stage.devtype = IG_DEV_MBR;
933 device->stage.fstype = IG_FS_NONE;
934 device->stage.start = part[i].relsect;
935 device->stage.size = part[i].numsect;
936 device->stage.offset = 1; /* leave sector 0 for VBR */
937 return (BC_SUCCESS);
938 }
939
940 static int
941 get_boot_slice(ib_device_t *device, struct dk_gpt *vtoc)
942 {
943 uint_t i;
944 char *path, *ptr;
945
946 for (i = 0; i < vtoc->efi_nparts; i++) {
947 if (vtoc->efi_parts[i].p_tag == V_BOOT) {
948 if ((path = strdup(device->target.path)) == NULL) {
949 perror(gettext("Memory allocation failure"));
950 return (BC_ERROR);
951 }
952 ptr = strrchr(path, 's');
953 ptr++;
954 *ptr = '\0';
955 (void) asprintf(&ptr, "%s%d", path, i);
956 free(path);
957 if (ptr == NULL) {
958 perror(gettext("Memory allocation failure"));
959 return (BC_ERROR);
960 }
961 device->stage.path = ptr;
962 device->stage.fd = open_device(ptr);
963 device->stage.id = i;
964 device->stage.devtype = IG_DEV_EFI;
965 device->stage.fstype = IG_FS_NONE;
966 device->stage.start = vtoc->efi_parts[i].p_start;
967 device->stage.size = vtoc->efi_parts[i].p_size;
968 device->stage.offset = 1; /* leave sector 0 for VBR */
969 return (BC_SUCCESS);
970 }
971 }
972 return (BC_SUCCESS);
973 }
974
975 static int
976 init_device(ib_device_t *device, char *path)
977 {
978 struct dk_gpt *vtoc;
979 fstyp_handle_t fhdl;
980 const char *fident;
981 char *p;
982 int pathlen = strlen(path);
983 int ret;
984
985 bzero(device, sizeof (*device));
986 device->fd = -1; /* whole disk fd */
987 device->stage.fd = -1; /* bootblock partition fd */
988 device->target.fd = -1; /* target fs partition fd */
989
990 /* basic check, whole disk is not allowed */
991 if ((p = strrchr(path, '/')) == NULL)
992 p = path;
993 if ((strrchr(p, 'p') == NULL && strrchr(p, 's') == NULL) ||
994 (path[pathlen-2] == 'p' && path[pathlen-1] == '0')) {
995 (void) fprintf(stderr, gettext("installing loader to "
996 "whole disk device is not supported\n"));
997 }
998
999 device->target.path = strdup(path);
1000 if (device->target.path == NULL) {
1001 perror(gettext("Memory allocation failure"));
1002 return (BC_ERROR);
1003 }
1004 device->path = strdup(path);
1005 if (device->path == NULL) {
1006 perror(gettext("Memory allocation failure"));
1007 return (BC_ERROR);
1125 return (BC_ERROR);
1126
1127 if (fstyp_ident(fhdl, NULL, &fident) == 0) {
1128 (void) fprintf(stderr, gettext("Unexpected %s file "
1129 "system on boot partition\n"), fident);
1130 fstyp_fini(fhdl);
1131 return (BC_ERROR);
1132 }
1133 fstyp_fini(fhdl);
1134 }
1135 return (get_start_sector(device));
1136 }
1137
1138 static void
1139 cleanup_device(ib_device_t *device)
1140 {
1141 if (device->path)
1142 free(device->path);
1143 if (device->stage.path)
1144 free(device->stage.path);
1145 if (device->target.path)
1146 free(device->target.path);
1147
1148 if (device->fd != -1)
1149 (void) close(device->fd);
1150 if (device->stage.fd != -1)
1151 (void) close(device->stage.fd);
1152 if (device->target.fd != -1)
1153 (void) close(device->target.fd);
1154 bzero(device, sizeof (*device));
1155 }
1156
1157 static void
1158 cleanup_bootblock(ib_bootblock_t *bblock)
1159 {
1160 free(bblock->buf);
1161 bzero(bblock, sizeof (ib_bootblock_t));
1162 }
1163
1164 /*
1165 * Propagate the bootblock on the source disk to the destination disk and
1166 * version it with 'updt_str' in the process. Since we cannot trust any data
1167 * on the attaching disk, we do not perform any specific check on a potential
1168 * target extended information structure and we just blindly update.
1169 */
1170 static int
1171 propagate_bootblock(ib_data_t *src, ib_data_t *dest, char *updt_str)
1235 return (write_stage1(data));
1236 }
1237
1238 /*
1239 * Install a new bootblock on the given device. handle_install() expects argv
1240 * to contain 3 parameters (the target device path and the path to the
1241 * bootblock.
1242 *
1243 * Returns: BC_SUCCESS - if the installation is successful
1244 * BC_ERROR - if the installation failed
1245 * BC_NOUPDT - if no installation was performed because the
1246 * version currently installed is more recent than the
1247 * supplied one.
1248 *
1249 */
1250 static int
1251 handle_install(char *progname, char **argv)
1252 {
1253 ib_data_t install_data;
1254 ib_bootblock_t *bblock = &install_data.bootblock;
1255 char *stage1 = NULL;
1256 char *bootblock = NULL;
1257 char *device_path = NULL;
1258 int ret = BC_ERROR;
1259
1260 stage1 = strdup(argv[0]);
1261 bootblock = strdup(argv[1]);
1262 device_path = strdup(argv[2]);
1263
1264 if (!device_path || !bootblock || !stage1) {
1265 (void) fprintf(stderr, gettext("Missing parameter"));
1266 usage(progname);
1267 goto out;
1268 }
1269
1270 BOOT_DEBUG("device path: %s, stage1 path: %s bootblock path: %s\n",
1271 device_path, stage1, bootblock);
1272 bzero(&install_data, sizeof (ib_data_t));
1273
1274 if (init_device(&install_data.device, device_path) != BC_SUCCESS) {
1275 (void) fprintf(stderr, gettext("Unable to open device %s\n"),
1276 device_path);
1277 goto out;
1278 }
1279
1280 if (read_stage1_from_file(stage1, &install_data) != BC_SUCCESS) {
1281 (void) fprintf(stderr, gettext("Error opening %s\n"), stage1);
1282 goto out_dev;
1283 }
1284
1285 if (read_bootblock_from_file(bootblock, bblock) != BC_SUCCESS) {
1286 (void) fprintf(stderr, gettext("Error reading %s\n"),
1287 bootblock);
1288 goto out_dev;
1289 }
1290
1291 /*
1292 * is_update_necessary() will take care of checking if versioning and/or
1293 * forcing the update have been specified. It will also emit a warning
1294 * if a non-versioned update is attempted over a versioned bootblock.
1295 */
1296 if (!is_update_necessary(&install_data, update_str)) {
1297 (void) fprintf(stderr, gettext("bootblock version installed "
1298 "on %s is more recent or identical\n"
1299 "Use -F to override or install without the -u option\n"),
1300 device_path);
1301 ret = BC_NOUPDT;
1302 goto out_dev;
1303 }
1304
1305 BOOT_DEBUG("Ready to commit to disk\n");
1306 ret = commit_to_disk(&install_data, update_str);
1307
1308 out_dev:
1309 cleanup_device(&install_data.device);
1310 out:
1311 free(stage1);
1312 free(bootblock);
1313 free(device_path);
1314 return (ret);
1315 }
1316
1317 /*
1318 * Retrieves from a device the extended information (einfo) associated to the
1319 * file or installed stage2.
1320 * Expects one parameter, the device path, in the form: /dev/rdsk/c?[t?]d?s0
1321 * or file name.
1322 * Returns:
1323 * - BC_SUCCESS (and prints out einfo contents depending on 'flags')
1324 * - BC_ERROR (on error)
1325 * - BC_NOEINFO (no extended information available)
1326 */
1327 static int
1328 handle_getinfo(char *progname, char **argv)
1329 {
1330 struct stat sb;
|
15 * If applicable, add the following below this CDDL HEADER, with the
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) 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
24 * Copyright 2017 Toomas Soome <tsoome@me.com>
25 */
26
27 #include <stdio.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <assert.h>
32 #include <locale.h>
33 #include <strings.h>
34 #include <libfdisk.h>
35 #include <libgen.h>
36
37 #include <sys/dktp/fdisk.h>
38 #include <sys/dkio.h>
39 #include <sys/vtoc.h>
40 #include <sys/multiboot.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <sys/sysmacros.h>
44 #include <sys/efi_partition.h>
45 #include <libfstyp.h>
46 #include <uuid/uuid.h>
47
48 #include "installboot.h"
49 #include "../../common/bblk_einfo.h"
50 #include "../../common/boot_utils.h"
51 #include "../../common/mboot_extra.h"
52 #include "getresponse.h"
53
54 #ifndef TEXT_DOMAIN
55 #define TEXT_DOMAIN "SUNW_OST_OSCMD"
77 * In case of pcfs, the stage2 location is 50 512B sectors from beginning
78 * of the disk, filling the space between MBR and first partition.
79 * This location assumes no other bootloader and the space is one cylinder,
80 * as first partition is starting from cylinder 1.
81 *
82 * In case of GPT partitioning and if file system is not zfs, the boot
83 * support is only possible with dedicated boot partition. For GPT,
84 * the current implementation is using BOOT partition, which must exist.
85 * BOOT partition does only contain raw boot blocks, without any file system.
86 *
87 * Loader stage2 is created with embedded version, by using fake multiboot (MB)
88 * header within first 32k and EINFO block is at the end of the actual
89 * boot block. MB header load_addr is set to 0 and load_end_addr is set to
90 * actual block end, so the EINFO size is (file size - load_end_addr).
91 * installboot does also store the illumos boot partition LBA to MB space,
92 * starting from bss_end_addr structure member location; stage2 will
93 * detect the partition and file system based on this value.
94 *
95 * Stored location values in MBR/stage2 also mean the bootblocks must be
96 * reinstalled in case the partition content is relocated.
97 *
98 * EFI boot program installation:
99 * EFI boot requires EFI System partition with following directory
100 * hierarchy:
101 * EFI/VENDOR/file
102 * EFI/BOOT/BOOTx64.EFI
103 * Where EFI/BOOT is fallback directory. While we have no mechanism to set
104 * EFI variable values to define vendor specific boot program location, we
105 * will just use EFI/BOOT/BOOTx64.EFI; also this setup is only possible
106 * solution for removable media.
107 * For now the boot1.efi is used for boot program, boot1.efi is also
108 * versioned as is gptzfsboot.
109 */
110
111 static boolean_t write_mbr = B_FALSE;
112 static boolean_t force_mbr = B_FALSE;
113 static boolean_t force_update = B_FALSE;
114 static boolean_t do_getinfo = B_FALSE;
115 static boolean_t do_version = B_FALSE;
116 static boolean_t do_mirror_bblk = B_FALSE;
117 static boolean_t strip = B_FALSE;
118 static boolean_t verbose_dump = B_FALSE;
119
120 #define EFIBOOT64 "bootx64.efi"
121 #define EFIBOOT32 "bootia32.efi"
122
123 /* Versioning string, if present. */
124 static char *update_str;
125
126 /*
127 * Temporary buffer to store the first 32K of data looking for a multiboot
128 * signature.
129 */
130 char mboot_scan[MBOOT_SCAN_SIZE];
131
132 /* Function prototypes. */
133 static void check_options(char *);
134 static int get_start_sector(ib_device_t *);
135
136 static int read_stage1_from_file(char *, ib_data_t *);
137 static int read_bootblock_from_file(char *, ib_bootblock_t *);
138 static int read_bootblock_from_disk(ib_device_t *, ib_bootblock_t *, char **);
139 static void add_bootblock_einfo(ib_bootblock_t *, char *);
140 static int prepare_stage1(ib_data_t *);
141 static int prepare_bootblock(ib_data_t *, char *);
142 static int write_stage1(ib_data_t *);
943 return (BC_ERROR);
944 }
945 device->stage.path = ptr;
946 device->stage.fd = open_device(ptr);
947 device->stage.id = i + 1;
948 device->stage.devtype = IG_DEV_MBR;
949 device->stage.fstype = IG_FS_NONE;
950 device->stage.start = part[i].relsect;
951 device->stage.size = part[i].numsect;
952 device->stage.offset = 1; /* leave sector 0 for VBR */
953 return (BC_SUCCESS);
954 }
955
956 static int
957 get_boot_slice(ib_device_t *device, struct dk_gpt *vtoc)
958 {
959 uint_t i;
960 char *path, *ptr;
961
962 for (i = 0; i < vtoc->efi_nparts; i++) {
963 if (vtoc->efi_parts[i].p_tag == V_SYSTEM) {
964 if ((path = strdup(device->target.path)) == NULL) {
965 perror(gettext("Memory allocation failure"));
966 return (BC_ERROR);
967 }
968 ptr = strrchr(path, 's');
969 ptr++;
970 *ptr = '\0';
971 (void) asprintf(&ptr, "%s%d", path, i);
972 free(path);
973 if (ptr == NULL) {
974 perror(gettext("Memory allocation failure"));
975 return (BC_ERROR);
976 }
977 device->system.path = ptr;
978 device->system.fd = open_device(ptr);
979 device->system.id = i;
980 device->system.devtype = IG_DEV_EFI;
981 device->system.fstype = IG_FS_PCFS;
982 device->system.start = vtoc->efi_parts[i].p_start;
983 device->system.size = vtoc->efi_parts[i].p_size;
984 device->system.offset = 0;
985 } else if (vtoc->efi_parts[i].p_tag == V_BOOT) {
986 if ((path = strdup(device->target.path)) == NULL) {
987 perror(gettext("Memory allocation failure"));
988 return (BC_ERROR);
989 }
990 ptr = strrchr(path, 's');
991 ptr++;
992 *ptr = '\0';
993 (void) asprintf(&ptr, "%s%d", path, i);
994 free(path);
995 if (ptr == NULL) {
996 perror(gettext("Memory allocation failure"));
997 return (BC_ERROR);
998 }
999 device->stage.path = ptr;
1000 device->stage.fd = open_device(ptr);
1001 device->stage.id = i;
1002 device->stage.devtype = IG_DEV_EFI;
1003 device->stage.fstype = IG_FS_NONE;
1004 device->stage.start = vtoc->efi_parts[i].p_start;
1005 device->stage.size = vtoc->efi_parts[i].p_size;
1006 device->stage.offset = 1; /* leave sector 0 for VBR */
1007 }
1008 }
1009 return (BC_SUCCESS);
1010 }
1011
1012 static int
1013 init_device(ib_device_t *device, char *path)
1014 {
1015 struct dk_gpt *vtoc;
1016 fstyp_handle_t fhdl;
1017 const char *fident;
1018 char *p;
1019 int pathlen = strlen(path);
1020 int ret;
1021
1022 bzero(device, sizeof (*device));
1023 device->fd = -1; /* whole disk fd */
1024 device->stage.fd = -1; /* bootblock partition fd */
1025 device->system.fd = -1; /* efi system partition fd */
1026 device->target.fd = -1; /* target fs partition fd */
1027
1028 /* basic check, whole disk is not allowed */
1029 if ((p = strrchr(path, '/')) == NULL)
1030 p = path;
1031 if ((strrchr(p, 'p') == NULL && strrchr(p, 's') == NULL) ||
1032 (path[pathlen-2] == 'p' && path[pathlen-1] == '0')) {
1033 (void) fprintf(stderr, gettext("installing loader to "
1034 "whole disk device is not supported\n"));
1035 }
1036
1037 device->target.path = strdup(path);
1038 if (device->target.path == NULL) {
1039 perror(gettext("Memory allocation failure"));
1040 return (BC_ERROR);
1041 }
1042 device->path = strdup(path);
1043 if (device->path == NULL) {
1044 perror(gettext("Memory allocation failure"));
1045 return (BC_ERROR);
1163 return (BC_ERROR);
1164
1165 if (fstyp_ident(fhdl, NULL, &fident) == 0) {
1166 (void) fprintf(stderr, gettext("Unexpected %s file "
1167 "system on boot partition\n"), fident);
1168 fstyp_fini(fhdl);
1169 return (BC_ERROR);
1170 }
1171 fstyp_fini(fhdl);
1172 }
1173 return (get_start_sector(device));
1174 }
1175
1176 static void
1177 cleanup_device(ib_device_t *device)
1178 {
1179 if (device->path)
1180 free(device->path);
1181 if (device->stage.path)
1182 free(device->stage.path);
1183 if (device->system.path)
1184 free(device->system.path);
1185 if (device->target.path)
1186 free(device->target.path);
1187
1188 if (device->fd != -1)
1189 (void) close(device->fd);
1190 if (device->stage.fd != -1)
1191 (void) close(device->stage.fd);
1192 if (device->system.fd != -1)
1193 (void) close(device->system.fd);
1194 if (device->target.fd != -1)
1195 (void) close(device->target.fd);
1196 bzero(device, sizeof (*device));
1197 }
1198
1199 static void
1200 cleanup_bootblock(ib_bootblock_t *bblock)
1201 {
1202 free(bblock->buf);
1203 bzero(bblock, sizeof (ib_bootblock_t));
1204 }
1205
1206 /*
1207 * Propagate the bootblock on the source disk to the destination disk and
1208 * version it with 'updt_str' in the process. Since we cannot trust any data
1209 * on the attaching disk, we do not perform any specific check on a potential
1210 * target extended information structure and we just blindly update.
1211 */
1212 static int
1213 propagate_bootblock(ib_data_t *src, ib_data_t *dest, char *updt_str)
1277 return (write_stage1(data));
1278 }
1279
1280 /*
1281 * Install a new bootblock on the given device. handle_install() expects argv
1282 * to contain 3 parameters (the target device path and the path to the
1283 * bootblock.
1284 *
1285 * Returns: BC_SUCCESS - if the installation is successful
1286 * BC_ERROR - if the installation failed
1287 * BC_NOUPDT - if no installation was performed because the
1288 * version currently installed is more recent than the
1289 * supplied one.
1290 *
1291 */
1292 static int
1293 handle_install(char *progname, char **argv)
1294 {
1295 ib_data_t install_data;
1296 ib_bootblock_t *bblock = &install_data.bootblock;
1297 ib_bootblock_t *eblock = &install_data.efiblock;
1298 char *stage1 = NULL;
1299 char *bootblock = NULL;
1300 char *efiboot = NULL;
1301 char *device_path = NULL;
1302 char *tmp;
1303 int ret = BC_ERROR;
1304
1305 stage1 = strdup(argv[0]);
1306 bootblock = strdup(argv[1]);
1307 device_path = strdup(argv[2]);
1308
1309 if (!device_path || !bootblock || !stage1) {
1310 (void) fprintf(stderr, gettext("Missing parameter"));
1311 usage(progname);
1312 goto out;
1313 }
1314
1315 tmp = strdup(argv[1]);
1316 if (tmp == NULL) {
1317 perror(gettext("Memory allocation failure"));
1318 goto out;
1319 }
1320 (void) asprintf(&efiboot, "%s/" EFIBOOT64, dirname(tmp));
1321 free(tmp);
1322 if (efiboot == NULL) {
1323 perror(gettext("Memory allocation failure"));
1324 goto out;
1325 }
1326
1327 BOOT_DEBUG("device path: %s, stage1 path: %s bootblock path: %s\n",
1328 device_path, stage1, bootblock);
1329 bzero(&install_data, sizeof (ib_data_t));
1330
1331 if (init_device(&install_data.device, device_path) != BC_SUCCESS) {
1332 (void) fprintf(stderr, gettext("Unable to open device %s\n"),
1333 device_path);
1334 goto out;
1335 }
1336
1337 if (read_stage1_from_file(stage1, &install_data) != BC_SUCCESS) {
1338 (void) fprintf(stderr, gettext("Error opening %s\n"), stage1);
1339 goto out_dev;
1340 }
1341
1342 if (read_bootblock_from_file(bootblock, bblock) != BC_SUCCESS) {
1343 (void) fprintf(stderr, gettext("Error reading %s\n"),
1344 bootblock);
1345 goto out_dev;
1346 }
1347
1348 /* only read EFI boot program if there is system partition */
1349 if (install_data.device.system.fd != -1) {
1350 if (read_bootblock_from_file(efiboot, eblock) != BC_SUCCESS) {
1351 (void) fprintf(stderr, gettext("Error reading %s\n"),
1352 efiboot);
1353 goto out_dev;
1354 }
1355 }
1356
1357 /*
1358 * is_update_necessary() will take care of checking if versioning and/or
1359 * forcing the update have been specified. It will also emit a warning
1360 * if a non-versioned update is attempted over a versioned bootblock.
1361 */
1362 if (!is_update_necessary(&install_data, update_str)) {
1363 (void) fprintf(stderr, gettext("bootblock version installed "
1364 "on %s is more recent or identical\n"
1365 "Use -F to override or install without the -u option\n"),
1366 device_path);
1367 ret = BC_NOUPDT;
1368 goto out_dev;
1369 }
1370
1371 BOOT_DEBUG("Ready to commit to disk\n");
1372 ret = commit_to_disk(&install_data, update_str);
1373
1374 out_dev:
1375 cleanup_device(&install_data.device);
1376 out:
1377 free(efiboot);
1378 free(stage1);
1379 free(bootblock);
1380 free(device_path);
1381 return (ret);
1382 }
1383
1384 /*
1385 * Retrieves from a device the extended information (einfo) associated to the
1386 * file or installed stage2.
1387 * Expects one parameter, the device path, in the form: /dev/rdsk/c?[t?]d?s0
1388 * or file name.
1389 * Returns:
1390 * - BC_SUCCESS (and prints out einfo contents depending on 'flags')
1391 * - BC_ERROR (on error)
1392 * - BC_NOEINFO (no extended information available)
1393 */
1394 static int
1395 handle_getinfo(char *progname, char **argv)
1396 {
1397 struct stat sb;
|