Ich versuche, ADB auf einem Linux-Server mit mehreren Benutzern auszuführen, auf denen ich nicht root bin (um mit meinem Android-Emulator zu spielen). Der adb-Daemon schreibt seine Protokolle in die Datei, /tmp/adb.log
die leider fest in ADB codiert zu sein scheint, und diese Situation wird sich nicht ändern .
Daher kann adb nicht ausgeführt werden, was den offensichtlichen Fehler ergibt : cannot open '/tmp/adb.log': Permission denied
. Diese Datei wurde von einem anderen Benutzer erstellt und /tmp
hat ein Sticky Bit. Wenn ich adb mit dem adb nodaemon server
Schreiben in stdout beginne , treten keine Fehler auf (ich habe auch den Port auf einen eindeutigen Wert eingerichtet, um Konflikte zu vermeiden).
Meine Frage ist: Gibt es eine Möglichkeit, ADB dazu zu bringen, in eine andere Datei zu schreiben als /tmp/adb.log
? Gibt es allgemein eine Möglichkeit, eine Art prozessspezifischen Symlink zu erstellen? Ich möchte alle Dateizugriffe auf /tmp/adb.log
eine Datei umleiten ~/tmp/adb.log
.
Auch hier bin ich auf dem Server nicht als root, so chroot
, mount -o rbind
und chmod
sind nicht gültig Optionen. Wenn möglich, möchte ich ADB-Quellen nicht ändern, aber wenn es keine anderen Lösungen gibt, werde ich das tun.
PS Für den spezifischen ADB-Fall kann ich auf die Ausführung adb nodaemon server
mit nohup
und die Ausgabeumleitung zurückgreifen , aber die allgemeine Frage ist immer noch relevant.
/tmp/adb.log
oder sogar eine eigene private Datei/tmp
bereitstellen. tunman unshare
undman namespaces
undman nsenter
.LD_PRELOAD
Tricks, obwohl das komplizierter wäre./home/$USER/tmp/adb.log
, adb fest zuAntworten:
Hier ist ein sehr einfaches Beispiel für die Verwendung von
util-linux
'sunshare
, um einen Prozess in einen privaten Mount-Namespace zu stellen und ihm eine andere Ansicht desselben Dateisystems zu geben, über das sein übergeordnetes Element derzeit verfügt:Sie können einem Prozess mit dem
unshare
Dienstprogramm auf aktuellen Linux-Systemen eine private Ansicht seines Dateisystems geben , obwohl die Mount-Namespace-Funktion selbst für die gesamte 3.x-Kernel-Serie ziemlich ausgereift ist. Sie können bereits vorhandene Namespaces aller Art mit demnsenter
Dienstprogramm aus demselben Paket eingeben und mit erfahren Sie mehr darüberman
.quelle
unshare
alle Arten von Namespaces verwenden, um den Benutzernamensraum einzuschließen. Auf diese Weise kann Ihr Benutzer einen Namespace ausführen, in dem er über Root-Zugriff verfügt, und alles, was ein Root-Benutzer möglicherweise vermasselt, wirkt sich nicht auf den übergeordneten Namespace aus. Mit anderen Worten, ein Mount-Namespace kann in einen Benutzernamensraum eingebettet werden. Sie müssen dieseman
Seiten wirklich lesen . es wird tief. Genau sodocker
und sosytemd-nspawn
funktioniert es.runuser
Dienstprogramm, mit dem Sie arbeiten könnenunshare
, und wenn Sie trotzdem bereit sind, kompilierte Programme zu schreiben, gibt es keinen Grund, warum Sie denunshare()
Syscall nicht verwenden könnten , um dasselbe zu tun, oder sogar nursystem()
mit suid binary.LD_PRELOAD ist nicht allzu schwierig und Sie müssen nicht root sein. Fügen Sie Ihre eigene C-Routine ein, die anstelle des Real
open()
in der C-Bibliothek aufgerufen wird . Ihre Routine prüft, ob die zu öffnende Datei "/tmp/adb.log" ist, und ruft das echte Öffnen mit einem anderen Dateinamen auf. Hier ist deine shim_open.c:Kompilieren Sie es mit
gcc -Wall -O2 -fpic -shared -ldl -o shim_open.so shim_open.c
und testen Sie es, indem Sie etwas einfügen/tmp/myadb.log
und ausführenLD_PRELOAD=/.../shim_open.so cat /tmp/adb.log
. Versuchen Sie dann LD_PRELOAD auf adb.quelle
Operation not permitted
). Ich hoffe,open
das reicht aus, aber schließlichunlink
ist es nicht schwierig, diesen Handler zu erweitern.unshare
, also gewinnen wir alle!