scripts/gestion/iscsi/udev_update_symlinks.py
Pierre-Elliott Bécue c37b3b0f34 [iscsi] Kludges sales pour virer les liens morts supplémentaires.
Si seulement udev se débarassait des modules physiques qui n'existent plus...
2013-04-25 00:09:48 +02:00

114 lines
4.1 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Auteur : Pierre-Elliott Bécue <becue@crans.org>
# Inspiré du travail de Jérémie Dimino <jeremie@dimino.org>
# Licence : BSD3
import sys
import os
sys.path.append('/usr/scripts/gestion/iscsi')
sys.path.append('/usr/scripts/gestion')
from affich_tools import coul
import udev_get_iscsi_name as ugin
import subprocess
PATH = "/dev/disk/by-path/"
def store_iscsi_volumes():
"""Extrait la liste des volumes
de /dev/disk/by-path/ip-*"""
links = {}
# os.listdir retourne une liste désordonnée, l'idée est de privilégier
# l'ordre lexicographique pour que l'état du retour soit identifié.
state = subprocess.Popen(['ls', PATH], stdout=subprocess.PIPE)
state = state.stdout.readlines()
for line in state:
line = line.replace('\n', '')
if line.startswith('ip-'):
device = os.readlink(PATH+line) # de la forme ../../sdb42
device = device.rsplit('/', 1)[1]
if line.rsplit('-', 1)[1][0:4] == "part":
symlink = 'iscsi_' + ugin.getname("".join([i for i in device if i.isalpha()])) + "_part" + line.rsplit('-', 1)[1][4:]
else:
symlink = 'iscsi_' + ugin.getname(device)
line = line.rsplit('-', 1)[1]
_ = links.setdefault(line, [symlink, device])
return links
def make_link(couple):
"""Crée le symlink /dev/iscsi_nom -> /dev/sdb42"""
os.chdir("/dev/")
sym, dev = couple
diskstatus = subprocess.Popen(['file', '-sb', '/dev/' + dev], stdout=subprocess.PIPE)
diskstatus = diskstatus.stdout.readlines()[0]
if not (os.path.islink(sym)) and not 'empty' in diskstatus and not 'ERROR' in diskstatus:
sys.stdout.write("Création du lien /dev/" + sym + " -> /dev/" + dev + "")
try:
os.symlink(dev, sym)
sys.stdout.write(coul("OK", 'vert'))
res = True
except:
sys.stdout.write(coul("ECHEC", 'rouge'))
res = False
sys.stdout.write('\n')
elif os.path.islink(sym) and ('empty' in diskstatus or 'ERROR' in diskstatus):
sys.stdout.write("Destruction du lien /dev/" + sym + "")
try:
os.remove(sym)
sys.stdout.write(coul("OK", 'vert'))
res = True
except:
sys.stdout.write(coul("ECHEC", 'rouge'))
res = False
sys.stdout.write('\n')
elif os.path.islink(sym) and os.readlink(sym) != dev:
sys.stdout.write("Mise à jour du lien /dev/" + sym + " -> /dev/" + dev + "")
try:
os.remove(sym)
os.symlink(dev, sym)
sys.stdout.write(coul("OK", 'vert'))
res = True
except:
sys.stdout.write(coul("ECHEC", 'rouge'))
res = False
sys.stdout.write('\n')
else:
res = None
return res
def clean_iscsi_links():
"""Nettoie les liens présents dans /dev/iscsi_*"""
links = {}
# os.listdir retourne une liste désordonnée, l'idée est de privilégier
# l'ordre lexicographique pour que l'état du retour soit identifié.
state = subprocess.Popen(['ls', '/dev'], stdout=subprocess.PIPE)
state = state.stdout.readlines()
for line in state:
line = line.replace('\n', '')
if line.startswith('iscsi_'):
device = os.readlink('/dev/'+line) # de la forme ../../sdb42
symlink = line
make_link((symlink, device))
return links
if __name__ == '__main__':
if "-h" in sys.argv or "--help" in sys.argv:
print "Usage: udev_update_symlinks.py <options>"
print " -h, --help : print this message and exit"
print " --clean : clean empty links no longer referenced"
if "--clean" in sys.argv:
clean_iscsi_links()
nothing = True
links = store_iscsi_volumes()
for path in links.keys():
cmd = make_link(links[path])
if cmd != None:
nothing = False
if nothing:
sys.stdout.write("Terminé, pas de changement pour les liens.\n")
else:
sys.stdout.write("Terminé.\n")