880 lines
29 KiB
Python
880 lines
29 KiB
Python
import subprocess
|
|
import sys
|
|
import os.path
|
|
|
|
import ogGlobals
|
|
import SystemLib
|
|
import DiskLib
|
|
import CacheLib
|
|
|
|
def ogCheckFs(int_ndisk, int_nfilesys):
|
|
# Si se solicita, mostrar ayuda.
|
|
if int_ndisk == "help":
|
|
ogHelp("ogCheckFs", "ogCheckFs int_ndisk int_nfilesys", "ogCheckFs 1 1")
|
|
return
|
|
|
|
# Error si no se reciben 2 parámetros.
|
|
if len(sys.argv) != 3:
|
|
ogRaiseError(OG_ERR_FORMAT)
|
|
return
|
|
|
|
# Obtener partición.
|
|
PART = ogDiskToDev(int_ndisk, int_nfilesys)
|
|
if not PART:
|
|
return
|
|
|
|
TYPE = ogGetFsType(int_ndisk, int_nfilesys)
|
|
if TYPE == "EXT[234]" or TYPE == "CACHE":
|
|
PROG = "e2fsck"
|
|
PARAMS = "-y"
|
|
CODES = [1, 2]
|
|
elif TYPE == "BTRFS":
|
|
PROG = "btrfsck"
|
|
CODES = [1]
|
|
elif TYPE == "REISERFS":
|
|
PROG = "fsck.reiserfs"
|
|
PARAMS = "<<<\"Yes\""
|
|
CODES = [1, 2]
|
|
elif TYPE == "REISER4":
|
|
PROG = "fsck.reiser4"
|
|
PARAMS = "-ay"
|
|
elif TYPE == "JFS":
|
|
PROG = "fsck.jfs"
|
|
CODES = [1, 2]
|
|
elif TYPE == "XFS":
|
|
PROG = "xfs_repair"
|
|
elif TYPE == "F2FS":
|
|
PROG = "fsck.f2fs"
|
|
elif TYPE == "NTFS":
|
|
PROG = "ntfsfix"
|
|
elif TYPE == "EXFAT":
|
|
PROG = "fsck.exfat"
|
|
elif TYPE == "FAT32":
|
|
PROG = "dosfsck"
|
|
PARAMS = "-a"
|
|
CODES = [1]
|
|
elif TYPE == "FAT16":
|
|
PROG = "dosfsck"
|
|
PARAMS = "-a"
|
|
CODES = [1]
|
|
elif TYPE == "FAT12":
|
|
PROG = "dosfsck"
|
|
PARAMS = "-a"
|
|
CODES = [1]
|
|
elif TYPE == "HFS":
|
|
PROG = "fsck.hfs"
|
|
PARAMS = "-f"
|
|
elif TYPE == "HFSPLUS":
|
|
PROG = "fsck.hfs"
|
|
PARAMS = "-f"
|
|
elif TYPE == "UFS":
|
|
PROG = "fsck.ufs"
|
|
elif TYPE == "ZFS":
|
|
PROG = "fsck.zfs"
|
|
else:
|
|
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk}, {int_nfilesys}")
|
|
return
|
|
|
|
# Error si el sistema de archivos esta montado o bloqueado.
|
|
ogUnmount(int_ndisk, int_nfilesys)
|
|
if ogIsMounted(int_ndisk, int_nfilesys):
|
|
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk} {int_nfilesys}")
|
|
return
|
|
if ogIsLocked(int_ndisk, int_nfilesys):
|
|
ogRaiseError(OG_ERR_LOCKED, f"{int_ndisk} {int_nfilesys}")
|
|
return
|
|
|
|
# Comprobar en modo uso exclusivo.
|
|
ogLock(int_ndisk, int_nfilesys)
|
|
try:
|
|
result = subprocess.run([PROG, PARAMS, PART], capture_output=True)
|
|
ERRCODE = result.returncode
|
|
except FileNotFoundError:
|
|
ogRaiseError(OG_ERR_NOTEXEC, PROG)
|
|
ERRCODE = OG_ERR_NOTEXEC
|
|
except:
|
|
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk} {int_nfilesys}")
|
|
ERRCODE = OG_ERR_PARTITION
|
|
|
|
ogUnlock(int_ndisk, int_nfilesys)
|
|
return ERRCODE
|
|
|
|
def ogExtendFs():
|
|
# Si se solicita, mostrar ayuda.
|
|
if len(sys.argv) == 2 and sys.argv[1] == "help":
|
|
ogHelp("ogExtendFs", "ogExtendFs int_ndisk int_nfilesys", "ogExtendFs 1 1")
|
|
return
|
|
|
|
# Error si no se reciben 2 parámetros.
|
|
if len(sys.argv) != 3:
|
|
ogRaiseError(OG_ERR_FORMAT)
|
|
return
|
|
|
|
# Obtener partición.
|
|
PART = ogDiskToDev(int(sys.argv[1]), int(sys.argv[2]))
|
|
if not PART:
|
|
return
|
|
|
|
# Redimensionar al tamaño máximo según el tipo de partición.
|
|
TYPE = ogGetFsType(int(sys.argv[1]), int(sys.argv[2]))
|
|
if TYPE == "EXT[234]":
|
|
PROG = "resize2fs"
|
|
PARAMS = "-f"
|
|
elif TYPE == "BTRFS":
|
|
PROG = "btrfs"
|
|
PARAMS = "filesystem resize max"
|
|
DOMOUNT = True # Debe estar montado.
|
|
elif TYPE == "REISERFS" or TYPE == "REISER4":
|
|
PROG = "resize_reiserfs"
|
|
PARAMS = "-f"
|
|
elif TYPE == "F2FS" or TYPE == "JFS" or TYPE == "NILFS2" or TYPE == "XFS" or TYPE == "EXFAT" or TYPE == "FAT32" or TYPE == "FAT16" or TYPE == "HFS" or TYPE == "HFSPLUS" or TYPE == "UFS":
|
|
return # No se reduce (por el momento).
|
|
elif TYPE == "NTFS":
|
|
PROG = "ntfsresize"
|
|
PARAMS = "<<<\"y\" -f"
|
|
else:
|
|
ogRaiseError(OG_ERR_PARTITION, f"{int(sys.argv[1])} {int(sys.argv[2])} {TYPE}")
|
|
return
|
|
|
|
# Salida normal si no se va a aplicar la operación.
|
|
if not PROG:
|
|
return
|
|
|
|
# Error si el sistema de archivos no se queda en el estado de montaje adecuado.
|
|
if DOMOUNT:
|
|
PART = ogMount(int(sys.argv[1]), int(sys.argv[2]))
|
|
if not PART:
|
|
return
|
|
else:
|
|
ogUnmount(int(sys.argv[1]), int(sys.argv[2]))
|
|
if ogIsMounted(int(sys.argv[1]), int(sys.argv[2])):
|
|
ogRaiseError(OG_ERR_PARTITION, f"{int(sys.argv[1])} {int(sys.argv[2])}")
|
|
return
|
|
|
|
# Error si el sistema de archivos está bloqueado.
|
|
if ogIsLocked(int(sys.argv[1]), int(sys.argv[2])):
|
|
ogRaiseError(OG_ERR_LOCKED, f"{int(sys.argv[1])} {int(sys.argv[2])}")
|
|
return
|
|
|
|
# Redimensionar en modo uso exclusivo.
|
|
ogLock(int(sys.argv[1]), int(sys.argv[2]))
|
|
try:
|
|
subprocess.run([PROG, PARAMS, PART], capture_output=True)
|
|
ERRCODE = 0
|
|
except FileNotFoundError:
|
|
ogRaiseError(OG_ERR_NOTEXEC, PROG)
|
|
ERRCODE = OG_ERR_NOTEXEC
|
|
except:
|
|
ogRaiseError(OG_ERR_PARTITION, f"{int(sys.argv[1])} {int(sys.argv[2])}")
|
|
ERRCODE = OG_ERR_PARTITION
|
|
|
|
ogUnlock(int(sys.argv[1]), int(sys.argv[2]))
|
|
return ERRCODE
|
|
|
|
def ogFormat(int_ndisk, int_nfilesys):
|
|
if int_nfilesys.lower() == "cache":
|
|
ogFormatCache()
|
|
else:
|
|
ogFormatFs(int_ndisk, int_nfilesys)
|
|
|
|
def ogFormatFs(int_ndisk, int_nfilesys, str_label=None):
|
|
# Si se solicita, mostrar ayuda.
|
|
if str_label == "help":
|
|
ogHelp("ogFormatFs", "ogFormatFs int_ndisk int_nfilesys [str_label]", "ogFormatFs 1 1", "ogFormatFs 1 1 EXT4", "ogFormatFs 1 1 \"DATA\"", "ogFormatFs 1 1 EXT4 \"DATA\"")
|
|
return
|
|
|
|
# Error si no se reciben entre 2 y 4 parámetros.
|
|
if not (2 <= len(sys.argv) <= 4):
|
|
ogRaiseError(OG_ERR_FORMAT)
|
|
return
|
|
|
|
# Obtener fichero de dispositivo.
|
|
PART = ogDiskToDev(int_ndisk, int_nfilesys)
|
|
if not PART:
|
|
return
|
|
|
|
# Error si la partición está montada o bloqueada.
|
|
if ogIsMounted(int_ndisk, int_nfilesys):
|
|
ogRaiseError(OG_ERR_DONTFORMAT, f"{MSG_MOUNT}: {int_ndisk} {int_nfilesys}")
|
|
return
|
|
if ogIsLocked(int_ndisk, int_nfilesys):
|
|
ogRaiseError(OG_ERR_LOCKED, f"{int_ndisk} {int_nfilesys}")
|
|
return
|
|
|
|
# Si no se indica el tipo de sistema de archivos, intentar obtenerlo.
|
|
TYPE = ogGetFsType(int_ndisk, int_nfilesys)
|
|
if not TYPE:
|
|
TYPE = sys.argv[3]
|
|
|
|
# Error, si no especifica el tipo de sistema de archivos a formatear.
|
|
if not TYPE:
|
|
ogRaiseError(OG_ERR_FORMAT, f"{int_ndisk} {int_nfilesys} ...")
|
|
return
|
|
|
|
# Elegir tipo de formato.
|
|
if TYPE == "EXT2":
|
|
PROG = "mkfs.ext2"
|
|
PARAMS = "-F"
|
|
elif TYPE == "EXT3":
|
|
PROG = "mkfs.ext3"
|
|
PARAMS = "-F"
|
|
elif TYPE == "EXT4":
|
|
PROG = "mkfs.ext4"
|
|
PARAMS = "-F"
|
|
elif TYPE == "BTRFS":
|
|
PROG = "mkfs.btrfs"
|
|
PARAMS = "-f"
|
|
elif TYPE == "REISERFS":
|
|
PROG = "mkfs.reiserfs"
|
|
PARAMS = "-f"
|
|
LABELPARAM = "-l"
|
|
elif TYPE == "REISER4":
|
|
PROG = "mkfs.reiser4"
|
|
PARAMS = "-f <<<\"y\""
|
|
elif TYPE == "XFS":
|
|
PROG = "mkfs.xfs"
|
|
PARAMS = "-f"
|
|
elif TYPE == "JFS":
|
|
PROG = "mkfs.jfs"
|
|
PARAMS = "<<<\"y\""
|
|
elif TYPE == "F2FS":
|
|
PROG = "mkfs.f2fs"
|
|
LABELPARAM = "-l"
|
|
elif TYPE == "NILFS2":
|
|
PROG = "mkfs.nilfs2"
|
|
PARAMS = "-f"
|
|
elif TYPE == "LINUX-SWAP":
|
|
PROG = "mkswap"
|
|
elif TYPE == "NTFS":
|
|
PROG = "mkntfs"
|
|
PARAMS = "-f"
|
|
elif TYPE == "EXFAT":
|
|
PROG = "mkfs.exfat"
|
|
LABELPARAM = "-n"
|
|
elif TYPE == "FAT32":
|
|
PROG = "mkdosfs"
|
|
PARAMS = "-F 32"
|
|
LABELPARAM = "-n"
|
|
elif TYPE == "FAT16":
|
|
PROG = "mkdosfs"
|
|
PARAMS = "-F 16"
|
|
LABELPARAM = "-n"
|
|
elif TYPE == "FAT12":
|
|
PROG = "mkdosfs"
|
|
PARAMS = "-F 12"
|
|
LABELPARAM = "-n"
|
|
elif TYPE == "HFS":
|
|
PROG = "mkfs.hfs"
|
|
elif TYPE == "HFSPLUS":
|
|
PROG = "mkfs.hfsplus"
|
|
LABELPARAM = "-v"
|
|
elif TYPE == "UFS":
|
|
PROG = "mkfs.ufs"
|
|
PARAMS = "-O 2"
|
|
else:
|
|
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk} {int_nfilesys} {TYPE}")
|
|
return
|
|
|
|
# Etiquetas de particion.
|
|
if not str_label:
|
|
if sys.argv[4] == "CACHE":
|
|
ogRaiseError(OG_ERR_FORMAT, f"{MSG_RESERVEDVALUE}: CACHE")
|
|
return
|
|
if len(sys.argv) >= 4:
|
|
PARAMS = f"{PARAMS} {LABELPARAM or '-L'} {sys.argv[4]}"
|
|
else:
|
|
PARAMS = f"{PARAMS} {LABELPARAM or '-L'} {str_label}"
|
|
|
|
# Formatear en modo uso exclusivo (desmontar siempre).
|
|
ogLock(int_ndisk, int_nfilesys)
|
|
try:
|
|
subprocess.run([PROG, PARAMS, PART], capture_output=True)
|
|
ERRCODE = 0
|
|
except FileNotFoundError:
|
|
ogRaiseError(OG_ERR_NOTEXEC, PROG)
|
|
ERRCODE = OG_ERR_NOTEXEC
|
|
except:
|
|
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk} {int_nfilesys}")
|
|
ERRCODE = OG_ERR_PARTITION
|
|
|
|
ogUnlock(int_ndisk, int_nfilesys)
|
|
return ERRCODE
|
|
|
|
def ogGetFsSize(int_ndisk, int_npartition, str_unit=None):
|
|
# Si se solicita, mostrar ayuda.
|
|
if str_unit == "help":
|
|
ogHelp("ogGetFsSize", "ogGetFsSize int_ndisk int_npartition [str_unit]", "ogGetFsSize 1 1", "ogGetFsSize 1 1 KB")
|
|
return
|
|
|
|
# Error si no se reciben 2 o 3 parámetros.
|
|
if not (2 <= len(sys.argv) <= 3):
|
|
ogRaiseError(OG_ERR_FORMAT)
|
|
return
|
|
|
|
# Obtener unidad y factor de medida.
|
|
UNIT = str_unit or "KB"
|
|
FACTOR = 1
|
|
if UNIT.upper() == "MB":
|
|
FACTOR = 1024
|
|
elif UNIT.upper() == "GB":
|
|
FACTOR = 1024 * 1024
|
|
elif UNIT.upper() == "TB":
|
|
FACTOR = 1024 * 1024 * 1024
|
|
elif UNIT.upper() != "KB":
|
|
ogRaiseError(OG_ERR_FORMAT, f"{UNIT} != {{ KB, MB, GB, TB }}")
|
|
return
|
|
|
|
# Obtener el tamaño del sistema de archivo (si no está formateado; tamaño = 0).
|
|
MNTDIR = ogMount(int_ndisk, int_npartition)
|
|
if MNTDIR:
|
|
result = subprocess.run(["df", "-BK", MNTDIR], capture_output=True, text=True)
|
|
VALUE = result.stdout.split("\n")[1].split()[1]
|
|
SIZE = float(VALUE) / FACTOR
|
|
else:
|
|
SIZE = 0
|
|
|
|
# Devolver el tamaño (quitar decimales si son 0).
|
|
return int(SIZE) if SIZE.is_integer() else SIZE
|
|
|
|
#/**
|
|
# ogGetFsType int_ndisk int_nfilesys
|
|
#@brief Devuelve el mnemonico con el tipo de sistema de archivos.
|
|
#@param int_ndisk nº de orden del disco
|
|
#@param int_nfilesys nº de orden del sistema de archivos
|
|
#@return Mnemonico
|
|
#@note Mnemonico: { EXT2, EXT3, EXT4, BTRFS, REISERFS, XFS, JFS, FAT12, FAT16, FAT32, NTFS, LINUX-SWAP, LINUX-LVM, LINUX-RAID, HFS, HFSPLUS, CACHE }
|
|
#@exception OG_ERR_FORMAT Formato incorrecto.
|
|
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
|
|
#*/ ##
|
|
def ogGetFsType(disk, part):
|
|
PART = DiskLib.ogDiskToDev(disk, part)
|
|
if not PART: return
|
|
|
|
TYPE = None
|
|
if PART.startswith("/"):
|
|
out = subprocess.run(["blkid", "-o", "export", PART], capture_output=True, text=True).stdout.splitlines()
|
|
for line in out:
|
|
if line.startswith("TYPE="):
|
|
TYPE = line.split("=")[1].upper()
|
|
break
|
|
else:
|
|
try:
|
|
subprocess.run(["zfs", "mount", PART])
|
|
except FileNotFoundError:
|
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, 'zfs')
|
|
return
|
|
out = subprocess.run(["mount"], capture_output=True, text=True).stdout.splitlines()
|
|
for line in out:
|
|
if line.startswith(PART):
|
|
TYPE = line.split()[4].upper()
|
|
break
|
|
|
|
if not TYPE:
|
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{disk} {part}')
|
|
return
|
|
|
|
# Componer valores correctos.
|
|
if TYPE == "EXT4":
|
|
if f"{disk} {part}" == CacheLib.ogFindCache():
|
|
if ogIsFormated(disk, part):
|
|
TYPE = "CACHE"
|
|
elif TYPE == "VFAT":
|
|
result = subprocess.run(["blkid", "-po", "export", PART], capture_output=True, text=True)
|
|
for line in result.stdout.split("\n"):
|
|
if line.startswith("VERSION="):
|
|
TYPE = line.split("=")[1].upper()
|
|
break
|
|
elif TYPE == "SWAP":
|
|
TYPE = "LINUX-SWAP"
|
|
elif TYPE.startswith("LVM"):
|
|
TYPE = "LINUX-LVM"
|
|
elif "RAID" in TYPE:
|
|
TYPE = "LINUX-RAID"
|
|
elif TYPE == "ZFS_MEMBER":
|
|
TYPE = "ZVOL"
|
|
elif "_MEMBER" in TYPE:
|
|
TYPE = TYPE.replace("_MEMBER", "")
|
|
|
|
return TYPE
|
|
|
|
|
|
#/**
|
|
# ogGetMountPoint int_ndisk int_nfilesys
|
|
#@brief Devuelve el punto de montaje de un sistema de archivos.
|
|
#@param int_ndisk nº de orden del disco
|
|
#@param int_nfilesys nº de orden del sistema de archivos
|
|
#@return Punto de montaje
|
|
#@exception OG_ERR_FORMAT Formato incorrecto.
|
|
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
|
|
#@note Requisitos: \c mount* \c awk
|
|
#*/ ##
|
|
|
|
def ogGetMountPoint(disk, par):
|
|
PART = DiskLib.ogDiskToDev(disk, par)
|
|
if not PART: return
|
|
|
|
return subprocess.run(["findmnt", "-n", "-o", "TARGET", PART], capture_output=True, text=True).stdout.strip()
|
|
|
|
|
|
|
|
#/**
|
|
# ogIsFormated int_ndisk int_nfilesys
|
|
#@brief Comprueba si un sistema de archivos está formateado.
|
|
#@param int_ndisk nº de orden del disco o volumen.
|
|
#@param int_nfilesys nº de orden del sistema de archivos
|
|
#@return Código de salida: True - formateado, False - sin formato o error.
|
|
#*/ ##
|
|
def ogIsFormated(disk, part):
|
|
PART = ogDiskToDev(disk, part)
|
|
if not PART:
|
|
return
|
|
|
|
# Revisar tipo de sistema de archivos.
|
|
if PART.startswith("/"):
|
|
out = subprocess.run(["blkid", "-s", "TYPE", PART], capture_output=True, text=True).stdout.strip()
|
|
if 'swap' in out: return False
|
|
if '_member' in out: return False
|
|
return bool(out)
|
|
else:
|
|
out = subprocess.run(["zfs", "list", "-Hp", "-o", "canmount", PART], capture_output=True, text=True).stdout.strip()
|
|
return out == "on"
|
|
|
|
|
|
|
|
#/**
|
|
# ogIsLocked int_ndisk int_npartition
|
|
#@see ogIsPartitionLocked
|
|
#*/
|
|
|
|
def ogIsLocked(disk, par):
|
|
return ogIsPartitionLocked(disk, par)
|
|
|
|
|
|
#/**
|
|
# ogIsPartitionLocked int_ndisk int_npartition
|
|
#@brief Comprueba si una partición o su disco están bloqueados por una operación de uso exclusivo.
|
|
#@param int_ndisk nº de orden del disco
|
|
#@param int_npartition nº de orden de la partición
|
|
#@return Código de salida: 0 - bloqueado, 1 - sin bloquear o error.
|
|
#@note Los ficheros de bloqueo se localizan en \c /var/lock/dev, siendo \c dev el dispositivo de la partición o de su disco, sustituyendo el carácter "/" por "-".
|
|
#*/ ##
|
|
def ogIsPartitionLocked(disk, par):
|
|
DISK = DiskLib.ogDiskToDev(disk)
|
|
PART = DiskLib.ogDiskToDev(disk, par)
|
|
if not PART: return
|
|
|
|
LOCKDISK = f"/var/lock/lock{DISK.replace('/', '-')}"
|
|
LOCKPART = f"/var/lock/lock{PART.replace('/', '-')}"
|
|
return os.path.isfile(LOCKDISK) or os.path.isfile(LOCKPART)
|
|
|
|
def ogIsMounted(int_ndisk, int_nfilesys):
|
|
# Si se solicita, mostrar ayuda.
|
|
if len(sys.argv) == 3 and sys.argv[2] == "help":
|
|
ogHelp("ogIsMounted", "ogIsMounted int_ndisk int_nfilesys", "ogIsMounted 1 1")
|
|
return
|
|
|
|
# Error si no se reciben 2 parámetros.
|
|
if len(sys.argv) != 3:
|
|
ogRaiseError(OG_ERR_FORMAT)
|
|
return
|
|
|
|
# Obtener punto de montaje.
|
|
MNTDIR = ogGetMountPoint(int_ndisk, int_nfilesys)
|
|
return bool(MNTDIR)
|
|
|
|
|
|
#/**
|
|
# ogIsReadonly int_ndisk int_nfilesys
|
|
#@brief Comprueba si un sistema de archivos está montado solo de lectura.
|
|
#@param int_ndisk nº de orden del disco
|
|
#@param int_nfilesys nº de orden del sistema de archivos
|
|
#@return Código de salida: 0 - montado solo de lectura, 1 - con escritura o no montado.
|
|
#@version 1.1.0 - Primera versión para OpenGnsys.
|
|
#@author Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@date 2016-01-20
|
|
#*/ ##
|
|
|
|
def ogIsReadonly(disk, par):
|
|
PART = DiskLib.ogDiskToDev(disk, par)
|
|
if not PART: return
|
|
|
|
result = subprocess.run(["findmnt", "-n", "-o", "OPTIONS", PART], capture_output=True, text=True)
|
|
options = result.stdout.strip().split(",")
|
|
return "ro" in options
|
|
|
|
def ogIsWritable(int_ndisk, int_nfilesys):
|
|
# Si se solicita, mostrar ayuda.
|
|
if len(sys.argv) == 3 and sys.argv[2] == "help":
|
|
ogHelp("ogIsWritable", "ogIsWritable int_ndisk int_nfilesys", "ogIsWritable 1 1")
|
|
return
|
|
|
|
# Error si no se reciben 2 parámetros.
|
|
if len(sys.argv) != 3:
|
|
ogRaiseError(OG_ERR_FORMAT)
|
|
return
|
|
|
|
# Obtener partición.
|
|
PART = ogDiskToDev(int_ndisk, int_nfilesys)
|
|
if not PART:
|
|
return
|
|
|
|
# Comprobar si la partición está montada en modo de escritura.
|
|
result = subprocess.run(["findmnt", "-n", "-o", "OPTIONS", PART], capture_output=True, text=True)
|
|
options = result.stdout.strip().split(",")
|
|
return "rw" in options
|
|
|
|
def ogLock(int_ndisk, int_nfilesys):
|
|
ogLockPartition(int_ndisk, int_nfilesys)
|
|
|
|
def ogLockPartition(int_ndisk, int_npartition):
|
|
# Si se solicita, mostrar ayuda.
|
|
if len(sys.argv) == 3 and sys.argv[2] == "help":
|
|
ogHelp("ogLockPartition", "ogLockPartition int_ndisk int_npartition", "ogLockPartition 1 1")
|
|
return
|
|
|
|
# Error si no se reciben 2 parámetros.
|
|
if len(sys.argv) != 3:
|
|
ogRaiseError(OG_ERR_FORMAT)
|
|
return
|
|
|
|
# Obtener partición.
|
|
PART = ogDiskToDev(int_ndisk, int_npartition)
|
|
if not PART:
|
|
return
|
|
|
|
# Crear archivo de bloqueo exclusivo.
|
|
LOCKFILE = f"/var/lock/lock{PART.replace('/', '-')}"
|
|
open(LOCKFILE, 'a').close()
|
|
|
|
|
|
#/**
|
|
# ogMount int_ndisk int_nfilesys
|
|
#@see ogMountFs ogMountCache ogMountCdrom
|
|
#*/ ##
|
|
def ogMount(*args):
|
|
if 1 == len (args):
|
|
if 'cache' == args[0].lower():
|
|
return ogMountCache()
|
|
elif 'cdrom' == args[0].lower():
|
|
return ogMountCdrom()
|
|
elif 2 == len (args):
|
|
return ogMountFs(args[0], args[1])
|
|
|
|
def ogMountFirstFs(int_ndisk):
|
|
# Obtener número de particiones del disco.
|
|
NPARTS = ogGetPartitionsNumber(int_ndisk)
|
|
for PART in range(1, NPARTS + 1):
|
|
MNTDIR = ogMount(int_ndisk, PART)
|
|
if MNTDIR:
|
|
return MNTDIR
|
|
ogRaiseError(OG_ERR_NOTFOUND, int_ndisk)
|
|
return OG_ERR_NOTFOUND
|
|
|
|
#/**
|
|
# ogMountFs int_ndisk int_nfilesys
|
|
#@brief Monta un sistema de archivos.
|
|
#@param int_ndisk nº de orden del disco
|
|
#@param int_nfilesys nº de orden del sistema de archivos
|
|
#@return Punto de montaje
|
|
#@exception OG_ERR_FORMAT Formato incorrecto.
|
|
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
|
|
#@exception OG_ERR_PARTITION Tipo de particion desconocido o no se puede montar.
|
|
#*/ ##
|
|
|
|
def ogMountFs (disk, par):
|
|
dev = DiskLib.ogDiskToDev (disk, par)
|
|
if not dev: return
|
|
|
|
mntdir = ogGetMountPoint (disk, par)
|
|
if mntdir: return mntdir
|
|
|
|
if ogIsLocked (disk, par):
|
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f"{ogGlobals.lang.MSG_PARTITION}, {disk} {par}")
|
|
return
|
|
|
|
# El camino de un dispositivo normal comienza por el carácter "/".
|
|
if dev.startswith ('/'):
|
|
# Crear punto de montaje o enlace simbólico para caché local.
|
|
mntdir = dev.replace ('/dev', '/mnt')
|
|
if f"{disk} {par}" == CacheLib.ogFindCache():
|
|
os.makedirs(ogGlobals.OGCAC, exist_ok=True)
|
|
try:
|
|
os.symlink(ogGlobals.OGCAC, mntdir)
|
|
except FileExistsError:
|
|
pass
|
|
else:
|
|
os.makedirs(mntdir, exist_ok=True)
|
|
|
|
# Montar sistema de archivos.
|
|
try:
|
|
rc = subprocess.run(['mount', dev, mntdir], check=True).returncode
|
|
except subprocess.CalledProcessError:
|
|
try:
|
|
rc = subprocess.run(['mount', dev, mntdir, '-o', 'force,remove_hiberfile'], check=True).returncode
|
|
except subprocess.CalledProcessError:
|
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk}, {par}")
|
|
return
|
|
|
|
if 0 == rc:
|
|
pass
|
|
elif 14 == rc:
|
|
try:
|
|
subprocess.run (['ntfsfix', '-d', par], check=True)
|
|
except subprocess.CalledProcessError:
|
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk, par}")
|
|
#return
|
|
else:
|
|
try:
|
|
subprocess.run (['mount', par, mntdir, '-o', 'ro'], check=True)
|
|
except subprocess.CalledProcessError:
|
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk, par}")
|
|
#return
|
|
|
|
# Aviso de montaje de solo lectura.
|
|
if ogIsReadonly(disk, par):
|
|
SystemLib.ogEcho("warning", f'ogMountFs: {ogGlobals.lang.MSG_MOUNTREADONLY}: "{disk}, {par}"')
|
|
else:
|
|
# Montar sistema de archivos ZFS (un ZPOOL no comienza por "/").
|
|
subprocess.run(['zfs', 'mount', dev])
|
|
|
|
return mntdir
|
|
|
|
|
|
|
|
#/**
|
|
# ogMountCdrom
|
|
#@brief Monta dispositivo óptico por defecto
|
|
#@return Punto de montaje
|
|
#@exception OG_ERR_FORMAT Formato incorrecto.
|
|
#@exception OG_ERR_PARTITION Tipo de particion desconocido o no se puede montar.
|
|
#@version
|
|
#@author
|
|
#@date
|
|
#*/ ##
|
|
def ogMountCdrom():
|
|
DEV = "/dev/cdrom" # Por defecto
|
|
MNTDIR = subprocess.run(["mount", "-l", "-t", "iso9660", DEV], capture_output=True, text=True)
|
|
MNTDIR = MNTDIR.stdout.strip().split(" ")[2]
|
|
if not MNTDIR:
|
|
MNTDIR = DEV.replace("/dev", "/mnt")
|
|
os.makedirs(MNTDIR, exist_ok=True)
|
|
try:
|
|
subprocess.run(["mount", "-t", "iso9660", DEV, MNTDIR], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
except subprocess.CalledProcessError:
|
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, "cdrom")
|
|
return
|
|
return MNTDIR
|
|
|
|
def ogReduceFs(int_ndisk, int_nfilesys):
|
|
# Si se solicita, mostrar ayuda.
|
|
if len(sys.argv) == 3 and sys.argv[2] == "help":
|
|
ogHelp("ogReduceFs", "ogReduceFs int_ndisk int_nfilesys", "ogReduceFs 1 1")
|
|
return
|
|
|
|
# Error si no se reciben 2 parámetros.
|
|
if len(sys.argv) != 3:
|
|
ogRaiseError(OG_ERR_FORMAT)
|
|
return
|
|
|
|
# Obtener partición.
|
|
PART = ogDiskToDev(int_ndisk, int_nfilesys)
|
|
if not PART:
|
|
return
|
|
|
|
# Redimensionar según el tipo de partición.
|
|
TYPE = ogGetFsType(int_ndisk, int_nfilesys)
|
|
if TYPE == "EXT4":
|
|
ogUnmount(int_ndisk, int_nfilesys)
|
|
subprocess.run(["resize2fs", "-fpM", PART], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
elif TYPE == "BTRFS":
|
|
MNTDIR = ogMount(int_ndisk, int_nfilesys)
|
|
SIZE = subprocess.run(["btrfs", "filesystem", "show", MNTDIR], capture_output=True, text=True)
|
|
SIZE = SIZE.stdout.strip().split(" ")[6]
|
|
SIZE = int(float(SIZE) * 1.1 + 1)
|
|
subprocess.run(["btrfs", "filesystem", "resize", str(SIZE), MNTDIR], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
elif TYPE in ["REISERFS", "REISER4"]:
|
|
MNTDIR = ogMount(int_ndisk, int_nfilesys)
|
|
SIZE = int(subprocess.run(["df", "-k", MNTDIR], capture_output=True, text=True).stdout.strip().split("\n")[1].split()[2])
|
|
SIZE = SIZE * 110 // 100
|
|
ogUnmount(int_ndisk, int_nfilesys)
|
|
subprocess.run(["resize_reiserfs", "-s" + str(SIZE) + "K", PART], input="y\n", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
elif TYPE == "NTFS":
|
|
ogUnmount(int_ndisk, int_nfilesys)
|
|
MAXSIZE, SIZE = subprocess.run(["ntfsresize", "-fi", PART], capture_output=True, text=True)
|
|
MAXSIZE = MAXSIZE.strip().split(" ")[3]
|
|
SIZE = SIZE.strip().split(" ")[4]
|
|
SIZE = int(float(SIZE) * 1.1 / 1024 + 1) * 1024
|
|
RETVAL = 1
|
|
while RETVAL != 0 and SIZE + EXTRASIZE < MAXSIZE:
|
|
EXTRASIZE = subprocess.run(["ntfsresize", "-fns", str(SIZE), PART], capture_output=True, text=True)
|
|
EXTRASIZE = int(EXTRASIZE.stdout.strip()) if EXTRASIZE.stdout.strip() else 0
|
|
RETVAL = EXTRASIZE != 0
|
|
SIZE += EXTRASIZE
|
|
if SIZE < MAXSIZE:
|
|
subprocess.run(["ntfsresize", "-fs", str(SIZE), PART], input="y\n", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
elif TYPE in ["FAT32", "FAT16"]:
|
|
# No se reduce (por el momento).
|
|
pass
|
|
elif TYPE == "HFS" or TYPE == "HFSPLUS":
|
|
# No se reduce (por el momento).
|
|
pass
|
|
elif TYPE == "UFS":
|
|
# No se reduce (por el momento).
|
|
pass
|
|
else:
|
|
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk}, {int_nfilesys}")
|
|
|
|
# Devuelve tamaño del sistema de ficheros.
|
|
return ogGetFsSize(int_ndisk, int_nfilesys)
|
|
|
|
def ogUnlock(int_ndisk, int_npartition):
|
|
ogUnlockPartition(int_ndisk, int_npartition)
|
|
|
|
def ogUnlockPartition(int_ndisk, int_npartition):
|
|
# Si se solicita, mostrar ayuda.
|
|
if len(sys.argv) == 3 and sys.argv[2] == "help":
|
|
ogHelp("ogUnlockPartition", "ogUnlockPartition int_ndisk int_npartition", "ogUnlockPartition 1 1")
|
|
return
|
|
|
|
# Error si no se reciben 2 parámetros.
|
|
if len(sys.argv) != 3:
|
|
ogRaiseError(OG_ERR_FORMAT)
|
|
return
|
|
|
|
# Obtener partición.
|
|
PART = ogDiskToDev(int_ndisk, int_npartition)
|
|
if not PART:
|
|
return
|
|
|
|
# Borrar archivo de bloqueo exclusivo.
|
|
LOCKFILE = f"/var/lock/lock{PART.replace('/', '-')}"
|
|
os.remove(LOCKFILE)
|
|
|
|
|
|
#/**
|
|
# ogUnmount int_ndisk int_npartition
|
|
#@see ogUnmountFs
|
|
#*/ ##
|
|
def ogUnmount (disk, par):
|
|
ogUnmountFs (disk, par)
|
|
|
|
#/**
|
|
# ogUnmountFs int_ndisk int_nfilesys
|
|
#@brief Desmonta un sistema de archivos.
|
|
#@param int_ndisk nº de orden del disco
|
|
#@param int_nfilesys nº de orden del sistema de archivos
|
|
#@return Nada
|
|
#@exception OG_ERR_FORMAT Formato incorrecto.
|
|
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
|
|
#@warning La partición no está previamente montada o no se puede desmontar.
|
|
#*/ ##
|
|
|
|
def ogUnmountFs(disk, par):
|
|
PART = DiskLib.ogDiskToDev (disk, par)
|
|
if not PART: return
|
|
MNTDIR = ogGetMountPoint (disk, par)
|
|
|
|
# Si está montada, desmontarla.
|
|
if MNTDIR:
|
|
# Error si la particion está bloqueada.
|
|
if ogIsLocked (disk, par):
|
|
ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f"{ogGlobals.lang.MSG_PARTITION}, {disk} {par}")
|
|
return
|
|
|
|
# Desmontar y borrar punto de montaje.
|
|
try:
|
|
subprocess.run(["umount", PART], check=True)
|
|
except subprocess.CalledProcessError:
|
|
SystemLib.ogEcho("warning", f'ogUnmountFs: {ogGlobals.lang.MSG_DONTUNMOUNT}: "{disk}, {par}"')
|
|
try:
|
|
os.rmdir(MNTDIR)
|
|
except:
|
|
try:
|
|
os.remove(MNTDIR)
|
|
except:
|
|
pass
|
|
else:
|
|
SystemLib.ogEcho ([], "warning", f'{ogGlobals.lang.MSG_DONTMOUNT}: "{disk},{par}"')
|
|
|
|
|
|
#/**
|
|
# ogUnmountAll int_ndisk
|
|
#@brief Desmonta todos los sistema de archivos de un disco, excepto el caché local.
|
|
#@param int_ndisk nº de orden del disco
|
|
#@return Nada
|
|
#@exception OG_ERR_FORMAT Formato incorrecto.
|
|
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
|
|
#@warning No se desmonta la partición marcada como caché local.
|
|
#*/ ##
|
|
def ogUnmountAll(int_ndisk):
|
|
# Si se solicita, mostrar ayuda.
|
|
if len(sys.argv) == 3 and sys.argv[2] == "help":
|
|
ogHelp("ogUnmountAll", "ogUnmountAll int_ndisk", "ogUnmountAll 1")
|
|
return
|
|
|
|
# Error si no se recibe 1 parámetro.
|
|
if len(sys.argv) != 3:
|
|
ogRaiseError(OG_ERR_FORMAT)
|
|
return
|
|
|
|
# Obtener partición y punto de montaje.
|
|
DISK = ogDiskToDev(int_ndisk)
|
|
for PART in range(1, ogGetPartitionsNumber(int_ndisk) + 1):
|
|
if ogGetFsType(int_ndisk, PART) != "CACHE":
|
|
ogUnmount(int_ndisk, PART)
|
|
|
|
def ogUnsetDirtyBit(int_ndisk, int_nfilesys):
|
|
# Si se solicita, mostrar ayuda.
|
|
if len(sys.argv) == 3 and sys.argv[2] == "help":
|
|
ogHelp("ogUnsetDirtyBit", "ogUnsetDirtyBit int_ndisk int_nfilesys", "ogUnsetDirtyBit 1 1")
|
|
return
|
|
|
|
# Error si no se reciben 2 parámetros.
|
|
if len(sys.argv) != 3:
|
|
ogRaiseError(OG_ERR_FORMAT)
|
|
return
|
|
|
|
# Obtener partición y punto de montaje.
|
|
PART = ogDiskToDev(int_ndisk, int_nfilesys)
|
|
if not PART:
|
|
return
|
|
|
|
# Realizar acciones específicas según el tipo de sistema de archivos.
|
|
TYPE = ogGetFsType(int_ndisk, int_nfilesys)
|
|
if TYPE == "NTFS":
|
|
ogUnmount(int_ndisk, int_nfilesys)
|
|
subprocess.run(["ntfsfix", "-d", PART], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
else:
|
|
pass # Add more specific actions for other file systems if needed.
|
|
|
|
def ogGetFreeSize(int_ndisk, int_npartition, str_SizeOutput):
|
|
if len(sys.argv) == 3 and sys.argv[2] == "help":
|
|
ogHelp("ogGetFreeSize", "ogGetFreeSize int_ndisk int_npartition str_SizeOutput", "ogGetFreeSize 1 1 GB")
|
|
return
|
|
|
|
if len(sys.argv) < 3:
|
|
ogRaiseError(OG_ERR_FORMAT)
|
|
return
|
|
|
|
PART = ogDiskToDev(int_ndisk, int_npartition)
|
|
if not PART:
|
|
return
|
|
|
|
unit = str_SizeOutput
|
|
if not unit:
|
|
unit = "GB"
|
|
|
|
factor = 1.024 / 1000000
|
|
if unit == "kB":
|
|
factor = 1.024
|
|
elif unit == "MB":
|
|
factor = 1.024 / 1000
|
|
|
|
result = subprocess.run(["df", PART], capture_output=True, text=True)
|
|
output = result.stdout.strip().split("\n")[1].split()
|
|
size = float(output[1]) * factor
|
|
used = float(output[2]) * factor
|
|
free = float(output[3]) * factor
|
|
|
|
return free
|