func (b *downwardAPIVolumeBuilder) SetUpAt(dir string, fsGroup *int64) error { glog.V(3).Infof("Setting up a downwardAPI volume %v for pod %v/%v at %v", b.volName, b.pod.Namespace, b.pod.Name, dir) // Wrap EmptyDir. Here we rely on the idempotency of the wrapped plugin to avoid repeatedly mounting wrapped, err := b.plugin.host.NewWrapperBuilder(b.volName, wrappedVolumeSpec, b.pod, *b.opts) if err != nil { glog.Errorf("Couldn't setup downwardAPI volume %v for pod %v/%v: %s", b.volName, b.pod.Namespace, b.pod.Name, err.Error()) return err } if err := wrapped.SetUpAt(dir, fsGroup); err != nil { glog.Errorf("Unable to setup downwardAPI volume %v for pod %v/%v: %s", b.volName, b.pod.Namespace, b.pod.Name, err.Error()) return err } data, err := b.collectData() if err != nil { glog.Errorf("Error preparing data for downwardAPI volume %v for pod %v/%v: %s", b.volName, b.pod.Namespace, b.pod.Name, err.Error()) return err } if !b.isDataChanged(data) { // No data changed: nothing to write return nil } if err := b.writeData(data); err != nil { glog.Errorf("Unable to dump files for downwardAPI volume %v for pod %v/%v: %s", b.volName, b.pod.Namespace, b.pod.Name, err.Error()) return err } glog.V(3).Infof("Data dumped for downwardAPI volume %v for pod %v/%v", b.volName, b.pod.Namespace, b.pod.Name) volume.SetVolumeOwnership(b, fsGroup) return nil }
func (b *secretVolumeBuilder) SetUpAt(dir string, fsGroup *int64) error { notMnt, err := b.mounter.IsLikelyNotMountPoint(dir) // Getting an os.IsNotExist err from is a contingency; the directory // may not exist yet, in which case, setup should run. if err != nil && !os.IsNotExist(err) { return err } // If the plugin readiness file is present for this volume and // the setup dir is a mountpoint, this volume is already ready. if volumeutil.IsReady(b.getMetaDir()) && !notMnt { return nil } glog.V(3).Infof("Setting up volume %v for pod %v at %v", b.volName, b.pod.UID, dir) // Wrap EmptyDir, let it do the setup. wrapped, err := b.plugin.host.NewWrapperBuilder(b.volName, wrappedVolumeSpec, &b.pod, *b.opts) if err != nil { return err } if err := wrapped.SetUpAt(dir, fsGroup); err != nil { return err } kubeClient := b.plugin.host.GetKubeClient() if kubeClient == nil { return fmt.Errorf("Cannot setup secret volume %v because kube client is not configured", b.volName) } secret, err := kubeClient.Core().Secrets(b.pod.Namespace).Get(b.secretName) if err != nil { glog.Errorf("Couldn't get secret %v/%v", b.pod.Namespace, b.secretName) return err } else { totalBytes := totalSecretBytes(secret) glog.V(3).Infof("Received secret %v/%v containing (%v) pieces of data, %v total bytes", b.pod.Namespace, b.secretName, len(secret.Data), totalBytes) } for name, data := range secret.Data { hostFilePath := path.Join(dir, name) glog.V(3).Infof("Writing secret data %v/%v/%v (%v bytes) to host file %v", b.pod.Namespace, b.secretName, name, len(data), hostFilePath) err := b.writer.WriteFile(hostFilePath, data, 0444) if err != nil { glog.Errorf("Error writing secret data to host path: %v, %v", hostFilePath, err) return err } } volume.SetVolumeOwnership(b, fsGroup) volumeutil.SetReady(b.getMetaDir()) return nil }
// SetUpAt attaches the disk and bind mounts to the volume path. func (b *awsElasticBlockStoreMounter) SetUpAt(dir string, fsGroup *int64) error { // TODO: handle failed mounts here. notMnt, err := b.mounter.IsLikelyNotMountPoint(dir) glog.V(4).Infof("PersistentDisk set up: %s %v %v", dir, !notMnt, err) if err != nil && !os.IsNotExist(err) { glog.Errorf("cannot validate mount point: %s %v", dir, err) return err } if !notMnt { return nil } globalPDPath := makeGlobalPDPath(b.plugin.host, b.volumeID) if err := os.MkdirAll(dir, 0750); err != nil { return err } // Perform a bind mount to the full path to allow duplicate mounts of the same PD. options := []string{"bind"} if b.readOnly { options = append(options, "ro") } err = b.mounter.Mount(globalPDPath, dir, "", options) if err != nil { notMnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("IsLikelyNotMountPoint check failed for %s: %v", dir, mntErr) return err } if !notMnt { if mntErr = b.mounter.Unmount(dir); mntErr != nil { glog.Errorf("failed to unmount %s: %v", dir, mntErr) return err } notMnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("IsLikelyNotMountPoint check failed for %s: %v", dir, mntErr) return err } if !notMnt { // This is very odd, we don't expect it. We'll try again next sync loop. glog.Errorf("%s is still mounted, despite call to unmount(). Will try again next sync loop.", dir) return err } } os.Remove(dir) glog.Errorf("Mount of disk %s failed: %v", dir, err) return err } if !b.readOnly { volume.SetVolumeOwnership(b, fsGroup) } glog.V(4).Infof("Successfully mounted %s", dir) return nil }
func (b *configMapVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { glog.V(3).Infof("Setting up volume %v for pod %v at %v", b.volName, b.pod.UID, dir) // Wrap EmptyDir, let it do the setup. wrapped, err := b.plugin.host.NewWrapperMounter(b.volName, wrappedVolumeSpec, &b.pod, *b.opts) if err != nil { return err } if err := wrapped.SetUpAt(dir, fsGroup); err != nil { return err } kubeClient := b.plugin.host.GetKubeClient() if kubeClient == nil { return fmt.Errorf("Cannot setup configMap volume %v because kube client is not configured", b.volName) } configMap, err := kubeClient.Core().ConfigMaps(b.pod.Namespace).Get(b.source.Name) if err != nil { glog.Errorf("Couldn't get configMap %v/%v: %v", b.pod.Namespace, b.source.Name, err) return err } totalBytes := totalBytes(configMap) glog.V(3).Infof("Received configMap %v/%v containing (%v) pieces of data, %v total bytes", b.pod.Namespace, b.source.Name, len(configMap.Data), totalBytes) payload, err := makePayload(b.source.Items, configMap) if err != nil { return err } writerContext := fmt.Sprintf("pod %v/%v volume %v", b.pod.Namespace, b.pod.Name, b.volName) writer, err := volumeutil.NewAtomicWriter(dir, writerContext) if err != nil { glog.Errorf("Error creating atomic writer: %v", err) return err } err = writer.Write(payload) if err != nil { glog.Errorf("Error writing payload to dir: %v", err) return err } err = volume.SetVolumeOwnership(b, fsGroup) if err != nil { glog.Errorf("Error applying volume ownership settings for group: %v", fsGroup) return err } return nil }
// SetUp attaches the disk and bind mounts to the volume path. func (b *vsphereVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { glog.V(5).Infof("vSphere volume setup %s to %s", b.volPath, dir) // TODO: handle failed mounts here. notmnt, err := b.mounter.IsLikelyNotMountPoint(dir) if err != nil && !os.IsNotExist(err) { glog.V(4).Infof("IsLikelyNotMountPoint failed: %v", err) return err } if !notmnt { glog.V(4).Infof("Something is already mounted to target %s", dir) return nil } if err := os.MkdirAll(dir, 0750); err != nil { glog.V(4).Infof("Could not create directory %s: %v", dir, err) return err } options := []string{"bind"} // Perform a bind mount to the full path to allow duplicate mounts of the same PD. globalPDPath := makeGlobalPDPath(b.plugin.host, b.volPath) err = b.mounter.Mount(globalPDPath, dir, "", options) if err != nil { notmnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) return err } if !notmnt { if mntErr = b.mounter.Unmount(dir); mntErr != nil { glog.Errorf("Failed to unmount: %v", mntErr) return err } notmnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) return err } if !notmnt { glog.Errorf("%s is still mounted, despite call to unmount(). Will try again next sync loop.", b.GetPath()) return err } } os.Remove(dir) return err } volume.SetVolumeOwnership(b, fsGroup) glog.V(3).Infof("vSphere volume %s mounted to %s", b.volPath, dir) return nil }
// SetUpAt creates new directory. func (ed *emptyDir) SetUpAt(dir string, fsGroup *int64) error { notMnt, err := ed.mounter.IsLikelyNotMountPoint(dir) // Getting an os.IsNotExist err from is a contingency; the directory // may not exist yet, in which case, setup should run. if err != nil && !os.IsNotExist(err) { return err } // If the plugin readiness file is present for this volume, and the // storage medium is the default, then the volume is ready. If the // medium is memory, and a mountpoint is present, then the volume is // ready. if volumeutil.IsReady(ed.getMetaDir()) { if ed.medium == api.StorageMediumMemory && !notMnt { return nil } else if ed.medium == api.StorageMediumDefault { return nil } } // Determine the effective SELinuxOptions to use for this volume. securityContext := "" if selinuxEnabled() { securityContext = ed.rootContext } switch ed.medium { case api.StorageMediumDefault: err = ed.setupDir(dir) case api.StorageMediumMemory: err = ed.setupTmpfs(dir, securityContext) default: err = fmt.Errorf("unknown storage medium %q", ed.medium) } volume.SetVolumeOwnership(ed, fsGroup) if err == nil { volumeutil.SetReady(ed.getMetaDir()) } return err }
func (b *downwardAPIVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { glog.V(3).Infof("Setting up a downwardAPI volume %v for pod %v/%v at %v", b.volName, b.pod.Namespace, b.pod.Name, dir) // Wrap EmptyDir. Here we rely on the idempotency of the wrapped plugin to avoid repeatedly mounting wrapped, err := b.plugin.host.NewWrapperMounter(b.volName, wrappedVolumeSpec(), b.pod, *b.opts) if err != nil { glog.Errorf("Couldn't setup downwardAPI volume %v for pod %v/%v: %s", b.volName, b.pod.Namespace, b.pod.Name, err.Error()) return err } if err := wrapped.SetUpAt(dir, fsGroup); err != nil { glog.Errorf("Unable to setup downwardAPI volume %v for pod %v/%v: %s", b.volName, b.pod.Namespace, b.pod.Name, err.Error()) return err } data, err := b.collectData(b.source.DefaultMode) if err != nil { glog.Errorf("Error preparing data for downwardAPI volume %v for pod %v/%v: %s", b.volName, b.pod.Namespace, b.pod.Name, err.Error()) return err } writerContext := fmt.Sprintf("pod %v/%v volume %v", b.pod.Namespace, b.pod.Name, b.volName) writer, err := volumeutil.NewAtomicWriter(dir, writerContext) if err != nil { glog.Errorf("Error creating atomic writer: %v", err) return err } err = writer.Write(data) if err != nil { glog.Errorf("Error writing payload to dir: %v", err) return err } err = volume.SetVolumeOwnership(b, fsGroup) if err != nil { glog.Errorf("Error applying volume ownership settings for group: %v", fsGroup) return err } return nil }
// utility to mount a disk based filesystem func diskSetUp(manager diskManager, b rbdMounter, volPath string, mounter mount.Interface, fsGroup *int64) error { globalPDPath := manager.MakeGlobalPDName(*b.rbd) // TODO: handle failed mounts here. notMnt, err := mounter.IsLikelyNotMountPoint(volPath) if err != nil && !os.IsNotExist(err) { glog.Errorf("cannot validate mountpoint: %s", volPath) return err } if !notMnt { return nil } if err := manager.AttachDisk(b); err != nil { glog.Errorf("failed to attach disk") return err } if err := os.MkdirAll(volPath, 0750); err != nil { glog.Errorf("failed to mkdir:%s", volPath) return err } // Perform a bind mount to the full path to allow duplicate mounts of the same disk. options := []string{"bind"} if (&b).GetAttributes().ReadOnly { options = append(options, "ro") } err = mounter.Mount(globalPDPath, volPath, "", options) if err != nil { glog.Errorf("failed to bind mount:%s", globalPDPath) return err } if !b.ReadOnly { volume.SetVolumeOwnership(&b, fsGroup) } return nil }
// SetUp bind mounts to the volume path. func (b *cinderVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { glog.V(5).Infof("Cinder SetUp %s to %s", b.pdName, dir) b.plugin.volumeLocks.LockKey(b.pdName) defer b.plugin.volumeLocks.UnlockKey(b.pdName) // TODO: handle failed mounts here. notmnt, err := b.mounter.IsLikelyNotMountPoint(dir) if err != nil && !os.IsNotExist(err) { glog.Errorf("Cannot validate mount point: %s %v", dir, err) return err } if !notmnt { glog.V(4).Infof("Something is already mounted to target %s", dir) return nil } globalPDPath := makeGlobalPDName(b.plugin.host, b.pdName) options := []string{"bind"} if b.readOnly { options = append(options, "ro") } if err := os.MkdirAll(dir, 0750); err != nil { // TODO: we should really eject the attach/detach out into its own control loop. glog.V(4).Infof("Could not create directory %s: %v", dir, err) detachDiskLogError(b.cinderVolume) return err } // Perform a bind mount to the full path to allow duplicate mounts of the same PD. glog.V(4).Infof("Attempting to mount cinder volume %s to %s with options %v", b.pdName, dir, options) err = b.mounter.Mount(globalPDPath, dir, "", options) if err != nil { glog.V(4).Infof("Mount failed: %v", err) notmnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) return err } if !notmnt { if mntErr = b.mounter.Unmount(dir); mntErr != nil { glog.Errorf("Failed to unmount: %v", mntErr) return err } notmnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) return err } if !notmnt { // This is very odd, we don't expect it. We'll try again next sync loop. glog.Errorf("%s is still mounted, despite call to unmount(). Will try again next sync loop.", b.GetPath()) return err } } os.Remove(dir) // TODO: we should really eject the attach/detach out into its own control loop. detachDiskLogError(b.cinderVolume) glog.Errorf("Failed to mount %s: %v", dir, err) return err } if !b.readOnly { volume.SetVolumeOwnership(b, fsGroup) } glog.V(3).Infof("Cinder volume %s mounted to %s", b.pdName, dir) return nil }
// SetUp bind mounts to the volume path. func (b *cinderVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { glog.V(5).Infof("Cinder SetUp %s to %s", b.pdName, dir) b.plugin.volumeLocks.LockKey(b.pdName) defer b.plugin.volumeLocks.UnlockKey(b.pdName) // TODO: handle failed mounts here. notmnt, err := b.mounter.IsLikelyNotMountPoint(dir) if err != nil && !os.IsNotExist(err) { glog.V(4).Infof("IsLikelyNotMountPoint failed: %v", err) return err } if !notmnt { glog.V(4).Infof("Something is already mounted to target %s", dir) return nil } globalPDPath := makeGlobalPDName(b.plugin.host, b.pdName) // NOTE(harryz): In hyper case, we use manager to attach disk. But this should be refactored into cinder.attacher // after cinderVolume.manager is removed. if !b.withOpenStackCP && b.isNoMountSupported { if err := b.manager.AttachDisk(b, globalPDPath); err != nil { glog.V(4).Infof("AttachDisk failed: %v", err) return err } glog.V(3).Infof("Cinder volume %s attached", b.pdName) } // NOTE END if err := os.MkdirAll(dir, 0750); err != nil { // TODO: we should really eject the attach/detach out into its own control loop. glog.V(4).Infof("Could not create directory %s: %v", dir, err) detachDiskLogError(b.cinderVolume, b.isNoMountSupported) return err } // Without openstack cloud provider, create a tag file if !b.withOpenStackCP && b.isNoMountSupported { fw, err := os.Create(path.Join(dir, OpenStackCloudProviderTagFile)) if err != nil { os.Remove(dir) detachDiskLogError(b.cinderVolume, b.isNoMountSupported) return err } _, err = fw.WriteString(b.pdName) if err != nil { os.Remove(dir) detachDiskLogError(b.cinderVolume, b.isNoMountSupported) return err } fw.Close() return nil } options := []string{"bind"} if b.readOnly { options = append(options, "ro") } // Perform a bind mount to the full path to allow duplicate mounts of the same PD. err = b.mounter.Mount(globalPDPath, dir, "", options) if err != nil { glog.V(4).Infof("Mount failed: %v", err) notmnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) return err } if !notmnt { if mntErr = b.mounter.Unmount(dir); mntErr != nil { glog.Errorf("Failed to unmount: %v", mntErr) return err } notmnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) return err } if !notmnt { // This is very odd, we don't expect it. We'll try again next sync loop. glog.Errorf("%s is still mounted, despite call to unmount(). Will try again next sync loop.", b.GetPath()) return err } } os.Remove(dir) // TODO: we should really eject the attach/detach out into its own control loop. detachDiskLogError(b.cinderVolume, b.isNoMountSupported) return err } if !b.readOnly { volume.SetVolumeOwnership(b, fsGroup) } glog.V(3).Infof("Cinder volume %s mounted to %s", b.pdName, dir) return nil }
/* SetUpAt will setup a Flocker volume following this flow of calls to the Flocker control service: 1. Get the dataset id for the given volume name/dir 2. It should already be there, if it's not the user needs to manually create it 3. Check the current Primary UUID 4. If it doesn't match with the Primary UUID that we got on 2, then we will need to update the Primary UUID for this volume. 5. Wait until the Primary UUID was updated or timeout. */ func (b *flockerVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { var err error if b.flockerClient == nil { b.flockerClient, err = b.newFlockerClient() if err != nil { return err } } datasetUUID, err := b.GetDatasetUUID() if err != nil { return fmt.Errorf("The datasetUUID for volume with datasetName='%s' can not be found using flocker: %s", b.datasetName, err) } datasetState, err := b.flockerClient.GetDatasetState(datasetUUID) if err != nil { return fmt.Errorf("The datasetState for volume with datasetUUID='%s' could not determinted uusing flocker: %s", datasetUUID, err) } primaryUUID, err := b.flockerClient.GetPrimaryUUID() if err != nil { return err } if datasetState.Primary != primaryUUID { if err := b.updateDatasetPrimary(datasetUUID, primaryUUID); err != nil { return err } _, err := b.flockerClient.GetDatasetState(datasetUUID) if err != nil { return fmt.Errorf("The volume with datasetUUID='%s' migrated unsuccessfully.", datasetUUID) } } // TODO: handle failed mounts here. notMnt, err := b.mounter.IsLikelyNotMountPoint(dir) glog.V(4).Infof("flockerVolume set up: %s %v %v, datasetUUID %v readOnly %v", dir, !notMnt, err, datasetUUID, b.readOnly) if err != nil && !os.IsNotExist(err) { glog.Errorf("cannot validate mount point: %s %v", dir, err) return err } if !notMnt { return nil } if err := os.MkdirAll(dir, 0750); err != nil { glog.Errorf("mkdir failed on disk %s (%v)", dir, err) return err } // Perform a bind mount to the full path to allow duplicate mounts of the same PD. options := []string{"bind"} if b.readOnly { options = append(options, "ro") } globalFlockerPath := makeGlobalFlockerPath(datasetUUID) glog.V(4).Infof("attempting to mount %s", dir) err = b.mounter.Mount(globalFlockerPath, dir, "", options) if err != nil { notMnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("isLikelyNotMountPoint check failed: %v", mntErr) return err } if !notMnt { if mntErr = b.mounter.Unmount(dir); mntErr != nil { glog.Errorf("failed to unmount: %v", mntErr) return err } notMnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("isLikelyNotMountPoint check failed: %v", mntErr) return err } if !notMnt { // This is very odd, we don't expect it. We'll try again next sync loop. glog.Errorf("%s is still mounted, despite call to unmount(). Will try again next sync loop.", dir) return err } } os.Remove(dir) glog.Errorf("mount of disk %s failed: %v", dir, err) return err } if !b.readOnly { volume.SetVolumeOwnership(b, fsGroup) } glog.V(4).Infof("successfully mounted %s", dir) return nil }
// SetUpAt creates new directory and clones a git repo. func (b *gitRepoVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { if volumeutil.IsReady(b.getMetaDir()) { return nil } // Wrap EmptyDir, let it do the setup. wrapped, err := b.plugin.host.NewWrapperMounter(b.volName, wrappedVolumeSpec(), &b.pod, b.opts) if err != nil { return err } if err := wrapped.SetUpAt(dir, fsGroup); err != nil { return err } args := []string{"clone", b.source} if len(b.target) != 0 { args = append(args, b.target) } if output, err := b.execCommand("git", args, dir); err != nil { return fmt.Errorf("failed to exec 'git %s': %s: %v", strings.Join(args, " "), output, err) } files, err := ioutil.ReadDir(dir) if err != nil { return err } if len(b.revision) == 0 { // Done! volumeutil.SetReady(b.getMetaDir()) return nil } var subdir string switch { case b.target == ".": // if target dir is '.', use the current dir subdir = path.Join(dir) case len(files) == 1: // if target is not '.', use the generated folder subdir = path.Join(dir, files[0].Name()) default: // if target is not '.', but generated many files, it's wrong return fmt.Errorf("unexpected directory contents: %v", files) } if output, err := b.execCommand("git", []string{"checkout", b.revision}, subdir); err != nil { return fmt.Errorf("failed to exec 'git checkout %s': %s: %v", b.revision, output, err) } if output, err := b.execCommand("git", []string{"reset", "--hard"}, subdir); err != nil { return fmt.Errorf("failed to exec 'git reset --hard': %s: %v", output, err) } volume.SetVolumeOwnership(b, fsGroup) volumeutil.SetReady(b.getMetaDir()) return nil }
// SetUpAt attaches the disk and bind mounts to the volume path. func (b *azureDiskMounter) SetUpAt(dir string, fsGroup *int64) error { b.plugin.volumeLocks.LockKey(b.diskName) defer b.plugin.volumeLocks.UnlockKey(b.diskName) // TODO: handle failed mounts here. notMnt, err := b.mounter.IsLikelyNotMountPoint(dir) glog.V(4).Infof("DataDisk set up: %s %v %v", dir, !notMnt, err) if err != nil && !os.IsNotExist(err) { glog.Errorf("IsLikelyNotMountPoint failed: %v", err) return err } if !notMnt { glog.V(4).Infof("%s is a mount point", dir) return nil } globalPDPath := makeGlobalPDPath(b.plugin.host, b.diskName) if err := os.MkdirAll(dir, 0750); err != nil { glog.V(4).Infof("Could not create directory %s: %v", dir, err) return err } // Perform a bind mount to the full path to allow duplicate mounts of the same PD. options := []string{"bind"} if b.readOnly { options = append(options, "ro") } err = b.mounter.Mount(globalPDPath, dir, "", options) if err != nil { notMnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) return err } if !notMnt { if mntErr = b.mounter.Unmount(dir); mntErr != nil { glog.Errorf("Failed to unmount: %v", mntErr) return err } notMnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) return err } if !notMnt { // This is very odd, we don't expect it. We'll try again next sync loop. glog.Errorf("%s is still mounted, despite call to unmount(). Will try again next sync loop.", dir) return err } } os.Remove(dir) return err } if !b.readOnly { volume.SetVolumeOwnership(b, fsGroup) } glog.V(3).Infof("Azure disk volume %s mounted to %s", b.diskName, dir) return nil }
// SetUpAt attaches the disk and bind mounts to the volume path. func (b *awsElasticBlockStoreBuilder) SetUpAt(dir string, fsGroup *int64) error { // TODO: handle failed mounts here. notMnt, err := b.mounter.IsLikelyNotMountPoint(dir) glog.V(4).Infof("PersistentDisk set up: %s %v %v", dir, !notMnt, err) if err != nil && !os.IsNotExist(err) { return err } if !notMnt { return nil } globalPDPath := makeGlobalPDPath(b.plugin.host, b.volumeID) if err := b.manager.AttachAndMountDisk(b, globalPDPath); err != nil { return err } if err := os.MkdirAll(dir, 0750); err != nil { // TODO: we should really eject the attach/detach out into its own control loop. detachDiskLogError(b.awsElasticBlockStore) return err } // Perform a bind mount to the full path to allow duplicate mounts of the same PD. options := []string{"bind"} if b.readOnly { options = append(options, "ro") } err = b.mounter.Mount(globalPDPath, dir, "", options) if err != nil { notMnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) return err } if !notMnt { if mntErr = b.mounter.Unmount(dir); mntErr != nil { glog.Errorf("Failed to unmount: %v", mntErr) return err } notMnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) return err } if !notMnt { // This is very odd, we don't expect it. We'll try again next sync loop. glog.Errorf("%s is still mounted, despite call to unmount(). Will try again next sync loop.", dir) return err } } os.Remove(dir) // TODO: we should really eject the attach/detach out into its own control loop. detachDiskLogError(b.awsElasticBlockStore) return err } if !b.readOnly { volume.SetVolumeOwnership(b, fsGroup) } return nil }