source: MondoRescue/trunk/mondo/src/common/libmondo-fifo.c@ 900

Last change on this file since 900 was 900, checked in by Bruno Cornec, 17 years ago

Huge patch to introduce low level functions that will bw used everywhere (mr_free, mr_asprintf, ...)
Nearly linking now due to that.

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