~ubuntu-branches/ubuntu/trusty/util-linux/trusty-proposed

« back to all changes in this revision

Viewing changes to mount/umount.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones
  • Date: 2011-11-03 15:38:23 UTC
  • mto: (4.5.5 sid) (1.6.4)
  • mto: This revision was merged to the branch mainline in revision 85.
  • Revision ID: package-import@ubuntu.com-20111103153823-10sx16jprzxlhkqf
ImportĀ upstreamĀ versionĀ 2.20.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
98
98
 * returns: 0: no exec was done, 1: exec was done, status has result
99
99
 */
100
100
static int
101
 
check_special_umountprog(const char *spec, const char *node,
 
101
check_special_umountprog(const char *node,
102
102
                         const char *type, int *status) {
103
103
        char umountprog[120];
104
104
        struct stat statbuf;
263
263
   on a non-fatal error.  We lock/unlock around each umount.  */
264
264
static int
265
265
umount_one (const char *spec, const char *node, const char *type,
266
 
            const char *opts, struct mntentchn *mc) {
 
266
            struct mntentchn *mc) {
267
267
        int umnt_err = 0;
268
268
        int isroot;
269
269
        int res = 0;
288
288
         * Call umount.TYPE for types that require a separate umount program.
289
289
         * All such special things must occur isolated in the types string.
290
290
         */
291
 
        if (check_special_umountprog(spec, node, type, &status))
 
291
        if (check_special_umountprog(node, type, &status))
292
292
                return status;
293
293
 
294
294
        block_signals(SIG_BLOCK);
455
455
        mc = mc0;
456
456
        while (res && mc) {
457
457
                res = umount_one(mc->m.mnt_fsname, mc->m.mnt_dir,
458
 
                                 mc->m.mnt_type, mc->m.mnt_opts, mc);
 
458
                                 mc->m.mnt_type, mc);
459
459
                mc = getmntdirbackward(file, mc);
460
460
        }
461
461
        mc = mc0;
462
462
        while (res && mc) {
463
463
                res = umount_one(mc->m.mnt_fsname, mc->m.mnt_dir,
464
 
                                 mc->m.mnt_type, mc->m.mnt_opts, mc);
 
464
                                 mc->m.mnt_type, mc);
465
465
                mc = getmntdevbackward(file, mc);
466
466
        }
467
467
        return res;
484
484
          if (matching_type (mc->m.mnt_type, types)
485
485
              && matching_opts (mc->m.mnt_opts, test_opts)) {
486
486
               errors |= umount_one (mc->m.mnt_fsname, mc->m.mnt_dir,
487
 
                                     mc->m.mnt_type, mc->m.mnt_opts, mc);
 
487
                                     mc->m.mnt_type, mc);
488
488
          }
489
489
     }
490
490
 
574
574
        return 0;
575
575
}
576
576
 
 
577
/*
 
578
 * umount helper call based on {u,p}helper= mount option
 
579
 */
 
580
static int check_helper_umountprog(const char *node,
 
581
                                   const char *opts, const char *name,
 
582
                                   int *status)
 
583
{
 
584
        char *helper;
 
585
 
 
586
        if (!external_allowed || !opts)
 
587
                return 0;
 
588
 
 
589
        helper = get_option_value(opts, name);
 
590
        if (helper)
 
591
                return check_special_umountprog(node, helper, status);
 
592
 
 
593
        return 0;
 
594
}
 
595
 
577
596
static int
578
597
umount_file (char *arg) {
579
598
        struct mntentchn *mc, *fs;
580
599
        const char *file, *options;
581
600
        int fstab_has_user, fstab_has_users, fstab_has_owner, fstab_has_group;
582
 
        int ok;
 
601
        int ok, status = 0;
583
602
        struct stat statbuf;
 
603
        char *loopdev = NULL;
584
604
 
585
605
        if (!*arg) {            /* "" would be expanded to `pwd` */
586
606
                die(2, _("Cannot unmount \"\"\n"));
589
609
 
590
610
        file = canonicalize(arg); /* mtab paths are canonicalized */
591
611
 
592
 
        /* if file is a regular file, check if it is associated
593
 
         * with some loop device
594
 
         */
595
 
        if (!stat(file, &statbuf) && S_ISREG(statbuf.st_mode)) {
596
 
                char *loopdev = NULL;
597
 
                switch (find_loopdev_by_backing_file(file, &loopdev)) {
598
 
                case 0:
599
 
                        if (verbose)
600
 
                                printf(_("%s is associated with %s, trying to unmount it\n"),
601
 
                                       arg, loopdev);
602
 
                        file = loopdev;
603
 
                        break;
604
 
                case 2:
605
 
                        if (verbose)
606
 
                                printf(_("%s is associated with more than one loop device: not unmounting\n"),
607
 
                                       arg);
608
 
                        break;
609
 
                }
610
 
        }
611
 
 
 
612
try_loopdev:
612
613
        if (verbose > 1)
613
614
                printf(_("Trying to unmount %s\n"), file);
614
615
 
640
641
        if (!mc && verbose)
641
642
                printf(_("Could not find %s in mtab\n"), file);
642
643
 
 
644
        /* not found in mtab - check if it is associated with some loop device
 
645
         * (only if it is a regular file)
 
646
         */
 
647
        if (!mc && !loopdev && !stat(file, &statbuf) && S_ISREG(statbuf.st_mode)) {
 
648
                switch (find_loopdev_by_backing_file(file, &loopdev)) {
 
649
                case 0:
 
650
                        if (verbose)
 
651
                                printf(_("%s is associated with %s\n"),
 
652
                                       arg, loopdev);
 
653
                        file = loopdev;
 
654
                        goto try_loopdev;
 
655
                        break;
 
656
                case 2:
 
657
                        if (verbose)
 
658
                                printf(_("%s is associated with more than one loop device: not unmounting\n"),
 
659
                                       arg);
 
660
                        break;
 
661
                }
 
662
        }
 
663
 
 
664
        if (mc) {
 
665
                /*
 
666
                 * helper - umount helper (e.g. pam_mount)
 
667
                 */
 
668
                 if (check_helper_umountprog(arg, mc->m.mnt_opts,
 
669
                                            "helper=", &status))
 
670
                        return status;
 
671
        }
 
672
 
643
673
        if (restricted) {
644
674
                char *mtab_user = NULL;
645
675
 
648
678
                            _("umount: %s is not mounted (according to mtab)"),
649
679
                            file);
650
680
                /*
651
 
                 * uhelper - unprivileged umount helper
652
 
                 * -- external umount (for example HAL mounts)
 
681
                 * uhelper - unprivileged umount helper (e.g. HAL/udisks mounts)
653
682
                 */
654
 
                if (external_allowed) {
655
 
                        char *uhelper = NULL;
656
 
 
657
 
                        if (mc->m.mnt_opts)
658
 
                                uhelper = get_option_value(mc->m.mnt_opts,
659
 
                                                           "uhelper=");
660
 
                        if (uhelper) {
661
 
                                int status = 0;
662
 
                                if (check_special_umountprog(arg, arg,
663
 
                                                        uhelper, &status))
664
 
                                        return status;
665
 
                        }
666
 
                }
 
683
                if (check_helper_umountprog(arg, mc->m.mnt_opts,
 
684
                                            "uhelper=", &status))
 
685
                        return status;
667
686
 
668
687
                /* The 2.4 kernel will generally refuse to mount the same
669
688
                   filesystem on the same mount point, but will accept NFS.
734
753
                        die (2, _("umount: only %s can unmount %s from %s"),
735
754
                             mtab_user ? mtab_user : "root",
736
755
                             fs->m.mnt_fsname, fs->m.mnt_dir);
 
756
 
737
757
        }
738
758
 
739
759
        if (mc)
740
760
                return umount_one_bw (file, mc);
741
761
        else
742
 
                return umount_one (arg, arg, arg, arg, NULL);
 
762
                return umount_one (arg, arg, arg, NULL);
743
763
}
744
764
 
745
765
int