mirror of
https://github.com/restic/restic.git
synced 2026-06-17 22:24:17 +00:00
fs: unexport more vss types
This commit is contained in:
@@ -25,16 +25,11 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// NewVSSConfig returns a new VSSConfig with the default values filled in.
|
||||
func NewVSSConfig() VSSConfig {
|
||||
return VSSConfig{
|
||||
Timeout: time.Second * 120,
|
||||
}
|
||||
}
|
||||
|
||||
// ParseVSSConfig parses a VSS extended options to VSSConfig struct.
|
||||
func ParseVSSConfig(o options.Options) (VSSConfig, error) {
|
||||
cfg := NewVSSConfig()
|
||||
cfg := VSSConfig{
|
||||
Timeout: time.Second * 120,
|
||||
}
|
||||
o = o.Extract("vss")
|
||||
if err := o.Apply("vss", &cfg); err != nil {
|
||||
return VSSConfig{}, err
|
||||
@@ -56,7 +51,7 @@ type VolumeFilter func(volume string) bool
|
||||
// shadow copy service (VSS) in a transparent way.
|
||||
type LocalVss struct {
|
||||
FS
|
||||
snapshots map[string]VssSnapshot
|
||||
snapshots map[string]vssSnapshot
|
||||
failedSnapshots map[string]struct{}
|
||||
mutex sync.RWMutex
|
||||
msgError ErrorHandler
|
||||
@@ -96,7 +91,7 @@ func parseMountPoints(list string, msgError ErrorHandler) (volumes map[string]st
|
||||
func NewLocalVss(msgError ErrorHandler, msgMessage MessageHandler, cfg VSSConfig) *LocalVss {
|
||||
return &LocalVss{
|
||||
FS: NewLocal(),
|
||||
snapshots: make(map[string]VssSnapshot),
|
||||
snapshots: make(map[string]vssSnapshot),
|
||||
failedSnapshots: make(map[string]struct{}),
|
||||
msgError: msgError,
|
||||
msgMessage: msgMessage,
|
||||
@@ -112,7 +107,7 @@ func (fs *LocalVss) DeleteSnapshots() {
|
||||
fs.mutex.Lock()
|
||||
defer fs.mutex.Unlock()
|
||||
|
||||
activeSnapshots := make(map[string]VssSnapshot)
|
||||
activeSnapshots := make(map[string]vssSnapshot)
|
||||
|
||||
for volumeName, snapshot := range fs.snapshots {
|
||||
if err := snapshot.Delete(); err != nil {
|
||||
@@ -197,7 +192,7 @@ func (fs *LocalVss) snapshotPath(path string) string {
|
||||
}
|
||||
}
|
||||
|
||||
if snapshot, err := NewVssSnapshot(fs.provider, vssVolume, fs.timeout, includeVolume, fs.msgError); err != nil {
|
||||
if snapshot, err := newVssSnapshot(fs.provider, vssVolume, fs.timeout, includeVolume, fs.msgError); err != nil {
|
||||
fs.msgError(vssVolume, errors.Errorf("failed to create snapshot for [%s]: %s",
|
||||
vssVolume, err))
|
||||
fs.failedSnapshots[volumeNameLower] = struct{}{}
|
||||
|
||||
+8
-8
@@ -22,8 +22,8 @@ func (p *MountPoint) GetSnapshotDeviceObject() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// VssSnapshot is a dummy for non-windows platforms to let client code compile.
|
||||
type VssSnapshot struct {
|
||||
// vssSnapshot is a dummy for non-windows platforms to let client code compile.
|
||||
type vssSnapshot struct {
|
||||
mountPointInfo map[string]MountPoint
|
||||
}
|
||||
|
||||
@@ -38,20 +38,20 @@ func getVolumeNameForVolumeMountPoint(mountPoint string) (string, error) {
|
||||
return mountPoint, nil
|
||||
}
|
||||
|
||||
// NewVssSnapshot creates a new vss snapshot. If creating the snapshots doesn't
|
||||
// newVssSnapshot creates a new vss snapshot. If creating the snapshots doesn't
|
||||
// finish within the timeout an error is returned.
|
||||
func NewVssSnapshot(_ string,
|
||||
_ string, _ time.Duration, _ VolumeFilter, _ ErrorHandler) (VssSnapshot, error) {
|
||||
return VssSnapshot{}, errors.New("VSS snapshots are only supported on windows")
|
||||
func newVssSnapshot(_ string,
|
||||
_ string, _ time.Duration, _ VolumeFilter, _ ErrorHandler) (vssSnapshot, error) {
|
||||
return vssSnapshot{}, errors.New("VSS snapshots are only supported on windows")
|
||||
}
|
||||
|
||||
// Delete deletes the created snapshot.
|
||||
func (p *VssSnapshot) Delete() error {
|
||||
func (p *vssSnapshot) Delete() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSnapshotDeviceObject returns root path to access the snapshot files
|
||||
// and folders.
|
||||
func (p *VssSnapshot) GetSnapshotDeviceObject() string {
|
||||
func (p *vssSnapshot) GetSnapshotDeviceObject() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
+46
-46
@@ -518,7 +518,7 @@ func (vss *IVssBackupComponents) DeleteSnapshots(snapshotID ole.GUID) (int32, ol
|
||||
|
||||
// GetSnapshotProperties calls the equivalent VSS api.
|
||||
func (vss *IVssBackupComponents) GetSnapshotProperties(snapshotID ole.GUID,
|
||||
properties *VssSnapshotProperties) error {
|
||||
properties *vssSnapshotProperties) error {
|
||||
var result uintptr
|
||||
|
||||
if runtime.GOARCH == "386" {
|
||||
@@ -537,7 +537,7 @@ func (vss *IVssBackupComponents) GetSnapshotProperties(snapshotID ole.GUID,
|
||||
}
|
||||
|
||||
// vssFreeSnapshotProperties calls the equivalent VSS api.
|
||||
func vssFreeSnapshotProperties(properties *VssSnapshotProperties) error {
|
||||
func vssFreeSnapshotProperties(properties *vssSnapshotProperties) error {
|
||||
proc, err := findVssProc("VssFreeSnapshotProperties")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -557,9 +557,9 @@ func (vss *IVssBackupComponents) BackupComplete() (*IVSSAsync, error) {
|
||||
return vss.convertToVSSAsync(oleIUnknown, err)
|
||||
}
|
||||
|
||||
// VssSnapshotProperties defines the properties of a VSS snapshot as part of the VSS api.
|
||||
// vssSnapshotProperties defines the properties of a VSS snapshot as part of the VSS api.
|
||||
// nolint:structcheck
|
||||
type VssSnapshotProperties struct {
|
||||
type vssSnapshotProperties struct {
|
||||
snapshotID ole.GUID
|
||||
snapshotSetID ole.GUID
|
||||
snapshotsCount uint32
|
||||
@@ -595,7 +595,7 @@ func vssFreeProviderProperties(p *VssProviderProperties) {
|
||||
|
||||
// GetSnapshotDeviceObject returns root path to access the snapshot files
|
||||
// and folders.
|
||||
func (p *VssSnapshotProperties) GetSnapshotDeviceObject() string {
|
||||
func (p *vssSnapshotProperties) GetSnapshotDeviceObject() string {
|
||||
return ole.UTF16PtrToString(p.snapshotDeviceObject)
|
||||
}
|
||||
|
||||
@@ -759,38 +759,38 @@ func (vssEnum *IVssEnumObject) Next(count uint, props unsafe.Pointer) (uint, err
|
||||
return uint(fetched), newVssErrorIfResultNotOK("Next() failed", HRESULT(result))
|
||||
}
|
||||
|
||||
// MountPoint wraps all information of a snapshot of a mountpoint on a volume.
|
||||
type MountPoint struct {
|
||||
// mountPoint wraps all information of a snapshot of a mountpoint on a volume.
|
||||
type mountPoint struct {
|
||||
isSnapshotted bool
|
||||
snapshotSetID ole.GUID
|
||||
snapshotProperties VssSnapshotProperties
|
||||
snapshotProperties vssSnapshotProperties
|
||||
snapshotDeviceObject string
|
||||
}
|
||||
|
||||
// IsSnapshotted is true if this mount point was snapshotted successfully.
|
||||
func (p *MountPoint) IsSnapshotted() bool {
|
||||
func (p *mountPoint) IsSnapshotted() bool {
|
||||
return p.isSnapshotted
|
||||
}
|
||||
|
||||
// GetSnapshotDeviceObject returns root path to access the snapshot files and folders.
|
||||
func (p *MountPoint) GetSnapshotDeviceObject() string {
|
||||
func (p *mountPoint) GetSnapshotDeviceObject() string {
|
||||
return p.snapshotDeviceObject
|
||||
}
|
||||
|
||||
// VssSnapshot wraps windows volume shadow copy api (vss) via a simple
|
||||
// vssSnapshot wraps windows volume shadow copy api (vss) via a simple
|
||||
// interface to create and delete a vss snapshot.
|
||||
type VssSnapshot struct {
|
||||
type vssSnapshot struct {
|
||||
iVssBackupComponents *IVssBackupComponents
|
||||
snapshotID ole.GUID
|
||||
snapshotProperties VssSnapshotProperties
|
||||
snapshotProperties vssSnapshotProperties
|
||||
snapshotDeviceObject string
|
||||
mountPointInfo map[string]MountPoint
|
||||
mountPointInfo map[string]mountPoint
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
// GetSnapshotDeviceObject returns root path to access the snapshot files
|
||||
// and folders.
|
||||
func (p *VssSnapshot) GetSnapshotDeviceObject() string {
|
||||
func (p *vssSnapshot) GetSnapshotDeviceObject() string {
|
||||
return p.snapshotDeviceObject
|
||||
}
|
||||
|
||||
@@ -883,18 +883,18 @@ func getVolumeNameForVolumeMountPoint(mountPoint string) (string, error) {
|
||||
return syscall.UTF16ToString(volumeNameBuffer), nil
|
||||
}
|
||||
|
||||
// NewVssSnapshot creates a new vss snapshot. If creating the snapshots doesn't
|
||||
// newVssSnapshot creates a new vss snapshot. If creating the snapshots doesn't
|
||||
// finish within the timeout an error is returned.
|
||||
func NewVssSnapshot(provider string,
|
||||
volume string, timeout time.Duration, filter VolumeFilter, msgError ErrorHandler) (VssSnapshot, error) {
|
||||
func newVssSnapshot(provider string,
|
||||
volume string, timeout time.Duration, filter VolumeFilter, msgError ErrorHandler) (vssSnapshot, error) {
|
||||
is64Bit, err := isRunningOn64BitWindows()
|
||||
if err != nil {
|
||||
return VssSnapshot{}, newVssTextError(fmt.Sprintf(
|
||||
return vssSnapshot{}, newVssTextError(fmt.Sprintf(
|
||||
"Failed to detect windows architecture: %s", err.Error()))
|
||||
}
|
||||
|
||||
if (is64Bit && runtime.GOARCH != "amd64") || (!is64Bit && runtime.GOARCH != "386") {
|
||||
return VssSnapshot{}, newVssTextError(fmt.Sprintf("executables compiled for %s can't use "+
|
||||
return vssSnapshot{}, newVssTextError(fmt.Sprintf("executables compiled for %s can't use "+
|
||||
"VSS on other architectures. Please use an executable compiled for your platform.",
|
||||
runtime.GOARCH))
|
||||
}
|
||||
@@ -906,12 +906,12 @@ func NewVssSnapshot(provider string,
|
||||
defer oleIUnknown.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return VssSnapshot{}, err
|
||||
return vssSnapshot{}, err
|
||||
}
|
||||
|
||||
comInterface, err := queryInterface(oleIUnknown, UUID_IVSS)
|
||||
if err != nil {
|
||||
return VssSnapshot{}, err
|
||||
return vssSnapshot{}, err
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -936,39 +936,39 @@ func NewVssSnapshot(provider string,
|
||||
providerID, err := getProviderID(provider)
|
||||
if err != nil {
|
||||
iVssBackupComponents.Release()
|
||||
return VssSnapshot{}, err
|
||||
return vssSnapshot{}, err
|
||||
}
|
||||
|
||||
if err := iVssBackupComponents.InitializeForBackup(); err != nil {
|
||||
iVssBackupComponents.Release()
|
||||
return VssSnapshot{}, err
|
||||
return vssSnapshot{}, err
|
||||
}
|
||||
|
||||
if err := iVssBackupComponents.SetContext(VSS_CTX_BACKUP); err != nil {
|
||||
iVssBackupComponents.Release()
|
||||
return VssSnapshot{}, err
|
||||
return vssSnapshot{}, err
|
||||
}
|
||||
|
||||
// see https://techcommunity.microsoft.com/t5/Storage-at-Microsoft/What-is-the-difference-between-VSS-Full-Backup-and-VSS-Copy/ba-p/423575
|
||||
|
||||
if err := iVssBackupComponents.SetBackupState(false, false, VSS_BT_COPY, false); err != nil {
|
||||
iVssBackupComponents.Release()
|
||||
return VssSnapshot{}, err
|
||||
return vssSnapshot{}, err
|
||||
}
|
||||
|
||||
err = callAsyncFunctionAndWait(iVssBackupComponents.GatherWriterMetadata,
|
||||
"GatherWriterMetadata", deadline)
|
||||
if err != nil {
|
||||
iVssBackupComponents.Release()
|
||||
return VssSnapshot{}, err
|
||||
return vssSnapshot{}, err
|
||||
}
|
||||
|
||||
if isSupported, err := iVssBackupComponents.IsVolumeSupported(providerID, volume); err != nil {
|
||||
iVssBackupComponents.Release()
|
||||
return VssSnapshot{}, err
|
||||
return vssSnapshot{}, err
|
||||
} else if !isSupported {
|
||||
iVssBackupComponents.Release()
|
||||
return VssSnapshot{}, newVssTextError(fmt.Sprintf("Snapshots are not supported for volume "+
|
||||
return vssSnapshot{}, newVssTextError(fmt.Sprintf("Snapshots are not supported for volume "+
|
||||
"%s", volume))
|
||||
}
|
||||
|
||||
@@ -985,7 +985,7 @@ func NewVssSnapshot(provider string,
|
||||
|
||||
if err != nil {
|
||||
iVssBackupComponents.Release()
|
||||
return VssSnapshot{}, err
|
||||
return vssSnapshot{}, err
|
||||
} else {
|
||||
break
|
||||
}
|
||||
@@ -993,10 +993,10 @@ func NewVssSnapshot(provider string,
|
||||
|
||||
if err := iVssBackupComponents.AddToSnapshotSet(volume, providerID, &snapshotSetID); err != nil {
|
||||
iVssBackupComponents.Release()
|
||||
return VssSnapshot{}, err
|
||||
return vssSnapshot{}, err
|
||||
}
|
||||
|
||||
mountPointInfo := make(map[string]MountPoint)
|
||||
mountPointInfo := make(map[string]mountPoint)
|
||||
|
||||
// if filter==nil just don't process mount points for this volume at all
|
||||
if filter != nil {
|
||||
@@ -1004,32 +1004,32 @@ func NewVssSnapshot(provider string,
|
||||
if err != nil {
|
||||
iVssBackupComponents.Release()
|
||||
|
||||
return VssSnapshot{}, newVssTextError(fmt.Sprintf(
|
||||
return vssSnapshot{}, newVssTextError(fmt.Sprintf(
|
||||
"failed to enumerate mount points for volume %s: %s", volume, err))
|
||||
}
|
||||
|
||||
for _, mountPoint := range mountPoints {
|
||||
for _, mp := range mountPoints {
|
||||
// ensure every mountpoint is available even without a valid
|
||||
// snapshot because we need to consider this when backing up files
|
||||
mountPointInfo[mountPoint] = MountPoint{isSnapshotted: false}
|
||||
mountPointInfo[mp] = mountPoint{isSnapshotted: false}
|
||||
|
||||
if !filter(mountPoint) {
|
||||
if !filter(mp) {
|
||||
continue
|
||||
} else if isSupported, err := iVssBackupComponents.IsVolumeSupported(providerID, mountPoint); err != nil {
|
||||
} else if isSupported, err := iVssBackupComponents.IsVolumeSupported(providerID, mp); err != nil {
|
||||
continue
|
||||
} else if !isSupported {
|
||||
continue
|
||||
}
|
||||
|
||||
var mountPointSnapshotSetID ole.GUID
|
||||
err := iVssBackupComponents.AddToSnapshotSet(mountPoint, providerID, &mountPointSnapshotSetID)
|
||||
err := iVssBackupComponents.AddToSnapshotSet(mp, providerID, &mountPointSnapshotSetID)
|
||||
if err != nil {
|
||||
iVssBackupComponents.Release()
|
||||
|
||||
return VssSnapshot{}, err
|
||||
return vssSnapshot{}, err
|
||||
}
|
||||
|
||||
mountPointInfo[mountPoint] = MountPoint{
|
||||
mountPointInfo[mp] = mountPoint{
|
||||
isSnapshotted: true,
|
||||
snapshotSetID: mountPointSnapshotSetID,
|
||||
}
|
||||
@@ -1044,7 +1044,7 @@ func NewVssSnapshot(provider string,
|
||||
// It is not necessary to call BackupComplete before releasing the VSS instance afterwards.
|
||||
iVssBackupComponents.AbortBackup()
|
||||
iVssBackupComponents.Release()
|
||||
return VssSnapshot{}, err
|
||||
return vssSnapshot{}, err
|
||||
}
|
||||
|
||||
err = callAsyncFunctionAndWait(iVssBackupComponents.DoSnapshotSet, "DoSnapshotSet",
|
||||
@@ -1052,15 +1052,15 @@ func NewVssSnapshot(provider string,
|
||||
if err != nil {
|
||||
_ = iVssBackupComponents.AbortBackup()
|
||||
iVssBackupComponents.Release()
|
||||
return VssSnapshot{}, err
|
||||
return vssSnapshot{}, err
|
||||
}
|
||||
|
||||
var snapshotProperties VssSnapshotProperties
|
||||
var snapshotProperties vssSnapshotProperties
|
||||
err = iVssBackupComponents.GetSnapshotProperties(snapshotSetID, &snapshotProperties)
|
||||
if err != nil {
|
||||
_ = iVssBackupComponents.AbortBackup()
|
||||
iVssBackupComponents.Release()
|
||||
return VssSnapshot{}, err
|
||||
return vssSnapshot{}, err
|
||||
}
|
||||
|
||||
for mountPoint, info := range mountPointInfo {
|
||||
@@ -1082,14 +1082,14 @@ func NewVssSnapshot(provider string,
|
||||
mountPointInfo[mountPoint] = info
|
||||
}
|
||||
|
||||
return VssSnapshot{
|
||||
return vssSnapshot{
|
||||
iVssBackupComponents, snapshotSetID, snapshotProperties,
|
||||
snapshotProperties.GetSnapshotDeviceObject(), mountPointInfo, time.Until(deadline),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Delete deletes the created snapshot.
|
||||
func (p *VssSnapshot) Delete() error {
|
||||
func (p *vssSnapshot) Delete() error {
|
||||
var err error
|
||||
if err = vssFreeSnapshotProperties(&p.snapshotProperties); err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user