Systemd忽略LD_PRELOAD变量和服务可以启动

发布于 2025-02-12 18:40:05 字数 8690 浏览 0 评论 0原文

我在预加载图书馆时有问题。

但是首先,我要解释我打算做什么。 我已经使用Un4Seen低音音频库开发了一款Blazor Web应用程序。该应用程序托管在Kestrel Web服务器上,我想将应用程序部署为服务(SystemD)。

该应用程序可完美地工作,旨在在Ubuntu和Windows系统上运行。正如我所说,它可以按照我想要的方式工作。只是不是作为服务。

如前所述,执行需要的Un4Seen Audio库是所需的,这些库存储在项目结构中,如下所示。

[AppRoot]
¦
+---....
¦
+---Bass.Net.dll
¦
+---....
¦   
+---libs
    +---unix
    ¦   +---x64
    ¦   ¦       libbass.so
    ¦   ¦       libbassalac.so
    ¦   ¦       libbassenc.so
    ¦   ¦       libbassenc_flac.so
    ¦   ¦       libbassenc_mp3.so
    ¦   ¦       libbassenc_opus.so
    ¦   ¦       libbassflac.so
    ¦   ¦       libbassmix.so
    ¦   ¦       libbassopus.so
    ¦   ¦       libbasswebm.so
    ¦   ¦       libbass_aac.so
    ¦   ¦       libbass_ac3.so
    ¦   ¦       
    ¦   +---x86
    ¦           libbass.so
    ¦           libbassalac.so
    ¦           libbassenc.so
    ¦           libbassenc_flac.so
    ¦           libbassenc_mp3.so
    ¦           libbassenc_opus.so
    ¦           libbassflac.so
    ¦           libbassmix.so
    ¦           libbassopus.so
    ¦           libbasswebm.so
    ¦           libbass_aac.so
    ¦           libbass_ac3.so
    ¦           
    +---Win32NT
        +---x64
        ¦       bass.dll
        ¦       bassalac.dll
        ¦       bassenc.dll
        ¦       bassenc_flac.dll
        ¦       bassenc_mp3.dll
        ¦       bassenc_opus.dll
        ¦       bassflac.dll
        ¦       bassmix.dll
        ¦       bassopus.dll
        ¦       basswebm.dll
        ¦       bass_aac.dll
        ¦       bass_ac3.dll
        ¦       
        +---x86
                bass.dll
                bassalac.dll
                bassenc.dll
                bassenc_flac.dll
                bassenc_mp3.dll
                bassenc_opus.dll
                bassflac.dll
                bassmix.dll
                bassopus.dll
                basswebm.dll
                bass_aac.dll
                bass_ac3.dll

使用以下方法,我初始化了低音库:

private bool InitializeBassLibrary()
{
    var appPath = new Uri(Assembly.GetEntryAssembly()?.GetName().CodeBase ?? throw new NullReferenceException())
        .LocalPath;
    appPath = Path.GetDirectoryName(appPath);
    if (string.IsNullOrEmpty(appPath))
    {
        return false;
    }

    var librariesPath = appPath;

    var osPlatform = Environment.OSVersion.Platform;

    switch (osPlatform)
    {
        case PlatformID.Win32NT:
        {
            librariesPath += Environment.Is64BitProcess ? "\\libs\\win32nt\\x64\\" : "\\libs\\win32nt\\x86\\";
            break;
        }
        case PlatformID.Unix:
        {
            // Add following paths to search path for libs of your linux distribution.
            // e.g. for Ubuntu
            //      ldconfig /full/path/to/libs/unix/x64
            //      ldconfig /full/path/to/libs/unix/x86
            break;
        }
    }

    BassNet.Registration("[email protected]", "X123456789012345");

    if (osPlatform == PlatformID.Win32NT)
    {
        var libLoadIsOk = Bass.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassAac.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassAc3.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassAlac.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassFlac.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassOpus.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassEnc.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassEnc_Flac.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassEnc_Mp3.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassEnc_Opus.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassMix.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }
    }

    if (osPlatform == PlatformID.Unix)
    {
        // For preloading BASS libs execute creation of fake streams or execute GetVersion() Methods if exists.
        Bass.BASS_GetVersion(4);
        _ = BassAc3.BASS_AC3_StreamCreateFile("", 0, 0, BASSFlag.BASS_DEFAULT);
        _ = BassAlac.BASS_ALAC_StreamCreateFile("", 0, 0, BASSFlag.BASS_DEFAULT);
        _ = BassFlac.BASS_FLAC_StreamCreateFile("", 0, 0, BASSFlag.BASS_DEFAULT);
        _ = BassOpus.BASS_OPUS_StreamCreateFile("", 0, 0, BASSFlag.BASS_DEFAULT);
        BassEnc.BASS_Encode_GetVersion();
        BassEnc_Flac.BASS_Encode_FLAC_GetVersion();
        BassEnc_Mp3.BASS_Encode_MP3_GetVersion();
        BassEnc_Opus.BASS_Encode_OPUS_GetVersion();
        BassMix.BASS_Mixer_GetVersion();
    }
    
    Bass.BASS_Init(AudioDevice, AudioDeviceSamplingRate, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero);
    if (Bass.BASS_ErrorGetCode() != BASSError.BASS_OK)
    {
        return false;
    }

    return true;
}

该应用程序的Ubuntu版本是针对Linux-X64发布的,然后将其复制到Ubuntu机器。

因此,库分配在Ubuntu下正常工作,我创建了文件/etc/ld.so.conf.d/app_name.conf

/etc/ld.so.conf.d/app_name.conf

/usr/share/nginx/html/dds-audio-transcoder-service/libs/unix/x64
/usr/share/nginx/html/dds-audio-transcoder-service/libs/unix/x86

此LD配置文件通过sudo> sudo ldconfig -v成功应用。

无论出于何种原因,要使它起作用,我都必须预努加载libbass.so带有ld_preload库,尽管它已经在/etc/ld.so.conf中.d/app_name.conf应该可以发现。我输入了ld_preload通过/etc/code>和值/usr/share/nginx/nginx/html/app_name/libs/unix/x64/x64/x64/ libbass.so设置。 对于那些不知道低音音频库的人:libbass.o是主要库。其他文件是插件。

If I don't set the LD_PRELOAD variable the application won't start and gives the error: symbol lookup error: /usr/share/nginx/html/dds-audio-transcoder-service /libs/unix/x64/libbass_ac3.so:不确定的符号:bass_getversion。这是完全误导的,因为该方法根本没有调用。至少不在libbass_ac3.so上。花了一点时间来弄清楚这是从libbass.o中弄清楚的。

如果我然后以:sudo [app_file_name] - environment [custom_environment]该应用程序按预期工作。

现在终于出现了问题

我将此Kestrel托管应用程序配置为SystemD中的服务。为此目的创建了以下服务文件。

/etc/systemd/system/app_name.service

[Unit]
Description=DDS-Audio-Transcoder for transcoding audio files to different audio formats

[Service]
WorkingDirectory=/usr/share/nginx/html/app-name
ExecStart=/usr/share/nginx/html/app-name/app-name-start-binary --environment TestInstance3Unix
Restart=always
RestartSec=150
KillSignal=SIGINT
SyslogIdentifier=bit-dds-transcoder
User=www-data
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
Environment="LD_PRELOAD=libbass.so"
Environment="LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/share/nginx/html/dds-transcoder-service/libs/unix/x64:/usr/share/nginx/html/dds-transcoder-service/libs/unix/x86"

[Install]
WantedBy=multi-user.target

启用了服务:sudo systemctl enable app_name.service

然后我尝试了:sudo systemctl start app_name.service.service.service.service.service.service.service.service.service.service.service.service.service.service.service.service.name开始服务,什么也不会发生。

Syslog说以下内容:

Jul  4 23:04:49 l01-v-s-0081 systemd[1]: app_name.service: Scheduled restart job, restart counter is at 21.
Jul  4 23:04:49 l01-v-s-0081 systemd[1]: Stopped app_name.
Jul  4 23:04:49 l01-v-s-0081 systemd[1]: Started app_name.
Jul  4 23:04:50 l01-v-s-0081 app_name[2241]: /usr/share/nginx/html/app_name/app-name-start-binary: symbol lookup error: /usr/share/nginx/html/dds-audio-transcoder-service/libs/unix/x64/libbass_ac3.so: undefined symbol: BASS_GetVersion
Jul  4 23:04:50 l01-v-s-0081 systemd[1]: dds-audio-transcoder.service: Main process exited, code=exited, status=127/n/a
Jul  4 23:04:50 l01-v-s-0081 systemd[1]: dds-audio-transcoder.service: Failed with result 'exit-code'.

系统信息

esx虚拟Mashine with ubuntu 20.04 .net 5.0

我缺少什么或我做错了什么?

记得!没有SystemD,它可以正常工作。

我真的很感激每个小费。

许多问候

马库斯

i have a problem with preloading a library.

But first I'll explain what I intend to do.
I've developed a Blazor web application using the Un4Seen Bass Audio libraries. The application is hosted on the Kestrel Web Server and I wanted to deploy the application as a service (systemd).

The application works flawlessly and is designed to run on both Ubuntu and Windows systems. As I said, it works the way I want it to. Just not as a service.

As already mentioned, the Un4Seen audio libraries are required for execution, which are stored in the project structure as follows.

[AppRoot]
¦
+---....
¦
+---Bass.Net.dll
¦
+---....
¦   
+---libs
    +---unix
    ¦   +---x64
    ¦   ¦       libbass.so
    ¦   ¦       libbassalac.so
    ¦   ¦       libbassenc.so
    ¦   ¦       libbassenc_flac.so
    ¦   ¦       libbassenc_mp3.so
    ¦   ¦       libbassenc_opus.so
    ¦   ¦       libbassflac.so
    ¦   ¦       libbassmix.so
    ¦   ¦       libbassopus.so
    ¦   ¦       libbasswebm.so
    ¦   ¦       libbass_aac.so
    ¦   ¦       libbass_ac3.so
    ¦   ¦       
    ¦   +---x86
    ¦           libbass.so
    ¦           libbassalac.so
    ¦           libbassenc.so
    ¦           libbassenc_flac.so
    ¦           libbassenc_mp3.so
    ¦           libbassenc_opus.so
    ¦           libbassflac.so
    ¦           libbassmix.so
    ¦           libbassopus.so
    ¦           libbasswebm.so
    ¦           libbass_aac.so
    ¦           libbass_ac3.so
    ¦           
    +---Win32NT
        +---x64
        ¦       bass.dll
        ¦       bassalac.dll
        ¦       bassenc.dll
        ¦       bassenc_flac.dll
        ¦       bassenc_mp3.dll
        ¦       bassenc_opus.dll
        ¦       bassflac.dll
        ¦       bassmix.dll
        ¦       bassopus.dll
        ¦       basswebm.dll
        ¦       bass_aac.dll
        ¦       bass_ac3.dll
        ¦       
        +---x86
                bass.dll
                bassalac.dll
                bassenc.dll
                bassenc_flac.dll
                bassenc_mp3.dll
                bassenc_opus.dll
                bassflac.dll
                bassmix.dll
                bassopus.dll
                basswebm.dll
                bass_aac.dll
                bass_ac3.dll

With the following method i initialize the Bass Libraries:

private bool InitializeBassLibrary()
{
    var appPath = new Uri(Assembly.GetEntryAssembly()?.GetName().CodeBase ?? throw new NullReferenceException())
        .LocalPath;
    appPath = Path.GetDirectoryName(appPath);
    if (string.IsNullOrEmpty(appPath))
    {
        return false;
    }

    var librariesPath = appPath;

    var osPlatform = Environment.OSVersion.Platform;

    switch (osPlatform)
    {
        case PlatformID.Win32NT:
        {
            librariesPath += Environment.Is64BitProcess ? "\\libs\\win32nt\\x64\\" : "\\libs\\win32nt\\x86\\";
            break;
        }
        case PlatformID.Unix:
        {
            // Add following paths to search path for libs of your linux distribution.
            // e.g. for Ubuntu
            //      ldconfig /full/path/to/libs/unix/x64
            //      ldconfig /full/path/to/libs/unix/x86
            break;
        }
    }

    BassNet.Registration("[email protected]", "X123456789012345");

    if (osPlatform == PlatformID.Win32NT)
    {
        var libLoadIsOk = Bass.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassAac.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassAc3.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassAlac.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassFlac.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassOpus.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassEnc.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassEnc_Flac.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassEnc_Mp3.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassEnc_Opus.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }

        libLoadIsOk = BassMix.LoadMe(librariesPath);
        if (!libLoadIsOk)
        {
            return false;
        }
    }

    if (osPlatform == PlatformID.Unix)
    {
        // For preloading BASS libs execute creation of fake streams or execute GetVersion() Methods if exists.
        Bass.BASS_GetVersion(4);
        _ = BassAc3.BASS_AC3_StreamCreateFile("", 0, 0, BASSFlag.BASS_DEFAULT);
        _ = BassAlac.BASS_ALAC_StreamCreateFile("", 0, 0, BASSFlag.BASS_DEFAULT);
        _ = BassFlac.BASS_FLAC_StreamCreateFile("", 0, 0, BASSFlag.BASS_DEFAULT);
        _ = BassOpus.BASS_OPUS_StreamCreateFile("", 0, 0, BASSFlag.BASS_DEFAULT);
        BassEnc.BASS_Encode_GetVersion();
        BassEnc_Flac.BASS_Encode_FLAC_GetVersion();
        BassEnc_Mp3.BASS_Encode_MP3_GetVersion();
        BassEnc_Opus.BASS_Encode_OPUS_GetVersion();
        BassMix.BASS_Mixer_GetVersion();
    }
    
    Bass.BASS_Init(AudioDevice, AudioDeviceSamplingRate, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero);
    if (Bass.BASS_ErrorGetCode() != BASSError.BASS_OK)
    {
        return false;
    }

    return true;
}

The Ubuntu version of the application is released for linux-x64 and is then copied to an Ubuntu machine.

So that the library assignment works correctly under Ubuntu, I created the file /etc/ld.so.conf.d/app_name.conf.

/etc/ld.so.conf.d/app_name.conf

/usr/share/nginx/html/dds-audio-transcoder-service/libs/unix/x64
/usr/share/nginx/html/dds-audio-transcoder-service/libs/unix/x86

This LD configuration file was then successfully applied with sudo ldconfig -v.

Whatever the reason, to get it working I had to preload the libbass.so library with LD_PRELOAD although it already has it in /etc/ld.so.conf.d/app_name.conf should be discoverable. I entered the LD_PRELOAD variable system-wide via /etc/environment and the value /usr/share/nginx/html/app_name/libs/unix/x64/libbass.so set.
For those who don't know the bass audio libraries: libbass.so is the main library. The other files are plugins.

If I don't set the LD_PRELOAD variable the application won't start and gives the error: symbol lookup error: /usr/share/nginx/html/dds-audio-transcoder-service/libs/unix/ x64/libbass_ac3.so: undefined symbol: BASS_GetVersion. This is completely misleading because the method is not called at all. At least not on libbass_ac3.so. Took a bit to figure out it's from libbass.so.

If I then start the application with: sudo [app_file_name] --environment [custom_environment] the app works as expected.

Now finally comes the problem

I configured this Kestrel hosted application as a service in systemd. The following service file was created for this purpose.

/etc/systemd/system/app_name.service

[Unit]
Description=DDS-Audio-Transcoder for transcoding audio files to different audio formats

[Service]
WorkingDirectory=/usr/share/nginx/html/app-name
ExecStart=/usr/share/nginx/html/app-name/app-name-start-binary --environment TestInstance3Unix
Restart=always
RestartSec=150
KillSignal=SIGINT
SyslogIdentifier=bit-dds-transcoder
User=www-data
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
Environment="LD_PRELOAD=libbass.so"
Environment="LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/share/nginx/html/dds-transcoder-service/libs/unix/x64:/usr/share/nginx/html/dds-transcoder-service/libs/unix/x86"

[Install]
WantedBy=multi-user.target

The service was enabled with: sudo systemctl enable app_name.service

Then I tried with: sudo systemctl start app_name.service to start the service and nothing happens.

The syslog says the following:

Jul  4 23:04:49 l01-v-s-0081 systemd[1]: app_name.service: Scheduled restart job, restart counter is at 21.
Jul  4 23:04:49 l01-v-s-0081 systemd[1]: Stopped app_name.
Jul  4 23:04:49 l01-v-s-0081 systemd[1]: Started app_name.
Jul  4 23:04:50 l01-v-s-0081 app_name[2241]: /usr/share/nginx/html/app_name/app-name-start-binary: symbol lookup error: /usr/share/nginx/html/dds-audio-transcoder-service/libs/unix/x64/libbass_ac3.so: undefined symbol: BASS_GetVersion
Jul  4 23:04:50 l01-v-s-0081 systemd[1]: dds-audio-transcoder.service: Main process exited, code=exited, status=127/n/a
Jul  4 23:04:50 l01-v-s-0081 systemd[1]: dds-audio-transcoder.service: Failed with result 'exit-code'.

System Informations

esx Virtual Mashine with Ubuntu 20.04
.Net 5.0

What i'm missing or what i have done wrong?

Remember! Without systemd it works fine.

I'm really grateful for every tip.

Many greetings

Marcus

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文