3 # Copyright (c) 2003 Intel Corporation
6 # Copyright (c) 2004-2006 The Trustees of Princeton University
11 import InstallPartitionDisks
12 from Exceptions import *
22 Find any new large block devices we can add to the vservers volume group
24 Expect the following variables to be set:
25 SYSIMG_PATH the path where the system image will be mounted
26 MINIMUM_DISK_SIZE any disks smaller than this size, in GB, are not used
27 NODE_MODEL_OPTIONS the node's model options
29 Set the following variables upon successfully running:
30 ROOT_MOUNTED the node root file system is mounted
33 log.write("\n\nStep: Checking for unused disks to add to LVM.\n")
35 # make sure we have the variables we need
37 SYSIMG_PATH = vars["SYSIMG_PATH"]
39 raise ValueError("SYSIMG_PATH")
41 MINIMUM_DISK_SIZE = int(vars["MINIMUM_DISK_SIZE"])
43 PARTITIONS = vars["PARTITIONS"]
44 if PARTITIONS == None:
45 raise ValueError("PARTITIONS")
47 NODE_MODEL_OPTIONS = vars["NODE_MODEL_OPTIONS"]
48 except KeyError as var:
49 raise BootManagerException("Missing variable in vars: {}\n".format(var))
50 except ValueError as var:
51 raise BootManagerException("Variable in vars, shouldn't be: {}\n".format(var))
53 devices_dict = systeminfo.get_block_devices_dict(vars, log)
55 # will contain the new devices to add to the volume group
58 # total amount of new space in gb
61 utils.display_disks_status(PARTITIONS, "In CheckForNewDisks", log)
63 for device, details in devices_dict.items():
65 (major, minor, blocks, gb_size, readonly) = details
67 if device[:14] == "/dev/planetlab":
68 log.write("Skipping device {} in volume group.\n".format(device))
72 log.write("Skipping read only device {}\n".format(device))
75 if gb_size < MINIMUM_DISK_SIZE:
76 log.write("Skipping too small device {} ({:4.2f}) Gb\n"\
77 .format(device, gb_size))
80 log.write("Checking device {} to see if it is part " \
81 "of the volume group.\n".format(device))
84 # when introducing the 'upgrade' verb, we ran into the situation
85 # where 'pvdisplay' at this point displays e.g. /dev/sda, instead
87 # we thus consider that if either of these is known, then
88 # the disk is already part of LVM
89 first_partition = InstallPartitionDisks.get_partition_path_from_device(device, vars, log)
90 probe_first_part = "pvdisplay {} | grep -q planetlab".format(first_partition)
91 probe_device = "pvdisplay {} | grep -q planetlab".format(device)
92 already_added = utils.sysexec_noerr(probe_first_part, log, shell=True) \
93 or utils.sysexec_noerr(probe_device, log, shell=True)
96 log.write("It appears {} is part of the volume group, continuing.\n"\
100 # just to be extra paranoid, ignore the device if it already has
101 # an lvm partition on it (new disks won't have this, and that is
102 # what this code is for, so it should be ok).
103 cmd = "parted --script --list {} | grep -q lvm$".format(device)
104 has_lvm = utils.sysexec_noerr(cmd, log, shell=True)
106 log.write("It appears {} has lvm already setup on it.\n".format(device))
109 log.write("Too paranoid to add {} to vservers lvm.\n".format(device))
112 if not InstallPartitionDisks.single_partition_device(device, vars, log):
113 log.write("Unable to partition {}, not using it.\n".format(device))
116 log.write("Successfully partitioned {}\n".format(device))
118 if NODE_MODEL_OPTIONS & ModelOptions.RAWDISK:
119 log.write("Running on a raw disk node, not using it.\n")
122 part_path = InstallPartitionDisks.get_partition_path_from_device(device,
125 log.write("Attempting to add {} to the volume group\n".format(device))
127 if not InstallPartitionDisks.create_lvm_physical_volume(part_path,
129 log.write("Unable to create lvm physical volume {}, not using it.\n"\
133 log.write("Adding {} to list of devices to add to "
134 "planetlab volume group.\n".format(device))
136 extended_gb_size = extended_gb_size + gb_size
137 new_devices.append(part_path)
140 if len(new_devices) > 0:
142 log.write("Extending planetlab volume group.\n")
144 log.write("Unmounting disks.\n")
146 # backwards compat, though, we should never hit this case post PL 3.2
147 os.stat("{}/rcfs/taskclass".format(SYSIMG_PATH))
148 utils.sysexec_chroot_noerr(SYSIMG_PATH, "umount /rcfs", log)
152 # umount in order to extend disk size
153 utils.sysexec_noerr("umount {}/proc".format(SYSIMG_PATH), log)
154 utils.sysexec_noerr("umount {}/vservers".format(SYSIMG_PATH), log)
155 utils.sysexec_noerr("umount {}".format(SYSIMG_PATH), log)
156 utils.sysexec("vgchange -an", log)
158 vars['ROOT_MOUNTED'] = 0
161 cmd = "vgextend planetlab {}".format(" ".join(new_devices))
162 if not utils.sysexec_noerr(cmd, log):
163 log.write("Failed to add physical volumes {} to "\
164 "volume group, continuing.\n".format(" ".join(new_devices)))
168 # now, get the number of unused extents, and extend the vserver
169 # logical volume by that much.
170 remaining_extents = \
171 InstallPartitionDisks.get_remaining_extents_on_vg(vars, log)
173 log.write("Extending vservers logical volume.\n")
174 utils.sysexec("vgchange -ay", log)
175 cmd = "lvextend -l +{} {}".format(remaining_extents, PARTITIONS["vservers"])
176 if not utils.sysexec_noerr(cmd, log):
177 log.write("Failed to extend vservers logical volume, continuing\n")
181 log.write("making the ext filesystem match new logical volume size.\n")
183 vars['ROOT_MOUNTED'] = 1
184 cmd = "mount {} {}".format(PARTITIONS["root"], SYSIMG_PATH)
185 utils.sysexec_noerr(cmd, log)
186 cmd = "mount {} {}/vservers".format(PARTITIONS["vservers"], SYSIMG_PATH)
187 utils.sysexec_noerr(cmd, log)
188 cmd = "resize2fs {}".format(PARTITIONS["vservers"])
189 resize = utils.sysexec_noerr(cmd,log)
190 utils.sysexec_noerr("umount {}/vservers".format(SYSIMG_PATH), log)
191 utils.sysexec_noerr("umount {}".format(SYSIMG_PATH), log)
192 vars['ROOT_MOUNTED'] = 0
194 utils.sysexec("vgchange -an", log)
197 log.write("Failed to resize vservers partition, continuing.\n")
201 log.write("Extended vservers partition by {:4.2f} Gb\n"\
202 .format(extended_gb_size))
207 log.write("No new disk devices to add to volume group.\n")