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.
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.
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]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * I18N message number ranges
28 * This file: 6000 - 6499
29 * Shared common messages: 1 - 1999
40 #include <sys/param.h>
41 #include <sys/mnttab.h>
42 #include <sys/types.h>
44 #include <sys/openpromio.h>
54 * 128 is the size of the largest (currently) property name
55 * 8192 - MAXPROPSIZE - sizeof (int) is the size of the largest
56 * (currently) property value, viz. nvramrc.
57 * the sizeof(uint_t) is from struct openpromio
59 #define MAXPROPSIZE 128
60 #define MAXVALSIZE (8192 - MAXPROPSIZE - sizeof (uint_t))
62 #define BOOTDEV_PROP_NAME "boot-device"
64 static int getbootdevname(char *, char *);
65 static int setprom(unsigned, unsigned, char *);
66 extern int devfs_dev_to_prom_name(char *, char *);
69 * Call getbootdevname() to get the absolute pathname of boot device
70 * and call setprom() to set the boot-device variable.
73 setboot(unsigned int yes
, unsigned int verbose
, char *fname
)
75 char bdev
[MAXPATHLEN
];
77 if (!getbootdevname(fname
, bdev
)) {
78 (void) fprintf(stderr
, MSGSTR(6000,
79 "Cannot determine device name for %s\n"),
84 return (setprom(yes
, verbose
, bdev
));
88 * Read the mnttab and resolve the special device of the fs we are
89 * interested in, into an absolute pathname
92 getbootdevname(char *bootfs
, char *bdev
)
104 if (stat(bootfs
, &sbuf
) < 0) {
105 perror(MSGSTR(6001, "stat"));
109 switch (sbuf
.st_mode
& S_IFMT
) {
119 f
= fopen(fname
, "r");
125 while (getmntent(f
, &m
) == 0) {
126 if (strcmp(m
.mnt_mountp
, bootfs
))
139 devname
= m
.mnt_special
;
142 if (devfs_dev_to_prom_name(devname
, bdev
) != 0) {
151 * setprom() - use /dev/openprom to read the "boot_device" variable and set
152 * it to the new value.
155 setprom(unsigned yes
, unsigned verbose
, char *bdev
)
157 struct openpromio
*pio
;
159 char save_bootdev
[MAXVALSIZE
];
161 if ((fd
= open("/dev/openprom", O_RDWR
)) < 0) {
162 perror(MSGSTR(6002, "Could not open openprom dev"));
166 pio
= (struct openpromio
*)malloc(sizeof (struct openpromio
) +
167 MAXVALSIZE
+ MAXPROPSIZE
);
170 perror(MSGSTR(6003, " Error: Unable to allocate memory."));
174 pio
->oprom_size
= MAXVALSIZE
;
175 (void) strcpy(pio
->oprom_array
, BOOTDEV_PROP_NAME
);
177 if (ioctl(fd
, OPROMGETOPT
, pio
) < 0) {
178 perror(MSGSTR(6004, "openprom getopt ioctl"));
183 * save the existing boot-device, so we can use it if setting
184 * to new value fails.
186 (void) strcpy(save_bootdev
, pio
->oprom_array
);
189 (void) fprintf(stdout
,
191 "Current boot-device = %s\n"), pio
->oprom_array
);
192 (void) fprintf(stdout
, MSGSTR(6006,
193 "New boot-device = %s\n"), bdev
);
197 (void) fprintf(stdout
, MSGSTR(6007,
198 "Do you want to change boot-device "
199 "to the new setting? (y/n) "));
209 /* set the new value for boot-device */
211 pio
->oprom_size
= (int)strlen(BOOTDEV_PROP_NAME
) + 1 +
214 (void) strcpy(pio
->oprom_array
, BOOTDEV_PROP_NAME
);
215 (void) strcpy(pio
->oprom_array
+ (int)strlen(BOOTDEV_PROP_NAME
) + 1,
218 if (ioctl(fd
, OPROMSETOPT
, pio
) < 0) {
219 perror(MSGSTR(6008, "openprom setopt ioctl"));
223 /* read back the value that was set */
225 pio
->oprom_size
= MAXVALSIZE
;
226 (void) strcpy(pio
->oprom_array
, BOOTDEV_PROP_NAME
);
228 if (ioctl(fd
, OPROMGETOPT
, pio
) < 0) {
229 perror(MSGSTR(6009, "openprom getopt ioctl"));
233 if (strcmp(bdev
, pio
->oprom_array
)) {
235 /* could not set the new device name, set the old one back */
238 "Could not set boot-device, reverting to old value"));
239 pio
->oprom_size
= (int)strlen(BOOTDEV_PROP_NAME
) + 1 +
240 (int)strlen(save_bootdev
);
242 (void) strcpy(pio
->oprom_array
, BOOTDEV_PROP_NAME
);
243 (void) strcpy(pio
->oprom_array
+
244 (int)strlen(BOOTDEV_PROP_NAME
) + 1,
247 if (ioctl(fd
, OPROMSETOPT
, pio
) < 0) {
248 perror(MSGSTR(6011, "openprom setopt ioctl"));