Какой код Предотвращает ложки пространства имен монтирования? В более сложном случае, связанное с распространением монтажа

Вы говорите -F, , но (согласно вашему комментарию) ваши данные разделены пробелами, не запятые. Вот что видит [n] awk

Line 1:   $1="100 150"   $2=""
Line 2:   $1="200 250"   $2=""

Когда вы используете их в арифметическом выражении, awk преобразует их в

Line 1:   $1=100        $2=0
Line 2:   $1=200        $2=0

, и вы получаете деление на 0. Просто оставьте выключите -F, (или измените данные, чтобы они были разделены запятыми) , и вы должны получить желаемый результат. Ну почти; в моей системе я получаю 66.6667 и 80 . Вам просто нужно округлить результат до ближайшего целого числа (если это действительно то, что вы хотите).

2
07.10.2018, 20:51
1 ответ

См. коммит 4ce5d2b1a8fd, vfs :Не копировать привязки монтирования /proc/<pid>/ns/mntмежду пространствами имен

propagate_one()вызывает copy_tree()без CL_COPY_MNT_NS_FILE. В этом случае, если корень дерева является монтированием NS-файла, copy_tree()завершается с ошибкой EINVAL. Термин "файл NS" означает один из файлов /proc/*/ns/mnt.

Читая дальше, я замечаю, что если корень дерева не является NS-файлом, но одним из дочерних монтирований является, он исключается из распространения (точно так же, как и несвязываемое монтирование ).

Пример NS-файла, который автоматически пропускается во время распространения

# mount --make-shared /tmp
# cd /tmp
# mkdir private_mnt
# mount --bind private_mnt private_mnt
# mount --make-private private_mnt
# touch private_mnt/child_ns
# unshare --mount=private_mnt/child_ns --propagation=shared ls -l /proc/self/ns/mnt
lrwxrwxrwx. 1 root root 0 Oct  7 18:25 /proc/self/ns/mnt -> 'mnt:[4026532807]'
# findmnt | grep /tmp
├─/tmp                                tmpfs                             tmpfs          ...
│ ├─/tmp/private_mnt                  tmpfs[/private_mnt]               tmpfs          ...
│ │ └─/tmp/private_mnt/child_ns       nsfs[mnt:[4026532807]]            nsfs           ...

Создадим нормальное крепление для сравнения

# mkdir private_mnt/child_mnt
# mount --bind private_mnt/child_mnt private_mnt/child_mnt

Теперь попробуйте распространить все. (Создайте рекурсивное монтирование private_mntвнутри /tmp. /tmpявляется общим креплением ).

# mkdir shared_mnt
# mount --rbind private_mnt shared_mnt
# findmnt | grep /tmp/shared_mnt
│ └─/tmp/shared_mnt                   tmpfs[/private_mnt]               tmpfs          ...
│   ├─/tmp/shared_mnt/child_ns        nsfs[mnt:[4026532809]]            nsfs           ...
│   └─/tmp/shared_mnt/child_mnt       tmpfs[/private_mnt/child_mnt]     tmpfs          ...
# nsenter --mount=/tmp/private_mnt/child_ns findmnt|grep /tmp/shared_mnt
│ └─/tmp/shared_mnt                   tmpfs[/private_mnt]               tmpfs          ...
│   └─/tmp/shared_mnt/child_mnt       tmpfs[/private_mnt/child_mnt]     tmpfs          ...

Код ядра

Вот выдержки из текущей версии кода, который был добавлен в фиксацию, указанную выше.

https://elixir.bootlin.com/linux/v4.18/source/fs/pnode.c#L226

static int propagate_one(struct mount *m)
{
...
    /* Notice when we are propagating across user namespaces */
    if (m->mnt_ns->user_ns != user_ns)
        type |= CL_UNPRIVILEGED;
    child = copy_tree(last_source, last_source->mnt.mnt_root, type);
    if (IS_ERR(child))
        return PTR_ERR(child);

https://elixir.bootlin.com/linux/v4.18/source/fs/namespace.c#L1790

struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
                    int flag)
{
    struct mount *res, *p, *q, *r, *parent;

    if (!(flag & CL_COPY_UNBINDABLE) && IS_MNT_UNBINDABLE(mnt))
        return ERR_PTR(-EINVAL);

    if (!(flag & CL_COPY_MNT_NS_FILE) && is_mnt_ns_file(dentry))
        return ERR_PTR(-EINVAL);
1
27.01.2020, 22:29

Теги

Похожие вопросы