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

syscall: can't inherit fcntlFlock on linux after syscall.Exec #25249

Closed
sakeven opened this issue May 4, 2018 · 6 comments
Closed

syscall: can't inherit fcntlFlock on linux after syscall.Exec #25249

sakeven opened this issue May 4, 2018 · 6 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Linux
Milestone

Comments

@sakeven
Copy link

sakeven commented May 4, 2018

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.10.1 linux/amd64
go version go1.8.5 linux/amd64
go version go1.10.2 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/chenlin/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build057651522=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

What did you do?

If possible, provide a recipe for reproducing the error.
A complete runnable program is good.
A link on play.golang.org is best.

See code:
https://play.golang.org/p/jTMF5dejA74

What did you expect to see?

Should inherit fcntlFlock on linux after syscall.Exec.

man 2 fcntl:

Record locks are not inherited by a child created via fork(2), but are preserved across an execve(2).

I test c code below. It can inherit fcntlFlock on linux after exceve.

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int main() {
    printf("begin %d\n", getpid());
    int fd = open("lock", O_WRONLY | O_CREAT | O_TRUNC , 0777);
    if (fd < 0 ) {
      printf("fail to open");
      return -1;
    }

    printf("fd %d\n", fd); 

    struct flock fl ;
    fl.l_type = F_WRLCK;
    fl.l_whence = SEEK_SET;
    fl.l_start = 0;
    fl.l_len = 0;
    
    int errno = fcntl(fd, F_SETLK, &fl);
    if( errno != 0) {
      printf("err %d", errno);
      return -1;
    }

    sleep(5);
    char *env[] = { NULL };
    char *argv[] = {"./test.sh", NULL};
    execve(argv[0], argv, env);
    return 0;
}

I also test go code on macOS. It can inherit fcntlFlock on macOS after syscall.Exec, too.

What did you see instead?

Can't inherit fcntlFlock on linux after syscall.Exec.

@sakeven sakeven changed the title can't inherit fcntlFlock on linux after syscall.Exec syscall: can't inherit fcntlFlock on linux after syscall.Exec May 4, 2018
@tklauser
Copy link
Member

tklauser commented May 4, 2018

/cc @ianlancetaylor @bradfitz

@tklauser tklauser added OS-Linux NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels May 4, 2018
@bradfitz bradfitz added this to the Go1.12 milestone May 4, 2018
@ianlancetaylor
Copy link
Contributor

I expect that the key difference is that Go files are all opened with O_CLOEXEC. Try adding that to the flags you pass to open in your C program. If that is the problem as I expect, then you'll need to modify your Go program to import golang.org/x/sys/unix and use unix.FcntlInt(fd, F_SETFD, 0) to clear the FD_CLOEXEC flag.

@sakeven
Copy link
Author

sakeven commented May 5, 2018

@ianlancetaylor I used syscall.Open rather than os.Open. I know os.Open will open files with O_CLOEXEC, but syscall.Open not.

Also I tryed clearing the FD_CLOEXEC flag after os.Open and it met the problem again.

@sakeven
Copy link
Author

sakeven commented May 7, 2018

It seems that it's a problem with Linux kernel.
In a multi-threaded environment the fcntlFlock may be released when execve.

@ianlancetaylor
Copy link
Contributor

Thanks for following up. I'll close this issue since it sounds like there is nothing we can change in Go to fix it. Please comment if you disagree.

@gopherbot
Copy link

Change https://golang.org/cl/114090 mentions this issue: compiler: fix DWARF inline debug issue with dead local vars

@golang golang locked and limited conversation to collaborators May 23, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Linux
Projects
None yet
Development

No branches or pull requests

5 participants