refs #1409 add ogCreateCache, fix bugs
parent
0b95027e5e
commit
56ba419461
|
@ -23,35 +23,97 @@ import CacheLib
|
||||||
#@warning El tamaño de caché debe estar entre 50 MB y la mitad del disco.
|
#@warning El tamaño de caché debe estar entre 50 MB y la mitad del disco.
|
||||||
#@warning La caché no puede solaparse con las particiones de datos.
|
#@warning La caché no puede solaparse con las particiones de datos.
|
||||||
#*/ ##
|
#*/ ##
|
||||||
def ogCreateCache(ndisk=1, npart=4, partsize=None):
|
def ogCreateCache (ndsk=1, part=4, sizecache=0):
|
||||||
"""
|
if not sizecache:
|
||||||
Define la caché local, por defecto en partición 4 del disco 1.
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '')
|
||||||
|
return None
|
||||||
:param ndisk: número de disco donde crear la caché, por defecto es 1.
|
sizecache = int (sizecache)
|
||||||
:param npart: número de partición (opcional, 4 por defecto).
|
|
||||||
:param partsize: tamaño de la partición en KB.
|
|
||||||
:raises ValueError: Si el formato de los parámetros es incorrecto.
|
|
||||||
:raises RuntimeError: Si ocurre un error durante la creación de la caché.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if partsize is None:
|
DISK = DiskLib.ogDiskToDev (ndsk)
|
||||||
raise ValueError("El tamaño de la partición debe especificarse.")
|
if not DISK: return None
|
||||||
|
|
||||||
# Verifica si las herramientas necesarias están instaladas
|
# PATCH Para discos nvme la particion debe ser p1, p2, etc...en lugar de 1,2, sino falla sfdisk
|
||||||
required_tools = ["sfdisk", "parted", "awk", "sed"]
|
NVME_PREFIX = ''
|
||||||
for tool in required_tools:
|
if 'nvme' in DISK:
|
||||||
if not shutil.which(tool):
|
NVME_PREFIX = 'p'
|
||||||
raise RuntimeError(f"La herramienta {tool} no está instalada.")
|
|
||||||
|
|
||||||
# Preparar los comandos para crear la caché
|
END = DiskLib.ogGetLastSector (ndsk)
|
||||||
disk = f"/dev/sd{chr(96 + ndisk)}"
|
SIZE = 2 * sizecache
|
||||||
size_in_sectors = partsize * 2 # Asumiendo 512B por sector
|
# Inicio partición cache según el disco tenga sectores de 4k o menores
|
||||||
|
IOSIZE = 0
|
||||||
|
fdisk_out = subprocess.run (['fdisk', '-l', DISK], capture_output=True, text=True).stdout
|
||||||
|
for l in fdisk_out.splitlines():
|
||||||
|
items = l.split()
|
||||||
|
if len(items) < 4: continue
|
||||||
|
if 'I/O' == items[0]:
|
||||||
|
IOSIZE = int (items[3])
|
||||||
|
break
|
||||||
|
START = 0
|
||||||
|
if 4096 == IOSIZE:
|
||||||
|
END -= 8192
|
||||||
|
START = END - SIZE + 2048 - (END-SIZE)%2048
|
||||||
|
else:
|
||||||
|
START = END - SIZE + 1
|
||||||
|
|
||||||
|
ENDPREVPART = None
|
||||||
|
i = 1
|
||||||
|
while True:
|
||||||
|
prev_part = part - i
|
||||||
|
if prev_part <= 0: break
|
||||||
|
ENDPREVPART = DiskLib.ogGetLastSector (ndsk, prev_part)
|
||||||
|
if ENDPREVPART: break
|
||||||
|
i += 1
|
||||||
|
if not ENDPREVPART:
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, ndsk)
|
||||||
|
return None
|
||||||
|
# Error si tamaño no está entre límites permitidos o si se solapa con la partición anterior.
|
||||||
|
MINSIZE = 25000
|
||||||
|
MAXSIZE = END
|
||||||
|
if SIZE < MINSIZE or SIZE > MAXSIZE or START < ENDPREVPART:
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, ndsk)
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Desmontar todos los sistemas de archivos del disco.
|
||||||
|
FileSystemLib.ogUnmountAll (ndsk)
|
||||||
|
# Definir particiones y notificar al kernel.
|
||||||
|
# En el caso de ser disco GPT, de momento se borra la particion y se vuelve a crear,
|
||||||
|
# por lo que se pierden los datos.
|
||||||
|
pttype = DiskLib.ogGetPartitionTableType (ndsk)
|
||||||
|
if not pttype:
|
||||||
|
pttype = 'MSDOS'
|
||||||
|
DiskLib.ogCreatePartitionTable (ndsk, pttype)
|
||||||
|
|
||||||
|
get_ptt = DiskLib.ogGetPartitionTableType (ndsk)
|
||||||
|
if 'GPT' == get_ptt:
|
||||||
|
# Si la tabla de particiones no es valida, volver a generarla.
|
||||||
|
if subprocess.run (['sgdisk', '-p', DISK]).returncode:
|
||||||
|
subprocess.run (['gdisk', DISK], input='2\nw\nY\n', text=True)
|
||||||
|
# Si existe la cache se borra previamente
|
||||||
|
if ogFindCache(): ogDeleteCache()
|
||||||
|
# Capturamos el codigo de particion GPT para cache
|
||||||
|
# PATCH - Cuando es GPT, la particion con codigo CACHE (CA00) no existe y no puede crearse, se cambia por LINUX (8300)
|
||||||
|
ID = DiskLib.ogTypeToId ('LINUX', 'GPT')
|
||||||
|
subprocess.run (['sgdisk', DISK, f'-n{part}:{START}:{END}', f'-c{part}:CACHE', f'-t{part}:{ID}'])
|
||||||
|
elif 'MSDOS' == get_ptt:
|
||||||
|
# Si la tabla de particiones no es valida, volver a generarla.
|
||||||
|
if subprocess.run (['parted', '-s', DISK, 'print']).returncode:
|
||||||
|
subprocess.run (['fdisk', DISK], input='w\n', text=True)
|
||||||
|
# Definir particiones y notificar al kernel.
|
||||||
|
ID = DiskLib.ogTypeToId ('CACHE', 'MSDOS')
|
||||||
|
# Salvamos la configuración de las particiones e incluimos la cache.
|
||||||
|
tmp = subprocess.run (['sfdisk', '--dump', DISK], capture_output=True, text=True).stdout.splitlines()
|
||||||
|
tmp = [ x for x in tmp if f'{DISK}{part}' not in x ]
|
||||||
|
tmp.append (f'{DISK}{NVME_PREFIX}{part} : start= {START}, size= {SIZE}, Id={ID}')
|
||||||
|
# Ordenamos las líneas de los dispositivos
|
||||||
|
UNIT = [ x for x in tmp if 'unit' in x ][0]
|
||||||
|
tmp = sorted ([ x for x in tmp if re.match ('^/dev', x) ])
|
||||||
|
tmp = [UNIT, ''] + tmp
|
||||||
|
# Guardamos nueva configuración en el disco.
|
||||||
|
i = '\n'.join(tmp)
|
||||||
|
subprocess.run (['sfdisk', '--no-reread', DISK], input=i, text=True)
|
||||||
|
# Actualiza la tabla de particiones en el kernel.
|
||||||
|
DiskLib.ogUpdatePartitionTable()
|
||||||
|
|
||||||
try:
|
|
||||||
# Lógica simplificada para crear la caché en la partición
|
|
||||||
subprocess.run(["parted", disk, "mkpart", "primary", str(npart), str(partsize)], check=True)
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
raise RuntimeError(f"Error al crear la caché: {e}")
|
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
|
|
@ -711,8 +711,8 @@ def ogGetLastSector (disk, par=None):
|
||||||
for l in sgdisk_out.splitlines():
|
for l in sgdisk_out.splitlines():
|
||||||
items = l.split()
|
items = l.split()
|
||||||
if len(items) < 3: continue
|
if len(items) < 3: continue
|
||||||
if par != items[0]: continue
|
if str (par) != items[0]: continue
|
||||||
last = items[2]
|
last = int (items[2])
|
||||||
break
|
break
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -720,7 +720,7 @@ def ogGetLastSector (disk, par=None):
|
||||||
for l in sgdisk_out.splitlines():
|
for l in sgdisk_out.splitlines():
|
||||||
if 'last usable sector' not in l: continue
|
if 'last usable sector' not in l: continue
|
||||||
items = l.split()
|
items = l.split()
|
||||||
last = items[-1]
|
last = int (items[-1])
|
||||||
|
|
||||||
return last
|
return last
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
from SystemLib import ogHelp
|
||||||
|
from CacheLib import ogCreateCache
|
||||||
|
|
||||||
|
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
|
||||||
|
#parser.print_help() sale en inglés aunque la locale indique otra cosa
|
||||||
|
ogHelp ('ogCreateCache', 'ogCreateCache [int_ndisk [int_npart]] int_partsize', ['ogCreateCache 10000000', 'ogCreateCache 1 10000000', 'ogCreateCache 1 4 10000000'])
|
||||||
|
sys.exit (0)
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser (add_help=False)
|
||||||
|
if 2 == len (sys.argv):
|
||||||
|
parser.add_argument ('sizecache')
|
||||||
|
elif 3 == len (sys.argv):
|
||||||
|
parser.add_argument ('disk')
|
||||||
|
parser.add_argument ('sizecache')
|
||||||
|
elif 4 == len (sys.argv):
|
||||||
|
parser.add_argument ('disk')
|
||||||
|
parser.add_argument ('part')
|
||||||
|
parser.add_argument ('sizecache')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if 2 == len (sys.argv):
|
||||||
|
ret = ogCreateCache (sizecache=args.sizecache)
|
||||||
|
elif 3 == len (sys.argv):
|
||||||
|
ret = ogCreateCache (ndsk=args.disk, sizecache=args.sizecache)
|
||||||
|
elif 4 == len (sys.argv):
|
||||||
|
ret = ogCreateCache (ndsk=int(args.disk), part=int(args.part), sizecache=int(args.sizecache))
|
||||||
|
|
||||||
|
if ret is not None:
|
||||||
|
if ret == True: sys.exit (0)
|
||||||
|
elif ret == False: sys.exit (1)
|
||||||
|
else: print (ret)
|
|
@ -3,7 +3,6 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import tempfile
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
import ogGlobals
|
import ogGlobals
|
||||||
|
|
Loading…
Reference in New Issue