02-01-2005, 07:06 AM
After some research and testing I did not only learn some things about
shared objects and about the quirks of glibc but also managed to run the
Source Dedicated Server on my Debian 3.0 Server.
Because I didn't read a tutorial yet how this can be made, I decided to
write one myself and share it to others.
The problem
The Source Dedicated Server (called srcds in the following) is build as a
dynamic linked executable which needs the core C runtime library on Linux
systems, the GLIBC (aka as libc6) to run.
The current version of the GLIBC is 2.3.x, which almost all Linux
distributions are shipping. However, Debian 3.0 ('stable' or 'woody') was
released when GLIBC 2.2.x was the latest release.
Unfortunately the srcds binary isn't able to run whith the GLIBC 2.2.5 of
Debian 3.0.
This is what I read in various forums and sadly hat to realize when I
tried to run the srcds on the dedicated server I own.
The real problem is that you can't simply update the GLIBC to a higher
minor number because of some incompatibilities which can render the whole
system unusable since every dynamic linked binary depends on the GLIBC and
is linked against a defined version. You better not try to simply take the
GLIBC from Debian Testing ('Sarge') and install it on a Woody system in
case it's not just a test installation...
The solution which isn't one (for me)
What most posters recommended therefore is to update the whole
distribution to Debian Sarge which is planned to become the next stable
release in some weeks or months. While this is technically easy as long as
you have a clean installation (without any packages installed from source
etc.), it can be dangerous if you have self compiled applications and
services which of course also depend on the GLIBC in the right version... For me this wasn't a solution for exactly this reason, besides I don't
want to change the whole system just to get one service running...
How it can be done
In the following, I will describe how I managed it to get it to work but
not how it works in detail and why it is done this way since I'm not a
specialist for shared objects, linker, loader, ELF, ... . For those who
are interested in these things I'll mention the sites I read to learn what
I have to do (in a pragmatic way).
The goal is to install the needed version of the glibc in a seperate
directory and tell the srcds to use this version instead of the one under
/lib. This sounds trivial but has a view pitfalls...
You'll need:
- write access to the root directory of yor server
- a binary editor (I used bvi)
- the rtldi tool (http://www.bitwagon.com/rtldi/rtldi.html)
- the glibc 2.3.x (e.g. the .deb-Package from Debian Testing)
First, install the srcds in a arbitrary directory either by using the
steam tool or by copying an installation from another machine. Create the directory /glibc23 and copy all files belonging to the glibc
2.3.x into this directory:
/root:# mkdir /glibc23
/root:# wget
http://ftp.debian.org/debian/pool/main/g/glibc/libc6_2.3.2.ds1-20_i386.deb
/root:# dpkg -x libc6_2.3.2.ds1-20_i386.deb /glibc23
/root:# chmod 755 /glibc23/*
Install the rtldi tool which isn't available from the Debian repositories.
You have to download the sources and compile it yourself. For me it didn't
compile on my woody system so I compiled it on another machine with Debian
testing and copied the resulting binary file rtldi to the target. Place it
in the /glibc23 directory and make it executable.
Finally you have to patch the ELF header of the srcds binary you want to
use (srcds_i686 for me) to make it use the rtldi as dynamic loader for the
shared libraries instead of /lib/ld-linux.so.2 (which isn't compatible
with glibc2.3).
You can use any binary editor, search for the path to the loader and
replace it with "/glibc23/rtldi". Make sure that the path is null
terminated and not longer than the original path. Fill it with \0 to let
it have the same length as before. This is why you should create the
directory on top level. You can of course create any path as long as it's
shorter than "/lib/ld-linux.so.2"...
I used the bvi -c commandline option to do this:
/root:# bvi -c "s/\/lib\/ld-linux.so.2\0/\/glibc23\/rtldi\0\0\0\0\0/"
/path/to/srcds_i686
Well, and that's it!
Run the srcds_run script and be a happy server op! ;-)
If you want to know more about the how and why, read these documents:
The best source of information for me was this article by David Nutter: http://hemswell.lincoln.ac.uk/~dnutter/eclipse-woody.php
Before I found it a last, I read (at least partially...):
"Dissecting shared libraries":
http://www-106.ibm.com/developerworks/linux/library/l-shlibs.html?ca=dgr-lnxw03SharedLib
http://sources.redhat.com/ml/libc-alpha/2004-12/msg00020.html
http://www.codecomments.com/printthread.php?threadid=246112
http://www.bitwagon.com/rtldi/rtldi.html
Please post your comments and corrections to make this more useful for others!
CU,
Fabrizio
shared objects and about the quirks of glibc but also managed to run the
Source Dedicated Server on my Debian 3.0 Server.
Because I didn't read a tutorial yet how this can be made, I decided to
write one myself and share it to others.
The problem
The Source Dedicated Server (called srcds in the following) is build as a
dynamic linked executable which needs the core C runtime library on Linux
systems, the GLIBC (aka as libc6) to run.
The current version of the GLIBC is 2.3.x, which almost all Linux
distributions are shipping. However, Debian 3.0 ('stable' or 'woody') was
released when GLIBC 2.2.x was the latest release.
Unfortunately the srcds binary isn't able to run whith the GLIBC 2.2.5 of
Debian 3.0.
This is what I read in various forums and sadly hat to realize when I
tried to run the srcds on the dedicated server I own.
The real problem is that you can't simply update the GLIBC to a higher
minor number because of some incompatibilities which can render the whole
system unusable since every dynamic linked binary depends on the GLIBC and
is linked against a defined version. You better not try to simply take the
GLIBC from Debian Testing ('Sarge') and install it on a Woody system in
case it's not just a test installation...
The solution which isn't one (for me)
What most posters recommended therefore is to update the whole
distribution to Debian Sarge which is planned to become the next stable
release in some weeks or months. While this is technically easy as long as
you have a clean installation (without any packages installed from source
etc.), it can be dangerous if you have self compiled applications and
services which of course also depend on the GLIBC in the right version... For me this wasn't a solution for exactly this reason, besides I don't
want to change the whole system just to get one service running...
How it can be done
In the following, I will describe how I managed it to get it to work but
not how it works in detail and why it is done this way since I'm not a
specialist for shared objects, linker, loader, ELF, ... . For those who
are interested in these things I'll mention the sites I read to learn what
I have to do (in a pragmatic way).
The goal is to install the needed version of the glibc in a seperate
directory and tell the srcds to use this version instead of the one under
/lib. This sounds trivial but has a view pitfalls...
You'll need:
- write access to the root directory of yor server
- a binary editor (I used bvi)
- the rtldi tool (http://www.bitwagon.com/rtldi/rtldi.html)
- the glibc 2.3.x (e.g. the .deb-Package from Debian Testing)
First, install the srcds in a arbitrary directory either by using the
steam tool or by copying an installation from another machine. Create the directory /glibc23 and copy all files belonging to the glibc
2.3.x into this directory:
/root:# mkdir /glibc23
/root:# wget
http://ftp.debian.org/debian/pool/main/g/glibc/libc6_2.3.2.ds1-20_i386.deb
/root:# dpkg -x libc6_2.3.2.ds1-20_i386.deb /glibc23
/root:# chmod 755 /glibc23/*
Install the rtldi tool which isn't available from the Debian repositories.
You have to download the sources and compile it yourself. For me it didn't
compile on my woody system so I compiled it on another machine with Debian
testing and copied the resulting binary file rtldi to the target. Place it
in the /glibc23 directory and make it executable.
Finally you have to patch the ELF header of the srcds binary you want to
use (srcds_i686 for me) to make it use the rtldi as dynamic loader for the
shared libraries instead of /lib/ld-linux.so.2 (which isn't compatible
with glibc2.3).
You can use any binary editor, search for the path to the loader and
replace it with "/glibc23/rtldi". Make sure that the path is null
terminated and not longer than the original path. Fill it with \0 to let
it have the same length as before. This is why you should create the
directory on top level. You can of course create any path as long as it's
shorter than "/lib/ld-linux.so.2"...
I used the bvi -c commandline option to do this:
/root:# bvi -c "s/\/lib\/ld-linux.so.2\0/\/glibc23\/rtldi\0\0\0\0\0/"
/path/to/srcds_i686
Well, and that's it!
Run the srcds_run script and be a happy server op! ;-)
If you want to know more about the how and why, read these documents:
The best source of information for me was this article by David Nutter: http://hemswell.lincoln.ac.uk/~dnutter/eclipse-woody.php
Before I found it a last, I read (at least partially...):
"Dissecting shared libraries":
http://www-106.ibm.com/developerworks/linux/library/l-shlibs.html?ca=dgr-lnxw03SharedLib
http://sources.redhat.com/ml/libc-alpha/2004-12/msg00020.html
http://www.codecomments.com/printthread.php?threadid=246112
http://www.bitwagon.com/rtldi/rtldi.html
Please post your comments and corrections to make this more useful for others!
CU,
Fabrizio