diff --git a/dentos-poe-agent/opt/poeagent/bin/poecli.py b/dentos-poe-agent/opt/poeagent/bin/poecli.py index e626297..a261891 100755 --- a/dentos-poe-agent/opt/poeagent/bin/poecli.py +++ b/dentos-poe-agent/opt/poeagent/bin/poecli.py @@ -24,6 +24,7 @@ import imp import sys import subprocess +import stat import os import argparse import time @@ -422,8 +423,13 @@ def is_poed_alive(self): def send_ipc_event(self, action=POECLI_SET): try: - with open(POE_IPC_EVT, "w") as f: - f.write(action) + if check_file(POE_IPC_EVT) == True: + if stat.S_ISFIFO(os.stat(POE_IPC_EVT).st_mode) == False: + print_stderr( + "Invalid IPC channel: {0}".format(POE_IPC_EVT)) + return + with open(POE_IPC_EVT, "w") as f: + f.write(action) except Exception as e: pass @@ -500,7 +506,15 @@ def main(argv): if set_flag == True and poed_alive == True: poecli.send_ipc_event() elif len(cfg_action)>0 and poed_alive == True: + touch_file(POED_BUSY_FLAG) poecli.send_ipc_event(cfg_action) + if wait_poed_busy(title="Wait cfg action", timeout=SAVE_FILE_TIMEOUT) == True: + print_stderr("done") + if check_file(POED_BUSY_FLAG): + remove_file(POED_BUSY_FLAG) + + + if __name__ == '__main__': main(sys.argv) diff --git a/dentos-poe-agent/opt/poeagent/bin/poed.py b/dentos-poe-agent/opt/poeagent/bin/poed.py index 97f76aa..b66845f 100755 --- a/dentos-poe-agent/opt/poeagent/bin/poed.py +++ b/dentos-poe-agent/opt/poeagent/bin/poed.py @@ -21,6 +21,7 @@ from pathlib import Path import os +import stat import sys import errno import threading @@ -39,6 +40,7 @@ TIME_FMT = "%Y/%m/%d %H:%M:%S" thread_flag = True +ipc_busy = False class PoeAgentState(object): CLEAN_START = 0 @@ -82,13 +84,15 @@ def is_valid_gen_info(self, gen_info): self.is_valid_poe_cfg_ver(gen_info[POE_CFG_VER]) def is_increasing_time_sequence(self, t1, t2): - tDelta = datetime.strptime(t2, TIME_FMT) - \ - datetime.strptime(t1, TIME_FMT) - result1 =(tDelta.days > 0 or tDelta.seconds > 0) - result2 =(tDelta.days * tDelta.seconds) >= 0 - # print_stderr("is_increasing_time_sequence(self, t1, t2): result1={0},result2={1} ".format(str(result1), - # str(result2))) - return result1 and result2 + unixtime1 = time.mktime(datetime.strptime(t1, TIME_FMT).timetuple()) + unixtime2 = time.mktime(datetime.strptime(t2, TIME_FMT).timetuple()) + unixtime_diff = unixtime2-unixtime1 + # print_stderr( + # "unixtime diff: {0}-{1}={2}".format(unixtime2, unixtime1, (unixtime2-unixtime1))) + if unixtime_diff >=0: + return True + else: + return False def is_valid_timestamp(self, timestamp): last_save_time = timestamp[LAST_SAVE_TIME] last_set_time = timestamp[LAST_SET_TIME] @@ -312,33 +316,39 @@ def save_curerent_runtime(self): copyfile(self.runtime_cfg.path(), self.permanent_cfg.path()) + def autosave_main(self): global thread_flag + global ipc_busy self.log.info("Start autosave thread") self.rt_counter = 0 self.fail_counter = 0 while thread_flag is True: - try: - if self.rt_counter >= self.cfg_update_intvl_rt: - cfg_data = self.collect_running_state() - if self.failsafe_flag == False: - if self.save_poe_cfg(self.runtime_cfg, cfg_data) == True: - self.rt_counter = 0 + if ipc_busy == True: + time.sleep(self.autosave_intvl) + else: + try: + if self.rt_counter >= self.cfg_update_intvl_rt: + # print_stderr("Load chip state") + cfg_data = self.collect_running_state() + if self.failsafe_flag == False: + if self.save_poe_cfg(self.runtime_cfg, cfg_data) == True: + self.rt_counter = 0 + else: + self.log.warn( + "Failed to save cfg data in autosave routine!") else: self.log.warn( - "Failed to save cfg data in autosave routine!") - else: - self.log.warn( - "POE Agent in failsafe mode, stop saving runtime cfg") - self.rt_counter = 0 + "POE Agent in failsafe mode, stop saving runtime cfg") + self.rt_counter = 0 - self.rt_counter += self.autosave_intvl - time.sleep(self.autosave_intvl) - except Exception as e: - self.fail_counter += 1 - self.log.err("An exception in autosave routine: %s, cnt: %d" % - (str(e), self.fail_counter)) - time.sleep(1) + self.rt_counter += self.autosave_intvl + time.sleep(self.autosave_intvl) + except Exception as e: + self.fail_counter += 1 + self.log.err("An exception in autosave routine: %s, cnt: %d" % + (str(e), self.fail_counter)) + time.sleep(1) @PoeAccessExclusiveLock def flush_settings_to_chip(self, poe_cfg): @@ -413,11 +423,17 @@ def get_poe_agent_stae(self): return self.poe_agent_state def create_poe_set_ipc(self): + try: + if Path(POE_IPC_EVT).exists() and stat.S_ISFIFO(os.stat(POE_IPC_EVT).st_mode) == False: + #Remove non-namedpipe file + remove_file(POE_IPC_EVT) + except: + pass try: os.mkfifo(POE_IPC_EVT) except OSError as oe: if oe.errno != errno.EEXIST: - self.log.err("Failed to open named pipe: %s" % str(e)) + self.log.err("Failed to open named pipe: %s" % str(oe)) def get_prev_pid(): return int(open(POED_PID_PATH, 'r').read()) @@ -435,6 +451,7 @@ def save_cur_pid(): def main(argv): global thread_flag + global ipc_busy if os.geteuid() != 0: raise RuntimeError("Warning, poed service must be run as root!") @@ -504,10 +521,10 @@ def main(argv): if data == POECLI_SET: pa.update_set_time() pa.log.info("Receive a set event from poecli!") - if pa.rt_counter 0: + print_stderr(".", end='') timeout -= 1 else: - print_stderr("\r\rpoe agent busy...timeout") + print_stderr("timeout") return False time.sleep(1) return True