3 # Copyright (c) 2003 Intel Corporation
6 # Copyright (c) 2004-2006 The Trustees of Princeton University
8 # expected /proc/partitions format
15 from Exceptions import *
17 import notify_messages
23 Make sure the hardware we are running on is sufficient for
24 the PlanetLab OS to be installed on. In the process, identify
25 the list of block devices that may be used for a node installation,
26 and identify the cdrom device that we booted off of.
28 Return 1 if requiremenst met, 0 if requirements not met. Raise
29 BootManagerException if any problems occur that prevent the requirements
32 Expect the following variables from the store:
34 MINIMUM_MEMORY minimum amount of memory in kb required
36 NODE_ID the node_id from the database for this node
37 MINIMUM_DISK_SIZE any disks smaller than this size, in GB, are not used
38 TOTAL_MINIMUM_DISK_SIZE total disk size in GB, if all usable disks
39 meet this number, there isn't enough disk space for
40 this node to be usable after install
41 SKIP_HARDWARE_REQUIREMENT_CHECK
42 If set, don't check if minimum requirements are met
43 BOOT_CD_VERSION A tuple of the current bootcd version
44 Sets the following variables:
45 INSTALL_BLOCK_DEVICES list of block devices to install onto
48 log.write( "\n\nStep: Checking if hardware requirements met.\n" )
51 MINIMUM_MEMORY= int(vars["MINIMUM_MEMORY"])
52 if MINIMUM_MEMORY == "":
53 raise ValueError, "MINIMUM_MEMORY"
55 NODE_ID= vars["NODE_ID"]
57 raise ValueError("NODE_ID")
59 MINIMUM_DISK_SIZE= int(vars["MINIMUM_DISK_SIZE"])
61 TOTAL_MINIMUM_DISK_SIZE= \
62 int(vars["TOTAL_MINIMUM_DISK_SIZE"])
64 SKIP_HARDWARE_REQUIREMENT_CHECK= \
65 int(vars["SKIP_HARDWARE_REQUIREMENT_CHECK"])
67 BOOT_CD_VERSION= vars["BOOT_CD_VERSION"]
68 if BOOT_CD_VERSION == "":
69 raise ValueError, "BOOT_CD_VERSION"
72 raise BootManagerException, \
73 "Missing variable in install store: %s" % var
74 except ValueError, var:
75 raise BootManagerException, \
76 "Variable in install store blank, shouldn't be: %s" % var
78 # lets see if we have enough memory to run
79 log.write( "Checking for available memory.\n" )
81 total_mem= systeminfo.get_total_phsyical_mem(vars, log)
83 raise BootManagerException, "Unable to read total physical memory"
85 if total_mem < MINIMUM_MEMORY:
86 if not SKIP_HARDWARE_REQUIREMENT_CHECK:
87 log.write( "Insufficient memory to run node: %s kb\n" % total_mem )
88 log.write( "Required memory: %s kb\n" % MINIMUM_MEMORY )
94 #sent= BootAPI.call_api_function( vars, "BootNotifyOwners",
95 # (notify_messages.MSG_INSUFFICIENT_MEMORY,
99 params = {"hostname" : vars['hostname'] + vars['domainname']}
100 person_ids = BootAPI.call_api_function( vars, "GetSites",
101 (vars['SITE_ID'], ['person_ids']))[0]
102 persons = BootAPI.call_api_function( vars, "GetPersons",
103 (person_ids, ['person_id', 'roles']))
104 for person in persons:
105 if "tech" in person['roles']: techs.append(person['person_id'])
106 msg = BootAPI.call_api_function( vars, "GetMessages",
107 ({"message_id": notify_messages.MSG_INSUFFICIENT_MEMORY}),)[0]
108 sent= BootAPI.call_api_function( vars, "NotifyPersons",
109 (techs, msg['subject'] % params, msg['body'] % params))
111 except BootManagerException, e:
112 log.write( "Call to NotifyPersons failed: %s.\n" % e )
115 log.write( "Unable to notify site contacts of problem.\n" )
117 log.write( "Notified contacts of problem.\n" )
121 log.write( "Memory requirements not met, but running anyway: %s kb\n"
124 log.write( "Looks like we have enough memory: %s kb\n" % total_mem )
128 # get a list of block devices to attempt to install on
129 # (may include cdrom devices)
130 install_devices= systeminfo.get_block_device_list(vars, log)
132 # save the list of block devices in the log
133 log.write( "Detected block devices:\n" )
134 log.write( repr(install_devices) + "\n" )
136 if not install_devices or len(install_devices) == 0:
137 log.write( "No block devices detected.\n" )
145 sent= BootAPI.call_api_function( vars, "BootNotifyOwners",
146 (notify_messages.MSG_INSUFFICIENT_DISK,
150 except BootManagerException, e:
151 log.write( "Call to BootNotifyOwners failed: %s.\n" % e )
154 log.write( "Unable to notify site contacts of problem.\n" )
158 # now, lets remove any block devices we know won't work (readonly,cdroms),
159 # or could be other writable removable disks (usb keychains, zip disks, etc)
160 # i'm not aware of anything that helps with the latter test, so,
161 # what we'll probably do is simply not use any block device below
162 # some size threshold (set in installstore)
164 # also, keep track of the total size for all devices that appear usable
167 for device in install_devices.keys():
169 (major,minor,blocks,gb_size,readonly)= install_devices[device]
171 # if the device string starts with
172 # planetlab or dm- (device mapper), ignore it (could be old lvm setup)
173 if device[:14] == "/dev/planetlab" or device[:8] == "/dev/dm-":
174 del install_devices[device]
177 if gb_size < MINIMUM_DISK_SIZE:
178 log.write( "Device is too small to use: %s \n(appears" \
179 " to be %4.2f GB)\n" % (device,gb_size) )
181 del install_devices[device]
187 log.write( "Device is readonly, not using: %s\n" % device )
189 del install_devices[device]
194 # add this sector count to the total count of usable
195 # sectors we've found.
196 total_size= total_size + gb_size
199 if len(install_devices) == 0:
200 log.write( "No suitable block devices found for install.\n" )
208 sent= BootAPI.call_api_function( vars, "BootNotifyOwners",
209 (notify_messages.MSG_INSUFFICIENT_DISK,
213 except BootManagerException, e:
214 log.write( "Call to BootNotifyOwners failed: %s.\n" % e )
217 log.write( "Unable to notify site contacts of problem.\n" )
222 # show the devices we found that are usable
223 log.write( "Usable block devices:\n" )
224 log.write( repr(install_devices.keys()) + "\n" )
226 # save the list of devices for the following steps
227 vars["INSTALL_BLOCK_DEVICES"]= install_devices.keys()
230 # ensure the total disk size is large enough. if
231 # not, we need to email the tech contacts the problem, and
232 # put the node into debug mode.
233 if total_size < TOTAL_MINIMUM_DISK_SIZE:
234 if not SKIP_HARDWARE_REQUIREMENT_CHECK:
235 log.write( "The total usable disk size of all disks is " \
236 "insufficient to be usable as a PlanetLab node.\n" )
243 sent= BootAPI.call_api_function( vars, "BootNotifyOwners",
244 (notify_messages.MSG_INSUFFICIENT_DISK,
248 except BootManagerException, e:
249 log.write( "Call to BootNotifyOwners failed: %s.\n" % e )
252 log.write( "Unable to notify site contacts of problem.\n" )
257 log.write( "The total usable disk size of all disks is " \
258 "insufficient, but running anyway.\n" )
260 log.write( "Total size for all usable block devices: %4.2f GB\n" % total_size )
262 # turn off UDMA for all block devices on 2.x cds (2.4 kernel)
263 if BOOT_CD_VERSION[0] == 2:
264 for device in install_devices:
265 log.write( "Disabling UDMA on %s\n" % device )
266 utils.sysexec_noerr( "/sbin/hdparm -d0 %s" % device, log )