-/* Mount the device.
- * If timeout, wait until the mount command returns 0.
- * If !timeout, try to mount the device only once.
- */
-bool mount_dev(DEVICE* dev, int timeout)
-{
- Dmsg0(900, "Enter mount_dev\n");
- if (dev->is_mounted()) {
- return true;
- } else if (dev->requires_mount()) {
- return do_mount_dev(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_dev(DEVICE *dev, int timeout)
-{
- Dmsg0(900, "Enter unmount_dev\n");
- if (dev->is_mounted()) {
- return do_mount_dev(dev, 0, timeout);
- }
- return true;
-}
-
-/* (Un)mount the device */
-static bool do_mount_dev(DEVICE* dev, int mount, int dotimeout)
-{
- POOL_MEM ocmd(PM_FNAME);
- POOLMEM *results;
- char *icmd;
- int status, timeout;
-
- if (mount) {
- if (dev->is_mounted()) {
- return true;
- }
- icmd = dev->device->mount_command;
- } else {
- if (!dev->is_mounted()) {
- return true;
- }
- icmd = dev->device->unmount_command;
- }
-
- edit_device_codes_dev(dev, ocmd.c_str(), icmd);
-
- Dmsg2(200, "do_mount_dev: 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) {
- if (fnmatch("*is already mounted on", 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_dev(dev, 0, 0);
- }
- bmicrosleep(1, 0);
- continue;
- }
- Dmsg2(40, "Device %s cannot be mounted. ERR=%s\n", dev->print_name(), results);
- Mmsg(dev->errmsg, "Device %s cannot be mounted. ERR=%s\n",
- dev->print_name(), 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 = 0;
-
- 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, "open_mounted_dev: failed to open dir %s (dev=%s), ERR=%s\n", dev->device->mount_point, dev->dev_name, be.strerror());
- goto get_out;
- }
-
- entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);
- while (1) {
- if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
- dev->dev_errno = ENOENT;
- Dmsg2(29, "open_mounted_dev: failed to find suitable file in dir %s (dev=%s)\n", dev->device->mount_point, dev->dev_name);
- break;
- }
- count++;
- }
- free(entry);
- closedir(dp);
- if (count > 2) {
- mount = 1; /* If we got more than . and .. */
- break; /* there must be something mounted */
- }
-get_out:
- free_pool_memory(results);
- return false;
- }
-
- dev->set_mounted(mount); /* set/clear mounted flag */
- free_pool_memory(results);
- return true;
-}
-