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 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 0. dev=%s\n", dev->dev_name);
213 /* read_dev_volume_label_guess must now check dev->free_space_errno to understand that the media is not writable. */
218 name_max = pathconf(".", _PC_NAME_MAX);
219 if (name_max < 1024) {
223 if (!(dp = opendir(dev->device->mount_point))) {
225 dev->dev_errno = errno;
226 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());
230 entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 100);
232 if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
233 dev->dev_errno = ENOENT;
234 Dmsg2(29, "open_guess_name_dev: failed to find suitable file in dir %s (dev=%s)\n", dev->device->mount_point, dev->dev_name);
239 ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry));
241 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
245 pm_strcpy(guessedname, dev->device->mount_point);
246 if (guessedname.c_str()[strlen(guessedname.c_str())-1] != '/') {
247 pm_strcat(guessedname, "/");
249 pm_strcat(guessedname, entry->d_name);
251 if (stat(guessedname.c_str(), &statp) < 0) {
253 Dmsg3(29, "open_guess_name_dev: failed to stat %s (dev=%s), ERR=%s\n",
254 guessedname.c_str(), dev->dev_name, be.strerror());
258 if (!S_ISREG(statp.st_mode) || (statp.st_size < 500)) {
259 Dmsg2(100, "open_guess_name_dev: %s is not a regular file, or less than 500 bytes (dev=%s)\n",
260 guessedname.c_str(), dev->dev_name);
264 /* Ok, we found a good file, remove the part extension if possible. */
265 for (index = strlen(guessedname.c_str())-1; index >= 0; index--) {
266 if ((guessedname.c_str()[index] == '/') ||
267 (guessedname.c_str()[index] < '0') ||
268 (guessedname.c_str()[index] > '9')) {
271 if (guessedname.c_str()[index] == '.') {
272 guessedname.c_str()[index] = '\0';
277 if ((stat(guessedname.c_str(), &statp) < 0) || (statp.st_size < 500)) {
278 /* The file with extension truncated does not exists or is too small, so use it with its extension. */
280 Dmsg3(100, "open_guess_name_dev: failed to stat %s (dev=%s), using the file with its extension, ERR=%s\n",
281 guessedname.c_str(), dev->dev_name, be.strerror());
282 pm_strcpy(guessedname, dev->device->mount_point);
283 if (guessedname.c_str()[strlen(guessedname.c_str())-1] != '/') {
284 pm_strcat(guessedname, "/");
286 pm_strcat(guessedname, entry->d_name);
298 if ((dev->fd = open(guessedname.c_str(), O_RDONLY | O_BINARY)) < 0) {
300 dev->dev_errno = errno;
301 Dmsg3(29, "open_guess_name_dev: failed to open %s (dev=%s), ERR=%s\n",
302 guessedname.c_str(), dev->dev_name, be.strerror());
303 if (open_first_part(dev) < 0) {
305 dev->dev_errno = errno;
306 Mmsg1(&dev->errmsg, _("Could not open_first_part, ERR=%s\n"), be.strerror());
307 Emsg0(M_FATAL, 0, dev->errmsg);
312 dev->part_size = statp.st_size;
314 dev->state |= ST_OPENED;
317 Dmsg2(29, "open_guess_name_dev: %s opened (dev=%s)\n", guessedname.c_str(), dev->dev_name);
323 /* Update the free space on the device */
324 void update_free_space_dev(DEVICE* dev)
326 POOL_MEM ocmd(PM_FNAME);
332 icmd = dev->device->free_space_command;
336 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. */
352 if (run_program_full_output(ocmd.c_str(), dev->max_open_wait/2, results) == 0) {
353 Dmsg1(100, "Free space program run : %s\n", results);
354 free = str_to_int64(results);
356 dev->free_space = free;
357 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 Dmsg2(29, "update_free_space_dev: free_space=%lld, free_space_errno=%d\n", dev->free_space, dev->free_space_errno);
388 static int write_part(DEVICE *dev)
390 Dmsg1(29, "write_part: device is %s\n", dev->dev_name);
392 if (unmount_dev(dev, 1) < 0) {
393 Dmsg0(29, "write_part: unable to unmount the device\n");
396 POOL_MEM ocmd(PM_FNAME);
398 results = get_pool_memory(PM_MESSAGE);
403 icmd = dev->device->write_part_command;
405 edit_device_codes_dev(dev, ocmd.c_str(), icmd);
407 /* Wait at most the time a maximum size part is written in DVD 0.5x speed
408 * FIXME: Minimum speed should be in device configuration
410 timeout = dev->max_open_wait + (dev->max_part_size/(1350*1024/2));
412 Dmsg2(29, "write_part: cmd=%s timeout=%d\n", ocmd.c_str(), timeout);
414 status = run_program_full_output(ocmd.c_str(), timeout, results);
416 Mmsg1(dev->errmsg, "Error while writing current part to the DVD: %s", results);
417 dev->dev_errno = EIO;
418 free_pool_memory(results);
422 Dmsg1(29, "write_part: command output=%s\n", results);
423 POOL_MEM archive_name(PM_FNAME);
424 get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
425 unlink(archive_name.c_str());
426 free_pool_memory(results);
431 /* Open the next part file.
433 * - Increment part number
434 * - Reopen the device
436 int open_next_part(DEVICE *dev) {
439 Dmsg3(29, "open_next_part %s %s %d\n", dev->dev_name, dev->VolCatInfo.VolCatName, dev->openmode);
440 /* When appending, do not open a new part if the current is empty */
441 if (dev->can_append() && (dev->part == dev->num_parts) &&
442 (dev->part_size == 0)) {
443 Dmsg0(29, "open_next_part exited immediately (dev->part_size == 0).\n");
454 dev->state &= ~ST_OPENED;
456 if (dev->is_dvd() && (dev->part == dev->num_parts) && dev->can_append()) {
457 if (write_part(dev) < 0) {
462 dev->part_start += dev->part_size;
465 if ((dev->num_parts < dev->part) && dev->can_append()) {
466 dev->num_parts = dev->part;
468 /* Check that the next part file does not exists.
469 * If it does, move it away... */
470 POOL_MEM archive_name(PM_FNAME);
471 POOL_MEM archive_bkp_name(PM_FNAME);
474 get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
476 /* Check if the next part exists. */
477 if ((stat(archive_name.c_str(), &buf) == 0) || (errno != ENOENT)) {
478 Dmsg1(29, "open_next_part %s is in the way, moving it away...\n", archive_name.c_str());
479 pm_strcpy(archive_bkp_name, archive_name.c_str());
480 pm_strcat(archive_bkp_name, ".bak");
481 unlink(archive_bkp_name.c_str());
483 /* First try to rename it */
484 if (rename(archive_name.c_str(), archive_bkp_name.c_str()) < 0) {
486 Dmsg3(29, "open_next_part can't rename %s to %s, ERR=%s\n",
487 archive_name.c_str(), archive_bkp_name.c_str(), be.strerror());
488 /* Then try to unlink it */
489 if (unlink(archive_name.c_str()) < 0) {
491 dev->dev_errno = errno;
492 Mmsg2(&dev->errmsg, _("open_next_part can't unlink existing part %s, ERR=%s\n"),
493 archive_name.c_str(), be.strerror());
494 Emsg0(M_FATAL, 0, dev->errmsg);
501 if (open_dev(dev, dev->VolCatInfo.VolCatName, dev->openmode) < 0) {
509 /* Open the first part file.
511 * - Reopen the device
513 int open_first_part(DEVICE *dev) {
516 Dmsg3(29, "open_first_part %s %s %d\n", dev->dev_name, dev->VolCatInfo.VolCatName, dev->openmode);
523 dev->state &= ~ST_OPENED;
528 if (open_dev(dev, dev->VolCatInfo.VolCatName, dev->openmode)) {
537 /* Protected version of lseek, which opens the right part if necessary */
538 off_t lseek_dev(DEVICE *dev, off_t offset, int whence)
542 if (dev->num_parts == 0) { /* If there is only one part, simply call lseek. */
543 return lseek(dev->fd, offset, whence);
548 Dmsg1(100, "lseek_dev SEEK_SET called %d\n", offset);
549 if ((uint64_t)offset >= dev->part_start) {
550 if ((uint64_t)(offset - dev->part_start) < dev->part_size) {
551 /* We are staying in the current part, just seek */
552 if ((pos = lseek(dev->fd, (off_t)(offset-dev->part_start), SEEK_SET)) < 0) {
555 return pos + dev->part_start;
558 /* Load next part, and start again */
559 if (open_next_part(dev) < 0) {
560 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
563 return lseek_dev(dev, offset, SEEK_SET);
566 /* pos < dev->part_start :
567 * We need to access a previous part,
568 * so just load the first one, and seek again
569 * until the right one is loaded */
570 if (open_first_part(dev) < 0) {
571 Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
574 return lseek_dev(dev, offset, SEEK_SET);
578 Dmsg1(100, "lseek_dev SEEK_CUR called %d\n", offset);
579 if ((pos = lseek(dev->fd, (off_t)0, SEEK_CUR)) < 0) {
582 pos += dev->part_start;
586 else { /* Not used in Bacula, but should work */
587 return lseek_dev(dev, pos, SEEK_SET);
591 Dmsg1(100, "lseek_dev SEEK_END called %d\n", offset);
592 if (offset > 0) { /* Not used by bacula */
593 Dmsg1(100, "lseek_dev SEEK_END called with an invalid offset %d\n", offset);
598 if (dev->part == dev->num_parts) { /* The right part is already loaded */
599 if ((pos = lseek(dev->fd, (off_t)0, SEEK_END)) < 0) {
602 return pos + dev->part_start;
605 /* Load the first part, then load the next until we reach the last one.
606 * This is the only way to be sure we compute the right file address. */
607 /* Save previous openmode, and open all but last part read-only (useful for DVDs) */
608 openmode = dev->openmode;
609 dev->openmode = OPEN_READ_ONLY;
611 /* Works because num_parts > 0. */
612 if (open_first_part(dev) < 0) {
613 Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
616 while (dev->part < (dev->num_parts-1)) {
617 if (open_next_part(dev) < 0) {
618 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
622 dev->openmode = openmode;
623 if (open_next_part(dev) < 0) {
624 Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
627 return lseek_dev(dev, 0, SEEK_END);
638 * Edit codes into (Un)MountCommand, Write(First)PartCommand
640 * %a = archive device name
642 * %v = last part name
644 * omsg = edited output message
645 * imsg = input string containing edit codes (%x)
648 static char *edit_device_codes_dev(DEVICE* dev, char *omsg, const char *imsg)
654 POOL_MEM archive_name(PM_FNAME);
655 get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
658 Dmsg1(800, "edit_device_codes: %s\n", imsg);
659 for (p=imsg; *p; p++) {
666 bsnprintf(add, sizeof(add), "%d", dev->part);
673 str = dev->device->mount_point;
676 str = archive_name.c_str();
690 Dmsg1(900, "add_str %s\n", str);
691 pm_strcat(&omsg, (char *)str);
692 Dmsg1(800, "omsg=%s\n", omsg);