source: MondoRescue/branches/3.0/mondo/src/common/libmondo-fifo.c@ 3192

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