Friday, March 10, 2017

Preventing Windows OS from sleeping while your python code runs

Do you have a python script that you want to run through to completion, but might take several hours without user interaction?

Might you run on a laptop or other Windows computer that has power management enabled, so that it might go to sleep or hibernate when not being used?

If you do nothing, windows will likely sleep or hibernate before your script can complete.

The following simple piece of code can prevent this problem. When used, it will ask windows not to sleep while the script runs. (In some cases, such as when the battery is running out, Windows will ignore your request.)

class WindowsInhibitor:
    '''Prevent OS sleep/hibernate in windows; code from:
    https://github.com/h3llrais3r/Deluge-PreventSuspendPlus/blob/master/preventsuspendplus/core.py
    API documentation:
    https://msdn.microsoft.com/en-us/library/windows/desktop/aa373208(v=vs.85).aspx'''
    ES_CONTINUOUS = 0x80000000
    ES_SYSTEM_REQUIRED = 0x00000001

    def __init__(self):
        pass

    def inhibit(self):
        import ctypes
        print("Preventing Windows from going to sleep")
        ctypes.windll.kernel32.SetThreadExecutionState(
            WindowsInhibitor.ES_CONTINUOUS | \
            WindowsInhibitor.ES_SYSTEM_REQUIRED)

    def uninhibit(self):
        import ctypes
        print("Allowing Windows to go to sleep")
        ctypes.windll.kernel32.SetThreadExecutionState(
            WindowsInhibitor.ES_CONTINUOUS)


To run it, simply:

import os

osSleep = None
# in Windows, prevent the OS from sleeping while we run
if os.name == 'nt':
    osSleep = WindowsInhibitor()
    osSleep.inhibit()

# do slow stuff

if osSleep:
    osSleep.uninhibit()

It is based on code from here, which also has code for preventing suspension on Linux under GNOME and KDE, should you need that.

Thursday, March 2, 2017

ufsd NTFS driver on mount: Fixing 'Unknown Error 1000'

I've previously mentioned using the ufsd driver for NTFS or HFS+, because it is significantly faster at writing than the default ntfs-3g driver provided with in Linux, and it supports writing for HFS+ drives even with journaling enabled. (It is available free for non-commercial use).

But what happens if you have a hard power down with an NTFS drive mounted? Or you encounter corruption for whatever reason?

UFSD may give this error upon mounting it for read-write:

mount: Unknown error 1000

This error is because the "dirty" flag is set on the drive and ufsd won't mount it read/write for fear of corrupting it. In many simple cases, you can correct errors in Linux with ntfsfix, from the ntfsprogs package, and also use ntfsfix to clear the dirty flag.

So if the volume in question is /dev/sdb1, I could do the following as root while the drive is unmounted. The first command repairs simple issues. The second clears the dirty flag:

root ~ # ntfsfix /dev/sdb1   
root ~ # ntfsfix -d /dev/sdb1

IMPORTANT NOTE: If you have extremely valuable data, especially that was being written when the failures occurred, you should be very cautious, because these commands may cause you to lose data.

A better approach may be to load Windows and run chkdsk /f  (to fix file system errors) or chkdsk /r (to detect and mark bad sectors) on the offending drive. Chkdsk is much more sophisticated at detecting and fixing errors than anything available in Linux, although it too may cause you to lose data (and some data loss may be inevitable if power goes off while writing). Here is one approach (using a bootable CD) to using chkdsk even if you don't have Windows installed or handy.

Final note, if this drive is not critical for your machine and you mount it from fstab, you can add the errors=remount-ro flag to the fstab mount line, in order to avoid hanging up your boot when things go wrong.