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);
34 * Write the current volume/part filename to archive_name.
36 void make_dvd_filename(DEVICE *dev, POOL_MEM &archive_name)
41 * If we try to open the last part, just open it from disk,
42 * otherwise, open it from the spooling directory.
44 Dmsg2(100, "DVD part=%d num_parts=%d\n", dev->part, dev->num_parts);
45 if (dev->part < dev->num_parts) {
46 Dmsg1(100, "Arch = mount point: %s\n", dev->device->mount_point);
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 if (archive_name.c_str()[strlen(archive_name.c_str())-1] != '/') {
58 pm_strcat(archive_name, "/");
61 pm_strcat(archive_name, dev->VolCatInfo.VolCatName);
62 /* if part != 0, append .# to the filename (where # is the part number) */
64 pm_strcat(archive_name, ".");
65 bsnprintf(partnumber, sizeof(partnumber), "%d", dev->part);
66 pm_strcat(archive_name, partnumber);
68 Dmsg1(100, "Exit make_dvd_filename: arch=%s\n", archive_name.c_str());
72 * If timeout, wait until the mount command returns 0.
73 * If !timeout, try to mount the device only once.
75 bool mount_dev(DEVICE* dev, int timeout)
77 Dmsg0(900, "Enter mount_dev\n");
78 if (dev->is_mounted()) {
80 } else if (dev->requires_mount()) {
81 return do_mount_dev(dev, 1, timeout);
87 * If timeout, wait until the unmount command returns 0.
88 * If !timeout, try to unmount the device only once.
90 bool unmount_dev(DEVICE *dev, int timeout)
92 Dmsg0(900, "Enter unmount_dev\n");
93 if (dev->is_mounted()) {
94 return do_mount_dev(dev, 0, timeout);
99 /* (Un)mount the device */
100 static bool do_mount_dev(DEVICE* dev, int mount, int dotimeout)
102 POOL_MEM ocmd(PM_FNAME);
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(200, "do_mount_dev: cmd=%s mounted=%d\n", ocmd.c_str(), !!dev->is_mounted());
124 /* Try at most 1 time to (un)mount the device. This should perhaps be configurable. */
129 results = get_pool_memory(PM_MESSAGE);
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(400, "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(400, "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 */
152 free_pool_memory(results);
155 Dmsg1(29, "Exit do_mount_dev: mounted=%d\n", !!dev->is_mounted());
159 /* Only for devices that require a mount -- currently DVDs only
161 * Try to find the Volume name of the loaded device.
163 * Returns true if read_dev_volume_label can now read the label,
164 * NOTE!!! at this point the device may not be
166 * Maybe it should open the first part. ***FIXME***
168 * false if an error occured, and read_dev_volume_label
169 * must abort with an IO_ERROR.
171 * To find the Volume name, it lists all the files on the DVD,
172 * and searches for a file which has a minimum size (500 bytes).
173 * If this file has a numeric extension, like part files, try to
174 * open the file which has no extension (e.g. the first part
177 * So, if the DVD does not contains a Bacula volume, a random file is opened,
178 * and no valid label could be read from this file.
180 * It is useful, so the operator can be told that a wrong volume is mounted, with
181 * the label name of the current volume. We can also check that the currently
182 * mounted disk is writable. (See also read_dev_volume_label_guess in label.c).
184 If we are writing, then there is no need to guess. We should just
185 check that the Volume does not already exist.
187 If we are reading, I don't see the reason to guess since we
188 know what Volume we want. The file either exists or does not
194 bool can_open_mounted_dev(DEVICE *dev)
196 Dmsg1(29, "Enter: dev=%s\n", dev->dev_name);
197 POOL_MEM guessedname(PM_FNAME);
199 struct dirent *entry, *result;
204 if (!dev->is_dvd()) {
205 Dmsg1(100, "device does not require mount, returning 0. dev=%s\n", dev->dev_name);
209 #ifndef HAVE_DIRENT_H
210 Dmsg0(29, "readdir not available, cannot guess volume name\n");
214 update_free_space_dev(dev);
216 if (mount_dev(dev, 1) < 0) {
217 /* If the device cannot be mounted, check if it is writable */
218 if (dev->have_media()) {
219 Dmsg1(100, "device cannot be mounted, but it seems to be writable, returning 0. dev=%s\n", dev->dev_name);
222 Dmsg1(100, "device cannot be mounted, and is not writable, returning -1. dev=%s\n", dev->dev_name);
227 name_max = pathconf(".", _PC_NAME_MAX);
228 if (name_max < 1024) {
232 if (!(dp = opendir(dev->device->mount_point))) {
234 dev->dev_errno = errno;
235 Dmsg3(29, "failed to open dir %s (dev=%s), ERR=%s\n", dev->device->mount_point, dev->dev_name, be.strerror());
239 entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 100);
241 if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
242 dev->dev_errno = ENOENT;
243 Dmsg2(29, "failed to find suitable file in dir %s (dev=%s)\n", dev->device->mount_point, dev->dev_name);
249 ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry));
251 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
255 pm_strcpy(guessedname, dev->device->mount_point);
256 if (guessedname.c_str()[strlen(guessedname.c_str())-1] != '/') {
257 pm_strcat(guessedname, "/");
259 pm_strcat(guessedname, entry->d_name);
261 if (stat(guessedname.c_str(), &statp) < 0) {
263 Dmsg3(29, "failed to stat %s (dev=%s), ERR=%s\n",
264 guessedname.c_str(), dev->dev_name, be.strerror());
268 if (!S_ISREG(statp.st_mode) || (statp.st_size < 500)) {
269 Dmsg2(100, "%s is not a regular file, or less than 500 bytes (dev=%s)\n",
270 guessedname.c_str(), dev->dev_name);
274 /* Ok, we found a good file, remove the part extension if possible. */
275 for (index = strlen(guessedname.c_str())-1; index >= 0; index--) {
276 if ((guessedname.c_str()[index] == '/') ||
277 (guessedname.c_str()[index] < '0') ||
278 (guessedname.c_str()[index] > '9')) {
281 if (guessedname.c_str()[index] == '.') {
282 guessedname.c_str()[index] = '\0';
287 if ((stat(guessedname.c_str(), &statp) < 0) || (statp.st_size < 500)) {
288 /* The file with extension truncated does not exists or is too small, so use it with its extension. */
290 Dmsg3(100, "failed to stat %s (dev=%s), using the file with its extension, ERR=%s\n",
291 guessedname.c_str(), dev->dev_name, be.strerror());
292 pm_strcpy(guessedname, dev->device->mount_point);
293 if (guessedname.c_str()[strlen(guessedname.c_str())-1] != '/') {
294 pm_strcat(guessedname, "/");
296 pm_strcat(guessedname, entry->d_name);
308 Dmsg1(100, "open(%s) read-only\n", guessedname.c_str());
309 if ((dev->fd = open(guessedname.c_str(), O_RDONLY | O_BINARY)) < 0) {
311 dev->dev_errno = errno;
312 Dmsg3(29, "failed to open %s (dev=%s), ERR=%s\n",
313 guessedname.c_str(), dev->dev_name, be.strerror());
314 Dmsg0(100, "Call open_first_part\n");
315 if (open_first_part(dev, OPEN_READ_ONLY) < 0) {
317 dev->dev_errno = errno;
318 Mmsg1(&dev->errmsg, _("Could not open_first_part, ERR=%s\n"), be.strerror());
319 Emsg0(M_FATAL, 0, dev->errmsg);
324 dev->part_size = statp.st_size;
328 Dmsg2(29, "Exit: %s opened (dev=%s)\n", guessedname.c_str(), dev->dev_name);
335 /* Update the free space on the device */
336 void update_free_space_dev(DEVICE* dev)
338 POOL_MEM ocmd(PM_FNAME);
345 icmd = dev->device->free_space_command;
349 dev->free_space_errno = 0;
351 Dmsg2(29, "update_free_space_dev: free_space=%d, free_space_errno=%d (!icmd)\n", dev->free_space, dev->free_space_errno);
355 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
357 Dmsg1(29, "update_free_space_dev: cmd=%s\n", ocmd.c_str());
359 results = get_pool_memory(PM_MESSAGE);
361 /* Try at most 3 times to get the free space on the device. This should perhaps be configurable. */
365 if (run_program_full_output(ocmd.c_str(), dev->max_open_wait/2, results) == 0) {
366 Dmsg1(100, "Free space program run : %s\n", results);
367 free = str_to_int64(results);
369 dev->free_space = free;
370 dev->free_space_errno = 1;
372 Mmsg0(dev->errmsg, "");
377 dev->free_space_errno = -EPIPE;
378 Mmsg1(dev->errmsg, "Cannot run free space command (%s)\n", results);
381 Dmsg4(40, "Cannot get free space on device %s. free_space=%s, "
382 "free_space_errno=%d ERR=%s\n", dev->dev_name,
383 edit_uint64(dev->free_space, ed1), dev->free_space_errno,
389 dev->dev_errno = -dev->free_space_errno;
390 Dmsg4(40, "Cannot get free space on device %s. free_space=%s, "
391 "free_space_errno=%d ERR=%s\n",
392 dev->dev_name, edit_uint64(dev->free_space, ed1),
393 dev->free_space_errno, dev->errmsg);
397 free_pool_memory(results);
398 Dmsg3(29, "update_free_space_dev: free_space=%s, free_space_errno=%d have_media=%d\n",
399 edit_uint64(dev->free_space, ed1), dev->free_space_errno, dev->have_media());
403 static int dvd_write_part(DEVICE *dev)
405 Dmsg1(29, "dvd_write_part: device is %s\n", dev->dev_name);
407 if (unmount_dev(dev, 1) < 0) {
408 Dmsg0(29, "dvd_write_part: unable to unmount the device\n");
411 POOL_MEM ocmd(PM_FNAME);
413 results = get_pool_memory(PM_MESSAGE);
418 icmd = dev->device->write_part_command;
420 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
422 /* Wait at most the time a maximum size part is written in DVD 0.5x speed
423 * FIXME: Minimum speed should be in device configuration
425 timeout = dev->max_open_wait + (dev->max_part_size/(1350*1024/2));
427 Dmsg2(29, "dvd_write_part: cmd=%s timeout=%d\n", ocmd.c_str(), timeout);
429 status = run_program_full_output(ocmd.c_str(), timeout, results);
431 Mmsg1(dev->errmsg, "Error while writing current part to the DVD: %s",
433 Dmsg1(000, "%s", dev->errmsg);
434 dev->dev_errno = EIO;
435 free_pool_memory(results);
438 Dmsg1(10, "dvd_write_part: command output=%s\n", results);
439 POOL_MEM archive_name(PM_FNAME);
440 Dmsg1(100, "Call get_filename. Vol=%s\n", dev->VolCatInfo.VolCatName);
441 make_dvd_filename(dev, archive_name);
442 unlink(archive_name.c_str());
443 free_pool_memory(results);
448 /* Open the next part file.
450 * - Increment part number
451 * - Reopen the device
453 int open_next_part(DCR *dcr)
455 DEVICE *dev = dcr->dev;
457 Dmsg3(29, "Enter: open_next_part %s %s %d\n", dev->dev_name,
458 dev->VolCatInfo.VolCatName, dev->openmode);
459 /* When appending, do not open a new part if the current is empty */
460 if (dev->can_append() && (dev->part == dev->num_parts) &&
461 (dev->part_size == 0)) {
462 Dmsg0(29, "open_next_part exited immediately (dev->part_size == 0).\n");
474 * If we have a part open for write, then write it to
475 * DVD before opening the next part.
477 if (dev->is_dvd() && (dev->part == dev->num_parts) && dev->can_append()) {
478 if (dvd_write_part(dev) < 0) {
483 dev->part_start += dev->part_size;
486 if ((dev->num_parts < dev->part) && dev->can_append()) {
487 POOL_MEM archive_name(PM_FNAME);
491 * First check what is on DVD. If out part is there, we
492 * are in trouble, so bail out.
494 make_dvd_filename(dev, archive_name); /* makes dvd name */
495 if (stat(archive_name.c_str(), &buf) == 0) {
496 /* bad new bail out */
497 Mmsg1(&dev->errmsg, _("Next Volume part already exists on DVD. Cannot continue: %s\n"),
498 archive_name.c_str());
502 dev->num_parts = dev->part;
503 make_dvd_filename(dev, archive_name); /* makes spool name */
505 /* Check if the next part exists in spool directory . */
506 if ((stat(archive_name.c_str(), &buf) == 0) || (errno != ENOENT)) {
507 Dmsg1(29, "open_next_part %s is in the way, moving it away...\n", archive_name.c_str());
508 /* Then try to unlink it */
509 if (unlink(archive_name.c_str()) < 0) {
511 dev->dev_errno = errno;
512 Mmsg2(dev->errmsg, _("open_next_part can't unlink existing part %s, ERR=%s\n"),
513 archive_name.c_str(), be.strerror());
519 Dmsg2(50, "Call dev->open(vol=%s, mode=%d", dev->VolCatInfo.VolCatName,
522 if (dev->open(dcr, dev->openmode) < 0) {
525 dev->set_labeled(); /* all next parts are "labeled" */
529 /* Open the first part file.
531 * - Reopen the device
533 int open_first_part(DCR *dcr, int mode)
535 DEVICE *dev = dcr->dev;
536 Dmsg3(29, "Enter: open_first_part dev=%s Vol=%s mode=%d\n", dev->dev_name,
537 dev->VolCatInfo.VolCatName, dev->openmode);
547 Dmsg2(50, "Call dev->open(vol=%s, mode=%d)\n", dcr->VolCatInfo.VolCatName,
549 if (dev->open(dcr, mode) < 0) {
550 Dmsg0(50, "open dev() failed\n");
553 Dmsg1(50, "Leave open_first_part state=%s\n", dev->is_open()?"open":"not open");
558 /* Protected version of lseek, which opens the right part if necessary */
559 off_t lseek_dev(DEVICE *dev, off_t offset, int whence)
564 if (dev->num_parts == 0) { /* If there is only one part, simply call lseek. */
565 return lseek(dev->fd, offset, whence);
568 dcr = (DCR *)dev->attached_dcrs->first(); /* any dcr will do */
571 Dmsg1(100, "lseek_dev SEEK_SET called %d\n", offset);
572 if ((uint64_t)offset >= dev->part_start) {
573 if ((uint64_t)(offset - dev->part_start) < dev->part_size) {
574 /* We are staying in the current part, just seek */
575 if ((pos = lseek(dev->fd, (off_t)(offset-dev->part_start), SEEK_SET)) < 0) {
578 return pos + dev->part_start;
581 /* Load next part, and start again */
582 if (open_next_part(dcr) < 0) {
583 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
586 return lseek_dev(dev, offset, SEEK_SET);
589 /* pos < dev->part_start :
590 * We need to access a previous part,
591 * so just load the first one, and seek again
592 * until the right one is loaded */
593 if (open_first_part(dcr, dev->openmode) < 0) {
594 Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
597 return lseek_dev(dev, offset, SEEK_SET);
601 Dmsg1(100, "lseek_dev SEEK_CUR called %d\n", offset);
602 if ((pos = lseek(dev->fd, (off_t)0, SEEK_CUR)) < 0) {
605 pos += dev->part_start;
609 else { /* Not used in Bacula, but should work */
610 return lseek_dev(dev, pos, SEEK_SET);
614 Dmsg1(100, "lseek_dev SEEK_END called %d\n", offset);
615 if (offset > 0) { /* Not used by bacula */
616 Dmsg1(100, "lseek_dev SEEK_END called with an invalid offset %d\n", offset);
621 if (dev->part == dev->num_parts) { /* The right part is already loaded */
622 if ((pos = lseek(dev->fd, (off_t)0, SEEK_END)) < 0) {
625 return pos + dev->part_start;
628 /* Load the first part, then load the next until we reach the last one.
629 * This is the only way to be sure we compute the right file address. */
630 /* Save previous openmode, and open all but last part read-only (useful for DVDs) */
631 openmode = dev->openmode;
633 /* Works because num_parts > 0. */
634 if (open_first_part(dcr, OPEN_READ_ONLY) < 0) {
635 Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
638 while (dev->part < (dev->num_parts-1)) {
639 if (open_next_part(dcr) < 0) {
640 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
644 dev->openmode = openmode;
645 if (open_next_part(dcr) < 0) {
646 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
649 return lseek_dev(dev, 0, SEEK_END);
658 bool dvd_close_job(DCR *dcr)
660 DEVICE *dev = dcr->dev;
664 /* If the device is a dvd and WritePartAfterJob
665 * is set to yes, open the next part, so, in case of a device
666 * that requires mount, it will be written to the device.
668 if (dev->is_dvd() && jcr->write_part_after_job && (dev->part_size > 0)) {
669 Dmsg0(100, "Writing last part because write_part_after_job is set.\n");
670 if (dev->part < dev->num_parts) {
671 Jmsg3(jcr, M_FATAL, 0, _("Error while writing, current part number is less than the total number of parts (%d/%d, device=%s)\n"),
672 dev->part, dev->num_parts, dev->print_name());
673 dev->dev_errno = EIO;
677 if (ok && (open_next_part(dcr) < 0)) {
678 Jmsg2(jcr, M_FATAL, 0, _("Unable to open device next part %s: ERR=%s\n"),
679 dev->print_name(), strerror_dev(dev));
680 dev->dev_errno = EIO;
684 dev->VolCatInfo.VolCatParts = dev->num_parts;
691 * Edit codes into (Un)MountCommand, Write(First)PartCommand
693 * %a = archive device name
695 * %v = last part name
697 * omsg = edited output message
698 * imsg = input string containing edit codes (%x)
701 static char *edit_device_codes_dev(DEVICE* dev, char *omsg, const char *imsg)
707 POOL_MEM archive_name(PM_FNAME);
710 Dmsg1(800, "edit_device_codes: %s\n", imsg);
711 for (p=imsg; *p; p++) {
718 bsnprintf(add, sizeof(add), "%d", dev->part);
725 str = dev->device->mount_point;
728 make_dvd_filename(dev, archive_name);
729 str = archive_name.c_str();
743 Dmsg1(900, "add_str %s\n", str);
744 pm_strcat(&omsg, (char *)str);
745 Dmsg1(800, "omsg=%s\n", omsg);