source: trunk/mondo/mondo/common/libmondo-fifo.c @ 42

Last change on this file since 42 was 42, checked in by bcornec, 15 years ago

asprintf usage continues on libmondo-fifo.c + indent

  • Property svn:keywords set to Id
File size: 4.6 KB
Line 
1/* $Id: libmondo-fifo.c 42 2005-10-03 23:32:14Z bcornec $ */
2
3/**
4 * @file
5 * Functions to handle buffering of tape archives as they are read/written.
6 * This used the external program @c buffer mostly.
7 */
8
9#include <unistd.h>
10#include <stdio.h>
11#include <signal.h>
12#include <fcntl.h>
13#include <stdio.h>
14
15#include <errno.h>
16#include <sys/types.h>
17#include <sys/stat.h>
18#include <sys/ipc.h>
19#include <sys/shm.h>
20#include <sys/sem.h>
21#include <sys/wait.h>
22#include <pthread.h>
23
24#include "my-stuff.h"
25#include "mondostructures.h"
26#include "libmondo.h"
27
28/**
29 * @addtogroup globalGroup
30 * @{
31 */
32/**
33 * The SIGPIPE handler sets this to TRUE.
34 */
35bool g_sigpipe = FALSE;
36
37/**
38 * PID of the "main" process.
39 */
40pid_t g_mastermind_pid = 0;
41
42
43
44/**
45 * Command line with which @c buffer was invoked.
46 */
47char *g_sz_call_to_buffer;
48
49/**
50 * Size of the buffer used with @c buffer.
51 */
52int g_tape_buffer_size_MB = 0;
53
54/* @} - end of globalGroup */
55
56
57/**
58 * @addtogroup fifoGroup
59 * @{
60 */
61/**
62 * Open a pipe to/from @c buffer.
63 * If buffer does not work at all, we use `dd'.
64 * @param device The device to read from/write to.
65 * @param direction @c 'r' (reading) or @c 'w' (writing).
66 * @return A file pointer to/from the @c buffer process.
67 */
68FILE *open_device_via_buffer(char *device, char direction,
69                             long internal_tape_block_size)
70{
71    char *sz_dir;
72    char keych;
73    char *tmp;
74    FILE *fres;
75    int bufsize;                // in megabytes
76    int res;
77    int wise_upper_limit;
78    int wise_lower_limit;
79
80    assert_string_is_neither_NULL_nor_zerolength(device);
81    assert(direction == 'w' || direction == 'r');
82    asprintf(&sz_dir, "%c", direction);
83    wise_upper_limit = (am_I_in_disaster_recovery_mode()? 8 : 32);
84    wise_lower_limit = 1;       // wise_upper_limit/2 + 1;
85    paranoid_system("sync");
86    for (bufsize = wise_upper_limit, res = -1;
87         res != 0 && bufsize >= wise_lower_limit; bufsize--) {
88        asprintf(&tmp,
89                 "dd if=/dev/zero bs=1024 count=16k 2> /dev/null | buffer -o /dev/null -s %ld -m %d%c",
90                 internal_tape_block_size, bufsize, 'm');
91        res = run_program_and_log_output(tmp, 2);
92        paranoid_free(tmp);
93    }
94    if (!res) {
95        bufsize++;
96        asprintf(&tmp, "Negotiated max buffer of %d MB ", bufsize);
97        log_to_screen(tmp);
98        paranoid_free(tmp);
99    } else {
100        bufsize = 0;
101        res = 0;
102        log_to_screen
103            ("Cannot negotiate a buffer of ANY size. Using dd instead.");
104    }
105    if (direction == 'r') {
106        keych = 'i';
107    } else {
108        keych = 'o';
109    }
110    if (bufsize) {
111        asprintf(&g_sz_call_to_buffer,
112                 "buffer -m %d%c -p%d -B -s%ld -%c %s 2>> %s", bufsize,
113                 'm', (direction == 'r') ? 20 : 75,
114                 internal_tape_block_size, keych, device, MONDO_LOGFILE);
115    } else {
116        asprintf(&g_sz_call_to_buffer, "dd bs=%ld %cf=%s",
117                 internal_tape_block_size, keych, device);
118    }
119    log_msg(2, "Calling buffer --- command = '%s'", g_sz_call_to_buffer);
120    fres = popen(g_sz_call_to_buffer, sz_dir);
121    paranoid_free(sz_dir);
122    if (fres) {
123        log_msg(2, "Successfully opened ('%c') tape device %s", direction,
124                device);
125    } else {
126        log_msg(2, "Failed to open ('%c') tape device %s", direction,
127                device);
128    }
129    sleep(2);
130    asprintf(&tmp, "ps wwax | grep \"%s\"", g_sz_call_to_buffer);
131    if (run_program_and_log_output(tmp, 2)) {
132        log_msg(2, "Warning - I think I failed to open tape, actually.");
133    }
134    paranoid_free(tmp);
135    g_tape_buffer_size_MB = bufsize;
136    /* BERLIOS: usless ?
137       strcmp(tmp, g_sz_call_to_buffer);
138       tmp[30] = '\0';
139     */
140    asprintf(&tmp, "ps wwax | grep buffer | grep -v grep");
141    if (run_program_and_log_output(tmp, 1)) {
142        fres = NULL;
143        log_to_screen("Failed to open tape streamer. Buffer error.");
144    } else {
145        log_to_screen("Buffer successfully started.");
146    }
147    paranoid_free(tmp);
148    return (fres);
149}
150
151
152/**
153 * Kill @c buffer processes.
154 */
155void kill_buffer()
156{
157    char *tmp;
158    char *command;
159
160    paranoid_system("sync");
161    asprintf(&command,
162             "ps wwax | fgrep \"%s\" | fgrep -v grep | awk '{print $1;}' | grep -v PID | tr -s '\n' ' ' | awk '{ print $1; }'",
163             g_sz_call_to_buffer);
164    paranoid_free(g_sz_call_to_buffer);
165    log_msg(2, "kill_buffer() --- command = %s", command);
166
167    asprintf(&tmp, "%s",
168             call_program_and_get_last_line_of_output(command));
169    paranoid_free(command);
170
171    asprintf(&command, "kill %s", tmp);
172    log_msg(2, "kill_buffer() --- command = %s", command);
173
174    if (strlen(tmp) > 0) {
175        run_program_and_log_output(command, TRUE);
176    }
177    paranoid_free(command);
178    paranoid_free(tmp);
179}
180
181
182/**
183 * Handler for SIGPIPE.
184 * @param sig The signal that occurred (hopefully SIGPIPE).
185 */
186void sigpipe_occurred(int sig)
187{
188    g_sigpipe = TRUE;
189}
190
191/* @} - end of fifoGroup */
192
193/* BERLIOS: useless ?
194int
195extract_config_file_from_ramdisk( struct s_bkpinfo *bkpinfo,
196                  char *ramdisk_fname,
197                  char *output_cfg_file,
198                  char *output_mountlist_file);
199*/
Note: See TracBrowser for help on using the repository browser.