aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util-linux/mount.c186
1 files changed, 87 insertions, 99 deletions
diff --git a/util-linux/mount.c b/util-linux/mount.c
index de0558024..61ad23528 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -407,7 +407,7 @@ static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts)
407 vfsflags, filteropts); 407 vfsflags, filteropts);
408 408
409 // If mount failed, try 409 // If mount failed, try
410 // helper program <mnt_type> 410 // helper program mount.<mnt_type>
411 if (ENABLE_FEATURE_MOUNT_HELPERS && rc) { 411 if (ENABLE_FEATURE_MOUNT_HELPERS && rc) {
412 char *args[6]; 412 char *args[6];
413 int errno_save = errno; 413 int errno_save = errno;
@@ -1727,11 +1727,11 @@ static int singlemount(struct mntent *mp, int ignore_busy)
1727static const char must_be_root[] ALIGN1 = "you must be root"; 1727static const char must_be_root[] ALIGN1 = "you must be root";
1728 1728
1729int mount_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1729int mount_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1730int mount_main(int argc, char **argv) 1730int mount_main(int argc ATTRIBUTE_UNUSED, char **argv)
1731{ 1731{
1732 char *cmdopts = xstrdup(""); 1732 char *cmdopts = xstrdup("");
1733 char *fstype = NULL; 1733 char *fstype = NULL;
1734 char *storage_path = NULL; 1734 char *storage_path;
1735 char *opt_o; 1735 char *opt_o;
1736 const char *fstabname; 1736 const char *fstabname;
1737 FILE *fstab; 1737 FILE *fstab;
@@ -1740,43 +1740,35 @@ int mount_main(int argc, char **argv)
1740 struct mntent mtpair[2], *mtcur = mtpair; 1740 struct mntent mtpair[2], *mtcur = mtpair;
1741 SKIP_DESKTOP(const int nonroot = 0;) 1741 SKIP_DESKTOP(const int nonroot = 0;)
1742 1742
1743 USE_DESKTOP( int nonroot = ) sanitize_env_if_suid(); 1743 USE_DESKTOP(int nonroot = ) sanitize_env_if_suid();
1744 1744
1745 // Parse long options, like --bind and --move. Note that -o option 1745 // Parse long options, like --bind and --move. Note that -o option
1746 // and --option are synonymous. Yes, this means --remount,rw works. 1746 // and --option are synonymous. Yes, this means --remount,rw works.
1747 1747 for (i = j = 1; argv[i]; i++) {
1748 for (i = j = 0; i < argc; i++) { 1748 if (argv[i][0] == '-' && argv[i][1] == '-')
1749 if (argv[i][0] == '-' && argv[i][1] == '-') { 1749 append_mount_options(&cmdopts, argv[i] + 2);
1750 append_mount_options(&cmdopts, argv[i]+2); 1750 else
1751 } else argv[j++] = argv[i]; 1751 argv[j++] = argv[i];
1752 } 1752 }
1753 argv[j] = NULL; 1753 argv[j] = NULL;
1754 argc = j;
1755 1754
1756 // Parse remaining options 1755 // Parse remaining options
1757 1756 // Max 2 params; -v is a counter
1758#if ENABLE_FEATURE_MOUNT_VERBOSE 1757 opt_complementary = "?2" USE_FEATURE_MOUNT_VERBOSE(":vv");
1759 opt_complementary = "vv"; // -v is a counter
1760#endif
1761 opt = getopt32(argv, OPTION_STR, &opt_o, &fstype 1758 opt = getopt32(argv, OPTION_STR, &opt_o, &fstype
1762 USE_FEATURE_MOUNT_VERBOSE(, &verbose)); 1759 USE_FEATURE_MOUNT_VERBOSE(, &verbose));
1763 if (opt & OPT_o) append_mount_options(&cmdopts, opt_o); // -o 1760 if (opt & OPT_o) append_mount_options(&cmdopts, opt_o); // -o
1764 if (opt & OPT_r) append_mount_options(&cmdopts, "ro"); // -r 1761 if (opt & OPT_r) append_mount_options(&cmdopts, "ro"); // -r
1765 if (opt & OPT_w) append_mount_options(&cmdopts, "rw"); // -w 1762 if (opt & OPT_w) append_mount_options(&cmdopts, "rw"); // -w
1766 argv += optind; 1763 argv += optind;
1767 argc -= optind;
1768
1769 // Three or more non-option arguments? Die with a usage message.
1770
1771 if (argc > 2) bb_show_usage();
1772 1764
1773 // If we have no arguments, show currently mounted filesystems 1765 // If we have no arguments, show currently mounted filesystems
1774 1766 if (!argv[0]) {
1775 if (!argc) {
1776 if (!(opt & OPT_a)) { 1767 if (!(opt & OPT_a)) {
1777 FILE *mountTable = setmntent(bb_path_mtab_file, "r"); 1768 FILE *mountTable = setmntent(bb_path_mtab_file, "r");
1778 1769
1779 if (!mountTable) bb_error_msg_and_die("no %s", bb_path_mtab_file); 1770 if (!mountTable)
1771 bb_error_msg_and_die("no %s", bb_path_mtab_file);
1780 1772
1781 while (getmntent_r(mountTable, &mtpair[0], getmntent_buf, 1773 while (getmntent_r(mountTable, &mtpair[0], getmntent_buf,
1782 GETMNTENT_BUFSIZE)) 1774 GETMNTENT_BUFSIZE))
@@ -1790,152 +1782,148 @@ int mount_main(int argc, char **argv)
1790 mtpair->mnt_dir, mtpair->mnt_type, 1782 mtpair->mnt_dir, mtpair->mnt_type,
1791 mtpair->mnt_opts); 1783 mtpair->mnt_opts);
1792 } 1784 }
1793 if (ENABLE_FEATURE_CLEAN_UP) endmntent(mountTable); 1785 if (ENABLE_FEATURE_CLEAN_UP)
1786 endmntent(mountTable);
1794 return EXIT_SUCCESS; 1787 return EXIT_SUCCESS;
1795 } 1788 }
1796 } else storage_path = bb_simplify_path(argv[0]); 1789 storage_path = NULL;
1797 1790 } else {
1798 // When we have two arguments, the second is the directory and we can 1791 // When we have two arguments, the second is the directory and we can
1799 // skip looking at fstab entirely. We can always abspath() the directory 1792 // skip looking at fstab entirely. We can always abspath() the directory
1800 // argument when we get it. 1793 // argument when we get it.
1801 1794 if (argv[1]) {
1802 if (argc == 2) { 1795 if (nonroot)
1803 if (nonroot) 1796 bb_error_msg_and_die(must_be_root);
1804 bb_error_msg_and_die(must_be_root); 1797 mtpair->mnt_fsname = argv[0];
1805 mtpair->mnt_fsname = argv[0]; 1798 mtpair->mnt_dir = argv[1];
1806 mtpair->mnt_dir = argv[1]; 1799 mtpair->mnt_type = fstype;
1807 mtpair->mnt_type = fstype; 1800 mtpair->mnt_opts = cmdopts;
1808 mtpair->mnt_opts = cmdopts; 1801 if (ENABLE_FEATURE_MOUNT_LABEL) {
1809 if (ENABLE_FEATURE_MOUNT_LABEL) { 1802 resolve_mount_spec(&mtpair->mnt_fsname);
1810 resolve_mount_spec(&mtpair->mnt_fsname); 1803 }
1804 rc = singlemount(mtpair, 0);
1805 return rc;
1811 } 1806 }
1812 rc = singlemount(mtpair, 0); 1807 storage_path = bb_simplify_path(argv[0]); // malloced
1813 goto clean_up;
1814 } 1808 }
1815 1809
1810 // Past this point, we are handling either "mount -a [opts]"
1811 // or "mount [opts] single_param"
1812
1816 i = parse_mount_options(cmdopts, 0); // FIXME: should be "long", not "int" 1813 i = parse_mount_options(cmdopts, 0); // FIXME: should be "long", not "int"
1817 if (nonroot && (i & ~MS_SILENT)) // Non-root users cannot specify flags 1814 if (nonroot && (i & ~MS_SILENT)) // Non-root users cannot specify flags
1818 bb_error_msg_and_die(must_be_root); 1815 bb_error_msg_and_die(must_be_root);
1819 1816
1820 // If we have a shared subtree flag, don't worry about fstab or mtab. 1817 // If we have a shared subtree flag, don't worry about fstab or mtab.
1821
1822 if (ENABLE_FEATURE_MOUNT_FLAGS 1818 if (ENABLE_FEATURE_MOUNT_FLAGS
1823 && (i & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) 1819 && (i & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
1824 ) { 1820 ) {
1825 rc = verbose_mount("", argv[0], "", i, ""); 1821 rc = verbose_mount(/*source:*/ "", /*target:*/ argv[0],
1826 if (rc) bb_simple_perror_msg_and_die(argv[0]); 1822 /*type:*/ "", /*flags:*/ i, /*data:*/ "");
1827 goto clean_up; 1823 if (rc)
1824 bb_simple_perror_msg_and_die(argv[0]);
1825 return rc;
1828 } 1826 }
1829 1827
1830 // Open either fstab or mtab 1828 // Open either fstab or mtab
1831
1832 fstabname = "/etc/fstab"; 1829 fstabname = "/etc/fstab";
1833 if (i & MS_REMOUNT) { 1830 if (i & MS_REMOUNT) {
1831 // WARNING. I am not sure this matches util-linux's
1832 // behavior. It's possible util-linux does not
1833 // take -o opts from mtab (takes only mount source).
1834 fstabname = bb_path_mtab_file; 1834 fstabname = bb_path_mtab_file;
1835 } 1835 }
1836 fstab = setmntent(fstabname, "r"); 1836 fstab = setmntent(fstabname, "r");
1837 if (!fstab) 1837 if (!fstab)
1838 bb_perror_msg_and_die("cannot read %s", fstabname); 1838 bb_perror_msg_and_die("cannot read %s", fstabname);
1839 1839
1840 // Loop through entries until we find what we're looking for. 1840 // Loop through entries until we find what we're looking for
1841
1842 memset(mtpair, 0, sizeof(mtpair)); 1841 memset(mtpair, 0, sizeof(mtpair));
1843 for (;;) { 1842 for (;;) {
1844 struct mntent *mtnext = (mtcur==mtpair ? mtpair+1 : mtpair); 1843 struct mntent *mtother = (mtcur==mtpair ? mtpair+1 : mtpair);
1845 1844
1846 // Get next fstab entry 1845 // Get next fstab entry
1847
1848 if (!getmntent_r(fstab, mtcur, getmntent_buf 1846 if (!getmntent_r(fstab, mtcur, getmntent_buf
1849 + (mtcur==mtpair ? GETMNTENT_BUFSIZE/2 : 0), 1847 + (mtcur==mtpair ? GETMNTENT_BUFSIZE/2 : 0),
1850 GETMNTENT_BUFSIZE/2)) 1848 GETMNTENT_BUFSIZE/2)
1851 { 1849 ) { // End of fstab/mtab is reached
1852 // Were we looking for something specific? 1850 mtcur = mtother; // the thing we found last time
1853 1851 break;
1854 if (argc) {
1855
1856 // If we didn't find anything, complain.
1857
1858 if (!mtnext->mnt_fsname)
1859 bb_error_msg_and_die("can't find %s in %s",
1860 argv[0], fstabname);
1861
1862 mtcur = mtnext;
1863 if (nonroot) {
1864 // fstab must have "users" or "user"
1865 if (!(parse_mount_options(mtcur->mnt_opts, 0) & MOUNT_USERS))
1866 bb_error_msg_and_die(must_be_root);
1867 }
1868
1869 // Mount the last thing we found.
1870
1871 mtcur->mnt_opts = xstrdup(mtcur->mnt_opts);
1872 append_mount_options(&(mtcur->mnt_opts), cmdopts);
1873 if (ENABLE_FEATURE_MOUNT_LABEL) {
1874 resolve_mount_spec(&mtpair->mnt_fsname);
1875 }
1876 rc = singlemount(mtcur, 0);
1877 free(mtcur->mnt_opts);
1878 }
1879 goto clean_up;
1880 } 1852 }
1881 1853
1882 /* If we're trying to mount something specific and this isn't it, 1854 // If we're trying to mount something specific and this isn't it,
1883 * skip it. Note we must match both the exact text in fstab (ala 1855 // skip it. Note we must match the exact text in fstab (ala
1884 * "proc") or a full path from root */ 1856 // "proc") or a full path from root
1885 1857 if (argv[0]) {
1886 if (argc) {
1887 1858
1888 // Is this what we're looking for? 1859 // Is this what we're looking for?
1889
1890 if (strcmp(argv[0], mtcur->mnt_fsname) && 1860 if (strcmp(argv[0], mtcur->mnt_fsname) &&
1891 strcmp(storage_path, mtcur->mnt_fsname) && 1861 strcmp(storage_path, mtcur->mnt_fsname) &&
1892 strcmp(argv[0], mtcur->mnt_dir) && 1862 strcmp(argv[0], mtcur->mnt_dir) &&
1893 strcmp(storage_path, mtcur->mnt_dir)) continue; 1863 strcmp(storage_path, mtcur->mnt_dir)) continue;
1894 1864
1895 // Remember this entry. Something later may have overmounted 1865 // Remember this entry. Something later may have
1896 // it, and we want the _last_ match. 1866 // overmounted it, and we want the _last_ match.
1897 1867 mtcur = mtother;
1898 mtcur = mtnext;
1899
1900 // If we're mounting all.
1901 1868
1869 // If we're mounting all
1902 } else { 1870 } else {
1903 // Do we need to match a filesystem type? 1871 // Do we need to match a filesystem type?
1904 if (fstype && match_fstype(mtcur, fstype)) 1872 if (fstype && match_fstype(mtcur, fstype))
1905 continue; 1873 continue;
1906 1874
1907 // Skip noauto and swap anyway. 1875 // Skip noauto and swap anyway.
1908
1909 if (parse_mount_options(mtcur->mnt_opts, 0) & (MOUNT_NOAUTO | MOUNT_SWAP)) 1876 if (parse_mount_options(mtcur->mnt_opts, 0) & (MOUNT_NOAUTO | MOUNT_SWAP))
1910 continue; 1877 continue;
1911 1878
1912 // No, mount -a won't mount anything, 1879 // No, mount -a won't mount anything,
1913 // even user mounts, for mere humans. 1880 // even user mounts, for mere humans
1914
1915 if (nonroot) 1881 if (nonroot)
1916 bb_error_msg_and_die(must_be_root); 1882 bb_error_msg_and_die(must_be_root);
1917 1883
1918 // Mount this thing. 1884 // Mount this thing
1919 if (ENABLE_FEATURE_MOUNT_LABEL) 1885 if (ENABLE_FEATURE_MOUNT_LABEL)
1920 resolve_mount_spec(&mtpair->mnt_fsname); 1886 resolve_mount_spec(&mtpair->mnt_fsname);
1921 1887
1922 // NFS mounts want this to be xrealloc-able 1888 // NFS mounts want this to be xrealloc-able
1923 mtcur->mnt_opts = xstrdup(mtcur->mnt_opts); 1889 mtcur->mnt_opts = xstrdup(mtcur->mnt_opts);
1924 if (singlemount(mtcur, 1)) { 1890 if (singlemount(mtcur, 1)) {
1925 /* Count number of failed mounts */ 1891 // Count number of failed mounts
1926 rc++; 1892 rc++;
1927 } 1893 }
1928 free(mtcur->mnt_opts); 1894 free(mtcur->mnt_opts);
1929 } 1895 }
1930 } 1896 }
1931 if (ENABLE_FEATURE_CLEAN_UP) endmntent(fstab);
1932 1897
1933 clean_up: 1898 // End of fstab/mtab is reached.
1899 // Were we looking for something specific?
1900 if (argv[0]) {
1901 // If we didn't find anything, complain
1902 if (!mtcur->mnt_fsname)
1903 bb_error_msg_and_die("can't find %s in %s",
1904 argv[0], fstabname);
1905 if (nonroot) {
1906 // fstab must have "users" or "user"
1907 if (!(parse_mount_options(mtcur->mnt_opts, 0) & MOUNT_USERS))
1908 bb_error_msg_and_die(must_be_root);
1909 }
1934 1910
1911 // Mount the last thing we found
1912 mtcur->mnt_opts = xstrdup(mtcur->mnt_opts);
1913 append_mount_options(&(mtcur->mnt_opts), cmdopts);
1914 if (ENABLE_FEATURE_MOUNT_LABEL) {
1915 resolve_mount_spec(&mtpair->mnt_fsname);
1916 }
1917 rc = singlemount(mtcur, 0);
1918 if (ENABLE_FEATURE_CLEAN_UP)
1919 free(mtcur->mnt_opts);
1920 }
1921
1922 if (ENABLE_FEATURE_CLEAN_UP)
1923 endmntent(fstab);
1935 if (ENABLE_FEATURE_CLEAN_UP) { 1924 if (ENABLE_FEATURE_CLEAN_UP) {
1936 free(storage_path); 1925 free(storage_path);
1937 free(cmdopts); 1926 free(cmdopts);
1938 } 1927 }
1939
1940 return rc; 1928 return rc;
1941} 1929}