1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte /* 22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*fcf3ce44SJohn Forte * Use is subject to license terms. 24*fcf3ce44SJohn Forte */ 25*fcf3ce44SJohn Forte 26*fcf3ce44SJohn Forte /* 27*fcf3ce44SJohn Forte * I18N message number ranges 28*fcf3ce44SJohn Forte * This file: 6000 - 6499 29*fcf3ce44SJohn Forte * Shared common messages: 1 - 1999 30*fcf3ce44SJohn Forte */ 31*fcf3ce44SJohn Forte 32*fcf3ce44SJohn Forte 33*fcf3ce44SJohn Forte 34*fcf3ce44SJohn Forte #include <stdio.h> 35*fcf3ce44SJohn Forte #include <unistd.h> 36*fcf3ce44SJohn Forte #include <stdlib.h> 37*fcf3ce44SJohn Forte #include <string.h> 38*fcf3ce44SJohn Forte #include <fcntl.h> 39*fcf3ce44SJohn Forte #include <errno.h> 40*fcf3ce44SJohn Forte #include <sys/param.h> 41*fcf3ce44SJohn Forte #include <sys/mnttab.h> 42*fcf3ce44SJohn Forte #include <sys/types.h> 43*fcf3ce44SJohn Forte #include <sys/stat.h> 44*fcf3ce44SJohn Forte #include <sys/openpromio.h> 45*fcf3ce44SJohn Forte 46*fcf3ce44SJohn Forte 47*fcf3ce44SJohn Forte /* 48*fcf3ce44SJohn Forte * For i18n 49*fcf3ce44SJohn Forte */ 50*fcf3ce44SJohn Forte #include <stgcom.h> 51*fcf3ce44SJohn Forte 52*fcf3ce44SJohn Forte 53*fcf3ce44SJohn Forte /* 54*fcf3ce44SJohn Forte * 128 is the size of the largest (currently) property name 55*fcf3ce44SJohn Forte * 8192 - MAXPROPSIZE - sizeof (int) is the size of the largest 56*fcf3ce44SJohn Forte * (currently) property value, viz. nvramrc. 57*fcf3ce44SJohn Forte * the sizeof(uint_t) is from struct openpromio 58*fcf3ce44SJohn Forte */ 59*fcf3ce44SJohn Forte #define MAXPROPSIZE 128 60*fcf3ce44SJohn Forte #define MAXVALSIZE (8192 - MAXPROPSIZE - sizeof (uint_t)) 61*fcf3ce44SJohn Forte 62*fcf3ce44SJohn Forte #define BOOTDEV_PROP_NAME "boot-device" 63*fcf3ce44SJohn Forte 64*fcf3ce44SJohn Forte static int getbootdevname(char *, char *); 65*fcf3ce44SJohn Forte static int setprom(unsigned, unsigned, char *); 66*fcf3ce44SJohn Forte extern int devfs_dev_to_prom_name(char *, char *); 67*fcf3ce44SJohn Forte 68*fcf3ce44SJohn Forte /* 69*fcf3ce44SJohn Forte * Call getbootdevname() to get the absolute pathname of boot device 70*fcf3ce44SJohn Forte * and call setprom() to set the boot-device variable. 71*fcf3ce44SJohn Forte */ 72*fcf3ce44SJohn Forte int 73*fcf3ce44SJohn Forte setboot(unsigned int yes, unsigned int verbose, char *fname) 74*fcf3ce44SJohn Forte { 75*fcf3ce44SJohn Forte char bdev[MAXPATHLEN]; 76*fcf3ce44SJohn Forte 77*fcf3ce44SJohn Forte if (!getbootdevname(fname, bdev)) { 78*fcf3ce44SJohn Forte (void) fprintf(stderr, MSGSTR(6000, 79*fcf3ce44SJohn Forte "Cannot determine device name for %s\n"), 80*fcf3ce44SJohn Forte fname); 81*fcf3ce44SJohn Forte return (errno); 82*fcf3ce44SJohn Forte } 83*fcf3ce44SJohn Forte 84*fcf3ce44SJohn Forte return (setprom(yes, verbose, bdev)); 85*fcf3ce44SJohn Forte } 86*fcf3ce44SJohn Forte 87*fcf3ce44SJohn Forte /* 88*fcf3ce44SJohn Forte * Read the mnttab and resolve the special device of the fs we are 89*fcf3ce44SJohn Forte * interested in, into an absolute pathname 90*fcf3ce44SJohn Forte */ 91*fcf3ce44SJohn Forte static int 92*fcf3ce44SJohn Forte getbootdevname(char *bootfs, char *bdev) 93*fcf3ce44SJohn Forte { 94*fcf3ce44SJohn Forte FILE *f; 95*fcf3ce44SJohn Forte char *fname; 96*fcf3ce44SJohn Forte char *devname; 97*fcf3ce44SJohn Forte struct mnttab m; 98*fcf3ce44SJohn Forte struct stat sbuf; 99*fcf3ce44SJohn Forte int mountpt = 0; 100*fcf3ce44SJohn Forte int found = 0; 101*fcf3ce44SJohn Forte 102*fcf3ce44SJohn Forte devname = bootfs; 103*fcf3ce44SJohn Forte 104*fcf3ce44SJohn Forte if (stat(bootfs, &sbuf) < 0) { 105*fcf3ce44SJohn Forte perror(MSGSTR(6001, "stat")); 106*fcf3ce44SJohn Forte return (0); 107*fcf3ce44SJohn Forte } 108*fcf3ce44SJohn Forte 109*fcf3ce44SJohn Forte switch (sbuf.st_mode & S_IFMT) { 110*fcf3ce44SJohn Forte case S_IFBLK: 111*fcf3ce44SJohn Forte break; 112*fcf3ce44SJohn Forte default: 113*fcf3ce44SJohn Forte mountpt = 1; 114*fcf3ce44SJohn Forte break; 115*fcf3ce44SJohn Forte } 116*fcf3ce44SJohn Forte 117*fcf3ce44SJohn Forte if (mountpt) { 118*fcf3ce44SJohn Forte fname = MNTTAB; 119*fcf3ce44SJohn Forte f = fopen(fname, "r"); 120*fcf3ce44SJohn Forte if (f == NULL) { 121*fcf3ce44SJohn Forte perror(fname); 122*fcf3ce44SJohn Forte return (0); 123*fcf3ce44SJohn Forte } 124*fcf3ce44SJohn Forte 125*fcf3ce44SJohn Forte while (getmntent(f, &m) == 0) { 126*fcf3ce44SJohn Forte if (strcmp(m.mnt_mountp, bootfs)) 127*fcf3ce44SJohn Forte continue; 128*fcf3ce44SJohn Forte else { 129*fcf3ce44SJohn Forte found = 1; 130*fcf3ce44SJohn Forte break; 131*fcf3ce44SJohn Forte } 132*fcf3ce44SJohn Forte } 133*fcf3ce44SJohn Forte 134*fcf3ce44SJohn Forte (void) fclose(f); 135*fcf3ce44SJohn Forte 136*fcf3ce44SJohn Forte if (!found) { 137*fcf3ce44SJohn Forte return (0); 138*fcf3ce44SJohn Forte } 139*fcf3ce44SJohn Forte devname = m.mnt_special; 140*fcf3ce44SJohn Forte } 141*fcf3ce44SJohn Forte 142*fcf3ce44SJohn Forte if (devfs_dev_to_prom_name(devname, bdev) != 0) { 143*fcf3ce44SJohn Forte perror(devname); 144*fcf3ce44SJohn Forte return (0); 145*fcf3ce44SJohn Forte } 146*fcf3ce44SJohn Forte 147*fcf3ce44SJohn Forte return (1); 148*fcf3ce44SJohn Forte } 149*fcf3ce44SJohn Forte 150*fcf3ce44SJohn Forte /* 151*fcf3ce44SJohn Forte * setprom() - use /dev/openprom to read the "boot_device" variable and set 152*fcf3ce44SJohn Forte * it to the new value. 153*fcf3ce44SJohn Forte */ 154*fcf3ce44SJohn Forte static int 155*fcf3ce44SJohn Forte setprom(unsigned yes, unsigned verbose, char *bdev) 156*fcf3ce44SJohn Forte { 157*fcf3ce44SJohn Forte struct openpromio *pio; 158*fcf3ce44SJohn Forte int fd; 159*fcf3ce44SJohn Forte char save_bootdev[MAXVALSIZE]; 160*fcf3ce44SJohn Forte 161*fcf3ce44SJohn Forte if ((fd = open("/dev/openprom", O_RDWR)) < 0) { 162*fcf3ce44SJohn Forte perror(MSGSTR(6002, "Could not open openprom dev")); 163*fcf3ce44SJohn Forte return (errno); 164*fcf3ce44SJohn Forte } 165*fcf3ce44SJohn Forte 166*fcf3ce44SJohn Forte pio = (struct openpromio *)malloc(sizeof (struct openpromio) + 167*fcf3ce44SJohn Forte MAXVALSIZE + MAXPROPSIZE); 168*fcf3ce44SJohn Forte 169*fcf3ce44SJohn Forte if (pio == (struct openpromio *)NULL) { 170*fcf3ce44SJohn Forte perror(MSGSTR(6003, " Error: Unable to allocate memory.")); 171*fcf3ce44SJohn Forte return (errno); 172*fcf3ce44SJohn Forte } 173*fcf3ce44SJohn Forte 174*fcf3ce44SJohn Forte pio->oprom_size = MAXVALSIZE; 175*fcf3ce44SJohn Forte (void) strcpy(pio->oprom_array, BOOTDEV_PROP_NAME); 176*fcf3ce44SJohn Forte 177*fcf3ce44SJohn Forte if (ioctl(fd, OPROMGETOPT, pio) < 0) { 178*fcf3ce44SJohn Forte perror(MSGSTR(6004, "openprom getopt ioctl")); 179*fcf3ce44SJohn Forte return (errno); 180*fcf3ce44SJohn Forte } 181*fcf3ce44SJohn Forte 182*fcf3ce44SJohn Forte /* 183*fcf3ce44SJohn Forte * save the existing boot-device, so we can use it if setting 184*fcf3ce44SJohn Forte * to new value fails. 185*fcf3ce44SJohn Forte */ 186*fcf3ce44SJohn Forte (void) strcpy(save_bootdev, pio->oprom_array); 187*fcf3ce44SJohn Forte 188*fcf3ce44SJohn Forte if (verbose) { 189*fcf3ce44SJohn Forte (void) fprintf(stdout, 190*fcf3ce44SJohn Forte MSGSTR(6005, 191*fcf3ce44SJohn Forte "Current boot-device = %s\n"), pio->oprom_array); 192*fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(6006, 193*fcf3ce44SJohn Forte "New boot-device = %s\n"), bdev); 194*fcf3ce44SJohn Forte } 195*fcf3ce44SJohn Forte 196*fcf3ce44SJohn Forte if (!yes) { 197*fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(6007, 198*fcf3ce44SJohn Forte "Do you want to change boot-device " 199*fcf3ce44SJohn Forte "to the new setting? (y/n) ")); 200*fcf3ce44SJohn Forte switch (getchar()) { 201*fcf3ce44SJohn Forte case 'Y': 202*fcf3ce44SJohn Forte case 'y': 203*fcf3ce44SJohn Forte break; 204*fcf3ce44SJohn Forte default: 205*fcf3ce44SJohn Forte return (0); 206*fcf3ce44SJohn Forte } 207*fcf3ce44SJohn Forte } 208*fcf3ce44SJohn Forte 209*fcf3ce44SJohn Forte /* set the new value for boot-device */ 210*fcf3ce44SJohn Forte 211*fcf3ce44SJohn Forte pio->oprom_size = (int)strlen(BOOTDEV_PROP_NAME) + 1 + 212*fcf3ce44SJohn Forte (int)strlen(bdev); 213*fcf3ce44SJohn Forte 214*fcf3ce44SJohn Forte (void) strcpy(pio->oprom_array, BOOTDEV_PROP_NAME); 215*fcf3ce44SJohn Forte (void) strcpy(pio->oprom_array + (int)strlen(BOOTDEV_PROP_NAME) + 1, 216*fcf3ce44SJohn Forte bdev); 217*fcf3ce44SJohn Forte 218*fcf3ce44SJohn Forte if (ioctl(fd, OPROMSETOPT, pio) < 0) { 219*fcf3ce44SJohn Forte perror(MSGSTR(6008, "openprom setopt ioctl")); 220*fcf3ce44SJohn Forte return (errno); 221*fcf3ce44SJohn Forte } 222*fcf3ce44SJohn Forte 223*fcf3ce44SJohn Forte /* read back the value that was set */ 224*fcf3ce44SJohn Forte 225*fcf3ce44SJohn Forte pio->oprom_size = MAXVALSIZE; 226*fcf3ce44SJohn Forte (void) strcpy(pio->oprom_array, BOOTDEV_PROP_NAME); 227*fcf3ce44SJohn Forte 228*fcf3ce44SJohn Forte if (ioctl(fd, OPROMGETOPT, pio) < 0) { 229*fcf3ce44SJohn Forte perror(MSGSTR(6009, "openprom getopt ioctl")); 230*fcf3ce44SJohn Forte return (errno); 231*fcf3ce44SJohn Forte } 232*fcf3ce44SJohn Forte 233*fcf3ce44SJohn Forte if (strcmp(bdev, pio->oprom_array)) { 234*fcf3ce44SJohn Forte 235*fcf3ce44SJohn Forte /* could not set the new device name, set the old one back */ 236*fcf3ce44SJohn Forte 237*fcf3ce44SJohn Forte perror(MSGSTR(6010, 238*fcf3ce44SJohn Forte "Could not set boot-device, reverting to old value")); 239*fcf3ce44SJohn Forte pio->oprom_size = (int)strlen(BOOTDEV_PROP_NAME) + 1 + 240*fcf3ce44SJohn Forte (int)strlen(save_bootdev); 241*fcf3ce44SJohn Forte 242*fcf3ce44SJohn Forte (void) strcpy(pio->oprom_array, BOOTDEV_PROP_NAME); 243*fcf3ce44SJohn Forte (void) strcpy(pio->oprom_array + 244*fcf3ce44SJohn Forte (int)strlen(BOOTDEV_PROP_NAME) + 1, 245*fcf3ce44SJohn Forte save_bootdev); 246*fcf3ce44SJohn Forte 247*fcf3ce44SJohn Forte if (ioctl(fd, OPROMSETOPT, pio) < 0) { 248*fcf3ce44SJohn Forte perror(MSGSTR(6011, "openprom setopt ioctl")); 249*fcf3ce44SJohn Forte return (errno); 250*fcf3ce44SJohn Forte } 251*fcf3ce44SJohn Forte 252*fcf3ce44SJohn Forte } 253*fcf3ce44SJohn Forte 254*fcf3ce44SJohn Forte (void) close(fd); 255*fcf3ce44SJohn Forte 256*fcf3ce44SJohn Forte return (0); 257*fcf3ce44SJohn Forte } 258