-/* Mount the device.
- * If timeout, wait until the mount command returns 0.
- * If !timeout, try to mount the device only once.
- */
-bool mount_dvd(DEVICE* dev, int timeout)
-{
- Dmsg0(90, "Enter mount_dvd\n");
- if (dev->is_mounted()) {
- return true;
- } else if (dev->requires_mount()) {
- return do_mount_dvd(dev, 1, timeout);
- }
- return true;
-}
-
-/* Unmount the device
- * If timeout, wait until the unmount command returns 0.
- * If !timeout, try to unmount the device only once.
- */
-bool unmount_dvd(DEVICE *dev, int timeout)
-{
- if (!dev->is_dvd()) {
- return true;
- }
- Dmsg0(90, "Enter unmount_dvd\n");
- if (dev->is_mounted()) {
- return do_mount_dvd(dev, 0, timeout);
- }
- return true;
-}
-
-/* (Un)mount the device */
-static bool do_mount_dvd(DEVICE* dev, int mount, int dotimeout)
-{
- POOL_MEM ocmd(PM_FNAME);
- POOLMEM *results;
- char *icmd;
- int status, timeout;
-
- sm_check(__FILE__, __LINE__, false);
- if (mount) {
- if (dev->is_mounted()) {
- Dmsg0(200, "======= DVD mount=1\n");
- return true;
- }
- icmd = dev->device->mount_command;
- } else {
- if (!dev->is_mounted()) {
- Dmsg0(200, "======= DVD mount=0\n");
- return true;
- }
- icmd = dev->device->unmount_command;
- }
-
- dev->edit_mount_codes(ocmd, icmd);
-
- Dmsg2(200, "do_mount_dvd: cmd=%s mounted=%d\n", ocmd.c_str(), !!dev->is_mounted());
-
- if (dotimeout) {
- /* Try at most 1 time to (un)mount the device. This should perhaps be configurable. */
- timeout = 1;
- } else {
- timeout = 0;
- }
- results = get_memory(2000);
- results[0] = 0;
- /* If busy retry each second */
- while ((status = run_program_full_output(ocmd.c_str(),
- dev->max_open_wait/2, results)) != 0) {
- /* Doesn't work with internationalisation (This is not a problem) */
- if (mount && fnmatch("*is already mounted on*", results, 0) == 0) {
- break;
- }
- if (!mount && fnmatch("* not mounted*", results, 0) == 0) {
- break;
- }
- if (timeout-- > 0) {
- /* Sometimes the device cannot be mounted because it is already mounted.
- * Try to unmount it, then remount it */
- if (mount) {
- Dmsg1(400, "Trying to unmount the device %s...\n", dev->print_name());
- do_mount_dvd(dev, 0, 0);
- }
- bmicrosleep(1, 0);
- continue;
- }
- Dmsg3(40, "Device %s cannot be %smounted. ERR=%s\n", dev->print_name(),
- (mount ? "" : "un"), results);
- Mmsg(dev->errmsg, _("Device %s cannot be %smounted. ERR=%s\n"),
- dev->print_name(), (mount ? "" : "un"), results);
- /*
- * Now, just to be sure it is not mounted, try to read the
- * filesystem.
- */
- DIR* dp;
- struct dirent *entry, *result;
- int name_max;
- int count;
-
- name_max = pathconf(".", _PC_NAME_MAX);
- if (name_max < 1024) {
- name_max = 1024;
- }
-
- if (!(dp = opendir(dev->device->mount_point))) {
- berrno be;
- dev->dev_errno = errno;
- Dmsg3(29, "do_mount_dvd: failed to open dir %s (dev=%s), ERR=%s\n",
- dev->device->mount_point, dev->print_name(), be.strerror());
- goto get_out;
- }
-
- entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);
- count = 0;
- while (1) {
- if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
- dev->dev_errno = EIO;
- Dmsg2(129, "do_mount_dvd: failed to find suitable file in dir %s (dev=%s)\n",
- dev->device->mount_point, dev->print_name());
- break;
- }
- if (strcmp(result->d_name, ".") && strcmp(result->d_name, "..") &&
- strcmp(result->d_name, ".keep")) {
- count++; /* result->d_name != ., .. or .keep (Gentoo-specific) */
- break;
- }
- else {
- Dmsg2(129, "do_mount_dvd: ignoring %s in %s\n",
- result->d_name, dev->device->mount_point);
- }
- }
- free(entry);
- closedir(dp);
-
- Dmsg1(29, "do_mount_dvd: got %d files in the mount point (not counting ., .. and .keep)\n", count);
-
- if (count > 0) {
- /* If we got more than ., .. and .keep */
- /* there must be something mounted */
- if (mount) {
- break;
- } else {
- /* An unmount request. We failed to unmount - report an error */
- dev->set_mounted(true);
- free_pool_memory(results);
- Dmsg0(200, "============ DVD mount=1\n");
- return false;
- }
- }
-get_out:
- dev->set_mounted(false);
- sm_check(__FILE__, __LINE__, false);
- free_pool_memory(results);
- Dmsg0(200, "============ DVD mount=0\n");
- return false;
- }
-
- dev->set_mounted(mount); /* set/clear mounted flag */
- free_pool_memory(results);
- /* Do not check free space when unmounting */
- if (mount) {
- update_free_space_dev(dev);
- }
- Dmsg1(200, "============ DVD mount=%d\n", mount);
- return true;
-}
-