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 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <stdio.h> 27 #include <sys/types.h> 28 #include <string.h> 29 #include <fcntl.h> 30 #include <libgen.h> 31 #include <stdlib.h> 32 #include <strings.h> 33 #include <unistd.h> 34 #include <sys/dktp/fdisk.h> 35 36 #define SECTOR_SIZE 512 37 static char boot_sect[SECTOR_SIZE]; 38 static char new_mboot[SECTOR_SIZE]; 39 40 static void 41 usage(char *progname) 42 { 43 fprintf(stderr, "Usage: %s [ -d | -n | -o | -r ] <device> [<mboot>]\n", 44 basename(progname)); 45 fprintf(stderr, "\t-n Set new Solaris partition magic 0xbf\n"); 46 fprintf(stderr, "\t-o Set old Solaris partition magic 0x82\n"); 47 fprintf(stderr, "\t-r Replace master boot program " 48 "(/usr/lib/fs/ufs/mboot)\n"); 49 exit(-1); 50 } 51 52 int 53 main(int argc, char *argv[]) 54 { 55 int c, fd, i, sol_part = -1; 56 int setold = 0, setnew = 0, write_mboot = 0, list_hd = 0; 57 char *device; 58 struct mboot *mboot; 59 char *mboot_file = "/usr/lib/fs/ufs/mboot"; 60 61 while ((c = getopt(argc, argv, "dnor")) != EOF) { 62 switch (c) { 63 case 'd': 64 list_hd = 1; 65 continue; 66 case 'n': 67 setnew = 1; 68 continue; 69 case 'o': 70 setold = 1; 71 continue; 72 case 'r': 73 write_mboot = 1; 74 continue; 75 default: 76 usage(argv[0]); 77 } 78 } 79 80 /* check arguments */ 81 if ((setnew && setold) || argc < optind + 1) { 82 usage(argv[0]); 83 } 84 85 if (write_mboot && argc > optind + 1) { 86 mboot_file = strdup(argv[optind + 1]); 87 } 88 if (!mboot_file) { 89 usage(argv[0]); 90 } 91 fd = open(mboot_file, O_RDONLY); 92 if (fd == -1 || read(fd, new_mboot, SECTOR_SIZE) != SECTOR_SIZE) { 93 fprintf(stderr, "cannot read file %s\n", mboot_file); 94 if (fd == -1) 95 perror("open"); 96 else 97 perror("read"); 98 exit(-1); 99 } 100 close(fd); 101 102 device = strdup(argv[optind]); 103 if (!device) { 104 usage(argv[0]); 105 } 106 fd = open(device, O_RDWR); 107 if (fd == -1 || read(fd, boot_sect, SECTOR_SIZE) != SECTOR_SIZE) { 108 fprintf(stderr, "cannot read MBR on %s\n", device); 109 if (fd == -1) 110 perror("open"); 111 else 112 perror("read"); 113 exit(-1); 114 } 115 116 mboot = (struct mboot *)boot_sect; 117 for (i = 0; i < FD_NUMPART; i++) { 118 struct ipart *part = (struct ipart *)mboot->parts + i; 119 if (!list_hd) 120 if (part->bootid == 128) 121 printf("active "); 122 else 123 printf(" "); 124 if (setnew && part->systid == 0x82) { 125 part->systid = 0xbf; 126 sol_part = i; 127 } else if (setold && part->systid == 0xbf) { 128 part->systid = 0x82; 129 sol_part = i; 130 } else if (list_hd && 131 (part->systid == 0x82 || part->systid == 0xbf)) { 132 sol_part = i; 133 } 134 if (!list_hd) 135 printf("%d (0x%2x): start_sect %u, size_sect %u\n", 136 i + 1, part->systid, part->relsect, part->numsect); 137 } 138 139 if (list_hd) { 140 printf("(hd0,%d,a)\n", sol_part); 141 (void) close(fd); 142 return (0); 143 } 144 145 /* write new mboot */ 146 if (write_mboot || sol_part != -1) { 147 if (write_mboot) { 148 /* copy over the new boot program */ 149 bcopy((void *)new_mboot, (void *)boot_sect, BOOTSZ); 150 } 151 152 if ((lseek(fd, 0, SEEK_SET) < 0) || 153 (write(fd, (void *)boot_sect, SECTOR_SIZE) < 0)) { 154 perror("failed to update MBR"); 155 exit(-1); 156 } 157 if (sol_part != -1) { 158 printf("Changed solaris partition %d", sol_part + 1); 159 if (setnew) 160 printf("from 0x82 to 0xbf\n"); 161 else 162 printf("from 0xbf to 0x82\n"); 163 } 164 if (write_mboot) { 165 printf("Replaced mboot program with %s\n", mboot_file); 166 } 167 } 168 169 (void) close(fd); 170 return (0); 171 } 172