Introduction
ACFS (ASM Cluster File System) est arrivé avec le Grid Infrastructure (GI) 11.2.
On peut le résumer en le décrivant comme le successeur d’OCFS2 (Oracle Cluster File System 2) et DBFS (DataBase File System), et intégrant des fonctionnalités habituellement disponibles sur NFS (Network File System) telle la gestion de Snapshot.
Comme son nom l’indique, ACFS n’est logiquement disponible qu’en mode Cluster, mais les modules ACFS et ADVM (ASM Dynamic Volume Manager) sont bel et bien présents en mode Restart (GI non-Cluster).
Il est donc tout à fait possible d’exploiter ACFS dans des environnements non Cluster, mais l’intégration n’y est pas faite dans l’outillage Restart : pas de crsctl/srvctl pour le contrôler, pas de chargement automatique des modules kernel, donc impossibilité d’utiliser « fstab » pour monter les volumes ACFS au démarrage de l’OS.
Le but de cet article n’est pas de proposer une solution à un manque de fonctionnalité de Restart, vu que clairement un Cluster File System est fait pour fonctionner dans un Cluster.
D’ailleurs la méthode la plus simple pour en disposer sur un serveur Standalone est de faire une installation de type Cluster, mais mono-nœud.
Donc le but de cet article est en fait détourné : se familiariser avec la gestion des ressources par le GI et sa déclinaison « Restart ».
Nous allons créer 3 ressources qui seront gérées par Restart à la mode Cluster :
- Ressource de contrôle des modules ADVM/ACFS
- Ressource de contrôle des volumes ASM
- Ressource de contrôle des points de montage ACFS
Puis nous créerons un volume ACFS qui sera géré par nos ressources.
1. Autoriser le user « oracle » à charger les modules ADVM/ACFS et à monter un volume
En root :
cat <<EOF >> /etc/sudoers %oinstall ALL = (ALL) NOPASSWD: ${ORACLE_HOME}/bin/acfsload, /bin/mount EOF
2. Création du script de contrôle des modules ADVM/ACFS et de sa ressource
En root :
cat <<EOF > /usr/local/bin/cust_drivers_acfs.sh #!/bin/bash #set -x RC=1 DIR=\$(dirname \${0}) FILE=\$(basename \${0}) case \${1} in "start") sudo \${ORACLE_HOME}/bin/acfsload start -s RC=\${?} ;; "stop") RC=0 let cnt=0 while [ \${RC} -eq 0 ] && [ \${cnt} -le 10 ] ; do let cnt=cnt+1 sudo \${ORACLE_HOME}/bin/acfsload stop -s sleep 5 \${0} check done RC=0 ;; "clean"|"abort") RC=0 ;; "check") ls -a /dev/asm/|grep ".asm" > /dev/null RC=\${?} ;; *) echo "Usage : \$FILE {start|stop|check|clean|abort}" RC=1 ;; esac exit \${RC} EOF chmod +x /usr/local/bin/cust_drivers_acfs.sh crsctl add res cust.drivers.acfs -type local_resource -attr "ACTION_SCRIPT=/usr/local/bin/cust_drivers_acfs.sh,ACTION_TIMEOUT=60,CHECK_INTERVAL=60,ACL='owner:oracle:rwx,pgrp:root:r-x,other::r--'"
- Ce script est un CallOut qui sera fourni à Restart pour contrôler le chargement / déchargement des modules ADVM/ACFS
- Restart l’exécutera avec pour seul argument l’action à réaliser, à savoir :
- start : chargement des modules
- stop : déchargement des modules
- clean : inutilisé ici, mais sert normalement à rendre un système propre en cas d’échec (Ex. : suppression de fichiers de type « pid »)
- abort : inutilisé ici, mais sert normalement à interrompre une action en court de « start »
- check : retourne l’état de la ressource, ici 0 si les modules sont bien chargés, sinon 1
- Création de la ressource « cust.volumes.acfs » associée au script CallOut, avec les attributs suivants :
- Arrêt de l’exécution du script après 60 secondes sans réponse
- Exécution du « check » toutes les 60 secondes
- Compte d’exécution du script : « oracle », Groupe ayant les droits d’exécution : « root », les autres ne les ayant pas
3. Création du script de contrôle des volumes ASM
En root :
cat <<EOF > /usr/local/bin/cust_volumes_acfs.sh #!/bin/bash #set -x RC=1 export ORACLE_SID=\$(ps -eo cmd|grep -v grep|grep pmon|awk -F'_' '{print \$3}') DIR=\$(dirname \${0}) FILE=\$(basename \${0}) case \${1} in "start") \${ORACLE_HOME}/bin/asmcmd volenable –all RC=\${?} ;; "stop") \${ORACLE_HOME}/bin/asmcmd voldisable –all RC=0 ;; "clean"|"abort") RC=0 ;; "check") nb=\$(ls /dev/asm|wc -w) if [ \$nb -eq 0 ] ; then RC=1 else RC=0 fi ;; *) echo "Usage : \$FILE {start|stop|check|clean|abort}" RC=1 ;; esac exit \${RC} EOF chmod +x /usr/local/bin/cust_volumes_acfs.sh crsctl add res cust.volumes.acfs -type local_resource -attr "ACTION_SCRIPT=/usr/local/bin/cust_volumes_acfs.sh,ACTION_TIMEOUT=60,CHECK_INTERVAL=60,START_DEPENDENCIES='pullup:always(ora.asm,cust.drivers.acfs) hard(ora.asm,cust.drivers.acfs)',STOP_DEPENDENCIES='hard(intermediate:ora.asm,intermediate:cust.drivers.acfs)',ACL='owner:oracle:rwx,pgrp:asmdba:r-x,other::r--'"
- Ce script est un CallOut qui sera fourni à Restart pour contrôler l’activation / désactivation des volumes ASM
- Restart l’exécutera avec pour seul argument l’action à réaliser, à savoir :
- start : activation de tous les volumes ASM
- stop : désactivation de tous les volumes ASM
- clean : inutilisé ici, mais sert normalement à rendre un système propre en cas d’échec (Ex. : suppression de fichiers de type « pid »)
- abort : inutilisé ici, mais sert normalement à interrompre une action en court de « start »
- check : retourne l’état de la ressource, ici 0 si au moins un volume est actif, sinon 1
- Création de la ressource « cust.volumes.acfs » associé au script CallOut, avec les attributs suivants :
- Arrêt de l’exécution du script après 60 secondes sans réponse
- Exécution du « check » toutes les 60 secondes
- Ne peut démarrer qu’après les ressources « ora.asm » (l’instance ASM) et « cust.drivers.acfs » (le chargement des modules ADVM/ACFS), et lance leur démarrage le cas échéant
- Ne peut s’arrêter qu’après les ressources « ora.asm » et « cust.drivers.acfs »
- Compte d’exécution du script : « oracle », Groupe ayant les droits d’exécution : «asmdba», les autres ne les ayant pas
4. Création du script de contrôle des volumes ASM
En root :
cat <<EOF > /usr/local/bin/cust_mount_acfs.sh #!/bin/bash #set -x RC=1 export ORACLE_SID=\$(ps -eo cmd|grep -v grep|grep pmon|awk -F'_' '{print \$3}') DIR=\$(dirname \${0}) FILE=\$(basename \${0}) case \${1} in "start") \${ORACLE_HOME}/bin/asmcmd volinfo --all | egrep "Mountpath|Volume Device" | while read line ; do val=\$(echo \$line | awk -F': ' '{print \$2}') if [ "\$device" == "" ] ; then device=\$val else path=\$val if [ "\$path" != "" ] ; then /bin/mount -t acfs \$device \$path fi device="" fi done RC=\${?} ;; "stop") \${ORACLE_HOME}/bin/asmcmd volinfo --all | egrep "Mountpath|Volume Device" | while read line ; do val=\$(echo \$line | awk -F': ' '{print \$2}') if [ "\$device" == "" ] ; then device=\$val else path=\$val if [ "\$path" != "" ] ; then /bin/umount -f \$path fi device="" fi done RC=\${?} ;; "clean"|"abort") RC=0 ;; "check") mount | grep acfs ;; *) echo "Usage : \$FILE {start|stop|check|clean|abort}" RC=1 ;; esac exit \${RC} EOF chmod +x /usr/local/bin/cust_mount_acfs.sh crsctl add res cust.mount.acfs -type local_resource -attr "ACTION_SCRIPT=/usr/local/bin/cust_mount_acfs.sh,ACTION_TIMEOUT=60,CHECK_INTERVAL=60,START_DEPENDENCIES='pullup:always(cust.volumes.acfs) hard(cust.volumes.acfs)',STOP_DEPENDENCIES='hard(intermediate:intermediate:cust.volumes.acfs)',ACL='owner:oracle:rwx,pgrp:asmdba:r-x,other::r--'"
- Ce script est un CallOut qui sera fourni à Restart pour contrôler le montage / démontage des ACFS
- Restart l’exécutera avec pour seul argument l’action à réaliser, à savoir :
- start : montage de tous les ACFS
- stop : démontage de tous les ACFS
- clean : inutilisé ici, mais sert normalement à rendre un système propre en cas d’échec (Ex. : suppression de fichiers de type « pid »)
- abort : inutilisé ici, mais sert normalement à interrompre une action en court de « start »
- check : retourne l’état de la ressource, ici 0 si au moins un ACFS est monté, sinon 1
- Création de la ressource « cust.mount.acfs » associé au script CallOut, avec les attributs suivants :
- Arrêt de l’exécution du script après 60 secondes sans réponse
- Exécution du « check » toutes les 60 secondes
- Ne peut démarrer qu’après la ressource « cust.volumes.acfs » (l’activation des volumes ASM), et lance son démarrage le cas échéant
- Ne peut s’arrêter qu’après la ressource « cust.volumes.acfs »
- Compte d’exécution du script : « oracle », Groupe ayant les droits d’exécution : «asmdba», les autres ne les ayant pas
5. Création d’un volume ASM
En oracle :
crsctl start res cust.drivers.acfs asmcmd volcreate -G DATA -s 1G v_test1 asmcmd volinfo -G DATA v_test1 Diskgroup Name: DATA Volume NAME: V_TEST1 … Mountpath:
En root :
mkfs -t acfs /dev/asm/v_test1* mkdir /media/test1 mount /dev/asm/v_test* /media/test1 umount /media/test1 asmcmd volinfo -G DATA v_test1 Diskgroup Name: DATA Volume NAME: V_TEST1 … Mountpath: /media/test1
En root ou oracle :
crsctl start res cust.mount.acfs
- On commence par charger les modules ADVM/ACFS, étape obligatoire pour pouvoir créer un volume ASM
- On crée un volume ASM de 1Go, nommé « V_TEST1 ». Comme il vient d’être créé, « volinfo » ne rapporte aucun point de montage associé
- On formate au format ACFS le volume qui apparaît dans « /dev/asm ». A noter que depuis la version 12c du GI/Restart, il est possible de formater un volume ASM dans un format non-Cluster (EXT4…)
- On crée le répertoire de point de montage, on monte puis démonte le volume « V-TEST1 » et on voit que sont attribut de point de montage indique le répertoire utilisé
- Dorénavant, les volumes au format ACFS seront bien controlés par Restart et démarreront bien automatiquement au boot du serveur, ou au redémarrage de Restart
Conclusion
Je vous ai proposé un petit aperçu de ce qu’il est possible de faire avec le GI dans un exemple certes pas très utile, mais concret.
Vous voyez bien que ça n’est qu’une ébauche de ce qu’il faudrait faire, notamment parce que la gestion des volumes ASM/ACFS y est globale, et non pas faite volume par volume (création d’une ressource par volume ASM et par point de montage ACFS). Pour se faire, il faudrait ajouter des attributs non standards à ces ressources, voire créer de nouveaux types de ressources, mais ça n’est pas l’objet de cet article.
Enjoy Oracle