From 71f38936e1d9a921905b5166b1d66d572928415a Mon Sep 17 00:00:00 2001 From: better0fdead Date: Wed, 19 Oct 2022 18:24:57 +0300 Subject: [PATCH] launcher: add fix for long socket paths Now relative path is used instead of real for console socket. It is used to prevent console socket path from being too long. Part of #124 --- cli/running/instance.go | 33 +++++++++++++++++++++++++++++++-- cli/running/instance_test.go | 4 ++-- cli/running/lua/launcher.lua | 26 +++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/cli/running/instance.go b/cli/running/instance.go index fb32ff1a4..b35acce40 100644 --- a/cli/running/instance.go +++ b/cli/running/instance.go @@ -5,6 +5,7 @@ import ( "os" "os/exec" "path/filepath" + "runtime" "sync" "syscall" "time" @@ -13,6 +14,11 @@ import ( "golang.org/x/sys/unix" ) +const ( + maxSocketPathLinux = 108 + maxSocketPathMac = 106 +) + // Instance describes a running process. type Instance struct { // Cmd represents an external command being prepared and run. @@ -104,9 +110,32 @@ func (inst *Instance) Start() error { return err } inst.Cmd.Env = append(os.Environ(), "TT_CLI_INSTANCE="+inst.appPath) - inst.Cmd.Env = append(inst.Cmd.Env, - "TT_CLI_CONSOLE_SOCKET="+inst.consoleSocket) + // It became common that console socket path is longer than 108/106 (on linux/macOs). + // To reduce length of path we use relative path + // with chdir into a directory of console socket. + // e.g foo/bar/123.sock -> ./123.sock + + maxSocketPath := maxSocketPathLinux + if runtime.GOOS == "darwin" { + maxSocketPath = maxSocketPathMac + } + + if inst.consoleSocket != "" { + if len("./"+filepath.Base(inst.consoleSocket)) > maxSocketPath { + return fmt.Errorf("socket name is longer than %d symbols: %s", + maxSocketPath-2, filepath.Base(inst.consoleSocket)) + } + inst.Cmd.Env = append(inst.Cmd.Env, + "TT_CLI_CONSOLE_SOCKET="+"unix/:./"+filepath.Base(inst.consoleSocket)) + inst.Cmd.Env = append(inst.Cmd.Env, + "TT_CLI_CONSOLE_SOCKET_DIR="+filepath.Dir(inst.consoleSocket)) + } + workDir, err := os.Getwd() + if err != nil { + return err + } + inst.Cmd.Env = append(inst.Cmd.Env, "TT_CLI_WORK_DIR="+workDir) dataDirAbs := "" if dataDirAbs, err = filepath.Abs(inst.dataDir); err != nil { return err diff --git a/cli/running/instance_test.go b/cli/running/instance_test.go index 1f13e3bb3..31c17601f 100644 --- a/cli/running/instance_test.go +++ b/cli/running/instance_test.go @@ -87,8 +87,8 @@ func TestInstanceLogger(t *testing.T) { defer writer.Close() defer reader.Close() logger := ttlog.NewCustomLogger(writer, "", 0) - - inst := startTestInstance(t, "log_check_test_app", "", logger) + consoleSock := "" + inst := startTestInstance(t, "log_check_test_app", consoleSock, logger) t.Cleanup(func() { cleanupTestInstance(inst) }) msg := "Check Log.\n" diff --git a/cli/running/lua/launcher.lua b/cli/running/lua/launcher.lua index f792e1e27..38b2fee36 100644 --- a/cli/running/lua/launcher.lua +++ b/cli/running/lua/launcher.lua @@ -43,6 +43,10 @@ local origin_cfg = box.cfg --- Wrapper for cfg to push our values over tarantool. local function cfg_wrapper(cfg) + ffi.cdef([[ + int chdir(const char *path); + ]]) + ffi.C.chdir(os.getenv('TT_CLI_CONSOLE_SOCKET_DIR')) local cfg = cfg or {} local tt_cfg = {} tt_cfg.wal_dir = os.getenv('TT_WAL_DIR') @@ -54,7 +58,8 @@ local function cfg_wrapper(cfg) end end local success, data = pcall(origin_cfg, cfg) - if not success then + ffi.C.chdir(os.getenv('TT_CLI_WORK_DIR')) + if not success then log.error('Someting wrong happened when tried to set dataDir.') end return data @@ -102,6 +107,19 @@ local function start_instance() ffi.C.setlinebuf(ffi.C.stdout) end + ffi.cdef([[ + int chdir(const char *path); + ]]) + + -- It became common that console socket path is longer than 108 symbols(sun_path limit). + -- To reduce length of path we use relative path with + -- chdir into a directory of console socket. + -- e.g foo/bar/123.sock -> ./123.sock + local console_sock_dir = os.getenv('TT_CLI_CONSOLE_SOCKET_DIR') + if console_sock_dir ~= nil and console_sock_dir ~= '' then + ffi.C.chdir(console_sock_dir) + end + -- If tarantool version is above 2.8.1, then can use environment variables -- instead of wrapping cfg. if not check_version({2,8,1,0}) then @@ -127,6 +145,12 @@ local function start_instance() end + -- After making console socket chdir back to work directory. + local work_dir = os.getenv('TT_CLI_WORK_DIR') + if work_dir ~= nil and work_dir ~= '' then + ffi.C.chdir(work_dir) + end + -- If stdin of the program was moved by command "tt run" to another fd -- then we need to move it back. -- It is used in cases when calling tarantool with "-" flag to hide input