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 as
15 published by the Free Software Foundation; either version 2 of
16 the License, or (at your option) any later version.
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 GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public
24 License along with this program; if not, write to the Free
25 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
33 int mount_dev(DEVICE *dev, int timeout);
34 int unmount_dev(DEVICE *dev, int timeout);
35 void update_free_space_dev(DEVICE *dev);
36 void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name);
38 /* Forward referenced functions */
39 static char *edit_device_codes_dev(DEVICE *dev, char *omsg, const char *imsg);
40 static int do_mount_dev(DEVICE* dev, int mount, int dotimeout);
41 static int dvd_write_part(DEVICE *dev);
45 * Write the current volume/part filename to archive_name.
47 void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name)
52 /* If we try to open the last part, just open it from disk,
53 * otherwise, open it from the spooling directory */
54 if (dev->part < dev->num_parts) {
55 pm_strcpy(archive_name, dev->device->mount_point);
57 /* Use the working directory if spool directory is not defined */
58 if (dev->device->spool_directory) {
59 pm_strcpy(archive_name, dev->device->spool_directory);
61 pm_strcpy(archive_name, working_directory);
65 pm_strcpy(archive_name, dev->dev_name);
68 if (archive_name.c_str()[strlen(archive_name.c_str())-1] != '/') {
69 pm_strcat(archive_name, "/");
71 pm_strcat(archive_name, VolName);
72 /* if part != 0, append .# to the filename (where # is the part number) */
73 if (dev->is_dvd() && dev->part != 0) {
74 pm_strcat(archive_name, ".");
75 bsnprintf(partnumber, sizeof(partnumber), "%d", dev->part);
76 pm_strcat(archive_name, partnumber);
81 * If timeout, wait until the mount command returns 0.
82 * If !timeout, try to mount the device only once.
84 int mount_dev(DEVICE* dev, int timeout)
86 if (dev->state & ST_MOUNTED) {
87 Dmsg0(100, "mount_dev: Device already mounted\n");
89 } else if (dev_cap(dev, CAP_REQMOUNT)) {
90 return do_mount_dev(dev, 1, timeout);
96 * If timeout, wait until the unmount command returns 0.
97 * If !timeout, try to unmount the device only once.
99 int unmount_dev(DEVICE *dev, int timeout)
101 if (dev->state & ST_MOUNTED) {
102 return do_mount_dev(dev, 0, timeout);
104 Dmsg0(100, "mount_dev: Device already unmounted\n");
108 /* (Un)mount the device */
109 static int do_mount_dev(DEVICE* dev, int mount, int dotimeout) {
110 POOL_MEM ocmd(PM_FNAME);
112 results = get_pool_memory(PM_MESSAGE);
117 icmd = dev->device->mount_command;
120 icmd = dev->device->unmount_command;
123 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
125 Dmsg2(29, "do_mount_dev: cmd=%s state=%d\n", ocmd.c_str(), dev->state & ST_MOUNTED);
128 /* Try at most 5 times to (un)mount the device. This should perhaps be configurable. */
134 /* If busy retry each second */
135 while ((status = run_program_full_output(ocmd.c_str(), dev->max_open_wait/2, results)) != 0) {
137 Dmsg2(40, "Device %s cannot be (un)mounted. Retrying... ERR=%s\n", dev->dev_name, results);
138 /* Sometimes the device cannot be mounted because it is already mounted.
139 * Try to unmount it, then remount it */
141 Dmsg1(40, "Trying to unmount the device %s...\n", dev->dev_name);
142 do_mount_dev(dev, 0, 0);
147 free_pool_memory(results);
148 Dmsg2(40, "Device %s cannot be mounted. ERR=%s\n", dev->dev_name, results);
153 dev->state |= ST_MOUNTED;
155 dev->state &= ~ST_MOUNTED;
157 free_pool_memory(results);
159 Dmsg1(29, "do_mount_dev: end_state=%d\n", dev->state & ST_MOUNTED);
163 /* Only for devices that require a mount.
164 * Try to find the volume name of the loaded device, and open the
165 * first part of this volume.
167 * Returns 0 if read_dev_volume_label can now read the label,
168 * -1 if an error occured, and read_dev_volume_label_guess must abort with an IO_ERROR.
170 * To guess the device name, it lists all the files on the DVD, and searches for a
171 * file which has a minimum size (500 bytes). If this file has a numeric extension,
172 * like part files, try to open the file which has no extension (e.g. the first
174 * So, if the DVD does not contains a Bacula volume, a random file is opened,
175 * and no valid label could be read from this file.
177 * It is useful, so the operator can be told that a wrong volume is mounted, with
178 * the label name of the current volume. We can also check that the currently
179 * mounted disk is writable. (See also read_dev_volume_label_guess in label.c).
181 * Note that if the right volume is mounted, open_guess_name_dev returns the same
182 * result as an usual open_dev.
184 int open_guess_name_dev(DEVICE *dev)
186 Dmsg1(29, "open_guess_name_dev: dev=%s\n", dev->dev_name);
187 POOL_MEM guessedname(PM_FNAME);
189 struct dirent *entry, *result;
194 if (!dev->is_dvd()) {
195 Dmsg1(100, "open_guess_name_dev: device does not require mount, returning 0. dev=%s\n", dev->dev_name);
199 #ifndef HAVE_DIRENT_H
200 Dmsg0(29, "open_guess_name_dev: readdir not available, cannot guess volume name\n");
204 update_free_space_dev(dev);
206 if (mount_dev(dev, 1) < 0) {
207 /* If the device cannot be mounted, check if it is writable */
208 if (dev->free_space_errno >= 0) {
209 Dmsg1(100, "open_guess_name_dev: device cannot be mounted, but it seems to be writable, returning 0. dev=%s\n", dev->dev_name);
212 Dmsg1(100, "open_guess_name_dev: device cannot be mounted, and is not writable, returning -1. dev=%s\n", dev->dev_name);
217 name_max = pathconf(".", _PC_NAME_MAX);
218 if (name_max < 1024) {
222 if (!(dp = opendir(dev->device->mount_point))) {
224 dev->dev_errno = errno;
225 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());
229 entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 100);
231 if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
232 dev->dev_errno = ENOENT;
233 Dmsg2(29, "open_guess_name_dev: failed to find suitable file in dir %s (dev=%s)\n", dev->device->mount_point, dev->dev_name);
238 ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry));
240 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
244 pm_strcpy(guessedname, dev->device->mount_point);
245 if (guessedname.c_str()[strlen(guessedname.c_str())-1] != '/') {
246 pm_strcat(guessedname, "/");
248 pm_strcat(guessedname, entry->d_name);
250 if (stat(guessedname.c_str(), &statp) < 0) {
252 Dmsg3(29, "open_guess_name_dev: failed to stat %s (dev=%s), ERR=%s\n",
253 guessedname.c_str(), dev->dev_name, be.strerror());
257 if (!S_ISREG(statp.st_mode) || (statp.st_size < 500)) {
258 Dmsg2(100, "open_guess_name_dev: %s is not a regular file, or less than 500 bytes (dev=%s)\n",
259 guessedname.c_str(), dev->dev_name);
263 /* Ok, we found a good file, remove the part extension if possible. */
264 for (index = strlen(guessedname.c_str())-1; index >= 0; index--) {
265 if ((guessedname.c_str()[index] == '/') ||
266 (guessedname.c_str()[index] < '0') ||
267 (guessedname.c_str()[index] > '9')) {
270 if (guessedname.c_str()[index] == '.') {
271 guessedname.c_str()[index] = '\0';
276 if ((stat(guessedname.c_str(), &statp) < 0) || (statp.st_size < 500)) {
277 /* The file with extension truncated does not exists or is too small, so use it with its extension. */
279 Dmsg3(100, "open_guess_name_dev: failed to stat %s (dev=%s), using the file with its extension, ERR=%s\n",
280 guessedname.c_str(), dev->dev_name, be.strerror());
281 pm_strcpy(guessedname, dev->device->mount_point);
282 if (guessedname.c_str()[strlen(guessedname.c_str())-1] != '/') {
283 pm_strcat(guessedname, "/");
285 pm_strcat(guessedname, entry->d_name);
297 if ((dev->fd = open(guessedname.c_str(), O_RDONLY | O_BINARY)) < 0) {
299 dev->dev_errno = errno;
300 Dmsg3(29, "open_guess_name_dev: failed to open %s (dev=%s), ERR=%s\n",
301 guessedname.c_str(), dev->dev_name, be.strerror());
302 if (open_first_part(dev) < 0) {
304 dev->dev_errno = errno;
305 Mmsg1(&dev->errmsg, _("Could not open_first_part, ERR=%s\n"), be.strerror());
306 Emsg0(M_FATAL, 0, dev->errmsg);
311 dev->part_size = statp.st_size;
313 dev->state |= ST_OPENED;
316 Dmsg2(29, "open_guess_name_dev: %s opened (dev=%s)\n", guessedname.c_str(), dev->dev_name);
322 /* Update the free space on the device */
323 void update_free_space_dev(DEVICE* dev)
325 POOL_MEM ocmd(PM_FNAME);
331 icmd = dev->device->free_space_command;
335 dev->free_space_errno = 0;
336 Dmsg2(29, "update_free_space_dev: free_space=%d, free_space_errno=%d (!icmd)\n", dev->free_space, dev->free_space_errno);
340 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
342 Dmsg1(29, "update_free_space_dev: cmd=%s\n", ocmd.c_str());
344 results = get_pool_memory(PM_MESSAGE);
346 /* 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;
357 Mmsg0(dev->errmsg, "");
362 dev->free_space_errno = -EPIPE;
363 Mmsg1(dev->errmsg, "Cannot run free space command (%s)\n", results);
366 Dmsg4(40, "Cannot get free space on device %s. free_space=%s, "
367 "free_space_errno=%d ERR=%s\n", dev->dev_name,
368 edit_uint64(dev->free_space, ed1), dev->free_space_errno,
374 dev->dev_errno = -dev->free_space_errno;
375 Dmsg4(40, "Cannot get free space on device %s. free_space=%s, "
376 "free_space_errno=%d ERR=%s\n",
377 dev->dev_name, edit_uint64(dev->free_space, ed1),
378 dev->free_space_errno, dev->errmsg);
382 free_pool_memory(results);
383 Dmsg2(29, "update_free_space_dev: free_space=%lld, free_space_errno=%d\n", dev->free_space, dev->free_space_errno);
387 static int dvd_write_part(DEVICE *dev)
389 Dmsg1(29, "dvd_write_part: device is %s\n", dev->dev_name);
391 if (unmount_dev(dev, 1) < 0) {
392 Dmsg0(29, "dvd_write_part: unable to unmount the device\n");
395 POOL_MEM ocmd(PM_FNAME);
397 results = get_pool_memory(PM_MESSAGE);
402 icmd = dev->device->write_part_command;
404 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
406 /* Wait at most the time a maximum size part is written in DVD 0.5x speed
407 * FIXME: Minimum speed should be in device configuration
409 timeout = dev->max_open_wait + (dev->max_part_size/(1350*1024/2));
411 Dmsg2(29, "dvd_write_part: cmd=%s timeout=%d\n", ocmd.c_str(), timeout);
413 status = run_program_full_output(ocmd.c_str(), timeout, results);
415 Mmsg1(dev->errmsg, "Error while writing current part to the DVD: %s", results);
416 dev->dev_errno = EIO;
417 free_pool_memory(results);
421 Dmsg1(29, "dvd_write_part: command output=%s\n", results);
422 POOL_MEM archive_name(PM_FNAME);
423 get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
424 unlink(archive_name.c_str());
425 free_pool_memory(results);
430 /* Open the next part file.
432 * - Increment part number
433 * - Reopen the device
435 int open_next_part(DEVICE *dev) {
438 Dmsg3(29, "open_next_part %s %s %d\n", dev->dev_name, dev->VolCatInfo.VolCatName, dev->openmode);
439 /* When appending, do not open a new part if the current is empty */
440 if (dev->can_append() && (dev->part == dev->num_parts) &&
441 (dev->part_size == 0)) {
442 Dmsg0(29, "open_next_part exited immediately (dev->part_size == 0).\n");
453 dev->state &= ~ST_OPENED;
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 if (open_dev(dev, dev->VolCatInfo.VolCatName, dev->openmode) < 0) {
508 /* Open the first part file.
510 * - Reopen the device
512 int open_first_part(DEVICE *dev) {
515 Dmsg3(29, "open_first_part %s %s %d\n", dev->dev_name, dev->VolCatInfo.VolCatName, dev->openmode);
522 dev->state &= ~ST_OPENED;
527 if (open_dev(dev, dev->VolCatInfo.VolCatName, dev->openmode)) {
536 /* Protected version of lseek, which opens the right part if necessary */
537 off_t lseek_dev(DEVICE *dev, off_t offset, int whence)
541 if (dev->num_parts == 0) { /* If there is only one part, simply call lseek. */
542 return lseek(dev->fd, offset, whence);
547 Dmsg1(100, "lseek_dev SEEK_SET called %d\n", offset);
548 if ((uint64_t)offset >= dev->part_start) {
549 if ((uint64_t)(offset - dev->part_start) < dev->part_size) {
550 /* We are staying in the current part, just seek */
551 if ((pos = lseek(dev->fd, (off_t)(offset-dev->part_start), SEEK_SET)) < 0) {
554 return pos + dev->part_start;
557 /* Load next part, and start again */
558 if (open_next_part(dev) < 0) {
559 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
562 return lseek_dev(dev, offset, SEEK_SET);
565 /* pos < dev->part_start :
566 * We need to access a previous part,
567 * so just load the first one, and seek again
568 * until the right one is loaded */
569 if (open_first_part(dev) < 0) {
570 Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
573 return lseek_dev(dev, offset, SEEK_SET);
577 Dmsg1(100, "lseek_dev SEEK_CUR called %d\n", offset);
578 if ((pos = lseek(dev->fd, (off_t)0, SEEK_CUR)) < 0) {
581 pos += dev->part_start;
585 else { /* Not used in Bacula, but should work */
586 return lseek_dev(dev, pos, SEEK_SET);
590 Dmsg1(100, "lseek_dev SEEK_END called %d\n", offset);
591 if (offset > 0) { /* Not used by bacula */
592 Dmsg1(100, "lseek_dev SEEK_END called with an invalid offset %d\n", offset);
597 if (dev->part == dev->num_parts) { /* The right part is already loaded */
598 if ((pos = lseek(dev->fd, (off_t)0, SEEK_END)) < 0) {
601 return pos + dev->part_start;
604 /* Load the first part, then load the next until we reach the last one.
605 * This is the only way to be sure we compute the right file address. */
606 /* Save previous openmode, and open all but last part read-only (useful for DVDs) */
607 openmode = dev->openmode;
608 dev->openmode = OPEN_READ_ONLY;
610 /* Works because num_parts > 0. */
611 if (open_first_part(dev) < 0) {
612 Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
615 while (dev->part < (dev->num_parts-1)) {
616 if (open_next_part(dev) < 0) {
617 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
621 dev->openmode = openmode;
622 if (open_next_part(dev) < 0) {
623 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
626 return lseek_dev(dev, 0, SEEK_END);
635 bool dvd_close_job(DCR *dcr)
637 DEVICE *dev = dcr->dev;
641 /* If the device is a dvd and WritePartAfterJob
642 * is set to yes, open the next part, so, in case of a device
643 * that requires mount, it will be written to the device.
645 if (dev->is_dvd() && jcr->write_part_after_job && (dev->part_size > 0)) {
646 Dmsg0(100, "Writing last part because write_part_after_job is set.\n");
647 if (dev->part < dev->num_parts) {
648 Jmsg3(jcr, M_FATAL, 0, _("Error while writing, current part number is less than the total number of parts (%d/%d, device=%s)\n"),
649 dev->part, dev->num_parts, dev->print_name());
650 dev->dev_errno = EIO;
654 if (ok && (open_next_part(dev) < 0)) {
655 Jmsg2(jcr, M_FATAL, 0, _("Unable to open device next part %s: ERR=%s\n"),
656 dev->print_name(), strerror_dev(dev));
657 dev->dev_errno = EIO;
661 dev->VolCatInfo.VolCatParts = dev->num_parts;
668 * Edit codes into (Un)MountCommand, Write(First)PartCommand
670 * %a = archive device name
672 * %v = last part name
674 * omsg = edited output message
675 * imsg = input string containing edit codes (%x)
678 static char *edit_device_codes_dev(DEVICE* dev, char *omsg, const char *imsg)
684 POOL_MEM archive_name(PM_FNAME);
685 get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
688 Dmsg1(800, "edit_device_codes: %s\n", imsg);
689 for (p=imsg; *p; p++) {
696 bsnprintf(add, sizeof(add), "%d", dev->part);
703 str = dev->device->mount_point;
706 str = archive_name.c_str();
720 Dmsg1(900, "add_str %s\n", str);
721 pm_strcat(&omsg, (char *)str);
722 Dmsg1(800, "omsg=%s\n", omsg);