3 * dvd.c -- Routines specific to DVD devices (and
4 * possibly other removable hard media).
11 Copyright (C) 2005 Kern Sibbald
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License
15 version 2 as ammended with additional clauses defined in the
16 file LICENSE in the main source directory.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 the file LICENSE for additional details.
28 int mount_dev(DEVICE *dev, int timeout);
29 int unmount_dev(DEVICE *dev, int timeout);
30 void update_free_space_dev(DEVICE *dev);
31 void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name);
33 /* Forward referenced functions */
34 static char *edit_device_codes_dev(DEVICE *dev, char *omsg, const char *imsg);
35 static int do_mount_dev(DEVICE* dev, int mount, int dotimeout);
36 static int dvd_write_part(DEVICE *dev);
40 * Write the current volume/part filename to archive_name.
42 void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name)
47 /* If we try to open the last part, just open it from disk,
48 * otherwise, open it from the spooling directory */
49 if (dev->part < dev->num_parts) {
50 pm_strcpy(archive_name, dev->device->mount_point);
52 /* Use the working directory if spool directory is not defined */
53 if (dev->device->spool_directory) {
54 pm_strcpy(archive_name, dev->device->spool_directory);
56 pm_strcpy(archive_name, working_directory);
60 pm_strcpy(archive_name, dev->dev_name);
63 if (archive_name.c_str()[strlen(archive_name.c_str())-1] != '/') {
64 pm_strcat(archive_name, "/");
66 pm_strcat(archive_name, VolName);
67 /* if part != 0, append .# to the filename (where # is the part number) */
68 if (dev->is_dvd() && dev->part != 0) {
69 pm_strcat(archive_name, ".");
70 bsnprintf(partnumber, sizeof(partnumber), "%d", dev->part);
71 pm_strcat(archive_name, partnumber);
76 * If timeout, wait until the mount command returns 0.
77 * If !timeout, try to mount the device only once.
79 int mount_dev(DEVICE* dev, int timeout)
81 if (dev->state & ST_MOUNTED) {
82 Dmsg0(100, "mount_dev: Device already mounted\n");
84 } else if (dev_cap(dev, CAP_REQMOUNT)) {
85 return do_mount_dev(dev, 1, timeout);
91 * If timeout, wait until the unmount command returns 0.
92 * If !timeout, try to unmount the device only once.
94 int unmount_dev(DEVICE *dev, int timeout)
96 if (dev->state & ST_MOUNTED) {
97 return do_mount_dev(dev, 0, timeout);
99 Dmsg0(100, "mount_dev: Device already unmounted\n");
103 /* (Un)mount the device */
104 static int do_mount_dev(DEVICE* dev, int mount, int dotimeout) {
105 POOL_MEM ocmd(PM_FNAME);
107 results = get_pool_memory(PM_MESSAGE);
112 icmd = dev->device->mount_command;
115 icmd = dev->device->unmount_command;
118 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
120 Dmsg2(29, "do_mount_dev: cmd=%s state=%d\n", ocmd.c_str(), dev->state & ST_MOUNTED);
123 /* Try at most 5 times to (un)mount the device. This should perhaps be configurable. */
129 /* If busy retry each second */
130 while ((status = run_program_full_output(ocmd.c_str(), dev->max_open_wait/2, results)) != 0) {
132 Dmsg2(40, "Device %s cannot be (un)mounted. Retrying... ERR=%s\n", dev->dev_name, results);
133 /* Sometimes the device cannot be mounted because it is already mounted.
134 * Try to unmount it, then remount it */
136 Dmsg1(40, "Trying to unmount the device %s...\n", dev->dev_name);
137 do_mount_dev(dev, 0, 0);
142 free_pool_memory(results);
143 Dmsg2(40, "Device %s cannot be mounted. ERR=%s\n", dev->dev_name, results);
148 dev->state |= ST_MOUNTED;
150 dev->state &= ~ST_MOUNTED;
152 free_pool_memory(results);
154 Dmsg1(29, "do_mount_dev: end_state=%d\n", dev->state & ST_MOUNTED);
158 /* Only for devices that require a mount.
159 * Try to find the volume name of the loaded device, and open the
160 * first part of this volume.
162 * Returns 0 if read_dev_volume_label can now read the label,
163 * -1 if an error occured, and read_dev_volume_label_guess must abort with an IO_ERROR.
165 * To guess the device name, it lists all the files on the DVD, and searches for a
166 * file which has a minimum size (500 bytes). If this file has a numeric extension,
167 * like part files, try to open the file which has no extension (e.g. the first
169 * So, if the DVD does not contains a Bacula volume, a random file is opened,
170 * and no valid label could be read from this file.
172 * It is useful, so the operator can be told that a wrong volume is mounted, with
173 * the label name of the current volume. We can also check that the currently
174 * mounted disk is writable. (See also read_dev_volume_label_guess in label.c).
176 * Note that if the right volume is mounted, open_guess_name_dev returns the same
177 * result as an usual open_dev.
179 int open_guess_name_dev(DEVICE *dev)
181 Dmsg1(29, "open_guess_name_dev: dev=%s\n", dev->dev_name);
182 POOL_MEM guessedname(PM_FNAME);
184 struct dirent *entry, *result;
189 if (!dev->is_dvd()) {
190 Dmsg1(100, "open_guess_name_dev: device does not require mount, returning 0. dev=%s\n", dev->dev_name);
194 #ifndef HAVE_DIRENT_H
195 Dmsg0(29, "open_guess_name_dev: readdir not available, cannot guess volume name\n");
199 update_free_space_dev(dev);
201 if (mount_dev(dev, 1) < 0) {
202 /* If the device cannot be mounted, check if it is writable */
203 if (dev->free_space_errno >= 0) {
204 Dmsg1(100, "open_guess_name_dev: device cannot be mounted, but it seems to be writable, returning 0. dev=%s\n", dev->dev_name);
207 Dmsg1(100, "open_guess_name_dev: device cannot be mounted, and is not writable, returning -1. dev=%s\n", dev->dev_name);
212 name_max = pathconf(".", _PC_NAME_MAX);
213 if (name_max < 1024) {
217 if (!(dp = opendir(dev->device->mount_point))) {
219 dev->dev_errno = errno;
220 Dmsg3(29, "open_guess_name_dev: failed to open dir %s (dev=%s), ERR=%s\n", dev->device->mount_point, dev->dev_name, be.strerror());
224 entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 100);
226 if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
227 dev->dev_errno = ENOENT;
228 Dmsg2(29, "open_guess_name_dev: failed to find suitable file in dir %s (dev=%s)\n", dev->device->mount_point, dev->dev_name);
233 ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry));
235 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
239 pm_strcpy(guessedname, dev->device->mount_point);
240 if (guessedname.c_str()[strlen(guessedname.c_str())-1] != '/') {
241 pm_strcat(guessedname, "/");
243 pm_strcat(guessedname, entry->d_name);
245 if (stat(guessedname.c_str(), &statp) < 0) {
247 Dmsg3(29, "open_guess_name_dev: failed to stat %s (dev=%s), ERR=%s\n",
248 guessedname.c_str(), dev->dev_name, be.strerror());
252 if (!S_ISREG(statp.st_mode) || (statp.st_size < 500)) {
253 Dmsg2(100, "open_guess_name_dev: %s is not a regular file, or less than 500 bytes (dev=%s)\n",
254 guessedname.c_str(), dev->dev_name);
258 /* Ok, we found a good file, remove the part extension if possible. */
259 for (index = strlen(guessedname.c_str())-1; index >= 0; index--) {
260 if ((guessedname.c_str()[index] == '/') ||
261 (guessedname.c_str()[index] < '0') ||
262 (guessedname.c_str()[index] > '9')) {
265 if (guessedname.c_str()[index] == '.') {
266 guessedname.c_str()[index] = '\0';
271 if ((stat(guessedname.c_str(), &statp) < 0) || (statp.st_size < 500)) {
272 /* The file with extension truncated does not exists or is too small, so use it with its extension. */
274 Dmsg3(100, "open_guess_name_dev: failed to stat %s (dev=%s), using the file with its extension, ERR=%s\n",
275 guessedname.c_str(), dev->dev_name, be.strerror());
276 pm_strcpy(guessedname, dev->device->mount_point);
277 if (guessedname.c_str()[strlen(guessedname.c_str())-1] != '/') {
278 pm_strcat(guessedname, "/");
280 pm_strcat(guessedname, entry->d_name);
292 if ((dev->fd = open(guessedname.c_str(), O_RDONLY | O_BINARY)) < 0) {
294 dev->dev_errno = errno;
295 Dmsg3(29, "open_guess_name_dev: failed to open %s (dev=%s), ERR=%s\n",
296 guessedname.c_str(), dev->dev_name, be.strerror());
297 if (open_first_part(dev) < 0) {
299 dev->dev_errno = errno;
300 Mmsg1(&dev->errmsg, _("Could not open_first_part, ERR=%s\n"), be.strerror());
301 Emsg0(M_FATAL, 0, dev->errmsg);
306 dev->part_size = statp.st_size;
308 dev->state |= ST_OPENED;
311 Dmsg2(29, "open_guess_name_dev: %s opened (dev=%s)\n", guessedname.c_str(), dev->dev_name);
317 /* Update the free space on the device */
318 void update_free_space_dev(DEVICE* dev)
320 POOL_MEM ocmd(PM_FNAME);
327 icmd = dev->device->free_space_command;
331 dev->free_space_errno = 0;
332 Dmsg2(29, "update_free_space_dev: free_space=%d, free_space_errno=%d (!icmd)\n", dev->free_space, dev->free_space_errno);
336 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
338 Dmsg1(29, "update_free_space_dev: cmd=%s\n", ocmd.c_str());
340 results = get_pool_memory(PM_MESSAGE);
342 /* Try at most 3 times to get the free space on the device. This should perhaps be configurable. */
346 if (run_program_full_output(ocmd.c_str(), dev->max_open_wait/2, results) == 0) {
347 Dmsg1(100, "Free space program run : %s\n", results);
348 free = str_to_int64(results);
350 dev->free_space = free;
351 dev->free_space_errno = 1;
352 Mmsg0(dev->errmsg, "");
357 dev->free_space_errno = -EPIPE;
358 Mmsg1(dev->errmsg, "Cannot run free space command (%s)\n", results);
361 Dmsg4(40, "Cannot get free space on device %s. free_space=%s, "
362 "free_space_errno=%d ERR=%s\n", dev->dev_name,
363 edit_uint64(dev->free_space, ed1), dev->free_space_errno,
369 dev->dev_errno = -dev->free_space_errno;
370 Dmsg4(40, "Cannot get free space on device %s. free_space=%s, "
371 "free_space_errno=%d ERR=%s\n",
372 dev->dev_name, edit_uint64(dev->free_space, ed1),
373 dev->free_space_errno, dev->errmsg);
377 free_pool_memory(results);
378 Dmsg2(29, "update_free_space_dev: free_space=%s, free_space_errno=%d\n",
379 edit_uint64(dev->free_space, ed1), dev->free_space_errno);
383 static int dvd_write_part(DEVICE *dev)
385 Dmsg1(29, "dvd_write_part: device is %s\n", dev->dev_name);
387 if (unmount_dev(dev, 1) < 0) {
388 Dmsg0(29, "dvd_write_part: unable to unmount the device\n");
391 POOL_MEM ocmd(PM_FNAME);
393 results = get_pool_memory(PM_MESSAGE);
398 icmd = dev->device->write_part_command;
400 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
402 /* Wait at most the time a maximum size part is written in DVD 0.5x speed
403 * FIXME: Minimum speed should be in device configuration
405 timeout = dev->max_open_wait + (dev->max_part_size/(1350*1024/2));
407 Dmsg2(29, "dvd_write_part: cmd=%s timeout=%d\n", ocmd.c_str(), timeout);
409 status = run_program_full_output(ocmd.c_str(), timeout, results);
411 Mmsg1(dev->errmsg, "Error while writing current part to the DVD: %s", results);
412 dev->dev_errno = EIO;
413 free_pool_memory(results);
417 Dmsg1(29, "dvd_write_part: command output=%s\n", results);
418 POOL_MEM archive_name(PM_FNAME);
419 get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
420 unlink(archive_name.c_str());
421 free_pool_memory(results);
426 /* Open the next part file.
428 * - Increment part number
429 * - Reopen the device
431 int open_next_part(DEVICE *dev) {
434 Dmsg3(29, "open_next_part %s %s %d\n", dev->dev_name, dev->VolCatInfo.VolCatName, dev->openmode);
435 /* When appending, do not open a new part if the current is empty */
436 if (dev->can_append() && (dev->part == dev->num_parts) &&
437 (dev->part_size == 0)) {
438 Dmsg0(29, "open_next_part exited immediately (dev->part_size == 0).\n");
449 dev->state &= ~ST_OPENED;
451 if (dev->is_dvd() && (dev->part == dev->num_parts) && dev->can_append()) {
452 if (dvd_write_part(dev) < 0) {
457 dev->part_start += dev->part_size;
460 if ((dev->num_parts < dev->part) && dev->can_append()) {
461 dev->num_parts = dev->part;
463 /* Check that the next part file does not exists.
464 * If it does, move it away... */
465 POOL_MEM archive_name(PM_FNAME);
466 POOL_MEM archive_bkp_name(PM_FNAME);
469 get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
471 /* Check if the next part exists. */
472 if ((stat(archive_name.c_str(), &buf) == 0) || (errno != ENOENT)) {
473 Dmsg1(29, "open_next_part %s is in the way, moving it away...\n", archive_name.c_str());
474 pm_strcpy(archive_bkp_name, archive_name.c_str());
475 pm_strcat(archive_bkp_name, ".bak");
476 unlink(archive_bkp_name.c_str());
478 /* First try to rename it */
479 if (rename(archive_name.c_str(), archive_bkp_name.c_str()) < 0) {
481 Dmsg3(29, "open_next_part can't rename %s to %s, ERR=%s\n",
482 archive_name.c_str(), archive_bkp_name.c_str(), be.strerror());
483 /* Then try to unlink it */
484 if (unlink(archive_name.c_str()) < 0) {
486 dev->dev_errno = errno;
487 Mmsg2(&dev->errmsg, _("open_next_part can't unlink existing part %s, ERR=%s\n"),
488 archive_name.c_str(), be.strerror());
489 Emsg0(M_FATAL, 0, dev->errmsg);
496 if (open_dev(dev, dev->VolCatInfo.VolCatName, dev->openmode) < 0) {
503 /* Open the first part file.
505 * - Reopen the device
507 int open_first_part(DEVICE *dev)
509 Dmsg3(29, "open_first_part %s %s %d\n", dev->dev_name, dev->VolCatInfo.VolCatName, dev->openmode);
514 dev->state &= ~ST_OPENED;
519 Dmsg2(50, "Call open_dev(dev, vol=%s, mode=%d",
520 dev->VolCatInfo.VolCatName, dev->openmode);
521 if (open_dev(dev, dev->VolCatInfo.VolCatName, dev->openmode) < 0) {
522 Dmsg0(50, "open_dev() failed\n");
525 Dmsg1(50, "Leave open_first_part state=%s\n", dev->is_open()?"open":"not open");
530 /* Protected version of lseek, which opens the right part if necessary */
531 off_t lseek_dev(DEVICE *dev, off_t offset, int whence)
535 if (dev->num_parts == 0) { /* If there is only one part, simply call lseek. */
536 return lseek(dev->fd, offset, whence);
541 Dmsg1(100, "lseek_dev SEEK_SET called %d\n", offset);
542 if ((uint64_t)offset >= dev->part_start) {
543 if ((uint64_t)(offset - dev->part_start) < dev->part_size) {
544 /* We are staying in the current part, just seek */
545 if ((pos = lseek(dev->fd, (off_t)(offset-dev->part_start), SEEK_SET)) < 0) {
548 return pos + dev->part_start;
551 /* Load next part, and start again */
552 if (open_next_part(dev) < 0) {
553 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
556 return lseek_dev(dev, offset, SEEK_SET);
559 /* pos < dev->part_start :
560 * We need to access a previous part,
561 * so just load the first one, and seek again
562 * until the right one is loaded */
563 if (open_first_part(dev) < 0) {
564 Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
567 return lseek_dev(dev, offset, SEEK_SET);
571 Dmsg1(100, "lseek_dev SEEK_CUR called %d\n", offset);
572 if ((pos = lseek(dev->fd, (off_t)0, SEEK_CUR)) < 0) {
575 pos += dev->part_start;
579 else { /* Not used in Bacula, but should work */
580 return lseek_dev(dev, pos, SEEK_SET);
584 Dmsg1(100, "lseek_dev SEEK_END called %d\n", offset);
585 if (offset > 0) { /* Not used by bacula */
586 Dmsg1(100, "lseek_dev SEEK_END called with an invalid offset %d\n", offset);
591 if (dev->part == dev->num_parts) { /* The right part is already loaded */
592 if ((pos = lseek(dev->fd, (off_t)0, SEEK_END)) < 0) {
595 return pos + dev->part_start;
598 /* Load the first part, then load the next until we reach the last one.
599 * This is the only way to be sure we compute the right file address. */
600 /* Save previous openmode, and open all but last part read-only (useful for DVDs) */
601 openmode = dev->openmode;
602 dev->openmode = OPEN_READ_ONLY;
604 /* Works because num_parts > 0. */
605 if (open_first_part(dev) < 0) {
606 Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
609 while (dev->part < (dev->num_parts-1)) {
610 if (open_next_part(dev) < 0) {
611 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
615 dev->openmode = openmode;
616 if (open_next_part(dev) < 0) {
617 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
620 return lseek_dev(dev, 0, SEEK_END);
629 bool dvd_close_job(DCR *dcr)
631 DEVICE *dev = dcr->dev;
635 /* If the device is a dvd and WritePartAfterJob
636 * is set to yes, open the next part, so, in case of a device
637 * that requires mount, it will be written to the device.
639 if (dev->is_dvd() && jcr->write_part_after_job && (dev->part_size > 0)) {
640 Dmsg0(100, "Writing last part because write_part_after_job is set.\n");
641 if (dev->part < dev->num_parts) {
642 Jmsg3(jcr, M_FATAL, 0, _("Error while writing, current part number is less than the total number of parts (%d/%d, device=%s)\n"),
643 dev->part, dev->num_parts, dev->print_name());
644 dev->dev_errno = EIO;
648 if (ok && (open_next_part(dev) < 0)) {
649 Jmsg2(jcr, M_FATAL, 0, _("Unable to open device next part %s: ERR=%s\n"),
650 dev->print_name(), strerror_dev(dev));
651 dev->dev_errno = EIO;
655 dev->VolCatInfo.VolCatParts = dev->num_parts;
662 * Edit codes into (Un)MountCommand, Write(First)PartCommand
664 * %a = archive device name
666 * %v = last part name
668 * omsg = edited output message
669 * imsg = input string containing edit codes (%x)
672 static char *edit_device_codes_dev(DEVICE* dev, char *omsg, const char *imsg)
678 POOL_MEM archive_name(PM_FNAME);
679 get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
682 Dmsg1(800, "edit_device_codes: %s\n", imsg);
683 for (p=imsg; *p; p++) {
690 bsnprintf(add, sizeof(add), "%d", dev->part);
697 str = dev->device->mount_point;
700 str = archive_name.c_str();
714 Dmsg1(900, "add_str %s\n", str);
715 pm_strcat(&omsg, (char *)str);
716 Dmsg1(800, "omsg=%s\n", omsg);