Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ghcWithPackages wrapper does not work with ghc-8.10.1 #79441

Closed
peti opened this issue Feb 7, 2020 · 17 comments · Fixed by #85446
Closed

ghcWithPackages wrapper does not work with ghc-8.10.1 #79441

peti opened this issue Feb 7, 2020 · 17 comments · Fixed by #85446
Labels

Comments

@peti
Copy link
Member

peti commented Feb 7, 2020

Using the current master branch @ 57ed5db, the following simple development environment cannot be created:

$ nix-shell --run zsh -p "haskell.packages.ghc8101.ghcWithPackages (pset: with pset; [zlib])"                                                                                         
these derivations will be built:
  /nix/store/rq2yzy1kc1vlvld8lsv1dwycq6l30b8k-ghc-8.10.0.20200123-with-packages.drv
these paths will be fetched (0.38 MiB download, 5.85 MiB unpacked):
  /nix/store/fig25wwp1gwv4q4ygxxa75xscc5z6cqv-zlib-0.6.2.1-doc
  /nix/store/knhfvkm690z4qv8wpnq8dza9dvrfidnx-zlib-0.6.2.1
copying path '/nix/store/fig25wwp1gwv4q4ygxxa75xscc5z6cqv-zlib-0.6.2.1-doc' from 'https://cache.nixos.org'...                                                                                                      
copying path '/nix/store/knhfvkm690z4qv8wpnq8dza9dvrfidnx-zlib-0.6.2.1' from 'https://cache.nixos.org'...
building '/nix/store/rq2yzy1kc1vlvld8lsv1dwycq6l30b8k-ghc-8.10.0.20200123-with-packages.drv'...
/nix/store/xkm18nmijvgs3822q10lkdbf9sssb11a-ghc-8.10.0.20200123/nix-support:
propagated-build-inputs: /nix/store/knhfvkm690z4qv8wpnq8dza9dvrfidnx-zlib-0.6.2.1/nix-support/propagated-build-inputs
ghc-pkg: Couldn't open database /nix/store/grg4b1j9zbi4f0a5ijhp0zlzgii723sy-ghc-8.10.0.20200123-with-packages/lib/ghc-8.10.0.20200123/package.conf.d for modification: {handle: /nix/store/grg4b1j9zbi4f0a5ijhp0zlzgii723sy-ghc-8.10.0.20200123-with-packages/lib/ghc-8.10.0.20200123/package.conf.d/package.cache.lock}: hLock: invalid argument (Bad file descriptor)
builder for '/nix/store/rq2yzy1kc1vlvld8lsv1dwycq6l30b8k-ghc-8.10.0.20200123-with-packages.drv' failed with exit code 1
error: build of '/nix/store/rq2yzy1kc1vlvld8lsv1dwycq6l30b8k-ghc-8.10.0.20200123-with-packages.drv' failed

The relevant bit is:

ghc-pkg: Couldn't open database /nix/store/grg4b1j9zbi4f0a5ijhp0zlzgii723sy-ghc-8.10.0.20200123-with-packages/lib/ghc-8.10.0.20200123/package.conf.d for modification: {handle: /nix/store/grg4b1j9zbi4f0a5ijhp0zlzgii723sy-ghc-8.10.0.20200123-with-packages/lib/ghc-8.10.0.20200123/package.conf.d/package.cache.lock}: hLock: invalid argument (Bad file descriptor)

@peti peti added 0.kind: bug Something is broken 6.topic: haskell labels Feb 7, 2020
@matthewbauer
Copy link
Member

That looks like ghc-pkg recache is failing.

Is it possible the version number being 8.10.0.20200123 is causing problems? It may somehow think it is 8.10.1.

@peti
Copy link
Member Author

peti commented Mar 20, 2020

https://gitlab.haskell.org/ghc/ghc/issues/13945 may or may not be relevant. The bug is supposed to be fixed since ghc-8.2.x, but the error messages look exactly like the one we are getting.

@vaibhavsagar
Copy link
Member

Still doesn't work with the most recent haskell-updates branch:

$ nix-shell -I nixpkgs=. -p 'haskell.packages.ghc8101.ghcWithPackages (p: [ p.vector ])'
these derivations will be built:
  /nix/store/g42dzyfixjsdic6v941pwr640my07712-ghc-8.10.1-with-packages.drv
building '/nix/store/g42dzyfixjsdic6v941pwr640my07712-ghc-8.10.1-with-packages.drv'...
/nix/store/y5mlq6k40lmglk83g2d4wwrqbnczlfcc-vector-0.12.1.2/nix-support:
propagated-build-inputs: /nix/store/mjgcc312nynrbf4157g6yyll362swykh-primitive-0.7.0.1/nix-support/propagated-build-inputs
/nix/store/si82shf1fvp87zkv0dx6bsr0hw4h0v0q-ghc-8.10.1/nix-support:
propagated-build-inputs: /nix/store/mjgcc312nynrbf4157g6yyll362swykh-primitive-0.7.0.1/nix-support/propagated-build-inputs
ghc-pkg: Couldn't open database /nix/store/8k4pha8h3ah1dar9985g9p1bs64k04a3-ghc-8.10.1-with-packages/lib/ghc-8.10.1/package.conf.d for modification: {handle: /nix/store/8k4pha8h3ah1dar9985g9p1bs64k04a3-ghc-8.10.1-with-packages/lib/ghc-8.10.1/package.conf.d/package.cache.lock}: hLock: invalid argument (Bad file descriptor)
builder for '/nix/store/g42dzyfixjsdic6v941pwr640my07712-ghc-8.10.1-with-packages.drv' failed with exit code 1
error: build of '/nix/store/g42dzyfixjsdic6v941pwr640my07712-ghc-8.10.1-with-packages.drv' failed

I asked on the #ghc channel and I was pointed to this possibly related issue: haskell/cabal#6222.

@vaibhavsagar
Copy link
Member

@mpickering suggests that this error is related to https://gitlab.haskell.org/ghc/ghc/-/merge_requests/1996, and reverting that patch might make this error go away.

@phadej
Copy link

phadej commented Mar 26, 2020

The strace ghc-pkg-8.10.1 recache does contain lines like (on Ubuntu, but it's irrelevant).

openat(AT_FDCWD, "/opt/ghc/8.10.1/lib/ghc-8.10.1/package.conf.d/package.cache.lock", O_RDWR|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = -1 EACCES (Permission denied)
openat(AT_FDCWD, "/opt/ghc/8.10.1/lib/ghc-8.10.1/package.conf.d/package.cache.lock", O_RDONLY|O_NOCTTY|O_NONBLOCK) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
ioctl(3, TCGETS, 0x7fff08716e70)        = -1 ENOTTY (Inappropriate ioctl for device)
fcntl(3, F_OFD_SETLKW, {l_type=F_WRLCK, l_whence=SEEK_SET, l_start=0, l_len=0}) = -1 EBADF (Bad file descriptor)

So there is some code in ghc-pkg which tries to open lock file in read-write mode, then looks like to fallback to read-only one, but then acquiring lock fails.

This makes sense to me. You shouldn't be able to ghc-pkg recache something which is readonly!

I don't know what's the best way to tackle that. Maybe adding a flag to ghc-pkg to make it not take locks would make sense for nixpkgs usage, as these directories are "unique". (I guess you have to recache in the destination to make paths right).

Alternatively you can hack, and make that particular lock file (which is in known place) writable.

@phadej
Copy link

phadej commented Mar 26, 2020

And quick tests suggest that whether you have OFD locking or flock ones, if the lock wile is opened with O_RDONLY, both fail with Exception: fdLock: invalid argument (Bad file descriptor).


There is a regression in GHC:

% ghc-pkg-8.8.3 recache
ghc-pkg: /opt/ghc/8.8.3/lib/ghc-8.8.3/package.conf.d/package.cache: you don't have permission to modify this file

% ghc-pkg-8.10.1 recache
ghc-pkg: Couldn't open database /opt/ghc/8.10.1/lib/ghc-8.10.1/package.conf.d for modification: {handle: /opt/ghc/8.10.1/lib/ghc-8.10.1/package.conf.d/package.cache.lock}: hLock: invalid argument (Bad file descriptor)

I suggest opening an issue at least for that.

@vaibhavsagar
Copy link
Member

Thanks for looking into this! I tried the most obvious thing that came to mind and added chmod +w $(readlink "${packageCfgDir}/package.cache.lock") before the line that calls ghc-pkg recache but it didn't work because i can't change the permissions of files in the Nix store. Maybe there's another way to work around the read-only lock file?

@phadej
Copy link

phadej commented Mar 27, 2020

recache is write operation, therefore I think there's something wrong in the setup if you need to recache stuff which is (already) in /nix/store.

Unfortunately I cannot afford digging further in what the derivation tries to do here, and why. I just don't think this is ghc issue.

@vaibhavsagar
Copy link
Member

I'm a bit confused: you're saying that there is a regression in GHC, but this isn't a GHC issue?

@phadej
Copy link

phadej commented Mar 27, 2020

@vaibhavsagar the regression is that 8.8.3 says

 you don't have permission to modify this file

but 8.10.1 fails with weird error

hLock: invalid argument (Bad file descriptor)

EDIT: "neither work", but 8.8.3 at least tells you why.

@vaibhavsagar
Copy link
Member

Thanks for clarifying!

soareschen added a commit to maybevoid/casimir that referenced this issue Mar 29, 2020
Shell for 8.10 is not working due to NixOS/nixpkgs#79441
@guibou
Copy link
Contributor

guibou commented Apr 17, 2020

I've opened PR #85446 which does the simplest thing: rm the old package symlink database and let ghc-pkg recache rebuild it.

@guibou
Copy link
Contributor

guibou commented Apr 17, 2020

Thanks for looking into this! I tried the most obvious thing that came to mind and added chmod +w $(readlink "${packageCfgDir}/package.cache.lock") before the line that calls ghc-pkg recache but it didn't work because i can't change the permissions of files in the Nix store. Maybe there's another way to work around the read-only lock file?

I started from this and realized that it was not writable because it was a symlink to another derivation. However rming it was fine.

peti pushed a commit that referenced this issue Apr 17, 2020
This closes #79441.

ghcWithPackages is using `ghc-pkg recache` to build its package
database. By doing so, it overrides the `package.cache[.lock]` files.

Details are unclear, but GHC 8.10 changed a bit the behavior.
Previously, it was unconditionally replacing the files by new ones. Now
it tries to open (for modification) the files. These files are symlinks
to another nix derivation, which is hence read-only.

This commit removes the files before running `ghc-pkg recache`, hence it
will just write the new files.

Tested with `haskellPackages.ghcWithPackages` (i.e. GHC 8.8) and
`haskell.packages.ghc8101.ghcWithPackages` (i.e GHC 8.10) with the
following nix file, at the root of the nixpkgs repository:

```
with import ./. {
  overlays = [
    (
      self: super: {
        haskellPackages = super.haskell.packages.ghc8101.override {
          overrides = selfh: superh: {
             th-lift-instances = super.haskell.lib.doJailbreak superh.th-lift-instances;
             th-expand-syns    = super.haskell.lib.doJailbreak superh.th-expand-syns;
             th-reify-many     = super.haskell.lib.doJailbreak superh.th-reify-many;
             th-orphans        = super.haskell.lib.doJailbreak superh.th-orphans;
             haskell-src-meta  = super.haskell.lib.doJailbreak superh.haskell-src-meta;
          };
        };
      }
  )
  ];
};
haskellPackages.ghcWithPackages(p:[p.PyF])
```

This will test with GHC 8.10. Comment out the `overlays` to test with
GHC 8.8.
@peti peti closed this as completed in abc4f96 Apr 17, 2020
@ocharles
Copy link
Contributor

Could the fix be added to the 20.03 release?

@chessai
Copy link
Member

chessai commented Jul 1, 2020

Could the fix be added to the 20.03 release?

Seconded, that would be great.

@ocharles
Copy link
Contributor

ocharles commented Jul 1, 2020

I'm actively working on cherry picking this into 20.03. I'm just building everything on our work Hydra - if it fixes the build I'll open a PR.

@chessai
Copy link
Member

chessai commented Jul 1, 2020

Thanks @ocharles!

ocharles pushed a commit to circuithub/nixpkgs that referenced this issue Jul 6, 2020
This closes NixOS#79441.

ghcWithPackages is using `ghc-pkg recache` to build its package
database. By doing so, it overrides the `package.cache[.lock]` files.

Details are unclear, but GHC 8.10 changed a bit the behavior.
Previously, it was unconditionally replacing the files by new ones. Now
it tries to open (for modification) the files. These files are symlinks
to another nix derivation, which is hence read-only.

This commit removes the files before running `ghc-pkg recache`, hence it
will just write the new files.

Tested with `haskellPackages.ghcWithPackages` (i.e. GHC 8.8) and
`haskell.packages.ghc8101.ghcWithPackages` (i.e GHC 8.10) with the
following nix file, at the root of the nixpkgs repository:

```
with import ./. {
  overlays = [
    (
      self: super: {
        haskellPackages = super.haskell.packages.ghc8101.override {
          overrides = selfh: superh: {
             th-lift-instances = super.haskell.lib.doJailbreak superh.th-lift-instances;
             th-expand-syns    = super.haskell.lib.doJailbreak superh.th-expand-syns;
             th-reify-many     = super.haskell.lib.doJailbreak superh.th-reify-many;
             th-orphans        = super.haskell.lib.doJailbreak superh.th-orphans;
             haskell-src-meta  = super.haskell.lib.doJailbreak superh.haskell-src-meta;
          };
        };
      }
  )
  ];
};
haskellPackages.ghcWithPackages(p:[p.PyF])
```

This will test with GHC 8.10. Comment out the `overlays` to test with
GHC 8.8.

(cherry picked from commit abc4f96)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants