<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def softDeactivate(rh):
 """ Deactivate a virtual machine by first shutting down Linux and then log it off. Input: Request Handle with the following properties: function - 'POWERVM' subfunction - 'SOFTOFF' userid - userid of the virtual machine parms['maxQueries'] - Maximum number of queries to issue. Optional. parms['maxWait'] - Maximum time to wait in seconds. Optional, unless 'maxQueries' is specified. parms['poll'] - Polling interval in seconds. Optional, unless 'maxQueries' is specified. Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """


    rh.printSysLog("Enter powerVM.softDeactivate, userid: " +
        rh.userid)

    strCmd = "echo 'ping'"
    iucvResults = execCmdThruIUCV(rh, rh.userid, strCmd)

    if iucvResults['overallRC'] == 0:
        # We could talk to the machine, tell it to shutdown nicely.
        strCmd = "shutdown -h now"
        iucvResults = execCmdThruIUCV(rh, rh.userid, strCmd)
        if iucvResults['overallRC'] == 0:
            time.sleep(15)
        else:
            # Shutdown failed.  Let CP take down the system
            # after we log the results.
            rh.printSysLog("powerVM.softDeactivate " + rh.userid +
                " is unreachable. Treating it as already shutdown.")
    else:
        # Could not ping the machine.  Treat it as a success
        # after we log the results.
        rh.printSysLog("powerVM.softDeactivate " + rh.userid +
            " is unreachable. Treating it as already shutdown.")

    # Tell z/VM to log off the system.
    parms = ["-T", rh.userid]
    smcliResults = invokeSMCLI(rh, "Image_Deactivate", parms)
    if smcliResults['overallRC'] == 0:
        pass
    elif (smcliResults['overallRC'] == 8 and smcliResults['rc'] == 200 and
        (smcliResults['rs'] == 12 or + smcliResults['rs'] == 16)):
        # Tolerable error.
        # Machine is already logged off or is logging off.
        rh.printLn("N", rh.userid + " is already logged off.")
    else:
        # SMAPI API failed.
        rh.printLn("ES", smcliResults['response'])
        rh.updateResults(smcliResults)    # Use results from invokeSMCLI

    if rh.results['overallRC'] == 0 and 'maxQueries' in rh.parms:
        # Wait for the system to log off.
        waitResults = waitForVMState(
            rh,
            rh.userid,
            'off',
            maxQueries=rh.parms['maxQueries'],
            sleepSecs=rh.parms['poll'])
        if waitResults['overallRC'] == 0:
            rh.printLn("N", "Userid '" + rh.userid +
                " is in the desired state: off")
        else:
            rh.updateResults(waitResults)

    rh.printSysLog("Exit powerVM.softDeactivate, rc: " +
        str(rh.results['overallRC']))
    return rh.results['overallRC']