Насколько эффективна виртуальная файловая система procfs и можно ли ее оптимизировать

    Файловая система proc (в дальнейшем просто procfs) является виртуальной файловой системой, которая предоставляет информацию о процессах. Она — “прекрасный” пример интерфейсов следующих парадигме “все является файлом”. Procfs была разработана очень давно: во времена, когда серверы в среднем обслуживали несколько десятков процессов, когда открыть файл и вычитать информацию о процессе не было проблемой. Однако время не стоит на месте, и сейчас серверы обслуживают сотни тысяч, а то и больше процессов одновременно. В таком контексте идея “открыть файл для каждого процесса, чтобы вычитать интересующие данные” уже не выглядит такой привлекательной, и первое что приходит на ум чтобы ускорить чтение — это получение информации о группе процессов за одну итерацию. В этой статье мы попробуем найти элементы procfs которые можно оптимизировать.


    image


    Сама мысль улучшить procfs возникла когда мы обнаружили, что CRIU тратит значительное количество времени просто читая procfs файлы. Мы видели как подобная проблема была решена для сокетов, и решили сделать что-то похожее на sock-diag интерфейс, но только для procfs. Конечно мы предполагали, насколько сложно будет поменять давнишний и вполне устоявшийся интерфейс в ядре, убедить сообщество, что игра стоит свеч… и были приятно удивлены количеством людей, которые поддержали создание нового интерфейса. Строго говоря, никто не знал, как должен выглядеть новый интерфейс, но сомнений в том, что procfs не удовлетворяет текущим требованиям по производительности нет. Например такой сценарий: сервер отвечает на запросы слишком долго, vmstat показывает, что память ушла в своп, а запуск “ps ax” выполняется от 10 секунд и более, top и вовсе ничего не показывает. В этой статье мы не будем рассматривать какой-то конкретный новый интерфейс, скорее попробуем описать проблемы и пути их решения.


    Каждый исполняющийся процесс procfs представляет директорией /proc/<pid>.
    В каждой такой директории множество файлов и поддиректорий, которые предоставляют доступ к определенной информации о процессе. Поддиректории группируют данные по признакам. Например ($$ это специальная переменная оболочки, которая раскрывается в pid — идентификатор текущего процесса):


    $ ls -F /proc/$$
    attr/            exe@        mounts         projid_map    status
    autogroup        fd/         mountstats     root@         syscall
    auxv             fdinfo/     net/           sched         task/
    cgroup           gid_map     ns/            schedstat     timers
    clear_refs       io          numa_maps      sessionid     timerslack_ns
    cmdline          limits      oom_adj        setgroups     uid_map
    comm             loginuid    oom_score      smaps         wchan
    coredump_filter  map_files/  oom_score_adj  smaps_rollup
    cpuset           maps        pagemap        stack
    cwd@             mem         patch_state    stat
    environ          mountinfo   personality    statm

    Все эти файлы выдают данные в разных форматах. Большинство в формате ASCII текста, который легко воспринимается человеком. Ну почти легко:


    $ cat /proc/$$/stat
    24293 (bash) S 21811 24293 24293 34854 24876 4210688 6325 19702 0 10 15 7 33 35 20 0 1 0 47892016 135487488 3388 18446744073709551615 94447405350912 94447406416132 140729719486816 0 0 0 65536 3670020 1266777851 1 0 0 17 2 0 0 0 0 0 94447408516528 94447408563556 94447429677056 140729719494655 140729719494660 140729719494660 140729719496686 0

    Чтобы понять, что значит каждый элемент этого множества, читателю придется открыть man proc(5), либо документацию ядра. Например, второй элемент — это имя исполняемого файла в скобках, а девятнадцатый элемент — это текущее значение приоритета исполнения (nice).


    Некоторые файлы вполне читабельны сами по себе:


    $ cat /proc/$$/status | head -n 5
    Name:   bash
    Umask:  0002
    State:  S (sleeping)
    Tgid:   24293
    Ngid:   0

    Но как часто пользователи читают информацию напрямую из файлов procfs? Сколько времени нужно ядру чтобы перевести бинарные данные в текстовый формат? Какие накладные расходы у procfs? Насколько удобен такой интерфейс для программ мониторов состояния, и сколько времени они тратят чтобы обработать эти текстовые данные? Насколько критична такая медленная реализация в аварийных ситуациях?


    Скорее всего, не будет ошибкой сказать, что пользователи предпочитают программы типа top или ps, вместо того, чтобы читать данные из procfs напрямую.


    Для ответа на остальные вопросы проведем несколько экспериментов. Во-первых, найдем где именно ядро тратит время, чтобы сгенерировать файлы procfs.


    Чтобы получить определенную информацию у всех процессов в системе, нам придется пройти по директории /proc/ и выбрать все поддиректории, имя которых представлено десятичными цифрами. Затем, в каждой из них, нам необходимо открыть файл, прочитать его и закрыть.


    Суммарно мы исполним три системных вызова, причем один из них создаст файловый дескриптор (в ядре файловый дескриптор ассоциируется с набором внутренних объектов, для которых выделяется дополнительная память). Системные вызовы open() и close() сами по себе не дают нам никакой информации, так что их можно отнести к накладным расходам интерфейса procfs.


    Попробуем просто сделать open() и close() для каждого процесса в системе, но не будем читать содержимое файлов:


    $ time ./task_proc_all --noread stat
    tasks: 50290
    
    real    0m0.177s
    user    0m0.012s
    sys 0m0.162s

    $ time ./task_proc_all --noread loginuid
    tasks: 50289
    
    real    0m0.176s
    user    0m0.026s
    sys 0m0.145

    task-proc-all — небольшая утилита, с кодом которой можно ознакомится по ссылке снизу


    Неважно какой именно файл открыть, поскольку реальные данные генерируются только в момент read().


    А теперь посмотрим на вывод профилировщика ядра perf:


    -   92.18%     0.00%  task_proc_all    [unknown]
       - 0x8000
          - 64.01% __GI___libc_open
             - 50.71% entry_SYSCALL_64_fastpath
                - do_sys_open
                   - 48.63% do_filp_open
                      - path_openat
                         - 19.60% link_path_walk
                            - 14.23% walk_component
                               - 13.87% lookup_fast
                                  - 7.55% pid_revalidate
                                       4.13% get_pid_task
                                     + 1.58% security_task_to_inode
                                       1.10% task_dump_owner
                                    3.63% __d_lookup_rcu
                            + 3.42% security_inode_permission
                         + 14.76% proc_pident_lookup
                         + 4.39% d_alloc_parallel
                         + 2.93% get_empty_filp
                         + 2.43% lookup_fast
                         + 0.98% do_dentry_open
               2.07% syscall_return_via_sysret
               1.60% 0xfffffe000008a01b
               0.97% kmem_cache_alloc
               0.61% 0xfffffe000008a01e
          - 16.45% __getdents64
             - 15.11% entry_SYSCALL_64_fastpath
                  sys_getdents
                  iterate_dir
                - proc_pid_readdir
                   - 7.18% proc_fill_cache
                      + 3.53% d_lookup
                        1.59% filldir
                   + 6.82% next_tgid
                   + 0.61% snprintf
          - 9.89% __close
             + 4.03% entry_SYSCALL_64_fastpath
               0.98% syscall_return_via_sysret
               0.85% 0xfffffe000008a01b
               0.61% 0xfffffe000008a01e
            1.10% syscall_return_via_sysret

    Ядро тратит почти 75% времени просто чтобы создать и удалить файловый дескриптор, и около 16% чтобы вывести список процессов.


    Хотя мы и знаем сколько времени нужно на вызовы open() и close() для каждого процесса, мы пока не можем оценить насколько оно значительно. Нам надо сравнить полученные величины с чем-то. Попробуем сделать тоже самое с наиболее известными файлами. Обычно, когда надо вывести список процессов, используется утилита ps или top. Они обе читают /proc/<pid>/stat и /proc/<pid>/status для каждого процесса в системе.


    Начнем с /proc/<pid>/status — это массивный файл с фиксированным количеством полей:


    $ time ./task_proc_all status
    tasks: 50283
    
    real    0m0.455s
    user    0m0.033s
    sys 0m0.417s

    -   93.84%     0.00%  task_proc_all    [unknown]                   [k] 0x0000000000008000
       - 0x8000
          - 61.20% read
             - 53.06% entry_SYSCALL_64_fastpath
                - sys_read
                   - 52.80% vfs_read
                      - 52.22% __vfs_read
                         - seq_read
                            - 50.43% proc_single_show
                               - 50.38% proc_pid_status
                                  - 11.34% task_mem
                                     + seq_printf
                                  + 6.99% seq_printf
                                  - 5.77% seq_put_decimal_ull
                                       1.94% strlen
                                     + 1.42% num_to_str
                                  - 5.73% cpuset_task_status_allowed
                                     + seq_printf
                                  - 5.37% render_cap_t
                                     + 5.31% seq_printf
                                  - 5.25% render_sigset_t
                                       0.84% seq_putc
                                    0.73% __task_pid_nr_ns
                                  + 0.63% __lock_task_sighand
                                    0.53% hugetlb_report_usage
                            + 0.68% _copy_to_user
               1.10% number
               1.05% seq_put_decimal_ull
               0.84% vsnprintf
               0.79% format_decode
               0.73% syscall_return_via_sysret
               0.52% 0xfffffe000003201b
          + 20.95% __GI___libc_open
          + 6.44% __getdents64
          + 4.10% __close

    Видно, что только около 60% времени потрачено внутри системного вызова read(). Если же посмотреть профиль более внимательно, то обнаруживается, что 45% времени использовано внутри функций ядра seq_printf, seq_put_decimal_ull. А значит, конвертирование из бинарного формата в текстовый достаточно затратная операция. Что вызывает вполне обоснованный вопрос: а действительно ли нам нужен текстовый интерфейс, чтобы вытащить данные из ядра? Как часто пользователи хотят работать с сырыми данными? И почему утилитам top и ps приходится конвертировать эти текстовые данные обратно в бинарный вид?


    Наверное, интересно было бы узнать, насколько быстрее был бы вывод, если бы использовались бинарные данные напрямую, и если бы не требовалось три системных вызова.


    Попытки создать такой интерфейс уже были. В 2004 пробовали использовать netlink движок.


    [0/2][ANNOUNCE] nproc: netlink access to /proc information (https://lwn.net/Articles/99600/)
    
    nproc is an attempt to address the current problems with /proc. In
    short, it exposes the same information via netlink (implemented for a
    small subset).

    К сожалению, сообщество не проявило большого интереса к этой работе. Одна из последних попыток исправить ситуацию произошла два года назад.


    [PATCH 0/15] task_diag: add a new interface to get information about processes (https://lwn.net/Articles/683371/)

    Интерфейс task-diag базируется на следующих принципах:


    • Транзакционность: отправил запрос, получил ответ;
    • Формат сообщений в виде netlink (такой же как у sock_diag интерфейса: бинарный и расширяемый);
    • Возможность запросить информацию о множестве процессов в одном вызове;
    • Оптимизированная группировка атрибутов (любой атрибут в группе не должен увеличивать время ответа).

    Этот интерфейс был презентован на нескольких конференциях. Его интегрировали в утилиты pstools, CRIU, а также David Ahern интегрировал task_diag в perf, в качестве эксперимента.


    Сообщество разработчиков ядра заинтересовалось интерфейсом task_diag. Основным предметом обсуждений стал выбор транспорта между ядром и пространством пользователя. Начальная идея использования netlink сокетов была отклонена. Частично из-за нерешенных проблем в коде самого netlink движка, а частично потому, что многие думают, что интерфейс netlink был разработан исключительно для сетевой подсистемы. Потом было предложено использовать транзакционные файлы внутри procfs, то есть пользователь открывает файл, записывает в него сам запрос, а затем просто читает ответ. Как обычно, оказались и противники данного подхода. Решения, которое понравилось бы всем, пока не найдено.


    Давайте сравним производительность task_diag с procfs.


    У task_diag движка есть тестовая утилита, которая удачно подходит для наших экспериментов. Предположим, что мы хотим запросить идентификаторы процесса и его права. Ниже приведен вывод для одного процесса:


    $ ./task_diag_all one  -c -p $$
    pid  2305 tgid  2305 ppid  2299 sid  2305 pgid  2305 comm bash
    uid: 1000 1000 1000 1000
    gid: 1000 1000 1000 1000
    CapInh: 0000000000000000
    CapPrm: 0000000000000000
    CapEff: 0000000000000000
    CapBnd: 0000003fffffffff

    А теперь для всех процессов в системе, то есть тоже самое, что мы делали для эксперимента с procfs, когда читали файл /proc/pid/status:


    $ time ./task_diag_all all  -c
    
    real    0m0.048s
    user    0m0.001s
    sys 0m0.046s

    Всего лишь 0.05 секунды потребовалось, чтобы получить данные для построения дерева процессов. А с procfs требовалось 0.177 секунды только на открытие одного файла для каждого процесса, причем без чтения данных.


    Вывод perf для task_diag интерфейса:


    -   82.24%     0.00%  task_diag_all  [kernel.vmlinux]            [k] entry_SYSCALL_64_fastpath
       - entry_SYSCALL_64_fastpath
          - 81.84% sys_read
               vfs_read
               __vfs_read
               proc_reg_read
               task_diag_read
             - taskdiag_dumpit
                + 33.84% next_tgid
                  13.06% __task_pid_nr_ns
                + 6.63% ptrace_may_access
                + 5.68% from_kuid_munged
                - 4.19% __get_task_comm
                     2.90% strncpy
                     1.29% _raw_spin_lock
                  3.03% __nla_reserve
                  1.73% nla_reserve
                + 1.30% skb_copy_datagram_iter
                + 1.21% from_kgid_munged
                  1.12% strncpy   

    В самом листинге нет ничего интересного, кроме факта, что здесь нет очевидных функций, подходящих для оптимизации.


    Посмотрим на вывод perf при чтении информации обо всех процессах в системе:


     $ perf trace -s ./task_diag_all all -c  -q
    
     Summary of events:
    
     task_diag_all (54326), 185 events, 95.4%
    
       syscall            calls    total       min       avg       max      stddev
                                   (msec)    (msec)    (msec)    (msec)        (%)
       --------------- -------- --------- --------- --------- ---------     ------
       read                  49    40.209     0.002     0.821     4.126      9.50%
       mmap                  11     0.051     0.003     0.005     0.007      9.94%
       mprotect               8     0.047     0.003     0.006     0.009     10.42%
       openat                 5     0.042     0.005     0.008     0.020     34.86%
       munmap                 1     0.014     0.014     0.014     0.014      0.00%
       fstat                  4     0.006     0.001     0.002     0.002     10.47%
       access                 1     0.006     0.006     0.006     0.006      0.00%
       close                  4     0.004     0.001     0.001     0.001      2.11%
       write                  1     0.003     0.003     0.003     0.003      0.00%
       rt_sigaction           2     0.003     0.001     0.001     0.002     15.43%
       brk                    1     0.002     0.002     0.002     0.002      0.00%
       prlimit64              1     0.001     0.001     0.001     0.001      0.00%
       arch_prctl             1     0.001     0.001     0.001     0.001      0.00%
       rt_sigprocmask         1     0.001     0.001     0.001     0.001      0.00%
       set_robust_list        1     0.001     0.001     0.001     0.001      0.00%
       set_tid_address        1     0.001     0.001     0.001     0.001      0.00%

    Для procfs нам нужно выполнить более 150000 системных вызовов, чтобы вытащить информацию о всех процессах, а для task_diag — чуть более 50.


    Посмотрим на реальные ситуации из жизни. Например, мы хотим вывести дерево процессов вместе с аргументами командной строки для каждого. Для этого нам необходимо вытащить pid процесса, pid его родителя и непосредственно сами аргументы командной строки.


    Для интерфейса task_diag программа отправляет один запрос, чтобы получить все параметры разом:


    $ time ./task_diag_all all  --cmdline -q
    
    real    0m0.096s
    user    0m0.006s
    sys 0m0.090s

    Для оригинального procfs нам необходимо читать /proc//status and /proc//cmdline у каждого процесса:

    $ time ./task_proc_all status
    tasks: 50278
    
    real    0m0.463s
    user    0m0.030s
    sys 0m0.427s

    $ time ./task_proc_all cmdline
    tasks: 50281
    
    real    0m0.270s
    user    0m0.028s
    sys 0m0.237s

    Нетрудно заметить, что task_diag в 7 раз быстрее procfs (0.096 против 0.27 + 0.46). Обычно улучшение производительности на несколько процентов уже хороший результат, а тут скорость увеличилась почти на порядок.


    Стоит также упомянуть, что создание внутренних объектов ядра тоже сильно влияет на производительность. Особенно в случае, когда подсистема памяти под сильной нагрузкой. Сравним количество созданных объектов для procfs и task_diag:


    $ perf trace --event 'kmem:*alloc*'  ./task_proc_all status 2>&1 | grep kmem | wc -l
    58184
    $ perf trace --event 'kmem:*alloc*'  ./task_diag_all all -q 2>&1 | grep kmem | wc -l
    188

    А также надо выяснить сколько создается объектов при запуске простого процесса, например утилиты true:


    $ perf trace --event 'kmem:*alloc*'  true 2>&1 | wc -l
    94

    Procfs создает в 600 раз больше объектов, чем task_diag. Это одна из причин, почему procfs работает так плохо, когда сильная нагрузка по памяти. Хотя бы поэтому стоит ее оптимизировать.


    Надеемся, что статья привлечёт больше разработчиков к оптимизации состояния procfs подсистемы ядра.


    Огромная благодарность David Ahern, Andy Lutomirski, Stephen Hemming, Oleg Nesterov, W. Trevor King, Arnd Bergmann, Eric W. Biederman и многим другим, кто помогал разрабатывать и улучшать task_diag интерфейс.


    Спасибо cromer, k001 и Станиславу Кинсбурскому за помощь в написании этой статьи.


    Ссылки


    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

    Испытывали ли вы проблемы с procfs

    Virtuozzo
    37,00
    Разработчик ПО для контейнерной виртуализации
    Поделиться публикацией

    Похожие публикации

    Комментарии 18

      0
      Да видимо раньше когда ничего не работало все и лазили руками по /proc, сейчас конечно не нужден этот текстовый формат.
        +1

        С одной стороны стороны да, но вот как с помощью современных обёрток получить в шелл скрипте использованное процессом процессорное время с точностью хотя бы до сотой доли секунды без чтения /proc/$PID/stat? У меня сейчас это используется в самописном плагине для munin.

          –1
          Сейчас никак, но если в ядре появится что-то похожее на task-diag с бинарным форматом, то так же появится и пользовательская команда, которая будет выводить нужную для пользователя информацию с той же точностью, которую предоставляет ядро.
            –1
            Наверняка, вам в вашем плагине нужно получать cputime для всех процессов в системе. А теперь задумайтесь, сколько это займет времени, если это делать из шел скрипта.

            Я провел небольшой эксперимент. Запустил 10000 процессов и запустил следующую команду:

            # ps ax | wc -l
            10091

            # time for i in /proc/*/stat; do cat $i > /dev/null; done
            cat: /proc/net/stat: Is a directory

            real 0m21.923s
            user 0m2.326s
            sys 0m19.934s

            20 секунд на 50K процессов. Имхо, это очень много.
              +3

              Вы тут очень сильно передёргиваете. Во-первых, в ваших измерениях львиная доля времени тратится на порождение новых процессов, что для этой задачи просто не нужно. Если читать встроенными средствами шелла, то получается на порядок с лишним быстрее:


              $ time for i in /proc/*/stat; do cat $i >/dev/null ; done
              cat: /proc/net/stat: Is a directory
              
              real    0m0,373s
              user    0m0,238s
              sys 0m0,156s
              $ time for i in /proc/*/stat; do read STAT < $i; done
              -bash: read: read error: 0: Is a directory
              
              real    0m0,012s
              user    0m0,002s
              sys 0m0,011s

              Во-вторых, мне не нужно мониторить все процессы. Сейчас проверил — у меня мониторится 5 конкретных процессов. В этой ситуации при том, что мой плагин написан аккуратно и не делает лишних форков, тратится на сбор данных пренебрежимо мало времени, считанные миллисекунды.


              Не поймите неправильно. Я не считаю внедрение нового интерфейса вредным или ненужным — совсем наоборот! Я только приводил контраргумент к тезису "сейчас не бывает задач, для которых нужно читать напрямую из procfs".


              Впрочем, я сейчас осознал, что если старый текстовый интерфейс будет выпилен и мой скрипт будет вынужден получать данные из внешней утилиты, то за счёт лишнего форка он станет капельку медленнее, что грустно.

                0
                Да, с шельным скриптом я не додумал, точне я забыл про команду read. Тут вы правы, можно сделать быстрее.

                Про то что ваш скрипт станет немного медленнее из-за лишнего форка, тут вы просто свой скрипт перепишите на python или любом другом языке, который сможет напрямую работать с новым интерфейсом и все будет хорошо.
                  +2
                  Дело вовсе не в том, насколько баш-скрипт будет «быстрее» или «медленнее».

                  Дело в том, что bash/grep/sed/awk и 5 минут вашего ЦЕННОГО времени — и задача чего-то там выщемить/отмониторить решена. Прямо тут, прямо сейчас. В 98% на этом можно остановится — ибо задача решена. Если по ходу видно, что надо бы сэкономить ресурсов — можно думать дальше.
                    –2
                    Во-первых, текущий /proc еще долго никуда не денется, обратную совместимость никто ломать не даст. Даже если его когда-то решат выкинуть из ядра, то появится fuse файловая система, которая будет выглядеть как /proc.
                    Во-вторых, если вы говорите про grep, sed, awk и тп, то вы уже готовы запускать дополнительные процессы, а значит сможете запустить и дополнительную тулзу, которая выдаст вам нужные данные, полученные через новый интерфейс.
                    В-третьих, если мы идем чуть дальше и вместо shell начинаем использовать что-то вроде python, то с новым интерфейсом вам жить будет даже проще.
                      +1
                      Во-первых, текущий /proc еще долго никуда не денется

                      Я вам только что доступно объяснил — почему.

                      мы идем чуть дальше

                      Несколько условно — идя в любимый барбершоп и дойдя до него, вы:

                      1. заходите вовнутрь

                      2. «идете чуть дальше» километра на полтора, затем возвращаетесь и уже тогда заходите вовнутрь

                      Вы предлагаете (2). Дело ваше — спорить не буду.

                      Как сухой остаток — те 2%, что остаются после 98%, тоже надо чем-то делать. И это хорошо, что инструмент и для этого тоже постепенно затачивают.
                        –1
                        > Я вам только что доступно объяснил — почему.

                        Смените тон и прочтите еще раз коментарий.

                        > Вы предлагаете (2). Дело ваше — спорить не буду.

                        В вашем примере, я как раз выбираю первый вариант. А второй вариант — это то как сейчас работает ps или top. Сначала ядро данные о процессах выдает в текстовом виде, потому утилита ps декодирует их к бинарному виду, обрабатывает и выдает в другом текстовом виде.
                  0

                  По поводу количества процессов. Если у вас речь идет о десятках процессов, то действительно проблем нет и с текущим интерфейсом.


                  Я все же предлагаю сравнить производительность task_diag и procfs для большого количества процессов.


                  Для эксперимента, я опять запустил 10000 процессов. Давайте теперь посмотрим сколько будет выполняться приведенный вами скрипт и получение тех же данных через task-diag.


                  # time for i in /proc/*/stat; do read STAT < $i; done
                  -bash: read: read error: 0: Is a directory
                  
                  real    0m0.657s
                  user    0m0.138s
                  sys 0m0.515s

                  А теперь получим cputime через task_diag:


                  # time ./task_diag_all all -x  -q
                  
                  real    0m0.041s
                  user    0m0.000s
                  sys 0m0.039s

                  Для понимания, вот пример данных, которые мы получаем через task_diag:


                  # ./task_diag_all one -x -p 1
                  Start getting information about 1
                  pid     1 tgid     1 ppid     0 sid     1 pgid     1 comm systemd
                  minflt:      8658
                  cminflt:  8320191
                  majflt:        78
                  cmajflt:      670
                  utime:        155
                  stime:       3704
                  cutime:      5201
                  cstime:     16716
                  threads:        1
          +2
          НаверноеЗПТ интересно было бы узнать, насколько быстрее был бы вывод, если бы использовались бинарные данные напрямую, и если бы не требовалось три системных вызова.

          Попытки создать такой интерфейс уже были. В 2004 пробовали использовать netlink движок.

          В Solaris было как раз так, как вы мечтаете. Открываешь /proc, а там вместо текстовичков — бинарные файлы. В результате эти файлы, кажется, даже ps с top'ом не читали — обращались напрямую к ядру с запросами.
            0
            Про какие бы новые фишки в Linux мы не говорили, всегда кто-то скажет, что в Солярис все это было. Остается только один вопрос: «Почему не стало соляриса?». Судя по всему, это была ОС, которая сильно обогнала свое время.
              +1
              Про какие бы новые фишки в Linux мы не говорили, всегда кто-то скажет, что в Солярис все это было.

              Я не идеализирую Солярис, если вы об этом. Да и поработать под соляркой мне довелось недолго. Но да, это была прекрасно вылизанная, устойчивая и надежная операционная система с кучей продвинутых фишечек.
              Почему ее не стало — вопрос настолько же провокационный, насколько и дурацкий. Но я вам попытаюсь ответить — так, как вижу со своей колокольни.

              Поддержка коммерческой ОСи в актуальном состоянии — это большие расходы. Очень большие расходы. И эти расходы должны компенсироваться. Другими словами, ОСь должна приносить доход.
              Очевидно, у фирмы SUN накопилось множество проблем, и разработка соляриса перестала быть прибыльной. Плюс активизировались конкуренты и заняли ниши, в которых раньше господствовал Сан. Оборудование на базе Интела стало дешевым, Линукс — несмотря на легкую топорность — все-таки оказался вполне работоспособным решением, и солярка умерла. Это бизнес.

              К чести SUN, они сделали весьма многое, чтобы сохранить солярис. Проект OpenSolaris и портирование на архитектуру Intel — это по сути попытка сделать из солярки открытую операционную систему. Но — не срослось. Трижды тьфу на Оракл.

              Судя по всему, это была ОС, которая сильно обогнала свое время.

              Я бы не сказал, что она обогнала свое время. Скорее, это был продукт своего времени, но максимально вылизанный и хорошо продуманный. По крайней мере, такое впечатление он производил на неискушенного меня. :)
            0
            Извините, но абсурднее идеи представить сложно.
            Зачем вы хотите из файловой системы proc читать бинарные данные? Читайте прямо из ядра.
              –1
              Это долгая история, изначально мы использовали netlink сокеты, но потом пришли к тому, что к транзакционному файлу в /proc/. На самом деле в /proc достаточно много бинарных файлов: /dev/mem/, /dev/kmem, /proc/pid/pagemap, etc. В чем абсурдность идеи? Как вы бы это сделали?
              +2
              Не совсем понял из поста, вы хотите дополнить procfs ещё одним endpoint'ом с бинарным интерфейсом, или избавиться от plain text файлов?
              Если первое — флаг вам в руки, новый производительный бинарный интерфейс для утилит — это, наверное, хорошо.
              Если второе — как справедливо писали выше, иногда из какого-нибудь скрипта или приложения нужно просто заглянуть во вполне конкретный файл и достать кусочек информации, не всем нужно парсить полную информацию обо всём дереве процессов, поэтому удалять plain text не очень хорошо.
              А поддерживать два более-менее одинаковых интерфейса в ядре — накладно. Думаю, что в том числе и из-за этого ваше предложение буксует столько времени. Правда, как это решить я тоже не знаю.
                0
                Речь идет о первом варианте, обратную совместимость никто не отменял. В будущем, генерацию этих файлов из ядра можно будет перенести в user-space, что-то вроде fuse файловой системы, но тут надо еще думать.

                И вы совершенно правы, вопрос о поддержке двух интерфейсов регулярно возникает. Сейчас код написан так, что большая его часть шарится между procfs и task_diag.

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое