diff options
Diffstat (limited to 'meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon')
5 files changed, 234 insertions, 31 deletions
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/Makefile b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/Makefile index 926bf52..fa1e932 100644 --- a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/Makefile +++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/Makefile @@ -15,7 +15,7 @@ # 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301 USA -override CFLAGS+=-D_GNU_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=199309 -Wall -Werror -std=c99 +override CFLAGS+=-D_GNU_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=199309 -Wall -Werror -std=c99 override LDFLAGS+=-pthread all: modbuscmd gpiowatch modbussim rackmond rackmondata diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/psu-update-delta.py b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/psu-update-delta.py index a92cf8e..34a64f8 100755 --- a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/psu-update-delta.py +++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/psu-update-delta.py @@ -2,11 +2,15 @@ from __future__ import print_function import os.path +import os +import fcntl import socket import struct import sys import argparse import traceback +import json +from tempfile import mkstemp import hexfile @@ -18,8 +22,32 @@ def auto_int(x): parser = argparse.ArgumentParser() parser.add_argument('--addr', type=auto_int, required=True, help="PSU Modbus Address") +parser.add_argument('--statusfile', default=None, + help="Write status to JSON file during process") +parser.add_argument('--rmfwfile', action='store_true', + help="Delete FW file after update completes") parser.add_argument('file', help="firmware file") +status = { + 'pid': os.getpid(), + 'state': 'started' +} + +statuspath = None + +def write_status(): + global status + if statuspath is None: + return + tmppath = statuspath + '~' + with open(tmppath, 'wb') as tfh: + tfh.write(json.dumps(status)) + os.rename(tmppath, statuspath) + +def status_state(state): + global status + status['state'] = state + write_status() class ModbusTimeout(Exception): pass @@ -193,6 +221,7 @@ def write_data(addr, data): def send_image(addr, fwimg): + global statuspath total_chunks = sum([len(s) for s in fwimg.segments]) / 8 sent_chunks = 0 for s in fwimg.segments: @@ -205,11 +234,15 @@ def send_image(addr, fwimg): if len(chunk) < 8: chunk = chunk + ("\xFF" * (8 - len(chunk))) sent_chunks += 1 - print("\r[%.2f%%] Sending chunk %d of %d..." % - (sent_chunks * 100.0 / total_chunks, - sent_chunks, total_chunks), end="") + # dont fill the restapi log with junk + if statuspath is None: + print("\r[%.2f%%] Sending chunk %d of %d..." % + (sent_chunks * 100.0 / total_chunks, + sent_chunks, total_chunks), end="") sys.stdout.flush() write_data(addr, str(bytearray(chunk))) + status['flash_progress_percent'] = sent_chunks * 100.0 / total_chunks + write_status() print("") @@ -241,28 +274,45 @@ def erase_flash(addr): def update_psu(addr, filename): + status_state('pausing_monitoring') pause_monitoring() + status_state('parsing_fw_file') fwimg = hexfile.load(filename) + status_state('bootloader_handshake') enter_bootloader(addr) start_programming(addr) challenge = get_challenge(addr) send_key(addr, delta_seccalckey(challenge)) + status_state('erase_flash') erase_flash(addr) + status_state('flashing') send_image(addr, fwimg) + status_state('verifying') verify_flash(addr) + status_state('resetting') reset_psu(addr) + status_state('done') def main(): args = parser.parse_args() + global statuspath + statuspath = args.statusfile + print("statusfile %s" % statuspath) try: update_psu(args.addr, args.file) - except: - traceback.print_exc() + except Exception, e: print("Firmware update failed") + global status + status['exception'] = traceback.format_exc() + status_state('failed') resume_monitoring() + if args.rmfwfile: + os.remove(args.file) sys.exit(1) resume_monitoring() + if args.rmfwfile: + os.remove(args.file) sys.exit(0) if __name__ == "__main__": diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmon-config.py b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmon-config.py index e93dfae..130f26f 100644 --- a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmon-config.py +++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmon-config.py @@ -1,7 +1,4 @@ -from __future__ import print_function -import struct -import socket -import os, os.path +from rackmond import configure_rackmond reglist = [ {"begin": 0x0, #MFR_MODEL @@ -26,68 +23,198 @@ reglist = [ "length": 1, "keep": 10, # 10-sample ring buffer "flags": 1}, + {"begin": 0x6B, #BBU Battery Mode + "length": 1, + "keep": 10, # 10-sample ring buffer + "flags": 1}, + {"begin": 0x6C, #BBU Battery Status + "length": 1, + "keep": 10, # 10-sample ring buffer + "flags": 1}, + {"begin": 0x6D, #BBU Cell Voltage 1 + "length": 1, + "keep": 10}, + {"begin": 0x6E, #BBU Cell Voltage 2 + "length": 1, + "keep": 10}, + {"begin": 0x6F, #BBU Cell Voltage 3 + "length": 1, + "keep": 10}, + {"begin": 0x70, #BBU Cell Voltage 4 + "length": 1, + "keep": 10}, + {"begin": 0x71, #BBU Cell Voltage 5 + "length": 1, + "keep": 10}, + {"begin": 0x72, #BBU Cell Voltage 6 + "length": 1, + "keep": 10}, + {"begin": 0x73, #BBU Cell Voltage 7 + "length": 1, + "keep": 10}, + {"begin": 0x74, #BBU Cell Voltage 8 + "length": 1, + "keep": 10}, + {"begin": 0x75, #BBU Cell Voltage 9 + "length": 1, + "keep": 10}, + {"begin": 0x76, #BBU Cell Voltage 10 + "length": 1, + "keep": 10}, + {"begin": 0x77, #BBU Cell Voltage 11 + "length": 1, + "keep": 10}, + {"begin": 0x78, #BBU Cell Voltage 12 + "length": 1, + "keep": 10}, + {"begin": 0x79, #BBU Cell Voltage 13 + "length": 1, + "keep": 10}, + {"begin": 0x7A, #BBU Temp 1 + "length": 1, + "keep": 10}, + {"begin": 0x7B, #BBU Temp 2 + "length": 1, + "keep": 10}, + {"begin": 0x7C, #BBU Temp 3 + "length": 1, + "keep": 10}, + {"begin": 0x7D, #BBU Temp 4 + "length": 1, + "keep": 10}, + {"begin": 0x7E, #BBU Relative State of Charge + "length": 1, + "keep": 10}, + {"begin": 0x7F, #BBU Absolute State of Charge + "length": 1, + "keep": 10}, {"begin": 0x80, #Input VAC "length": 1, "keep": 10}, + {"begin": 0x81, #BBU Battery Voltage + "length": 1, + "keep": 10}, {"begin": 0x82, #Input Current AC "length": 1, "keep": 10}, + {"begin": 0x83, #BBU Battery Current + "length": 1, + "keep": 10}, {"begin": 0x84, #Battery Voltage "length": 1, "keep": 10}, + {"begin": 0x85, #BBU Average Current + "length": 1, + "keep": 10}, {"begin": 0x86, #Battery Current Output "length": 1}, + {"begin": 0x87, #BBU Remaining Capacity + "length": 1, + "keep": 10}, {"begin": 0x88, #Battery Current Input "length": 1}, + {"begin": 0x89, #BBU Full Charge Capacity + "length": 1, + "keep": 10}, {"begin": 0x8A, #Output Voltage (main converter) "length": 1, "keep": 10}, + {"begin": 0x8B, #BBU Run Time to Empty + "length": 1, + "keep": 10}, {"begin": 0x8C, #Output Current (main converter) "length": 1, "keep": 10}, + {"begin": 0x8D, #BBU Average Time to Empty + "length": 1, + "keep": 10}, {"begin": 0x8E, #IT Load Voltage Output "length": 1}, + {"begin": 0x8F, #BBU Charging Current + "length": 1}, {"begin": 0x90, #IT Load Current Output "length": 1}, + {"begin": 0x91, #BBU Charging Voltage + "length": 1, + "keep": 10}, {"begin": 0x92, #Bulk Cap Voltage "length": 1}, + {"begin": 0x93, #BBU Cycle Count + "length": 1, + "keep": 10}, {"begin": 0x94, #Input Power "length": 1, "keep": 10}, + {"begin": 0x95, #BBU Design Capacity + "length": 1}, {"begin": 0x96, #Output Power "length": 1, "keep": 10}, + {"begin": 0x97, #BBU Design Voltage + "length": 1}, {"begin": 0x98, #RPM Fan 0 "length": 1}, + {"begin": 0x99, #BBU At Rate + "length": 1}, {"begin": 0x9A, #RPM Fan 1 "length": 1}, + {"begin": 0x9B, #BBU At Rate Time to Full + "length": 1, + "keep": 10}, + {"begin": 0x9C, #BBU At Rate Time to Empty + "length": 1, + "keep": 10}, + {"begin": 0x9D, #BBU At Rate OK + "length": 1, + "keep": 10}, {"begin": 0x9E, #Temp 0 "length": 1}, + {"begin": 0x9F, #BBU Temp + "length": 1}, {"begin": 0xA0, #Temp 1 "length": 1}, + {"begin": 0xA1, #BBU Max Error + "length": 1}, + {"begin": 0xD0, #General Alarm Status Register + "length": 1}, + {"begin": 0xD1, #PFC Alarm Status Register + "length": 1}, + {"begin": 0xD2, #LLC Alarm Status Register + "length": 1}, + {"begin": 0xD3, #Current Feed Alarm Status Register + "length": 1}, + {"begin": 0xD4, #Auxiliary Alarm Status Register + "length": 1}, + {"begin": 0xD5, #Battery Charger Alarm Status Register + "length": 1}, + {"begin": 0xD7, #Temperature Alarm Status Register + "length": 1}, + {"begin": 0xD8, #Fan Alarm Status Register + "length": 1}, + {"begin": 0xD9, #Communication Alarm Status Register + "length": 1}, + {"begin": 0x106, #BBU Specification Info + "length": 1}, + {"begin": 0x107, #BBU Manufacturer Date + "length": 1}, + {"begin": 0x108, #BBU Serial Number + "length": 1}, + {"begin": 0x109, #BBU Device Chemistry + "length": 2}, + {"begin": 0x10B, #BBU Manufacturer Data + "length": 2}, + {"begin": 0x10D, #BBU Manufacturer Name + "length": 8}, + {"begin": 0x115, #BBU Device Name + "length": 8}, + {"begin": 0x11D, #FB Battery Status + "length": 4}, + {"begin": 0x121, #SoH results + "length": 1}, ] def main(): - COMMAND_TYPE_SET_CONFIG = 2 - config_command = struct.pack("@HxxH", - COMMAND_TYPE_SET_CONFIG, - len(reglist)) - for r in reglist: - keep = 1 - if "keep" in r: - keep = r["keep"] - flags = 0 - if "flags" in r: - flags = r["flags"] - monitor_interval = struct.pack("@HHHH", r["begin"], r["length"], keep, flags) - config_command += monitor_interval - - config_packet = struct.pack("H", len(config_command)) + config_command - srvpath = "/var/run/rackmond.sock" - if os.path.exists(srvpath): - client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - client.connect(srvpath) - client.send(config_packet) + configure_rackmond(reglist) if __name__ == "__main__": main() diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmond.py b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmond.py new file mode 100644 index 0000000..35dbaa5 --- /dev/null +++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmond.py @@ -0,0 +1,26 @@ +import struct +import socket +import os, os.path + +def configure_rackmond(reglist): + COMMAND_TYPE_SET_CONFIG = 2 + config_command = struct.pack("@HxxH", + COMMAND_TYPE_SET_CONFIG, + len(reglist)) + for r in reglist: + keep = 1 + if "keep" in r: + keep = r["keep"] + flags = 0 + if "flags" in r: + flags = r["flags"] + monitor_interval = struct.pack("@HHHH", r["begin"], r["length"], keep, flags) + config_command += monitor_interval + + config_packet = struct.pack("H", len(config_command)) + config_command + srvpath = "/var/run/rackmond.sock" + if os.path.exists(srvpath): + client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + client.connect(srvpath) + client.send(config_packet) + diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/setup-rackmond.sh b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/setup-rackmond.sh index 85a1e22..b592a35 100644 --- a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/setup-rackmond.sh +++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/setup-rackmond.sh @@ -16,5 +16,5 @@ echo -n "Starting rackmon background service..." echo "done." echo -n "Configuring rackmon service..." -python /etc/rackmon-config.py +PYTHONPATH=/etc python /etc/rackmon-config.py echo "done." |