summaryrefslogtreecommitdiffstats
path: root/bitbake/lib
diff options
context:
space:
mode:
authorRobert Yang <liezhi.yang@windriver.com>2013-03-15 15:42:48 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2013-03-19 13:55:38 +0000
commitaf9f5843d997455af66a2a1b63de530d14f1ff2b (patch)
tree054fa03639aee9e12469bd37cf5f01d31b6c9fac /bitbake/lib
parent37bfbd649398e56c3c792ddb26ce179f2fe819db (diff)
downloadpoky-af9f5843d997455af66a2a1b63de530d14f1ff2b.tar.gz
bitbake: monitordisk.py: monitor disks based on path
The previous monitor is based on the disk, and one disk only can have one action, this limits its function, for example we set this in the current local.conf: BB_DISKMON_DIRS = "\ STOPTASKS,${TMPDIR},1G,100K \ STOPTASKS,${DL_DIR},1G,100K \ STOPTASKS,${SSTATE_DIR},1G,100K \ ABORT,${TMPDIR},100M,1K \ ABORT,${DL_DIR},100M,1K \ ABORT,${SSTATE_DIR},100GM,1K" Before: * If TMPDIR, DL_DIR and SSTATE_DIR are on the same disk partition, only the last line "ABORT,${SSTATE_DIR},100GM,1K" works * If TMPDIR, DL_DIR and SSTATE_DIR are on the different disk partitions, only the last three lines (ABORT) work. These are not what we expect, now: * We monitor the disk based on the path and action, so all the six lines will work no matter whether they are on the same disk partition or not. * The out put format will be: WARNING: The free space of /path/to/directory (device) is running low (XXGB left) [YOCTO #3995] (Bitbake rev: e22a576672ee4a40b44f7a826a78a77fc07e9177) Signed-off-by: Robert Yang <liezhi.yang@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib')
-rw-r--r--bitbake/lib/bb/monitordisk.py73
1 files changed, 41 insertions, 32 deletions
diff --git a/bitbake/lib/bb/monitordisk.py b/bitbake/lib/bb/monitordisk.py
index 1c1e614848..a71dd9f4d5 100644
--- a/bitbake/lib/bb/monitordisk.py
+++ b/bitbake/lib/bb/monitordisk.py
@@ -107,7 +107,7 @@ def getDiskData(BBDirs, configuration):
107 printErr("Invalid disk space value in BB_DISKMON_DIRS: %s" % pathSpaceInodeRe.group(3)) 107 printErr("Invalid disk space value in BB_DISKMON_DIRS: %s" % pathSpaceInodeRe.group(3))
108 return None 108 return None
109 else: 109 else:
110 # 0 means that it is not specified 110 # None means that it is not specified
111 minSpace = None 111 minSpace = None
112 112
113 minInode = pathSpaceInodeRe.group(4) 113 minInode = pathSpaceInodeRe.group(4)
@@ -117,7 +117,7 @@ def getDiskData(BBDirs, configuration):
117 printErr("Invalid inode value in BB_DISKMON_DIRS: %s" % pathSpaceInodeRe.group(4)) 117 printErr("Invalid inode value in BB_DISKMON_DIRS: %s" % pathSpaceInodeRe.group(4))
118 return None 118 return None
119 else: 119 else:
120 # 0 means that it is not specified 120 # None means that it is not specified
121 minInode = None 121 minInode = None
122 122
123 if minSpace is None and minInode is None: 123 if minSpace is None and minInode is None:
@@ -127,8 +127,9 @@ def getDiskData(BBDirs, configuration):
127 # DL_DIR may not exist at the very beginning 127 # DL_DIR may not exist at the very beginning
128 if not os.path.exists(path): 128 if not os.path.exists(path):
129 bb.utils.mkdirhier(path) 129 bb.utils.mkdirhier(path)
130 mountedDev = getMountedDev(path) 130 dev = getMountedDev(path)
131 devDict[mountedDev] = [action, path, minSpace, minInode] 131 # Use path/action as the key
132 devDict[os.path.join(path, action)] = [dev, minSpace, minInode]
132 133
133 return devDict 134 return devDict
134 135
@@ -192,10 +193,10 @@ class diskMonitor:
192 # This is for STOPTASKS and ABORT, to avoid print the message repeatly 193 # This is for STOPTASKS and ABORT, to avoid print the message repeatly
193 # during waiting the tasks to finish 194 # during waiting the tasks to finish
194 self.checked = {} 195 self.checked = {}
195 for dev in self.devDict: 196 for k in self.devDict:
196 self.preFreeS[dev] = 0 197 self.preFreeS[k] = 0
197 self.preFreeI[dev] = 0 198 self.preFreeI[k] = 0
198 self.checked[dev] = False 199 self.checked[k] = False
199 if self.spaceInterval is None and self.inodeInterval is None: 200 if self.spaceInterval is None and self.inodeInterval is None:
200 self.enableMonitor = False 201 self.enableMonitor = False
201 202
@@ -204,53 +205,61 @@ class diskMonitor:
204 """ Take action for the monitor """ 205 """ Take action for the monitor """
205 206
206 if self.enableMonitor: 207 if self.enableMonitor:
207 for dev in self.devDict: 208 for k in self.devDict:
208 st = os.statvfs(self.devDict[dev][1]) 209 path = os.path.dirname(k)
210 action = os.path.basename(k)
211 dev = self.devDict[k][0]
212 minSpace = self.devDict[k][1]
213 minInode = self.devDict[k][2]
214
215 st = os.statvfs(path)
209 216
210 # The free space, float point number 217 # The free space, float point number
211 freeSpace = st.f_bavail * st.f_frsize 218 freeSpace = st.f_bavail * st.f_frsize
212 219
213 if self.devDict[dev][2] and freeSpace < self.devDict[dev][2]: 220 if minSpace and freeSpace < minSpace:
214 # Always show warning, the self.checked would always be False if the action is WARN 221 # Always show warning, the self.checked would always be False if the action is WARN
215 if self.preFreeS[dev] == 0 or self.preFreeS[dev] - freeSpace > self.spaceInterval and not self.checked[dev]: 222 if self.preFreeS[k] == 0 or self.preFreeS[k] - freeSpace > self.spaceInterval and not self.checked[k]:
216 logger.warn("The free space of %s is running low (%.3fGB left)" % (dev, freeSpace / 1024 / 1024 / 1024.0)) 223 logger.warn("The free space of %s (%s) is running low (%.3fGB left)" % \
217 self.preFreeS[dev] = freeSpace 224 (path, dev, freeSpace / 1024 / 1024 / 1024.0))
225 self.preFreeS[k] = freeSpace
218 226
219 if self.devDict[dev][0] == "STOPTASKS" and not self.checked[dev]: 227 if action == "STOPTASKS" and not self.checked[k]:
220 logger.error("No new tasks can be excuted since the disk space monitor action is \"STOPTASKS\"!") 228 logger.error("No new tasks can be excuted since the disk space monitor action is \"STOPTASKS\"!")
221 self.checked[dev] = True 229 self.checked[k] = True
222 rq.finish_runqueue(False) 230 rq.finish_runqueue(False)
223 bb.event.fire(bb.event.DiskFull(dev, 'disk', freeSpace, self.devDict[dev][1]), self.configuration) 231 bb.event.fire(bb.event.DiskFull(dev, 'disk', freeSpace, path), self.configuration)
224 elif self.devDict[dev][0] == "ABORT" and not self.checked[dev]: 232 elif action == "ABORT" and not self.checked[k]:
225 logger.error("Immediately abort since the disk space monitor action is \"ABORT\"!") 233 logger.error("Immediately abort since the disk space monitor action is \"ABORT\"!")
226 self.checked[dev] = True 234 self.checked[k] = True
227 rq.finish_runqueue(True) 235 rq.finish_runqueue(True)
228 bb.event.fire(bb.event.DiskFull(dev, 'disk', freeSpace, self.devDict[dev][1]), self.configuration) 236 bb.event.fire(bb.event.DiskFull(dev, 'disk', freeSpace, path), self.configuration)
229 237
230 # The free inodes, float point number 238 # The free inodes, float point number
231 freeInode = st.f_favail 239 freeInode = st.f_favail
232 240
233 if self.devDict[dev][3] and freeInode < self.devDict[dev][3]: 241 if minInode and freeInode < minInode:
234 # Some fs formats' (e.g., btrfs) statvfs.f_files (inodes) is 242 # Some fs formats' (e.g., btrfs) statvfs.f_files (inodes) is
235 # zero, this is a feature of the fs, we disable the inode 243 # zero, this is a feature of the fs, we disable the inode
236 # checking for such a fs. 244 # checking for such a fs.
237 if st.f_files == 0: 245 if st.f_files == 0:
238 logger.warn("Inode check for %s is unavaliable, remove it from disk monitor" % dev) 246 logger.warn("Inode check for %s is unavaliable, will remove it from disk monitor" % path)
239 self.devDict[dev][3] = None 247 minInode = None
240 continue 248 continue
241 # Always show warning, the self.checked would always be False if the action is WARN 249 # Always show warning, the self.checked would always be False if the action is WARN
242 if self.preFreeI[dev] == 0 or self.preFreeI[dev] - freeInode > self.inodeInterval and not self.checked[dev]: 250 if self.preFreeI[k] == 0 or self.preFreeI[k] - freeInode > self.inodeInterval and not self.checked[k]:
243 logger.warn("The free inode of %s is running low (%.3fK left)" % (dev, freeInode / 1024.0)) 251 logger.warn("The free inode of %s (%s) is running low (%.3fK left)" % \
244 self.preFreeI[dev] = freeInode 252 (path, dev, freeInode / 1024.0))
253 self.preFreeI[k] = freeInode
245 254
246 if self.devDict[dev][0] == "STOPTASKS" and not self.checked[dev]: 255 if action == "STOPTASKS" and not self.checked[k]:
247 logger.error("No new tasks can be excuted since the disk space monitor action is \"STOPTASKS\"!") 256 logger.error("No new tasks can be excuted since the disk space monitor action is \"STOPTASKS\"!")
248 self.checked[dev] = True 257 self.checked[k] = True
249 rq.finish_runqueue(False) 258 rq.finish_runqueue(False)
250 bb.event.fire(bb.event.DiskFull(dev, 'inode', freeSpace, self.devDict[dev][1]), self.configuration) 259 bb.event.fire(bb.event.DiskFull(dev, 'inode', freeInode, path), self.configuration)
251 elif self.devDict[dev][0] == "ABORT" and not self.checked[dev]: 260 elif action == "ABORT" and not self.checked[k]:
252 logger.error("Immediately abort since the disk space monitor action is \"ABORT\"!") 261 logger.error("Immediately abort since the disk space monitor action is \"ABORT\"!")
253 self.checked[dev] = True 262 self.checked[k] = True
254 rq.finish_runqueue(True) 263 rq.finish_runqueue(True)
255 bb.event.fire(bb.event.DiskFull(dev, 'inode', freeSpace, self.devDict[dev][1]), self.configuration) 264 bb.event.fire(bb.event.DiskFull(dev, 'inode', freeInode, path), self.configuration)
256 return 265 return