1 DKIO(7I) Ioctl Requests DKIO(7I)
2
3 NAME
4 dkio - disk control operations
5
6 SYNOPSIS
7 #include <sys/dkio.h>
8 #include <sys/vtoc.h>
9
10 DESCRIPTION
11 Disk drivers support a set of ioctl(2) requests for disk controller,
12 geometry, and partition information. Basic to these ioctl(2) requests
13 are the definitions in <sys/dkio.h>.
14
15 IOCTLS
16 The following ioctl(2) requests set and/or retrieve the current disk
17 controller, partitions, or geometry information on all architectures:
18
19 DKIOCINFO
20
21 The argument is a pointer to a dk_cinfo structure (described below).
22 This structure tells the controller-type and attributes regarding bad-
23 block processing done on the controller.
24
25 /*
26 * Structures and definitions for disk I/O control commands
27 */
28 #define DK_DEVLEN 16 /* device name max length, */
29 /* including unit # and NULL */
30
31 /* Used for controller info */
32 struct dk_cinfo {
33 char dki_cname[DK_DEVLEN]; /* controller name */
34 /* (no unit #) */
35 ushort_t dki_ctype; /* controller type */
36 ushort_t dki_flags; /* flags */
37 ushort_t dki_cnum; /* controller number */
38 uint_t dki_addr; /* controller address */
39 uint_t dki_space; /* controller bus type */
40 uint_t dki_prio; /* interrupt priority */
41 uint_t dki_vec; /* interrupt vector */
42 char dki_dname[DK_DEVLEN]; /* drive name (no unit #) */
43 uint_t dki_unit; /* unit number */
44 uint_t dki_slave; /* slave number */
45 ushort_t dki_partition; /* partition number */
46 ushort_t dki_maxtransfer; /* maximum transfer size */
47 /* in DEV_BSIZE */
48 };
49
50 /*
51 * Controller types
52 */
53 #define DKC_UNKNOWN 0
54 #define DKC_CDROM 1 /* CD-ROM, SCSI or other */
55 #define DKC_WDC2880 2
56 #define DKC_XXX_0 3 /* unassigned */
57 #define DKC_XXX_1 4 /* unassigned */
58 #define DKC_DSD5215 5
59 #define DKC_ACB4000 7
60 #define DKC_XXX_2 9 /* unassigned */
61 #define DKC_NCRFLOPPY 10
62 #define DKC_SMSFLOPPY 12
63 #define DKC_SCSI_CCS 13 /* SCSI CCS compatible */
64 #define DKC_INTEL82072 14 /* native floppy chip */
65 #define DKC_INTEL82077 19 /* 82077 floppy disk */
66 /* controller */
67 #define DKC_DIRECT 20 /* Intel direct attached */
68 /* device (IDE) */
69 #define DKC_PCMCIA_MEM 21 /* PCMCIA memory disk-like */
70 /* type */
71 #define DKC_PCMCIA_ATA 22 /* PCMCIA AT Attached type */
72
73 /*
74 * Sun reserves up through 1023
75 */
76
77 #define DKC_CUSTOMER_BASE 1024
78
79 /*
80 * Flags
81 */
82 #define DKI_BAD144 0x01 /* use DEC std 144 */
83 /* bad sector fwding */
84 #define DKI_MAPTRK 0x02 /* controller does */
85 /* track mapping */
86 #define DKI_FMTTRK 0x04 /* formats only full
87 /* track at a time */
88 #define DKI_FMTVOL 0x08 /* formats only full */
89 /* volume at a time */
90 #define DKI_FMTCYL 0x10 /* formats only full */
91 /* cylinders at a time */
92 #define DKI_HEXUNIT 0x20 /* unit number printed */
93 /* as 3 hexdigits */
94 #define DKI_PCMCIA_PFD 0x40 /* PCMCIA pseudo-floppy */
95 /* memory card */
96
97 DKIOCGAPART
98
99 The argument is a pointer to a dk_allmap structure (described below).
100 This ioctl(2) gets the controller's notion of the current partition
101 table for disk drive.
102
103 DKIOCSAPART
104
105 The argument is a pointer to a dk_allmap structure (described below).
106 This ioctl(2) sets the controller's notion of the partition table
107 without changing the disk itself.
108
109 /*
110 * Partition map (part of dk_label)
111 */
112 struct dk_map {
113 daddr_t dkl_cylno; /* starting cylinder */
114 daddr_t dkl_nblk; /* number of blocks */
115 };
116
117 /*
118 * Used for all partitions
119 */
120 struct dk_allmap {
121 struct dk_map dka_map[NDKMAP];
122 };
123
124 DKIOCGGEOM
125
126 The argument is a pointer to a dk_geom structure (described below).
127 This ioctl(2) gets the controller's notion of the current geometry of
128 the disk drive.
129
130 DKIOCSGEOM
131
132 The argument is a pointer to a dk_geom structure (described below).
133 This ioctl(2) sets the controller's notion of the geometry without
134 changing the disk itself.
135
136 DKIOCGVTOC
137
138 The argument is a pointer to a vtoc structure (described below). This
139 ioctl(2) returns the device's current volume table of contents (VTOC).
140 For disks larger than 1TB, DKIOCGEXTVTOC must be used instead.
141
142 DKIOCSVTOC
143
144 The argument is a pointer to a vtoc structure (described below). This
145 ioctl(2) changes the VTOC associated with the device. For disks
146 larger than 1TB, DKIOCSEXTVTOC must be used instead.
147
148 struct partition {
149 ushort_t p_tag; /* ID tag of partition */
150 ushort_t p_flag; /* permission flags */
151 daddr_t p_start; /* start sector of partition */
152 long p_size; /* # of blocks in partition */
153 };
154
155 If DKIOCSVTOC is used with a floppy diskette, the p_start field must
156 be the first sector of a cylinder. To compute the number of sectors
157 per cylinder, multiply the number of heads by the number of sectors
158 per track.
159
160 struct vtoc {
161 unsigned long v_bootinfo[3]; /* info needed by mboot */
162 /* (unsupported) */
163 unsigned long v_sanity; /* to verify vtoc */
164 /* sanity */
165 unsigned long v_version; /* layout version */
166 char v_volume[LEN_DKL_VVOL]; /* volume name */
167 ushort_t v_sectorsz; /* sector size in bytes */
168 ushort_t v_nparts; /* number of partitions */
169 unsigned long v_reserved[10]; /* free space */
170 struct partition v_part[V_NUMPAR]; /* partition headers */
171 time_t timestamp[V_NUMPAR]; /* partition timestamp */
172 /* (unsupported) */
173 char v_asciilabel[LEN_DKL_ASCII]; /* compatibility */
174 };
175
176 /*
177 * Partition permission flags
178 */
179 #define V_UNMNT 0x01 /* Unmountable partition */
180 #define V_RONLY 0x10 /* Read only */
181
182 /*
183 * Partition identification tags
184 */
185 #define V_UNASSIGNED 0x00 /* unassigned partition */
186 #define V_BOOT 0x01 /* Boot partition */
187 #define V_ROOT 0x02 /* Root filesystem */
188 #define V_SWAP 0x03 /* Swap filesystem */
189 #define V_USR 0x04 /* Usr filesystem */
190 #define V_BACKUP 0x05 /* full disk */
191 #define V_VAR 0x07 /* Var partition */
192 #define V_HOME 0x08 /* Home partition */
193 #define V_ALTSCTR 0x09 /* Alternate sector partition */
194
195 DKIOCGEXTVTOC
196
197 The argument is a pointer to an extvtoc structure (described below).
198 This ioctl returns the device's current volume table of contents
199 (VTOC). VTOC is extended to support a disk up to 2TB in size. For
200 disks larger than 1TB this ioctl must be used instead of DKIOCGVTOC.
201
202 DKIOCSEXTVTOC
203
204 The argument is a pointer to an extvtoc structure (described below).
205 This ioctl changes the VTOC associated with the device. VTOC is
206 extended to support a disk up to 2TB in size. For disks larger than
207 1TB this ioctl must be used instead of DKIOCSVTOC.
208
209 struct extpartition {
210 ushort_t p_tag; /* ID tag of partition */
211 ushort_t p_flag; /* permission flags */
212 ushort_t p_pad[2]; /* reserved */
213 diskaddr_t p_start; /* start sector no of partition */
214 diskaddr_t p_size; /* # of blocks in partition */
215 };
216
217 struct extvtoc {
218 uint64_t v_bootinfo[3]; /* info needed by mboot (unsupported) */
219 uint64_t v_sanity; /* to verify vtoc sanity */
220 uint64_t v_version; /* layout version */
221 char v_volume[LEN_DKL_VVOL]; /* volume name */
222 ushort_t v_sectorsz; /* sector size in bytes */
223 ushort_t v_nparts; /* number of partitions */
224 ushort_t pad[2];
225 uint64_t v_reserved[10];
226 struct extpartition v_part[V_NUMPAR]; /* partition headers */
227 uint64_t timestamp[V_NUMPAR]; /* partition timestamp */
228 /* (unsupported) */
229 char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */
230 };
231
232 Partition permissions flags and identification tags are defined the
233 same as vtoc structure.
234
235 DKIOCEJECT
236
237 If the drive supports removable media, this ioctl(2) requests the disk
238 drive to eject its disk.
239
240 DKIOCREMOVABLE
241
242 The argument to this ioctl(2) is an integer. After successful
243 completion, this ioctl(2) sets that integer to a non-zero value if the
244 drive in question has removable media. If the media is not removable,
245 the integer is set to 0.
246
247 DKIOCHOTPLUGGABLE
248
249 The argument to this ioctl(2) is an integer. After successful
250 completion, this ioctl(2) sets that integer to a non-zero value if the
251 drive in question is hotpluggable. If the media is not hotpluggable,
252 the integer is set to 0.
253
254 DKIOCSTATE
255
256 This ioctl(2) blocks until the state of the drive, inserted or
257 ejected, is changed. The argument is a pointer to a dkio_state, enum,
258 whose possible enumerations are listed below. The initial value
259 should be either the last reported state of the drive, or DKIO_NONE.
260 Upon return, the enum pointed to by the argument is updated with the
261 current state of the drive.
262
263 enum dkio_state {
264 DKIO_NONE, /* Return disk's current state */
265 DKIO_EJECTED, /* Disk state is 'ejected' */
266 DKIO_INSERTED /* Disk state is 'inserted' */
267 };
268
269 DKIOCLOCK
270
271 For devices with removable media, this ioctl(2) requests the disk
272 drive to lock the door.
273
274 DKIOCUNLOCK
275
276 For devices with removable media, this ioctl(2) requests the disk
277 drive to unlock the door.
278
279 DKIOCGMEDIAINFO
280
281 The argument to this ioctl(2) is a pointer to a dk_minfo structure.
282 The structure indicates the type of media or the command set profile
283 used by the drive to operate on the media. The dk_minfo structure
284 also indicates the logical media block size the drive uses as the
285 basic unit block size of operation and the raw formatted capacity of
286 the media in number of logical blocks.
287
288 DKIOCGMEDIAINFOEXT
289
290 The argument to this ioctl(2) is a pointer to a dk_minfo_ext
291 structure. The structure indicates the type of media or the command
292 set profile used by the drive to operate on the media. The
293 dk_minfo_ext structure also indicates the logical media block size the
294 drive uses as the basic unit block size of operation, the raw
295 formatted capacity of the media in number of logical blocks and the
296 physical block size of the media.
297
298 /*
299 * Used for media info or profile info
300 */
301 struct dk_minfo {
302 uint_t dki_media_type; /* Media type or profile info */
303 uint_t dki_lbsize; /* Logical blocksize of media */
304 diskaddr_t dki_capacity; /* Capacity as # of dki_lbsize blks */
305 };
306
307 /*
308 * Used for media info or profile info and physical blocksize
309 */
310 struct dk_minfo_ext {
311 uint_t dki_media_type; /* Media type or profile info */
312 uint_t dki_lbsize; /* Logical blocksize of media */
313 diskaddr_t dki_capacity; /* Capacity as # of dki_lbsize blks */
314 uint_t dki_pbsize; /* Physical blocksize of media */
315 };
316
317
318 /*
319 * Media types or profiles known
320 */
321 #define DK_UNKNOWN 0x00 /* Media inserted - type unknown */
322
323 /*
324 * SFF 8090 Specification Version 3, media types 0x01 - 0xfffe are
325 * retained to maintain compatibility with SFF8090. The following
326 * define the optical media type.
327 */
328 #define DK_MO_ERASABLE 0x03 /* MO Erasable */
329 #define DK_MO_WRITEONCE 0x04 /* MO Write once */
330 #define DK_AS_MO 0x05 /* AS MO */
331 #define DK_CDROM 0x08 /* CDROM */
332 #define DK_CDR 0x09 /* CD-R */
333 #define DK_CDRW 0x0A /* CD-RW */
334 #define DK_DVDROM 0x10 /* DVD-ROM */
335 #define DK_DVDR 0x11 /* DVD-R */
336 #define DK_DVDRAM 0x12 /* DVD_RAM or DVD-RW */
337
338 /*
339 * Media types for other rewritable magnetic media
340 */
341 #define DK_FIXED_DISK 0x10001 /* Fixed disk SCSI or otherwise */
342 #define DK_FLOPPY 0x10002 /* Floppy media */
343 #define DK_ZIP 0x10003 /* IOMEGA ZIP media */
344 #define DK_JAZ 0x10004 /* IOMEGA JAZ media */
345
346 If the media exists and the host can obtain a current profile list,
347 the command succeeds and returns the dk_minfo structure with data
348 representing that media.
349
350 If there is no media in the drive, the command fails and the host
351 returns an ENXIO error, indicating that it cannot gather the
352 information requested.
353
354 If the profile list is not available, the host attempts to identify
355 the media-type based on the available information.
356
357 If identification is not possible, the host returns media type
358 DK_UNKNOWN. See NOTES for blocksize usage and capacity information.
359
360 DKIOCSMBOOT
361
362 The argument is a pointer to struct mboot.
363
364 Copies the mboot information supplied in the argument to the absolute
365 sector 0 of the device. Prior to copying the information, this
366 ioctl(2) performs the following checks on the mboot data:
367
368 o Ensures that the signature field is set to 0xAA55.
369
370 o Ensures that partitions do not overlap.
371
372 o On SPARC platforms, determines if the device is a removable
373 media.
374
375 If the above verification fails, errno is set to EINVAL and the
376 ioctl(2) command fails.
377
378 x86 Platforms -- Upon successful write of mboot, the partition map
379 structure maintained in the driver is updated. If the new Solaris
380 partition is different from the previous one, the internal VTOC table
381 maintained in the driver is set as follows:
382
383 If _SUNOS_VTOC_8 is defined:
384
385 Partition: 0 Start: 0 Capacity = Capacity of device.
386 Partition: 2 Start: 0 Capacity = Capacity of device.
387
388 If _SUNOS_VTOC_16 is defined:
389
390 Partition: 2 Start: 0 Size = Size specified in mboot - 2 cylinders.
391 Partition: 8 Start: 0 Size = Sectors/cylinder.
392 Partition: 9 Start: Sectors/cylinder Size = 2 * sectors/cylinder
393
394 To determine if the Solaris partition has changed:
395
396 If either offset or the size of the Solaris partition is different
397 from the previous one then it shall be deemed to have changed. In
398 all other cases, the internal VTOC info remains as before.
399
400 SPARC Platforms -- The VTOC label and mboot both occupy the same
401 location, namely sector 0. As a result, following the successful
402 write of mboot info, the internal VTOC table maintained in the driver
403 is set as follows:
404
405 Partition: 0 Start: 0 Size = Capacity of device.
406 Partition: 2 Start: 0 Size = Capacity of device.
407
408 See the NOTES section for usage of DKIOCSMBOOT when modifying Solaris
409 partitions.
410
411 DKIOCGETVOLCAP
412
413 This ioctl provides information and status of available capabilities.
414 vc_info is a bitmap and the valid flag values are:
415
416 DKV_ABR_CAP Capable of application-based recovery
417 DKV_DMR_CAP Ability to read specific copy of data when multiple
418 copies exist. For example, in a two way mirror, this
419 ioctl is used to read each side of the mirror.
420
421 vc_set is a bitmap and the valid flag values are:
422
423 DKV_ABR_CAP This flag is set if ABR has been set on a device that
424 supports ABR functionality.
425 DKV_DMR_CAP Directed read has been enabled.
426
427 These capabilities are not required to be persistent across a system
428 reboot and their persistence depends upon the implementation. For
429 example, if the ABR capability for a DRL mirror simply clears the
430 dirty-region list and subsequently stops updating this list, there is
431 no reason for persistence because the VM recovery is a no-op.
432 Conversely, if the ABR capability is applied to a non-DRL mirror to
433 indicate that the VM should not perform a full recovery of the mirror
434 following a system crash, the capability must be persistent so that
435 the VM know whether or not to perform recovery.
436
437 Return Errors:
438
439 EINVAL Invalid device for this operation.
440 ENOTSUP Functionality that is attempted to be set is not supported.
441
442 DKIOCSETVOLCAP
443
444 This ioctl sets the available capabilities for the device. If a
445 capability flag is not set in vc_set, that capability is cleared.
446
447 vc_info flags are ignored.
448
449 vc_set valid flags are:
450
451 DKV_ABR_CAP Flag to set application-based recovery. A device can
452 successfully support ABR only if it is capable.
453 DKV_DMR_CAP Flag to set directed read.
454
455 DKIODMR
456
457 int ioctl(int, DKIODMR, vol_directed_rd *)
458
459 This ioctl allows highly available applications to perform round-robin
460 reads from the underlying devices of a replicated device.
461
462 vdr_offset Offset at which the read should occur.
463 vdr_nbytes Number of bytes to be read
464 vdr_bytesread Number of bytes successfully read by the kernel.
465 vdr_data Pointer to a user allocated buffer to return the data
466 read
467 vdr_side Side to be read. Initialized to DKV_SIDE_INIT
468 vdr_side_name The volume name that has been read.
469
470 Valid vdr_flags are:
471
472 DKV_DMR_NEXT_SIDE Set by user
473 DKV_DMR_DONE Return value
474 DKV_DMR_ERROR Return value
475 DKV_DMR_SUCCESS Return value
476 DKV_DMR_SHORT Return value
477
478 The calling sequence is as follows: The caller sets the vdr_flags to
479 DK_DMR_NEXT_SIDE and vdr_side to DKV_SIDE_INIT at the start.
480 Subsequent calls should be made without any changes to these values.
481 If they are changed the results of the ioctl are indeterminate.
482
483 When DKV_SIDE_INIT is set, the call results in the kernel reading from
484 the first side. The kernel updates vdr_side to indicate the side that
485 was read, and vdr_side_name to contain the name of that side.
486 vdr_data contains the data that was read. Therefore to perform a
487 round-robin read all of the valid sides, there is no need for the
488 caller to change the contents of vdr_side.
489
490 Subsequent ioctl(2) calls result in reads from the next valid side
491 until all valid sides have been read. On success, the kernel sets
492 DKV_DMR_SUCCESS. The following table shows the values of vdr_flags
493 that are returned when an error occurs:
494
495 vda_flags vdr_side Notes
496 DKV_DMR_ERROR DKV_SIDE_INIT No valid side to read
497 DKV_DMR_DONE Not Init side All valid sides read
498 DKV_DMR_SHORT Any value Bytes requested cannot be read
499 vdr_bytesread set to bytes
500 actually read
501 Typical code fragment:
502
503 enable->vc_set |= DKV_ABR_SET;
504 retval = ioctl(filedes, DKIOSETVOLCAP, enable);
505 if (retval != EINVAL || retval != ENOTSUP) {
506 if (info->vc_set & DKV_DMR_SET) {
507 dr->vdr_flags |= DKV_DMR_NEXT_SIDE;
508 dr->vdr_side = DKV_SIDE_INIT;
509 dr->vdr_nbytes = 1024;
510 dr->vdr_offset = 0xff00;
511 do {
512 rval = ioctl(fildes, DKIODMR, dr);
513 if (rval != EINVAL) {
514 /* Process data */
515 }
516 } while (rval != EINVAL || dr->vdr_flags &
517 (DKV_DMR_DONE | DKV_DMR_ERROR | DKV_DMR_SHORT)
518 }
519 }
520
521 RETURN VALUES
522 Upon successful completion, the value returned is 0. Otherwise, -1 is
523 returned and errno is set to indicate the error.
524
525 x86 Only
526 The following ioctl(2) requests set and/or retrieve the current disk
527 controller, partitions, or geometry information on the x86 architecture.
528
529 DKIOCG_PHYGEOM
530
531 The argument is a pointer to a dk_geom structure (described below).
532 This ioctl(2) gets the driver's notion of the physical geometry of the
533 disk drive. It is functionally identical to the DKIOCGGEOM ioctl(2).
534
535 DKIOCG_VIRTGEOM
536
537 The argument is a pointer to a dk_geom structure (described below).
538 This ioctl(2) gets the controller's (and hence the driver's) notion of
539 the virtual geometry of the disk drive. Virtual geometry is a view of
540 the disk geometry maintained by the firmware in a host bus adapter or
541 disk controller. If the disk is larger than 8 Gbytes, this ioctl
542 fails because a CHS-based geometry is not relevant or useful for this
543 drive.
544
545 /*
546 * Definition of a disk's geometry
547 */
548 struct dk_geom {
549 unsigned shor dkg_ncyl; /* # of data cylinders */
550 unsigned shor dkg_acyl; /* # of alternate cylinders */
551 unsigned short dkg_bcyl; /* cyl offset (for fixed head */
552 /* area) */
553 unsigned short dkg_nhead; /* # of heads */
554 unsigned short dkg_obs1; /* obsolete */
555 unsigned short dkg_nsect; /* # of sectors per track */
556 unsigned short dkg_intrlv; /* interleave factor */
557 unsigned short dkg_obs2; /* obsolete */
558 unsigned short dkg_obs3; /* obsolete */
559 unsigned short dkg_apc; /* alternates per cylinder */
560 /* (SCSI only) */
561 unsigned short dkg_rpm; /* revolutions per min */
562 unsigned short dkg_pcyl; /* # of physical cylinders */
563 unsigned short dkg_write_reinstruct; /* # sectors to skip, */
564 /* writes */
565 unsigned short dkg_read_reinstruct; /* # sectors to skip ,*/
566 /* reads */
567 unsigned short dkg_extra[7]; /* for compatible expansion */
568 };
569
570 DKIOCADDBAD
571
572 This ioctl(2) forces the driver to re-examine the alternates slice and
573 rebuild the internal bad block map accordingly. It should be used
574 whenever the alternates slice is changed by any method other than the
575 addbadsec(1M) or format(1M) utilities. DKIOCADDBAD can only be used
576 for software remapping on IDE drives; SCSI drives use hardware
577 remapping of alternate sectors.
578
579 DKIOCPARTINFO
580
581 The argument is a pointer to a part_info structure (described below).
582 This ioctl(2) gets the driver's notion of the size and extent of the
583 partition or slice indicated by the file descriptor argument.
584
585 /*
586 * Used by applications to get partition or slice information
587 */
588 struct part_info {
589 daddr_t p_start;
590 int p_length;
591 };
592
593 DKIOCEXTPARTINFO
594
595 The argument is a pointer to an extpart_info structure (described
596 below). This ioctl gets the driver's notion of the size and extent of
597 the partition or slice indicated by the file descriptor argument. On
598 disks larger than 1TB, this ioctl must be used instead of
599 DKIOCPARTINFO.
600
601 /*
602 * Used by applications to get partition or slice information
603 */
604 struct extpart_info {
605 diskaddr_t p_start;
606 diskaddr_t p_length;
607 };
608
609 DKIOCSETEXTPART
610
611 This ioctl is used to update the in-memory copy of the logical drive
612 information maintained by the driver. The ioctl takes no arguments.
613 It causes a re-read of the partition information and recreation of
614 minor nodes if required. Prior to updating the data structures, the
615 ioctl ensures that the partitions do not overlap. Device nodes are
616 created only for valid partition entries. If there is any change in
617 the partition offset, size or ID from the previous read, the partition
618 is deemed to have been changed and hence the device nodes are
619 recreated. Any modification to any of the logical partitions results
620 in the recreation of all logical device nodes.
621
622 SEE ALSO
623 addbadsec(1M), fdisk(1M), format(1M), ioctl(2), cmdk(7D), sd(7D),
624 cdio(7I), fdio(7I), hdio(7I)
625
626 NOTES
627 Blocksize information provided in DKIOCGMEDIAINFO is the size (in bytes)
628 of the device's basic unit of operation and can differ from the blocksize
629 that the Solaris operating environment exports to the user. Capacity
630 information provided in the DKIOCGMEDIAINFO are for reference only and
631 you are advised to use the values returned by DKIOCGGEOM or other
632 appropriate ioctl(2) for accessing data using the standard interfaces.
633
634 For x86 only: If the DKIOCSMBOOT command is used to modify the Solaris
635 partitions, the VTOC information should also be set appropriately to
636 reflect the changes to partition. Failure to do so leads to unexpected
637 results when the device is closed and reopened fresh at a later time.
638 This is because a default VTOC is assumed by driver when a Solaris
639 partition is changed. The default VTOC persists until the ioctl
640 DKIOCSVTOC is called to modify VTOC or the device is closed and reopened.
641 At that point, the old valid VTOC is read from the disk if it is still
642 available.
643
644 illumos February 17, 2020 illumos