cos-gpu-installer: reference locked file in the main function

Sending https requests might trigger Go garbage collection and
close unrefernced locked file so that the lock is released.
This results in allowing two installer instances running in one VM.

This CL makes the main function reference the locked file
and explicitly close it so that the lock won't be accidentally

TEST=Repeatedly trying to start a second installer during
the driver installation process.

Change-Id: I2654c2d280eebc64815849820a31aef774ad96fa
Tested-by: He Gao <>
Cloud-Build: GCB Service account <>
Reviewed-by: Robert Kolchmeyer <>
Reviewed-by: Arnav Kansal <>
diff --git a/src/cmd/cos_gpu_installer/main.go b/src/cmd/cos_gpu_installer/main.go
index 2414ae7..d3a6b24 100644
--- a/src/cmd/cos_gpu_installer/main.go
+++ b/src/cmd/cos_gpu_installer/main.go
@@ -19,7 +19,8 @@
 	log.V(2).Info("Checking if this is the only cos_gpu_installer that is running.")
-	utils.Flock()
+	f := utils.Flock()
+	defer f.Close()
 	subcommands.Register(subcommands.HelpCommand(), "")
 	subcommands.Register(subcommands.FlagsCommand(), "")
diff --git a/src/pkg/utils/utils.go b/src/pkg/utils/utils.go
index 7bc9126..0d8094a 100644
--- a/src/pkg/utils/utils.go
+++ b/src/pkg/utils/utils.go
@@ -70,7 +70,7 @@
 // Flock exclusively locks a special file on the host to make sure only one calling process is running at any time.
-func Flock() {
+func Flock() *os.File {
 	// TODO(mikewu): generalize Flock to make it useful for other use cases.
 	f, err := os.OpenFile(lockFile, os.O_RDONLY|os.O_CREATE, 0666)
 	if err != nil {
@@ -79,6 +79,7 @@
 	if err := syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
 		glog.Exitf("File %s is locked. Other process might be running.", lockFile)
+	return f
 // DownloadContentFromURL downloads file from a given URL.