Problema estranho com a instalação do Dwarf Fortress

4

Aqui está a coisa. Estou executando o Mint 19, uma instalação relativamente nova. Eu ouvi muito hype sobre Dwarf Fortress, e instalei uma vez; então, precisando sair às pressas, fechou com Control-C. Desde então, toda vez que eu tento executá-lo, recebo a saída:

/tmp/dwarf-fortresss7j3cousrun/df: 6: /tmp/dwarf-fortresss7j3cousrun/df: ./libs/Dwarf_Fortress: not found
Traceback (most recent call last):
  File "/usr/games/dwarf-fortress", line 93, in <module>
    main()
  File "/usr/games/dwarf-fortress", line 90, in main
    run_df_in_unionfs_with_cleanup(user_run_dir, data_dirs, sys.argv)
  File "/usr/games/dwarf-fortress", line 60, in run_df_in_unionfs_with_cleanup
    run_df_in_unionfs(user_run_dir, data_dirs, args)
  File "/usr/games/dwarf-fortress", line 54, in run_df_in_unionfs
    run_df(tmp_dir, args)
  File "/usr/games/dwarf-fortress", line 46, in run_df
    subprocess.run(cmd).check_returncode()
  File "/usr/lib/python3.6/subprocess.py", line 369, in check_returncode self.stderr)
subprocess.CalledProcessError: Command '['/tmp/dwarf-fortresss7j3cousrun/df', '/usr/games/dwarf-fortress']'
returned non-zero exit status 127.

Seguido pela finalização imediata do programa. Eu tentei remover, até mesmo purgar e reinstalar, anão-fortaleza, apenas para obter o mesmo resultado. Ele correu perfeitamente bem exatamente uma vez, e por mais que eu tenha encarado esse erro, não consigo entender.

Não é essencial para os negócios nem nada, não sou tecnicamente nem um jogador; mas eu realmente gostaria de saber por que o programa está falhando, e de que maneira ele foi quebrado por mim. É apenas um mistério demais para deixar desmarcado. Obrigado pelo seu tempo.

    
por Michael Eric Oberlin 02.09.2018 / 05:28

1 resposta

4

TL; DR: Use o script a seguir para limpar o $XDG_DATA_HOME / $HOME das sobras e desmembrar o% anteriorunionfs:

#!/bin/sh
set -eu

echo Killing currently running Dwarf Fortress instances
killall -q -9 Dwarf_Fortress || true

echo Removing old Dwarf Fortress unionfs mounts and mount points
find /tmp/ -maxdepth 1 -name "dwarf-fortress*" \
  -printf "  Found %f\n" \
  \( -exec fusermount -u {} \; -o -true \) \
  -exec rmdir {} \;


UNIONFSDIR=${XDG_DATA_HOME:-"${HOME:?}/.local/share/"}dwarf-fortress/run/.unionfs-fuse
if [ -d "$UNIONFSDIR" ]; then
  echo Removing old .unionfs-fuse directory
  rm -r "$UNIONFSDIR"
fi
echo Done. Run dwarf-fortress and praise Armok!

Por que isso acontece?

O pacote dwarf-fortress fornecido pelo Ubuntu usa um wrapper /usr/games/dwarf-fortress do Python. Esse wrapper cria uma hierarquia data secundária em $XDG_DATA_HOME/.local/share/dwarf-fortress/run/.unionfs-fuse , que é montada como unionfs(8) junto com alguns outros diretórios.

Isso permite que você coloque seus mods no diretório $XDG_DATA_HOME/.local/share/dwarf-fortress , assim você não precisa alterar o conteúdo de /usr/share/games/dwarf-fortress , o que é ótimo! No entanto, um unionfs deve ser manuseado com cuidado e limpo corretamente. O script Python falhou quando você usou C-c para sair do jogo.

Portanto, o unionfs provavelmente ainda está montado, mas em um estado ruim.

Como faço para corrigir isso?

Então, primeiro de tudo, certifique-se de que o jogo esteja completamente fechado:

killall -s KILL Dwarf_Fortress

Em seguida, certifique-se de que não há restos unionfs DF mount:

mount | grep -a -e dwarf -e unionfs
unionfs on /tmp/dwarf-fortresswvlaptrarun type fuse.unionfs (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)
unionfs on /tmp/dwarf-fortress4ylv2t19run type fuse.unionfs (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)

Como você pode ver, existem atualmente dois no meu sistema. Como ambos estão quebrados, vamos nos livrar deles com fusermount -u :

fusermount -u /tmp/dwarf-fortresswvlaptrarun 
fusermount -u /tmp/dwarf-fortress4ylv2t19run 

Por último, mas o mais importante, remova o .unionfs-fuse em $XDG_DATA_HOME/dwarf-fortress/run/ . Eu não tenho XDG_DATA_HOME set, então eu tenho que usar $HOME . Verifique env antes de excluir acidentalmente o diretório errado!

rm -r $HOME/.local/share/dwarf-fortress/run/.unionfs-fuse

É isso. Note que a versão df_linux de Bay 12 Games não se depara com esses problemas, já que não usa um wrapper do Python nem um Unionfs.

Em geral, acho que esta questão vale um relatório de erros, pois a solução de problemas é um incômodo. O wrapper dwarf-fortress deve fornecer uma opção -clean que manipule este caso. Se possível, por favor arquive um relatório de bug no repositório Debian .

Como surgiu essa solução?

Primeiro de tudo, eu dei uma olhada no file $(which dwarf-fortress) , que me disse que é um script Python:

$ file $(which dwarf-fortress)
/usr/games/dwarf-fortress: Python script, ASCII text executable

Em seguida, verifiquei o script com qualquer editor e encontrei

def get_user_run_dir():
    old_run_dir = xdg.BaseDirectory.save_data_path('dwarf-fortress')
    new_run_dir = os.path.join(old_run_dir, 'run')

    ...

def run_df_in_unionfs(user_run_dir, data_dirs, args):
    mnt_dirs = user_run_dir + "=rw:" + ':'.join(data_dirs)
    with tempfile.TemporaryDirectory(suffix='run', prefix='dwarf-fortress') as tmp_dir:
        cmd = ['unionfs', '-o', 'cow,relaxed_permissions', mnt_dirs, tmp_dir]
        subprocess.run(cmd).check_returncode()
        try:
            run_df(tmp_dir, args)
        finally:
            subprocess.run(['fusermount', '-u', tmp_dir]).check_returncode()

que mostrou que havia pelo menos algo a ser encontrado em xdg.BaseDirectory , que é $HOME/.local/share (a menos que definido de outra forma). Ao mesmo tempo, fusermount -u mostra que há uma desmontagem pendente depois que deixamos o Dwarf Fortress, e mount | grep unionfs confirmou as montagens ativas em /tmp . Eu me livrei do diretório $XDG_DATA_HOME/dwarf-fortress inteiro, e funcionou novamente. Com strace -ff -e trace=execve dwarf-fortress , consegui confirmar as unionfs montagens e encontrei o diretório .unionfs-fuse .

    
por 02.09.2018 / 10:44