2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-1998, 2000 University of Maryland at College Park
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of U.M. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. U.M. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
16 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Authors: the Amanda Development Team. Its members are listed in a
24 * file named AUTHORS, in the root directory of this distribution.
27 * $Id: amlabel.c,v 1.53.2.2 2007/02/06 14:07:44 martinea Exp $
29 * write an Amanda label on a tape
39 #endif /* HAVE_LIBVTBLC */
43 int main(int argc, char **argv);
49 fprintf(stderr, "Usage: %s [-f] <conf> <label> [slot <slot-number>] [-o configoption]*\n",
62 char *errstr = NULL, *label, *oldlabel=NULL, *tapename = NULL;
63 char *labelstr, *slotstr;
64 char *olddatestamp=NULL;
65 char *conf_tapelist_old;
66 unsigned long malloc_hist_1, malloc_size_1;
67 unsigned long malloc_hist_2, malloc_size_2;
68 #ifdef HAVE_LINUX_ZFTAPE_H
71 #endif /* HAVE_LINUX_ZFTAPE_H */
75 size_t tt_blocksize_kb;
87 char *rawtapedev = NULL;
88 int first_seg, last_seg;
89 #endif /* HAVE_LIBVTBLC */
96 dbopen(DBG_SUBDIR_SERVER);
98 /* Don't die when child closes pipe */
99 signal(SIGPIPE, SIG_IGN);
101 malloc_size_1 = malloc_inuse(&malloc_hist_1);
103 erroutput_type = ERR_INTERACTIVE;
105 parse_server_conf(argc, argv, &new_argc, &new_argv);
107 if(new_argc > 1 && strcmp(new_argv[1],"-f") == 0)
111 if(new_argc != 3+force && new_argc != 5+force)
114 config_name = new_argv[1+force];
115 label = new_argv[2+force];
117 if(new_argc == 5+force) {
118 if(strcmp(new_argv[3+force], "slot"))
120 slotstr = new_argv[4+force];
127 config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
128 conffile = stralloc2(config_dir, CONFFILE_NAME);
129 if (read_conffile(conffile)) {
130 error("errors processing config file \"%s\"", conffile);
134 dbrename(config_name, DBG_SUBDIR_SERVER);
136 report_bad_conf_arg();
138 conf_tapelist = getconf_str(CNF_TAPELIST);
139 if (*conf_tapelist == '/') {
140 conf_tapelist = stralloc(conf_tapelist);
142 conf_tapelist = stralloc2(config_dir, conf_tapelist);
144 if (read_tapelist(conf_tapelist)) {
145 error("could not load tapelist \"%s\"", conf_tapelist);
150 uid_dumpuser = uid_me;
151 dumpuser = getconf_str(CNF_DUMPUSER);
153 if ((pw = getpwnam(dumpuser)) == NULL) {
154 error("cannot look up dump user \"%s\"", dumpuser);
157 uid_dumpuser = pw->pw_uid;
158 if ((pw = getpwuid(uid_me)) == NULL) {
159 error("cannot look up my own uid %ld", (long)uid_me);
162 if (uid_me != uid_dumpuser) {
163 error("running as user \"%s\" instead of \"%s\"",
164 pw->pw_name, dumpuser);
168 labelstr = getconf_str(CNF_LABELSTR);
170 if(!match(labelstr, label)) {
171 error("label %s doesn't match labelstr \"%s\"", label, labelstr);
175 if((lookup_tapelabel(label))!=NULL) {
177 error("label %s already on a tape\n",label);
181 tape = lookup_tapetype(getconf_str(CNF_TAPETYPE));
182 tt_blocksize_kb = (size_t)tapetype_get_blocksize(tape);
184 if((have_changer = changer_init()) == 0) {
187 "%s: no tpchanger specified in \"%s\", so slot command invalid\n",
188 new_argv[0], conffile);
191 tapename = getconf_str(CNF_TAPEDEV);
192 if (tapename == NULL) {
193 error("No tapedev specified");
195 tapename = stralloc(tapename);
198 rawtapedev = stralloc(getconf_str(CNF_RAWTAPEDEV));
199 #endif /* HAVE_LIBVTBLC */
200 } else if(have_changer != 1) {
201 error("changer initialization failed: %s", strerror(errno));
204 if(changer_loadslot(slotstr, &outslot, &tapename)) {
205 error("could not load slot \"%s\": %s", slotstr, changer_resultstr);
209 printf("labeling tape in slot %s (%s):\n", outslot, tapename);
212 #ifdef HAVE_LINUX_ZFTAPE_H
213 isa_zftape = is_zftape(tapename);
215 if((fd = tape_open(tapename, O_WRONLY)) == -1) {
216 errstr = newstralloc2(errstr, "amlabel: ",
217 (errno == EACCES) ? "tape is write-protected"
223 #endif /* HAVE_LINUX_ZFTAPE_H */
225 printf("rewinding"); fflush(stdout);
227 #ifdef HAVE_LINUX_ZFTAPE_H
229 if(tapefd_rewind(fd) == -1) {
231 error(strerror(errno));
236 #endif /* HAVE_LINUX_ZFTAPE_H */
237 if((errstr = tape_rewind(tapename)) != NULL) {
244 printf(", reading label");fflush(stdout);
245 if((errstr = tape_rdlabel(tapename, &olddatestamp, &oldlabel)) != NULL) {
246 printf(", %s\n",errstr);
250 /* got an amanda tape */
251 printf(" %s",oldlabel);
252 if(strcmp(oldlabel, FAKE_LABEL) != 0
253 && match(labelstr, oldlabel) == 0) {
254 printf(", tape is in another amanda configuration");
259 if((lookup_tapelabel(oldlabel)) != NULL) {
260 printf(", tape is active");
268 amfree(olddatestamp);
270 printf("rewinding"); fflush(stdout);
272 #ifdef HAVE_LINUX_ZFTAPE_H
274 if(tapefd_rewind(fd) == -1) {
276 error(strerror(errno));
281 #endif /* HAVE_LINUX_ZFTAPE_H */
282 if((errstr = tape_rewind(tapename)) != NULL) {
289 printf(", writing label %s", label); fflush(stdout);
291 #ifdef HAVE_LINUX_ZFTAPE_H
293 errstr = tapefd_wrlabel(fd, "X", label,
294 (tt_blocksize_kb * 1024));
302 #endif /* HAVE_LINUX_ZFTAPE_H */
303 errstr = tape_wrlabel(tapename, "X", label,
304 (tt_blocksize_kb * 1024));
311 #ifdef HAVE_LINUX_ZFTAPE_H
313 tapefd_weof(fd, (off_t)1);
315 #endif /* HAVE_LINUX_ZFTAPE_H */
317 #ifdef HAVE_LINUX_ZFTAPE_H
319 errstr = tapefd_wrendmark(fd, "X",
320 (tt_blocksize_kb * 1024));
328 #endif /* HAVE_LINUX_ZFTAPE_H */
329 errstr = tape_wrendmark(tapename, "X",
330 (tt_blocksize_kb * 1024));
337 #ifdef HAVE_LINUX_ZFTAPE_H
339 tapefd_weof(fd, (off_t)1);
341 printf(",\nrewinding"); fflush(stdout);
343 if(tapefd_rewind(fd) == -1) {
345 error(strerror(errno));
350 /* update volume table */
351 printf(", updating volume table"); fflush(stdout);
353 if ((fd = raw_tape_open(rawtapedev, O_RDWR)) == -1) {
354 if(errno == EACCES) {
355 errstr = newstralloc(errstr,
356 "updating volume table: raw tape device is write protected");
358 errstr = newstralloc2(errstr,
359 "updating volume table: ", strerror(errno));
365 /* read volume table */
366 if ((num_volumes = read_vtbl(fd, volumes, vtbl_buffer,
367 &first_seg, &last_seg)) == -1 ) {
368 errstr = newstralloc2(errstr,
369 "reading volume table: ", strerror(errno));
374 /* set date and volume label for first entry */
377 if (set_date(datestr, volumes, num_volumes, vtbl_no)){
378 errstr = newstralloc2(errstr,
379 "setting date for entry 1: ", strerror(errno));
384 if(set_label(label, volumes, num_volumes, vtbl_no)){
385 errstr = newstralloc2(errstr,
386 "setting label for entry 1: ", strerror(errno));
391 /* set date and volume label for last entry */
394 if (set_date(datestr, volumes, num_volumes, vtbl_no)){
395 errstr = newstralloc2(errstr,
396 "setting date for entry 2: ", strerror(errno));
401 if(set_label("AMANDA Tape End", volumes, num_volumes, vtbl_no)){
402 errstr = newstralloc2(errstr,
403 "setting label for entry 2: ", strerror(errno));
408 /* write volume table back */
409 if (write_vtbl(fd, volumes, vtbl_buffer, num_volumes, first_seg,
411 errstr = newstralloc2(errstr,
412 "writing volume table: ", strerror(errno));
418 #endif /* HAVE_LIBVTBLC */
420 #endif /* HAVE_LINUX_ZFTAPE_H */
423 printf(", checking label"); fflush(stdout);
425 if((errstr = tape_rdlabel(tapename, &olddatestamp, &oldlabel)) != NULL) {
427 if (strcmp(errstr, "not an amanda tape") != 0) {
431 error("no label found, are you sure %s is non-rewinding?",
436 if (strcmp("X", olddatestamp) != 0 ||
437 (strcmp(oldlabel, FAKE_LABEL) != 0
438 && strcmp(label, oldlabel) != 0)) {
440 error("read label %s back, timestamp %s (expected X), what now?",
441 oldlabel, olddatestamp);
445 amfree(olddatestamp);
447 /* write tape list */
450 conf_tapelist_old = stralloc2(conf_tapelist, ".amlabel");
451 if(write_tapelist(conf_tapelist_old)) {
452 error("couldn't write tapelist: %s", strerror(errno));
455 amfree(conf_tapelist_old);
457 /* XXX add cur_tape number to tape list structure */
458 remove_tapelabel(label);
459 add_tapelabel("0", label);
460 if(write_tapelist(conf_tapelist)) {
461 error("couldn't write tapelist: %s", strerror(errno));
466 changer_label(outslot, label);
468 } /* write tape list */
471 printf("\ntape not labeled\n");
475 free_new_argv(new_argc, new_argv);
476 free_server_config();
480 amfree(conf_tapelist);
485 malloc_size_2 = malloc_inuse(&malloc_hist_2);
487 if(malloc_size_1 != malloc_size_2) {
488 malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);