Dyson is a general-purpose operating system, a Debian derivative using the illumos kernel, libc, and SMF init system (formerly OpenSolaris). See FAQ.
It is not a successor of any existing or existed distributions based on illumos or OpenSolaris. Dyson is constructed from scratch to be like Debian as much as possible. Namely, most of Debian packages can be built on Dyson without any changes, and arch-independent packages (arch all
in Debian terms) can be installed directly as is.
Currently Dyson only runs on x86_64 processors (it is fully 64-bit).
There is a LiveCD ISO image with a simple installer: https://dl.osdyson.ru/iso/2019-11-15/
For downloading and using Dyson consider using the mirrors.
VCS repositories are available for anonymous read-only access:
Debian patch tracker: https://patches.osdyson.ru/
If the APT repository cannot be verified due to missed public key (The following signatures couldn't be verified because the public key is not available: NO_PUBKEY),
get current singing key located at https://apt.osdyson.ru/dyson.asc and use "apt-key
" to add the key manually.
This key is usually automatically installed with the "dyson-archive-keyring
" package.
It is possible to use Vagrant to set up a VirtualBox machine. See https://git.osdyson.ru/vagrant/dyson.git.
https://lists.osdyson.ru/listinfo/dyson-devel - development of Dyson, technical topics, packaging, porting Debian packages, porting software to illumos.
Try it. Report issues and wishes. Feel free to email to dyson-devel@osdyson.org.
Port Debian packages and various software to Dyson. Send patches to upstream and/or Debian package maintainers. Ideally any Debian package should need no more than a simple rebuild. See Porting guide.
See https://www.osdyson.ru/issues to find out if you can help with an advise or coding.
Things to be done:
Assume Debian (Linux) to Dyson.
Dyson's APT repository includes pre-compiled packages for Debian (Linux / amd64). Add this line to /etc/apt/sources.list
:
deb [ arch=amd64 ] https://apt.osdyson.ru unstable main
Both normal and cross binutils should be installed on Debian (Linux) system. Thus original (not patched) version of binutils is overwritten by the Dyson's binutils. This is pretty safe, because Dyson's patches only affect Solaris targets.
$ dget -u https://apt.osdyson.ru/pool/main/b/binutils/binutils_2.28-5%2Bdyson1.dsc
$ cd binutils-2.28 $ ./debian/rules stamps/control $ dpkg-buildpackage --build=any
debian/README.cross
it's quite simple:$ cd binutils-2.28 $ TARGET=x86_64-pc-solaris2.11 ./debian/rules stamps/control $ TARGET=x86_64-pc-solaris2.11 dpkg-buildpackage --build=any
... find debian/binutils-x86-64-pc-solaris2.11 -depth -newermt 'Sat, 13 May 2017 13:33:58 +0300' -print0 | \ xargs -0r touch --no-dereference --date='Sat, 13 May 2017 13:33:58 +0300' dpkg --build debian/binutils-x86-64-pc-solaris2.11 .. dpkg-deb: building package 'binutils-x86-64-pc-solaris2.11' in '../binutils-x86-64-pc-solaris2.11_2.28-5+dyson1_amd64.deb'. $ dpkg -c ../binutils-x86-64-pc-solaris2.11_2.28-5+dyson1_amd64.deb drwxr-xr-x root/root 0 2017-05-13 13:33 ./ drwxr-xr-x root/root 0 2017-05-13 13:33 ./usr/ drwxr-xr-x root/root 0 2017-05-13 13:33 ./usr/bin/ -rwxr-xr-x root/root 28176 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-addr2line -rwxr-xr-x root/root 56856 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-ar -rwxr-xr-x root/root 369928 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-as -rwxr-xr-x root/root 23776 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-c++filt -rwxr-xr-x root/root 3064344 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-dwp -rwxr-xr-x root/root 28160 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-elfedit -rwxr-xr-x root/root 93144 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-gprof -rwxr-xr-x root/root 1185712 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-ld hrwxr-xr-x root/root 0 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-ld.bfd link to ./usr/bin/x86_64-pc-solaris2.11-ld -rwxr-xr-x root/root 5206392 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-ld.gold -rwxr-xr-x root/root 41192 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-nm -rwxr-xr-x root/root 222448 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-objcopy -rwxr-xr-x root/root 353144 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-objdump -rwxr-xr-x root/root 56856 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-ranlib -rwxr-xr-x root/root 494112 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-readelf -rwxr-xr-x root/root 28024 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-size -rwxr-xr-x root/root 28144 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-strings -rwxr-xr-x root/root 222456 2017-05-13 13:33 ./usr/bin/x86_64-pc-solaris2.11-strip drwxr-xr-x root/root 0 2017-05-13 13:33 ./usr/lib/ drwxr-xr-x root/root 0 2017-05-13 13:33 ./usr/lib/x86_64-linux-gnu/ -rw-r--r-- root/root 1234664 2017-05-13 13:33 ./usr/lib/x86_64-linux-gnu/libbfd-2.28-solaris-amd64.so -rw-r--r-- root/root 1661968 2017-05-13 13:33 ./usr/lib/x86_64-linux-gnu/libopcodes-2.28-solaris-amd64.so ...
To be done
To install Dyson you need:
You can also use virtual machines such as VirtualBox or QEMU.
This is tested on Debian amd64 with QEMU version 1.1.2.
$ qemu-img create -f qcow2 dyson.qcow2 10G $ qemu-system-x86_64 -hda dyson.qcow2 -m 1500 -cdrom dyson-netinst-2013-05-05-1506.iso
Download the latest ISO image of install CD from http://dl.osdyson.ru/iso/.
When booting from CD the startup script tries to bring networking up via DHCP.
If no DHCP servers available you have to configure network manually. To configure network manually switch to the console (press the F2
key), and use commands dladm
, ipadm
, route
, also remember to update the /etc/resolv.conf
file with vim
or nano
. See appropriate man pages, e. i. man ipadm
, for detail.
Example:
# dladm show-phys LINK MEDIA STATE SPEED DUPLEX DEVICE e1000g0 Ethernet unknown 1000 full e1000g0
# ipadm create-if e1000g0
dladm show-phys
again, you will see that the state of the interface is changed from "unknown" to "up" or "down" (cable connected or not). If the state is "down" there is no reason to go with this interface until you connect the cable.# ipadm create-addr -T dhcp e1000g0/dhcp
# ipadm create-addr -T static -a 192.168.2.45/24 e1000g0/static
route -n add default -gateway 192.168.2.1
netstat
:netstat -nr
/etc/resolv.conf
Dyson does not include closed source drivers, such as mpt
(see https://www.illumos.org/issues/3).
There are instruction by Jason Upton on how to get closed source drivers and use them during installation:
http://lists.osdyson.org/pipermail/dyson-devel/2013-April/000041.html
Since the installer is a network installer it uses "testing
" repository to install base system. "testing
" repository is known to work. After installation you may want to switch to "unstable
".
Given that Dyson is installed on the primary partition N of the first drive, add following lines to /etc/grub.d/40_custom
and run grub-mkconfig -o /boot/grub/grub.cfg
to updated GRUB2 menu.
menuentry "Dyson" { set root=(hd0,N) # change N to the partition number (1 to 4) chainloader +1 }
With this configuration Debian's GRUB2 will show the "Dyson" item in its menu and will run Dyson's GRUB if you choose that item ("chain loading").
Obviously, Dyson's GRUB should be installed into a partition, not into MBR (Debian's GRUB2 holds MBR).
This section describes an optimistic installation process on a clean virtual machine.
LiveCD GRUB menu:
LiveCD is booting:
The installer's start screen:
The console. You can switch to the console (press F2
) and execute any commands as root. To switch back to the installer press F1
:
First of all, the installer searches for hard disks and ZFS pools. The installer can install Dyson to existing ZFS pool, or can create a new one.
For new ZFS pool you need a disk with one Solaris partition:
cfdisk from util-linux is used for editing partitions :
Solaris partition has id = 0xbf
:
After creating a Solaris partirion remember to choose "Write" in cfdisk menu, then - "Quit":
Now you are ready to install Dyson:
The installer will format Solaris partition (with a single slice) and create ZFS root pool and minimal ZFS filesystems (including swap, /home and /):
Choosing how big the installed system will be:
Then you will be asked to choose a Dyson mirror:
Next, installation of a base system begins (using debootstrap):
If you choose basic or desktop profile, additional packages will be installed (via apt-get):
Then - enter a hostname (aka nodename):
And finally, enter root password:
If installing more than just a minimal system, you will be asked to create a regular user:
Then the installer will create boot archive:
And populate initial SMF repository:
Dyson uses GRUB 1 for booting (aka GRUB legacy). It can be installed on master boot record (MBR) or on a partitions (which you've choosen for root ZFS pool). Note that is that partition is a logical partition, GRUB will be forcedly installed on MBR. If you are installing on an existing ZFS pool (e. g. created by OpenIndiana), you may want to just update GRUB menu, or completely skip GRUB configuration. In any case an example configuration is saved in /boot/grub/menu.lst
on root filesystem.
Then, you are done:
Eject CD and reboot:
That was just the beginning...
Lightdm is the default desktop manager. It is started by the svc:/system/graphical-login:lightdm
SMF service. Disable it to disable X11 autostart.
Make sure vtdaemon
is installed and svc:/system/vtdaemon:default
is enabled. Enable the svc:/system/console-login:vt2
SMF service for virtual terminal 2. Use CTRL+ALT+F2
to switch to VT 2.
This is the primary site:
Thanks to Yandex:
Thanks to NLUUG and Mike Hulsman.
Synchronized every 2 hours on the even hours.
Thanks to http://dotsrc.org.
Synchronized every 4 hours.
Mirrors can be created with rsync:
rsync -a --delete --force --progress rsync://ftp.nluug.nl/dyson/apt/ /path/to/dyson/apt/mirror/ # or rsync -a --delete --force --progress rsync://apt.osdyson.ru/apt/ /path/to/dyson/apt/mirror/
rsync -a --delete --force --progress rsync://ftp.nluug.nl/dyson/ftp/ /path/to/dyson/ftp/mirror/ # or rsync -a --delete --force --progress rsync://dl.osdyson.ru/dl/ /path/to/dyson/dl/mirror/
d_type
of struct dirent
¶Synopsis:
inputoutput.cpp:82:27: error: ‘struct dirent’ has no member named ‘d_type’; did you mean ‘d_name’? if (dirp->d_type == DT_REG) ^~~~~~ inputoutput.cpp:82:37: error: ‘DT_REG’ was not declared in this scope if (dirp->d_type == DT_REG) ^~~~~~
Solution is to use dirfd
and fstatat
, as shown below.
Note that decent programs should use stat/fstat/fstatat anyway, because not checking d_type == DT_UNKNOWN
is a bug!
--- opencv-2.4.9.1+dfsg1.orig/modules/contrib/src/inputoutput.cpp +++ opencv-2.4.9.1+dfsg1/modules/contrib/src/inputoutput.cpp @@ -7,6 +7,7 @@ #include <tchar.h> #else #include <dirent.h> + #include <sys/stat.h> #endif namespace cv @@ -72,14 +73,18 @@ namespace cv (void)addPath; DIR *dp; struct dirent *dirp; + int dfd; + struct stat st; if((dp = opendir(path.c_str())) == NULL) { return list; } + dfd = dirfd(dp); while ((dirp = readdir(dp)) != NULL) { - if (dirp->d_type == DT_REG) + if ((0 == fstatat(dfd, dirp->d_name, &st, 0)) && + S_ISREG(st.st_mode)) { if (exten.compare("*") == 0) list.push_back(static_cast<std::string>(dirp->d_name));
If struct ifreq
causes problems (e. g. missing ifr_ifindex
) consider using struct lifreq
, see for example http://bugs.python.org/issue21287.
Compile with CPPFLAGS="-D_POSIX_C_SOURCE=199506L
" or "-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT
"
Use libiberty-dev
package: link with -liberty
, include libiberty/libiberty.h
. The only known package with such a problem is tree
(actually it includes strverscmp.c
).
glibc defines FILE
as _IO_FILE
, illumos libc - as __FILE
.
So C++ functions differ, and dh_makeshlibs
can fail:
dpkg-gensymbols: warning: some new symbols appeared in the symbols file: see diff output below dpkg-gensymbols: warning: some symbols or patterns disappeared in the symbols file: see diff output below dpkg-gensymbols: warning: debian/libqt5webkit5/DEBIAN/symbols doesn't match completely debian/libqt5webkit5.symbols ... dh_makeshlibs: failing due to earlier errors
Fix:
@@ -2182,7 +2182,8 @@ libQt5WebKit.so.5 libqt5webkit5 #MINVER# _ZN3JSC7JSProxy9setTargetERNS_2VMEPNS_14JSGlobalObjectE@Base 5.2.0 _ZN3JSC7JSScope13objectAtScopeEPS0_@Base 5.0.2 _ZN3JSC7JSValue13isValidCalleeEv@Base 5.0.2 - _ZN3JSC7Options14dumpAllOptionsEP8_IO_FILE@Base 5.0.2 + (arch=!illumos-amd64)_ZN3JSC7Options14dumpAllOptionsEP8_IO_FILE@Base 5.0.2 + (arch=illumos-amd64)_ZN3JSC7Options14dumpAllOptionsEP6__FILE@Base 5.2.1+dfsg-6~dyson1 _ZN3JSC7Options9s_optionsE@Base 5.0.2 _ZN3JSC7Options9setOptionEPKc@Base 5.0.2 _ZN3JSC7Profile10restoreAllEv@Base 5.0.2
On Linux we usually use pthread_getattr_np()
, on Dyson we have thr_stksegment()
.
Be careful: if stack is "unlimited", ss_size
will hold RLIM_INFINITY = -3
(see sys/resource.h
) which definitely must not be interpreted as stack size! In this case lower stack boundary should be set to 0xFFFF800000000000L
.
Example from Mono:
#elif (defined(__sun__) || defined(__illumos_kernel__)) #include <thread.h> #include <errno.h> { int rc; stack_t s; do { rc = thr_stksegment(&s); } while (rc != 0 && errno == EAGAIN); info->stack_end = s.ss_sp; // Is stack "unlimited" ? if (s.ss_size == RLIM_INFINITY) { // XXX Lower stack boundary info->stack_start_limit = (void*)0xFFFF800000000000L; } else { info->stack_start_limit = (void*)((intptr_t)s.ss_sp - (intptr_t)s.ss_size); } } #else
P. S. pthread_attr_get_np()
is provided by libc since 5.10.18.git.2a44663-4 (2017-11-22).
Use const char * getexecname()
from stdlib.h
or
readlink("/proc/self/path/a.out", buf, bufsize);
http://stackoverflow.com/questions/933850/how-to-find-the-location-of-the-executable-in-c
Synopsis:
In file included from ../../src/base/dict.h:40:0, from freetype.cpp:152: /usr/include/c++/4.8/cstdlib: In function ‘long long int std::abs(long long int)’: /usr/include/c++/4.8/cstdlib:174:20: error: declaration of C function ‘long long int std::abs(long long int)’ conflicts with abs(long long __x) { return __builtin_llabs (__x); } ^ In file included from /usr/include/stdlib.h:38:0, from ../../include/Inventor/SoType.h:37, from ../../include/Inventor/errors/SoError.h:39, from ../../include/Inventor/errors/SoDebugError.h:36, from ../../src/coindefs.h:95, from freetype.cpp:44: /usr/include/iso/stdlib_iso.h:122:12: error: previous declaration ‘int std::abs(int)’ here extern int abs(int); ^
cstdlib
, not stdlib.h
.
These macros are deprecated and removed from 64-bit Solaris or illumos. Glibc provides them via *_INT32
macros. Workaround:
#include <rpc/xdr.h> // ... #ifndef IXDR_GET_LONG #define IXDR_GET_LONG(buf) ((long)IXDR_GET_U_INT32(buf)) #endif #ifndef IXDR_PUT_LONG #define IXDR_PUT_LONG(buf, v) ((long)IXDR_PUT_INT32(buf, (long)(v))) #endif #ifndef IXDR_GET_U_LONG #define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf)) #endif #ifndef IXDR_PUT_U_LONG #define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG(buf, (long)(v)) #endif
See /usr/include/boost/config/platform/solaris.hpp
: -D_PTHREADS
must be defined, use g++ -pthread
For a while Dyson uses illumos libc, not GNU libc.
Some functions, expected to be in libc, really are in libsocket, libnsl and libresolv. Also Dyson uses GNU libiconv.
Workaround:
$ cat /usr/lib/x86_64-illumos/libc.so INPUT(libc.so.1 AS_NEEDED(-lsocket -lnsl -lresolv -liconv))
librt, libphtread, libdl are dummy ("filters"). There is not need to link with these libraries, all functions expected to be in these libraries are in libc or ld.so.1 (not worry either).
There are specific functions to work with extended attributes of files. These functions involve illumos library libnvpair. Functions known from Linux are provided by libattr (see #59).
See particular recipes.
illumos and Solaris have been using it for a long time. GNU/Linux is going to use it too. But now in Debian /bin
and /usr/bin
are separated. So additional modifications are required for some "low-level" packages like "sed", "ed", all shells, etc.
x86_64-illumos
for Dyson on x86_64 (64-bit) processorsi386-illumos
for Dyson on x86 (32-bit) processors (this distribution does not exist)So Dyson on amd64 has directories /lib/x86_64-illumos
and /usr/lib/x86_64-illumos
.
Some packages (e. g. "sudo") detect "SunOS" and put manpages in different directories, and dh_install
cannot find some manpages after that. Debian man page layout (aka GNU-style) is prefered.
The first version of GCC supporting x86_64-pc-solaris2.11
hosts is 4.7
uname
returns "SunOS", the linker is the SunOS linker.kbuild used to pass the "-i
" to the linker; for sun ld this means "Ignore the LD_LIBRARY_PATH", for GNU ld - "Incremental link".
Some rules for logrotate run init-scripts for sysvinit, e. g. Apache and Lighttpd.
See http://git.osdyson.ru/dh-smf.git
# ./rebuild pandoc Reading package lists... Done Building dependency tree Reading state information... Done E: Build-Depends dependency for pandoc cannot be satisfied because candidate version of package libghc-aeson-dev can't satisfy version requirements # ./rebuild libghc-aeson-dev
Non-interactively update a package from Debian source repository.
# cat /etc/apt/sources.list deb http://apt.osdyson.ru unstable main deb-src http://http.debian.net/debian sid main
Add your GPG key to GPG agent to bypass passphrase
/etc/dput.cf
:
[dyson] login= pashev fqdn= apt.osdyson.org method= scp incoming= /srv/apt/incoming allow_dcut= 1 post_upload_command = ssh apt.osdyson.ru /srv/apt/script/import-new-packages.sh && sudo apt-get update
#!/bin/sh set -u set -e set -x pkg="$1" vertries=7 sudo apt-get -y build-dep "$pkg" curver=`(apt-cache show $pkg || echo 'Version: 0~0') | awk '/Version:/ {print $2}'` tmpdir=`mktemp -d "/var/tmp/pkg-${pkg}-XXXXXXX"` cd "$tmpdir" apt-get source "$pkg" pkgdir=`find * -maxdepth 0 -type d | head -n 1` echo "*** building in $pkgdir ***" cd "$pkgdir" dch --l '+dyson' 'Package for Dyson' bump=0 while true; do newver=`dpkg-parsechangelog | awk '/Version:/ {print $2}'` if dpkg --compare-versions "$newver" gt "$curver"; then break else if [ $bump = 0 ]; then echo "There is already package version $newver in Dyson. Bump version? [y/N]" read bump fi case $bump in y|Y|yes|Yes) dch -i '' vertries=`expr $vertries - 1 || true` if [ $vertries = 0 ]; then echo "Version bump failed!" exit 1 fi ;; *) echo "Aborted" >&2 exit 1 ;; esac fi done dch -r '' dpkg-buildpackage -sa dput dyson `realpath ../*.changes` cd rm -fr -- "$tmpdir" exit 0
If Debian packages needs more attention than a simple patch to upstream sources, they need to be ported, and changes should be tracked in Git. After experimenting some time the best approach has been found.
1. Some Debian packages aren't tracked in Git at all. Subversion, Bazaar are still quite popular. This affects essential and the most hard to port and maintain packages like Binutils, GCC, OpenJDK, etc.
2. Debian repositories can stale, that is new packages are uploaded to APT repositories, but VCS repositories aren't updated. It is especially painful when a new version is required to fulfill build dependencies.
3. Most of Debian's Git repositories are bloated with upstream sources, pristine tarballs, branches, etc. We don't need them all. It all needs a lot of storage.
As some of Debian packages do, we should track only the ./debian
directory without upstream sources or tarballs. After all, we take them from Debian. We completely ignore Debian's VCS be it Git, Subversion or Bazaar. Instead
we start a git repository by importing the ./debian
directory of some Debian version, and then we make and track our changes in the master
branch. Vanilla Debian's version is tracked in the debian
branch. When a new version
lands in Debian and need to be ported, we import it into the debian
branch first (with no conflicts, etc.) and then merge the debian
branch into the master
branch, resolve conflicts, update Dyson specific parts etc.
See for example Binutils
The .git
directory is not friendly to dpkg format version 1.0. It can be moved away before building packages or dpkg-source
can be told to ignore it.