libreport 2.15.2
A tool to inform users about various problems on the running system
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);
232
233/* Create an item of the given name with contents of the given file (see man openat)
234 *
235 * @param dd Dump directory
236 * @param name Item's name
237 * @param src_dir_fd Source directory's file descriptor
238 * @param src_name Source file name
239 * @return 0 no success, or negative value if an error occurred
240 */
241int dd_copy_file_at(struct dump_dir *dd, const char *name, int src_dir_fd, const char *src_name);
242
243/* Creates/overwrites an element with data read from a file descriptor
244 *
245 * @param dd Dump directory
246 * @param name The name of the element
247 * @param fd The file descriptor
248 * @param flags libreport_copyfd_flags
249 * @param maxsize Limit for number of written Bytes. (0 for unlimited).
250 * @return Number of read Bytes. If the return value is greater than the maxsize
251 * the file descriptor content was truncated to the maxsize. The return value
252 * is not size of the file descriptor.
253 */
254off_t dd_copy_fd(struct dump_dir *dd, const char *name, int fd, int copy_flags, off_t maxsize);
255
256/* Stats dump dir elements
257 *
258 * @param dd Dump Directory
259 * @param name The name of the element
260 * @param statbuf See 'man 2 stat'
261 * @return -EINVAL if name is invalid element name, -EMEDIUMTYPE if name is not
262 * regular file, -errno on errors and 0 on success.
263 */
264int dd_item_stat(struct dump_dir *dd, const char *name, struct stat *statbuf);
265
266/* Returns value less than 0 if any error occured; otherwise returns size of an
267 * item in Bytes. If an item does not exist returns 0 instead of an error
268 * value.
269 */
270long dd_get_item_size(struct dump_dir *dd, const char *name);
271
272/* Returns the number of items in the dump directory (does not count meta-data).
273 *
274 * @return Negative number on errors (-errno). Otherwise number of dump
275 * directory items.
276 */
278
279/* Deletes an item from dump directory
280 * On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
281 * For more about errno see unlink documentation
282 */
283int dd_delete_item(struct dump_dir *dd, const char *name);
284
285/* Returns a file descriptor for the given name. The function is limited to open
286 * an element read only, write only or create new.
287 *
288 * O_RDONLY - opens an existing item for reading
289 * O_RDWR - removes an item, creates its file and opens the file for reading and writing
290 *
291 * @param dd Dump directory
292 * @param name The name of the item
293 * @param flags One of these : O_RDONLY, O_RDWR
294 * @return Negative number on error
295 */
296int dd_open_item(struct dump_dir *dd, const char *name, int flags);
297
298/* Returns a FILE for the given name. The function is limited to open
299 * an element read only, write only or create new.
300 *
301 * O_RDONLY - opens an existing file for reading
302 * O_RDWR - removes an item, creates its file and opens the file for reading and writing
303 *
304 * @param dd Dump directory
305 * @param name The name of the item
306 * @param flags One of these : O_RDONLY, O_RDWR
307 * @return NULL on error
308 */
309FILE *dd_open_item_file(struct dump_dir *dd, const char *name, int flags);
310
311/* Returns 0 if directory is deleted or not found */
312int dd_delete(struct dump_dir *dd);
313int dd_rename(struct dump_dir *dd, const char *new_path);
314/* Changes owner of dump dir
315 * Uses two different strategies selected at build time by
316 * DUMP_DIR_OWNED_BY_USER configuration:
317 * <= 0 : owner = abrt user's uid, group = new_uid's gid
318 * > 0 : owner = new_uid, group = abrt group's gid
319 *
320 * On success, zero is returned. On error, -1 is returned.
321 */
322int dd_chown(struct dump_dir *dd, uid_t new_uid);
323
324/* Returns the number of Bytes consumed by the dump directory.
325 *
326 * @param flags For the future needs (count also meta-data, ...).
327 * @return Negative number on errors (-errno). Otherwise size in Bytes.
328 */
329off_t dd_compute_size(struct dump_dir *dd, int flags);
330
331/* Sets a new owner (does NOT chown the directory)
332 *
333 * Does not validate the passed uid.
334 * The given dump_dir must be opened for writing.
335 */
336int dd_set_owner(struct dump_dir *dd, uid_t owner);
337
338/* Makes the dump directory owned by nobody.
339 *
340 * The directory will be accessible for all users.
341 * The given dump_dir must be opened for writing.
342 */
343int dd_set_no_owner(struct dump_dir *dd);
344
354uid_t dd_get_owner(struct dump_dir *dd);
355
356/* Returns UNIX time stamp of the first occurrence of the problem.
357 *
358 * @param dd Examined dump directory
359 * @returns On success, the value of time of the first occurrence in seconds
360 * since the Epoch is returned. On error, ((time_t) -1) is returned, and errno
361 * is set appropriately (ENODATA).
362 */
364
365/* Returns UNIX time stamp of the last occurrence of the problem.
366 *
367 * @param dd Examined dump directory
368 * @returns The returned value is never lower than the value returned by
369 * dd_get_first_occurrence(). On success, the value of time of the first
370 * occurrence in seconds since the Epoch is returned.On error, ((time_t) -1) is
371 * returned, and errno is set appropriately (ENODATA).
372 */
374
375/* Appends a new unique line to the list of report results
376 *
377 * If the reported_to data already contains the given line, the line will not
378 * be added again.
379 *
380 * @param reported_to The data
381 * @param line The appended line
382 * @return 1 if the line was added at the end of the reported_to; otherwise 0.
383 */
384int libreport_add_reported_to_data(char **reported_to, const char *line);
385
386/* Appends a new unique entry to the list of report results
387 *
388 * result->label must be non-empty string which does not contain ':' character.
389 *
390 * The function converts the result to a valid reported_to line and calls
391 * libreport_add_reported_to_data().
392 *
393 * @param reported_to The data
394 * @param result The appended entry
395 * @return -EINVAL if result->label is invalid; otherwise return value of
396 * libreport_add_reported_to_data
397 */
398int libreport_add_reported_to_entry_data(char **reported_to, struct report_result *result);
399
400/* This is a wrapper of libreport_add_reported_to_data which accepts 'struct dump_dir *'
401 * in the first argument instead of 'char **'. The added line is stored in
402 * 'reported_to' dump directory file.
403 */
404void libreport_add_reported_to(struct dump_dir *dd, const char *line);
405
406/* This is a wrapper of libreport_add_reported_to_entry_data which accepts 'struct
407 * dump_dir *' in the first argument instead of 'char **'. The added entry is
408 * stored in 'reported_to' dump directory file.
409 */
410void libreport_add_reported_to_entry(struct dump_dir *dd, struct report_result *result);
411
412report_result_t *libreport_find_in_reported_to_data(const char *reported_to, const char *report_label);
413report_result_t *libreport_find_in_reported_to(struct dump_dir *dd, const char *report_label);
414GList *libreport_read_entire_reported_to_data(const char* reported_to);
416
417
418void delete_dump_dir(const char *dirname);
419/* Checks dump dir accessibility for particular uid.
420 *
421 * If the directory doesn't exist the directory is not accessible and errno is
422 * set to ENOTDIR.
423 *
424 * Returns non zero if dump dir is accessible otherwise return 0 value.
425 */
426int dump_dir_accessible_by_uid(const char *dirname, uid_t uid);
427/* Returns the same information as dump_dir_accessible_by_uid
428 *
429 * The passed dump_dir can be opened with DD_OPEN_FD_ONLY
430 */
431int dd_accessible_by_uid(struct dump_dir *dd, uid_t uid);
432
433enum {
437};
438
439/* Gets information about a dump directory for particular uid.
440 *
441 * If the directory doesn't exist the directory is not accessible and errno is
442 * set to ENOTDIR.
443 *
444 * Returns negative number if error occurred otherwise returns 0 or positive number.
445 */
446int dump_dir_stat_for_uid(const char *dirname, uid_t uid);
447/* Returns the same information as dump_dir_stat_for_uid
448 *
449 * The passed dump_dir can be opened with DD_OPEN_FD_ONLY
450 */
451int dd_stat_for_uid(struct dump_dir *dd, uid_t uid);
452
453/* creates not_reportable file in the problem directory and saves the
454 reason to it, which prevents libreport from reporting the problem
455 On success, zero is returned.
456 On error, -1 is returned and an error message is logged.
457 - this could probably happen only if the dump dir is not locked
458*/
459int dd_mark_as_notreportable(struct dump_dir *dd, const char *reason);
460
461typedef int (*save_data_call_back)(struct dump_dir *, void *args);
462
463/* Saves data in a new dump directory
464 *
465 * Creates a new dump directory in "problem dump location", adds the basic
466 * information to the new directory, calls given callback to allow callees to
467 * customize the dump dir contents (save problem data) and commits the dump
468 * directory (makes the directory visible for a problem daemon).
469 */
470struct dump_dir *create_dump_dir(const char *base_dir_name, const char *type,
471 uid_t uid, save_data_call_back save_data, void *args);
472
473struct dump_dir *create_dump_dir_ext(const char *base_dir_name, const char *type,
474 pid_t pid, uid_t uid, save_data_call_back save_data, void *args);
475
476/* Creates a new archive from the dump directory contents
477 *
478 * The dd argument must be opened for reading.
479 *
480 * The archive_name must not exist. The file will be created with 0600 mode.
481 *
482 * The archive type is deduced from archive_name suffix. The supported archive
483 * suffixes are the following:
484 * - '.tag.gz' (note: the implementation uses child gzip process)
485 *
486 * The archive will include only the files that are not in the exclude_elements
487 * list. See libreport_get_global_always_excluded_elements().
488 *
489 * The argument "flags" is currently unused.
490 *
491 * @return 0 on success; otherwise non-0 value. -ENOSYS if archive type is not
492 * supported. -EEXIST if the archive file already exists. -ECHILD if child
493 * process fails. Other negative values can be converted to errno values by
494 * turning them positive.
495 */
496int dd_create_archive(struct dump_dir *dd, const char *archive_name,
497 const_string_vector_const_ptr_t exclude_elements, int flags);
498
499#ifdef __cplusplus
500}
501#endif
502
503#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:434
@ DD_STAT_OWNED_BY_UID
Definition: dump_dir.h:435
@ DD_STAT_NO_OWNER
Definition: dump_dir.h:436
int(* save_data_call_back)(struct dump_dir *, void *args)
Definition: dump_dir.h:461
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 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