Project

General

Profile

Actions

tickets #95015

closed

makehashes - ValueError: A string literal cannot contain NUL (0x00) characters.

Added by pjessen almost 3 years ago. Updated almost 2 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Mirrors
Target version:
-
Start date:
2021-07-02
Due date:
% Done:

0%

Estimated time:

Description

The daily job "/usr/bin/mb makehashes -b /srv/ftp-stage/pub/opensuse -t /srv/metalink-hashes/srv/ftp/pub/opensuse/ /srv/ftp-stage/pub/opensuse/repositories" has been failing for the last day or two:

Traceback (most recent call last):
  File "/usr/bin/mb", line 1729, in <module>
    r = mirrordoctor.main()
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 261, in main
    return self.cmd(args)
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 284, in cmd
    retval = self.onecmd(argv)
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 422, in onecmd
    return self._dispatch_cmd(handler, argv)
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 1123, in _dispatch_cmd
    return handler(argv[0], opts, *args)
  File "/usr/bin/mb", line 1148, in do_makehashes
    force=opts.force)
  File "/usr/lib64/python2.7/site-packages/mb/hashes.py", line 214, in check_db
    file_id])
ValueError: A string literal cannot contain NUL (0x00) characters.
Actions #1

Updated by lrupp almost 3 years ago

  • Category set to Mirrors
Actions #2

Updated by pjessen over 2 years ago

  • Private changed from Yes to No

Just to confirm the error is still there. The cron output is sent to admin-auto.

Actions #3

Updated by pjessen over 2 years ago

I ran a makehash with -v and found the file causing the problem:

/srv/ftp-stage/pub/opensuse/repositories/home:/legoktm/Debian_9.0/mediawiki_1.31.1.orig.tar.gz

Prior to that one, 93 other files had their hashes updated. The file exists in table 'filearr':

    id     |                                path                                |            mirrors            |                dirname                 |           filename           
-----------+--------------------------------------------------------------------+-------------------------------+----------------------------------------+------------------------------
 230646335 | repositories/home:/legoktm/Debian_9.0/mediawiki_1.31.1.orig.tar.gz | {495,582,566,169,508,583,177} | repositories/home:/legoktm/Debian_9.0/ | mediawiki_1.31.1.orig.tar.gz
Actions #4

Updated by pjessen over 2 years ago

Yesterday, I deleted the entry (id 230646335) from the 'hash' table and started a manual makehashes run. It ran for about five hours, until:

Hashing '/srv/ftp-stage/pub/opensuse/repositories/home:/legoktm/Debian_9.0/mediawiki_1.31.1.orig.tar.gz'... 
Traceback (most recent call last):
done.
  File "/usr/bin/mb", line 1729, in <module>
    r = mirrordoctor.main()
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 261, in main
    return self.cmd(args)
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 284, in cmd
    retval = self.onecmd(argv)
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 422, in onecmd
    return self._dispatch_cmd(handler, argv)
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 1123, in _dispatch_cmd
    return handler(argv[0], opts, *args)
  File "/usr/bin/mb", line 1148, in do_makehashes
    force=opts.force)
  File "/usr/lib64/python2.7/site-packages/mb/hashes.py", line 175, in check_db
    binascii.hexlify(''.join(self.hb.zsums))]
ValueError: A string literal cannot contain NUL (0x00) characters.

The 'hash' table is defined thus:

mb_opensuse2=# \d hash
                          Table "public.hash"
    Column     |         Type         | Collation | Nullable | Default 
---------------+----------------------+-----------+----------+---------
 file_id       | integer              |           | not null | 
 mtime         | integer              |           | not null | 
 size          | bigint               |           | not null | 
 md5           | bytea                |           | not null | 
 sha1          | bytea                |           | not null | 
 sha256        | bytea                |           | not null | 
 sha1piecesize | integer              |           | not null | 
 sha1pieces    | bytea                |           | not null | 
 btih          | bytea                |           | not null | 
 pgp           | text                 |           | not null | 
 zblocksize    | smallint             |           | not null | 
 zhashlens     | character varying(8) |           |          | 
 zsums         | bytea                |           | not null | 

I'm no postgresql expert, but 'string' seems to mean fields 'pgp' or 'zhashlens'.

Actions #5

Updated by pjessen over 2 years ago

I added some debug output to /usr/lib64/python2.7/site-packages/mb/hashes.py to print the values of pgp and zhashlens.

Hashing '/srv/ftp-stage/pub/opensuse/repositories/home:/legoktm/Debian_9.0/mediawiki_1.31.1.orig.tar.gz'... done.
pgp = '\x88]\x04\x00\x11\x02\x00\x1d\x16!\x04\x1d\x98\x86~\x82\x98,\x8f\xe0\xab\xc2_\x9bi\xb3\x10\x9d;\xb7\xb0\x05\x02[\xa3\xf0\xf8\x00\n\t\x10\x9bi\xb3\x10\x9d;\xb7\xb0@_\x00\x9ft\x82j\x16\xd5\xa0\xb6\xb2\x9f<+,\xe0-\xb7\xac\x9c\xec\x1a\x91\x00\xa0\xae\x93Tg\xe7a\x7f\xd4\x9d#\xcc\xa9\x95DV\xd9*\x12`\xd7'
zhashlens = ''

So, 'pgp' has four 0x00s ... the pgp signature is read from mediawiki_1.31.1.orig.tar.gz.asc, which does indeed contain some gobbledegook.

Actions #6

Updated by pjessen over 2 years ago

I ended up renaming:

/srv/ftp-stage/pub/opensuse/repositories/home:/legoktm/xUbuntu_18.04/mediawiki_1.31.1.orig.tar.gz.asc 
to
/srv/ftp-stage/pub/opensuse/repositories/home:/legoktm/xUbuntu_18.04/mediawiki_1.31.1.orig.tar.gz.xasc

and

/srv/ftp-stage/pub/opensuse/repositories/home:/legoktm/Debian_9.0/mediawiki_1.31.1.orig.tar.gz.asc 
to
/srv/ftp-stage/pub/opensuse/repositories/home:/legoktm/Debian_9.0/mediawiki_1.31.1.orig.tar.gz.xasc

After that, the makehashes run continued much longer, but still eventually failed:

Unlinking obsolete '/srv/metalink-hashes/srv/ftp/pub/opensuse/repositories/vdr/openSUSE_Factory_ARM/src/vdradmin-am-3.6.10-4.26.src.rpm.size_627000'
Traceback (most recent call last):
  File "/usr/bin/mb", line 1729, in <module>
    r = mirrordoctor.main()
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 261, in main
    return self.cmd(args)
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 284, in cmd
    retval = self.onecmd(argv)
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 422, in onecmd
    return self._dispatch_cmd(handler, argv)
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 1123, in _dispatch_cmd
    return handler(argv[0], opts, *args)
  File "/usr/bin/mb", line 1046, in do_makehashes
    os.makedirs(dst_dir, mode = 0755)
  File "/usr/lib64/python2.7/os.py", line 157, in makedirs
    mkdir(name, mode)
OSError: [Errno 17] File exists: '/srv/metalink-hashes/srv/ftp/pub/opensuse/repositories/vdr/openSUSE_Leap_15.3/noarch'
Actions #7

Updated by pjessen over 2 years ago

  • Status changed from New to Workable
  • Assignee set to pjessen

Latest status from today:

Traceback (most recent call last):
  File "/usr/bin/mb", line 1729, in <module>
    r = mirrordoctor.main()
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 261, in main
    return self.cmd(args)
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 284, in cmd
    retval = self.onecmd(argv)
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 422, in onecmd
    return self._dispatch_cmd(handler, argv)
  File "/usr/lib/python2.7/site-packages/cmdln.py", line 1123, in _dispatch_cmd
    return handler(argv[0], opts, *args)
  File "/usr/bin/mb", line 1148, in do_makehashes
    force=opts.force)
  File "/usr/lib64/python2.7/site-packages/mb/hashes.py", line 180, in check_db
    binascii.hexlify(''.join(self.hb.zsums))]
ValueError: A string literal cannot contain NUL (0x00) characters.

I'm going to go through the filesystem tree, looking for files names '.asc$' and containing invalid characters.

Actions #8

Updated by pjessen over 2 years ago

The following files contain weird binary gunk:

./repositories/home:/jejb1:/TPM/Debian_Testing/gnupg2_2.2.25.orig.tar.bz2.asc
./repositories/home:/legoktm:/mediawiki/Debian_9.0/mediawiki_1.31.1.orig.tar.gz.asc
./repositories/home:/legoktm:/mediawiki/Raspbian_9.0/mediawiki_1.31.1.orig.tar.gz.asc
./repositories/home:/legoktm:/mediawiki/xUbuntu_18.04/mediawiki_1.31.1.orig.tar.gz.asc

I think I ought to be able to exclude those using the '-i' option on the makehashes command.

Actions #9

Updated by pjessen over 2 years ago

pjessen wrote:

I think I ought to be able to exclude those using the '-i' option on the makehashes command.

1st attempt - using two '-i' options:

/usr/bin/mb makehashes -b /srv/ftp-stage/pub/opensuse -t /srv/metalink-hashes/srv/ftp/pub/opensuse/ -i 'repositories/home:/legoktm:/mediawiki/Debian_9.0/mediawiki_1.31.1' -i 'repositories/home:/jejb1:/TPM/Debian_Testing/gnupg2_2.2.25'

Looks like the command doesn't work with multiple exclusions ....

Combining the two regexes into one:

-i 'repositories/home:/legoktm:/mediawiki/Debian_9.0/mediawiki_1.31.1|repositories/home:/jejb1:/TPM/Debian_Testing/gnupg2_2.2.25'

The shell somehow sees the '|' as a pipe ... well, that is probably due to the makehashes command being wrapped in another script (withlock).
Running it manually seems to work, but I still need to run it with cron and withlock.

Actions #10

Updated by pjessen over 2 years ago

Better "solution" - hack /usr/lib64/python2.7/site-packages/mb/hashes.py :

    from string import printable
    if set(str(self.hb.pgp)).difference(printable):
        self.hb.pgp=''

It seems reasonable to ignore invalid characters. Running a new makehashes just now, we'll see if it works.

Actions #11

Updated by pjessen over 2 years ago

It worked! makehashes is running continually, see /home/mirror/bin/update_metalinks2 - doing repositories takes quite long though, the last run took 37hours ... another one started last night at 1916, it is still running.

We are currently creating hashes for

repositories distribution debug "history" "source" update factory-snapshot

"factory-snapshot" does not exist any more, we have "tumbleweed". Also, "ports" is missing. I've updated /home/mirror/bin/update_metalinks2 accordingly:

repositories distribution debug "history" "source" update tumbleweed ports

I worry about the time needed to hash "repositories", if it is going to continue to take so long, we'll have to think of parallelising this process.

Actions #12

Updated by pjessen over 2 years ago

pjessen wrote:

It worked! makehashes is running continually, see /home/mirror/bin/update_metalinks2 - doing repositories takes quite long though, the last run took 37hours ... another one started last night at 1916, it is still running.

Started at 2021-09-13T19:16:59, now at 2021-09-15T06:24:51 it is still running. The previous run took exactly 37h:37m:16s, so maybe this one will finish around 08:53 UTC?

Actions #13

Updated by pjessen over 2 years ago

pjessen wrote:

Started at 2021-09-13T19:16:59, now at 2021-09-15T06:24:51 it is still running. The previous run took exactly 37h:37m:16s, so maybe this one will finish around 08:53 UTC?

Thu 16 Sep 09:09:00 Still running, almost 60 hours later.

Actions #14

Updated by pjessen over 2 years ago

Now at 85 hours. This is getting ridiculous - the /srv filesystem is also 98% full ....

Actions #15

Updated by pjessen over 2 years ago

It finally finished, this morning:

Start time  = 2021-09-13T19:16:59
End time    = 2021-09-18T06:06:50
Elapse time = 106h 49m 51s

For now, I have removed 'repositories' from the directory list in /home/mirror/bin/update_metalinks2, I think I'll let it run in parallel to the rest.

Actions #16

Updated by pjessen over 2 years ago

Mostly notes for myself -

running the makehashes on 'distribution debug history source update tumbleweed ports' can now be done in reasonable time, maybe 1-2 hours in total. 'repositories' still takes a day, sometimes more.
I have created a metalinkhashes@.service - if instance='none', it runs the directories above.

I have enabled two services running continually -

metalinkhashes@none.service
metalinkhashes@repositories.service

Output is sent to 'admin-auto', but only when there is anything to report.
metalinkhashes@none.service could really be run once a day on a cron or timer, but with the rate of change we are seeing, I think it is a good idea to let it run continually.

Actions #17

Updated by pjessen over 2 years ago

I have created a separate service for 'ports', I noticed the makehashes run sometimes taking quite a while. Otherwise, my hack (comment 10) worked just fine.
I guess I need to get it merged into our mirrorbrain package.

Actions #18

Updated by pjessen almost 2 years ago

  • Status changed from Workable to New
  • Assignee changed from pjessen to andriinikitin
Actions #19

Updated by andriinikitin almost 2 years ago

  • Status changed from New to Closed

makehashes is disabled after switch to MirrorCache, so closing this.

Actions

Also available in: Atom PDF