def doUnmountMaster(cls, masterdir): """ Unmount the master metadata file system. Should be called only by SPM. """ # fuser processes holding mount point and validate that the umount # succeeded cls.__handleStuckUmount(masterdir) try: masterMount = mount.getMountFromTarget(masterdir) except OSError as ex: if ex.errno == errno.ENOENT: return raise if masterMount.isMounted(): # Try umount, take 1 try: masterMount.umount() except mount.MountError: # umount failed, try to kill that processes holding mount point svdsmp = svdsm.getProxy() pids = svdsmp.fuser(masterMount.fs_file, mountPoint=True) # It was unmounted while I was checking no need to do anything if not masterMount.isMounted(): return if len(pids) == 0: cls.log.warn("Unmount failed because of errors that fuser " "can't solve") else: for pid in pids: try: cls.log.debug("Trying to kill pid %d", pid) os.kill(pid, signal.SIGKILL) except OSError as e: if e.errno == errno.ESRCH: # No such process pass elif e.errno == errno.EPERM: # Op. not permitted cls.log.warn("Could not kill pid %d because " "operation was not permitted", pid) else: cls.log.warn("Could not kill pid %d because an" " unexpected error", exc_info=True) except: cls.log.warn("Could not kill pid %d because an " "unexpected error", exc_info=True) # Try umount, take 2 try: masterMount.umount() except mount.MountError: pass if masterMount.isMounted(): # We failed to umount masterFS # Forcibly rebooting the SPM host would be safer. ??? raise se.StorageDomainMasterUnmountError(masterdir, 1)
def selftest(self): """ Run internal self test """ try: self.oop.os.statvfs(self.domaindir) except OSError as e: if e.errno == errno.ESTALE: # In case it is "Stale NFS handle" we are taking preventive # measures and unmounting this NFS resource. Chances are # that is the most intelligent thing we can do in this # situation anyway. self.log.debug("Unmounting stale file system %s", self.mountpoint) mount.getMountFromTarget(self.mountpoint).umount() raise se.FileStorageDomainStaleNFSHandle() raise
def __handleStuckUmount(cls, masterDir): umountPids = utils.pgrep("umount") try: masterMount = mount.getMountFromTarget(masterDir) except OSError as ex: if ex.errno == errno.ENOENT: return raise for umountPid in umountPids: try: state = utils.pidStat(umountPid).state mountPoint = utils.getCmdArgs(umountPid)[-1] except: # Process probably exited continue if mountPoint != masterDir: continue if state != "D": # If the umount is not in d state there # is a possibility that the world might # be in flux and umount will get stuck # in an unkillable state that is not D # which I don't know about, perhaps a # bug in umount will cause umount to # wait for something unrelated that is # not the syscall. Waiting on a process # which is not your child is race prone # I will just call for another umount # and wait for it to finish. That way I # know that a umount ended. try: masterMount.umount() except mount.MountError: # timeout! we are stuck again. # if you are here spmprotect forgot to # reboot the machine but in any case # continue with the disconnection. pass try: vgName = masterDir.rsplit("/", 2)[1] masterDev = os.path.join( "/dev/mapper", vgName.replace("-", "--") + "-" + MASTERLV) except KeyError: # Umount succeeded after all return cls.log.warn( "master mount resource is `%s`, trying to disconnect " "underlying storage", masterDev) iscsi.disconnectFromUndelyingStorage(masterDev)
def __handleStuckUmount(cls, masterDir): umountPids = utils.pgrep("umount") try: masterMount = mount.getMountFromTarget(masterDir) except OSError as ex: if ex.errno == errno.ENOENT: return raise for umountPid in umountPids: try: state = utils.pidStat(umountPid).state mountPoint = utils.getCmdArgs(umountPid)[-1] except: # Process probably exited continue if mountPoint != masterDir: continue if state != "D": # If the umount is not in d state there # is a possibility that the world might # be in flux and umount will get stuck # in an unkillable state that is not D # which I don't know about, perhaps a # bug in umount will cause umount to # wait for something unrelated that is # not the syscall. Waiting on a process # which is not your child is race prone # I will just call for another umount # and wait for it to finish. That way I # know that a umount ended. try: masterMount.umount() except mount.MountError: # timeout! we are stuck again. # if you are here spmprotect forgot to # reboot the machine but in any case # continue with the disconnection. pass try: vgName = masterDir.rsplit("/", 2)[1] masterDev = os.path.join( "/dev/mapper", vgName.replace("-", "--") + "-" + MASTERLV) except KeyError: # Umount succeeded after all return cls.log.warn("master mount resource is `%s`, trying to disconnect " "underlying storage", masterDev) iscsi.disconnectFromUndelyingStorage(masterDev)
def getRealPath(self): try: return mount.getMountFromTarget(self.mountpoint).fs_spec except mount.MountError: return ""