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 2006/07/25 18:27:57 martinea Exp $
29 * write an Amanda label on a tape
36 #include <timestamp.h>
37 #include <taperscan.h>
41 int main(int argc, char **argv);
43 static void usage(void) {
44 g_fprintf(stderr, _("Usage: %s [-f] <conf> <label> [slot <slot-number>] [-o configoption]*\n"),
49 static void print_read_label_status_error(ReadLabelStatusFlags status) {
52 if (status == READ_LABEL_STATUS_SUCCESS)
55 status_strv = g_flags_nick_to_strv(status,
56 READ_LABEL_STATUS_FLAGS_TYPE);
57 g_assert(g_strv_length(status_strv) > 0);
58 if (g_strv_length(status_strv) == 1) {
59 g_printf("Error was %s.\n", *status_strv);
61 char * status_list = g_english_strjoinv(status_strv, "or");
62 g_printf("Error was one of %s.\n", status_list);
65 g_strfreev(status_strv);
75 char *label, *tapename = NULL;
76 char *labelstr, *slotstr;
77 char *conf_tapelist_old;
81 size_t tt_blocksize_kb;
84 ReadLabelStatusFlags label_status;
86 config_overwrites_t *cfg_ovr = NULL;
89 * Configure program for internationalization:
90 * 1) Only set the message locale for now.
91 * 2) Set textdomain for all amanda related programs to "amanda"
92 * We don't want to be forced to support dozens of message catalogs.
94 setlocale(LC_MESSAGES, "C");
100 set_pname("amlabel");
102 dbopen(DBG_SUBDIR_SERVER);
105 /* Don't die when child closes pipe */
106 signal(SIGPIPE, SIG_IGN);
108 malloc_size_1 = malloc_inuse(&malloc_hist_1);
110 erroutput_type = ERR_INTERACTIVE;
112 cfg_ovr = extract_commandline_config_overwrites(&argc, &argv);
114 if(argc > 1 && strcmp(argv[1],"-f") == 0)
118 if(argc != 3+force && argc != 5+force)
121 cfg_opt = argv[1+force];
122 label = argv[2+force];
124 if(argc == 5+force) {
125 if(strcmp(argv[3+force], "slot"))
127 slotstr = argv[4+force];
134 config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_FATAL,
136 apply_config_overwrites(cfg_ovr);
138 check_running_as(RUNNING_AS_DUMPUSER);
140 dbrename(config_name, DBG_SUBDIR_SERVER);
142 conf_tapelist = config_dir_relative(getconf_str(CNF_TAPELIST));
143 if (read_tapelist(conf_tapelist)) {
144 error(_("could not load tapelist \"%s\""), conf_tapelist);
148 labelstr = getconf_str(CNF_LABELSTR);
150 if(!match(labelstr, label)) {
151 error(_("label %s doesn't match labelstr \"%s\""), label, labelstr);
155 if((lookup_tapelabel(label))!=NULL) {
157 error(_("label %s already on a tape\n"),label);
161 tape = lookup_tapetype(getconf_str(CNF_TAPETYPE));
162 tt_blocksize_kb = (size_t)tapetype_get_blocksize(tape);
164 if((have_changer = changer_init()) == 0) {
167 _("%s: no tpchanger specified in \"%s\", so slot command invalid\n"),
168 argv[0], config_filename);
171 tapename = getconf_str(CNF_TAPEDEV);
172 if (tapename == NULL) {
173 error(_("No tapedev specified"));
175 } else if(have_changer != 1) {
176 error(_("changer initialization failed: %s"), strerror(errno));
179 if(changer_loadslot(slotstr, &outslot, &tapename)) {
180 error(_("could not load slot \"%s\": %s"), slotstr, changer_resultstr);
184 #endif /* HAVE_LINUX_ZFTAPE_H */
186 g_printf(_("labeling tape in slot %s (%s):\n"), outslot, tapename);
190 g_printf("Reading label...\n");fflush(stdout);
191 device = device_open(tapename);
192 if (device == NULL) {
193 error("Could not open device %s.\n", tapename);
196 device_set_startup_properties_from_config(device);
197 label_status = device_read_label(device);
199 if (label_status & READ_LABEL_STATUS_VOLUME_UNLABELED) {
200 g_printf("Found an unlabeled tape.\n");
201 } else if (label_status != READ_LABEL_STATUS_SUCCESS) {
202 g_printf("Reading the tape label failed: \n ");
203 print_read_label_status_error(label_status);
206 /* got an amanda tape */
207 g_printf(_("Found Amanda tape %s"),device->volume_label);
208 if(match(labelstr, device->volume_label) == 0) {
209 g_printf(_(", but it is not from configuration %s."), config_name);
213 if((lookup_tapelabel(device->volume_label)) != NULL) {
214 g_printf(_(", tape is active"));
223 char *timestamp = NULL;
225 g_printf(_("Writing label %s..\n"), label); fflush(stdout);
227 timestamp = get_undef_timestamp();
228 if (!device_start(device, ACCESS_WRITE, label, timestamp)) {
229 error(_("Error writing label.\n"));
230 g_assert_not_reached();
231 } else if (!device_finish(device)) {
232 error(_("Error closing device.\n"));
233 g_assert_not_reached();
237 g_printf(_("Checking label...\n")); fflush(stdout);
239 label_status = device_read_label(device);
240 if (label_status != READ_LABEL_STATUS_SUCCESS) {
241 g_printf("Checking the tape label failed: \n ");
242 print_read_label_status_error(label_status);
244 } else if (device->volume_label == NULL) {
245 error(_("no label found.\n"));
246 g_assert_not_reached();
247 } else if (strcmp(device->volume_label, label) != 0) {
248 error(_("Read back a different label: Got %s, but expected %s\n"),
249 device->volume_label, label);
250 g_assert_not_reached();
251 } else if (get_timestamp_state(device->volume_time) !=
253 error(_("Read the right label, but the wrong timestamp: "
254 "Got %s, expected X.\n"), device->volume_time);
255 g_assert_not_reached();
258 /* write tape list */
261 conf_tapelist_old = stralloc2(conf_tapelist, ".amlabel");
262 if(write_tapelist(conf_tapelist_old)) {
263 error(_("couldn't write tapelist: %s"), strerror(errno));
266 amfree(conf_tapelist_old);
268 /* XXX add cur_tape number to tape list structure */
269 remove_tapelabel(label);
270 add_tapelabel("0", label);
271 if(write_tapelist(conf_tapelist)) {
272 error(_("couldn't write tapelist: %s"), strerror(errno));
276 g_printf(_("Success!\n"));
278 g_printf(_("\ntape not labeled\n"));
281 g_object_unref(device);
286 amfree(conf_tapelist);