summaryrefslogtreecommitdiffstats
path: root/client/engine
diff options
context:
space:
mode:
authorIrina Gómez <irinagomez@us.es>2019-04-15 10:47:20 +0200
committerIrina Gómez <irinagomez@us.es>2019-04-15 10:47:20 +0200
commitb00e622946cb37fb20e00f27d43f9fef37ec260e (patch)
tree1cea86546075465398c45d4714de4e06c98bb4e4 /client/engine
parentfae14f68cc17fdf1d96473fa1541137ba1186ac2 (diff)
#802 #888 Functions for the NVRAM management. Functions in UEFI.lib ordered in alphabetical order.
Diffstat (limited to 'client/engine')
-rwxr-xr-xclient/engine/System.lib1
-rw-r--r--client/engine/UEFI.lib400
2 files changed, 342 insertions, 59 deletions
diff --git a/client/engine/System.lib b/client/engine/System.lib
index d016be13..77f77b48 100755
--- a/client/engine/System.lib
+++ b/client/engine/System.lib
@@ -243,6 +243,7 @@ case "$CODE" in
$OG_ERR_DONTSYNC_IMAGE) MSG="$MSG_ERR_DONTSYNC_IMAGE \"$2\"" ;;
$OG_ERR_NOTDIFFERENT) MSG="$MSG_ERR_NOTDIFFERENT \"$2\"" ;;
$OG_ERR_SYNCHRONIZING) MSG="$MSG_ERR_SYNCHRONIZING \"$2\"" ;;
+ $OG_ERR_NOTUEFI) MSG="$MSG_ERR_NOTUEFI \"$2\"" ;;
*) MSG="$MSG_ERR_GENERIC"; CODE=$OG_ERR_GENERIC ;;
esac
diff --git a/client/engine/UEFI.lib b/client/engine/UEFI.lib
index fea81135..4c1345a6 100644
--- a/client/engine/UEFI.lib
+++ b/client/engine/UEFI.lib
@@ -3,6 +3,193 @@
# Las funciones se incluirán las librerías ya existentes
#/**
+# ogActiveNvramEntry
+#@brief Borra entrada de la NVRAM identificada por la etiqueta o el orden
+#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
+#@return (nada)
+#@exception OG_ERR_FORMAT formato incorrecto.
+#@exception OG_ERR_NOTUEFI UEFI no activa.
+#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
+#*/ ##
+function ogActiveNvramEntry () {
+local NUMENTRY
+
+# Si se solicita, mostrar ayuda.
+if [ "$*" == "help" ]; then
+ ogHelp "$FUNCNAME" "$FUNCNAME [ Num_order_entry | Label_entry ] " \
+ "$FUNCNAME 2" \
+ "$FUNCNAME \"Windows Boot Manager\""
+ return
+fi
+
+# Error si no se recibe 1 parámetro.
+[ $# -eq 1 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME [ Num_order_entry | Label_entry ]" || return $?
+
+# Si no es equipo UEFI salir con error
+ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
+
+# Distingo si es número de orden o etiqueta
+if [[ $1 =~ ^([0-9a-FA-F]+)*$ ]]; then
+ NUMENTRY=$( efibootmgr |awk -v NUM="$(printf %04x 0x$1|tr '[:lower:]' '[:upper:]')" '{ if($1~NUM) print substr($1,5,4)}')
+else
+ NUMENTRY=$(efibootmgr |awk -v LABEL="$1" '{ if(substr($0, index($0,$2))==LABEL) print substr($1,5,4)}')
+fi
+
+[ "$NUMENTRY" == "" ] && return $(ogRaiseError $OG_ERR_NOTFOUND "NVRAM entry '$1'")
+
+efibootmgr -a -b $NUMENTRY &>/dev/null
+}
+
+
+#/**
+# ogCopyEfiBootLoader int_ndisk str_repo path_image
+#@brief Copia el cargador de arranque desde la partición EFI a la de sistema.
+#@param int_ndisk nº de orden del disco
+#@param int_part nº de partición
+#@return (nada, por determinar)
+#@exception OG_ERR_FORMAT formato incorrecto.
+#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
+#@note Si existe el cargador en la partición de sistema no es válido
+#*/ ##
+function ogCopyEfiBootLoader () {
+# Variables locales
+local MNTDIR EFIDIR BOOTLABEL OSVERSION LOADER f
+
+# Si se solicita, mostrar ayuda.
+if [ "$*" == "help" ]; then
+ ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part" \
+ "$FUNCNAME 1 2"
+ return
+fi
+
+# Error si no se reciben 2 arámetros.
+[ $# == 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part" || return $?
+
+# Comprobamos que exista partición de sistema y la ESP
+MNTDIR=$(ogMount $1 $2) || ogRaiseError $OG_ERR_PARTITION "$DISK $PART" || return $?
+EFIDIR=$(ogMount $(ogGetEsp)) || ogRaiseError $OG_ERR_PARTITION "ESP" || return $?
+
+# Comprobamos que exista el cargador
+BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2)
+OSVERSION=$(ogGetOsVersion $1 $2)
+case $OSVERSION in
+ *Windows\ 10*)
+ for f in $EFIDIR/EFI/{$BOOTLABEL,Microsoft}/Boot/bootmgfw.efi; do
+ [ -r $f ] && LOADER=$f
+ done
+ [ -n "$LOADER" ] || ogRaiseError $OG_ERR_NOTOS "$1 $2 ($OSVERSION, EFI)" || return $?
+ # Si existe el directorio Boot lo borramos
+ [ -d $MNTDIR/Boot ] && rm -rf $MNTDIR/Boot
+ DIRLOADER=$(realpath "${LOADER%/*}/..")
+ cp -r ${DIRLOADER}/Boot $MNTDIR
+ ;;
+esac
+}
+
+
+#/**
+# ogDeleteNvramEntry
+#@brief Borra entrada de la NVRAM identificada por la etiqueta o el orden
+#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
+#@return (nada)
+#@exception OG_ERR_FORMAT formato incorrecto.
+#@exception OG_ERR_NOTUEFI UEFI no activa.
+#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (entrada en NVRAM).
+#*/ ##
+function ogDeleteNvramEntry () {
+local NUMENTRY
+
+# Si se solicita, mostrar ayuda.
+if [ "$*" == "help" ]; then
+ ogHelp "$FUNCNAME" "$FUNCNAME [ Num_order_entry | Label_entry ] " \
+ "$FUNCNAME 2" \
+ "$FUNCNAME \"Windows Boot Manager\""
+ return
+fi
+
+# Error si no se recibe 1 parámetro.
+[ $# -eq 1 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME [ Num_order_entry | Label_entry ]" || return $?
+
+# Si no es equipo UEFI salir con error
+ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
+
+# Distingo si es número de orden o etiqueta
+if [[ $1 =~ ^([0-9a-FA-F]+)*$ ]]; then
+ NUMENTRY=$( efibootmgr |awk -v NUM="$(printf %04x 0x$1|tr '[:lower:]' '[:upper:]')" '{ if($1~NUM) print substr($1,5,4)}')
+else
+ NUMENTRY=$(efibootmgr |awk -v LABEL="$1" '{ if(substr($0, index($0,$2))==LABEL) print substr($1,5,4)}')
+fi
+
+[ "$NUMENTRY" == "" ] && return $(ogRaiseError $OG_ERR_NOTFOUND "NVRAM entry '$1'")
+
+efibootmgr -B -b $NUMENTRY &>/dev/null
+}
+
+
+#/**
+# ogGetNvramCurrentEntry
+#@brief Muestra la entrada del gestor de arranque (NVRAM) que ha inciado el equipo.
+#@return Orden de las entradas
+#@exception OG_ERR_NOTUEFI UEFI no activa.
+#*/ ##
+function ogGetNvramCurrentEntry () {
+
+# Si se solicita, mostrar ayuda.
+if [ "$*" == "help" ]; then
+ ogHelp "$FUNCNAME" "$FUNCNAME" \
+ "$FUNCNAME"
+ return
+fi
+
+# Si no es equipo UEFI salir con error
+ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
+
+efibootmgr| awk '{if ($1~/BootCurrent/) bootentry=$2; if ($1~bootentry) printf "%s %s %s\n", gensub(/^0{1,3}/,"",1,substr($1,5,4))," ", substr($0, index($0,$2))}'
+}
+
+
+# ogGetNvramOrder
+#@brief Muestra el orden de las entradas de la NVRAM
+#@return Orden de las entradas
+#@exception OG_ERR_NOTUEFI UEFI no activa.
+#*/ ##
+function ogGetNvramOrder (){
+# Si se solicita, mostrar ayuda.
+if [ "$*" == "help" ]; then
+ ogHelp "$FUNCNAME" "$FUNCNAME" \
+ "$FUNCNAME"
+ return
+fi
+
+# Si no es equipo UEFI salir con error
+ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
+
+efibootmgr|awk '{ if ($1 == "BootOrder:") print $2}'
+}
+
+
+#/**
+# ogGetNvramTimeout
+#@brief Muestra el tiempo de espera del gestor de arranque (NVRAM)
+#@return Timeout de la NVRAM
+#@exception OG_ERR_NOTUEFI UEFI no activa.
+#*/ ##
+function ogGetNvramTimeout (){
+# Si se solicita, mostrar ayuda.
+if [ "$*" == "help" ]; then
+ ogHelp "$FUNCNAME" "$FUNCNAME" \
+ "$FUNCNAME"
+ return
+fi
+
+# Si no es equipo UEFI salir con error
+ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
+
+efibootmgr|awk '{ if ($1 == "Timeout:") print substr($0, index($0,$2))}'
+}
+
+
+#/**
# ogGrubUefiConf int_ndisk int_part str_dir_grub
#@brief Genera el fichero grub.cfg de la ESP
#@param int_ndisk nº de orden del disco
@@ -49,90 +236,68 @@ EOT
#cp $EFIGRUBDIR/grub.cfg "$EFIDIR/EFI/$BOOTLABEL/grub.cfg"
}
+
#/**
-# ogUuidChange int_ndisk str_repo
-#@brief Reemplaza el UUID de un sistema de ficheros.
-#@param int_ndisk nº de orden del disco
-#@param int_part nº de partición
-#@return (nada, por determinar)
+# ogInactiveNvramEntry
+#@brief Inactiva entrada de la NVRAM identificada por la etiqueta o el orden
+#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
+#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
+#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
-function ogUuidChange () {
-local MNTDIR DEVICE UUID NEWUUID f
+function ogInactiveNvramEntry () {
+local NUMENTRY
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
- ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part" \
- "$FUNCNAME 1 2"
+ ogHelp "$FUNCNAME" "$FUNCNAME [ Num_order_entry | Label_entry ] " \
+ "$FUNCNAME 2" \
+ "$FUNCNAME \"Windows Boot Manager\""
return
fi
-# Error si no se reciben al menos 2 parámetros.
-[ $# -eq 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part" || return $?
+# Error si no se recibe 1 parámetro.
+[ $# -eq 1 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME [ Num_order_entry | Label_entry ]" || return $?
-# Comprobamos que exista la partición
-MNTDIR=$(ogMount $1 $2) || ogRaiseError $OG_ERR_NOTFOUND "Device $1 $2" || return $?
-DEVICE=$(ogDiskToDev $1 $2)
-UUID=$(blkid -o value -s UUID $DEVICE)
-NEWUUID=$(cat /proc/sys/kernel/random/uuid)
+# Si no es equipo UEFI salir con error
+ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
-# Cambiamos UUID a la partición
-ogUnmount $1 $2
-tune2fs $DEVICE -U $NEWUUID
+# Distingo si es número de orden o etiqueta
+if [[ $1 =~ ^([0-9a-FA-F]+)*$ ]]; then
+ NUMENTRY=$( efibootmgr |awk -v NUM="$(printf %04x 0x$1|tr '[:lower:]' '[:upper:]')" '{ if($1~NUM) print substr($1,5,4)}')
+else
+ NUMENTRY=$(efibootmgr |awk -v LABEL="$1" '{ if(substr($0, index($0,$2))==LABEL) print substr($1,5,4)}')
+fi
-# Cambiamos UUID en la configuración (fstab y grub)
-ogMount $1 $2
-for f in $MNTDIR/etc/fstab $MNTDIR/{,boot/}{{grubMBR,grubPARTITION}/boot/,}{grub{,2},{,efi/}EFI/*}/{menu.lst,grub.cfg}; do
- [ -r $f ] && sed -i s/$UUID/$NEWUUID/g $f
-done
+[ "$NUMENTRY" == "" ] && return $(ogRaiseError $OG_ERR_NOTFOUND "NVRAM entry '$1'")
+
+efibootmgr -A -b $NUMENTRY &>/dev/null
}
+
#/**
-# ogCopyEfiBootLoader int_ndisk str_repo path_image
-#@brief Copia el cargador de arranque desde la partición EFI a la de sistema.
-#@param int_ndisk nº de orden del disco
-#@param int_part nº de partición
-#@return (nada, por determinar)
-#@exception OG_ERR_FORMAT formato incorrecto.
-#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
-#@note Si existe el cargador en la partición de sistema no es válido
+# ogListNvramEntry
+#@brief Lista las entradas de la NVRAN (sólo equipos UEFI)
+#@return Entradas de la NVRAM con el formato: orden etiqueta [* (si está activa) ]
+#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
-function ogCopyEfiBootLoader () {
-# Variables locales
-local MNTDIR EFIDIR BOOTLABEL OSVERSION LOADER f
+function ogListNvramEntry () {
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
- ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part" \
- "$FUNCNAME 1 2"
+ ogHelp "$FUNCNAME" "$FUNCNAME" \
+ "$FUNCNAME"
return
fi
-# Error si no se reciben 2 arámetros.
-[ $# == 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part" || return $?
-
-# Comprobamos que exista partición de sistema y la ESP
-MNTDIR=$(ogMount $1 $2) || ogRaiseError $OG_ERR_PARTITION "$DISK $PART" || return $?
-EFIDIR=$(ogMount $(ogGetEsp)) || ogRaiseError $OG_ERR_PARTITION "ESP" || return $?
+# Si no es equipo UEFI salir con error
+ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
-# Comprobamos que exista el cargador
-BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2)
-OSVERSION=$(ogGetOsVersion $1 $2)
-case $OSVERSION in
- *Windows\ 10*)
- for f in $EFIDIR/EFI/{$BOOTLABEL,Microsoft}/Boot/bootmgfw.efi; do
- [ -r $f ] && LOADER=$f
- done
- [ -n "$LOADER" ] || ogRaiseError $OG_ERR_NOTOS "$1 $2 ($OSVERSION, EFI)" || return $?
- # Si existe el directorio Boot lo borramos
- [ -d $MNTDIR/Boot ] && rm -rf $MNTDIR/Boot
- DIRLOADER=$(realpath "${LOADER%/*}/..")
- cp -r ${DIRLOADER}/Boot $MNTDIR
- ;;
-esac
+efibootmgr |awk '{if($1~/Boot[[:digit:]]/) ; active="" ;if ($1~/*/) active="*"; if($1~/Boot[[:digit:]]/) printf "%4s %s %s %s\n", gensub(/^0{1,3}/,"",1,substr($1,5,4))," ", substr($0, index($0,$2)), active}'
}
+
#/**
# ogRestoreEfiBootLoader int_ndisk str_repo
#@brief Copia el cargador de arranque de la partición de sistema a la partición EFI.
@@ -183,6 +348,7 @@ esac
}
+#/**
# ogRestoreUuidPartitions
#@brief Restaura los uuid de las particiones y la tabla de particiones
#@param int_ndisk nº de orden del disco
@@ -191,6 +357,7 @@ esac
#@param str_imgname nombre de la imagen
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND No encontrado fichero de información de la imagen (con uuid)
+#*/ ##
function ogRestoreUuidPartitions () {
local DISK PART IMGNAME INFOFILE DEVICE DATA GUID UUID IMGGUID
local EFIDEVICE EFIDATA EFIGUID EFIUUID EFIUUID IMGEFIGUID
@@ -246,9 +413,10 @@ echo sgdisk -U "$IMGEFIGUID" "$EFIDEVICE"
partprobe
fi
fi
-
}
+
+#/**
# ogSaveImageInfo
#@brief Crea un fichero con la información de la imagen.
#@param int_ndisk nº de orden del disco
@@ -257,6 +425,7 @@ fi
#@param str_imgname nombre de la imagen
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
+#*/ ##
function ogSaveImageInfo () {
local DISK PART IMGDIR IMGNAME INFO INFOFILE DEVICE DATA GUID
local EFIPARTDEVICE EFIDEVICE EFIDATA EFIGUID
@@ -313,3 +482,116 @@ cat << EOT | jq . > $INFOFILE
$INFO
EOT
}
+
+
+#/**
+# ogSetNvramOrder
+#@brief Configura el orden de las entradas de la NVRAM
+#@param Orden de las entradas separadas por espacios
+#@return (nada)
+#@exception OG_ERR_FORMAT formato incorrecto.
+#@exception OG_ERR_NOTUEFI UEFI no activa.
+#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (entrada NVRAM).
+#*/ ##
+function ogSetNvramOrder (){
+# Si se solicita, mostrar ayuda.
+if [ "$*" == "help" ]; then
+ ogHelp "$FUNCNAME" "$FUNCNAME Num_order1 [ Num_order2 ] ... " \
+ "$FUNCNAME 1 3"
+ return
+fi
+#
+# Error si no se recibe al menos 1 parámetro.
+[ $# -ge 1 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME Num_order1 [ Num_order2 ] ..." || return $?
+
+# Si no es equipo UEFI salir con error
+ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
+
+# Comprobamos que sean números
+[[ "$@" =~ ^([0-9a-fA-F ]+)*$ ]] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME Num_order1 [ Num_order2 ] ..." || return $?
+
+# Entradas de la NVRAM actuales
+NUMENTRYS=$(efibootmgr|awk '{ if ($1~/Boot[0-9a-fA-F]+/) printf "0%s ", substr($1,5,4)}')
+
+ORDER=""
+for ARG in $@; do
+ # Si no existe la entrada me salgo
+ ARG=$(printf %04x 0x$ARG)
+ echo $NUMENTRYS | grep "$ARG" &>/dev/null || ogRaiseError $OG_ERR_NOTFOUND "NVRAM entry order \"$ARG\"" || return $?
+ ORDER=${ORDER},$ARG
+done
+
+# Cambiamos el orden
+efibootmgr -o ${ORDER#,} &>/dev/null
+}
+
+
+#/**
+# ogSetNvramTimeout
+#@brief Configura el tiempo de espera de la NVRAM
+#@param Orden de las entradas separadas por espacios
+#@return (nada)
+
+#@exception OG_ERR_FORMAT formato incorrecto.
+#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
+#*/ ##
+function ogSetNvramTimeout (){
+# Si se solicita, mostrar ayuda.
+if [ "$*" == "help" ]; then
+ ogHelp "$FUNCNAME" "$FUNCNAME int_Timeout (seg)" \
+ "$FUNCNAME 2"
+ return
+fi
+#
+# Si no es equipo UEFI salir con error
+ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
+
+# Error si no se recibe 1 parámetro.
+[ $# -eq 1 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_Timeout (seg)" || return $?
+
+# Comprobamos que sea un número
+[[ "$1" =~ ^([0-9 ]+)*$ ]] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_Timeout (seg)" || return $?
+
+# Cambiamos el orden
+efibootmgr -t $1 &>/dev/null
+}
+
+
+#/**
+# ogUuidChange int_ndisk str_repo
+#@brief Reemplaza el UUID de un sistema de ficheros.
+#@param int_ndisk nº de orden del disco
+#@param int_part nº de partición
+#@return (nada, por determinar)
+#@exception OG_ERR_FORMAT formato incorrecto.
+#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
+#*/ ##
+function ogUuidChange () {
+local MNTDIR DEVICE UUID NEWUUID f
+
+# Si se solicita, mostrar ayuda.
+if [ "$*" == "help" ]; then
+ ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part" \
+ "$FUNCNAME 1 2"
+ return
+fi
+
+# Error si no se reciben al menos 2 parámetros.
+[ $# -eq 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part" || return $?
+
+# Comprobamos que exista la partición
+MNTDIR=$(ogMount $1 $2) || ogRaiseError $OG_ERR_NOTFOUND "Device $1 $2" || return $?
+DEVICE=$(ogDiskToDev $1 $2)
+UUID=$(blkid -o value -s UUID $DEVICE)
+NEWUUID=$(cat /proc/sys/kernel/random/uuid)
+
+# Cambiamos UUID a la partición
+ogUnmount $1 $2
+tune2fs $DEVICE -U $NEWUUID
+
+# Cambiamos UUID en la configuración (fstab y grub)
+ogMount $1 $2
+for f in $MNTDIR/etc/fstab $MNTDIR/{,boot/}{{grubMBR,grubPARTITION}/boot/,}{grub{,2},{,efi/}EFI/*}/{menu.lst,grub.cfg}; do
+ [ -r $f ] && sed -i s/$UUID/$NEWUUID/g $f
+done
+}