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 */
44 if (dev->part < dev->num_parts) {
45 pm_strcpy(archive_name, dev->device->mount_point);
47 /* Use the working directory if spool directory is not defined */
48 if (dev->device->spool_directory) {
49 pm_strcpy(archive_name, dev->device->spool_directory);
51 pm_strcpy(archive_name, working_directory);
55 pm_strcpy(archive_name, dev->dev_name);
58 if (archive_name.c_str()[strlen(archive_name.c_str())-1] != '/') {
59 pm_strcat(archive_name, "/");
61 pm_strcat(archive_name, VolumeName);
62 /* if part != 0, append .# to the filename (where # is the part number) */
63 if (dev->is_dvd() && dev->part != 0) {
64 pm_strcat(archive_name, ".");
65 bsnprintf(partnumber, sizeof(partnumber), "%d", dev->part);
66 pm_strcat(archive_name, partnumber);
71 * If timeout, wait until the mount command returns 0.
72 * If !timeout, try to mount the device only once.
74 bool mount_dev(DEVICE* dev, int timeout)
76 if (dev->is_mounted()) {
77 Dmsg0(100, "mount_dev: Device already mounted\n");
79 } else if (dev_cap(dev, CAP_REQMOUNT)) {
80 return do_mount_dev(dev, 1, timeout);
86 * If timeout, wait until the unmount command returns 0.
87 * If !timeout, try to unmount the device only once.
89 bool unmount_dev(DEVICE *dev, int timeout)
91 if (dev->is_mounted()) {
92 return do_mount_dev(dev, 0, timeout);
94 Dmsg0(100, "mount_dev: Device already unmounted\n");
98 /* (Un)mount the device */
99 static bool do_mount_dev(DEVICE* dev, int mount, int dotimeout)
101 POOL_MEM ocmd(PM_FNAME);
103 results = get_pool_memory(PM_MESSAGE);
108 if (dev->is_mounted()) {
111 icmd = dev->device->mount_command;
113 if (!dev->is_mounted()) {
116 icmd = dev->device->unmount_command;
119 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
121 Dmsg2(29, "do_mount_dev: cmd=%s state=%d\n", ocmd.c_str(), dev->is_mounted());
124 /* Try at most 5 times to (un)mount the device. This should perhaps be configurable. */
130 /* If busy retry each second */
131 while ((status = run_program_full_output(ocmd.c_str(),
132 dev->max_open_wait/2, results)) != 0) {
134 Dmsg2(40, "Device %s cannot be (un)mounted. Retrying... ERR=%s\n", dev->dev_name, results);
135 /* Sometimes the device cannot be mounted because it is already mounted.
136 * Try to unmount it, then remount it */
138 Dmsg1(40, "Trying to unmount the device %s...\n", dev->dev_name);
139 do_mount_dev(dev, 0, 0);
144 Dmsg2(40, "Device %s cannot be mounted. ERR=%s\n", dev->print_name(), results);
145 Mmsg(dev->errmsg, "Device %s cannot be mounted. ERR=%s\n",
146 dev->print_name(), results);
147 free_pool_memory(results);
151 dev->set_mounted(mount); /* set/clear mounted flag */
154 free_pool_memory(results);
155 Dmsg1(29, "do_mount_dev: end_state=%d\n", dev->is_mounted());
159 /* Only for devices that require a mount.
160 * Try to find the Volume name of the loaded device, and open the
161 * first part of this volume.
163 * Returns 0 if read_dev_volume_label can now read the label,
164 * -1 if an error occured, and read_dvd_volume_label
165 * must abort with an IO_ERROR.
167 * To find the Volume name, it lists all the files on the DVD,
168 * and searches for a file which has a minimum size (500 bytes).
169 * If this file has a numeric extension, like part files, try to
170 * open the file which has no extension (e.g. the first part
173 * So, if the DVD does not contains a Bacula volume, a random file is opened,
174 * and no valid label could be read from this file.
176 * It is useful, so the operator can be told that a wrong volume is mounted, with
177 * the label name of the current volume. We can also check that the currently
178 * mounted disk is writable. (See also read_dev_volume_label_guess in label.c).
180 * Note that if the right volume is mounted, open_mounted_dev returns
181 * the same result as an usual dev->open().
183 int open_mounted_dev(DEVICE *dev)
185 Dmsg1(29, "open_mounted_dev: dev=%s\n", dev->dev_name);
186 POOL_MEM guessedname(PM_FNAME);
188 struct dirent *entry, *result;
193 if (!dev->is_dvd()) {
194 Dmsg1(100, "open_mounted_dev: device does not require mount, returning 0. dev=%s\n", dev->dev_name);
198 #ifndef HAVE_DIRENT_H
199 Dmsg0(29, "open_mounted_dev: readdir not available, cannot guess volume name\n");
203 update_free_space_dev(dev);
205 if (mount_dev(dev, 1) < 0) {
206 /* If the device cannot be mounted, check if it is writable */
207 if (dev->have_media()) {
208 Dmsg1(100, "open_mounted_dev: device cannot be mounted, but it seems to be writable, returning 0. dev=%s\n", dev->dev_name);
211 Dmsg1(100, "open_mounted_dev: device cannot be mounted, and is not writable, returning -1. dev=%s\n", dev->dev_name);
216 name_max = pathconf(".", _PC_NAME_MAX);
217 if (name_max < 1024) {
221 if (!(dp = opendir(dev->device->mount_point))) {
223 dev->dev_errno = errno;
224 Dmsg3(29, "open_mounted_dev: failed to open dir %s (dev=%s), ERR=%s\n", dev->device->mount_point, dev->dev_name, be.strerror());
228 entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 100);
230 if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
231 dev->dev_errno = ENOENT;
232 Dmsg2(29, "open_mounted_dev: failed to find suitable file in dir %s (dev=%s)\n", dev->device->mount_point, dev->dev_name);
237 ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry));
239 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
243 pm_strcpy(guessedname, dev->device->mount_point);
244 if (guessedname.c_str()[strlen(guessedname.c_str())-1] != '/') {
245 pm_strcat(guessedname, "/");
247 pm_strcat(guessedname, entry->d_name);
249 if (stat(guessedname.c_str(), &statp) < 0) {
251 Dmsg3(29, "open_mounted_dev: failed to stat %s (dev=%s), ERR=%s\n",
252 guessedname.c_str(), dev->dev_name, be.strerror());
256 if (!S_ISREG(statp.st_mode) || (statp.st_size < 500)) {
257 Dmsg2(100, "open_mounted_dev: %s is not a regular file, or less than 500 bytes (dev=%s)\n",
258 guessedname.c_str(), dev->dev_name);
262 /* Ok, we found a good file, remove the part extension if possible. */
263 for (index = strlen(guessedname.c_str())-1; index >= 0; index--) {
264 if ((guessedname.c_str()[index] == '/') ||
265 (guessedname.c_str()[index] < '0') ||
266 (guessedname.c_str()[index] > '9')) {
269 if (guessedname.c_str()[index] == '.') {
270 guessedname.c_str()[index] = '\0';
275 if ((stat(guessedname.c_str(), &statp) < 0) || (statp.st_size < 500)) {
276 /* The file with extension truncated does not exists or is too small, so use it with its extension. */
278 Dmsg3(100, "open_mounted_dev: failed to stat %s (dev=%s), using the file with its extension, ERR=%s\n",
279 guessedname.c_str(), dev->dev_name, be.strerror());
280 pm_strcpy(guessedname, dev->device->mount_point);
281 if (guessedname.c_str()[strlen(guessedname.c_str())-1] != '/') {
282 pm_strcat(guessedname, "/");
284 pm_strcat(guessedname, entry->d_name);
296 if ((dev->fd = open(guessedname.c_str(), O_RDONLY | O_BINARY)) < 0) {
298 dev->dev_errno = errno;
299 Dmsg3(29, "open_mounted_dev: failed to open %s (dev=%s), ERR=%s\n",
300 guessedname.c_str(), dev->dev_name, be.strerror());
301 if (open_first_part(dev) < 0) {
303 dev->dev_errno = errno;
304 Mmsg1(&dev->errmsg, _("Could not open_first_part, ERR=%s\n"), be.strerror());
305 Emsg0(M_FATAL, 0, dev->errmsg);
310 dev->part_size = statp.st_size;
315 Dmsg2(29, "open_mounted_dev: %s opened (dev=%s)\n", guessedname.c_str(), dev->dev_name);
321 /* Update the free space on the device */
322 void update_free_space_dev(DEVICE* dev)
324 POOL_MEM ocmd(PM_FNAME);
331 icmd = dev->device->free_space_command;
335 dev->free_space_errno = 0;
337 Dmsg2(29, "update_free_space_dev: free_space=%d, free_space_errno=%d (!icmd)\n", dev->free_space, dev->free_space_errno);
341 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
343 Dmsg1(29, "update_free_space_dev: cmd=%s\n", ocmd.c_str());
345 results = get_pool_memory(PM_MESSAGE);
347 /* Try at most 3 times to get the free space on the device. This should perhaps be configurable. */
351 if (run_program_full_output(ocmd.c_str(), dev->max_open_wait/2, results) == 0) {
352 Dmsg1(100, "Free space program run : %s\n", results);
353 free = str_to_int64(results);
355 dev->free_space = free;
356 dev->free_space_errno = 1;
358 Mmsg0(dev->errmsg, "");
363 dev->free_space_errno = -EPIPE;
364 Mmsg1(dev->errmsg, "Cannot run free space command (%s)\n", results);
367 Dmsg4(40, "Cannot get free space on device %s. free_space=%s, "
368 "free_space_errno=%d ERR=%s\n", dev->dev_name,
369 edit_uint64(dev->free_space, ed1), dev->free_space_errno,
375 dev->dev_errno = -dev->free_space_errno;
376 Dmsg4(40, "Cannot get free space on device %s. free_space=%s, "
377 "free_space_errno=%d ERR=%s\n",
378 dev->dev_name, edit_uint64(dev->free_space, ed1),
379 dev->free_space_errno, dev->errmsg);
383 free_pool_memory(results);
384 Dmsg3(29, "update_free_space_dev: free_space=%s, free_space_errno=%d have_media=%d\n",
385 edit_uint64(dev->free_space, ed1), dev->free_space_errno, dev->have_media());
389 static int dvd_write_part(DEVICE *dev)
391 Dmsg1(29, "dvd_write_part: device is %s\n", dev->dev_name);
393 if (unmount_dev(dev, 1) < 0) {
394 Dmsg0(29, "dvd_write_part: unable to unmount the device\n");
397 POOL_MEM ocmd(PM_FNAME);
399 results = get_pool_memory(PM_MESSAGE);
404 icmd = dev->device->write_part_command;
406 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
408 /* Wait at most the time a maximum size part is written in DVD 0.5x speed
409 * FIXME: Minimum speed should be in device configuration
411 timeout = dev->max_open_wait + (dev->max_part_size/(1350*1024/2));
413 Dmsg2(29, "dvd_write_part: cmd=%s timeout=%d\n", ocmd.c_str(), timeout);
415 status = run_program_full_output(ocmd.c_str(), timeout, results);
417 Mmsg1(dev->errmsg, "Error while writing current part to the DVD: %s", results);
418 dev->dev_errno = EIO;
419 free_pool_memory(results);
423 Dmsg1(29, "dvd_write_part: command output=%s\n", results);
424 POOL_MEM archive_name(PM_FNAME);
425 get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
426 unlink(archive_name.c_str());
427 free_pool_memory(results);
432 /* Open the next part file.
434 * - Increment part number
435 * - Reopen the device
437 int open_next_part(DEVICE *dev)
440 Dmsg3(29, "open_next_part %s %s %d\n", dev->dev_name, dev->VolCatInfo.VolCatName, dev->openmode);
441 /* When appending, do not open a new part if the current is empty */
442 if (dev->can_append() && (dev->part == dev->num_parts) &&
443 (dev->part_size == 0)) {
444 Dmsg0(29, "open_next_part exited immediately (dev->part_size == 0).\n");
455 if (dev->is_dvd() && (dev->part == dev->num_parts) && dev->can_append()) {
456 if (dvd_write_part(dev) < 0) {
461 dev->part_start += dev->part_size;
464 if ((dev->num_parts < dev->part) && dev->can_append()) {
465 dev->num_parts = dev->part;
467 /* Check that the next part file does not exists.
468 * If it does, move it away... */
469 POOL_MEM archive_name(PM_FNAME);
470 POOL_MEM archive_bkp_name(PM_FNAME);
473 get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
475 /* Check if the next part exists. */
476 if ((stat(archive_name.c_str(), &buf) == 0) || (errno != ENOENT)) {
477 Dmsg1(29, "open_next_part %s is in the way, moving it away...\n", archive_name.c_str());
478 pm_strcpy(archive_bkp_name, archive_name.c_str());
479 pm_strcat(archive_bkp_name, ".bak");
480 unlink(archive_bkp_name.c_str());
482 /* First try to rename it */
483 if (rename(archive_name.c_str(), archive_bkp_name.c_str()) < 0) {
485 Dmsg3(29, "open_next_part can't rename %s to %s, ERR=%s\n",
486 archive_name.c_str(), archive_bkp_name.c_str(), be.strerror());
487 /* Then try to unlink it */
488 if (unlink(archive_name.c_str()) < 0) {
490 dev->dev_errno = errno;
491 Mmsg2(&dev->errmsg, _("open_next_part can't unlink existing part %s, ERR=%s\n"),
492 archive_name.c_str(), be.strerror());
493 Emsg0(M_FATAL, 0, dev->errmsg);
500 Dmsg2(50, "Call dev->open(vol=%s, mode=%d", dev->VolCatInfo.VolCatName,
502 if (dev->open(dev->VolCatInfo.VolCatName, dev->openmode) < 0) {
508 /* Open the first part file.
510 * - Reopen the device
512 int open_first_part(DEVICE *dev)
514 Dmsg3(29, "open_first_part %s %s %d\n", dev->dev_name, dev->VolCatInfo.VolCatName, dev->openmode);
524 Dmsg2(50, "Call dev->open(vol=%s, mode=%d", dev->VolCatInfo.VolCatName,
526 if (dev->open(dev->VolCatInfo.VolCatName, dev->openmode) < 0) {
527 Dmsg0(50, "open dev() failed\n");
530 Dmsg1(50, "Leave open_first_part state=%s\n", dev->is_open()?"open":"not open");
535 /* Protected version of lseek, which opens the right part if necessary */
536 off_t lseek_dev(DEVICE *dev, off_t offset, int whence)
540 if (dev->num_parts == 0) { /* If there is only one part, simply call lseek. */
541 return lseek(dev->fd, offset, whence);
546 Dmsg1(100, "lseek_dev SEEK_SET called %d\n", offset);
547 if ((uint64_t)offset >= dev->part_start) {
548 if ((uint64_t)(offset - dev->part_start) < dev->part_size) {
549 /* We are staying in the current part, just seek */
550 if ((pos = lseek(dev->fd, (off_t)(offset-dev->part_start), SEEK_SET)) < 0) {
553 return pos + dev->part_start;
556 /* Load next part, and start again */
557 if (open_next_part(dev) < 0) {
558 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
561 return lseek_dev(dev, offset, SEEK_SET);
564 /* pos < dev->part_start :
565 * We need to access a previous part,
566 * so just load the first one, and seek again
567 * until the right one is loaded */
568 if (open_first_part(dev) < 0) {
569 Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
572 return lseek_dev(dev, offset, SEEK_SET);
576 Dmsg1(100, "lseek_dev SEEK_CUR called %d\n", offset);
577 if ((pos = lseek(dev->fd, (off_t)0, SEEK_CUR)) < 0) {
580 pos += dev->part_start;
584 else { /* Not used in Bacula, but should work */
585 return lseek_dev(dev, pos, SEEK_SET);
589 Dmsg1(100, "lseek_dev SEEK_END called %d\n", offset);
590 if (offset > 0) { /* Not used by bacula */
591 Dmsg1(100, "lseek_dev SEEK_END called with an invalid offset %d\n", offset);
596 if (dev->part == dev->num_parts) { /* The right part is already loaded */
597 if ((pos = lseek(dev->fd, (off_t)0, SEEK_END)) < 0) {
600 return pos + dev->part_start;
603 /* Load the first part, then load the next until we reach the last one.
604 * This is the only way to be sure we compute the right file address. */
605 /* Save previous openmode, and open all but last part read-only (useful for DVDs) */
606 openmode = dev->openmode;
607 dev->openmode = OPEN_READ_ONLY;
609 /* Works because num_parts > 0. */
610 if (open_first_part(dev) < 0) {
611 Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
614 while (dev->part < (dev->num_parts-1)) {
615 if (open_next_part(dev) < 0) {
616 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
620 dev->openmode = openmode;
621 if (open_next_part(dev) < 0) {
622 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
625 return lseek_dev(dev, 0, SEEK_END);
634 bool dvd_close_job(DCR *dcr)
636 DEVICE *dev = dcr->dev;
640 /* If the device is a dvd and WritePartAfterJob
641 * is set to yes, open the next part, so, in case of a device
642 * that requires mount, it will be written to the device.
644 if (dev->is_dvd() && jcr->write_part_after_job && (dev->part_size > 0)) {
645 Dmsg0(100, "Writing last part because write_part_after_job is set.\n");
646 if (dev->part < dev->num_parts) {
647 Jmsg3(jcr, M_FATAL, 0, _("Error while writing, current part number is less than the total number of parts (%d/%d, device=%s)\n"),
648 dev->part, dev->num_parts, dev->print_name());
649 dev->dev_errno = EIO;
653 if (ok && (open_next_part(dev) < 0)) {
654 Jmsg2(jcr, M_FATAL, 0, _("Unable to open device next part %s: ERR=%s\n"),
655 dev->print_name(), strerror_dev(dev));
656 dev->dev_errno = EIO;
660 dev->VolCatInfo.VolCatParts = dev->num_parts;
667 * Edit codes into (Un)MountCommand, Write(First)PartCommand
669 * %a = archive device name
671 * %v = last part name
673 * omsg = edited output message
674 * imsg = input string containing edit codes (%x)
677 static char *edit_device_codes_dev(DEVICE* dev, char *omsg, const char *imsg)
683 POOL_MEM archive_name(PM_FNAME);
684 get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
687 Dmsg1(800, "edit_device_codes: %s\n", imsg);
688 for (p=imsg; *p; p++) {
695 bsnprintf(add, sizeof(add), "%d", dev->part);
702 str = dev->device->mount_point;
705 str = archive_name.c_str();
719 Dmsg1(900, "add_str %s\n", str);
720 pm_strcat(&omsg, (char *)str);
721 Dmsg1(800, "omsg=%s\n", omsg);