gh-99127: Allow some features of syslog to the main interpreter only#99128
gh-99127: Allow some features of syslog to the main interpreter only#99128corona10 merged 23 commits into
Conversation
(.oss) ➜ cpython git:(gh-99127) ✗ ./python.exe -m test test_syslog -R 3:3
Raised RLIMIT_NOFILE: 256 -> 1024
0:00:00 load avg: 3.65 Run tests sequentially
0:00:00 load avg: 3.65 [1/1] test_syslog
beginning 6 repetitions
123456
......
== Tests result: SUCCESS ==
1 test OK.
Total duration: 704 ms
Tests result: SUCCESS |
Sorry, something went wrong.
ronaldoussoren
left a comment
There was a problem hiding this comment.
Something to consider: what happens when multiple sub interpreters use the syslog extension. The current implementation always calls openlog(3) at least once before calling syslog(3), see the check in syslog_syslog_impl.
That results in interference between sub interpreters when in one of them the python code explicitly calls syslog.openlog and the other doesn't.
IMHO the check in syslog_syslog_impl is not necessary because it results in a call to openlog(3) with parameters that match the default behaviour of the syslog library. Removing it is a fairly minor behaviour change though (syslog.syslog will currently override any calls to openlog that were done in C before the first call to syslog.syslog and will stop doing that when removing the check in syslog_syslog_impl).
Sorry, something went wrong.
Thanks that's why I got a headache which makes me close the issue but thanks to suggest the solution.
Yeah, IIUC we should call openlog(3) anyway while calling syslog.syslog right? |
Sorry, something went wrong.
Or did you intended implicit call of openlog(3) while calling syslog(3)? |
Sorry, something went wrong.
|
Failure tests from buildbot/PPC64LE Fedora were not related to this change. |
Sorry, something went wrong.
|
Unfortunately I don't have time to review this right now. Maybe @serhiy-storchaka can have a look? He recently did some work on this module. |
Sorry, something went wrong.
At the C level calling openlog(3) before calling syslog(3) is not necessary, although the spec is not entirely clear about this. The linux manual page does clearly mention that openlog(3) is optional, and matches what I remember from older Unix systems. The call to openlog in syslog_syslog_impl basically resets the default system state (use the process name for the ident and log using the LOG_USER facility). Leaving that out should therefore be harmless, but this is technically a user-visible change of behaviour:
Currently the Python code resets the values set in the first step, with my proposal it would no longer do this. I'd consider this a good change, but there's bound to be someone affected by this. |
Sorry, something went wrong.
vstinner
left a comment
There was a problem hiding this comment.
The stateless syslog C API doesn't seem to be designed to be consumed by multiple interpreters. I'm not sure that making S_ident_o and S_log_open global varibles per interpreter is safe.
Sorry, something went wrong.
Oh I missed this, I will push the documentation ASAP. |
Sorry, something went wrong.
|
@vstinner Updated! PTAL @ericsnowcurrently |
Sorry, something went wrong.
vstinner
left a comment
There was a problem hiding this comment.
LGTM. I'm not good to review English, but the code LGTM :-)
Sorry, something went wrong.
ericsnowcurrently
left a comment
There was a problem hiding this comment.
I've left some recommendations for the docs.
Sorry, something went wrong.
|
When you're done making the requested changes, leave the comment: |
Sorry, something went wrong.
Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>
|
I have made the requested changes; please review again |
Sorry, something went wrong.
|
Thanks for making the requested changes! @ericsnowcurrently, @vstinner: please review the changes made to this pull request. |
Sorry, something went wrong.
The limitation comes from Python which stores a Python object in a global variable: We must hold a strong reference because we pass a pointer into the internal UTF-8 encoded flavor of the Unicode string, PyUnicode_AsUTF8(): I understand that openlog() doesn't copy the ident string. Maybe this assumption is wrong and the whole change is not needed. I don't know. I don't want to check the implementation of openlog() on all supported platforms, and run a real test.
Ok, I'm curious and I looked into the GNU glibc: https://sourceware.org/git/?p=glibc.git;a=blob;f=misc/syslog.c;h=f67d4b58a448cabdf63f629f72a9df6e009286cf;hb=HEAD#l295 The ident string is not copied, only the pointer is copied ( |
Sorry, something went wrong.
|
One problem with sub-interpreters is that Python objects should not travel from one interpreter to another. But For closelog(), I proposed earlier a counter increased by syslog.openlog() and decreased by syslog.closelog(). The C function closelog() would only be called when the counter reach zero. One problem is if two interepreters use different identifiers, the latest call to syslog.openlog() wins: it overrides the previous ident (and log level). os.chdir() has a similar problem: it's a process-wide parameter affecting all threads and all interpreters. But it's a simpler problem. The current working directory is stored in the kernel, not in Python, and no resource have to be released explicitly at exit :-) |
Sorry, something went wrong.
|
Agree, keeping a copy of ident in the raw dynamically allocated array will resolve the issue. But I do not think we need a reference counter. Just call |
Sorry, something went wrong.
|
What about keeping a static buffer and copying the str object's C string into it, then giving the buffer to #define MAX_IDENT 256
static char S_ident[MAX_IDENT+1];
...
static PyObject *
syslog_openlog_impl(...)
{
....
const char *ident_str = NULL;
if (ident != NULL) {
Py_ssize_t size = PyUnicode_GET_LENGTH(ident);
if (size > MAX_IDENT) {
PyErr_SetString(...);
return NULL;
}
else if (size > 0) {
strncpy(S_ident, PyUnicode_AsUTF8(ident), size);
ident_str = S_ident;
}
}
openlog(ident_str, logopt, facility);
Py_RETURN_NONE;
}
static PyObject *
syslog_syslog_impl(...)
{
if (PySys_Audit("syslog.syslog", "is", priority, message) < 0) {
...
}
#ifdef __APPLE__
// gh-98178: On macOS, libc syslog() is not thread-safe
syslog(priority, "%s", message);
#else
Py_BEGIN_ALLOW_THREADS;
syslog(priority, "%s", message);
Py_END_ALLOW_THREADS;
#endif
Py_RETURN_NONE;
}
static PyObject *
syslog_closelog_impl(PyObject *module)
{
...
closelog();
Py_RETURN_NONE;
}There would still be a race under per-interpreter GIL, though, if subinterpreters are allowed to call |
Sorry, something went wrong.
|
@ronaldoussoren @vstinner @ericsnowcurrently As the first step for the subinterpreter project, I would like to suggest maintaining restrictions for subinterpreter as the current PR. |
Sorry, something went wrong.
* main: (112 commits) pythongh-99894: Ensure the local names don't collide with the test file in traceback suggestion error checking (python#99895) pythongh-99612: Fix PyUnicode_DecodeUTF8Stateful() for ASCII-only data (pythonGH-99613) Doc: Add summary line to isolation_level & autocommit sqlite3.connect params (python#99917) pythonGH-98906 ```re``` module: ```search() vs. match()``` section should mention ```fullmatch()``` (pythonGH-98916) pythongh-89189: More compact range iterator (pythonGH-27986) bpo-47220: Document the optional callback parameter of weakref.WeakMethod (pythonGH-25491) pythonGH-99905: Fix output of misses in summarize_stats.py execution counts (pythonGH-99906) pythongh-99845: PEP 670: Convert PyObject macros to functions (python#99850) pythongh-99845: Use size_t type in __sizeof__() methods (python#99846) pythonGH-99877) Fix typo in exception message in `multiprocessing.pool` (python#99900) pythongh-87092: move all localsplus preparation into separate function called from assembler stage (pythonGH-99869) pythongh-99891: Fix infinite recursion in the tokenizer when showing warnings (pythonGH-99893) pythongh-99824: Document that sqlite3.connect implicitly open a transaction if autocommit=False (python#99825) pythonGH-81057: remove static state from suggestions.c (python#99411) Improve zip64 limit error message (python#95892) pythongh-98253: Break potential reference cycles in external code worsened by typing.py lru_cache (python#98591) pythongh-99127: Allow some features of syslog to the main interpreter only (pythongh-99128) pythongh-82836: fix private network check (python#97733) Docs: improve accuracy of socketserver reference (python#24767) ...
edited by bedevere-bot
LoadingUh oh!
There was an error while loading. Please reload this page.
Copy link Copy MarkdownSorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.