Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
| /* | |
| * Copyright (c) 2012 Joyent Inc., All Rights Reserved. | |
| */ | |
| // Ensure we're using the platform's node | |
| require('/usr/node/node_modules/platform_node_version').assert(); | |
| var kstat = require('/usr/node/node_modules/kstat'); | |
| var systempages_reader = null; | |
| var arcstats_reader = null; | |
| // Default value is 20% of RAM, caller can override. | |
| exports.arc_reserve_factor = 0.20; | |
| /* | |
| * This function grabs some basic memory usage information via kstat. It should | |
| * be called like: | |
| * | |
| * system.getMemoryInfo(function (err, data) { | |
| * // data will contain several memory properties if err is not set | |
| * }); | |
| * | |
| * values in the data object are in bytes for maximum accuracy. | |
| * | |
| */ | |
| exports.getMemoryInfo = function (callback) | |
| { | |
| var arcstats_val, systempages_val; | |
| // Setup readers if we've not already done so. | |
| if (!arcstats_reader) { | |
| arcstats_reader = new kstat.Reader({ module: 'zfs', | |
| 'class': 'misc', instance: 0, name: 'arcstats' }); | |
| } | |
| if (!systempages_reader) { | |
| systempages_reader = new kstat.Reader({ module: 'unix', | |
| 'class': 'pages', instance: 0, name: 'system_pages' }); | |
| } | |
| // Get the latest values from kstat | |
| systempages_val = systempages_reader.read(); | |
| arcstats_val = arcstats_reader.read(); | |
| if (!systempages_val) { | |
| return callback(new Error('No value for system_pages.')); | |
| } | |
| if (!arcstats_val) { | |
| return callback(new Error('No value for arcstats.')); | |
| } | |
| if (!systempages_val.hasOwnProperty(0) | |
| || !systempages_val[0].hasOwnProperty('data') | |
| || !systempages_val[0].data.hasOwnProperty('availrmem') | |
| || !systempages_val[0].data.hasOwnProperty('pagestotal')) { | |
| return callback(new Error('Invalid data returned for system_pages:' | |
| + JSON.stringify(systempages_val))); | |
| } | |
| if (!arcstats_val.hasOwnProperty(0) | |
| || !arcstats_val[0].hasOwnProperty('data') | |
| || !arcstats_val[0].data.hasOwnProperty('size')) { | |
| return callback(new Error('Invalid data returned for arcstats:' | |
| + JSON.stringify(arcstats_val))); | |
| } | |
| return callback(null, { | |
| 'availrmem_bytes': (systempages_val[0].data.availrmem * 4096), | |
| 'arcsize_bytes': arcstats_val[0].data.size, | |
| 'total_bytes': (systempages_val[0].data.pagestotal * 4096) | |
| }); | |
| }; | |
| /* | |
| * This function attempts to determine the amount of memory that is available | |
| * for provisioning a VM. It takes the memory that's used for the ZFS ARC and | |
| * subtracts an amount that's reserved for ARC (by default total memory * 0.20) | |
| * if there's memory used by the ARC above this reserved amount, that's added | |
| * to the available memory. The result is converted to MiB (1024 * 1024 bytes). | |
| * | |
| * Note: the arc_reserve_factor can be changed before calling this function. It | |
| * must be between 0 and 1. | |
| * | |
| */ | |
| exports.getProvisionableMemory = function (callback) | |
| { | |
| this.getMemoryInfo(function (err, data) { | |
| var reserve_arc, reclaimable_arc = 0, available_MiB; | |
| if (err) { | |
| return err; | |
| } | |
| reserve_arc = Math.ceil(data.total_bytes * exports.arc_reserve_factor); | |
| if (exports.arc_reserve_factor > 0 && exports.arc_reserve_factor < 1) { | |
| if (reserve_arc < data.arcsize_bytes) { | |
| reclaimable_arc = (data.arcsize_bytes - reserve_arc); | |
| } | |
| } else { | |
| throw new Error('Invalid arc_reserve_factor: ' | |
| + exports.arc_reserve_factor + '. Must be between 0 and 1.'); | |
| } | |
| available_MiB = Math.floor((data.availrmem_bytes + reclaimable_arc) | |
| / (1024 * 1024)); | |
| return callback(null, available_MiB); | |
| }); | |
| }; |