backend.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. import os
  2. import subprocess
  3. from pardus.fileutils import FileLock
  4. # Config
  5. DIRECTORY_BLACKLIST = "/etc/modprobe.d"
  6. MODULES_DIR = "/lib/modules"
  7. MODULES_CONF = "/etc/modprobe.conf"
  8. MODULES_CONF_DIR = "/etc/modules.d"
  9. MODULES_AUTOLOAD = "/etc/modules.autoload.d/kernel-%s"
  10. MODULES_BLACKLIST = "/etc/modprobe.d/blacklist-compat"
  11. MODULES_COMAR_BLACKLIST = "/etc/modprobe.d/blacklist-comar"
  12. TIMEOUT = 5.0
  13. # l10n
  14. FAIL_TIMEOUT = _({
  15. "en": "Request timed out. Try again later.",
  16. "tr": "Talep zaman aşımına uğradı. Daha sonra tekrar deneyin.",
  17. })
  18. FAIL_VERSION = _({
  19. "en": "Invalid kernel version.",
  20. "tr": "Geçersiz çekirdek sürümü.",
  21. })
  22. FAIL_PROBE = _({
  23. "en": "Unable to load module %s: %s",
  24. "tr": "%s modülü yüklenemedi: %s",
  25. })
  26. FAIL_RMMOD = _({
  27. "en": "Unable to unload module %s: %s",
  28. "tr": "%s modülü kaldırılamadı: %s",
  29. })
  30. FAIL_UPDATE = _({
  31. "en": "Unable to update modprobe.conf: %s",
  32. "tr": "modprobe.conf güncellenemedi: %s",
  33. })
  34. # Utils
  35. def majorVersion(kernel_version):
  36. """Parses kernel version and returns major revision."""
  37. version = kernel_version.split(".")
  38. if len(version) < 2:
  39. fail(FAIL_VERSION)
  40. return ".".join(version[0:2])
  41. class Lock:
  42. def __init__(self, _file, shared=False):
  43. lockfile = os.path.join(os.path.dirname(_file), ".%s" % os.path.basename(_file))
  44. try:
  45. self.lock = FileLock(_file)
  46. self.lock.lock(timeout=TIMEOUT, shared=shared)
  47. except IOError:
  48. fail(FAIL_TIMEOUT)
  49. def release(self):
  50. self.lock.unlock()
  51. def listConfig(_file, prefix=None):
  52. """Parses given module configuration file and returns modules as a list."""
  53. lock = Lock(_file, shared=True)
  54. lines = []
  55. for line in file(_file):
  56. line = line.strip()
  57. if line and not line.startswith("#"):
  58. lines.append(line)
  59. lock.release()
  60. lines = [x.split("#")[0].strip() for x in lines]
  61. if prefix:
  62. lines = [x.replace(prefix, "") for x in lines if x.startswith(prefix)]
  63. return lines
  64. def editConfig(_file, add=[], remove=[], prefix=None):
  65. """Edits given module list file."""
  66. lock = Lock(_file, shared=False)
  67. newlines = []
  68. if os.path.exists(_file):
  69. for line in file(_file):
  70. module = line.strip()
  71. if prefix and prefix in module:
  72. module = module.split(prefix)[1]
  73. if module in remove:
  74. continue
  75. if module in add:
  76. newlines.append("Added through COMAR")
  77. newlines.append(module)
  78. add.remove(module)
  79. else:
  80. newlines.append(module)
  81. newlines.extend(add)
  82. if prefix:
  83. newlines = ["#Added through COMAR\n%s %s\n" % (prefix, x) for x in newlines if not x.startswith("#")]
  84. file(_file, "w").write("\n".join(newlines))
  85. lock.release()
  86. # Boot.Modules methods
  87. def listAvailable():
  88. """Returns a list of available modules on the system."""
  89. modules = []
  90. kernel_version = os.uname()[2]
  91. path = os.path.join(MODULES_DIR, kernel_version)
  92. if os.path.exists(path):
  93. for root, dirs, files in os.walk(path):
  94. for _file in files:
  95. if _file.endswith(".ko"):
  96. modname = _file[:-3]
  97. modules.append(modname)
  98. return modules
  99. def listLoaded():
  100. """Returns loaded modules and their options."""
  101. # Get loaded modules
  102. modules = {}
  103. for module in file("/proc/modules"):
  104. modname = module.split()[0]
  105. modules[modname] = ""
  106. # Get options from modprobe.conf
  107. lock = Lock(MODULES_CONF, shared=True)
  108. for line in file(MODULES_CONF):
  109. line = line.strip()
  110. if line.startswith("options"):
  111. try:
  112. command, modname, arguments = line.split(" ", 2)
  113. except ValueError:
  114. continue
  115. if modname in modules:
  116. modules[modname] = arguments
  117. lock.release()
  118. # Build (module: options) list
  119. list_modules = {}
  120. for module, options in modules.iteritems():
  121. list_modules[module] = options
  122. return list_modules
  123. def setOptions(module, options=""):
  124. """Sets module options."""
  125. # Lock modprobe.conf
  126. lock = Lock(MODULES_CONF, shared=False)
  127. module_found = False
  128. # Search for module's config file
  129. for _file in os.listdir(MODULES_CONF_DIR):
  130. _file = os.path.join(MODULES_CONF_DIR, _file)
  131. newlines = []
  132. for line in file(_file):
  133. line = line.strip()
  134. if line.startswith("options %s " % module):
  135. if options:
  136. newlines.append("options %s %s" % (module, options))
  137. module_found = True
  138. else:
  139. newlines.append(line)
  140. # Update config file
  141. if module_found:
  142. file(_file, "w").write("\n".join(newlines))
  143. break
  144. # Append module config to "/etc/modules.d/other"
  145. if not module_found:
  146. config_file = os.path.join(MODULES_CONF_DIR, "other")
  147. file(config_file, "a").write("options %s %s" % (module, options))
  148. # Release lock on modprobe.conf
  149. lock.release()
  150. # Update modprobe.conf
  151. updateModules()
  152. def load(module, options=""):
  153. """Loads given module with options."""
  154. cmd = ["/sbin/modprobe", module]
  155. if options:
  156. cmd.extend(options.split())
  157. pipe = subprocess.Popen(cmd, stderr=subprocess.PIPE)
  158. if pipe.wait() != 0:
  159. fail(FAIL_PROBE % (module, pipe.stderr.read()))
  160. def unload(module):
  161. """Unloads given module name."""
  162. cmd = ["/sbin/rmmod", module]
  163. pipe = subprocess.Popen(cmd, stderr=subprocess.PIPE)
  164. if pipe.wait() != 0:
  165. fail(FAIL_RMMOD % (module, pipe.stderr.read()))
  166. def listAutoload(kernel_version):
  167. """Lists specified kernel's autoload list."""
  168. major_release = majorVersion(kernel_version)
  169. modules_autoload = MODULES_AUTOLOAD % major_release
  170. modules = []
  171. if os.path.exists(modules_autoload):
  172. modules = listConfig(modules_autoload)
  173. else:
  174. fail(FAIL_VERSION)
  175. return modules
  176. def addAutoload(module, kernel_version):
  177. """Adds module to specified kernel's autoload list."""
  178. major_release = majorVersion(kernel_version)
  179. modules_autoload = MODULES_AUTOLOAD % major_release
  180. editConfig(modules_autoload, add=[module])
  181. def removeAutoload(module, kernel_version):
  182. """Removes module from specified kernel's autoload list."""
  183. major_release = majorVersion(kernel_version)
  184. modules_autoload = MODULES_AUTOLOAD % major_release
  185. if os.path.exists(modules_autoload):
  186. editConfig(modules_autoload, remove=[module])
  187. else:
  188. fail(FAIL_VERSION)
  189. def listBlacklist():
  190. """Lists blacklisted modules."""
  191. modules = []
  192. if os.path.exists(DIRECTORY_BLACKLIST):
  193. for f in os.listdir(DIRECTORY_BLACKLIST):
  194. modules.extend(listConfig(os.path.join(DIRECTORY_BLACKLIST, f), "blacklist "))
  195. # Make the list unique as there may be some .newconfig in the directory
  196. return list(set(modules))
  197. def addBlacklist(module):
  198. """Adds a module to blacklist."""
  199. editConfig(MODULES_BLACKLIST, add=[module], prefix="blacklist ")
  200. def removeBlacklist(module):
  201. """Removes module from blacklist."""
  202. editConfig(MODULES_BLACKLIST, remove=[module], prefix="blacklist ")
  203. def updateModules(kernel_version=None):
  204. """Updates modprobe.conf"""
  205. # Lock modprobe.conf
  206. lock = Lock(MODULES_CONF, shared=False)
  207. # Run update-modules
  208. pipe = subprocess.Popen(["/sbin/update-modules"], stderr=subprocess.PIPE)
  209. reply = pipe.wait()
  210. # Release lock on modprobe.conf
  211. lock.release()
  212. # Return error message on failure
  213. if reply != 0:
  214. fail(FAIL_UPDATE % pipe.stderr.read())
  215. # Run depmod if necessary
  216. if kernel_version:
  217. subprocess.call(["/sbin/depmod", "-a", kernel_version])