libreport 2.17.15
A tool to inform users about various problems on the running system
Loading...
Searching...
No Matches
dump_dir.h
Go to the documentation of this file.
1/*
2 On-disk storage of problem data
3
4 Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com)
5 Copyright (C) 2009 RedHat inc.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20*/
21#ifndef LIBREPORT_DUMP_DIR_H_
22#define LIBREPORT_DUMP_DIR_H_
23
24/* For const_string_vector_const_ptr_t */
25#include "libreport_types.h"
26#include "report_result.h"
27
28#include <stdint.h>
29#include <stdio.h>
30
31/* For DIR */
32#include <sys/types.h>
33#include <dirent.h>
34
35/* For 'struct stat' */
36#include <sys/stat.h>
37
38/* Fore GList */
39#include <glib.h>
40
41#ifdef __cplusplus
42extern "C" {
43#endif
44
45/* Utility function */
46int create_symlink_lockfile(const char *filename, const char *pid_str);
47int create_symlink_lockfile_at(int dir_fd, const char *filename, const char *pid_str);
48
49/* Opens filename for reading relatively to a directory represented by dir_fd.
50 * The function fails if the file is symbolic link, directory or hard link.
51 */
52int secure_openat_read(int dir_fd, const char *filename);
53
54/******************************************************************************/
55/* Global variables */
56/******************************************************************************/
57
58/* UID of super-user (default 0)
59 *
60 * This variable is used by the dd* functions when they access security
61 * sensitive elements. The functions will ONLY TRUST the contents of those
62 * elements that ARE OWNED by super-user.
63 */
64extern uid_t dd_g_super_user_uid;
65
66/* GID of a dump diretory created via dd_create() with uid != -1
67 *
68 * The default value is -1 which means that the dd* functions must ignore this
69 * variable.
70 *
71 * Initialize this variable only if you don't want to use the default group
72 * ('abrt').
73 */
74extern gid_t dd_g_fs_group_gid;
75
76/******************************************************************************/
77/* Dump Directory */
78/******************************************************************************/
79
83 /* Open symlinks. dd_* funcs don't open symlinks by default */
84 DD_OPEN_FOLLOW = (1 << 2),
85 DD_OPEN_READONLY = (1 << 3),
88 /* Create the new dump directory with parent directories (mkdir -p)*/
90 /* Initializes internal data, opens file descriptors and returns the
91 * structure. This flag is useful for testing whether a directory
92 * exists and to perform stat operations.
93 */
94 DD_OPEN_FD_ONLY = (1 << 7),
95};
96
97struct dump_dir {
101 uid_t dd_uid;
102 gid_t dd_gid;
103 /* mode of saved files */
104 mode_t mode;
105 time_t dd_time;
106 char *dd_type;
107
108 /* In case of recursive locking the first caller owns the lock and is
109 * responsible for unlocking. The consecutive dd_lock() callers acquire the
110 * lock but are not able to unlock the dump directory.
111 */
113 int dd_fd;
114 /* Never use this member directly, it is intialized on demand in
115 * dd_get_meta_data_dir_fd()
116 */
118};
119
120void dd_close(struct dump_dir *dd);
121
122/* Opens the given path
123 */
124struct dump_dir *dd_opendir(const char *dir, int flags);
125
126/* Re-opens a dump_dir opened with DD_OPEN_FD_ONLY.
127 *
128 * The passed dump_dir must not be used any more and the return value must be
129 * used instead.
130 *
131 * The passed flags must not contain DD_OPEN_FD_ONLY.
132 *
133 * The passed dump_dir must not be already locked.
134 */
135struct dump_dir *dd_fdopendir(struct dump_dir *dd, int flags);
136
137/* Creates a new directory with internal files
138 *
139 * The functions creates a new directory which remains owned by the user of the
140 * process until dd_reset_ownership() is called.
141 *
142 * The function logs error messages in case of errors.
143 *
144 * @param dir Full file system path of the new directory
145 * @param uid Desired file system owner of the new directory or -1 if the owner
146 * should stay untouched even after calling dd_reset_ownership().
147 * @param mode File system mode of the new directory.
148 * @param flags See 'enum dump_dir_flags'
149 * @return Initialized struct dump_dir of NULL
150 */
151struct dump_dir *dd_create_skeleton(const char *dir, uid_t uid, mode_t mode, int flags);
152
154
155/* Pass uid = (uid_t)-1L to disable chown'ing of newly created files
156 * (IOW: if you aren't running under root):
157 */
158struct dump_dir *dd_create(const char *dir, uid_t uid, mode_t mode);
159
160/* Creates the basic files except 'type' and sets the dump dir owner to passed
161 * 'uid'.
162 *
163 * The file 'type' is required and must be added with dd_save_text().
164 *
165 * If you want to have owner different than the problem 'uid', than pass -1 and
166 * add the file 'uid' with dd_save_text()
167 *
168 * List of created files:
169 * - time
170 * - last_occurrence
171 * - uid
172 * - kernel
173 * - architecture
174 * - hostname
175 * - os_info
176 * - os_release
177 *
178 * If any of these files has a counterpart in a chroot directory (os_info,
179 * os_relase), creates an element with the prefix "root_"
180 */
181void dd_create_basic_files(struct dump_dir *dd, uid_t uid, const char *chroot_dir);
182int dd_exist(const struct dump_dir *dd, const char *path);
184
185/* Initializes an iterator going through all dump directory items.
186 *
187 * @returns NULL if the iterator cannot be initialized; otherwise returns
188 * the result of opendir(). Do not use the return value after the iteration is
189 * finished or after calling dd_clear_next_file().
190 */
192
193/* Iterates over all dump directory item names
194 *
195 * Initialize the iterator by calling dd_init_next_file(). When iteration is
196 * finished, calls dd_clear_next_file().
197 *
198 * @returns 1 if the next item was read; otherwise return 0.
199 */
200int dd_get_next_file(struct dump_dir *dd, char **short_name, char **full_name);
201
202/* Destroys the next file iterator and cleans dump directory internal structures
203 *
204 * Calling dd_get_next_file() after this function returns will return 0. This
205 * function also invalidates the return value of dd_init_next_file().
206 */
208
209char *load_text_file(const char *path, unsigned flags);
210
211char* dd_load_text_ext(const struct dump_dir *dd, const char *name, unsigned flags);
212char* dd_load_text(const struct dump_dir *dd, const char *name);
213int dd_load_int32(const struct dump_dir *dd, const char *name, int32_t *value);
214int dd_load_uint32(const struct dump_dir *dd, const char *name, uint32_t *value);
215int dd_load_int64(const struct dump_dir *dd, const char *name, int64_t *value);
216int dd_load_uint64(const struct dump_dir *dd, const char *name, uint64_t *value);
217
218/* Returns value of environment variable with given name.
219 *
220 * @param dd Dump directory
221 * @param name Variables's name
222 * @param value Return value.
223 * @return 0 no success, or negative value if an error occurred (-ENOENT if the
224 * given dd does not support environment variables).
225 */
226int dd_get_env_variable(struct dump_dir *dd, const char *name, char **value);
227
228void dd_save_text(struct dump_dir *dd, const char *name, const char *data);
229void dd_save_binary(struct dump_dir *dd, const char *name, const char *data, unsigned size);
230int dd_copy_file(struct dump_dir *dd, const char *name, const char *source_path);
231int dd_copy_file_unpack(struct dump_dir *dd, const char *name, const char *source_path);
232int dd_unpack_coredump(struct dump_dir *dd, const char *coredump_archive_filename);
233
234/* Create an item of the given name with contents of the given file (see man openat)
235 *
236 * @param dd Dump directory
237 * @param name Item's name
238 * @param src_dir_fd Source directory's file descriptor
239 * @param src_name Source file name
240 * @return 0 no success, or negative value if an error occurred
241 */
242int dd_copy_file_at(struct dump_dir *dd, const char *name, int src_dir_fd, const char *src_name);
243
244/* Creates/overwrites an element with data read from a file descriptor
245 *
246 * @param dd Dump directory
247 * @param name The name of the element
248 * @param fd The file descriptor
249 * @param flags libreport_copyfd_flags
250 * @param maxsize Limit for number of written Bytes. (0 for unlimited).
251 * @return Number of read Bytes. If the return value is greater than the maxsize
252 * the file descriptor content was truncated to the maxsize. The return value
253 * is not size of the file descriptor.
254 */
255off_t dd_copy_fd(struct dump_dir *dd, const char *name, int fd, int copy_flags, off_t maxsize);
256
257/* Stats dump dir elements
258 *
259 * @param dd Dump Directory
260 * @param name The name of the element
261 * @param statbuf See 'man 2 stat'
262 * @return -EINVAL if name is invalid element name, -EMEDIUMTYPE if name is not
263 * regular file, -errno on errors and 0 on success.
264 */
265int dd_item_stat(struct dump_dir *dd, const char *name, struct stat *statbuf);
266
267/* Returns value less than 0 if any error occured; otherwise returns size of an
268 * item in Bytes. If an item does not exist returns 0 instead of an error
269 * value.
270 */
271long dd_get_item_size(struct dump_dir *dd, const char *name);
272
273/* Returns the number of items in the dump directory (does not count meta-data).
274 *
275 * @return Negative number on errors (-errno). Otherwise number of dump
276 * directory items.
277 */
279
280/* Deletes an item from dump directory
281 * On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
282 * For more about errno see unlink documentation
283 */
284int dd_delete_item(struct dump_dir *dd, const char *name);
285
286/* Returns a file descriptor for the given name. The function is limited to open
287 * an element read only, write only or create new.
288 *
289 * O_RDONLY - opens an existing item for reading
290 * O_RDWR - removes an item, creates its file and opens the file for reading and writing
291 *
292 * @param dd Dump directory
293 * @param name The name of the item
294 * @param flags One of these : O_RDONLY, O_RDWR
295 * @return Negative number on error
296 */
297int dd_open_item(struct dump_dir *dd, const char *name, int flags);
298
299/* Returns a FILE for the given name. The function is limited to open
300 * an element read only, write only or create new.
301 *
302 * O_RDONLY - opens an existing file for reading
303 * O_RDWR - removes an item, creates its file and opens the file for reading and writing
304 *
305 * @param dd Dump directory
306 * @param name The name of the item
307 * @param flags One of these : O_RDONLY, O_RDWR
308 * @return NULL on error
309 */
310FILE *dd_open_item_file(struct dump_dir *dd, const char *name, int flags);
311
312/* Returns 0 if directory is deleted or not found */
313int dd_delete(struct dump_dir *dd);
314int dd_rename(struct dump_dir *dd, const char *new_path);
315/* Changes owner of dump dir
316 * Uses two different strategies selected at build time by
317 * DUMP_DIR_OWNED_BY_USER configuration:
318 * <= 0 : owner = abrt user's uid, group = new_uid's gid
319 * > 0 : owner = new_uid, group = abrt group's gid
320 *
321 * On success, zero is returned. On error, -1 is returned.
322 */
323int dd_chown(struct dump_dir *dd, uid_t new_uid);
324
325/* Returns the number of Bytes consumed by the dump directory.
326 *
327 * @param flags For the future needs (count also meta-data, ...).
328 * @return Negative number on errors (-errno). Otherwise size in Bytes.
329 */
330off_t dd_compute_size(struct dump_dir *dd, int flags);
331
332/* Sets a new owner (does NOT chown the directory)
333 *
334 * Does not validate the passed uid.
335 * The given dump_dir must be opened for writing.
336 */
337int dd_set_owner(struct dump_dir *dd, uid_t owner);
338
339/* Makes the dump directory owned by nobody.
340 *
341 * The directory will be accessible for all users.
342 * The given dump_dir must be opened for writing.
343 */
344int dd_set_no_owner(struct dump_dir *dd);
345
355uid_t dd_get_owner(struct dump_dir *dd);
356
357/* Returns UNIX time stamp of the first occurrence of the problem.
358 *
359 * @param dd Examined dump directory
360 * @returns On success, the value of time of the first occurrence in seconds
361 * since the Epoch is returned. On error, ((time_t) -1) is returned, and errno
362 * is set appropriately (ENODATA).
363 */
365
366/* Returns UNIX time stamp of the last occurrence of the problem.
367 *
368 * @param dd Examined dump directory
369 * @returns The returned value is never lower than the value returned by
370 * dd_get_first_occurrence(). On success, the value of time of the first
371 * occurrence in seconds since the Epoch is returned.On error, ((time_t) -1) is
372 * returned, and errno is set appropriately (ENODATA).
373 */
375
376/* Appends a new unique line to the list of report results
377 *
378 * If the reported_to data already contains the given line, the line will not
379 * be added again.
380 *
381 * @param reported_to The data
382 * @param line The appended line
383 * @return 1 if the line was added at the end of the reported_to; otherwise 0.
384 */
385int libreport_add_reported_to_data(char **reported_to, const char *line);
386
387/* Appends a new unique entry to the list of report results
388 *
389 * result->label must be non-empty string which does not contain ':' character.
390 *
391 * The function converts the result to a valid reported_to line and calls
392 * libreport_add_reported_to_data().
393 *
394 * @param reported_to The data
395 * @param result The appended entry
396 * @return -EINVAL if result->label is invalid; otherwise return value of
397 * libreport_add_reported_to_data
398 */
399int libreport_add_reported_to_entry_data(char **reported_to, struct report_result *result);
400
401/* This is a wrapper of libreport_add_reported_to_data which accepts 'struct dump_dir *'
402 * in the first argument instead of 'char **'. The added line is stored in
403 * 'reported_to' dump directory file.
404 */
405void libreport_add_reported_to(struct dump_dir *dd, const char *line);
406
407/* This is a wrapper of libreport_add_reported_to_entry_data which accepts 'struct
408 * dump_dir *' in the first argument instead of 'char **'. The added entry is
409 * stored in 'reported_to' dump directory file.
410 */
411void libreport_add_reported_to_entry(struct dump_dir *dd, struct report_result *result);
412
413report_result_t *libreport_find_in_reported_to_data(const char *reported_to, const char *report_label);
414report_result_t *libreport_find_in_reported_to(struct dump_dir *dd, const char *report_label);
415GList *libreport_read_entire_reported_to_data(const char* reported_to);
417
418
419void delete_dump_dir(const char *dirname);
420/* Checks dump dir accessibility for particular uid.
421 *
422 * If the directory doesn't exist the directory is not accessible and errno is
423 * set to ENOTDIR.
424 *
425 * Returns non zero if dump dir is accessible otherwise return 0 value.
426 */
427int dump_dir_accessible_by_uid(const char *dirname, uid_t uid);
428/* Returns the same information as dump_dir_accessible_by_uid
429 *
430 * The passed dump_dir can be opened with DD_OPEN_FD_ONLY
431 */
432int dd_accessible_by_uid(struct dump_dir *dd, uid_t uid);
433
434enum {
438};
439
440/* Gets information about a dump directory for particular uid.
441 *
442 * If the directory doesn't exist the directory is not accessible and errno is
443 * set to ENOTDIR.
444 *
445 * Returns negative number if error occurred otherwise returns 0 or positive number.
446 */
447int dump_dir_stat_for_uid(const char *dirname, uid_t uid);
448/* Returns the same information as dump_dir_stat_for_uid
449 *
450 * The passed dump_dir can be opened with DD_OPEN_FD_ONLY
451 */
452int dd_stat_for_uid(struct dump_dir *dd, uid_t uid);
453
454/* creates not_reportable file in the problem directory and saves the
455 reason to it, which prevents libreport from reporting the problem
456 On success, zero is returned.
457 On error, -1 is returned and an error message is logged.
458 - this could probably happen only if the dump dir is not locked
459*/
460int dd_mark_as_notreportable(struct dump_dir *dd, const char *reason);
461
462typedef int (*save_data_call_back)(struct dump_dir *, void *args);
463
464/* Saves data in a new dump directory
465 *
466 * Creates a new dump directory in "problem dump location", adds the basic
467 * information to the new directory, calls given callback to allow callees to
468 * customize the dump dir contents (save problem data) and commits the dump
469 * directory (makes the directory visible for a problem daemon).
470 */
471struct dump_dir *create_dump_dir(const char *base_dir_name, const char *type,
472 uid_t uid, save_data_call_back save_data, void *args);
473
474struct dump_dir *create_dump_dir_ext(const char *base_dir_name, const char *type,
475 pid_t pid, uid_t uid, save_data_call_back save_data, void *args);
476
477/* Creates a new archive from the dump directory contents
478 *
479 * The dd argument must be opened for reading.
480 *
481 * The archive_name must not exist. The file will be created with 0600 mode.
482 *
483 * The archive type is deduced from archive_name suffix. The supported archive
484 * suffixes are the following:
485 * - '.tag.gz' (note: the implementation uses child gzip process)
486 *
487 * The archive will include only the files that are not in the exclude_elements
488 * list. See libreport_get_global_always_excluded_elements().
489 *
490 * The argument "flags" is currently unused.
491 *
492 * @return 0 on success; otherwise non-0 value. -ENOSYS if archive type is not
493 * supported. -EEXIST if the archive file already exists. -ECHILD if child
494 * process fails. Other negative values can be converted to errno values by
495 * turning them positive.
496 */
497int dd_create_archive(struct dump_dir *dd, const char *archive_name,
498 const_string_vector_const_ptr_t exclude_elements, int flags);
499
500#ifdef __cplusplus
501}
502#endif
503
504#endif
int dd_get_next_file(struct dump_dir *dd, char **short_name, char **full_name)
void delete_dump_dir(const char *dirname)
void dd_save_binary(struct dump_dir *dd, const char *name, const char *data, unsigned size)
@ DD_STAT_ACCESSIBLE_BY_UID
Definition dump_dir.h:435
@ DD_STAT_OWNED_BY_UID
Definition dump_dir.h:436
@ DD_STAT_NO_OWNER
Definition dump_dir.h:437
int(* save_data_call_back)(struct dump_dir *, void *args)
Definition dump_dir.h:462
int dd_reset_ownership(struct dump_dir *dd)
char * dd_load_text_ext(const struct dump_dir *dd, const char *name, unsigned flags)
void dd_clear_next_file(struct dump_dir *dd)
int dd_copy_file(struct dump_dir *dd, const char *name, const char *source_path)
int dd_copy_file_unpack(struct dump_dir *dd, const char *name, const char *source_path)
int dd_delete_item(struct dump_dir *dd, const char *name)
int dump_dir_accessible_by_uid(const char *dirname, uid_t uid)
int dd_load_int32(const struct dump_dir *dd, const char *name, int32_t *value)
int dd_get_items_count(struct dump_dir *dd)
int dd_open_item(struct dump_dir *dd, const char *name, int flags)
report_result_t * libreport_find_in_reported_to(struct dump_dir *dd, const char *report_label)
int create_symlink_lockfile_at(int dir_fd, const char *filename, const char *pid_str)
char * load_text_file(const char *path, unsigned flags)
GList * libreport_read_entire_reported_to(struct dump_dir *dd)
void dd_close(struct dump_dir *dd)
void libreport_add_reported_to(struct dump_dir *dd, const char *line)
int dd_chown(struct dump_dir *dd, uid_t new_uid)
int dd_accessible_by_uid(struct dump_dir *dd, uid_t uid)
int dd_mark_as_notreportable(struct dump_dir *dd, const char *reason)
int libreport_add_reported_to_entry_data(char **reported_to, struct report_result *result)
gid_t dd_g_fs_group_gid
struct dump_dir * dd_fdopendir(struct dump_dir *dd, int flags)
off_t dd_copy_fd(struct dump_dir *dd, const char *name, int fd, int copy_flags, off_t maxsize)
int dd_exist(const struct dump_dir *dd, const char *path)
GList * libreport_read_entire_reported_to_data(const char *reported_to)
int dd_set_no_owner(struct dump_dir *dd)
struct dump_dir * dd_create_skeleton(const char *dir, uid_t uid, mode_t mode, int flags)
void libreport_add_reported_to_entry(struct dump_dir *dd, struct report_result *result)
int libreport_add_reported_to_data(char **reported_to, const char *line)
int dd_load_int64(const struct dump_dir *dd, const char *name, int64_t *value)
void dd_create_basic_files(struct dump_dir *dd, uid_t uid, const char *chroot_dir)
int dd_load_uint64(const struct dump_dir *dd, const char *name, uint64_t *value)
time_t dd_get_last_occurrence(struct dump_dir *dd)
FILE * dd_open_item_file(struct dump_dir *dd, const char *name, int flags)
int dd_create_archive(struct dump_dir *dd, const char *archive_name, const_string_vector_const_ptr_t exclude_elements, int flags)
DIR * dd_init_next_file(struct dump_dir *dd)
dump_dir_flags
Definition dump_dir.h:80
@ DD_CREATE_PARENTS
Definition dump_dir.h:89
@ DD_FAIL_QUIETLY_EACCES
Definition dump_dir.h:82
@ DD_OPEN_FD_ONLY
Definition dump_dir.h:94
@ DD_FAIL_QUIETLY_ENOENT
Definition dump_dir.h:81
@ DD_OPEN_FOLLOW
Definition dump_dir.h:84
@ DD_DONT_WAIT_FOR_LOCK
Definition dump_dir.h:87
@ DD_OPEN_READONLY
Definition dump_dir.h:85
@ DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE
Definition dump_dir.h:86
int dd_stat_for_uid(struct dump_dir *dd, uid_t uid)
uid_t dd_g_super_user_uid
off_t dd_compute_size(struct dump_dir *dd, int flags)
void dd_sanitize_mode_and_owner(struct dump_dir *dd)
int create_symlink_lockfile(const char *filename, const char *pid_str)
int dd_item_stat(struct dump_dir *dd, const char *name, struct stat *statbuf)
struct dump_dir * dd_create(const char *dir, uid_t uid, mode_t mode)
int dd_copy_file_at(struct dump_dir *dd, const char *name, int src_dir_fd, const char *src_name)
int dd_unpack_coredump(struct dump_dir *dd, const char *coredump_archive_filename)
int dump_dir_stat_for_uid(const char *dirname, uid_t uid)
uid_t dd_get_owner(struct dump_dir *dd)
int dd_load_uint32(const struct dump_dir *dd, const char *name, uint32_t *value)
char * dd_load_text(const struct dump_dir *dd, const char *name)
struct dump_dir * create_dump_dir(const char *base_dir_name, const char *type, uid_t uid, save_data_call_back save_data, void *args)
time_t dd_get_first_occurrence(struct dump_dir *dd)
struct dump_dir * create_dump_dir_ext(const char *base_dir_name, const char *type, pid_t pid, uid_t uid, save_data_call_back save_data, void *args)
report_result_t * libreport_find_in_reported_to_data(const char *reported_to, const char *report_label)
int dd_set_owner(struct dump_dir *dd, uid_t owner)
struct dump_dir * dd_opendir(const char *dir, int flags)
int dd_rename(struct dump_dir *dd, const char *new_path)
int secure_openat_read(int dir_fd, const char *filename)
void dd_save_text(struct dump_dir *dd, const char *name, const char *data)
int dd_get_env_variable(struct dump_dir *dd, const char *name, char **value)
long dd_get_item_size(struct dump_dir *dd, const char *name)
int dd_delete(struct dump_dir *dd)
Definition dump_dir.h:97
mode_t mode
Definition dump_dir.h:104
time_t dd_time
Definition dump_dir.h:105
char * dd_type
Definition dump_dir.h:106
int dd_md_fd
Definition dump_dir.h:117
DIR * next_dir
Definition dump_dir.h:99
uid_t dd_uid
Definition dump_dir.h:101
int locked
Definition dump_dir.h:100
int owns_lock
Definition dump_dir.h:112
gid_t dd_gid
Definition dump_dir.h:102
char * dd_dirname
Definition dump_dir.h:98
int dd_fd
Definition dump_dir.h:113