diff options
author | Robert Yang <liezhi.yang@windriver.com> | 2013-03-15 15:42:48 +0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2013-03-19 13:55:38 +0000 |
commit | af9f5843d997455af66a2a1b63de530d14f1ff2b (patch) | |
tree | 054fa03639aee9e12469bd37cf5f01d31b6c9fac | |
parent | 37bfbd649398e56c3c792ddb26ce179f2fe819db (diff) | |
download | poky-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>
-rw-r--r-- | bitbake/lib/bb/monitordisk.py | 73 |
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 |