CIFS issues during npm install

Expected behavior

npm install doesn’t fail, or fails for non i/o related reasons.

Actual behavior

13162 verbose stack Error: EIO: i/o error, open '/home/build/.npm/request/2.33.0/package/package.json'
13162 verbose stack     at Error (native)
13163 verbose cwd /work
13164 error Linux 4.4.13-moby
13165 error argv "/work/node/node" "/work/node/node_modules/npm/bin/npm-cli.js" "install" "--progress=false" "--no-bin-links" "--no-shrinkwrap"
13166 error node v4.4.5
13167 error npm  v3.9.5
13168 error path /home/build/.npm/request/2.33.0/package/package.json
13169 error code EIO
13170 error errno -5
13171 error syscall open
13172 error EIO: i/o error, open '/home/build/.npm/request/2.33.0/package/package.json'
13173 error If you need help, you may report this error at:
13173 error     <https://github.com/npm/npm/issues>
13174 verbose exit [ -5, true ]

(Plus many more similar errors in the log file)

Information

Win 10 Pro.

docker version:
Client:
 Version:      1.12.0-rc2
 API version:  1.24
 Go version:   go1.6.2
 Git commit:   906eacd
 Built:        Fri Jun 17 20:35:33 2016
 OS/Arch:      windows/amd64
 Experimental: true

Server:
 Version:      1.12.0-rc2
 API version:  1.24
 Go version:   go1.6.2
 Git commit:   a7119de
 Built:        Fri Jun 17 22:09:20 2016
 OS/Arch:      linux/amd64
 Experimental: true

Junos Pulse VPN connection (I have to disable/reenable DockerNAT every time I reconnect the vpn, but after I do this everything seems to work)

Diagnostic ID: 216B30D2-4FB5-4DED-88DC-F7EE126956B7/2016-06-24_09-27-34

looking at the output of “dmesg” on the mobylinux system I believe this message is related:
[ 70.758106] CIFS VFS: SMB signature verification returned error = -13
There are dozens of these lines, along with a few of these:
[ 561.521536] cifs_vfs_err: 18 callbacks suppressed

I am mounting the NPM cache directory at /usr/.npm
-v "C:\Users\jfriesen\AppData\Roaming\npm-cache":/usr/.npm
and symlinking that to the home directory of the build user
ln -s /usr/.npm /home/build/.npm

I have tried mounting the npm cache directory directly to the /home/build/.npm directory as well and the same issue occurs.

I tried remounting the cifs shares with some other options, such as vers=3.02,cache=none but even after remounting the shares and restarting the container the mount command inside the container didn’t show that the mount options had changed.

Just a follow up, I can reproduce this locally with the following dockerfile:
FROM node:4-onbuild
RUN mkdir -p /opt/app
VOLUME /opt/app
WORKDIR /opt/app
ENTRYPOINT [“npm”]

package.json:
{
“private”: true,
“name”: “Foobar”,
“version”: “0.0.1-SNAPSHOT”,
“devDependencies”: {
“autoprefixer”: “~5.2.0”,
“grunt”: “~0.4.5”,
“grunt-amdcheck”: “^1.3.1”,
“grunt-compile-handlebars”: “~2.0.0”,
“grunt-contrib-clean”: “~0.6.0”,
“grunt-contrib-concat”: “^0.5.1”,
“grunt-contrib-connect”: “~0.10.1”,
“grunt-contrib-copy”: “^0.8.0”,
“grunt-contrib-handlebars”: “~0.10.2”,
“grunt-contrib-jasmine”: “~0.9.0”,
“grunt-contrib-less”: “^1.0.0”,
“grunt-contrib-requirejs”: “~0.4.4”,
“grunt-contrib-watch”: “~0.6.1”,
“grunt-env”: “^0.4.4”,
“grunt-eslint”: “~16.0.0”,
“grunt-exec”: “~0.4.6”,
“grunt-filesize”: “0.0.7”,
“grunt-json-massager”: “^0.1.0”,
“grunt-open”: “~0.2.3”,
“grunt-parallel”: “~0.4.1”,
“grunt-postcss”: “^0.5.5”,
“grunt-protractor-runner”: “^2.1.0”,
“grunt-template-jasmine-istanbul”: “~0.3.3”,
“grunt-template-jasmine-requirejs”: “~0.2.2”,
“grunt-todo”: “~0.5.0”,
“grunt-uncss”: “^0.4.4”,
“jasmine-reporters”: “^2.0.7”,
“protractor”: “^2.5.1”,
“protractor-jasmine2-screenshot-reporter”: “0.3.1”,
“request”: “^2.72.0”,
“requirejs”: “2.2.0”,
“selenium-webdriver”: “^2.48.2”,
“time-grunt”: “~1.1.0”,
“xml2js”: “^0.4.6”
},
“dependencies”: {
“babel”: “^5.8.23”,
“config”: “^1.16.0”,
“fs-extra”: “^0.24.0”,
“glob”: “^5.0.15”,
“good”: “^6.3.0”,
“good-console”: “^5.0.3”,
“good-file”: “^5.1.0”,
“h2o2”: “^4.0.1”,
“handlebars”: “^4.0.3”,
“hapi”: “^10.1.0”,
“hasha”: “^2.0.2”,
“inert”: “^3.0.1”,
“lodash”: “^3.10.1”,
“newrelic”: “^1.22.1”,
“node-uuid”: “^1.4.7”,
“pkginfo”: “^0.3.0”,
“qs”: “^5.1.0”,
“vision”: “^3.0.0”,
“wreck”: “^6.2.0”
}
}

Execution: (in directory with package.json)
docker run -it -v %CD%:/opt/app <image-id> install
or, to use system npm cache:
docker run -it -v %CD%:/opt/app -v %APPDATA%\npm-cache:/root/.npm <image-id> install

The errors I get are not consistent, although generally they are similar. It seems to depend on when the cifs share falls down. Dmesg output seems to be cyclical each time I attempt this:
[15158.150586] docker0: port 3(veth9b45fe0) entered forwarding state
[15158.150606] docker0: port 3(veth9b45fe0) entered forwarding state
[15173.190162] docker0: port 3(veth9b45fe0) entered forwarding state
[15186.675614] cifs_vfs_err: 6 callbacks suppressed
[15186.675616] CIFS VFS: SMB signature verification returned error = -13
[15186.691233] CIFS VFS: SMB signature verification returned error = -13
[15186.716753] CIFS VFS: SMB signature verification returned error = -13
[15186.790513] CIFS VFS: SMB signature verification returned error = -13
[15186.899828] CIFS VFS: SMB signature verification returned error = -13
[15186.964720] CIFS VFS: SMB signature verification returned error = -13
[15187.108846] CIFS VFS: SMB signature verification returned error = -13
[15187.576819] CIFS VFS: SMB signature verification returned error = -13
[15187.641526] CIFS VFS: SMB signature verification returned error = -13
[15187.760544] CIFS VFS: SMB signature verification returned error = -13
[15191.959809] cifs_vfs_err: 5 callbacks suppressed
[15191.959811] CIFS VFS: SMB signature verification returned error = -13
[15282.734711] vethf548e5c: renamed from eth0
[15282.750408] docker0: port 3(veth9b45fe0) entered disabled state
[15282.810022] docker0: port 3(veth9b45fe0) entered disabled state
[15282.810341] device veth9b45fe0 left promiscuous mode
[15282.810344] docker0: port 3(veth9b45fe0) entered disabled state

FYI, I have managed to resolve my issue in a rather complicated, round about way… by mounting my own shared directories on the linux host with more appropriate options. I am using the following mount command:

mount -t cifs //10.0.75.1/C /C -o rw,vers=3.02,username=,domain=,uid=0,noforceuid,gid=0,noforcegid,file_mode=0755,dir_mode=0755,iocharset=utf8,nounix,serverino,mapposix,noperm,rsize=61440,wsize=4292,actimeo=1,mfsymlinks,cache=none

This forces the use of a more recent version of the SMB protocol which is more efficent and has better error recovery. It also allows symlinks to be created in linux, although those links won’t be valid in windows.

However, in order to get to the point where I can execute this command and have it stick I’ve had to construct a docker image which contains nsenter and allows me to connect to the linux host. My Dockerfile looks like this:

FROM alpine
RUN apk update && \
    apk add util-linux && \
    rm -rf /var/cache/apk/*
ENTRYPOINT ["nsenter"]
CMD ["--target", "1", "--mount", "--uts", "--ipc", "--net", "--pid", "/bin/sh"]

And I use this batch file to execute it from the command line:

@echo off
docker build ./ -t hostenter
docker run --rm -it --privileged --pid=host hostenter

Please take it as a feature request to use a more recent version of the SMB protocol as it has dramatically improved the stability of my maven/node builds as they pull from cache shared from the host computer.

Awesome, mfsymlinks is now part of the default config: https://docs.docker.com/docker-for-windows/release-notes/#/beta-23-release-2016-08-16-1-12-1-rc1-beta23

Have you checked whether the default setup works for you?
Michael

I have tried it and it still does not work consistently. At some point the cifs process goes off the rails and starts throwing I/O errors. This is not the case when you change the version of cifs/smb that is used. That really is the key part to my hack above. In fact, here is some notes from the SMB3 Kernel module wiki:

SMB3.02 was introduced in Windows 8.1 (Windows ‘Blue’) and Windows Server 2012 R2. Among the new protocol features are those particularly useful for virtualization (HyperV):

  • SMB3.02 dialect is not yet negotiated by Samba servers
  • SMB3.02 dialect can be requested by the Linux cifs client (“vers=3.02” on mount) but the new optional features, unique to SMB3.02, are not requested.
  • Unbuffered I/O flags (ie a ‘no cache flag’ which may be sent on read or write)
  • New RDMA remote invalidate flag
  • MS-RSVD (a set of remoteable FSCTLs that improve “SCSI over SMB3”)
  • Asymmetric Shares (extensions to Witness protocol to allow moving users of one share to a different server, eg for load balancing or maintenance - previously witness protocol could only do this on a per server rather than per-share basis).

Thanks, we’re looking at upgrading the protocol version - stay tuned.

FYI, just tried the latest beta which has the newer version of cifs specified and my issues seem to be resolved. No more hacks to remount the drives for me :smiley: