c81c23c0d0
The code was not properly waiting mount/unmount to be done.
65 lines
1.8 KiB
JavaScript
65 lines
1.8 KiB
JavaScript
import LRU from 'lru-cache'
|
|
import Fuse from 'fuse-native'
|
|
import { VhdSynthetic } from 'vhd-lib'
|
|
import { Disposable, fromCallback } from 'promise-toolbox'
|
|
|
|
// build a s stat object from https://github.com/fuse-friends/fuse-native/blob/master/test/fixtures/stat.js
|
|
const stat = st => ({
|
|
mtime: st.mtime || new Date(),
|
|
atime: st.atime || new Date(),
|
|
ctime: st.ctime || new Date(),
|
|
size: st.size !== undefined ? st.size : 0,
|
|
mode: st.mode === 'dir' ? 16877 : st.mode === 'file' ? 33188 : st.mode === 'link' ? 41453 : st.mode,
|
|
uid: st.uid !== undefined ? st.uid : process.getuid(),
|
|
gid: st.gid !== undefined ? st.gid : process.getgid(),
|
|
})
|
|
|
|
export const mount = Disposable.factory(async function* mount(handler, diskPath, mountDir) {
|
|
const vhd = yield VhdSynthetic.fromVhdChain(handler, diskPath)
|
|
|
|
const cache = new LRU({
|
|
max: 16, // each cached block is 2MB in size
|
|
})
|
|
await vhd.readBlockAllocationTable()
|
|
const fuse = new Fuse(mountDir, {
|
|
async readdir(path, cb) {
|
|
if (path === '/') {
|
|
return cb(null, ['vhd0'])
|
|
}
|
|
cb(Fuse.ENOENT)
|
|
},
|
|
async getattr(path, cb) {
|
|
if (path === '/') {
|
|
return cb(
|
|
null,
|
|
stat({
|
|
mode: 'dir',
|
|
size: 4096,
|
|
})
|
|
)
|
|
}
|
|
if (path === '/vhd0') {
|
|
return cb(
|
|
null,
|
|
stat({
|
|
mode: 'file',
|
|
size: vhd.footer.currentSize,
|
|
})
|
|
)
|
|
}
|
|
|
|
cb(Fuse.ENOENT)
|
|
},
|
|
read(path, fd, buf, len, pos, cb) {
|
|
if (path === '/vhd0') {
|
|
return vhd.readRawData(pos, len, cache, buf).then(cb)
|
|
}
|
|
throw new Error(`read file ${path} not exists`)
|
|
},
|
|
})
|
|
return new Disposable(
|
|
() => fromCallback(cb => fuse.unmount(cb)),
|
|
fromCallback(cb => fuse.mount(cb))
|
|
)
|
|
})
|