refs #1409 add ogCreateCache, fix bugs

code-review
Natalia Serrano 2025-01-31 15:54:26 +01:00
parent 0b95027e5e
commit 56ba419461
4 changed files with 126 additions and 29 deletions

View File

@ -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}")
#/** #/**

View File

@ -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

View File

@ -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)

View File

@ -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