440 lines
15 KiB
Bash
440 lines
15 KiB
Bash
#!/bin/bash
|
|
#/**
|
|
#@file Cache.lib
|
|
#@brief Librería o clase Cache
|
|
#@class Cache
|
|
#@brief Funciones para gestión de la caché local de disco.
|
|
#@version 1.1.1
|
|
#@warning License: GNU GPLv3+
|
|
#*/
|
|
|
|
|
|
#/**
|
|
# ogCreateCache [int_ndisk] int_partsize
|
|
#@brief Define la caché local, por defecto en partición 4 del disco 1.
|
|
#@param int_ndisk numero de disco donde crear la cache, si no se indica es el 1 por defecto
|
|
#@param int_npart número de partición (opcional, 4 por defecto)
|
|
#@param int_partsize tamaño de la partición (en KB)
|
|
#@return (nada, por determinar)
|
|
#@exception OG_ERR_FORMAT formato incorrecto.
|
|
#@note Requisitos: sfdisk, parted, awk, sed
|
|
#@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.
|
|
#@version 0.9.1 - Definición de caché local.
|
|
#@author Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@date 2010/03/09
|
|
#@version 0.9.2 - Corrección definición de límites.
|
|
#@author Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@date 2010/06/01
|
|
#@version 1.0.4 - Soporte para discos GPT.
|
|
#@author Universidad de Huelva
|
|
#@date 2012/03/13
|
|
#@version 1.0.5 - Posibilidad de crear la cache en cualquier disco duro
|
|
#@author Universidad de Huelva
|
|
#@date 2012/09/18
|
|
#@version 1.1.0 - Posibilidad de crear la caché en cualquier partición.
|
|
#@author Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@date 2016/05/25
|
|
#@version 1.1.0 - Soporte discos con sectores de 4k
|
|
#@date 2017/01/09
|
|
#@version 1.0.6b - Al crear las particiones ordenamos los dispositivos en el fichero auxiliar.
|
|
#@author Irina Gomez, ETSII Universidad de Sevilla
|
|
#@date 2017/01/09
|
|
#*/ ##
|
|
function ogCreateCache ()
|
|
{
|
|
# Variables locales.
|
|
local FINDCACHE IOSIZE NDSK SIZECACHE PART DISK START END ENDPREVPART SIZE MINSIZE MAXSIZE
|
|
local PTTYPE ID TMPFILE NVME_PREFIX
|
|
# Si se solicita, mostrar ayuda.
|
|
if [ "$*" == "help" ]; then
|
|
ogHelp "$FUNCNAME" "$FUNCNAME [int_ndisk [int_npart]] int_partsize" \
|
|
"$FUNCNAME 10000000" "$FUNCNAME 1 10000000" "$FUNCNAME 1 4 10000000"
|
|
return
|
|
fi
|
|
# Si se recibe un parametro, sera el tamano de la cache
|
|
case $# in
|
|
1) # Error, si no es un entero positivo
|
|
[[ $1 =~ ^[1-9][0-9]*$ ]] || ogRaiseError $OG_ERR_FORMAT "$1" || return $?
|
|
NDSK=1
|
|
PART=4
|
|
SIZECACHE=$1
|
|
;;
|
|
2) # Error, si no son enteros positivos
|
|
[[ $1 =~ ^[1-9][0-9]*$ ]] || ogRaiseError $OG_ERR_FORMAT "$1" || return $?
|
|
[[ $2 =~ ^[1-9][0-9]*$ ]] || ogRaiseError $OG_ERR_FORMAT "$2" || return $?
|
|
NDSK=$1
|
|
PART=4
|
|
SIZECACHE=$2
|
|
;;
|
|
3) # Error, si no son enteros positivos
|
|
[[ $1 =~ ^[1-9][0-9]*$ ]] || ogRaiseError $OG_ERR_FORMAT "$1" || return $?
|
|
[[ $2 =~ ^[1-9][0-9]*$ ]] || ogRaiseError $OG_ERR_FORMAT "$2" || return $?
|
|
[[ $3 =~ ^[1-9][0-9]*$ ]] || ogRaiseError $OG_ERR_FORMAT "$3" || return $?
|
|
NDSK=$1
|
|
PART=$2
|
|
SIZECACHE=$3
|
|
;;
|
|
*) ogRaiseError $OG_ERR_FORMAT
|
|
return $?
|
|
;;
|
|
esac
|
|
|
|
TMPFILE=/tmp/sfdisk$$
|
|
DISK=$(ogDiskToDev $NDSK) || return $?
|
|
|
|
# PATCH Para discos nvme la particion debe ser p1, p2, etc...en lugar de 1,2, sino falla sfdisk
|
|
NVME_PREFIX=""
|
|
if [[ $DISK == *"nvme"* ]]; then
|
|
NVME_PREFIX="p"
|
|
fi
|
|
|
|
|
|
END=$[$(ogGetLastSector $NDSK 2>/dev/null)] # Sector final del disco.
|
|
SIZE=$[$SIZECACHE*2] # Tamaño en sectores de 512 B.
|
|
# Inicio partición cache según el disco tenga sectores de 4k o menores
|
|
IOSIZE=$(fdisk -l $DISK | awk '/I\/O/ {print $4}')
|
|
if [ $IOSIZE -eq 4096 ]; then
|
|
END=$[$END-8192]
|
|
START=$[END-SIZE+2048-(END-SIZE)%2048]
|
|
else
|
|
START=$[END-SIZE+1]
|
|
fi
|
|
ENDPREVPART=$[$(ogGetLastSector $NDSK $[PART-1] 2>/dev/null)]
|
|
# Error si tamaño no está entre límites permitidos o si se solapa con la partición anterior.
|
|
MINSIZE=25000 # Error de formateo si tamaño < 50 MB.
|
|
MAXSIZE=$END # Para restringir tamaño > mitad del disco: MAXSIZE=$[END/2]
|
|
if [ $SIZE -lt $MINSIZE -o $SIZE -gt $MAXSIZE -o $START -le $ENDPREVPART ]; then
|
|
ogRaiseError $OG_ERR_FORMAT "$1" || return $?
|
|
fi
|
|
|
|
# Desmontar todos los sistemas de archivos del disco.
|
|
ogUnmountAll $NDSK 2>/dev/null
|
|
# 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=$(ogGetPartitionTableType $NDSK)
|
|
if [ -z "$PTTYPE" ]; then
|
|
PTTYPE="MSDOS" # Por defecto para discos vacíos.
|
|
ogCreatePartitionTable $NDSK $PTTYPE
|
|
fi
|
|
case "$(ogGetPartitionTableType $NDSK)" in
|
|
GPT)
|
|
# Si la tabla de particiones no es valida, volver a generarla.
|
|
[ ! $(sgdisk -p $DISK &>/dev/null) ] || echo -e "2\nw\nY\n" | gdisk $DISK
|
|
# Si existe la cache se borra previamente
|
|
[ -n "$(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=$(ogTypeToId LINUX GPT)
|
|
sgdisk $DISK -n$PART:$START:$END -c$PART:CACHE -t$PART:$ID 2>/dev/null
|
|
;;
|
|
MSDOS)
|
|
# Si la tabla de particiones no es valida, volver a generarla.
|
|
parted -s $DISK print &>/dev/null || fdisk $DISK <<< "w"
|
|
# Definir particiones y notificar al kernel.
|
|
ID=$(ogTypeToId CACHE MSDOS)
|
|
# Salvamos la configuración de las particiones e incluimos la cache.
|
|
trap "rm -f $TMPFILE" 1 2 3 9 15
|
|
sfdisk --dump $DISK | grep -v $DISK$PART > $TMPFILE
|
|
echo "$DISK$NVME_PREFIX$PART : start= $START, size= $SIZE, Id=$ID" >> $TMPFILE
|
|
# Ordenamos las líneas de los dispositivos
|
|
UNIT=$(grep unit $TMPFILE)
|
|
grep ^/dev $TMPFILE|sort -o $TMPFILE
|
|
sed -i "1i $UNIT\n" $TMPFILE
|
|
# Guardamos nueva configuración en el disco.
|
|
sfdisk --no-reread $DISK < $TMPFILE
|
|
rm -f $TMPFILE
|
|
;;
|
|
esac
|
|
# Actualiza la tabla de particiones en el kernel.
|
|
ogUpdatePartitionTable
|
|
}
|
|
|
|
|
|
#/**
|
|
# ogDeleteCache
|
|
#@brief Elimina la partición de caché local.
|
|
#@return (nada, por determinar)
|
|
#@exception OG_ERR_FORMAT formato incorrecto.
|
|
#@note Requisitos: fdisk, sgdisk, partprobe
|
|
#@version 0.91 - Definición de caché local.
|
|
#@author Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@date 2010/03/11
|
|
#@version 1.0.4 - Soporte para discos GPT.
|
|
#@author Universidad de Huelva
|
|
#@date 2012/03/13
|
|
#@version 1.0.6b - llamada correcta a ogUpdatePartitionTable
|
|
#@author Antonio Doblas Universidad de Málaga
|
|
#@date 2016/11/16
|
|
#@version 1.1.0 - Sustituir "sfdisk" por "fdisk" para discos MSDOS.
|
|
#@author Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@date 2016/05/25
|
|
#*/ ##
|
|
function ogDeleteCache ()
|
|
{
|
|
# Variables locales.
|
|
local NDISK NPART DISK
|
|
# Si se solicita, mostrar ayuda.
|
|
if [ "$*" == "help" ]; then
|
|
ogHelp "$FUNCNAME" "$FUNCNAME"
|
|
return
|
|
fi
|
|
# Error si no se encuentra partición de caché.
|
|
read NDISK NPART <<<"$(ogFindCache)"
|
|
[ -n "$NDISK" -a -n "$NPART" ] || ogRaiseError $OG_ERR_PARTITION "$MSG_NOCACHE" || return $?
|
|
DISK=$(ogDiskToDev $NDISK)
|
|
|
|
# Desmontar todos los sistemas de archivos del disco.
|
|
ogUnmountAll $NDISK 2>/dev/null
|
|
case "$(ogGetPartitionTableType $NDISK)" in
|
|
GPT)
|
|
# Si la tabla de particiones no es valida, volver a generarla.
|
|
[ ! $(sgdisk -p $DISK 2>&1 >/dev/null) ] || echo -e "2\nw\nY\n" | gdisk $DISK
|
|
sgdisk $DISK -d$NPART 2>/dev/null
|
|
;;
|
|
MSDOS)
|
|
# Si la tabla de particiones no es valida, volver a generarla.
|
|
parted -s $DISK print &>/dev/null || fdisk $DISK <<< "w"
|
|
# Eliminar la partición de caché.
|
|
echo -e "d\n$NPART\nw" | fdisk $DISK 2>/dev/null
|
|
;;
|
|
esac
|
|
# Borrar etiqueta de la caché.
|
|
rm -f /dev/disk/by-label/CACHE
|
|
#Actualiza la tabla de particiones en el kernel.
|
|
ogUpdatePartitionTable $NDISK
|
|
}
|
|
|
|
|
|
#/**
|
|
# ogFindCache
|
|
#@brief Detecta la partición caché local.
|
|
#@param No requiere parametros
|
|
#@return int_ndisk int_npart - devuelve el par nº de disco-nº de partición .
|
|
#@warning Si no hay cache no devuelve nada
|
|
#@version 0.1 - Integracion para Opengnsys - EAC: FindCache() en ATA.lib - HIDRA: DetectarCache.sh
|
|
#@author Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@Date 2008/06/19
|
|
#@author Antonio J. Doblas Viso. Universidad de Malaga
|
|
#@Date 2008/10/27
|
|
#@version 0.91 - Adaptacion a la cache local de OpenGnSys.
|
|
#@author Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@date 2010/03/16
|
|
#@version 1.0.5 - Obtener caché en discos GPT.
|
|
#@author Alberto García, Universidad de Málaga y Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@date 2014/05/28
|
|
#*/ ##
|
|
function ogFindCache ()
|
|
{
|
|
# Variables locales
|
|
local DISK PART
|
|
# Si se solicita, mostrar ayuda.
|
|
if [ "$*" == "help" ]; then
|
|
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => 1 4"
|
|
return
|
|
fi
|
|
# Obtener el dispositivo del sistema de archivos etiquetado como "CACHE".
|
|
PART=$(blkid -L "CACHE")
|
|
# En discos nvme con particiones GPT la partición se detecta usando el tag PARTLABEL
|
|
PART=${PART:-$(blkid -t PARTLABEL=CACHE | awk -F: '{print $1}')}
|
|
# Si no se detecta, obtener particiones marcadas de tipo caché en discos MSDOS.
|
|
PART=${PART:-$(sfdisk -l 2>/dev/null | awk '$6~/ca|a7/ {print $1}')}
|
|
|
|
# Por último revisar todos los discos GPT y obtener las particiones etiquetadas como caché.
|
|
if [ -z "$PART" ]; then
|
|
for DISK in $(ogDiskToDev); do
|
|
# Nota: se añade espacio separador solo si existe valor previo.
|
|
PART="${PART:+"$PART "}$(sgdisk -p $DISK 2>/dev/null | awk -v d=$DISK '$7~/CACHE/ {printf "%s%s",d,$1;}')"
|
|
done
|
|
fi
|
|
|
|
# Devolver número de disco y número de partición de la 1ª partición encontrada.
|
|
ogDevToDisk ${PART%% *} 2>/dev/null
|
|
}
|
|
|
|
|
|
#/**
|
|
# ogFormatCache
|
|
#@brief Formatea el sistema de ficheros para la caché local.
|
|
#@return (por determinar)
|
|
#@warning Prueba con formato Reiser.
|
|
#@attention
|
|
#@note El sistema de archivos de la caché se queda montado.
|
|
#@version 0.1 - Integracion para Opengnsys - EAC: FormatCache() en ATA.lib
|
|
#@author Antonio J. Doblas Viso. Universidad de Malaga
|
|
#@date 2008/10/27
|
|
#@version 0.91 - Creacion cache local.
|
|
#@author Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@date 2010-03-11
|
|
#@version 1.1.0 - llamada a updateBootCache.
|
|
#@author Antonio J. Doblas Viso. Universidad de Malaga
|
|
#@date 2018-01-21
|
|
|
|
#*/ ##
|
|
function ogFormatCache ()
|
|
{
|
|
# Variables locales.
|
|
local DEV MNTDIR OPTIONS
|
|
# Si se solicita, mostrar ayuda.
|
|
if [ "$*" == "help" ]; then
|
|
ogHelp "$FUNCNAME" "$FUNCNAME"
|
|
return
|
|
fi
|
|
|
|
# Error si no hay definida partición de caché.
|
|
DEV=$(ogFindCache) || ogRaiseError $OG_ERR_PARTITION "$MSG_NOCACHE" || return $?
|
|
DEV=$(ogDiskToDev $DEV) || return $?
|
|
|
|
# Formatear sistema de ficheros.
|
|
ogUnmountCache 2>/dev/null
|
|
OPTIONS="extent,large_file"
|
|
[[ $(uname -r) =~ ^5 ]] && OPTIONS+=",uninit_bg,^metadata_csum,^64bit"
|
|
mkfs.ext4 -q -F $DEV -L "CACHE" -O "$OPTIONS" 2>/dev/null || ogRaiseError $OG_ERR_PARTITION "CACHE" || return $?
|
|
|
|
# Crear estructura básica.
|
|
MNTDIR=$(ogMountCache)
|
|
mkdir -p $MNTDIR/$OGIMG
|
|
|
|
# Incluir kernel e Initrd del ogLive
|
|
updateBootCache 2>&1>/dev/null
|
|
}
|
|
|
|
|
|
#/**
|
|
# ogGetCacheSize
|
|
#@brief Devuelve el tamaño definido para la partición de caché.
|
|
#@return int_partsize tamaño de la partición (en KB)
|
|
#@exception OG_ERR_PARTITION No existe partición de caché.
|
|
#@version 0.1 - Integracion para Opengnsys - EAC: InfoCache() en FileSystem.lib
|
|
#@author Antonio J. Doblas Viso. Universidad de Malaga
|
|
#@date 2008/10/27
|
|
#@version 0.91 - Definicion de cache local.
|
|
#@author Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@date 2010/03/09
|
|
#*/ ##
|
|
function ogGetCacheSize ()
|
|
{
|
|
# Variables locales
|
|
local PART
|
|
|
|
# Si se solicita, mostrar ayuda.
|
|
if [ "$*" == "help" ]; then
|
|
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => 10000000"
|
|
return
|
|
fi
|
|
# Error si no se encuentra partición de caché.
|
|
PART=$(ogFindCache) || ogRaiseError $OG_ERR_PARTITION "$MSG_NOCACHE" || return $?
|
|
|
|
# Devuelve tamaño de la partición de caché.
|
|
ogGetPartitionSize $PART
|
|
}
|
|
|
|
|
|
#/**
|
|
# ogGetCacheSpace
|
|
#@brief Devuelve el espacio de disco disponible para la partición de caché.
|
|
#@return int_size tamaño disponible (en KB)
|
|
#@note El espacio disponible es el que hay entre el límite superior de la partición 3 del disco 1 y el final de dicho disco, y no puede ser superior a la mitad de dicho disco.
|
|
#@version 0.1 - Integracion para Opengnsys - EAC: InfoCache() en FileSystem.lib
|
|
#@author Antonio J. Doblas Viso. Universidad de Malaga
|
|
#@date 2008/10/27
|
|
#@version 0.91 - Definicion de cache local.
|
|
#@author Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@date 2010/03/09
|
|
#@version 1.0.5 - Uso de ogFindCache para detectar disco y particion
|
|
#@author Universidad de Huelva
|
|
#@date 2012/09/18
|
|
#*/ ##
|
|
function ogGetCacheSpace ()
|
|
{
|
|
# Variables locales.
|
|
local NDISK DISK NPART SECTORS CYLS ENDPART3
|
|
# Si se solicita, mostrar ayuda.
|
|
if [ "$*" == "help" ]; then
|
|
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => 23165386"
|
|
return
|
|
fi
|
|
# Parche UHU para usar ogFindCache en lugar de 1
|
|
# Error si no se encuentra partición de caché.
|
|
read NDISK NPART <<<"$(ogFindCache)"
|
|
[ -n "$NDISK" -a -n "$NPART" ] || ogRaiseError $OG_ERR_PARTITION "$MSG_NOCACHE" || return $?
|
|
DISK=$(ogDiskToDev $NDISK) || return $?
|
|
|
|
SECTORS=$(awk -v D=${DISK#/dev/} '{if ($4==D) {print $3*2}}' /proc/partitions)
|
|
CYLS=$(sfdisk -g $DISK | cut -f2 -d" ")
|
|
SECTORS=$[SECTORS/CYLS*CYLS-1]
|
|
ENDPART3=$(sfdisk -uS -l $DISK | awk -v P="${DISK}3" '{if ($1==P) print $3}')
|
|
# Mostrar espacio libre en KB (1 KB = 2 sectores)
|
|
if [ $ENDPART3 -gt $[SECTORS/2] ]; then
|
|
echo $[(SECTORS-ENDPART3)/2]
|
|
else
|
|
echo $[SECTORS/4]
|
|
fi
|
|
}
|
|
|
|
|
|
#/**
|
|
# ogMountCache
|
|
#@brief Monta la partición Cache y exporta la variable $OGCAC
|
|
#@param sin parametros
|
|
#@return path_mountpoint - Punto de montaje del sistema de archivos de cache.
|
|
#@warning Salidas de errores no determinada
|
|
#@version 0.1 - Integracion para Opengnsys - EAC: MountCache() en FileSystem.lib - HIDRA: MontarCache.sh
|
|
#@author Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@date 2008/06/19
|
|
#@author Antonio J. Doblas Viso. Universidad de Malaga
|
|
#@Date 2008/10/27
|
|
#@version 0.91 - Adaptacion a la cache local de OpenGnSys.
|
|
#@author Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@date 2010/03/16
|
|
#@version 1.0 - Correccion multiples montajes de cache.
|
|
#@author Antonio J. Doblas Viso, Universidad de Malaga
|
|
#@date 2011/02/24
|
|
#*/ ##
|
|
function ogMountCache ()
|
|
{
|
|
# Si se solicita, mostrar ayuda.
|
|
if [ "$*" == "help" ]; then
|
|
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME ==> /mnt/sda4"
|
|
return
|
|
fi
|
|
|
|
ogMountFs $(ogFindCache) 2>/dev/null || ogRaiseError $OG_ERR_PARTITION "$MSG_NOCACHE" || return $?
|
|
}
|
|
|
|
|
|
#/**
|
|
# ogUnmountCache
|
|
#@brief Desmonta la particion Cache y elimina la variable $OGCAC
|
|
#@param sin parametros
|
|
#@return nada
|
|
#@warning Salidas de errores no determinada
|
|
#@version 0.1 - Integracion para Opengnsys - EAC: UmountCache() en FileSystem.lib
|
|
#@author Antonio J. Doblas Viso. Universidad de Malaga
|
|
#@Date 2008/10/27
|
|
#@version 0.91 - Adaptacion a la cache local de OpenGnSys.
|
|
#@author Ramon Gomez, ETSII Universidad de Sevilla
|
|
#@date 2010/03/16
|
|
#@version 1.0 - Correccion multiples montajes de cache.
|
|
#@author Antonio J. Doblas Viso, Universidad de Malaga
|
|
#@date 2011/02/24
|
|
#*/ ##
|
|
function ogUnmountCache ()
|
|
{
|
|
# Variables locales.
|
|
local CACHE
|
|
# Si se solicita, mostrar ayuda.
|
|
if [ "$*" == "help" ]; then
|
|
ogHelp "$FUNCNAME" "$FUNCNAME"
|
|
return
|
|
fi
|
|
|
|
CACHE=$(ogFindCache) || ogRaiseError $OG_ERR_PARTITION "$MSG_NOCACHE"
|
|
ogIsMounted $CACHE || return 0
|
|
ogUnmountFs $CACHE
|
|
# Borrar enlace simbólico de /mnt/ParticiónCache.
|
|
rm -f $(ogDiskToDev $CACHE | sed 's/dev/mnt/')
|
|
}
|
|
|