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 /* Forward referenced functions */
29 static char *edit_device_codes_dev(DEVICE *dev, char *omsg, const char *imsg);
30 static bool do_mount_dev(DEVICE* dev, int mount, int dotimeout);
31 static int dvd_write_part(DEVICE *dev);
35 * Write the current volume/part filename to archive_name.
37 void get_filename(DEVICE *dev, char *VolumeName, POOL_MEM& archive_name)
42 /* If we try to open the last part, just open it from disk,
43 * otherwise, open it from the spooling directory.
45 Dmsg2(100, "part=%d num_parts=%d\n", dev->part, dev->num_parts);
46 if (dev->num_parts == 0 || dev->part < dev->num_parts) {
47 pm_strcpy(archive_name, dev->device->mount_point);
49 /* Use the working directory if spool directory is not defined */
50 if (dev->device->spool_directory) {
51 pm_strcpy(archive_name, dev->device->spool_directory);
53 pm_strcpy(archive_name, working_directory);
57 pm_strcpy(archive_name, dev->dev_name);
60 if (archive_name.c_str()[strlen(archive_name.c_str())-1] != '/') {
61 pm_strcat(archive_name, "/");
63 pm_strcat(archive_name, VolumeName);
64 /* if part != 0, append .# to the filename (where # is the part number) */
65 if (dev->is_dvd() && dev->part != 0) {
66 pm_strcat(archive_name, ".");
67 bsnprintf(partnumber, sizeof(partnumber), "%d", dev->part);
68 pm_strcat(archive_name, partnumber);
73 * If timeout, wait until the mount command returns 0.
74 * If !timeout, try to mount the device only once.
76 bool mount_dev(DEVICE* dev, int timeout)
78 Dmsg0(900, "Enter mount_dev\n");
79 if (dev->is_mounted()) {
81 } else if (dev->requires_mount()) {
82 return do_mount_dev(dev, 1, timeout);
88 * If timeout, wait until the unmount command returns 0.
89 * If !timeout, try to unmount the device only once.
91 bool unmount_dev(DEVICE *dev, int timeout)
93 Dmsg0(900, "Enter unmount_dev\n");
94 if (dev->is_mounted()) {
95 return do_mount_dev(dev, 0, timeout);
100 /* (Un)mount the device */
101 static bool do_mount_dev(DEVICE* dev, int mount, int dotimeout)
103 POOL_MEM ocmd(PM_FNAME);
109 if (dev->is_mounted()) {
112 icmd = dev->device->mount_command;
114 if (!dev->is_mounted()) {
117 icmd = dev->device->unmount_command;
120 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
122 Dmsg2(200, "do_mount_dev: cmd=%s mounted=%d\n", ocmd.c_str(), dev->is_mounted());
125 /* Try at most 1 time to (un)mount the device. This should perhaps be configurable. */
130 results = get_pool_memory(PM_MESSAGE);
131 /* If busy retry each second */
132 while ((status = run_program_full_output(ocmd.c_str(),
133 dev->max_open_wait/2, results)) != 0) {
135 Dmsg2(400, "Device %s cannot be (un)mounted. Retrying... ERR=%s\n", dev->dev_name, results);
136 /* Sometimes the device cannot be mounted because it is already mounted.
137 * Try to unmount it, then remount it */
139 Dmsg1(400, "Trying to unmount the device %s...\n", dev->dev_name);
140 do_mount_dev(dev, 0, 0);
145 Dmsg2(40, "Device %s cannot be mounted. ERR=%s\n", dev->print_name(), results);
146 Mmsg(dev->errmsg, "Device %s cannot be mounted. ERR=%s\n",
147 dev->print_name(), results);
148 free_pool_memory(results);
152 dev->set_mounted(mount); /* set/clear mounted flag */
153 free_pool_memory(results);
156 Dmsg1(29, "Exit do_mount_dev: mounted=%d\n", dev->is_mounted());
160 /* Only for devices that require a mount -- currently DVDs only
162 * Try to find the Volume name of the loaded device.
164 * Returns true if read_dev_volume_label can now read the label,
165 * NOTE!!! at this point the device may not be
167 * Maybe it should open the first part. ***FIXME***
169 * false if an error occured, and read_dvd_volume_label
170 * must abort with an IO_ERROR.
172 * To find the Volume name, it lists all the files on the DVD,
173 * and searches for a file which has a minimum size (500 bytes).
174 * If this file has a numeric extension, like part files, try to
175 * open the file which has no extension (e.g. the first part
178 * So, if the DVD does not contains a Bacula volume, a random file is opened,
179 * and no valid label could be read from this file.
181 * It is useful, so the operator can be told that a wrong volume is mounted, with
182 * the label name of the current volume. We can also check that the currently
183 * mounted disk is writable. (See also read_dev_volume_label_guess in label.c).
186 bool can_open_mounted_dev(DEVICE *dev)
188 Dmsg1(29, "Enter: dev=%s\n", dev->dev_name);
189 POOL_MEM guessedname(PM_FNAME);
191 struct dirent *entry, *result;
196 if (!dev->is_dvd()) {
197 Dmsg1(100, "device does not require mount, returning 0. dev=%s\n", dev->dev_name);
201 #ifndef HAVE_DIRENT_H
202 Dmsg0(29, "readdir not available, cannot guess volume name\n");
206 update_free_space_dev(dev);
208 if (mount_dev(dev, 1) < 0) {
209 /* If the device cannot be mounted, check if it is writable */
210 if (dev->have_media()) {
211 Dmsg1(100, "device cannot be mounted, but it seems to be writable, returning 0. dev=%s\n", dev->dev_name);
214 Dmsg1(100, "device cannot be mounted, and is not writable, returning -1. dev=%s\n", dev->dev_name);
219 name_max = pathconf(".", _PC_NAME_MAX);
220 if (name_max < 1024) {
224 if (!(dp = opendir(dev->device->mount_point))) {
226 dev->dev_errno = errno;
227 Dmsg3(29, "failed to open dir %s (dev=%s), ERR=%s\n", dev->device->mount_point, dev->dev_name, be.strerror());
231 entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 100);
233 if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
234 dev->dev_errno = ENOENT;
235 Dmsg2(29, "failed to find suitable file in dir %s (dev=%s)\n", dev->device->mount_point, dev->dev_name);
241 ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry));
243 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
247 pm_strcpy(guessedname, dev->device->mount_point);
248 if (guessedname.c_str()[strlen(guessedname.c_str())-1] != '/') {
249 pm_strcat(guessedname, "/");
251 pm_strcat(guessedname, entry->d_name);
253 if (stat(guessedname.c_str(), &statp) < 0) {
255 Dmsg3(29, "failed to stat %s (dev=%s), ERR=%s\n",
256 guessedname.c_str(), dev->dev_name, be.strerror());
260 if (!S_ISREG(statp.st_mode) || (statp.st_size < 500)) {
261 Dmsg2(100, "%s is not a regular file, or less than 500 bytes (dev=%s)\n",
262 guessedname.c_str(), dev->dev_name);
266 /* Ok, we found a good file, remove the part extension if possible. */
267 for (index = strlen(guessedname.c_str())-1; index >= 0; index--) {
268 if ((guessedname.c_str()[index] == '/') ||
269 (guessedname.c_str()[index] < '0') ||
270 (guessedname.c_str()[index] > '9')) {
273 if (guessedname.c_str()[index] == '.') {
274 guessedname.c_str()[index] = '\0';
279 if ((stat(guessedname.c_str(), &statp) < 0) || (statp.st_size < 500)) {
280 /* The file with extension truncated does not exists or is too small, so use it with its extension. */
282 Dmsg3(100, "failed to stat %s (dev=%s), using the file with its extension, ERR=%s\n",
283 guessedname.c_str(), dev->dev_name, be.strerror());
284 pm_strcpy(guessedname, dev->device->mount_point);
285 if (guessedname.c_str()[strlen(guessedname.c_str())-1] != '/') {
286 pm_strcat(guessedname, "/");
288 pm_strcat(guessedname, entry->d_name);
300 Dmsg1(100, "open(%s) read-only\n", guessedname.c_str());
301 if ((dev->fd = open(guessedname.c_str(), O_RDONLY | O_BINARY)) < 0) {
303 dev->dev_errno = errno;
304 Dmsg3(29, "failed to open %s (dev=%s), ERR=%s\n",
305 guessedname.c_str(), dev->dev_name, be.strerror());
306 Dmsg0(100, "Call open_first_part\n");
307 if (open_first_part(dev, OPEN_READ_ONLY) < 0) {
309 dev->dev_errno = errno;
310 Mmsg1(&dev->errmsg, _("Could not open_first_part, ERR=%s\n"), be.strerror());
311 Emsg0(M_FATAL, 0, dev->errmsg);
316 dev->part_size = statp.st_size;
320 Dmsg2(29, "Exit: %s opened (dev=%s)\n", guessedname.c_str(), dev->dev_name);
326 /* Update the free space on the device */
327 void update_free_space_dev(DEVICE* dev)
329 POOL_MEM ocmd(PM_FNAME);
336 icmd = dev->device->free_space_command;
340 dev->free_space_errno = 0;
342 Dmsg2(29, "update_free_space_dev: free_space=%d, free_space_errno=%d (!icmd)\n", dev->free_space, dev->free_space_errno);
346 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
348 Dmsg1(29, "update_free_space_dev: cmd=%s\n", ocmd.c_str());
350 results = get_pool_memory(PM_MESSAGE);
352 /* Try at most 3 times to get the free space on the device. This should perhaps be configurable. */
356 if (run_program_full_output(ocmd.c_str(), dev->max_open_wait/2, results) == 0) {
357 Dmsg1(100, "Free space program run : %s\n", results);
358 free = str_to_int64(results);
360 dev->free_space = free;
361 dev->free_space_errno = 1;
363 Mmsg0(dev->errmsg, "");
368 dev->free_space_errno = -EPIPE;
369 Mmsg1(dev->errmsg, "Cannot run free space command (%s)\n", results);
372 Dmsg4(40, "Cannot get free space on device %s. free_space=%s, "
373 "free_space_errno=%d ERR=%s\n", dev->dev_name,
374 edit_uint64(dev->free_space, ed1), dev->free_space_errno,
380 dev->dev_errno = -dev->free_space_errno;
381 Dmsg4(40, "Cannot get free space on device %s. free_space=%s, "
382 "free_space_errno=%d ERR=%s\n",
383 dev->dev_name, edit_uint64(dev->free_space, ed1),
384 dev->free_space_errno, dev->errmsg);
388 free_pool_memory(results);
389 Dmsg3(29, "update_free_space_dev: free_space=%s, free_space_errno=%d have_media=%d\n",
390 edit_uint64(dev->free_space, ed1), dev->free_space_errno, dev->have_media());
394 static int dvd_write_part(DEVICE *dev)
396 Dmsg1(29, "dvd_write_part: device is %s\n", dev->dev_name);
398 if (unmount_dev(dev, 1) < 0) {
399 Dmsg0(29, "dvd_write_part: unable to unmount the device\n");
402 POOL_MEM ocmd(PM_FNAME);
404 results = get_pool_memory(PM_MESSAGE);
409 icmd = dev->device->write_part_command;
411 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
413 /* Wait at most the time a maximum size part is written in DVD 0.5x speed
414 * FIXME: Minimum speed should be in device configuration
416 timeout = dev->max_open_wait + (dev->max_part_size/(1350*1024/2));
418 Dmsg2(29, "dvd_write_part: cmd=%s timeout=%d\n", ocmd.c_str(), timeout);
420 status = run_program_full_output(ocmd.c_str(), timeout, results);
422 Mmsg1(dev->errmsg, "Error while writing current part to the DVD: %s", results);
423 dev->dev_errno = EIO;
424 free_pool_memory(results);
427 Dmsg1(29, "dvd_write_part: command output=%s\n", results);
428 POOL_MEM archive_name(PM_FNAME);
429 get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
430 unlink(archive_name.c_str());
431 free_pool_memory(results);
436 /* Open the next part file.
438 * - Increment part number
439 * - Reopen the device
441 int open_next_part(DEVICE *dev)
444 Dmsg3(29, "Enter: open_next_part %s %s %d\n", dev->dev_name,
445 dev->VolCatInfo.VolCatName, dev->openmode);
446 /* When appending, do not open a new part if the current is empty */
447 if (dev->can_append() && (dev->part == dev->num_parts) &&
448 (dev->part_size == 0)) {
449 Dmsg0(29, "open_next_part exited immediately (dev->part_size == 0).\n");
460 if (dev->is_dvd() && (dev->part == dev->num_parts) && dev->can_append()) {
461 if (dvd_write_part(dev) < 0) {
466 dev->part_start += dev->part_size;
469 if ((dev->num_parts < dev->part) && dev->can_append()) {
470 dev->num_parts = dev->part;
472 /* Check that the next part file does not exists.
473 * If it does, move it away... */
474 POOL_MEM archive_name(PM_FNAME);
475 POOL_MEM archive_bkp_name(PM_FNAME);
478 get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
480 /* Check if the next part exists. */
481 if ((stat(archive_name.c_str(), &buf) == 0) || (errno != ENOENT)) {
482 Dmsg1(29, "open_next_part %s is in the way, moving it away...\n", archive_name.c_str());
483 pm_strcpy(archive_bkp_name, archive_name.c_str());
484 pm_strcat(archive_bkp_name, ".bak");
485 unlink(archive_bkp_name.c_str());
487 /* First try to rename it */
488 if (rename(archive_name.c_str(), archive_bkp_name.c_str()) < 0) {
490 Dmsg3(29, "open_next_part can't rename %s to %s, ERR=%s\n",
491 archive_name.c_str(), archive_bkp_name.c_str(), be.strerror());
492 /* Then try to unlink it */
493 if (unlink(archive_name.c_str()) < 0) {
495 dev->dev_errno = errno;
496 Mmsg2(&dev->errmsg, _("open_next_part can't unlink existing part %s, ERR=%s\n"),
497 archive_name.c_str(), be.strerror());
498 Emsg0(M_FATAL, 0, dev->errmsg);
505 Dmsg2(50, "Call dev->open(vol=%s, mode=%d", dev->VolCatInfo.VolCatName,
507 if (dev->open(dev->VolCatInfo.VolCatName, dev->openmode) < 0) {
513 /* Open the first part file.
515 * - Reopen the device
517 int open_first_part(DEVICE *dev, int mode)
519 Dmsg3(29, "Enter: open_first_part dev=%s Vol=%s mode=%d\n", dev->dev_name,
520 dev->VolCatInfo.VolCatName, dev->openmode);
530 Dmsg2(50, "Call dev->open(vol=%s, mode=%d)\n", dev->VolCatInfo.VolCatName,
532 if (dev->open(dev->VolCatInfo.VolCatName, mode) < 0) {
533 Dmsg0(50, "open dev() failed\n");
536 Dmsg1(50, "Leave open_first_part state=%s\n", dev->is_open()?"open":"not open");
541 /* Protected version of lseek, which opens the right part if necessary */
542 off_t lseek_dev(DEVICE *dev, off_t offset, int whence)
546 if (dev->num_parts == 0) { /* If there is only one part, simply call lseek. */
547 return lseek(dev->fd, offset, whence);
552 Dmsg1(100, "lseek_dev SEEK_SET called %d\n", offset);
553 if ((uint64_t)offset >= dev->part_start) {
554 if ((uint64_t)(offset - dev->part_start) < dev->part_size) {
555 /* We are staying in the current part, just seek */
556 if ((pos = lseek(dev->fd, (off_t)(offset-dev->part_start), SEEK_SET)) < 0) {
559 return pos + dev->part_start;
562 /* Load next part, and start again */
563 if (open_next_part(dev) < 0) {
564 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
567 return lseek_dev(dev, offset, SEEK_SET);
570 /* pos < dev->part_start :
571 * We need to access a previous part,
572 * so just load the first one, and seek again
573 * until the right one is loaded */
574 if (open_first_part(dev, dev->openmode) < 0) {
575 Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
578 return lseek_dev(dev, offset, SEEK_SET);
582 Dmsg1(100, "lseek_dev SEEK_CUR called %d\n", offset);
583 if ((pos = lseek(dev->fd, (off_t)0, SEEK_CUR)) < 0) {
586 pos += dev->part_start;
590 else { /* Not used in Bacula, but should work */
591 return lseek_dev(dev, pos, SEEK_SET);
595 Dmsg1(100, "lseek_dev SEEK_END called %d\n", offset);
596 if (offset > 0) { /* Not used by bacula */
597 Dmsg1(100, "lseek_dev SEEK_END called with an invalid offset %d\n", offset);
602 if (dev->part == dev->num_parts) { /* The right part is already loaded */
603 if ((pos = lseek(dev->fd, (off_t)0, SEEK_END)) < 0) {
606 return pos + dev->part_start;
609 /* Load the first part, then load the next until we reach the last one.
610 * This is the only way to be sure we compute the right file address. */
611 /* Save previous openmode, and open all but last part read-only (useful for DVDs) */
612 openmode = dev->openmode;
614 /* Works because num_parts > 0. */
615 if (open_first_part(dev, OPEN_READ_ONLY) < 0) {
616 Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
619 while (dev->part < (dev->num_parts-1)) {
620 if (open_next_part(dev) < 0) {
621 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
625 dev->openmode = openmode;
626 if (open_next_part(dev) < 0) {
627 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
630 return lseek_dev(dev, 0, SEEK_END);
639 bool dvd_close_job(DCR *dcr)
641 DEVICE *dev = dcr->dev;
645 /* If the device is a dvd and WritePartAfterJob
646 * is set to yes, open the next part, so, in case of a device
647 * that requires mount, it will be written to the device.
649 if (dev->is_dvd() && jcr->write_part_after_job && (dev->part_size > 0)) {
650 Dmsg0(100, "Writing last part because write_part_after_job is set.\n");
651 if (dev->part < dev->num_parts) {
652 Jmsg3(jcr, M_FATAL, 0, _("Error while writing, current part number is less than the total number of parts (%d/%d, device=%s)\n"),
653 dev->part, dev->num_parts, dev->print_name());
654 dev->dev_errno = EIO;
658 if (ok && (open_next_part(dev) < 0)) {
659 Jmsg2(jcr, M_FATAL, 0, _("Unable to open device next part %s: ERR=%s\n"),
660 dev->print_name(), strerror_dev(dev));
661 dev->dev_errno = EIO;
665 dev->VolCatInfo.VolCatParts = dev->num_parts;
672 * Edit codes into (Un)MountCommand, Write(First)PartCommand
674 * %a = archive device name
676 * %v = last part name
678 * omsg = edited output message
679 * imsg = input string containing edit codes (%x)
682 static char *edit_device_codes_dev(DEVICE* dev, char *omsg, const char *imsg)
688 POOL_MEM archive_name(PM_FNAME);
689 get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
692 Dmsg1(800, "edit_device_codes: %s\n", imsg);
693 for (p=imsg; *p; p++) {
700 bsnprintf(add, sizeof(add), "%d", dev->part);
707 str = dev->device->mount_point;
710 str = archive_name.c_str();
724 Dmsg1(900, "add_str %s\n", str);
725 pm_strcat(&omsg, (char *)str);
726 Dmsg1(800, "omsg=%s\n", omsg);