2828#include <elfutils/libdwfl.h>
2929#endif
3030
31+ #include "sd-daemon.h"
3132#include "sd-journal.h"
3233#include "sd-login.h"
33- #include "sd-daemon .h"
34+ #include "sd-messages .h"
3435
3536#include "acl-util.h"
3637#include "alloc-util.h"
@@ -93,7 +94,6 @@ typedef enum CoredumpStorage {
9394 COREDUMP_STORAGE_NONE ,
9495 COREDUMP_STORAGE_EXTERNAL ,
9596 COREDUMP_STORAGE_JOURNAL ,
96- COREDUMP_STORAGE_BOTH ,
9797 _COREDUMP_STORAGE_MAX ,
9898 _COREDUMP_STORAGE_INVALID = -1
9999} CoredumpStorage ;
@@ -102,7 +102,6 @@ static const char* const coredump_storage_table[_COREDUMP_STORAGE_MAX] = {
102102 [COREDUMP_STORAGE_NONE ] = "none" ,
103103 [COREDUMP_STORAGE_EXTERNAL ] = "external" ,
104104 [COREDUMP_STORAGE_JOURNAL ] = "journal" ,
105- [COREDUMP_STORAGE_BOTH ] = "both" ,
106105};
107106
108107DEFINE_PRIVATE_STRING_TABLE_LOOKUP (coredump_storage , CoredumpStorage );
@@ -135,6 +134,10 @@ static int parse_config(void) {
135134 false, NULL );
136135}
137136
137+ static inline uint64_t storage_size_max (void ) {
138+ return arg_storage == COREDUMP_STORAGE_EXTERNAL ? arg_external_size_max : arg_journal_size_max ;
139+ }
140+
138141static int fix_acl (int fd , uid_t uid ) {
139142
140143#ifdef HAVE_ACL
@@ -247,7 +250,7 @@ static int maybe_remove_external_coredump(const char *filename, uint64_t size) {
247250
248251 /* Returns 1 if might remove, 0 if will not remove, < 0 on error. */
249252
250- if (IN_SET ( arg_storage , COREDUMP_STORAGE_EXTERNAL , COREDUMP_STORAGE_BOTH ) &&
253+ if (arg_storage == COREDUMP_STORAGE_EXTERNAL &&
251254 size <= arg_external_size_max )
252255 return 0 ;
253256
@@ -331,12 +334,13 @@ static int save_external_coredump(
331334 /* Is coredumping disabled? Then don't bother saving/processing the coredump.
332335 * Anything below PAGE_SIZE cannot give a readable coredump (the kernel uses
333336 * ELF_EXEC_PAGESIZE which is not easily accessible, but is usually the same as PAGE_SIZE. */
334- log_info ("Core dumping has been disabled for process %s (%s)." , context [CONTEXT_PID ], context [CONTEXT_COMM ]);
337+ log_info ("Resource limits disable core dumping for process %s (%s)." ,
338+ context [CONTEXT_PID ], context [CONTEXT_COMM ]);
335339 return - EBADSLT ;
336340 }
337341
338342 /* Never store more than the process configured, or than we actually shall keep or process */
339- max_size = MIN (rlimit , MAX (arg_process_size_max , arg_external_size_max ));
343+ max_size = MIN (rlimit , MAX (arg_process_size_max , storage_size_max () ));
340344
341345 r = make_filename (context , & fn );
342346 if (r < 0 )
@@ -349,19 +353,18 @@ static int save_external_coredump(
349353 return log_error_errno (fd , "Failed to create temporary file for coredump %s: %m" , fn );
350354
351355 r = copy_bytes (input_fd , fd , max_size , false);
352- if (r == - EFBIG ) {
353- log_error ("Coredump of %s (%s) is larger than configured processing limit, refusing." , context [CONTEXT_PID ], context [CONTEXT_COMM ]);
354- goto fail ;
355- } else if (IN_SET (r , - EDQUOT , - ENOSPC )) {
356- log_error ("Not enough disk space for coredump of %s (%s), refusing." , context [CONTEXT_PID ], context [CONTEXT_COMM ]);
357- goto fail ;
358- } else if (r < 0 ) {
359- log_error_errno (r , "Failed to dump coredump to file: %m" );
356+ if (r < 0 ) {
357+ log_error_errno (r , "Cannot store coredump of %s (%s): %m" , context [CONTEXT_PID ], context [CONTEXT_COMM ]);
360358 goto fail ;
361- }
359+ } else if (r == 1 )
360+ log_struct (LOG_INFO ,
361+ LOG_MESSAGE ("Core file was truncated to %zu bytes." , max_size ),
362+ "SIZE_LIMIT=%zu" , max_size ,
363+ LOG_MESSAGE_ID (SD_MESSAGE_TRUNCATED_CORE ),
364+ NULL );
362365
363366 if (fstat (fd , & st ) < 0 ) {
364- log_error_errno (errno , "Failed to fstat coredump %s: %m" , coredump_tmpfile_name (tmp ));
367+ log_error_errno (errno , "Failed to fstat core file %s: %m" , coredump_tmpfile_name (tmp ));
365368 goto fail ;
366369 }
367370
@@ -372,8 +375,7 @@ static int save_external_coredump(
372375
373376#if defined(HAVE_XZ ) || defined(HAVE_LZ4 )
374377 /* If we will remove the coredump anyway, do not compress. */
375- if (maybe_remove_external_coredump (NULL , st .st_size ) == 0
376- && arg_compress ) {
378+ if (arg_compress && !maybe_remove_external_coredump (NULL , st .st_size )) {
377379
378380 _cleanup_free_ char * fn_compressed = NULL , * tmp_compressed = NULL ;
379381 _cleanup_close_ int fd_compressed = -1 ;
@@ -705,7 +707,9 @@ static int submit_coredump(
705707
706708 coredump_filename = strjoina ("COREDUMP_FILENAME=" , filename );
707709 IOVEC_SET_STRING (iovec [n_iovec ++ ], coredump_filename );
708- }
710+ } else if (arg_storage == COREDUMP_STORAGE_EXTERNAL )
711+ log_info ("The core will not be stored: size %zu is greater than %zu (the configured maximum)" ,
712+ coredump_size , arg_external_size_max );
709713
710714 /* Vacuum again, but exclude the coredump we just created */
711715 (void ) coredump_vacuum (coredump_node_fd >= 0 ? coredump_node_fd : coredump_fd , arg_keep_free , arg_max_use );
@@ -730,7 +734,9 @@ static int submit_coredump(
730734 log_warning ("Failed to generate stack trace: %s" , dwfl_errmsg (dwfl_errno ()));
731735 else
732736 log_warning_errno (r , "Failed to generate stack trace: %m" );
733- }
737+ } else
738+ log_debug ("Not generating stack trace: core size %zu is greater than %zu (the configured maximum)" ,
739+ coredump_size , arg_process_size_max );
734740
735741 if (!core_message )
736742#endif
@@ -740,18 +746,22 @@ static int submit_coredump(
740746 IOVEC_SET_STRING (iovec [n_iovec ++ ], core_message );
741747
742748 /* Optionally store the entire coredump in the journal */
743- if (IN_SET (arg_storage , COREDUMP_STORAGE_JOURNAL , COREDUMP_STORAGE_BOTH ) &&
744- coredump_size <= arg_journal_size_max ) {
745- size_t sz = 0 ;
746-
747- /* Store the coredump itself in the journal */
748-
749- r = allocate_journal_field (coredump_fd , (size_t ) coredump_size , & coredump_data , & sz );
750- if (r >= 0 ) {
751- iovec [n_iovec ].iov_base = coredump_data ;
752- iovec [n_iovec ].iov_len = sz ;
753- n_iovec ++ ;
754- }
749+ if (arg_storage == COREDUMP_STORAGE_JOURNAL ) {
750+ if (coredump_size <= arg_journal_size_max ) {
751+ size_t sz = 0 ;
752+
753+ /* Store the coredump itself in the journal */
754+
755+ r = allocate_journal_field (coredump_fd , (size_t ) coredump_size , & coredump_data , & sz );
756+ if (r >= 0 ) {
757+ iovec [n_iovec ].iov_base = coredump_data ;
758+ iovec [n_iovec ].iov_len = sz ;
759+ n_iovec ++ ;
760+ } else
761+ log_warning_errno (r , "Failed to attach the core to the journal entry: %m" );
762+ } else
763+ log_info ("The core will not be stored: size %zu is greater than %zu (the configured maximum)" ,
764+ coredump_size , arg_journal_size_max );
755765 }
756766
757767 assert (n_iovec <= n_iovec_allocated );
0 commit comments