4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * This file contains the code to add new disk_type and partition
31 * definitions to a format data file.
42 #include <sys/fcntl.h>
43 #include <sys/param.h>
48 #include "add_definition.h"
50 #include "partition.h"
51 #include "menu_command.h"
54 extern struct ctlr_type ctlr_types
[];
59 /* Function prototypes */
62 static void add_disktype(FILE *fd
, struct disk_info
*disk_info
);
63 static void add_partition(FILE *fd
, struct disk_info
*,
64 struct partition_info
*);
65 static int add_entry(int col
, FILE *fd
, char *format
, ...);
69 static void add_disktype();
70 static void add_partition();
71 static int add_entry();
76 * Add new definitions for the current disk/partition to a format data file.
87 char deflt_str
[MAXPATHLEN
];
91 * There must be a current disk and partition table
93 if (cur_disk
== NULL
) {
94 err_print("No Current Disk.\n");
97 if (cur_dtype
== NULL
) {
98 err_print("Current disk type is not set.\n");
101 if (cur_parts
== NULL
) {
102 err_print("Current partition is not set.\n");
106 * If neither the disk definition nor the partition
107 * information has been changed, there's nothing to save.
109 if (cur_dtype
->dtype_filename
!= NULL
&&
110 cur_parts
->pinfo_filename
!= NULL
) {
112 Neither the disk type nor the partitioning has been changed.\n");
116 * If saving the partition, and it's unnamed, the user should name
119 if (cur_parts
->pinfo_name
== NULL
) {
120 assert(cur_parts
->pinfo_filename
== NULL
);
121 err_print("Please name this partition type before saving it\n");
125 * Let the user know what we're doing
127 if (cur_dtype
->dtype_filename
== NULL
&&
128 cur_parts
->pinfo_filename
== NULL
) {
129 fmt_print("Saving new disk and partition definitions\n");
130 } else if (cur_dtype
->dtype_filename
== NULL
) {
131 fmt_print("Saving new disk definition\n");
133 assert(cur_parts
->pinfo_filename
== NULL
);
134 fmt_print("Saving new partition definition\n");
137 * Ask for the file to which to append the new definitions
139 prompt
= "Enter file name";
140 (void) strcpy(x
.deflt_str
, "./format.dat");
141 filename
= (char *)(uintptr_t)input(FIO_OSTR
, prompt
,
142 ':', (u_ioparam_t
*)NULL
, &x
.xfoo
, DATA_INPUT
);
143 assert(filename
!= NULL
);
145 * Open the file in append mode, or create it, if necessary
147 if ((fd
= fopen(filename
, "a")) == NULL
) {
148 err_print("Cannot open `%s' - %s\n", filename
,
150 destroy_data(filename
);
154 * Write a header for the new definitions
156 if ((cur_dtype
->dtype_filename
== NULL
) &&
157 (cur_parts
->pinfo_filename
== NULL
)) {
158 (void) fprintf(fd
, "#\n# New disk/partition type ");
159 } else if (cur_dtype
->dtype_filename
== NULL
) {
160 (void) fprintf(fd
, "#\n# New disk type ");
162 (void) fprintf(fd
, "#\n# New partition type ");
165 (void) fprintf(fd
, " saved on %s#\n", ctime(&clock
));
167 * Save the new definitions
169 if (cur_dtype
->dtype_filename
== NULL
) {
170 add_disktype(fd
, cur_disk
);
172 if (cur_parts
->pinfo_filename
== NULL
) {
173 add_partition(fd
, cur_disk
, cur_parts
);
176 * We're finished. Clean up
179 destroy_data(filename
);
184 * Add a disk_type definition to the file fd
187 add_disktype(fd
, disk_info
)
189 struct disk_info
*disk_info
;
192 struct disk_type
*disk_type
;
194 disk_type
= disk_info
->disk_type
;
196 (void) fprintf(fd
, "disk_type = \"%s\" \\\n",
197 disk_type
->dtype_asciilabel
);
198 col
= add_entry(0, fd
, " : ctlr = %s",
199 ((disk_info
->disk_ctlr
)->ctlr_ctype
)->ctype_name
);
201 col
= add_entry(col
, fd
, " : ncyl = %d", disk_type
->dtype_ncyl
);
203 col
= add_entry(col
, fd
, " : acyl = %d", disk_type
->dtype_acyl
);
205 col
= add_entry(col
, fd
, " : pcyl = %d", disk_type
->dtype_pcyl
);
207 col
= add_entry(col
, fd
, " : nhead = %d", disk_type
->dtype_nhead
);
209 if (disk_type
->dtype_options
& SUP_PHEAD
) {
210 col
= add_entry(col
, fd
, " : phead = %d",
211 disk_type
->dtype_phead
);
214 col
= add_entry(col
, fd
, " : nsect = %d", disk_type
->dtype_nsect
);
216 if (disk_type
->dtype_options
& SUP_PSECT
) {
217 col
= add_entry(col
, fd
, " : psect = %d",
218 disk_type
->dtype_psect
);
221 if (disk_type
->dtype_options
& SUP_BPT
) {
222 col
= add_entry(col
, fd
, " : bpt = %d", disk_type
->dtype_bpt
);
225 col
= add_entry(col
, fd
, " : rpm = %d", disk_type
->dtype_rpm
);
227 if (disk_type
->dtype_options
& SUP_FMTTIME
) {
228 col
= add_entry(col
, fd
, " : fmt_time = %d",
229 disk_type
->dtype_fmt_time
);
232 if (disk_type
->dtype_options
& SUP_CYLSKEW
) {
233 col
= add_entry(col
, fd
, " : cyl_skew = %d",
234 disk_type
->dtype_cyl_skew
);
237 if (disk_type
->dtype_options
& SUP_TRKSKEW
) {
238 col
= add_entry(col
, fd
, " : trk_skew = %d",
239 disk_type
->dtype_trk_skew
);
242 if (disk_type
->dtype_options
& SUP_TRKS_ZONE
) {
243 col
= add_entry(col
, fd
, " : trks_zone = %d",
244 disk_type
->dtype_trks_zone
);
247 if (disk_type
->dtype_options
& SUP_ATRKS
) {
248 col
= add_entry(col
, fd
, " : atrks = %d",
249 disk_type
->dtype_atrks
);
252 if (disk_type
->dtype_options
& SUP_ASECT
) {
253 col
= add_entry(col
, fd
, " : asect = %d",
254 disk_type
->dtype_asect
);
257 if (disk_type
->dtype_options
& SUP_CACHE
) {
258 col
= add_entry(col
, fd
, " : cache = %d",
259 disk_type
->dtype_cache
);
262 if (disk_type
->dtype_options
& SUP_PREFETCH
) {
263 col
= add_entry(col
, fd
, " : prefetch = %d",
264 disk_type
->dtype_threshold
);
267 if (disk_type
->dtype_options
& SUP_CACHE_MIN
) {
268 col
= add_entry(col
, fd
, " : min_prefetch = %d",
269 disk_type
->dtype_prefetch_min
);
272 if (disk_type
->dtype_options
& SUP_CACHE_MAX
) {
273 col
= add_entry(col
, fd
, " : max_prefetch = %d",
274 disk_type
->dtype_prefetch_max
);
277 if (disk_type
->dtype_options
& SUP_BPS
) {
278 col
= add_entry(col
, fd
, " : bps = %d",
279 disk_type
->dtype_bps
);
282 if (disk_type
->dtype_options
& SUP_DRTYPE
) {
283 col
= add_entry(col
, fd
, " : drive_type = %d",
284 disk_type
->dtype_dr_type
);
288 * Terminate the last line, and print one blank line
290 (void) fprintf(fd
, col
== 0 ? "\n" : "\n\n");
296 * Once we exceed this length, wrap to a new line
298 #define MAX_COLUMNS 50
301 * Add a partition definition to the file fd
304 add_partition(fd
, disk_info
, part
)
306 struct disk_info
*disk_info
;
307 struct partition_info
*part
;
311 struct disk_type
*disk_type
;
315 #if defined(_SUNOS_VTOC_8)
318 #elif defined(_SUNOS_VTOC_16)
319 struct dkl_partition
*pv
;
322 #error No VTOC format defined.
323 #endif /* defined (_SUNOS_VTOC_8) */
326 disk_type
= disk_info
->disk_type
;
328 (void) fprintf(fd
, "partition = \"%s\" \\\n", part
->pinfo_name
);
329 (void) fprintf(fd
, "\t : disk = \"%s\" : ctlr = %s \\\n",
330 disk_type
->dtype_asciilabel
,
331 ((disk_info
->disk_ctlr
)->ctlr_ctype
)->ctype_name
);
334 * Print the specifications for each useful partition
337 pp
= part
->pinfo_map
;
338 pv
= part
->vtoc
.v_part
;
339 dv
= default_vtoc_map
;
340 for (i
= 0; i
< NDKMAP
; i
++, pp
++, pv
++, dv
++) {
341 if (pp
->dkl_nblk
!= 0) {
342 col
= add_entry(col
, fd
, " : %c = ",
344 if (pv
->p_tag
!= dv
->p_tag
||
345 pv
->p_flag
!= dv
->p_flag
) {
346 s
= find_string(ptag_choices
,
349 col
= add_entry(col
, fd
, " %s,", s
);
351 s
= find_string(pflag_choices
,
354 col
= add_entry(col
, fd
, " %s,", s
);
357 col
= add_entry(col
, fd
, " %d, %d", pp
->dkl_cylno
,
363 * Terminate the last line, and print one blank line
365 (void) fprintf(fd
, col
== 0 ? "\n" : "\n\n");
369 * Add an entry to the file fd. col is the current starting column.
370 * Return the resulting new column position.
374 add_entry(int col
, FILE *fd
, char *format
, ...)
377 va_start(ap
, format
);
379 if (col
> MAX_COLUMNS
) {
380 (void) fprintf(fd
, " \\\n");
384 col
+= fprintf(fd
, "\t");
386 col
+= vfprintf(fd
, format
, ap
);