|
|
|
@ -50,30 +50,32 @@ if len(sys.argv) > 1:
|
|
|
|
|
|
|
|
|
|
os.makedirs(fn_dir, exist_ok = True)
|
|
|
|
|
|
|
|
|
|
if pid is None and a_part != 'a':
|
|
|
|
|
for p, part in enumerate(dev.partlist):
|
|
|
|
|
if part['addr'] == 0 and part['size'] > 0x00800000: # 8MiB
|
|
|
|
|
pid = p
|
|
|
|
|
name = dev.partlist[p]['name'] # "ALL"
|
|
|
|
|
name = ''.join(e for e in name if e.isalnum())
|
|
|
|
|
addr = dev.partlist[p]['addr']
|
|
|
|
|
size = dev.partlist[p]['size']
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
def backup_and_download(pid, filename, die_on_error = True):
|
|
|
|
|
def backup_and_download(pid, filename, chunk_size = 0, die_on_error = True):
|
|
|
|
|
global fn_dir
|
|
|
|
|
os.remove(filename) if os.path.exists(filename) else None
|
|
|
|
|
with open(filename, 'wb') as file:
|
|
|
|
|
pass
|
|
|
|
|
part_size = dev.partlist[pid]["size"]
|
|
|
|
|
fn_remote = f'/tmp/dump_mtd.bin'
|
|
|
|
|
blk_size = 20*1024*1024
|
|
|
|
|
blk_size = 128*1024
|
|
|
|
|
if not chunk_size:
|
|
|
|
|
chunk_size = 20*1024*1024
|
|
|
|
|
if chunk_size % blk_size != 0:
|
|
|
|
|
die(f'Incorrect value of chunk_size = {chunk_size}')
|
|
|
|
|
max_blocks = chunk_size // blk_size
|
|
|
|
|
dump_size = 0
|
|
|
|
|
while dump_size < part_size:
|
|
|
|
|
if dump_size % blk_size != 0:
|
|
|
|
|
die(f'Internal error on backup_and_download (dump_size = {dump_size})')
|
|
|
|
|
skip = dump_size // blk_size
|
|
|
|
|
fn_local = fn_dir + f'dump_mtd{pid}_{skip}.bin'
|
|
|
|
|
os.remove(fn_local) if os.path.exists(fn_local) else None
|
|
|
|
|
cmd = f"rm -f {fn_remote} ; dd if=/dev/mtd{pid} of={fn_remote} bs={blk_size} count=1 skip={skip}"
|
|
|
|
|
count = (part_size - dump_size) // blk_size
|
|
|
|
|
if count == 0:
|
|
|
|
|
count = 1
|
|
|
|
|
if count > max_blocks:
|
|
|
|
|
count = max_blocks
|
|
|
|
|
cmd = f"rm -f {fn_remote} ; dd if=/dev/mtd{pid} of={fn_remote} bs={blk_size} skip={skip} count={count}"
|
|
|
|
|
ret = gw.run_cmd(cmd, timeout = 25, die_on_error = False)
|
|
|
|
|
if not ret:
|
|
|
|
|
print(f'ERROR on execute command: "{cmd}"')
|
|
|
|
@ -88,10 +90,11 @@ def backup_and_download(pid, filename, die_on_error = True):
|
|
|
|
|
if die_on_error:
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
return False
|
|
|
|
|
if not os.path.exists(fn_local):
|
|
|
|
|
if not os.path.exists(fn_local) or os.path.getsize(fn_local) == 0:
|
|
|
|
|
print(f'ERROR: File "{fn_local}" not found!')
|
|
|
|
|
if die_on_error:
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
gw.run_cmd("rm -f " + fn_remote)
|
|
|
|
|
return False
|
|
|
|
|
chunk_size = os.path.getsize(fn_local)
|
|
|
|
|
if chunk_size:
|
|
|
|
@ -106,27 +109,24 @@ def backup_and_download(pid, filename, die_on_error = True):
|
|
|
|
|
print(f'File "{filename}" created!"')
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if pid is not None:
|
|
|
|
|
if os.path.exists(fn_dir):
|
|
|
|
|
if os.path.exists(fn_local):
|
|
|
|
|
if os.path.exists(fn_old):
|
|
|
|
|
os.remove(fn_old)
|
|
|
|
|
os.rename(fn_local, fn_old)
|
|
|
|
|
if a_part is None:
|
|
|
|
|
print("Full backup creating...")
|
|
|
|
|
backup_and_download(pid, fn_local)
|
|
|
|
|
print(" ")
|
|
|
|
|
if a_part is None:
|
|
|
|
|
print('Full backup saved to file "./{}"'.format(fn_local))
|
|
|
|
|
else:
|
|
|
|
|
print('Backup of "{}" saved to file "./{}"'.format(name, fn_local))
|
|
|
|
|
print('Backup of "{}" saved to file "./{}"'.format(name, fn_local))
|
|
|
|
|
else:
|
|
|
|
|
print("Full backup creating...")
|
|
|
|
|
for p, part in enumerate(dev.partlist):
|
|
|
|
|
if part['addr'] == 0 and part['size'] > 0x00800000: # 8MiB
|
|
|
|
|
continue # skip "ALL" part
|
|
|
|
|
name = dev.partlist[p]['name']
|
|
|
|
|
name = ''.join(e for e in name if e.isalnum())
|
|
|
|
|
name = "FULL_DUMP"
|
|
|
|
|
else:
|
|
|
|
|
name = dev.partlist[p]['name']
|
|
|
|
|
name = ''.join(e for e in name if e.isalnum())
|
|
|
|
|
addr = dev.partlist[p]['addr']
|
|
|
|
|
size = dev.partlist[p]['size']
|
|
|
|
|
fn_old = fn_dir + 'mtd{id}_{name}.old'.format(id=p, name=name)
|
|
|
|
@ -136,18 +136,7 @@ else:
|
|
|
|
|
if os.path.exists(fn_old):
|
|
|
|
|
os.remove(fn_old)
|
|
|
|
|
os.rename(fn_local, fn_old)
|
|
|
|
|
cmd = "dd if=/dev/mtd{id} of={o}".format(id=p, o=fn_remote)
|
|
|
|
|
ret = gw.run_cmd(cmd, timeout=30, die_on_error = False)
|
|
|
|
|
if not ret:
|
|
|
|
|
print('ERROR on execute command: "{}"'.format(cmd))
|
|
|
|
|
else:
|
|
|
|
|
print('Download dump to file "./{}"...'.format(fn_local))
|
|
|
|
|
try:
|
|
|
|
|
gw.download(fn_remote, fn_local, verbose = 0)
|
|
|
|
|
except Exception:
|
|
|
|
|
print('Remote file "{}" not found!'.format(fn_remote))
|
|
|
|
|
continue
|
|
|
|
|
gw.run_cmd("rm -f " + fn_remote)
|
|
|
|
|
ret = backup_and_download(p, fn_local, die_on_error = False)
|
|
|
|
|
if ret:
|
|
|
|
|
print('Backup of "{}" saved to file "./{}"'.format(name, fn_local))
|
|
|
|
|
print(" ")
|
|
|
|
|