// ------------------------------------------------- // --------------------- 9P ------------------------ // ------------------------------------------------- // Implementation of the 9p filesystem device following the // 9P2000.L protocol ( https://code.google.com/p/diod/wiki/protocol ) "use strict"; // TODO // flush // lock? // correct hard links var EPERM = 1; /* Operation not permitted */ var ENOENT = 2; /* No such file or directory */ var EINVAL = 22; /* Invalid argument */ var ENOTSUPP = 524; /* Operation is not supported */ var ENOTEMPTY = 39; /* Directory not empty */ var EPROTO = 71 /* Protocol error */ var P9_SETATTR_MODE = 0x00000001; var P9_SETATTR_UID = 0x00000002; var P9_SETATTR_GID = 0x00000004; var P9_SETATTR_SIZE = 0x00000008; var P9_SETATTR_ATIME = 0x00000010; var P9_SETATTR_MTIME = 0x00000020; var P9_SETATTR_CTIME = 0x00000040; var P9_SETATTR_ATIME_SET = 0x00000080; var P9_SETATTR_MTIME_SET = 0x00000100; var P9_STAT_MODE_DIR = 0x80000000; var P9_STAT_MODE_APPEND = 0x40000000; var P9_STAT_MODE_EXCL = 0x20000000; var P9_STAT_MODE_MOUNT = 0x10000000; var P9_STAT_MODE_AUTH = 0x08000000; var P9_STAT_MODE_TMP = 0x04000000; var P9_STAT_MODE_SYMLINK = 0x02000000; var P9_STAT_MODE_LINK = 0x01000000; var P9_STAT_MODE_DEVICE = 0x00800000; var P9_STAT_MODE_NAMED_PIPE = 0x00200000; var P9_STAT_MODE_SOCKET = 0x00100000; var P9_STAT_MODE_SETUID = 0x00080000; var P9_STAT_MODE_SETGID = 0x00040000; var P9_STAT_MODE_SETVTX = 0x00010000; var FID_NONE = -1; var FID_INODE = 1; var FID_XATTR = 2; /** * @constructor * * @param {FS} filesystem */ function Virtio9p(filesystem, bus) { /** @const @type {FS} */ this.fs = filesystem; /** @const @type {BusConnector} */ this.bus = bus; this.SendReply = function(x, y) {}; this.deviceid = 0x9; // 9p filesystem this.hostfeature = 0x1; // mountpoint //this.configspace = [0x0, 0x4, 0x68, 0x6F, 0x73, 0x74]; // length of string and "host" string //this.configspace = [0x0, 0x9, 0x2F, 0x64, 0x65, 0x76, 0x2F, 0x72, 0x6F, 0x6F, 0x74 ]; // length of string and "/dev/root" string this.configspace = new Uint8Array([0x6, 0x0, 0x68, 0x6F, 0x73, 0x74, 0x39, 0x70]); // length of string and "host9p" string this.VERSION = "9P2000.L"; this.BLOCKSIZE = 8192; // Let's define one page. this.msize = 8192; // maximum message size this.replybuffer = new Uint8Array(this.msize*2); // Twice the msize to stay on the safe site this.replybuffersize = 0; this.fids = []; } Virtio9p.prototype.get_state = function() { var state = []; state[0] = this.deviceid; state[1] = this.hostfeature; state[2] = this.configspace; state[3] = this.VERSION; state[4] = this.BLOCKSIZE; state[5] = this.msize; state[6] = this.replybuffer; state[7] = this.replybuffersize; state[8] = this.fids.map(function(f) { return [f.inodeid, f.type, f.uid] }); return state; }; Virtio9p.prototype.set_state = function(state) { this.deviceid = state[0]; this.hostfeature = state[1]; this.configspace = state[2]; this.VERSION = state[3]; this.BLOCKSIZE = state[4]; this.msize = state[5]; this.replybuffer = state[6]; this.replybuffersize = state[7]; this.fids = state[8].map(function(f) { return { inodeid: f[0], type: f[1], uid: f[2] } }); }; Virtio9p.prototype.Createfid = function(inode, type, uid) { return {inodeid: inode, type: type, uid: uid}; } Virtio9p.prototype.Reset = function() { this.fids = []; } Virtio9p.prototype.BuildReply = function(id, tag, payloadsize) { marshall.Marshall(["w", "b", "h"], [payloadsize+7, id+1, tag], this.replybuffer, 0); if ((payloadsize+7) >= this.replybuffer.length) { message.Debug("Error in 9p: payloadsize exceeds maximum length"); } //for(var i=0; i