dlfcn: implement dlclose()

Outline of the implementation:

1. For each object, we need an unordered_set<std::shared_ptr<elf::object>>
   of other objects which were used to resolve its symbols.

2. Add std::enable_shared_from_this to class object which would allow to
   get a shared_ptr to it without any additional code.

3. In object::resolve_pltgot(), symbol(sym) returns a symbol_module
   which includes a pointer to the object containing the symbol.

4. For this object*, call object->shared_from_this() and add it to the
   unordered_set

5. Delete the shared_ptr in dlclose(), which will decrease the reference
   count of its dependent modules via the shared_ptrs.

I have tested it via the following method:

  Add a printf in remove_object

  extern int add(int,int);
  dlopen("add.so",RTLD_NOW); 	// resolves the add function
  int c = add(1,2); 	   	// the running .so now contains a reference to the add.so
  dlclose(add.so);		// this does not result in call to remove_object
  return;			// remove_object is first called for the .so and then for add.so

Fixes #150.

Reviewed-by: Nadav Har'El <nyh@cloudius-systems.com>
Signed-off-by: Jaspal Singh Dhillon <jaspal.iiith@gmail.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
math: provide some more floating point symbols

Applications may require symbols like __isinf, __isnanl, etc. The standard
math.h header only provides macros. We currently have an implementation for
__isnan, but not for other important symbols that are being requested by the
application.

C++ have implementations of it, so there is no need to go for craft assemble.
I trully have no idea if our asm inline was more or less efficient than the C++
version, but I can't honestly imagine a program calling isinf in a loop 1
million times per sec.

For the record, it is an obvious possibility that the C++ implementation itself
could use those symbols, but I verified they don't. At least for x86. Example
code:

0000000000000040 <__isinfl>:
  40:   f2 0f 10 0d 00 00 00    movsd  0x0(%rip),%xmm1        # 48 <__isinfl+0x8>
  47:   00
  48:   31 c0                   xor    %eax,%eax
  4a:   55                      push   %rbp
  4b:   66 0f 54 c1             andpd  %xmm1,%xmm0
  4f:   48 89 e5                mov    %rsp,%rbp
  52:   5d                      pop    %rbp
  53:   66 0f 2e 05 00 00 00    ucomisd 0x0(%rip),%xmm0        # 5b <__isinfl+0x1b>
  5a:   00
  5b:   0f 97 c0                seta   %al
  5e:   c3                      retq

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
CC: Claudio Fontana <claudio.fontana@huawei.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
Merge branch 'master' of https://github.com/cloudius-systems/osv
gdb: add osv load-elf command

Sometimes one needs to load external ELF file which loader.py cannot
find automatically. For example when running an application which is
built outside OSv.

Signed-off-by: Tomasz Grabiec <tgrabiec@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
bsd: Implement some of the kobj functions

FreeBSD implements the kobj functions through the use of vnode operations,
whereas I simplified things by making use of system calls.
Otherwise, a bunch of code would have to be ported and adapted.
I'm only implementing here those needed by the function spa_config_load.

Reviewed-by: Glauber Costa <glommer@cloudius-systems.com>
Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
zfs: Re-enable spa_config_load

After the patch 'bsd: Implement kobj function set', spa_config_load can now be
re-enabled. spa_config_load is called during the spa (storage pool allocator)
initialization phase, i.e. spa_init(), and it's intended to populate the SPA
namespace with information stored in the pool configuration files.

Reviewed-by: Glauber Costa <glommer@cloudius-systems.com>
Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
tests: Make misc-fs-stress work on ZFS on Linux

ZFS on Linux doesn't support the O_DIRECT flag.

Reviewed-by: Glauber Costa <glommer@cloudius-systems.com>
Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
scripts: Add script for benchmarking ZFS mount time

The script basically stresses the ZFS dataset with misc-fs-stress, and
lately measures ZFS mount time.

Output example:
$ sudo ./scripts/benchs/zfs_mount.py --samples 3
Running ZFS mount time benchmark, total samples: 3
unit of time: millisecond (ms)
id	time	min	max	avg	stdev
--	----	---	---	---	-----
1	103.0	103.0	103.0	103.0	0.0
2	73.5	73.5	103.0	88.2	10.4
3	76.8	73.5	103.0	84.5	9.6

Reviewed-by: Glauber Costa <glommer@cloudius-systems.com>
Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
zfs: Improve mount time when previous instance has performed I/O

This patch considerably improves ZFS mount time when the previous OSv
instance has performed some I/O.
I tried the same type of benchmark on ZFS on Linux, and the results have
shown that apparently it's not affected by the same problem.

After tracing and investigation, the result showed that the slowness exists
at spa_load_impl procedure, whose purpose is to load an existent storage
pool. Back in time, it was discussed in our mailing list about things being
unfinished in the storage pool, being carried over to the next OSv instance,
and consequently slowing down the next ZFS mount.

The overall problem is quite complex, and requires further investigation to
discover everything about. I'm here coming up with a temporary solution which
consists of syncing all the pools when the last ZFS dataset is being unmounted.

Result:

:: BEFORE ::
$ sudo ./scripts/benchs/zfs_mount.py --samples 10
Running ZFS mount time benchmark, total samples: 10
unit of time: millisecond (ms)
id	time	min	max	avg	stdev
--	----	---	---	---	-----
1	2417.8	2417.8	2417.8	2417.8	0.0
2	1329.3	1329.3	2417.8	1873.6	384.8
3	2949.5	1329.3	2949.5	2232.2	519.8
4	1296.9	1296.9	2949.5	1998.4	570.7
5	3337.5	1296.9	3337.5	2266.2	700.1
6	3399.8	1296.9	3399.8	2455.1	746.4
7	3358.2	1296.9	3399.8	2584.1	750.4
8	2946.7	1296.9	3399.8	2629.5	710.9
9	3002.2	1296.9	3399.8	2670.9	679.2
10	1169.5	1169.5	3399.8	2520.8	773.2

:: AFTER ::
$ sudo ./scripts/benchs/zfs_mount.py --samples 10
Running ZFS mount time benchmark, total samples: 10
unit of time: millisecond (ms)
id	time	min	max	avg	stdev
--	----	---	---	---	-----
1	103.0	103.0	103.0	103.0	0.0
2	73.5	73.5	103.0	88.2	10.4
3	76.8	73.5	103.0	84.5	9.6
4	91.8	73.5	103.0	86.3	8.7
5	120.0	73.5	120.0	93.0	14.4
6	84.3	73.5	120.0	91.6	13.5
7	162.7	73.5	162.7	101.7	26.2
8	103.9	73.5	162.7	102.0	24.5
9	80.0	73.5	162.7	99.6	24.0
10	127.8	73.5	162.7	102.4	24.2

Reviewed-by: Glauber Costa <glommer@cloudius-systems.com>
Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
Fix spelling of "below" in comments.

Signed-off-by: Don Marti <dmarti@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
elf: move arch-specific relocation enums to arch

add a per-arch jump slot define for pltgot relocation,
add basic rela relocations for aarch64.

Signed-off-by: Claudio Fontana <claudio.fontana@huawei.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
elf: replace non-ascii 'fi' character combination with 'fi'

replace a mysterious UTF-8 'fi' character combination with two
ASCII 'fi' characters.

Signed-off-by: Claudio Fontana <claudio.fontana@huawei.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
elf: aarch64: relocate pltgot

this adds basic support for AArch64
object::relocate_pltgot()
object::resolve_pltgot()

including support for lazy binding.

Signed-off-by: Claudio Fontana <claudio.fontana@huawei.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
Add entries to .gitignore

Pekka is suspicious:

  OK, so why are we adding the above to to global osv.git ignore list?
  Neither of them are generated by the OS build system. If they bother
  your workflow, you can hide them in your local git configuration...

Raphael explains:

  The same applies to many files there :-) And it was already discussed
  that .gitignore could afford files that would make the OSv experience
  better.

  tracefile is always generated by the trace tool, and it just doesn't
  make sense to show it, imagine every new people to OSv needlessly
  having to add tracefile to their local git configuration.

Glauber wins:

  I agree with Raphael. We have discussed it before. This criteria of
  "generated by the build" is totally arbitrary. The real thing that
  matters is how many people are likely to have to do it locally.

  Those are quite pervasive files.

Agreed-with-Raphael-by: Glauber Costa <glommer@cloudius-systems.com>
Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
shrinkers: wake_waiters should be called when target is zero

__do_reclaim calls byte_until_normal() to get the target (amount
of memory to be freed), however, when there is no pressure in the
system, zero will be returned.

Going further, either ballooning or registered shrinkers will be
used to aliviate pressure, respectively.

On the latter case, _shrinker_loop will be called to go through
all the registered shrinkers asking each of them to release memory.
The problem is that our code currently assumes target being greater
than zero to wake the waiters after memory has been released, and
that will eventually block everything.

My solution is to call _oom_blocked.wake_waiters() even when target
is zero given that __do_reclaim wakes up even when there is no
memory pressure. Change was tested on memory-hog, which is a good
project to test and play with the shrinker infrastructure.
For those interested, follow: https://github.com/dmarti/memory-hog/

Reviewed-by: Glauber Costa <glommer@cloudius-systems.com>
Reported-by: Don Marti <dmarti@cloudius-systems.com>
Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
elf: move arch-specific object rela relocs to arch

Signed-off-by: Claudio Fontana <claudio.fontana@huawei.com>
Signed-off-by: Avi Kivity <avi@cloudius-systems.com>
elf: move arch-specific object jump slot relocs to arch

Signed-off-by: Claudio Fontana <claudio.fontana@huawei.com>
Signed-off-by: Avi Kivity <avi@cloudius-systems.com>
elf: move arch-specific initial dynamic segment relocs

move the initial arch-specific relocations done in get_init
into the arch-specific directories.

Signed-off-by: Claudio Fontana <claudio.fontana@huawei.com>
Signed-off-by: Avi Kivity <avi@cloudius-systems.com>
drivers: Add null device

Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
Signed-off-by: Avi Kivity <avi@cloudius-systems.com>
mmu: introduce memory areas

This patch introduces memory areas. They are going to be used to determine
which memory allocator is responsible for a particular object.

Signed-off-by: Paweł Dziepak <pdziepak@quarnos.org>
Signed-off-by: Avi Kivity <avi@cloudius-systems.com>