Почему systemctl запускает докер с разными arguments

Есть три вещи, о которых вам нужно позаботиться при компиляции/сшивке с пакетом, не являющимся пакетом по умолчанию:

  • заголовки (обычно CFLAGS)
  • путь библиотеки времени компиляции (обычно LDFLAGS)
  • путь библиотеки времени исполнения (rpath через LDFLAGS, LD_RUN_PATH, LD_LIBRARY_PATH или ld. so.conf)

Вы не сказали, что такое prog, так что я не могу сказать, насколько хорошо может быть ее конфигурация (или если она использует autoconf? ), я видел много таких, которые надежно выполняют только первые два шага.

На этапе компоновки порядок путей к библиотеке актуален, предполагая, что вы используете инструментарий GNU (gcc & binutils), вы, вероятно, можете увидеть, что происходит, установив CFLAGS до configure (или, возможно, непосредственно в Makefile):

export CFLAGS="-Wl,-t"

Это передает опцию трассировки -t компоновщику. Может потребоваться добавить V=1 или VERBOSE=1 к команде make, если во время выполнения команды make выводятся только строки "CC" и "LD".)

Во время выполнения команды можно увидеть, что пытается ld.so, аккуратно установив LD_DEBUG, e. g.

LD_DEBUG=libs ./myprog

(или попробуйте значения files или symbols более подробно)

Чтобы правильно указать все три параметра во время сборки, вы должны уметь:

  • экспортировать CFLAGS="-I/usr/local/ssl-1. 0.2/include"
  • export LDFLAGS="-L/usr/local/ssl-1.0.2/lib -R/usr/local/ssl-1.0.2/lib"

затем переконфигурировать/перекомпилировать.

Вы используете --openssldir, а не более обычный --prefix (я рекомендую последний, а также использую make install_sw, если вам не нужны 1000 или около того man-страниц и симлинков, которые дает установка по умолчанию). Это может быть частью проблемы. По некоторым причинам библиотеки .so, которые вы показываете, известны в ld.so, не имеют суффикса версии (например, .so.1 .0.2), соответствующий "make install" должен был установить это для вас (через link-shared target в главном Makefile).

Опция -R инструктирует компоновщика встроить RPATH в исполняемый выход для конкретной библиотеки OpenSSL, чтобы ему не нужно было полагаться на умолчания, которые обычно предоставляет компоновщик (ld.so). Вместо этого вы можете модифицировать существующие двоичные файлы с помощью chrpath .

Это более или менее эквивалентно экспорту LD_LIBRARY_PATH=/usr/local/ssl-1.0.2/lib. Подробнее о RPATH и связанной с ней RUNPATH можно прочитать здесь: http://blog.tremily.us/posts/rpath/

В крайнем случае вы можете собрать OpenSSL без "shared" или с "noshared", это даст вам статические библиотеки, которые не будут иметь этой проблемы (но вполне могут иметь другие проблемы, например, для использования внутри ELF .so, вызывая проблемы PIC/PIE)


Основываясь на обновленных деталях, я считаю, что проблема в том, что 1.0.1 и 1.0.2beta устанавливают суффикс версии .so (SONAME) в 1.0.0. На первой системе с версией только 0.9.8 это не вызывает проблем; на второй системе с версиями 1.0.1 и 1.0.2, обе версии версий 1.0.0, это "первое совпадение выигрывает" на основе ld.so.{conf,d} заказа. Помните, ld компоновщик времени компиляции - это другая программа, отличная от ld.so компоновщика времени компиляции, и может иметь различное поведение (обычно приводящее к ошибкам в символах или, что еще хуже, как вы видели).

$ cd /usr/local/src/openssl/openssl/1.0.2beta1
$ readelf -a libssl.so | grep SONAME
0x0000000e (SONAME)                     Library soname: [libssl.so.1.0.0]

$ cat verchk.c
int main(int argc, char *argv[]) {
    printf("build: %s\n",OPENSSL_VERSION_TEXT);
    printf("run  : %s\n",SSLeay_version(SSLEAY_VERSION));
    return 0;
}

$ gcc -Wall  -I/usr/local/src/openssl/openssl-1.0.2-beta1/include \
    -Wl,-rpath /usr/local/src/openssl/openssl-1.0.2-beta1/ \
    -o verchk /usr/local/src/openssl/openssl-1.0.2-beta1/libcrypto.so verchk.c

$ ./verchk
build: OpenSSL 1.0.2-beta1 24 Feb 2014
run  : OpenSSL 1.0.2-beta1 24 Feb 2014

$ grep SHLIB_M...R= Makefile
SHLIB_MAJOR=1
SHLIB_MINOR=0.0

Обновление В OpenSSL-1.1 произошли некоторые изменения уровня API, приведенный выше код не скомпилируется с заголовками v1.1 и старыми библиотеками (неопределенная ссылка на `OpenSSL_version'').

SSLeay_version() теперь устарела и (в зависимости от OPENSSL_API_COMPAT) может быть #define-d к соответствующей функции API OpenSSL_version().

.

1
02.09.2015, 15:45
1 ответ

Вы пытались повторно включить службу, чтобы изменения вступили в силу?

systemctl reenable docker.service
2
27.01.2020, 23:36

Теги

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