17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*342440ecSPrasad Singamsetty * Common Development and Distribution License (the "License").
6*342440ecSPrasad Singamsetty * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22*342440ecSPrasad Singamsetty * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <stdio.h>
277c478bd9Sstevel@tonic-gate #include <sys/types.h>
287c478bd9Sstevel@tonic-gate #include <string.h>
297c478bd9Sstevel@tonic-gate #include <fcntl.h>
307c478bd9Sstevel@tonic-gate #include <libgen.h>
317c478bd9Sstevel@tonic-gate #include <stdlib.h>
327c478bd9Sstevel@tonic-gate #include <strings.h>
337c478bd9Sstevel@tonic-gate #include <unistd.h>
347c478bd9Sstevel@tonic-gate #include <sys/dktp/fdisk.h>
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate #define SECTOR_SIZE 512
377c478bd9Sstevel@tonic-gate static char boot_sect[SECTOR_SIZE];
387c478bd9Sstevel@tonic-gate static char new_mboot[SECTOR_SIZE];
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate static void
usage(char * progname)417c478bd9Sstevel@tonic-gate usage(char *progname)
427c478bd9Sstevel@tonic-gate {
437c478bd9Sstevel@tonic-gate fprintf(stderr, "Usage: %s [ -d | -n | -o | -r ] <device> [<mboot>]\n",
447c478bd9Sstevel@tonic-gate basename(progname));
457c478bd9Sstevel@tonic-gate fprintf(stderr, "\t-n Set new Solaris partition magic 0xbf\n");
467c478bd9Sstevel@tonic-gate fprintf(stderr, "\t-o Set old Solaris partition magic 0x82\n");
477c478bd9Sstevel@tonic-gate fprintf(stderr, "\t-r Replace master boot program "
487c478bd9Sstevel@tonic-gate "(/usr/lib/fs/ufs/mboot)\n");
497c478bd9Sstevel@tonic-gate exit(-1);
507c478bd9Sstevel@tonic-gate }
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate int
main(int argc,char * argv[])537c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
547c478bd9Sstevel@tonic-gate {
557c478bd9Sstevel@tonic-gate int c, fd, i, sol_part = -1;
567c478bd9Sstevel@tonic-gate int setold = 0, setnew = 0, write_mboot = 0, list_hd = 0;
577c478bd9Sstevel@tonic-gate char *device;
587c478bd9Sstevel@tonic-gate struct mboot *mboot;
597c478bd9Sstevel@tonic-gate char *mboot_file = "/usr/lib/fs/ufs/mboot";
607c478bd9Sstevel@tonic-gate
617c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "dnor")) != EOF) {
627c478bd9Sstevel@tonic-gate switch (c) {
637c478bd9Sstevel@tonic-gate case 'd':
647c478bd9Sstevel@tonic-gate list_hd = 1;
657c478bd9Sstevel@tonic-gate continue;
667c478bd9Sstevel@tonic-gate case 'n':
677c478bd9Sstevel@tonic-gate setnew = 1;
687c478bd9Sstevel@tonic-gate continue;
697c478bd9Sstevel@tonic-gate case 'o':
707c478bd9Sstevel@tonic-gate setold = 1;
717c478bd9Sstevel@tonic-gate continue;
727c478bd9Sstevel@tonic-gate case 'r':
737c478bd9Sstevel@tonic-gate write_mboot = 1;
747c478bd9Sstevel@tonic-gate continue;
757c478bd9Sstevel@tonic-gate default:
767c478bd9Sstevel@tonic-gate usage(argv[0]);
777c478bd9Sstevel@tonic-gate }
787c478bd9Sstevel@tonic-gate }
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate /* check arguments */
817c478bd9Sstevel@tonic-gate if ((setnew && setold) || argc < optind + 1) {
827c478bd9Sstevel@tonic-gate usage(argv[0]);
837c478bd9Sstevel@tonic-gate }
847c478bd9Sstevel@tonic-gate
857c478bd9Sstevel@tonic-gate if (write_mboot && argc > optind + 1) {
867c478bd9Sstevel@tonic-gate mboot_file = strdup(argv[optind + 1]);
877c478bd9Sstevel@tonic-gate }
887c478bd9Sstevel@tonic-gate if (!mboot_file) {
897c478bd9Sstevel@tonic-gate usage(argv[0]);
907c478bd9Sstevel@tonic-gate }
917c478bd9Sstevel@tonic-gate fd = open(mboot_file, O_RDONLY);
927c478bd9Sstevel@tonic-gate if (fd == -1 || read(fd, new_mboot, SECTOR_SIZE) != SECTOR_SIZE) {
937c478bd9Sstevel@tonic-gate fprintf(stderr, "cannot read file %s\n", mboot_file);
947c478bd9Sstevel@tonic-gate if (fd == -1)
957c478bd9Sstevel@tonic-gate perror("open");
967c478bd9Sstevel@tonic-gate else
977c478bd9Sstevel@tonic-gate perror("read");
987c478bd9Sstevel@tonic-gate exit(-1);
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate close(fd);
1017c478bd9Sstevel@tonic-gate
1027c478bd9Sstevel@tonic-gate device = strdup(argv[optind]);
1037c478bd9Sstevel@tonic-gate if (!device) {
1047c478bd9Sstevel@tonic-gate usage(argv[0]);
1057c478bd9Sstevel@tonic-gate }
1067c478bd9Sstevel@tonic-gate fd = open(device, O_RDWR);
1077c478bd9Sstevel@tonic-gate if (fd == -1 || read(fd, boot_sect, SECTOR_SIZE) != SECTOR_SIZE) {
1087c478bd9Sstevel@tonic-gate fprintf(stderr, "cannot read MBR on %s\n", device);
1097c478bd9Sstevel@tonic-gate if (fd == -1)
1107c478bd9Sstevel@tonic-gate perror("open");
1117c478bd9Sstevel@tonic-gate else
1127c478bd9Sstevel@tonic-gate perror("read");
1137c478bd9Sstevel@tonic-gate exit(-1);
1147c478bd9Sstevel@tonic-gate }
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate mboot = (struct mboot *)boot_sect;
1177c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) {
1187c478bd9Sstevel@tonic-gate struct ipart *part = (struct ipart *)mboot->parts + i;
1197c478bd9Sstevel@tonic-gate if (!list_hd)
1207c478bd9Sstevel@tonic-gate if (part->bootid == 128)
1217c478bd9Sstevel@tonic-gate printf("active ");
1227c478bd9Sstevel@tonic-gate else
1237c478bd9Sstevel@tonic-gate printf(" ");
1247c478bd9Sstevel@tonic-gate if (setnew && part->systid == 0x82) {
1257c478bd9Sstevel@tonic-gate part->systid = 0xbf;
1267c478bd9Sstevel@tonic-gate sol_part = i;
1277c478bd9Sstevel@tonic-gate } else if (setold && part->systid == 0xbf) {
1287c478bd9Sstevel@tonic-gate part->systid = 0x82;
1297c478bd9Sstevel@tonic-gate sol_part = i;
1307c478bd9Sstevel@tonic-gate } else if (list_hd &&
1317c478bd9Sstevel@tonic-gate (part->systid == 0x82 || part->systid == 0xbf)) {
1327c478bd9Sstevel@tonic-gate sol_part = i;
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate if (!list_hd)
135*342440ecSPrasad Singamsetty printf("%d (0x%2x): start_sect %u, size_sect %u\n",
1367c478bd9Sstevel@tonic-gate i + 1, part->systid, part->relsect, part->numsect);
1377c478bd9Sstevel@tonic-gate }
1387c478bd9Sstevel@tonic-gate
1397c478bd9Sstevel@tonic-gate if (list_hd) {
1407c478bd9Sstevel@tonic-gate printf("(hd0,%d,a)\n", sol_part);
1417c478bd9Sstevel@tonic-gate (void) close(fd);
1427c478bd9Sstevel@tonic-gate return (0);
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate
1457c478bd9Sstevel@tonic-gate /* write new mboot */
1467c478bd9Sstevel@tonic-gate if (write_mboot || sol_part != -1) {
1477c478bd9Sstevel@tonic-gate if (write_mboot) {
1487c478bd9Sstevel@tonic-gate /* copy over the new boot program */
1497c478bd9Sstevel@tonic-gate bcopy((void *)new_mboot, (void *)boot_sect, BOOTSZ);
1507c478bd9Sstevel@tonic-gate }
1517c478bd9Sstevel@tonic-gate
1527c478bd9Sstevel@tonic-gate if ((lseek(fd, 0, SEEK_SET) < 0) ||
1537c478bd9Sstevel@tonic-gate (write(fd, (void *)boot_sect, SECTOR_SIZE) < 0)) {
1547c478bd9Sstevel@tonic-gate perror("failed to update MBR");
1557c478bd9Sstevel@tonic-gate exit(-1);
1567c478bd9Sstevel@tonic-gate }
1577c478bd9Sstevel@tonic-gate if (sol_part != -1) {
1587c478bd9Sstevel@tonic-gate printf("Changed solaris partition %d", sol_part + 1);
1597c478bd9Sstevel@tonic-gate if (setnew)
1607c478bd9Sstevel@tonic-gate printf("from 0x82 to 0xbf\n");
1617c478bd9Sstevel@tonic-gate else
1627c478bd9Sstevel@tonic-gate printf("from 0xbf to 0x82\n");
1637c478bd9Sstevel@tonic-gate }
1647c478bd9Sstevel@tonic-gate if (write_mboot) {
1657c478bd9Sstevel@tonic-gate printf("Replaced mboot program with %s\n", mboot_file);
1667c478bd9Sstevel@tonic-gate }
1677c478bd9Sstevel@tonic-gate }
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate (void) close(fd);
1707c478bd9Sstevel@tonic-gate return (0);
1717c478bd9Sstevel@tonic-gate }
172