235 bblock->buf = NULL;
236 return (BC_ERROR);
237 }
238
239 dest += BBLK_DATA_RSVD_SIZE;
240 size = bblock->buf_size - BBLK_DATA_RSVD_SIZE;
241
242 if (read_in(dev_fd, dest, size, BBLK_ZFS_EXTRA_OFF) != BC_SUCCESS) {
243 BOOT_DEBUG("Error reading ZFS reserved area the second time\n");
244 (void) free(bblock->buf);
245 bblock->buf = NULL;
246 return (BC_ERROR);
247 }
248
249 /* Update pointers. */
250 bblock->file = bblock->buf;
251 bblock->mboot_off = mboot_off;
252 bblock->mboot = (multiboot_header_t *)(bblock->buf + bblock->mboot_off
253 + BBLK_DATA_RSVD_SIZE);
254 bblock->extra = (char *)bblock->mboot + sizeof (multiboot_header_t);
255 return (BC_SUCCESS);
256 }
257
258 static boolean_t
259 is_update_necessary(ib_data_t *data, char *updt_str)
260 {
261 bblk_einfo_t *einfo;
262 bblk_hs_t bblock_hs;
263 ib_bootblock_t bblock_disk;
264 ib_bootblock_t *bblock_file = &data->bootblock;
265 ib_device_t *device = &data->device;
266 int dev_fd = device->fd;
267
268 assert(data != NULL);
269 assert(device->fd != -1);
270
271 /* Nothing to do if we are not updating a ZFS bootblock. */
272 if (!is_zfs(device->type))
273 return (B_TRUE);
274
275 bzero(&bblock_disk, sizeof (ib_bootblock_t));
276
277 if (read_bootblock_from_disk(dev_fd, &bblock_disk) != BC_SUCCESS) {
278 BOOT_DEBUG("Unable to read bootblock from %s\n", device->path);
279 return (B_TRUE);
280 }
281
282 einfo = find_einfo(bblock_disk.extra);
283 if (einfo == NULL) {
284 BOOT_DEBUG("No extended information available\n");
285 return (B_TRUE);
286 }
287
288 if (!do_version || updt_str == NULL) {
289 (void) fprintf(stdout, "WARNING: target device %s has a "
290 "versioned bootblock that is going to be overwritten by a "
291 "non versioned one\n", device->path);
292 return (B_TRUE);
293 }
294
295 if (force_update) {
296 BOOT_DEBUG("Forcing update of %s bootblock\n", device->path);
297 return (B_TRUE);
298 }
299
300 BOOT_DEBUG("Ready to check installed version vs %s\n", updt_str);
301
302 bblock_hs.src_buf = (unsigned char *)bblock_file->file;
699 goto out_dev;
700 }
701
702 ret = read_bootblock_from_disk(device->fd, bblock);
703 if (ret == BC_ERROR) {
704 (void) fprintf(stderr, gettext("Error reading bootblock from "
705 "%s\n"), device_path);
706 goto out_dev;
707 }
708
709 if (ret == BC_NOEXTRA) {
710 BOOT_DEBUG("No multiboot header found on %s, unable "
711 "to locate extra information area (old/non versioned "
712 "bootblock?) \n", device_path);
713 (void) fprintf(stderr, gettext("No extended information "
714 "found\n"));
715 retval = BC_NOEINFO;
716 goto out_dev;
717 }
718
719 einfo = find_einfo(bblock->extra);
720 if (einfo == NULL) {
721 retval = BC_NOEINFO;
722 (void) fprintf(stderr, gettext("No extended information "
723 "found\n"));
724 goto out_dev;
725 }
726
727 /* Print the extended information. */
728 if (strip)
729 flags |= EINFO_EASY_PARSE;
730 if (verbose_dump)
731 flags |= EINFO_PRINT_HEADER;
732
733 size = bblock->buf_size - P2ROUNDUP(bblock->file_size, 8) -
734 sizeof (multiboot_header_t);
735 print_einfo(flags, einfo, size);
736 retval = BC_SUCCESS;
737
738 out_dev:
739 cleanup_device(&data.device);
800 "information from %s (attaching device)\n"),
801 attach_device_path);
802 goto out_devs;
803 }
804
805 ret = read_bootblock_from_disk(curr_device->fd, bblock_curr);
806 if (ret == BC_ERROR) {
807 BOOT_DEBUG("Error reading bootblock from %s\n",
808 curr_device->path);
809 retval = BC_ERROR;
810 goto out_devs;
811 }
812
813 if (ret == BC_NOEXTRA) {
814 BOOT_DEBUG("No multiboot header found on %s, unable to retrieve"
815 " the bootblock\n", curr_device->path);
816 retval = BC_NOEXTRA;
817 goto out_devs;
818 }
819
820 einfo_curr = find_einfo(bblock_curr->extra);
821 if (einfo_curr != NULL)
822 updt_str = einfo_get_string(einfo_curr);
823
824 retval = propagate_bootblock(&curr_data, &attach_data, updt_str);
825 cleanup_bootblock(bblock_curr);
826 cleanup_bootblock(bblock_attach);
827 out_devs:
828 cleanup_device(attach_device);
829 out_currdev:
830 cleanup_device(curr_device);
831 out:
832 free(curr_device_path);
833 free(attach_device_path);
834 return (retval);
835 }
836
837 #define USAGE_STRING "Usage: %s [-h|-f|-F fstype|-u verstr] bootblk " \
838 "raw-device\n" \
839 "\t%s [-e|-V] -i -F zfs raw-device\n" \
840 "\t%s -M -F zfs raw-device attach-raw-device\n" \
|
235 bblock->buf = NULL;
236 return (BC_ERROR);
237 }
238
239 dest += BBLK_DATA_RSVD_SIZE;
240 size = bblock->buf_size - BBLK_DATA_RSVD_SIZE;
241
242 if (read_in(dev_fd, dest, size, BBLK_ZFS_EXTRA_OFF) != BC_SUCCESS) {
243 BOOT_DEBUG("Error reading ZFS reserved area the second time\n");
244 (void) free(bblock->buf);
245 bblock->buf = NULL;
246 return (BC_ERROR);
247 }
248
249 /* Update pointers. */
250 bblock->file = bblock->buf;
251 bblock->mboot_off = mboot_off;
252 bblock->mboot = (multiboot_header_t *)(bblock->buf + bblock->mboot_off
253 + BBLK_DATA_RSVD_SIZE);
254 bblock->extra = (char *)bblock->mboot + sizeof (multiboot_header_t);
255 bblock->extra_size = bblock->buf_size - bblock->mboot_off
256 - BBLK_DATA_RSVD_SIZE - sizeof (multiboot_header_t);
257 return (BC_SUCCESS);
258 }
259
260 static boolean_t
261 is_update_necessary(ib_data_t *data, char *updt_str)
262 {
263 bblk_einfo_t *einfo;
264 bblk_hs_t bblock_hs;
265 ib_bootblock_t bblock_disk;
266 ib_bootblock_t *bblock_file = &data->bootblock;
267 ib_device_t *device = &data->device;
268 int dev_fd = device->fd;
269
270 assert(data != NULL);
271 assert(device->fd != -1);
272
273 /* Nothing to do if we are not updating a ZFS bootblock. */
274 if (!is_zfs(device->type))
275 return (B_TRUE);
276
277 bzero(&bblock_disk, sizeof (ib_bootblock_t));
278
279 if (read_bootblock_from_disk(dev_fd, &bblock_disk) != BC_SUCCESS) {
280 BOOT_DEBUG("Unable to read bootblock from %s\n", device->path);
281 return (B_TRUE);
282 }
283
284 einfo = find_einfo(bblock_disk.extra, bblock_disk.extra_size);
285 if (einfo == NULL) {
286 BOOT_DEBUG("No extended information available\n");
287 return (B_TRUE);
288 }
289
290 if (!do_version || updt_str == NULL) {
291 (void) fprintf(stdout, "WARNING: target device %s has a "
292 "versioned bootblock that is going to be overwritten by a "
293 "non versioned one\n", device->path);
294 return (B_TRUE);
295 }
296
297 if (force_update) {
298 BOOT_DEBUG("Forcing update of %s bootblock\n", device->path);
299 return (B_TRUE);
300 }
301
302 BOOT_DEBUG("Ready to check installed version vs %s\n", updt_str);
303
304 bblock_hs.src_buf = (unsigned char *)bblock_file->file;
701 goto out_dev;
702 }
703
704 ret = read_bootblock_from_disk(device->fd, bblock);
705 if (ret == BC_ERROR) {
706 (void) fprintf(stderr, gettext("Error reading bootblock from "
707 "%s\n"), device_path);
708 goto out_dev;
709 }
710
711 if (ret == BC_NOEXTRA) {
712 BOOT_DEBUG("No multiboot header found on %s, unable "
713 "to locate extra information area (old/non versioned "
714 "bootblock?) \n", device_path);
715 (void) fprintf(stderr, gettext("No extended information "
716 "found\n"));
717 retval = BC_NOEINFO;
718 goto out_dev;
719 }
720
721 einfo = find_einfo(bblock->extra, bblock->extra_size);
722 if (einfo == NULL) {
723 retval = BC_NOEINFO;
724 (void) fprintf(stderr, gettext("No extended information "
725 "found\n"));
726 goto out_dev;
727 }
728
729 /* Print the extended information. */
730 if (strip)
731 flags |= EINFO_EASY_PARSE;
732 if (verbose_dump)
733 flags |= EINFO_PRINT_HEADER;
734
735 size = bblock->buf_size - P2ROUNDUP(bblock->file_size, 8) -
736 sizeof (multiboot_header_t);
737 print_einfo(flags, einfo, size);
738 retval = BC_SUCCESS;
739
740 out_dev:
741 cleanup_device(&data.device);
802 "information from %s (attaching device)\n"),
803 attach_device_path);
804 goto out_devs;
805 }
806
807 ret = read_bootblock_from_disk(curr_device->fd, bblock_curr);
808 if (ret == BC_ERROR) {
809 BOOT_DEBUG("Error reading bootblock from %s\n",
810 curr_device->path);
811 retval = BC_ERROR;
812 goto out_devs;
813 }
814
815 if (ret == BC_NOEXTRA) {
816 BOOT_DEBUG("No multiboot header found on %s, unable to retrieve"
817 " the bootblock\n", curr_device->path);
818 retval = BC_NOEXTRA;
819 goto out_devs;
820 }
821
822 einfo_curr = find_einfo(bblock_curr->extra, bblock_curr->extra_size);
823 if (einfo_curr != NULL)
824 updt_str = einfo_get_string(einfo_curr);
825
826 retval = propagate_bootblock(&curr_data, &attach_data, updt_str);
827 cleanup_bootblock(bblock_curr);
828 cleanup_bootblock(bblock_attach);
829 out_devs:
830 cleanup_device(attach_device);
831 out_currdev:
832 cleanup_device(curr_device);
833 out:
834 free(curr_device_path);
835 free(attach_device_path);
836 return (retval);
837 }
838
839 #define USAGE_STRING "Usage: %s [-h|-f|-F fstype|-u verstr] bootblk " \
840 "raw-device\n" \
841 "\t%s [-e|-V] -i -F zfs raw-device\n" \
842 "\t%s -M -F zfs raw-device attach-raw-device\n" \
|