~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, Roger Leigh, LaMont Jones, 김종규, Niels Thykier
  • Date: 2011-11-03 15:38:23 UTC
  • mfrom: (1.7.2)
  • mto: This revision was merged to the branch mainline in revision 85.
  • Revision ID: package-import@ubuntu.com-20111103153823-n2nt15ce74gyvnaa
Tags: 2.20.1-1
* New upstream

[Roger Leigh]

* Various merge fixes [with edits - lamont]
  - drop old unused patches
  - cleanup debian/rules
  - updated symbols files for lib{blkid,mount,uuid}1

[LaMont Jones]

* merge in 2.19.1-{3..5}
* deliver /etc/fstab.d

[김종규]

* add korean debconf pofile.  Closes: #632421, #632425

[Niels Thykier]

* Add build-arch and build-indep targets.  Closes: #648467

Show diffs side-by-side

added added

removed removed

Lines of Context:
181
181
  { "nosub",    0, 0, MS_NOSUB  },      /* don't allow submounts */
182
182
#endif
183
183
#ifdef MS_SILENT
184
 
  { "quiet",    0, 0, MS_SILENT    },   /* be quiet  */
 
184
  { "silent",   0, 0, MS_SILENT    },   /* be quiet  */
185
185
  { "loud",     0, 1, MS_SILENT    },   /* print out messages. */
186
186
#endif
187
187
#ifdef MS_MANDLOCK
218
218
static int opt_nofail = 0;
219
219
 
220
220
static const char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_sizelimit,
221
 
        *opt_encryption, *opt_speed, *opt_comment, *opt_uhelper;
 
221
        *opt_encryption, *opt_speed, *opt_comment, *opt_uhelper, *opt_helper;
222
222
static const char *opt_keybits, *opt_nohashpass;
223
223
 
224
224
static int is_readonly(const char *node);
225
 
static int mounted (const char *spec0, const char *node0);
 
225
static int mounted (const char *spec0, const char *node0, struct mntentchn *fstab_mc);
226
226
static int check_special_mountprog(const char *spec, const char *node,
227
227
                const char *type, int flags, char *extra_opts, int *status);
228
228
 
241
241
  { "speed=", 0, &opt_speed },
242
242
  { "comment=", 1, &opt_comment },
243
243
  { "uhelper=", 0, &opt_uhelper },
 
244
  { "helper=", 0, &opt_helper },
244
245
  { NULL, 0, NULL }
245
246
};
246
247
 
442
443
                if (strncmp(begin, "context=", 8) == 0 ||
443
444
                    strncmp(begin, "fscontext=", 10) == 0 ||
444
445
                    strncmp(begin, "defcontext=", 11) == 0 ||
445
 
                    strncmp(begin, "rootcontext=", 12) == 0) {
 
446
                    strncmp(begin, "rootcontext=", 12) == 0 ||
 
447
                    strncmp(begin, "seclabel", 8) == 0) {
446
448
                        size_t sz;
447
449
 
448
450
                        if ((begin == opts || *(begin - 1) == ',') && *end == ',')
456
458
                        p = begin;
457
459
                        changed = 1;
458
460
                }
 
461
                begin = end = NULL;
459
462
        }
460
463
 
461
464
        if (changed && verbose)
770
773
                res = snprintf(mountprog, sizeof(mountprog), "%s/mount.%s",
771
774
                               path, type);
772
775
                path = strtok(NULL, ":");
773
 
                if (res >= sizeof(mountprog) || res < 0)
 
776
                if (res < 0 || (size_t) res >= sizeof(mountprog))
774
777
                        continue;
775
778
 
776
779
                res = stat(mountprog, &statbuf);
1174
1177
                        res = loopfile_used_with((char *) mnt->m.mnt_fsname,
1175
1178
                                        loopfile, offset);
1176
1179
 
1177
 
                else if ((p = strstr(mnt->m.mnt_opts, "loop="))) {
 
1180
                else if (mnt->m.mnt_opts &&
 
1181
                         (p = strstr(mnt->m.mnt_opts, "loop=")))
 
1182
                {
1178
1183
                        char *dev = xstrdup(p+5);
1179
1184
                        if ((p = strchr(dev, ',')))
1180
1185
                                *p = '\0';
1346
1351
#ifdef HAVE_LIBMOUNT_MOUNT
1347
1352
static void
1348
1353
verbose_mount_info(const char *spec, const char *node, const char *type,
1349
 
                  const char *opts, int flags)
 
1354
                  const char *opts)
1350
1355
{
1351
1356
        struct my_mntent mnt;
1352
1357
 
1547
1552
  struct stat statbuf;
1548
1553
 
1549
1554
  /* copies for freeing on exit */
1550
 
  const char *opts1, *spec1, *node1, *types1, *extra_opts1;
 
1555
  const char *opts1, *spec1, *node1, *types1;
1551
1556
 
1552
1557
  if (verbose > 2) {
1553
1558
          printf("mount: spec:  \"%s\"\n", spec0);
1562
1567
  opts = opts1 = xstrdup(opts0);
1563
1568
 
1564
1569
  parse_opts (opts, &flags, &extra_opts);
1565
 
  extra_opts1 = extra_opts;
1566
 
  mount_opts = extra_opts;
 
1570
  mount_opts = xstrdup(extra_opts);
1567
1571
 
1568
1572
  /* quietly succeed for fstab entries that don't get mounted automatically */
1569
1573
  if (mount_all && (flags & MS_NOAUTO))
1574
1578
  /* The "mount -f" checks for for existing record in /etc/mtab (with
1575
1579
   * regular non-fake mount this is usually done by kernel)
1576
1580
   */
1577
 
  if (!(flags & MS_REMOUNT) && fake && mounted (spec, node))
 
1581
  if (!(flags & MS_REMOUNT) && fake && mounted (spec, node, NULL))
1578
1582
      die(EX_USAGE, _("mount: according to mtab, "
1579
1583
                      "%s is already mounted on %s\n"),
1580
1584
                      spec, node);
1604
1608
      /*
1605
1609
       * Linux kernel does not accept any selinux context option on remount
1606
1610
       */
1607
 
      if (mount_opts)
 
1611
      if (mount_opts) {
 
1612
          char *tmp = mount_opts;
1608
1613
          mount_opts = remove_context_options(mount_opts);
 
1614
          my_free(tmp);
 
1615
      }
1609
1616
 
1610
1617
  } else if (types && strcmp(types, "tmpfs") == 0 && is_selinux_enabled() > 0 &&
1611
1618
           !has_context_option(mount_opts)) {
1683
1690
#ifdef HAVE_LIBMOUNT_MOUNT
1684
1691
      update_mtab_entry(flags);
1685
1692
      if (verbose)
1686
 
              verbose_mount_info(loop ? loopfile : spec, node, tp, mo, flags);
 
1693
              verbose_mount_info(loop ? loopfile : spec, node, tp, mo);
1687
1694
#else
1688
1695
      if (!(mounttype & MS_PROPAGATION))
1689
1696
              update_mtab_entry(loop ? loopfile : spec,
1777
1784
      unsigned long long size = 0;
1778
1785
 
1779
1786
      if (flags & MS_REMOUNT) {
1780
 
        error (_("mount: %s not mounted already, or bad option"), node);
 
1787
        error (_("mount: %s not mounted or bad option"), node);
1781
1788
      } else {
1782
1789
        error (_("mount: wrong fs type, bad option, bad superblock on %s,\n"
1783
1790
               "       missing codepage or helper program, or other error"),
1934
1941
  }
1935
1942
#endif
1936
1943
 
1937
 
  if (extra_opts1 != mount_opts)
1938
 
          my_free(mount_opts);
1939
 
  my_free(extra_opts1);
 
1944
  my_free(mount_opts);
 
1945
  my_free(extra_opts);
1940
1946
  my_free(spec1);
1941
1947
  my_free(node1);
1942
1948
  my_free(opts1);
2028
2034
        return try_mount_one (spec, node, types, opts, freq, pass, 0);
2029
2035
}
2030
2036
 
 
2037
#ifdef HAVE_LIBMOUNT_MOUNT
 
2038
static struct libmnt_table *minfo;      /* parsed mountinfo file */
 
2039
#endif
 
2040
 
2031
2041
/* Check if an fsname/dir pair was already in the old mtab.  */
2032
2042
static int
2033
 
mounted (const char *spec0, const char *node0) {
 
2043
mounted (const char *spec0, const char *node0, struct mntentchn *fstab_mc) {
2034
2044
        struct mntentchn *mc, *mc0;
2035
2045
        const char *spec, *node;
2036
2046
        int ret = 0;
2037
2047
 
 
2048
#ifdef HAVE_LIBMOUNT_MOUNT
 
2049
        /*
 
2050
         * Use libmount to check for already mounted bind mounts on systems
 
2051
         * without mtab.
 
2052
         */
 
2053
        if (fstab_mc && fstab_mc->m.mnt_opts &&
 
2054
            mtab_is_a_symlink() && strstr(fstab_mc->m.mnt_opts, "bind")) {
 
2055
 
 
2056
                struct libmnt_fs *fs = mnt_new_fs();
 
2057
                int rc = fs ? 0 : -1;
 
2058
 
 
2059
                if (!rc)
 
2060
                        rc = mnt_fs_set_fstype(fs, fstab_mc->m.mnt_type);
 
2061
                if (!rc)
 
2062
                        rc = mnt_fs_set_source(fs, fstab_mc->m.mnt_fsname);
 
2063
                if (!rc)
 
2064
                        rc = mnt_fs_set_target(fs, fstab_mc->m.mnt_dir);
 
2065
                if (!rc)
 
2066
                        rc =  mnt_fs_set_options(fs, fstab_mc->m.mnt_opts);
 
2067
                if (!rc && !minfo)
 
2068
                         minfo = mnt_new_table_from_file("/proc/self/mountinfo");
 
2069
                if (!rc && minfo)
 
2070
                        rc = mnt_table_is_fs_mounted(minfo, fs);
 
2071
 
 
2072
                mnt_free_fs(fs);
 
2073
                if (rc == 1)
 
2074
                        return 1;
 
2075
        }
 
2076
#endif
2038
2077
        /* Handle possible UUID= and LABEL= in spec */
2039
2078
        spec = spec_to_devname(spec0);
2040
2079
        if (!spec)
2042
2081
 
2043
2082
        node = canonicalize(node0);
2044
2083
 
 
2084
 
2045
2085
        mc0 = mtab_head();
2046
2086
        for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
2047
2087
                if (streq (spec, mc->m.mnt_fsname) &&
2062
2102
{
2063
2103
        struct stat st;
2064
2104
 
2065
 
        if (mounted(mc->m.mnt_fsname, mc->m.mnt_dir))
 
2105
        if (mounted(mc->m.mnt_fsname, mc->m.mnt_dir, mc))
2066
2106
                goto yes;
2067
2107
 
2068
2108
        /* extra care for loop devices */
2069
 
        if ((strstr(mc->m.mnt_opts, "loop=") ||
2070
 
             (stat(mc->m.mnt_fsname, &st) == 0 && S_ISREG(st.st_mode)))) {
 
2109
        if ((mc->m.mnt_opts && strstr(mc->m.mnt_opts, "loop=")) ||
 
2110
            (stat(mc->m.mnt_fsname, &st) == 0 && S_ISREG(st.st_mode))) {
2071
2111
 
2072
2112
                char *p = get_option_value(mc->m.mnt_opts, "offset=");
2073
2113
                uintmax_t offset = 0;
2326
2366
        else if (label)
2327
2367
                mc = getfs_by_label(label);
2328
2368
        else {
2329
 
                mc = getfs_by_spec(spec);
 
2369
                mc = getfs_by_dir(spec);
2330
2370
 
2331
2371
                if (!mc)
2332
 
                        mc = getfs_by_dir(spec);
 
2372
                        mc = getfs_by_spec(spec);
2333
2373
        }
2334
2374
        if (mc)
2335
2375
                return mc;