diff options
author | lawl <github@dumbinter.net> | 2020-07-17 16:31:07 +0200 |
---|---|---|
committer | lawl <github@dumbinter.net> | 2020-07-17 16:31:07 +0200 |
commit | 26a497783101e6f14a01c0c992164998bcf6f676 (patch) | |
tree | f935d2c6982df2356edfbdb8c25ca9968ad51aa5 | |
parent | 120b3fe00b84e6cb53389837baf0d1eec0ac84e9 (diff) | |
download | noisetorch-26a497783101e6f14a01c0c992164998bcf6f676.tar.gz noisetorch-26a497783101e6f14a01c0c992164998bcf6f676.zip |
remove rttime-rlimit as root during loading
-rw-r--r-- | main.go | 15 | ||||
-rw-r--r-- | module.go | 27 | ||||
-rw-r--r-- | rlimit.go | 68 |
3 files changed, 109 insertions, 1 deletions
@@ -1,11 +1,13 @@ package main import ( + "flag" "image" "io" "io/ioutil" "log" "os" + "syscall" "github.com/aarzilli/nucular/font" @@ -28,6 +30,19 @@ type input struct { func main() { + var pulsepid int + flag.IntVar(&pulsepid, "removerlimit", -1, "for internal use only") + flag.Parse() + if pulsepid > 0 { + const MaxUint = ^uint64(0) + new := syscall.Rlimit{Cur: MaxUint, Max: MaxUint} + err := setRlimit(pulsepid, &new) + if err != nil { + os.Exit(1) + } + os.Exit(0) + } + f, err := os.OpenFile("/tmp/noisetorch.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) if err != nil { log.Fatalf("error opening file: %v\n", err) @@ -59,6 +59,29 @@ func supressorState(c *pulseaudio.Client) int { } func loadSupressor(c *pulseaudio.Client, inp input, ui *uistate) error { + + log.Printf("Querying pulse rlimit\n") + + pid, err := getPulsePid() + if err != nil { + return err + } + + lim, err := getRlimit(pid) + if err != nil { + return err + } + log.Printf("Rlimit: %+v. Trying to remove.\n", lim) + removeRlimitAsRoot(pid) + defer setRlimit(pid, &lim) // lowering RLIMIT doesn't require root + + newLim, err := getRlimit(pid) + if err != nil { + return err + } + log.Printf("Rlimit: %+v\n", newLim) + + time.Sleep(time.Millisecond * 1000) // pulseaudio gets SIGKILL'd because of RLIMITS if we send these too fast log.Printf("Loading supressor\n") idx, err := c.LoadModule("module-null-sink", "sink_name=nui_mic_denoised_out") if err != nil { @@ -108,6 +131,7 @@ func unloadSupressor(c *pulseaudio.Client) error { log.Printf("Found null-sink at id [%d], sending unload command\n", m.Index) c.UnloadModule(m.Index) } + time.Sleep(time.Millisecond * 500) // pulseaudio gets SIGKILL'd because of RLIMITS if we send these too fast log.Printf("Searching for ladspa-sink\n") m, found, err = findModule(c, "module-ladspa-sink", "sink_name=nui_mic_raw_in sink_master=nui_mic_denoised_out") if err != nil { @@ -117,6 +141,7 @@ func unloadSupressor(c *pulseaudio.Client) error { log.Printf("Found ladspa-sink at id [%d], sending unload command\n", m.Index) c.UnloadModule(m.Index) } + time.Sleep(time.Millisecond * 500) // pulseaudio gets SIGKILL'd because of RLIMITS if we send these too fast log.Printf("Searching for loopback\n") m, found, err = findModule(c, "module-loopback", "sink=nui_mic_raw_in") if err != nil { @@ -126,7 +151,7 @@ func unloadSupressor(c *pulseaudio.Client) error { log.Printf("Found loopback at id [%d], sending unload command\n", m.Index) c.UnloadModule(m.Index) } - + time.Sleep(time.Millisecond * 500) // pulseaudio gets SIGKILL'd because of RLIMITS if we send these too fast log.Printf("Searching for remap-source\n") m, found, err = findModule(c, "module-remap-source", "master=nui_mic_denoised_out.monitor source_name=nui_mic_remap") if err != nil { diff --git a/rlimit.go b/rlimit.go new file mode 100644 index 0000000..1355965 --- /dev/null +++ b/rlimit.go @@ -0,0 +1,68 @@ +package main + +import ( + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "syscall" + "unsafe" +) + +const rlimitRTTime = 15 + +func getPulsePid() (int, error) { + runtimeDir := os.Getenv("XDG_RUNTIME_DIR") + pulsepidfile := filepath.Join(runtimeDir, "pulse/pid") + pidbuf, err := ioutil.ReadFile(pulsepidfile) + if err != nil { + return 0, err + } + pid, err := strconv.Atoi(strings.TrimSpace(string(pidbuf))) + if err != nil { + return 0, err + } + return pid, nil +} + +func getRlimit(pid int) (syscall.Rlimit, error) { + var res syscall.Rlimit + err := pRlimit(pid, rlimitRTTime, nil, &res) + return res, err +} + +func setRlimit(pid int, new *syscall.Rlimit) error { + var junk syscall.Rlimit + err := pRlimit(pid, rlimitRTTime, new, &junk) + return err +} + +func removeRlimitAsRoot(pid int) { + self, err := os.Executable() + if err != nil { + log.Printf("Couldn't find path to own binary, trying PATH\n") + self = "noisetorch" //try PATH and hope for the best + } + + cmd := exec.Command("pkexec", self, "-removerlimit", strconv.Itoa(pid)) + log.Printf("Calling: %s\n", cmd.String()) + err = cmd.Run() + if err != nil { + log.Printf("Couldn't remove rlimit as root: %v\n", err) + } +} + +func pRlimit(pid int, limit uintptr, new *syscall.Rlimit, old *syscall.Rlimit) error { + _, _, errno := syscall.RawSyscall6(syscall.SYS_PRLIMIT64, + uintptr(pid), + limit, + uintptr(unsafe.Pointer(new)), + uintptr(unsafe.Pointer(old)), 0, 0) + if errno != 0 { + return errno + } + return nil +} |