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) if fileUtils.isMounted(mountPoint=masterdir): # Try umount, take 1 fileUtils.umount(mountPoint=masterdir) if fileUtils.isMounted(mountPoint=masterdir): # umount failed, try to kill that processes holding mount point fuser_cmd = [constants.EXT_FUSER, "-m", masterdir] (rc, out, err) = misc.execCmd(fuser_cmd) # It was unmounted while I was checking no need to do anything if not fileUtils.isMounted(mountPoint=masterdir): return cls.log.warn(out) if len(out) == 0: cls.log.warn( "Unmount failed because of errors that fuser can't solve" ) else: for match in out[0].split(): try: pid = int(match) except ValueError: # Match can be "kernel" continue try: cls.log.debug("Trying to kill pid %d", pid) os.kill(pid, signal.SIGKILL) except OSError, e: if e.errno == errno.ESRCH: # No such process pass elif e.errno == errno.EPERM: # Operation 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)
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) if fileUtils.isMounted(mountPoint=masterdir): # Try umount, take 1 fileUtils.umount(mountPoint=masterdir) if fileUtils.isMounted(mountPoint=masterdir): # umount failed, try to kill that processes holding mount point fuser_cmd = [constants.EXT_FUSER, "-m", masterdir] (rc, out, err) = misc.execCmd(fuser_cmd) # It was unmounted while I was checking no need to do anything if not fileUtils.isMounted(mountPoint=masterdir): return cls.log.warn(out) if len(out) == 0: cls.log.warn("Unmount failed because of errors that fuser can't solve") else: for match in out[0].split(): try: pid = int(match) except ValueError: # Match can be "kernel" continue try: cls.log.debug("Trying to kill pid %d", pid) os.kill(pid, signal.SIGKILL) except OSError, e: if e.errno == errno.ESRCH: # No such process pass elif e.errno == errno.EPERM: # Operation 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)
def __handleStuckUmount(cls, masterDir): umountPids = misc.pgrep("umount") for umountPid in umountPids: try: state = misc.pidStat(umountPid)[2] mountPoint = misc.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 possiblity 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: rc = fileUtils.umount(mountPoint=masterDir) if rc == 0: return except: # 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 = misc.pgrep("umount") for umountPid in umountPids: try: state = misc.pidStat(umountPid)[2] mountPoint = misc.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 possiblity 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: rc = fileUtils.umount(mountPoint=masterDir) if rc == 0: return except: # 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)
try: cls.log.debug("Trying to kill pid %d", pid) os.kill(pid, signal.SIGKILL) except OSError, e: if e.errno == errno.ESRCH: # No such process pass elif e.errno == errno.EPERM: # Operation 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 fileUtils.umount(mountPoint=masterdir) if fileUtils.isMounted(mountPoint=masterdir): # We failed to umount masterFS # Forcibly rebooting the SPM host would be safer. ??? raise se.StorageDomainMasterUnmountError(masterdir, rc) def unmountMaster(self): """ Unmount the master metadata file system. Should be called only by SPM. """ masterdir = os.path.join(self.domaindir, sd.MASTER_FS_DIR) self.doUnmountMaster(masterdir) # It is time to deactivate the master LV now lvm.deactivateLVs(self.sdUUID, MASTERLV)
pass elif e.errno == errno.EPERM: # Operation 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 fileUtils.umount(mountPoint=masterdir) if fileUtils.isMounted(mountPoint=masterdir): # We failed to umount masterFS # Forcibly rebooting the SPM host would be safer. ??? raise se.StorageDomainMasterUnmountError(masterdir, rc) def unmountMaster(self): """ Unmount the master metadata file system. Should be called only by SPM. """ masterdir = os.path.join(self.domaindir, sd.MASTER_FS_DIR) self.doUnmountMaster(masterdir) # It is time to deactivate the master LV now lvm.deactivateLVs(self.sdUUID, MASTERLV) def refreshDirTree(self):