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.18.2.15.4.3.2.4.2.4 2005/10/02 13:48:42 martinea Exp $
29 * write an Amanda label on a tape
39 #endif /* HAVE_LIBVTBLC */
43 void usage P((char *argv0));
48 fprintf(stderr, "Usage: %s [-f] <conf> <label> [slot <slot-number>]\n",
60 char *errstr = NULL, *label, *oldlabel=NULL, *tapename = NULL;
61 char *labelstr, *slotstr;
62 char *olddatestamp=NULL;
63 char *conf_tapelist_old;
64 unsigned long malloc_hist_1, malloc_size_1;
65 unsigned long malloc_hist_2, malloc_size_2;
66 #ifdef HAVE_LINUX_ZFTAPE_H
69 #endif /* HAVE_LINUX_ZFTAPE_H */
84 char *rawtapedev = NULL;
85 int first_seg, last_seg;
86 #endif /* HAVE_LIBVTBLC */
94 malloc_size_1 = malloc_inuse(&malloc_hist_1);
96 erroutput_type = ERR_INTERACTIVE;
98 if(argc > 1 && strcmp(argv[1],"-f") == 0)
102 if(argc != 3+force && argc != 5+force)
105 config_name = argv[1+force];
106 label = argv[2+force];
108 if(argc == 5+force) {
109 if(strcmp(argv[3+force], "slot"))
111 slotstr = argv[4+force];
118 config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
119 conffile = stralloc2(config_dir, CONFFILE_NAME);
120 if (read_conffile(conffile)) {
121 error("errors processing config file \"%s\"", conffile);
123 conf_tapelist = getconf_str(CNF_TAPELIST);
124 if (*conf_tapelist == '/') {
125 conf_tapelist = stralloc(conf_tapelist);
127 conf_tapelist = stralloc2(config_dir, conf_tapelist);
129 if (read_tapelist(conf_tapelist)) {
130 error("could not load tapelist \"%s\"", conf_tapelist);
134 uid_dumpuser = uid_me;
135 dumpuser = getconf_str(CNF_DUMPUSER);
137 if ((pw = getpwnam(dumpuser)) == NULL) {
138 error("cannot look up dump user \"%s\"", dumpuser);
141 uid_dumpuser = pw->pw_uid;
142 if ((pw = getpwuid(uid_me)) == NULL) {
143 error("cannot look up my own uid %ld", (long)uid_me);
146 if (uid_me != uid_dumpuser) {
147 error("running as user \"%s\" instead of \"%s\"",
148 pw->pw_name, dumpuser);
152 labelstr = getconf_str(CNF_LABELSTR);
154 if(!match(labelstr, label))
155 error("label %s doesn't match labelstr \"%s\"", label, labelstr);
157 if((tp = lookup_tapelabel(label))!=NULL) {
159 error("label %s already on a tape\n",label);
161 tape = lookup_tapetype(getconf_str(CNF_TAPETYPE));
162 tt_blocksize_kb = tape->blocksize;
164 if((have_changer = changer_init()) == 0) {
167 "%s: no tpchanger specified in \"%s\", so slot command invalid\n",
171 tapename = stralloc(getconf_str(CNF_TAPEDEV));
173 rawtapedev = stralloc(getconf_str(CNF_RAWTAPEDEV));
174 #endif /* HAVE_LIBVTBLC */
175 } else if(have_changer != 1) {
176 error("changer initialization failed: %s", strerror(errno));
178 if(changer_loadslot(slotstr, &outslot, &tapename)) {
179 error("could not load slot \"%s\": %s", slotstr, changer_resultstr);
182 printf("labeling tape in slot %s (%s):\n", outslot, tapename);
185 #ifdef HAVE_LINUX_ZFTAPE_H
186 isa_zftape = is_zftape(tapename);
188 if((fd = tape_open(tapename, O_WRONLY)) == -1) {
189 errstr = newstralloc2(errstr, "amlabel: ",
190 (errno == EACCES) ? "tape is write-protected"
195 #endif /* HAVE_LINUX_ZFTAPE_H */
197 printf("rewinding"); fflush(stdout);
199 #ifdef HAVE_LINUX_ZFTAPE_H
201 if(tapefd_rewind(fd) == -1) {
203 error(strerror(errno));
207 #endif /* HAVE_LINUX_ZFTAPE_H */
208 if((errstr = tape_rewind(tapename)) != NULL) {
214 printf(", reading label");fflush(stdout);
215 if((errstr = tape_rdlabel(tapename, &olddatestamp, &oldlabel)) != NULL) {
216 printf(", %s\n",errstr);
220 /* got an amanda tape */
221 printf(" %s",oldlabel);
222 if(strcmp(oldlabel, FAKE_LABEL) != 0
223 && match(labelstr, oldlabel) == 0) {
224 printf(", tape is in another amanda configuration");
229 if((tp = lookup_tapelabel(oldlabel)) != NULL) {
230 printf(", tape is active");
238 amfree(olddatestamp);
240 printf("rewinding"); fflush(stdout);
242 #ifdef HAVE_LINUX_ZFTAPE_H
244 if(tapefd_rewind(fd) == -1) {
246 error(strerror(errno));
250 #endif /* HAVE_LINUX_ZFTAPE_H */
251 if((errstr = tape_rewind(tapename)) != NULL) {
257 printf(", writing label %s", label); fflush(stdout);
259 #ifdef HAVE_LINUX_ZFTAPE_H
261 errstr = tapefd_wrlabel(fd, "X", label, tt_blocksize_kb * 1024);
268 #endif /* HAVE_LINUX_ZFTAPE_H */
269 errstr = tape_wrlabel(tapename, "X", label, tt_blocksize_kb * 1024);
275 #ifdef HAVE_LINUX_ZFTAPE_H
279 #endif /* HAVE_LINUX_ZFTAPE_H */
281 #ifdef HAVE_LINUX_ZFTAPE_H
283 errstr = tapefd_wrendmark(fd, "X", tt_blocksize_kb * 1024);
290 #endif /* HAVE_LINUX_ZFTAPE_H */
291 errstr = tape_wrendmark(tapename, "X", tt_blocksize_kb * 1024);
297 #ifdef HAVE_LINUX_ZFTAPE_H
301 printf(",\nrewinding"); fflush(stdout);
303 if(tapefd_rewind(fd) == -1) {
305 error(strerror(errno));
309 /* update volume table */
310 printf(", updating volume table"); fflush(stdout);
312 if ((fd = raw_tape_open(rawtapedev, O_RDWR)) == -1) {
313 if(errno == EACCES) {
314 errstr = newstralloc(errstr,
315 "updating volume table: raw tape device is write protected");
317 errstr = newstralloc2(errstr,
318 "updating volume table: ", strerror(errno));
323 /* read volume table */
324 if ((num_volumes = read_vtbl(fd, volumes, vtbl_buffer,
325 &first_seg, &last_seg)) == -1 ) {
326 errstr = newstralloc2(errstr,
327 "reading volume table: ", strerror(errno));
331 /* set date and volume label for first entry */
334 if (set_date(datestr, volumes, num_volumes, vtbl_no)){
335 errstr = newstralloc2(errstr,
336 "setting date for entry 1: ", strerror(errno));
340 if(set_label(label, volumes, num_volumes, vtbl_no)){
341 errstr = newstralloc2(errstr,
342 "setting label for entry 1: ", strerror(errno));
346 /* set date and volume label for last entry */
349 if (set_date(datestr, volumes, num_volumes, vtbl_no)){
350 errstr = newstralloc2(errstr,
351 "setting date for entry 2: ", strerror(errno));
355 if(set_label("AMANDA Tape End", volumes, num_volumes, vtbl_no)){
356 errstr = newstralloc2(errstr,
357 "setting label for entry 2: ", strerror(errno));
361 /* write volume table back */
362 if (write_vtbl(fd, volumes, vtbl_buffer, num_volumes, first_seg,
364 errstr = newstralloc2(errstr,
365 "writing volume table: ", strerror(errno));
370 #endif /* HAVE_LIBVTBLC */
372 #endif /* HAVE_LINUX_ZFTAPE_H */
375 printf(", checking label"); fflush(stdout);
377 if((errstr = tape_rdlabel(tapename, &olddatestamp, &oldlabel)) != NULL) {
379 if (strcmp(errstr, "not an amanda tape") != 0)
381 error("no label found, are you sure %s is non-rewinding?",
385 if (strcmp("X", olddatestamp) != 0 ||
386 (strcmp(oldlabel, FAKE_LABEL) != 0
387 && strcmp(label, oldlabel) != 0)) {
389 error("read label %s back, timestamp %s (expected X), what now?",
390 oldlabel, olddatestamp);
393 amfree(olddatestamp);
395 /* write tape list */
398 conf_tapelist_old = stralloc2(conf_tapelist, ".amlabel");
399 if(write_tapelist(conf_tapelist_old)) {
400 error("couldn't write tapelist: %s", strerror(errno));
402 amfree(conf_tapelist_old);
404 /* XXX add cur_tape number to tape list structure */
405 remove_tapelabel(label);
406 add_tapelabel(0, label);
407 if(write_tapelist(conf_tapelist)) {
408 error("couldn't write tapelist: %s", strerror(errno));
410 } /* write tape list */
413 /* Now we try to inform the changer, about the new label */
414 changer_label(outslot,label);
418 printf("\ntape not labeled\n");
424 amfree(conf_tapelist);
428 malloc_size_2 = malloc_inuse(&malloc_hist_2);
430 if(malloc_size_1 != malloc_size_2) {
431 malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);