File: media.c

package info (click to toggle)
xfsdump 3.1.9%2B0
  • links: PTS
  • area: main
  • in suites: bullseye
  • size: 3,932 kB
  • sloc: ansic: 45,863; sh: 3,227; makefile: 545
file content (306 lines) | stat: -rw-r--r-- 7,442 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
/*
 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdlib.h>
#include <sys/dirent.h>
#include <stdio.h>
#include <getopt.h>
#include <assert.h>

#include "config.h"

#include "types.h"
#include "util.h"
#include "mlog.h"
#include "getopt.h"
#include "stream.h"
#include "global.h"
#include "drive.h"
#include "media.h"

/* media.c - selects and initializes a media strategy
 */


/* declarations of externally defined global symbols *************************/

extern void usage(void);

/* declare all media strategies here
 */
extern media_strategy_t media_strategy_simple;
extern media_strategy_t media_strategy_rmvtape;


/* forward declarations of locally defined static functions ******************/

static media_t *media_alloc(drive_t *, char *);


/* definition of locally defined global variables ****************************/


/* definition of locally defined static variables *****************************/

/* media strategy array - ordered by precedence
 */
static media_strategy_t *strategyp[] = {
	&media_strategy_simple,
	&media_strategy_rmvtape,
};


/* definition of locally defined global functions ****************************/

/* media_create - select and initialize a media strategy.
 * and create and initialize media managers for each stream.
 */
media_strategy_t *
media_create(int argc, char *argv[], drive_strategy_t *dsp)
{
	int c;
	size_t mediaix;
	size_t mediacnt;
	media_t **mediapp;
	char *medialabel;
	media_strategy_t **spp = strategyp;
	media_strategy_t **epp = strategyp + sizeof(strategyp)
					     /
					     sizeof(strategyp[0]);
	media_strategy_t *chosen_sp;
	int id;
	bool_t ok;

	/* sanity check asserts
	 */
	assert(sizeof(media_hdr_t) == MEDIA_HDR_SZ);
	assert(MEDIA_MARKLOG_SZ == sizeof(media_marklog_t));

	/* scan the command line for a media label
	 */
	medialabel = 0;
	optind = 1;
	opterr = 0;
	while ((c = getopt(argc, argv, GETOPT_CMDSTRING)) != EOF) {
		switch (c) {
#ifdef DUMP
		case GETOPT_MEDIALABEL:
			if (medialabel) {
				mlog(MLOG_NORMAL,
				      _("too many -%c arguments: "
				      "\"-%c %s\" already given\n"),
				      c,
				      c,
				      medialabel);
				usage();
				return 0;
			}
			if (!optarg || optarg[0] == '-') {
				mlog(MLOG_NORMAL,
				      _("-%c argument missing\n"),
				      c);
				usage();
				return 0;
			}
			medialabel = optarg;
			break;
#endif /* DUMP */
		}
	}

	/* if no media label specified, synthesize one
	 */
	if (!medialabel) {
		/* not useful
		mlog(MLOG_VERBOSE,
		      _("WARNING: no media label specified\n"));
		*/
		medialabel = "";
	}

	/* create a media_t array, and a media_ts for each drive.
	 * Initialize each media_t's generic portions. these will
	 * be lended to each media strategy during the strategy
	 * match phase, and given to the winning strategy.
	 */
	mediacnt = dsp->ds_drivecnt;
	mediapp = (media_t **)calloc(mediacnt, sizeof(media_t *));
	assert(mediapp);
	for (mediaix = 0; mediaix < mediacnt; mediaix++) {
		mediapp[mediaix] = media_alloc(dsp->ds_drivep[mediaix],
					 	  medialabel);
	}

	/* choose the first strategy which claims appropriateness.
	 * if none match, return null. Also, initialize the strategy ID
	 * and pointer to the drive strategy. the ID is simply the index
	 * of the strategy in the strategy array. it is placed in the
	 * media_strategy_t as well as the write headers.
	 */
	chosen_sp = 0;
	for (id = 0; spp < epp; spp++, id++) {
		(*spp)->ms_id = id;
		if (!chosen_sp) {
			/* lend the media_t array to the strategy
			 */
			(*spp)->ms_mediap = mediapp;
			(*spp)->ms_dsp = dsp;
			(*spp)->ms_mediacnt = mediacnt;
			for (mediaix = 0; mediaix < mediacnt; mediaix++) {
				media_t *mediap = mediapp[mediaix];
				mediap->m_strategyp = *spp;
				mediap->m_writehdrp->mh_strategyid = id;
			}
			if ((*(*spp)->ms_match)(argc, argv, dsp)) {
				chosen_sp = *spp;
			}
		}
	}
	if (!chosen_sp) {
		mlog(MLOG_NORMAL,
#ifdef DUMP
		      _("no media strategy available for selected "
		      "dump destination(s)\n")
#endif /* DUMP */
#ifdef RESTORE
		      _("no media strategy available for selected "
		      "restore source(s)\n")
#endif /* RESTORE */
			);
		usage();
		return 0;
	}

	/* give the media_t array to the chosen strategy
	 */
	for (mediaix = 0; mediaix < mediacnt; mediaix++) {
		media_t *mediap = mediapp[mediaix];
		mediap->m_strategyp = chosen_sp;
		mediap->m_writehdrp->mh_strategyid = chosen_sp->ms_id;
	}

	/* initialize the strategy. this will cause each of the managers
	 * to be initialized as well. if error, return 0.
	 */
	ok = (*chosen_sp->ms_create)(chosen_sp, argc, argv);
	if (!ok) {
		return 0;
	}

	/* return the selected strategy
	 */
	return chosen_sp;
}

bool_t
media_init(media_strategy_t *msp, int argc, char *argv[])
{
	bool_t ok;

	ok = (*msp->ms_init)(msp, argc, argv);

	return ok;
}

void
media_complete(media_strategy_t *msp)
{
	(*msp->ms_complete)(msp);
}

/* media_get_upper_hdrs - supply pointers to portion of media file headers
 * set aside for upper software layers, as well as to the global hdrs
 */
void
media_get_upper_hdrs(media_t *mediap,
		      global_hdr_t **grhdrpp,
		      char **rhdrpp,
		      size_t *rhdrszp,
		      global_hdr_t **gwhdrpp,
		      char **whdrpp,
		      size_t *whdrszp)
{
	*grhdrpp = mediap->m_greadhdrp;
	*rhdrpp = mediap->m_readhdrp->mh_upper;
	*rhdrszp = sizeof(mediap->m_readhdrp->mh_upper);

	*gwhdrpp = mediap->m_gwritehdrp;
	*whdrpp = mediap->m_writehdrp->mh_upper;
	*whdrszp = sizeof(mediap->m_writehdrp->mh_upper);
}


/* definition of locally defined static functions ****************************/

/* media_alloc - allocate and initialize the generic portions of a media
 * descriptor and read and write media headers
 */
static media_t *
media_alloc(drive_t *drivep,
	     char *medialabel)
{
	media_t *mediap;
	global_hdr_t *grhdrp;
	global_hdr_t *gwhdrp;
	media_hdr_t *mrhdrp;
	media_hdr_t *mwhdrp;
	size_t mrhdrsz;
	size_t mwhdrsz;

	mediap = (media_t *)calloc(1, sizeof(media_t));
	assert(mediap);

	grhdrp = 0;
	gwhdrp = 0;
	mrhdrp = 0;
	mwhdrp = 0;
	drive_get_upper_hdrs(drivep,
			      &grhdrp,
			      (char **)&mrhdrp,
			      &mrhdrsz,
			      &gwhdrp,
			      (char **)&mwhdrp,
			      &mwhdrsz);
	assert(grhdrp);
	assert(gwhdrp);
	assert(mrhdrp);
	assert(mwhdrp);
	assert(mrhdrsz == MEDIA_HDR_SZ);
	assert(mwhdrsz == MEDIA_HDR_SZ);

	mediap->m_greadhdrp = grhdrp;
	mediap->m_gwritehdrp = gwhdrp;
	mediap->m_readhdrp = mrhdrp;
	mediap->m_writehdrp = mwhdrp;
	mediap->m_drivep = drivep;

	strncpyterm(mwhdrp->mh_medialabel,
		     medialabel,
		     sizeof(mwhdrp->mh_medialabel));

#ifdef DUMP
	uuid_create(mwhdrp->mh_mediaid);
#else /* DUMP */
	uuid_clear(mwhdrp->mh_mediaid);
#endif /* DUMP */

	return mediap;
}