Issue 16139: Python 3.3 fails when starting from read-only FS (original) (raw)
This occurs when python is installed on a read-only mount AND all the .pyc files are out-of-date. Therefore, when python starts and attempts to write a new .pyc file, _write_atomic in "Lib/importlib/_bootstrap.py" throws an OSError with an errno of EROFS, which is not handled (and ignored) and kills the interpreter.
$ python Fatal Python error: Py_Initialize: Unable to get the locale encoding Traceback (most recent call last): File "", line 1558, in _find_and_load File "", line 1525, in _find_and_load_unlocked File "", line 586, in _check_name_wrapper File "", line 1023, in load_module File "", line 1004, in load_module File "", line 562, in module_for_loader_wrapper File "", line 854, in _load_module File "", line 990, in get_code File "", line 1051, in _cache_bytecode File "", line 1074, in set_data File "", line 128, in _write_atomic OSError: [Errno 30] Read-only file system: '/lib/python3.3/encodings/pycache/init.cpython-33.pyc.139872939267056' Aborted (core dumped)
The following (hacky) patch fixes the issue for me:
--- a/Python-3.Lib/importlib/_bootstrap.py +++ b/Python-3.Lib/importlib/_bootstrap.py @@ -1070,6 +1070,10 @@ class SourceFileLoader(FileLoader, SourceLoader): # If can't get proper access, then just forget about writing # the data. return
except OSError as e:
if e.errno != 30: # ignore EROFS
raise
return try: _write_atomic(path, data, _mode) _verbose_message('created {!r}', path)
@@ -1077,6 +1081,9 @@ class SourceFileLoader(FileLoader, SourceLoader): # Don't worry if you can't write bytecode or someone is writing # it at the same time. pass
except OSError as e:
if e.errno != 30: # ignore EROFS
raise
Python 3.2 logs an error to stderr (if Python is started in verbose mode) if the directory and/or the pyc file cannot be created, and continue.
#ifdef MS_WINDOWS if (_mkdir(cpathname) < 0 && errno != EEXIST) { #else if (mkdir(cpathname, dirmode) < 0 && errno != EEXIST) { #endif *dirpath = saved; if (Py_VerboseFlag) PySys_WriteStderr( "# cannot create cache dir %s\n", cpathname); return; } *dirpath = saved;
fp = open_exclusive(cpathname, mode);
if (fp == NULL) {
if (Py_VerboseFlag)
PySys_WriteStderr(
"# can't create %s\n", cpathname);
return;
}