Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add overflow checks to refcounting, port stuff to Cython etc #891

Merged
merged 2 commits into from
Apr 14, 2016

Conversation

enkore
Copy link
Contributor

@enkore enkore commented Apr 11, 2016

(This changeset does not include #890, since that one is already for 1.0-maint. It supersedes merged #887, and unmerged #888 for master)

@codecov-io
Copy link

Current coverage is 82.58%

Merging #891 into 1.0-maint will decrease coverage by -0.01% as of 5a99605

@@            1.0-maint    #891   diff @@
=========================================
  Files              14      14       
  Stmts            4132    4129     -3
  Branches          730     730       
  Methods             0       0       
=========================================
- Hit              3413    3410     -3
  Partial           210     210       
  Missed            509     509       

Review entire Coverage Diff as of 5a99605


Uncovered Suggestions

  1. +0.36% via borg/helpers.py#848...862
  2. +0.29% via borg/upgrader.py#316...327
  3. +0.27% via borg/archiver.py#620...630
  4. See 7 more...

Powered by Codecov. Updated on successful CI builds.

((uint32_t) -1) - 1 mark empty entries.

This, among other things, limits the number of segments in a repository to 2**32-2. This is a hard limit above
which data corruption will always occur.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

~10 PB

@enkore enkore changed the title Port hashindex_summarize to Cython, and use fixed-width integer types Add overflow checks to refcounting, port stuff to Cython etc Apr 12, 2016
@@ -155,12 +166,13 @@ cdef class NSKeyIterator:
cdef class ChunkIndex(IndexBase):

value_size = 12
max_ref = 2**30-1 # to be *extra* safe, from constants like EMPTY and DELETED
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not make this 231-2 to double the space? Also 232-2 should also work it appears since the refcount cannot be negative, so we can always go for the unsigned as the counter, so (unsigned) -1 is deleted, (unsigned)-2 is empty and (unsigned) -3 is "too popular".

This is likely not super critical due to a sheer repetition count, I guess.

@verygreen
Copy link
Contributor

I tried the current feature branch on a powermac (fedora23), and this is the result:

[root@powermac borg]# fakeroot -u tox
GLOB sdist-make: /root/bk/borg/setup.py
py34 create: /root/bk/borg/.tox/py34
py34 installdeps: -rrequirements.d/development.txt, attic
py34 inst: /root/bk/borg/.tox/dist/borgbackup-1.0.2.dev10+ng1f70fbd.zip
py34 installed: You are using pip version 7.1.2, however version 8.1.1 is available.,You should consider upgrading via the 'pip install --upgrade pip' command.,Attic==0.16,borgbackup==1.0.2.dev10+ng1f70fbd,coverage==4.0.3,Cython==0.24,msgpack-python==0.4.7,pluggy==0.3.1,py==1.4.31,pytest==2.9.1,pytest-benchmark==3.0.0,pytest-cov==2.2.1,tox==2.3.1,virtualenv==13.1.2,wheel==0.24.0
py34 runtests: PYTHONHASHSEED='3606867701'
py34 runtests: commands[0] | py.test --cov=borg --cov-config=../.coveragerc --benchmark-skip --pyargs borg.testsuite
============================= test session starts ==============================
platform linux -- Python 3.4.3, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
benchmark: 3.0.0 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=5.00us max_time=1.00s calibration_precision=10 warmup=False warmup_iterations=100000)
rootdir: /root/bk/borg, inifile: setup.cfg
plugins: benchmark-3.0.0, cov-2.2.1
collected 515 items 

py34/lib/python3.4/site-packages/borg/testsuite/archive.py .......
py34/lib/python3.4/site-packages/borg/testsuite/archiver.py .s.....................ss.........X.........ssssssssssssssssssssssssssssssssssssssssss...............s...........ss.........X...........
py34/lib/python3.4/site-packages/borg/testsuite/benchmark.py sssssssssssssssssssssssssssssssssssssssssssssssss
py34/lib/python3.4/site-packages/borg/testsuite/chunker.py ...
py34/lib/python3.4/site-packages/borg/testsuite/compress.py ........
py34/lib/python3.4/site-packages/borg/testsuite/crypto.py ...
py34/lib/python3.4/site-packages/borg/testsuite/hashindex.py ..............
py34/lib/python3.4/site-packages/borg/testsuite/helpers.py .............................................................................................................................................................
py34/lib/python3.4/site-packages/borg/testsuite/key.py ....
py34/lib/python3.4/site-packages/borg/testsuite/locking.py ..............
py34/lib/python3.4/site-packages/borg/testsuite/logger.py ....
py34/lib/python3.4/site-packages/borg/testsuite/lrucache.py ..
py34/lib/python3.4/site-packages/borg/testsuite/platform.py sssss
py34/lib/python3.4/site-packages/borg/testsuite/repository.py ........................................
py34/lib/python3.4/site-packages/borg/testsuite/shellpattern.py .............................................................
py34/lib/python3.4/site-packages/borg/testsuite/upgrader.py .......
py34/lib/python3.4/site-packages/borg/testsuite/xattr.py s
---------------- coverage: platform linux, python 3.4.3-final-0 ----------------
Name                                                    Stmts   Miss Branch BrPart  Cover
-----------------------------------------------------------------------------------------
py34/lib/python3.4/site-packages/borg/archive.py          665     70    285     38    88%
py34/lib/python3.4/site-packages/borg/archiver.py         707    111    233     30    83%
py34/lib/python3.4/site-packages/borg/cache.py            314     23    100     20    89%
py34/lib/python3.4/site-packages/borg/helpers.py          638     84    219     25    86%
py34/lib/python3.4/site-packages/borg/key.py              306     54     72     23    76%
py34/lib/python3.4/site-packages/borg/locking.py          184     12     60      9    91%
py34/lib/python3.4/site-packages/borg/logger.py            80     19     16      4    74%
py34/lib/python3.4/site-packages/borg/lrucache.py          31      0      4      0   100%
py34/lib/python3.4/site-packages/borg/platform.py           5      2      0      0    60%
py34/lib/python3.4/site-packages/borg/remote.py           267     31    117     21    84%
py34/lib/python3.4/site-packages/borg/repository.py       564     37    210     25    91%
py34/lib/python3.4/site-packages/borg/shellpattern.py      36      0     22      0   100%
py34/lib/python3.4/site-packages/borg/upgrader.py         169     55     52     12    61%
py34/lib/python3.4/site-packages/borg/xattr.py            160     87     72     13    41%
-----------------------------------------------------------------------------------------
TOTAL                                                    4126    585   1462    220    83%

============= 410 passed, 103 skipped, 2 xpassed in 782.38 seconds =============
py35 create: /root/bk/borg/.tox/py35
ERROR: InterpreterNotFound: python3.5
flake8 create: /root/bk/borg/.tox/flake8
flake8 installdeps: flake8
flake8 inst: /root/bk/borg/.tox/dist/borgbackup-1.0.2.dev10+ng1f70fbd.zip
flake8 installed: You are using pip version 7.1.2, however version 8.1.1 is available.,You should consider upgrading via the 'pip install --upgrade pip' command.,borgbackup==1.0.2.dev10+ng1f70fbd,flake8==2.5.4,mccabe==0.4.0,msgpack-python==0.4.7,pep8==1.7.0,pyflakes==1.0.0,wheel==0.24.0
flake8 runtests: PYTHONHASHSEED='3606867701'
flake8 runtests: commands[0] | flake8
___________________________________ summary ____________________________________
  py34: commands succeeded
ERROR:   py35: InterpreterNotFound: python3.5
  flake8: commands succeeded

@enkore
Copy link
Contributor Author

enkore commented Apr 12, 2016

That looks indeed good. Can you try with 0ac324c whether that still works for BE? Just using INT32_MAX for the ceiling should probably be no problem, but I will have to think some more about it to be sure... [and if we keep that we'll just remove MAX_REF altogether and just write int32_max -- plus, I can then clean up the tests a bit]

Naturally all of this breaks for non two's complement, but I doubt that's relevant.

@verygreen
Copy link
Contributor

[root@powermac borg]# fakeroot -u tox
GLOB sdist-make: /root/bk/borg/setup.py
py34 inst-nodeps: /root/bk/borg/.tox/dist/borgbackup-1.0.2.dev11+ng0ac324c.zip
py34 installed: You are using pip version 7.1.2, however version 8.1.1 is available.,You should consider upgrading via the 'pip install --upgrade pip' command.,Attic==0.16,borgbackup==1.0.2.dev11+ng0ac324c,coverage==4.0.3,Cython==0.24,msgpack-python==0.4.7,pluggy==0.3.1,py==1.4.31,pytest==2.9.1,pytest-benchmark==3.0.0,pytest-cov==2.2.1,tox==2.3.1,virtualenv==13.1.2,wheel==0.24.0
py34 runtests: PYTHONHASHSEED='366175955'
py34 runtests: commands[0] | py.test --cov=borg --cov-config=../.coveragerc --benchmark-skip --pyargs borg.testsuite
============================= test session starts ==============================
platform linux -- Python 3.4.3, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
benchmark: 3.0.0 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=5.00us max_time=1.00s calibration_precision=10 warmup=False warmup_iterations=100000)
rootdir: /root/bk/borg, inifile: setup.cfg
plugins: benchmark-3.0.0, cov-2.2.1
collected 515 items 

py34/lib/python3.4/site-packages/borg/testsuite/archive.py .......
py34/lib/python3.4/site-packages/borg/testsuite/archiver.py .s.....................ss.........X.........ssssssssssssssssssssssssssssssssssssssssss...............s...........ss.........X...........
py34/lib/python3.4/site-packages/borg/testsuite/benchmark.py sssssssssssssssssssssssssssssssssssssssssssssssss
py34/lib/python3.4/site-packages/borg/testsuite/chunker.py ...
py34/lib/python3.4/site-packages/borg/testsuite/compress.py ........
py34/lib/python3.4/site-packages/borg/testsuite/crypto.py ...
py34/lib/python3.4/site-packages/borg/testsuite/hashindex.py ..............
py34/lib/python3.4/site-packages/borg/testsuite/helpers.py .............................................................................................................................................................
py34/lib/python3.4/site-packages/borg/testsuite/key.py ....
py34/lib/python3.4/site-packages/borg/testsuite/locking.py ..............
py34/lib/python3.4/site-packages/borg/testsuite/logger.py ....
py34/lib/python3.4/site-packages/borg/testsuite/lrucache.py ..
py34/lib/python3.4/site-packages/borg/testsuite/platform.py sssss
py34/lib/python3.4/site-packages/borg/testsuite/repository.py ........................................
py34/lib/python3.4/site-packages/borg/testsuite/shellpattern.py .............................................................
py34/lib/python3.4/site-packages/borg/testsuite/upgrader.py .......
py34/lib/python3.4/site-packages/borg/testsuite/xattr.py s
---------------- coverage: platform linux, python 3.4.3-final-0 ----------------
Name                                                    Stmts   Miss Branch BrPart  Cover
-----------------------------------------------------------------------------------------
py34/lib/python3.4/site-packages/borg/archive.py          665     70    285     38    88%
py34/lib/python3.4/site-packages/borg/archiver.py         707    111    233     30    83%
py34/lib/python3.4/site-packages/borg/cache.py            314     23    100     20    89%
py34/lib/python3.4/site-packages/borg/helpers.py          638     86    219     26    85%
py34/lib/python3.4/site-packages/borg/key.py              306     54     72     23    76%
py34/lib/python3.4/site-packages/borg/locking.py          184     12     60      9    91%
py34/lib/python3.4/site-packages/borg/logger.py            80     19     16      4    74%
py34/lib/python3.4/site-packages/borg/lrucache.py          31      0      4      0   100%
py34/lib/python3.4/site-packages/borg/platform.py           5      2      0      0    60%
py34/lib/python3.4/site-packages/borg/remote.py           267     29    117     21    85%
py34/lib/python3.4/site-packages/borg/repository.py       564     37    210     25    91%
py34/lib/python3.4/site-packages/borg/shellpattern.py      36      0     22      0   100%
py34/lib/python3.4/site-packages/borg/upgrader.py         169     55     52     12    61%
py34/lib/python3.4/site-packages/borg/xattr.py            160     87     72     13    41%
-----------------------------------------------------------------------------------------
TOTAL                                                    4126    585   1462    221    83%

============= 410 passed, 103 skipped, 2 xpassed in 782.69 seconds =============
py35 create: /root/bk/borg/.tox/py35
ERROR: InterpreterNotFound: python3.5
flake8 inst-nodeps: /root/bk/borg/.tox/dist/borgbackup-1.0.2.dev11+ng0ac324c.zip
flake8 installed: You are using pip version 7.1.2, however version 8.1.1 is available.,You should consider upgrading via the 'pip install --upgrade pip' command.,borgbackup==1.0.2.dev11+ng0ac324c,flake8==2.5.4,mccabe==0.4.0,msgpack-python==0.4.7,pep8==1.7.0,pyflakes==1.0.0,wheel==0.24.0
flake8 runtests: PYTHONHASHSEED='366175955'
flake8 runtests: commands[0] | flake8
___________________________________ summary ____________________________________
  py34: commands succeeded
ERROR:   py35: InterpreterNotFound: python3.5
  flake8: commands succeeded

@enkore enkore force-pushed the feature/cython-summarize branch from 4d43b66 to b7c6504 Compare April 12, 2016 15:17
@enkore
Copy link
Contributor Author

enkore commented Apr 12, 2016

Thanks, looks good. I did some cleanup which doesn't affect functionality in b7c6504.

Can you copy the cache (~/.borg/cache//, the repo id is in the repository/config file) from a LE machine to your BE machine (and/or vice versa) and check whether e.g. borg info gives you the same output (pass --debug to make sure that it doesn't rebuild it for some reason).

@verygreen
Copy link
Contributor

copied the cache around from Be to LE and from LE to BE and see no problems.

raise KeyError(key)
cdef int32_t refcount = _le32toh(data[0])
if refcount != INT32_MAX:
if INT32_MAX - refcount < 1:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refcount is not equal to INT32_MAX (see previous "if"), thus INT32_MAX - refcount can never be 0.

So the "< 1" (which is equivalent to "<= 0" for integers) is misleading as it can never be 0.

So what you really meant here is "< 0"?

When is that the case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, refcount != INT32_MAX is already a sufficient check here. It's just the arbitrary additions in _add that need this verbose kind of check. The same applies to decref.

(When MAX_REF != INT32_MAX this would not hold)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check is in fact correct, it is needed for corrupted caches from before this change.
So INT32_MAX - (int32_t)-2 (or any other negative number, really) is some negative number.
It's either this or we need to make sure that refcount is > 0 (I don't think there's such a check on load?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

INT32_MAX - (something negative) is only < 1 for INT32_MIN (because INT32_MIN = -2**31). So if the refcount wrapped around in the past in a cache this wouldn't really work.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure I get what you mean, this has nothing to do with INT32_MIN other than
INT32_MAX - -1 == INT32_MIN
INT32_MAX - -2 == INT32_MIN + 1
...
INT32_MAX - -INT32_MIN == 0

All negative numbers (except the last one, but still smaller than 1)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@enkore The behavior is undefined, but in reality we all know what the end result is.

The problem statement: due to a prior corruption (1.0.[01] on bigendian architectures, integer overflow on very popular chunks before this change was merged, some other sources of corruption) refcount might become negative (ignoring two validly negative values -1 and -2).

We can assume that "this is incorrect refcount, but we are too lazy to calculate correct one, so set it to "really popular" value" - what the current code is doing.
Alternatively the loading method (hashindex_get, except it does not dereference value so not a good fit?) could check the value to be valid (i.e. positive, 0, -1, or -2) and if not - throw the cache away and rebuild or assign a saner "really popular value" or just throw the hands in the air and abort.

I guess there might be other solutions here. But ignoring this condition seems to be the least safe one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we consider this case (and as I wrote above it might be valid to ignore this), then we'd need to do something like

# refcount = -something
if refcount < 0:
  refcount = INT32_MAX  # aha, now refcount set back to INT32_MAX, ok
elif refcount != INT32_MAX:
  refcount += / -= 1  # normal range
# Normal operation: will reach INT32_MAX "naturally" by += 1

For _add we'd need to check sign of operands (because both are variable instead of +-1 as here) and choose appropiate check from there. Overflowing is UB and can't be used.

(or just plain cache corruption of some other sort).

There are no integrity checks for the indices, but they should be added.


Alternatively the loading method (hashindex_get, except it does not dereference value so not a good fit?) could check the value to be valid (i.e. positive, 0, -1, or -2) and if not - throw the cache away and rebuild or assign a saner "really popular value" or just throw the hands in the air and abort.

The hashindex on-disk format is just a copy of the memory contents; it's loaded by loading one huge hunk of data into memory; individual entries are not visited when loading/saving from/to disk.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that for the first overflown values (-1, -2) the chunk is lost from the index. So a chunk would only "survive" overflowing by merging, not from incref/decref. Not relevant to the end result.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope.
In fact the first overflow value is INT32_MIN ( = INT32_MAX + 1).
the -2 and -1 are the two last possible values after which we revert to 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

@enkore
Copy link
Contributor Author

enkore commented Apr 12, 2016

Q: If we just changed all int32_t to uint32_t (and adjust the limit to UINT32_MAX**-3** accordingly), then all wrapped around values from previous signed overflows should become valid, and even correct, refcounts w/o requiring extra handling?

126, 127, -128, -127 => 126, 127, 128, 129

unique_size += _le32toh(values[1])
unique_csize += _le32toh(values[2])
size += <long long> _le32toh(values[1]) * _le32toh(values[0])
csize += <long long> _le32toh(values[2]) * _le32toh(values[0])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 blank too much here after *

@verygreen
Copy link
Contributor

yes, converting to unsigned like that would work.
Keep in mind that if you do that, you are limiting your future self from adding some additional special index counts should you need them. With current approach you have all negative space for that.

idx1.decref(H(1))
refcount, *_ = idx1[H(1)]
assert refcount == self.MAX_REF

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there could be also tests for a normal incref and decref

@enkore
Copy link
Contributor Author

enkore commented Apr 12, 2016

82d31df

... might consider making this change in master only. OTOH not switching
to unsigned needs more complex overflow checks and it looks like no one
is really comfortable writing those...

I'll leave this here so we can think about it for a bit. if we decided
what course of action and what should go where then i'll untangle
what's been intertwined in the course of this changeset.

@enkore
Copy link
Contributor Author

enkore commented Apr 12, 2016

as thomas noted independent of what will be applied to 1.0-maint and/or master (which might be different things in the end): this needs very careful testing & review. the chance that somewhere overflows happened is slim, but the chance that we're putting extra bugs in here is higher.


since the hashtable is fully deterministic we should be able to verify (by file checksum) that these new algorithms generate the exact same caches as before. but that's just one test of many.

if not data:
raise KeyError(key)
return _le32toh(data[0]), _le32toh(data[1])

def __setitem__(self, key, value):
assert len(key) == self.key_size
cdef int32_t[2] data
cdef uint32_t[2] data
assert value[0] <= MAX_REF, "maximum number of segments reached"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in that case, it is a segment number, not a refcount, so MAX_SEGMENT?
or just have a generic MAX_VALUE?

@enkore
Copy link
Contributor Author

enkore commented Apr 14, 2016

as you did a byte order fix for big endian, please mention that - i didn't find a commit comment (1st line) about it.

That was in #887, this changeset only moves that particular fix.

# This bytestring was created with 1.0-maint at c2f9533
HASHINDEX = b'Gb"0J]a]R$\'Sb#Y:I;r1Ne"V?+Yd"E<ckKQkJHQcG61!$2<RPKGOcMn\\j*@DgUo?TdBsRa4pl.0afm>>Z7O2)/Bb=MbH`\\BZ' \
b'7O2)/Bb=MbH`\\BZ7O2)/Bb=MbH`\\BZ7O2)/Bb=MbH`\\BZ7O2)/Bb=MbH`\\BZ7O2)/Bb=MbH`\\BZ7O2)ln@&NF6>#IS_\'+' \
b'nR\'Z76]9h.G?%66bQ=X3bAQb=1=dEW%Q=X3bAQb=1=dEW%Q=X3bAQb=1=dEW%Q=X3bAQb=1=dEW%pAaLig9quB'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe use hex as in other places? or base64 so that it at least doesn't need that many escapes in the value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's go with b64 (not much difference to a85); hexlify is much longer.

@enkore enkore force-pushed the feature/cython-summarize branch 2 times, most recently from f270539 to 19ebe86 Compare April 14, 2016 12:35
# This bytestring was created with 1.0-maint at c2f9533
HASHINDEX = b'eJzt0L0NgmAUhtHLT0LDEI6AuAEhMVYmVnSuYefC7AB3Aj9KNedJbnfyFne6P67P27w0EdG1Eac+Cm1ZybAsy7Isy7Isy7Isy7I' \
b'sy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7LsL9nhc+cqTZ' \
b'3XlO2Ys++Du5fX+l1/YFmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVn2/+0O2rYccw=='
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZ
sy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Ls
interesting. frame/chunk length limit of zlib?

@ThomasWaldmann
Copy link
Member

OK, looks good - merge?

@enkore
Copy link
Contributor Author

enkore commented Apr 14, 2016

Did someone run the tests on BE recently? Otherwise looks "good to merge" to me as well (w/ squashed fixups).

e: btw. can you post how you run the vagrant stuff on ppc on x86?

@ThomasWaldmann
Copy link
Member

@enkore i am just booting the ppc qemu. :)

@enkore
Copy link
Contributor Author

enkore commented Apr 14, 2016

Is there a command line that does that? The whole qemukvmvirtvagrant-thing is a bit of a mystery to me ;)

@ThomasWaldmann
Copy link
Member

https://gmplib.org/~tege/qemu.html

I used ppc (not: ppc64) and debian 8 ooc.

@ThomasWaldmann
Copy link
Member

Linux powerpc 3.16.0-4-powerpc #1 Debian 3.16.7-ckt25-2 (2016-04-08) ppc GNU/Linux
============ 418 passed, 102 skipped, 2 xpassed in 2959.98 seconds =============

@enkore
Copy link
Contributor Author

enkore commented Apr 14, 2016

Thank you, my deb8 ppc is still at Installieren des Grundsystems :D

@enkore enkore force-pushed the feature/cython-summarize branch from 4ce0aab to 29ebdba Compare April 14, 2016 21:42
@enkore enkore merged commit dd95d0e into borgbackup:1.0-maint Apr 14, 2016
@ThomasWaldmann
Copy link
Member

\o/

@enkore enkore deleted the feature/cython-summarize branch April 15, 2016 09:52
@enkore enkore mentioned this pull request Oct 7, 2016
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants