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;
 
 |