7051027 Installer not enabling disk write cache when entire disk selected
authorDrew Fisher <drew.fisher@oracle.com>
Tue, 28 Jun 2011 06:57:09 -0600
changeset 1236 2f3a9d3aa9cb
parent 1235 fea9874bba56
child 1237 1422ef107116
7051027 Installer not enabling disk write cache when entire disk selected 7060008 offline disks cause a traceback error in discovery.py
usr/src/lib/install_target/controller.py
usr/src/lib/install_target/discovery.py
usr/src/lib/install_target/instantiation.py
usr/src/lib/install_target/libdiskmgt/diskmgt.py
usr/src/lib/install_target/logical.py
usr/src/lib/install_target/physical.py
--- a/usr/src/lib/install_target/controller.py	Mon Jun 27 19:26:14 2011 -0600
+++ b/usr/src/lib/install_target/controller.py	Tue Jun 28 06:57:09 2011 -0600
@@ -79,12 +79,14 @@
     '''
     pass
 
+
 class SubSizeDiskError(BadDiskError):
     ''' Specific exception sub-class for when a disk is below the
         minimum required size for installation.
     '''
     pass
 
+
 class SwapDumpGeneralError(Exception):
     ''' General exception for errors computing swap and dump values.
     '''
@@ -556,6 +558,11 @@
             else:
                 new_slice = disk.add_slice("0", start, slice_size,
                     Size.sector_units, force=True)
+
+            # enable the disk's write-cache if wipe_disk is True.
+            if wipe_disk:
+                disk.write_cache = True
+
         else:
             # Compile a list of the usable slices, if any
             slice_list = list()
--- a/usr/src/lib/install_target/discovery.py	Mon Jun 27 19:26:14 2011 -0600
+++ b/usr/src/lib/install_target/discovery.py	Tue Jun 28 06:57:09 2011 -0600
@@ -142,6 +142,11 @@
         new_disk.iscdrom = drive.cdrom
         new_disk.opath = drive_attributes.opath
 
+        # if a drive is offline or down return None
+        if drive_attributes.status == "DOWN":
+            self.logger.debug("disk '%s' is offline" % new_disk.ctd)
+            return None
+
         # set the devpath
         if os.path.islink(drive_attributes.opath):
             link = os.readlink(drive_attributes.opath)
--- a/usr/src/lib/install_target/instantiation.py	Mon Jun 27 19:26:14 2011 -0600
+++ b/usr/src/lib/install_target/instantiation.py	Tue Jun 28 06:57:09 2011 -0600
@@ -27,11 +27,16 @@
 """ instantiation.py - target instantiation checkpoint.  Parses the Data Object
 Cache for physical and logical targets.
 """
+import ctypes as C
+import fcntl
+import os
+
 from copy import copy
 
 from solaris_install.engine import InstallEngine
 from solaris_install.engine.checkpoint import AbstractCheckpoint as Checkpoint
 from solaris_install.target import Target
+from solaris_install.target.libdiskmgt.diskmgt import DKIOCSETWCE
 from solaris_install.target.logical import BE, DatasetOptions, Filesystem, \
     Options, PoolOptions, Vdev, Zvol, Zpool
 from solaris_install.target.physical import Disk, Partition, Slice
@@ -85,15 +90,27 @@
         """ method used to parse the list of disks and create the desired
         physical configuration.
         """
-        # walk the list
         for disk in self.physical_list:
-            # if the 'whole_disk' attribute is set to True
-            # don't even bother initializing the Disk. it will
-            # be processed appropriately at zpool instantiation
-            # time.
+            # if the 'whole_disk' attribute is set to True don't even bother
+            # initializing the Disk. it will be processed appropriately at
+            # zpool instantiation time.
             if disk.whole_disk:
                 continue
 
+            # check the write_cache attribute and, if set, enable it
+            if disk.write_cache:
+                fd = os.open(disk.opath, os.O_RDWR | os.O_NDELAY)
+                try:
+                    self.logger.debug("enabling write-cache on %s" % disk.ctd)
+                    number = C.c_int(1)
+                    fcntl.ioctl(fd, DKIOCSETWCE, C.addressof(number))
+                except Exception as err:
+                    # ignore any errors generated by the ioctl
+                    self.logger.debug("unable to enable write-cache:")
+                    self.logger.debug(str(err))
+                finally:
+                    os.close(fd)
+
             # get the list of fdisk partitions and slices on the disk
             partition_list = disk.get_descendants(class_type=Partition)
             slice_list = disk.get_descendants(class_type=Slice)
--- a/usr/src/lib/install_target/libdiskmgt/diskmgt.py	Mon Jun 27 19:26:14 2011 -0600
+++ b/usr/src/lib/install_target/libdiskmgt/diskmgt.py	Tue Jun 28 06:57:09 2011 -0600
@@ -64,6 +64,7 @@
 # #defines from /usr/include/sys/dkio.h
 DKIOCGGEOM = (0x04 << 8) | 1
 DKIOCINFO = (0x04 << 8) | 3
+DKIOCSETWCE = (0x04 << 8) | 37
 DKIOCGMEDIAINFO = (0x04 << 8) | 42
 DKC_CDROM = 1
 
--- a/usr/src/lib/install_target/logical.py	Mon Jun 27 19:26:14 2011 -0600
+++ b/usr/src/lib/install_target/logical.py	Tue Jun 28 06:57:09 2011 -0600
@@ -41,7 +41,8 @@
 from solaris_install.target.shadow.zpool import ShadowZpool
 from solaris_install.target.libbe.be import be_list, be_init, be_destroy, \
     be_activate, be_mount, be_unmount
-from solaris_install.target.libbe.const import ZFS_FS_NAMES, ZFS_SHARED_FS_NAMES
+from solaris_install.target.libbe.const import ZFS_FS_NAMES, \
+    ZFS_SHARED_FS_NAMES
 
 DUMPADM = "/usr/sbin/dumpadm"
 LOFIADM = "/usr/sbin/lofiadm"
@@ -903,7 +904,8 @@
     def init(self, dry_run, pool_name="rpool", nested_be=False,
             fs_list=None, fs_zfs_properties=None,
             shared_fs_list=None, shared_fs_zfs_properties=None):
-        """ method to initialize a BE by creating the empty datasets for the BE.
+        """ method to initialize a BE by creating the empty datasets for the
+        BE.
         """
 
         if not dry_run:
--- a/usr/src/lib/install_target/physical.py	Mon Jun 27 19:26:14 2011 -0600
+++ b/usr/src/lib/install_target/physical.py	Tue Jun 28 06:57:09 2011 -0600
@@ -577,6 +577,9 @@
         # disk label
         self.label = None
 
+        # write cache
+        self.write_cache = False
+
         # shadow lists
         self._children = ShadowPhysical(self)
 
@@ -948,7 +951,7 @@
                 new_start_sector = \
                     ((hole.start_sector / self.geometry.cylsize) * \
                     self.geometry.cylsize) + self.geometry.cylsize
-                
+
                 # calculate the difference so the size can be adjusted
                 difference = new_start_sector - hole.start_sector
 
@@ -1068,6 +1071,7 @@
         if self.in_vdev is not None:
             s += "; in_vdev=%s" % self.in_vdev
         s += "; whole_disk=%s" % self.whole_disk
+        s += "; write_cache=%s" % self.write_cache
 
         return s