diff --git a/src/metrics.js b/src/metrics.js index 7efb206f3..6b0481088 100644 --- a/src/metrics.js +++ b/src/metrics.js @@ -104,18 +104,29 @@ async function getRootDiskName() { if (gRootDiskName) return gRootDiskName; const mounts = await fs.promises.readFile('/proc/mounts', { encoding: 'utf8' }); - const rootfsLine = mounts.split('\n').find(line => line.split(' ')[1] === '/'); + const rootfsLine = mounts.split('\n').find(line => line.split(/\s+/)[1] === '/'); if (!rootfsLine) throw new BoxError(BoxError.EXTERNAL_ERROR, 'Root mount not found'); - const devicePath = rootfsLine.split(' ')[0]; // eg. /dev/foo . This can be a partition or a disk path + const maybeDevicePath = rootfsLine.split(/\s+/)[0]; // eg. /dev/foo . This can be a partition or a disk path - // -n is no headings , -d is no holder devices or slaves , -o is output format . PKNAME is parent kernel name - const output = await shell.spawn('lsblk', [ '-ndo', 'PKNAME', devicePath ], { encoding: 'utf8' }); - gRootDiskName = output.trim() || devicePath.replace('/dev/', ''); + // for LVM, the canonical devicePath might be a symlink to the real disk + const devicePath = await fs.promises.realpath(maybeDevicePath); + + // keep going up to find the final parent disk + let pkname = devicePath.replace('/dev/', ''); + while (true) { + // -n is no headings , -d is no holder devices or slaves , -o is output format . PKNAME is parent kernel name + const output = await shell.spawn('lsblk', [ '-ndo', 'PKNAME', `/dev/${pkname}` ], { encoding: 'utf8' }); + if (!output.trim()) break; + pkname = output.trim(); + } + + gRootDiskName = pkname; return gRootDiskName; } async function readDiskMetrics() { - const rootDiskName = await getRootDiskName(); + const [rootDiskError, rootDiskName] = await safe(getRootDiskName()); + if (rootDiskError) throw new BoxError(BoxError.EXTERNAL_ERROR, `Could not detect root disk: ${rootDiskError.message}`); const diskstats = await fs.promises.readFile('/proc/diskstats', { encoding: 'utf8' }); const statsLine = diskstats.split('\n').find(l => l.includes(` ${rootDiskName} `)); if (!statsLine) throw new BoxError(BoxError.EXTERNAL_ERROR, `Could not get disk stats of ${rootDiskName}`);