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

« back to all changes in this revision

Viewing changes to mount/mount.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:
172
172
  { "nosub",    0, 0, MS_NOSUB  },      /* don't allow submounts */
173
173
#endif
174
174
#ifdef MS_SILENT
175
 
  { "quiet",    0, 0, MS_SILENT    },   /* be quiet  */
 
175
  { "silent",   0, 0, MS_SILENT    },   /* be quiet  */
176
176
  { "loud",     0, 1, MS_SILENT    },   /* print out messages. */
177
177
#endif
178
178
#ifdef MS_MANDLOCK
209
209
static int opt_nofail = 0;
210
210
 
211
211
static const char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_sizelimit,
212
 
        *opt_encryption, *opt_speed, *opt_comment, *opt_uhelper;
 
212
        *opt_encryption, *opt_speed, *opt_comment, *opt_uhelper, *opt_helper;
213
213
 
214
214
static int is_readonly(const char *node);
215
 
static int mounted (const char *spec0, const char *node0);
 
215
static int mounted (const char *spec0, const char *node0, struct mntentchn *fstab_mc);
216
216
static int check_special_mountprog(const char *spec, const char *node,
217
217
                const char *type, int flags, char *extra_opts, int *status);
218
218
 
229
229
  { "speed=", 0, &opt_speed },
230
230
  { "comment=", 1, &opt_comment },
231
231
  { "uhelper=", 0, &opt_uhelper },
 
232
  { "helper=", 0, &opt_helper },
232
233
  { NULL, 0, NULL }
233
234
};
234
235
 
430
431
                if (strncmp(begin, "context=", 8) == 0 ||
431
432
                    strncmp(begin, "fscontext=", 10) == 0 ||
432
433
                    strncmp(begin, "defcontext=", 11) == 0 ||
433
 
                    strncmp(begin, "rootcontext=", 12) == 0) {
 
434
                    strncmp(begin, "rootcontext=", 12) == 0 ||
 
435
                    strncmp(begin, "seclabel", 8) == 0) {
434
436
                        size_t sz;
435
437
 
436
438
                        if ((begin == opts || *(begin - 1) == ',') && *end == ',')
444
446
                        p = begin;
445
447
                        changed = 1;
446
448
                }
 
449
                begin = end = NULL;
447
450
        }
448
451
 
449
452
        if (changed && verbose)
758
761
                res = snprintf(mountprog, sizeof(mountprog), "%s/mount.%s",
759
762
                               path, type);
760
763
                path = strtok(NULL, ":");
761
 
                if (res >= sizeof(mountprog) || res < 0)
 
764
                if (res < 0 || (size_t) res >= sizeof(mountprog))
762
765
                        continue;
763
766
 
764
767
                res = stat(mountprog, &statbuf);
1162
1165
                        res = loopfile_used_with((char *) mnt->m.mnt_fsname,
1163
1166
                                        loopfile, offset);
1164
1167
 
1165
 
                else if ((p = strstr(mnt->m.mnt_opts, "loop="))) {
 
1168
                else if (mnt->m.mnt_opts &&
 
1169
                         (p = strstr(mnt->m.mnt_opts, "loop=")))
 
1170
                {
1166
1171
                        char *dev = xstrdup(p+5);
1167
1172
                        if ((p = strchr(dev, ',')))
1168
1173
                                *p = '\0';
1331
1336
#ifdef HAVE_LIBMOUNT_MOUNT
1332
1337
static void
1333
1338
verbose_mount_info(const char *spec, const char *node, const char *type,
1334
 
                  const char *opts, int flags)
 
1339
                  const char *opts)
1335
1340
{
1336
1341
        struct my_mntent mnt;
1337
1342
 
1532
1537
  struct stat statbuf;
1533
1538
 
1534
1539
  /* copies for freeing on exit */
1535
 
  const char *opts1, *spec1, *node1, *types1, *extra_opts1;
 
1540
  const char *opts1, *spec1, *node1, *types1;
1536
1541
 
1537
1542
  if (verbose > 2) {
1538
1543
          printf("mount: spec:  \"%s\"\n", spec0);
1547
1552
  opts = opts1 = xstrdup(opts0);
1548
1553
 
1549
1554
  parse_opts (opts, &flags, &extra_opts);
1550
 
  extra_opts1 = extra_opts;
1551
 
  mount_opts = extra_opts;
 
1555
  mount_opts = xstrdup(extra_opts);
1552
1556
 
1553
1557
  /* quietly succeed for fstab entries that don't get mounted automatically */
1554
1558
  if (mount_all && (flags & MS_NOAUTO))
1559
1563
  /* The "mount -f" checks for for existing record in /etc/mtab (with
1560
1564
   * regular non-fake mount this is usually done by kernel)
1561
1565
   */
1562
 
  if (!(flags & MS_REMOUNT) && fake && mounted (spec, node))
 
1566
  if (!(flags & MS_REMOUNT) && fake && mounted (spec, node, NULL))
1563
1567
      die(EX_USAGE, _("mount: according to mtab, "
1564
1568
                      "%s is already mounted on %s\n"),
1565
1569
                      spec, node);
1589
1593
      /*
1590
1594
       * Linux kernel does not accept any selinux context option on remount
1591
1595
       */
1592
 
      if (mount_opts)
 
1596
      if (mount_opts) {
 
1597
          char *tmp = mount_opts;
1593
1598
          mount_opts = remove_context_options(mount_opts);
 
1599
          my_free(tmp);
 
1600
      }
1594
1601
 
1595
1602
  } else if (types && strcmp(types, "tmpfs") == 0 && is_selinux_enabled() > 0 &&
1596
1603
           !has_context_option(mount_opts)) {
1668
1675
#ifdef HAVE_LIBMOUNT_MOUNT
1669
1676
      update_mtab_entry(flags);
1670
1677
      if (verbose)
1671
 
              verbose_mount_info(loop ? loopfile : spec, node, tp, mo, flags);
 
1678
              verbose_mount_info(loop ? loopfile : spec, node, tp, mo);
1672
1679
#else
1673
1680
      if (!(mounttype & MS_PROPAGATION))
1674
1681
              update_mtab_entry(loop ? loopfile : spec,
1762
1769
      unsigned long long size = 0;
1763
1770
 
1764
1771
      if (flags & MS_REMOUNT) {
1765
 
        error (_("mount: %s not mounted already, or bad option"), node);
 
1772
        error (_("mount: %s not mounted or bad option"), node);
1766
1773
      } else {
1767
1774
        error (_("mount: wrong fs type, bad option, bad superblock on %s,\n"
1768
1775
               "       missing codepage or helper program, or other error"),
1919
1926
  }
1920
1927
#endif
1921
1928
 
1922
 
  if (extra_opts1 != mount_opts)
1923
 
          my_free(mount_opts);
1924
 
  my_free(extra_opts1);
 
1929
  my_free(mount_opts);
 
1930
  my_free(extra_opts);
1925
1931
  my_free(spec1);
1926
1932
  my_free(node1);
1927
1933
  my_free(opts1);
2013
2019
        return try_mount_one (spec, node, types, opts, freq, pass, 0);
2014
2020
}
2015
2021
 
 
2022
#ifdef HAVE_LIBMOUNT_MOUNT
 
2023
static struct libmnt_table *minfo;      /* parsed mountinfo file */
 
2024
#endif
 
2025
 
2016
2026
/* Check if an fsname/dir pair was already in the old mtab.  */
2017
2027
static int
2018
 
mounted (const char *spec0, const char *node0) {
 
2028
mounted (const char *spec0, const char *node0, struct mntentchn *fstab_mc) {
2019
2029
        struct mntentchn *mc, *mc0;
2020
2030
        const char *spec, *node;
2021
2031
        int ret = 0;
2022
2032
 
 
2033
#ifdef HAVE_LIBMOUNT_MOUNT
 
2034
        /*
 
2035
         * Use libmount to check for already mounted bind mounts on systems
 
2036
         * without mtab.
 
2037
         */
 
2038
        if (fstab_mc && fstab_mc->m.mnt_opts &&
 
2039
            mtab_is_a_symlink() && strstr(fstab_mc->m.mnt_opts, "bind")) {
 
2040
 
 
2041
                struct libmnt_fs *fs = mnt_new_fs();
 
2042
                int rc = fs ? 0 : -1;
 
2043
 
 
2044
                if (!rc)
 
2045
                        rc = mnt_fs_set_fstype(fs, fstab_mc->m.mnt_type);
 
2046
                if (!rc)
 
2047
                        rc = mnt_fs_set_source(fs, fstab_mc->m.mnt_fsname);
 
2048
                if (!rc)
 
2049
                        rc = mnt_fs_set_target(fs, fstab_mc->m.mnt_dir);
 
2050
                if (!rc)
 
2051
                        rc =  mnt_fs_set_options(fs, fstab_mc->m.mnt_opts);
 
2052
                if (!rc && !minfo)
 
2053
                         minfo = mnt_new_table_from_file("/proc/self/mountinfo");
 
2054
                if (!rc && minfo)
 
2055
                        rc = mnt_table_is_fs_mounted(minfo, fs);
 
2056
 
 
2057
                mnt_free_fs(fs);
 
2058
                if (rc == 1)
 
2059
                        return 1;
 
2060
        }
 
2061
#endif
2023
2062
        /* Handle possible UUID= and LABEL= in spec */
2024
2063
        spec = spec_to_devname(spec0);
2025
2064
        if (!spec)
2027
2066
 
2028
2067
        node = canonicalize(node0);
2029
2068
 
 
2069
 
2030
2070
        mc0 = mtab_head();
2031
2071
        for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
2032
2072
                if (streq (spec, mc->m.mnt_fsname) &&
2047
2087
{
2048
2088
        struct stat st;
2049
2089
 
2050
 
        if (mounted(mc->m.mnt_fsname, mc->m.mnt_dir))
 
2090
        if (mounted(mc->m.mnt_fsname, mc->m.mnt_dir, mc))
2051
2091
                goto yes;
2052
2092
 
2053
2093
        /* extra care for loop devices */
2054
 
        if ((strstr(mc->m.mnt_opts, "loop=") ||
2055
 
             (stat(mc->m.mnt_fsname, &st) == 0 && S_ISREG(st.st_mode)))) {
 
2094
        if ((mc->m.mnt_opts && strstr(mc->m.mnt_opts, "loop=")) ||
 
2095
            (stat(mc->m.mnt_fsname, &st) == 0 && S_ISREG(st.st_mode))) {
2056
2096
 
2057
2097
                char *p = get_option_value(mc->m.mnt_opts, "offset=");
2058
2098
                uintmax_t offset = 0;
2310
2350
        else if (label)
2311
2351
                mc = getfs_by_label(label);
2312
2352
        else {
2313
 
                mc = getfs_by_spec(spec);
 
2353
                mc = getfs_by_dir(spec);
2314
2354
 
2315
2355
                if (!mc)
2316
 
                        mc = getfs_by_dir(spec);
 
2356
                        mc = getfs_by_spec(spec);
2317
2357
        }
2318
2358
        if (mc)
2319
2359
                return mc;