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

Clash 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!
chroot fork bind-mount unshare
add a comment |Â
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!
chroot fork bind-mount unshare
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 commandmountrelated? Did youexecve()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
add a comment |Â
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!
chroot fork bind-mount unshare
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!
chroot fork bind-mount unshare
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 commandmountrelated? Did youexecve()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
add a comment |Â
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 commandmountrelated? Did youexecve()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
add a comment |Â
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.
No need to useexecwithunshare:unshare --mount bashis enough. Then themount --bindcan 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
add a comment |Â
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.
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
add a comment |Â
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.
No need to useexecwithunshare:unshare --mount bashis enough. Then themount --bindcan 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
add a comment |Â
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.
No need to useexecwithunshare:unshare --mount bashis enough. Then themount --bindcan 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
add a comment |Â
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.
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.
edited May 19 at 11:36
answered May 19 at 0:07
A.B
2,4901315
2,4901315
No need to useexecwithunshare:unshare --mount bashis enough. Then themount --bindcan 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
add a comment |Â
No need to useexecwithunshare:unshare --mount bashis enough. Then themount --bindcan 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
add a comment |Â
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.
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
add a comment |Â
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.
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
add a comment |Â
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.
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.
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
add a comment |Â
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
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
mountrelated? Did youexecve()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