Skip to content
This repository was archived by the owner on Jan 29, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ Example
Here's an example of using `node-lkl` to read a file inside a disk image of
a ext4 partition and pipe it to `process.stdout`:

If you can omit the `filesystem` options parameter, all supported filesystems
will be tried.

``` javascript
const Promise = require('bluebird');
const filedisk = Promise.promisifyAll(require('file-disk'), { multiArgs: true });
Expand Down
46 changes: 38 additions & 8 deletions lib/lkl.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ const bindings = require('bindings')('bindings');
const binding = require('./binding');

const queue = require('./queue');
const constants = require('./constants');

const lkl = exports;

lkl.fs = require('./fs');
lkl.disk = require('./disk');

const SUPPORTED_FILESYSTEMS = [ // TODO: get this list from lkl
'ext4', 'ext3', 'ext2', 'btrfs', 'xfs', 'vfat'
];

lkl.startKernelSync = function(memory) {
bindings.startKernel(memory);
binding.clock_settime(null, function(){});
Expand Down Expand Up @@ -39,6 +44,35 @@ function mount(diskId, opts, callback) {
);
}

function mountGuessFS(disk, opts, callback, fsIndex) {
fsIndex = (fsIndex === undefined) ? 0 : fsIndex;
opts.filesystem = SUPPORTED_FILESYSTEMS[fsIndex];
mount(disk, opts, function(err, mountpoint) {
if (err) {
if (
(err.errno === constants.EINVAL) &&
(fsIndex < SUPPORTED_FILESYSTEMS.length - 1)
) {
return mountGuessFS(disk, opts, callback, fsIndex + 1);
}
return callback(err);
}
return callback(null, mountpoint);
});
}

lkl.mount = function(disk, opts, callback) {
if ((callback === undefined) && (typeof opts === 'function')) {
callback = opts;
opts = {};
}
if (SUPPORTED_FILESYSTEMS.indexOf(opts.filesystem) !== -1) {
queue.addOperation(mount, [disk, opts, callback]);
} else {
queue.addOperation(mountGuessFS, [disk, opts, callback]);
}
};

function umount(mountpoint, callback) {
const info = mounts[mountpoint];
bindings.umount(info.diskId, info.partition, function(err) {
Expand All @@ -50,6 +84,10 @@ function umount(mountpoint, callback) {
});
}

lkl.umount = function(mountpoint, callback) {
queue.addOperation(umount, [mountpoint, callback]);
};

lkl.diskAdd = function(disk, callback) {
queue.addOperation(
bindings.disk_add,
Expand All @@ -61,12 +99,4 @@ lkl.diskRemove = function(diskId, callback) {
queue.addOperation(bindings.disk_remove, [ diskId, callback ]);
};

lkl.mount = function(diskId, opts, callback) {
queue.addOperation(mount, [diskId, opts, callback]);
};

lkl.umount = function(mountpoint, callback) {
queue.addOperation(umount, [mountpoint, callback]);
};

lkl.utils = require('./utils');
14 changes: 7 additions & 7 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe('node-lkl', function() {
});

it('should mount', function() {
return lkl.mountAsync(this.diskId, { readOnly: true, filesystem: 'ext4'})
return lkl.mountAsync(this.diskId, { readOnly: true })
.then(lkl.umountAsync);
});

Expand Down Expand Up @@ -80,27 +80,27 @@ describe('node-lkl', function() {
});

it('should mount vfat', function() {
return lkl.mountAsync(this.diskId, {readOnly: true, filesystem: 'vfat', partition: 1})
return lkl.mountAsync(this.diskId, {readOnly: true, partition: 1})
.then(lkl.umountAsync);
});

it('should mount ext2', function() {
return lkl.mountAsync(this.diskId, {readOnly: true, filesystem: 'ext2', partition: 2})
return lkl.mountAsync(this.diskId, {readOnly: true, partition: 2})
.then(lkl.umountAsync);
});

it('should mount ext4', function() {
return lkl.mountAsync(this.diskId, {readOnly: true, filesystem: 'ext4', partition: 3})
return lkl.mountAsync(this.diskId, {readOnly: true, partition: 3})
.then(lkl.umountAsync);
});

it('should mount btrfs', function() {
return lkl.mountAsync(this.diskId, {readOnly: true, filesystem: 'btrfs', partition: 5})
return lkl.mountAsync(this.diskId, {readOnly: true, partition: 5})
.then(lkl.umountAsync);
});

it('should mount xfs', function() {
return lkl.mountAsync(this.diskId, {readOnly: true, filesystem: 'xfs', partition: 6})
return lkl.mountAsync(this.diskId, {readOnly: true, partition: 6})
.then(lkl.umountAsync);
});

Expand Down Expand Up @@ -161,7 +161,7 @@ describe('node-lkl', function() {
})
.then(function(diskId) {
self.diskId = diskId;
return lkl.mountAsync(diskId, {filesystem: 'ext4'});
return lkl.mountAsync(diskId);
})
.then(function (mountpoint) {
self.mountpoint = mountpoint;
Expand Down