Making a bind-mount take effect only in the context of the current process and its descendants

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
0
down vote

favorite












I have 2 files: /MyDir/a and /MyDir/MySubDir/b and am running a bash script, to which I want to add code to make file /a point to file /b, but only in the current process and its descendants.



In hopes of making /MyDir/a point to /MyDir/MySubDir/b in the context of only the current process (not including its descendants, yet) I tried to first make the current process run in its own mount namespace by running a small C program in my script that performs



unshare(CLONE_NEWNS)


and then



mount --bind /MyDir/MySubDir/b /MyDir/a.


Unfortunately, this didn't work as I expected since the mount was still visible by other processes, despite the system call reporting success.



In another attempt, I tried to make the mount from the C code by calling



mount("/MyDir/a", "/MyDir/MySubDir/b", "ext3", MS_BIND, null)


But this didn't work as the mount didn't take effect at all (despite the call reporting success).



Is there a way of making /MyDir/a point to /MyDir/MySubDir/b in the context of only the current process and its descendants using a bash script?



I also read a little about chroot, but this applies only to the / directory...
Is there anything similar to chroot that applies only to a particular subdirectory?



Thanks for your time!







share|improve this question



















  • commands executed as the root user, right?
    – A.B
    May 18 at 21:31










  • Yes, that's right
    – Ben S.
    May 18 at 22:39










  • "But this didn't work as the mount didn't take effect at all" How did you check this? How are your C program and the shell command mount related? Did you execve() from the C program to the shell?
    – Hauke Laging
    May 18 at 22:44











  • This writing and reading was done within the C program?
    – Hauke Laging
    May 18 at 22:50










  • No, the writing was done by vi, before any mount operations, and reading was done by cat from within the bash script
    – Ben S.
    May 18 at 22:59














up vote
0
down vote

favorite












I have 2 files: /MyDir/a and /MyDir/MySubDir/b and am running a bash script, to which I want to add code to make file /a point to file /b, but only in the current process and its descendants.



In hopes of making /MyDir/a point to /MyDir/MySubDir/b in the context of only the current process (not including its descendants, yet) I tried to first make the current process run in its own mount namespace by running a small C program in my script that performs



unshare(CLONE_NEWNS)


and then



mount --bind /MyDir/MySubDir/b /MyDir/a.


Unfortunately, this didn't work as I expected since the mount was still visible by other processes, despite the system call reporting success.



In another attempt, I tried to make the mount from the C code by calling



mount("/MyDir/a", "/MyDir/MySubDir/b", "ext3", MS_BIND, null)


But this didn't work as the mount didn't take effect at all (despite the call reporting success).



Is there a way of making /MyDir/a point to /MyDir/MySubDir/b in the context of only the current process and its descendants using a bash script?



I also read a little about chroot, but this applies only to the / directory...
Is there anything similar to chroot that applies only to a particular subdirectory?



Thanks for your time!







share|improve this question



















  • commands executed as the root user, right?
    – A.B
    May 18 at 21:31










  • Yes, that's right
    – Ben S.
    May 18 at 22:39










  • "But this didn't work as the mount didn't take effect at all" How did you check this? How are your C program and the shell command mount related? Did you execve() from the C program to the shell?
    – Hauke Laging
    May 18 at 22:44











  • This writing and reading was done within the C program?
    – Hauke Laging
    May 18 at 22:50










  • No, the writing was done by vi, before any mount operations, and reading was done by cat from within the bash script
    – Ben S.
    May 18 at 22:59












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I have 2 files: /MyDir/a and /MyDir/MySubDir/b and am running a bash script, to which I want to add code to make file /a point to file /b, but only in the current process and its descendants.



In hopes of making /MyDir/a point to /MyDir/MySubDir/b in the context of only the current process (not including its descendants, yet) I tried to first make the current process run in its own mount namespace by running a small C program in my script that performs



unshare(CLONE_NEWNS)


and then



mount --bind /MyDir/MySubDir/b /MyDir/a.


Unfortunately, this didn't work as I expected since the mount was still visible by other processes, despite the system call reporting success.



In another attempt, I tried to make the mount from the C code by calling



mount("/MyDir/a", "/MyDir/MySubDir/b", "ext3", MS_BIND, null)


But this didn't work as the mount didn't take effect at all (despite the call reporting success).



Is there a way of making /MyDir/a point to /MyDir/MySubDir/b in the context of only the current process and its descendants using a bash script?



I also read a little about chroot, but this applies only to the / directory...
Is there anything similar to chroot that applies only to a particular subdirectory?



Thanks for your time!







share|improve this question











I have 2 files: /MyDir/a and /MyDir/MySubDir/b and am running a bash script, to which I want to add code to make file /a point to file /b, but only in the current process and its descendants.



In hopes of making /MyDir/a point to /MyDir/MySubDir/b in the context of only the current process (not including its descendants, yet) I tried to first make the current process run in its own mount namespace by running a small C program in my script that performs



unshare(CLONE_NEWNS)


and then



mount --bind /MyDir/MySubDir/b /MyDir/a.


Unfortunately, this didn't work as I expected since the mount was still visible by other processes, despite the system call reporting success.



In another attempt, I tried to make the mount from the C code by calling



mount("/MyDir/a", "/MyDir/MySubDir/b", "ext3", MS_BIND, null)


But this didn't work as the mount didn't take effect at all (despite the call reporting success).



Is there a way of making /MyDir/a point to /MyDir/MySubDir/b in the context of only the current process and its descendants using a bash script?



I also read a little about chroot, but this applies only to the / directory...
Is there anything similar to chroot that applies only to a particular subdirectory?



Thanks for your time!









share|improve this question










share|improve this question




share|improve this question









asked May 18 at 19:03









Ben S.

31




31











  • commands executed as the root user, right?
    – A.B
    May 18 at 21:31










  • Yes, that's right
    – Ben S.
    May 18 at 22:39










  • "But this didn't work as the mount didn't take effect at all" How did you check this? How are your C program and the shell command mount related? Did you execve() from the C program to the shell?
    – Hauke Laging
    May 18 at 22:44











  • This writing and reading was done within the C program?
    – Hauke Laging
    May 18 at 22:50










  • No, the writing was done by vi, before any mount operations, and reading was done by cat from within the bash script
    – Ben S.
    May 18 at 22:59
















  • commands executed as the root user, right?
    – A.B
    May 18 at 21:31










  • Yes, that's right
    – Ben S.
    May 18 at 22:39










  • "But this didn't work as the mount didn't take effect at all" How did you check this? How are your C program and the shell command mount related? Did you execve() from the C program to the shell?
    – Hauke Laging
    May 18 at 22:44











  • This writing and reading was done within the C program?
    – Hauke Laging
    May 18 at 22:50










  • No, the writing was done by vi, before any mount operations, and reading was done by cat from within the bash script
    – Ben S.
    May 18 at 22:59















commands executed as the root user, right?
– A.B
May 18 at 21:31




commands executed as the root user, right?
– A.B
May 18 at 21:31












Yes, that's right
– Ben S.
May 18 at 22:39




Yes, that's right
– Ben S.
May 18 at 22:39












"But this didn't work as the mount didn't take effect at all" How did you check this? How are your C program and the shell command mount related? Did you execve() from the C program to the shell?
– Hauke Laging
May 18 at 22:44





"But this didn't work as the mount didn't take effect at all" How did you check this? How are your C program and the shell command mount related? Did you execve() from the C program to the shell?
– Hauke Laging
May 18 at 22:44













This writing and reading was done within the C program?
– Hauke Laging
May 18 at 22:50




This writing and reading was done within the C program?
– Hauke Laging
May 18 at 22:50












No, the writing was done by vi, before any mount operations, and reading was done by cat from within the bash script
– Ben S.
May 18 at 22:59




No, the writing was done by vi, before any mount operations, and reading was done by cat from within the bash script
– Ben S.
May 18 at 22:59










2 Answers
2






active

oldest

votes

















up vote
1
down vote



accepted










A shell-only solution would be:



For interactive shell:



# unshare --mount
# mount --bind /MyDir/MySubDir/b /MyDir/a
#


non-interactively, before a script that doesn't have to know about these settings:



# unshare --mount sh -c 'mount --bind /MyDir/MySubDir/b /MyDir/a; exec somethingelse'


The unshare manpage also warns about shared subtree mounts . If you have to disable them, consider adding for example --make-private to mount.



As Hauke told, you have to be sure to not leave the namespace just after having created it, because it will disappear.



If needed there's a method to maintain a namespace without process. Since it involves mount, it's just a bit more tricky for a mount namespace. Here's an interactive example for this:



shell1# unshare --mount
shell1# echo $$
12345
shell1#

shell2# : > /root/mntreference
shell2# mount --bind /proc/12345/ns/mnt /root/mntreference


Now as long as this reference is kept mounted, the namespace won't disappear even if there's no process using it anymore. Using nsenter --mount=/root/mntreference will enter it, so you can easily run additional scripts in it.



Using the equivalent in C shouldn't be a problem.






share|improve this answer























  • No need to use exec with unshare: unshare --mount bash is enough. Then the mount --bind can simply be done in the shell.
    – Hauke Laging
    May 19 at 9:21










  • Indeed, that was for a "one liner". I removed exec where useless (kept one exec, no need to have an useless sh staying around)
    – A.B
    May 19 at 11:39

















up vote
1
down vote













Unfortunately you still haven't explained how the C program and the script are related.



A possible (and here probable) reason for the problem is: You call the C program from the script but the namespace change is effective only within the C program (and possible children). After that program exists the situation is unchanged for all following commands.



You should start a shell from the C program by calling execve() for the intended shell.






share|improve this answer





















  • The C program is indeed called from within the script. Now I understand why it didn't work.
    – Ben S.
    May 18 at 23:48










Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f444683%2fmaking-a-bind-mount-take-effect-only-in-the-context-of-the-current-process-and-i%23new-answer', 'question_page');

);

Post as a guest






























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote



accepted










A shell-only solution would be:



For interactive shell:



# unshare --mount
# mount --bind /MyDir/MySubDir/b /MyDir/a
#


non-interactively, before a script that doesn't have to know about these settings:



# unshare --mount sh -c 'mount --bind /MyDir/MySubDir/b /MyDir/a; exec somethingelse'


The unshare manpage also warns about shared subtree mounts . If you have to disable them, consider adding for example --make-private to mount.



As Hauke told, you have to be sure to not leave the namespace just after having created it, because it will disappear.



If needed there's a method to maintain a namespace without process. Since it involves mount, it's just a bit more tricky for a mount namespace. Here's an interactive example for this:



shell1# unshare --mount
shell1# echo $$
12345
shell1#

shell2# : > /root/mntreference
shell2# mount --bind /proc/12345/ns/mnt /root/mntreference


Now as long as this reference is kept mounted, the namespace won't disappear even if there's no process using it anymore. Using nsenter --mount=/root/mntreference will enter it, so you can easily run additional scripts in it.



Using the equivalent in C shouldn't be a problem.






share|improve this answer























  • No need to use exec with unshare: unshare --mount bash is enough. Then the mount --bind can simply be done in the shell.
    – Hauke Laging
    May 19 at 9:21










  • Indeed, that was for a "one liner". I removed exec where useless (kept one exec, no need to have an useless sh staying around)
    – A.B
    May 19 at 11:39














up vote
1
down vote



accepted










A shell-only solution would be:



For interactive shell:



# unshare --mount
# mount --bind /MyDir/MySubDir/b /MyDir/a
#


non-interactively, before a script that doesn't have to know about these settings:



# unshare --mount sh -c 'mount --bind /MyDir/MySubDir/b /MyDir/a; exec somethingelse'


The unshare manpage also warns about shared subtree mounts . If you have to disable them, consider adding for example --make-private to mount.



As Hauke told, you have to be sure to not leave the namespace just after having created it, because it will disappear.



If needed there's a method to maintain a namespace without process. Since it involves mount, it's just a bit more tricky for a mount namespace. Here's an interactive example for this:



shell1# unshare --mount
shell1# echo $$
12345
shell1#

shell2# : > /root/mntreference
shell2# mount --bind /proc/12345/ns/mnt /root/mntreference


Now as long as this reference is kept mounted, the namespace won't disappear even if there's no process using it anymore. Using nsenter --mount=/root/mntreference will enter it, so you can easily run additional scripts in it.



Using the equivalent in C shouldn't be a problem.






share|improve this answer























  • No need to use exec with unshare: unshare --mount bash is enough. Then the mount --bind can simply be done in the shell.
    – Hauke Laging
    May 19 at 9:21










  • Indeed, that was for a "one liner". I removed exec where useless (kept one exec, no need to have an useless sh staying around)
    – A.B
    May 19 at 11:39












up vote
1
down vote



accepted







up vote
1
down vote



accepted






A shell-only solution would be:



For interactive shell:



# unshare --mount
# mount --bind /MyDir/MySubDir/b /MyDir/a
#


non-interactively, before a script that doesn't have to know about these settings:



# unshare --mount sh -c 'mount --bind /MyDir/MySubDir/b /MyDir/a; exec somethingelse'


The unshare manpage also warns about shared subtree mounts . If you have to disable them, consider adding for example --make-private to mount.



As Hauke told, you have to be sure to not leave the namespace just after having created it, because it will disappear.



If needed there's a method to maintain a namespace without process. Since it involves mount, it's just a bit more tricky for a mount namespace. Here's an interactive example for this:



shell1# unshare --mount
shell1# echo $$
12345
shell1#

shell2# : > /root/mntreference
shell2# mount --bind /proc/12345/ns/mnt /root/mntreference


Now as long as this reference is kept mounted, the namespace won't disappear even if there's no process using it anymore. Using nsenter --mount=/root/mntreference will enter it, so you can easily run additional scripts in it.



Using the equivalent in C shouldn't be a problem.






share|improve this answer















A shell-only solution would be:



For interactive shell:



# unshare --mount
# mount --bind /MyDir/MySubDir/b /MyDir/a
#


non-interactively, before a script that doesn't have to know about these settings:



# unshare --mount sh -c 'mount --bind /MyDir/MySubDir/b /MyDir/a; exec somethingelse'


The unshare manpage also warns about shared subtree mounts . If you have to disable them, consider adding for example --make-private to mount.



As Hauke told, you have to be sure to not leave the namespace just after having created it, because it will disappear.



If needed there's a method to maintain a namespace without process. Since it involves mount, it's just a bit more tricky for a mount namespace. Here's an interactive example for this:



shell1# unshare --mount
shell1# echo $$
12345
shell1#

shell2# : > /root/mntreference
shell2# mount --bind /proc/12345/ns/mnt /root/mntreference


Now as long as this reference is kept mounted, the namespace won't disappear even if there's no process using it anymore. Using nsenter --mount=/root/mntreference will enter it, so you can easily run additional scripts in it.



Using the equivalent in C shouldn't be a problem.







share|improve this answer















share|improve this answer



share|improve this answer








edited May 19 at 11:36


























answered May 19 at 0:07









A.B

2,4901315




2,4901315











  • No need to use exec with unshare: unshare --mount bash is enough. Then the mount --bind can simply be done in the shell.
    – Hauke Laging
    May 19 at 9:21










  • Indeed, that was for a "one liner". I removed exec where useless (kept one exec, no need to have an useless sh staying around)
    – A.B
    May 19 at 11:39
















  • No need to use exec with unshare: unshare --mount bash is enough. Then the mount --bind can simply be done in the shell.
    – Hauke Laging
    May 19 at 9:21










  • Indeed, that was for a "one liner". I removed exec where useless (kept one exec, no need to have an useless sh staying around)
    – A.B
    May 19 at 11:39















No need to use exec with unshare: unshare --mount bash is enough. Then the mount --bind can simply be done in the shell.
– Hauke Laging
May 19 at 9:21




No need to use exec with unshare: unshare --mount bash is enough. Then the mount --bind can simply be done in the shell.
– Hauke Laging
May 19 at 9:21












Indeed, that was for a "one liner". I removed exec where useless (kept one exec, no need to have an useless sh staying around)
– A.B
May 19 at 11:39




Indeed, that was for a "one liner". I removed exec where useless (kept one exec, no need to have an useless sh staying around)
– A.B
May 19 at 11:39












up vote
1
down vote













Unfortunately you still haven't explained how the C program and the script are related.



A possible (and here probable) reason for the problem is: You call the C program from the script but the namespace change is effective only within the C program (and possible children). After that program exists the situation is unchanged for all following commands.



You should start a shell from the C program by calling execve() for the intended shell.






share|improve this answer





















  • The C program is indeed called from within the script. Now I understand why it didn't work.
    – Ben S.
    May 18 at 23:48














up vote
1
down vote













Unfortunately you still haven't explained how the C program and the script are related.



A possible (and here probable) reason for the problem is: You call the C program from the script but the namespace change is effective only within the C program (and possible children). After that program exists the situation is unchanged for all following commands.



You should start a shell from the C program by calling execve() for the intended shell.






share|improve this answer





















  • The C program is indeed called from within the script. Now I understand why it didn't work.
    – Ben S.
    May 18 at 23:48












up vote
1
down vote










up vote
1
down vote









Unfortunately you still haven't explained how the C program and the script are related.



A possible (and here probable) reason for the problem is: You call the C program from the script but the namespace change is effective only within the C program (and possible children). After that program exists the situation is unchanged for all following commands.



You should start a shell from the C program by calling execve() for the intended shell.






share|improve this answer













Unfortunately you still haven't explained how the C program and the script are related.



A possible (and here probable) reason for the problem is: You call the C program from the script but the namespace change is effective only within the C program (and possible children). After that program exists the situation is unchanged for all following commands.



You should start a shell from the C program by calling execve() for the intended shell.







share|improve this answer













share|improve this answer



share|improve this answer











answered May 18 at 23:06









Hauke Laging

53.1k1282130




53.1k1282130











  • The C program is indeed called from within the script. Now I understand why it didn't work.
    – Ben S.
    May 18 at 23:48
















  • The C program is indeed called from within the script. Now I understand why it didn't work.
    – Ben S.
    May 18 at 23:48















The C program is indeed called from within the script. Now I understand why it didn't work.
– Ben S.
May 18 at 23:48




The C program is indeed called from within the script. Now I understand why it didn't work.
– Ben S.
May 18 at 23:48












 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f444683%2fmaking-a-bind-mount-take-effect-only-in-the-context-of-the-current-process-and-i%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Peggy Mitchell

The Forum (Inglewood, California)

Palaiologos