Merge branch 'master' of ssh://git.onelab.eu/git/nodemanager
[nodemanager.git] / plugins / rawdisk.py
1 #!/usr/bin/python -tt
2 # vim:set ts=4 sw=4 expandtab:
3 #
4 # $Id$
5 # $URL$
6 #
7 # NodeManager plugin to support mapping unused raw disks into a slice
8 # that has the rawdisk sliver tag
9
10 """
11 Raw disk support for NodeManager.
12
13 Copies all unused devices into slices with the rawdisk attribute set.
14 """
15
16 import errno
17 import os
18 import time
19 import re
20
21 import logger
22 import tools
23
24 def start():
25     logger.log("rawdisk: plugin starting up...")
26
27 def get_unused_devices():
28     devices = []
29     if os.path.exists("/dev/mapper/planetlab-rawdisk"):
30         devices.append("/dev/mapper/planetlab-rawdisk")
31     # Figure out which partitions are part of the VG
32     in_vg = []
33     for i in os.listdir("/sys/block"):
34         if not i.startswith("dm-"):
35             continue
36         in_vg.extend(map(lambda x: x.replace("!", "/"),
37                          os.listdir("/sys/block/%s/slaves" % i)))
38     # Read the list of partitions
39     partitions = file("/proc/partitions", "r")
40     pat = re.compile("\s+")
41     while True:
42         buf = partitions.readline()
43         if buf == "":
44             break
45         buf = buf.strip()
46         fields = re.split(pat, buf)
47         dev = fields[-1]
48         if (not dev.startswith("dm-") and dev not in in_vg and
49             os.path.exists("/dev/%s" % dev) and
50             (os.minor(os.stat("/dev/%s" % dev).st_rdev) % 2) != 0):
51             devices.append("/dev/%s" % dev)
52     partitions.close()
53     return devices
54
55 def GetSlivers(data, config=None, plc=None):
56     if 'slivers' not in data:
57         logger.log_missing_data("rawdisk.GetSlivers",'slivers')
58         return
59
60     devices = get_unused_devices()
61     for sliver in data['slivers']:
62         for attribute in sliver['attributes']:
63             name = attribute.get('tagname',attribute.get('name',''))
64             if name == 'rawdisk':
65                 for i in devices:
66                     st = os.stat(i)
67                     path = "/vservers/%s%s" % (sliver['name'], i)
68                     if os.path.exists(path):
69                         # should check whether its the proper type of device
70                         continue
71
72                     logger.log("rawdisk: Copying %s to %s" % (i, path))
73                     try:
74                         if os.path.exists(path):
75                             os.unlink(path)
76                     except:
77                         pass
78                     try:
79                         os.makedirs(os.path.dirname(path), 0755)
80                     except:
81                         pass
82                     os.mknod(path, st.st_mode, st.st_rdev)