kernel: chroot, #! scripts, rename and mmap as apk needs them
Found by running Alpine's apk on SchOS, one failure at a time: - chroot(2) was a stub returning EPERM. Each process now has a root: where an absolute path starts and where .. stops. Mounts remember whose root they were made under, and a walk leaves a mount by the way it came in, so one filesystem can be mounted twice. - devtmpfs and proc mounted only on /dev and /proc, whatever the target; a chroot got "already mounted". - mmap never reused freed address space, so musl's malloc used up the 256 mapping records while 780 MB were free. A mergeable mapping now goes straight after an anonymous one whose end has room. - unlinkat returned -1 (EPERM) where apk expects ENOENT, and renameat was an old copy of rename: no replacing the target, and v1 dirents written into SchFS. Both now share rename's implementation. - execve runs #! scripts, and says ENOEXEC for what it cannot run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
6f3175d8a5
commit
2cfa3f0bf2
9 changed files with 361 additions and 129 deletions
|
|
@ -318,18 +318,19 @@ const struct fs_ops devfs_ops = {
|
|||
.getdents = devfs_getdents,
|
||||
};
|
||||
|
||||
// Graft it over /dev. Called by init, which has made the directory.
|
||||
void
|
||||
devfs_mount(void)
|
||||
// Graft it over `target` -- /dev from init, and again wherever a chroot
|
||||
// wants one. It was always /dev whatever was asked for, so a second mount
|
||||
// failed as "already mounted" and a chroot had no devices.
|
||||
int
|
||||
devfs_mount(const char *target)
|
||||
{
|
||||
struct inode *dp = namei("/dev");
|
||||
struct inode *dp = namei((char *)target);
|
||||
int r;
|
||||
|
||||
if (dp == 0) {
|
||||
cprintf("devfs: /dev does not exist; not mounted\n");
|
||||
return;
|
||||
}
|
||||
if (mount_add(dp->dev, dp->inum, DEVFS_DEV, DEVFS_ROOT, "/dev", "dev",
|
||||
"devtmpfs") < 0)
|
||||
cprintf("devfs: /dev already has something mounted on it\n");
|
||||
if (dp == 0)
|
||||
return -ENOENT;
|
||||
r = mount_add(dp->dev, dp->inum, DEVFS_DEV, DEVFS_ROOT, (char *)target, "dev",
|
||||
"devtmpfs");
|
||||
iput(dp);
|
||||
return r < 0 ? -EBUSY : 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue