J'ai une application qui lit un fichier. Appelons-le processname et le fichier ~ / .configuration . Lorsque processname s'exécute, il lit toujours ~ / .configuration et ne peut pas être configuré différemment. Il existe également d'autres applications qui reposent sur "~ / .configuration", avant et après, mais pas pendant que processname est en cours d'exécution.
L'emballage du nom du processus dans un script qui remplace le contenu de ~ / .configuration est une option, mais j'ai récemment eu une panne de courant (alors que le contenu a été échangé), où j'ai perdu le contenu précédent dudit fichier, donc ce n'est pas souhaitable.
Existe-t-il un moyen (peut-être d'utiliser quelque chose de très éloigné LD_DEBUG=files processname
?) De tromper un processus en lisant différents contenus lorsqu'il essaie de lire un fichier spécifique? La recherche et le remplacement du nom de fichier dans l'exécutable sont un peu trop invasifs, mais devraient également fonctionner.
Je sais qu'il est possible d'écrire un module de noyau qui prend en charge l' open()
appel ( https://news.ycombinator.com/item?id=2972958 ), mais existe-t-il un moyen plus simple ou plus propre?
EDIT: Lors de la recherche de ~ / .configuration dans l' exécutable processname, j'ai découvert qu'il essayait de lire un autre nom de fichier juste avant de lire ~ / .configuration . Problème résolu.
la source
LD_PRELOAD
ou FUSE, comme avec ce problème quelque peu similaire , mais je ne connais aucune implémentation existante.Réponses:
Dans les versions récentes de Linux, vous pouvez annuler le partage de l' espace de noms de montage . Autrement dit, vous pouvez démarrer des processus qui affichent le système de fichiers virtuel différemment (avec des systèmes de fichiers montés différemment).
Cela peut également être fait avec
chroot
, maisunshare
est plus adapté à votre cas.Comme
chroot
, vous avez besoin d'un superutilisateur privilégié surunshare
l'espace de noms de montage.Alors, que vous avez
~/.configuration
et~/.configuration-for-that-cmd
fichiers.Vous pouvez démarrer un processus pour lequel il
~/.configuration
s'agit en fait d'un montage de liaison de~/.configuration-for-that-cmd
dedans, et l'exécuterthat-cmd
là-dedans.comme:
that-cmd
et tous ses processus descendants verront un autre~/.configuration
.that-cmd
ci-dessus s'exécutera en tant queroot
, utilisez-lesudo -u another-user that-cmd
s'il doit s'exécuter en tant qu'autre utilisateur .la source
/test
et cela a fonctionné sans problème.Liens souples.
Créez deux fichiers de configuration et pointez sur l'un d'eux avec un lien logiciel la plupart du temps, mais modifiez le lien logiciel pour qu'il pointe vers l'autre lorsque l'application spéciale est en cours d'exécution.
(Je sais que c'est un horrible hack, mais c'est un peu plus fiable que de changer le contenu d'un fichier).
Ou, manipulez $ HOME.
Dans le script qui démarre le processus ennuyeux, définissez $ HOME comme étant quelque chose dans le répertoire $ HOME normal, et votre application doit ensuite utiliser le fichier de configuration qui s'y trouve (testé et fonctionne pour les commandes de base du shell, ~ se développe en $ HOME).
Selon ce que fait le processus, changer $ HOME peut avoir des conséquences inattendues (c'est-à-dire que les fichiers de sortie peuvent se retrouver au mauvais endroit).
la source
Vous pouvez le faire en utilisant l'astuce LD_PRELOAD . Voici une implémentation qui mappe les chemins commençant par un préfixe spécifique vers un autre emplacement. Le code est également sur github .
Par exemple, vous pouvez simuler l'existence d'un fichier
/etc/
sans être root. Cela était nécessaire pour le client owncloud qui refuse de travailler lorsque le fichier/etc/ownCloud/sync-exclude.list
n'existe pas.Cela fonctionne en remplaçant les fonctions
open()
etopen64()
pour mapper un répertoire à un autre, par exemple tous lesopen()
appels vers/etc/ownCloud/...
pourraient être redirigés vers/home/user1/.etc/ownCloud/...
.Ajustez simplement le
path_map
, puis compilez et exécutez votre programme avec la lib préchargée:Code source de
path-mapping.c
:la source