vsphere/internal/virtualdevice/virtual_machine_disk_subresource.go
func (r *DiskSubresource) Read(l object.VirtualDeviceList) error {
	log.Printf("[DEBUG] %s: Reading state", r)
	disk, err := r.findVirtualDisk(l, true)
	if err != nil {
		return fmt.Errorf("cannot find disk device: %s", err)
	}
	unit, ctlr, err := r.findControllerInfo(l, disk)
	if err != nil {
		return err
	}
	r.Set("unit_number", unit)
	if err := r.SaveDevIDs(disk, ctlr); err != nil {
		return err
	}

	// Fetch disk attachment state in config
	var attach bool
	if r.Get("attach") != nil {
		attach = r.Get("attach").(bool)
	}
	// Save disk backing settings
	b, ok := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo)
	if !ok {
		return fmt.Errorf("disk backing at %s is of an unsupported type (type %T)", r.Get("device_address").(string), disk.Backing)
	}
	r.Set("uuid", b.Uuid)
	r.Set("disk_mode", b.DiskMode)
	r.Set("write_through", b.WriteThrough)

	// Only use disk_sharing if we are on vSphere 6.0 and higher. In addition,
	// skip if the value is unset - this prevents spurious diffs during upgrade
	// situations where the VM hardware version does not actually allow disk
	// sharing. In this situation, the value will be blank, and setting it will
	// actually result in an error.
	version := viapi.ParseVersionFromClient(r.client)
	if version.Newer(viapi.VSphereVersion{Product: version.Product, Major: 6}) && b.Sharing != "" {
		r.Set("disk_sharing", b.Sharing)
	}

	if !attach {
		r.Set("thin_provisioned", b.ThinProvisioned)
		r.Set("eagerly_scrub", b.EagerlyScrub)
	}
	r.Set("datastore_id", b.Datastore.Value)

	// Disk settings
	if !attach {
		dp := &object.DatastorePath{}
		if ok := dp.FromString(b.FileName); !ok {
			return fmt.Errorf("could not parse path from filename: %s", b.FileName)
		}
		r.Set("path", dp.Path)
		r.Set("size", diskCapacityInGiB(disk))
	}

	if allocation := disk.StorageIOAllocation; allocation != nil {
		r.Set("io_limit", allocation.Limit)
		r.Set("io_reservation", allocation.Reservation)
		if shares := allocation.Shares; shares != nil {
			r.Set("io_share_level", string(shares.Level))
			r.Set("io_share_count", shares.Shares)
		}
	}
	log.Printf("[DEBUG] %s: Read finished (key and device address may have changed)", r)
	return nil
}
func (r *DiskSubresource) Read(l object.VirtualDeviceList) error {
	log.Printf("[DEBUG] %s: Reading state", r)
	disk, err := r.findVirtualDisk(l, true)
	if err != nil {
		return fmt.Errorf("cannot find disk device: %s", err)
	}
	unit, ctlr, err := r.findControllerInfo(l, disk)
	if err != nil {
		return err
	}
	r.Set("unit_number", unit)
	if err := r.SaveDevIDs(disk, ctlr); err != nil {
		return err
	}

	// Fetch disk attachment state in config
	var attach bool
	if r.Get("attach") != nil {
		attach = r.Get("attach").(bool)
	}
	// Save disk backing settings
	b, ok := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo)
	if !ok {
		return fmt.Errorf("disk backing at %s is of an unsupported type (type %T)", r.Get("device_address").(string), disk.Backing)
	}
	r.Set("uuid", b.Uuid)
	r.Set("disk_mode", b.DiskMode)
	r.Set("write_through", b.WriteThrough)

	// Only use disk_sharing if we are on vSphere 6.0 and higher. In addition,
	// skip if the value is unset - this prevents spurious diffs during upgrade
	// situations where the VM hardware version does not actually allow disk
	// sharing. In this situation, the value will be blank, and setting it will
	// actually result in an error.
	version := viapi.ParseVersionFromClient(r.client)
	if version.Newer(viapi.VSphereVersion{Product: version.Product, Major: 6}) && b.Sharing != "" {
		r.Set("disk_sharing", b.Sharing)
	}

	if !attach {
		r.Set("thin_provisioned", b.ThinProvisioned)
		r.Set("eagerly_scrub", b.EagerlyScrub)
	}
	r.Set("datastore_id", b.Datastore.Value)

	// Disk settings
	if !attach {
		dp := &object.DatastorePath{}
		if ok := dp.FromString(b.FileName); !ok {
			return fmt.Errorf("could not parse path from filename: %s", b.FileName)
		}
		r.Set("path", dp.Path)
		r.Set("size", diskCapacityInGiB(disk))
	}

	if allocation := disk.StorageIOAllocation; allocation != nil {
		r.Set("io_limit", allocation.Limit)
		r.Set("io_reservation", allocation.Reservation)
		if shares := allocation.Shares; shares != nil {
			r.Set("io_share_level", string(shares.Level))
			r.Set("io_share_count", shares.Shares)
		}
	}
	log.Printf("[DEBUG] %s: Read finished (key and device address may have changed)", r)
	return nil
}
// Read reads a vsphere_virtual_machine disk sub-resource and commits the data
// to the newData layer.