aboutsummaryrefslogtreecommitdiff
path: root/util-linux/mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'util-linux/mount.c')
-rw-r--r--util-linux/mount.c102
1 files changed, 67 insertions, 35 deletions
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 525fdcce9..62fd41fd7 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -36,6 +36,10 @@
36//usage: IF_FEATURE_MTAB_SUPPORT( 36//usage: IF_FEATURE_MTAB_SUPPORT(
37//usage: "\n -n Don't update /etc/mtab" 37//usage: "\n -n Don't update /etc/mtab"
38//usage: ) 38//usage: )
39//usage: IF_FEATURE_MOUNT_VERBOSE(
40//usage: "\n -v Verbose"
41//usage: )
42////usage: "\n -s Sloppy (ignored)"
39//usage: "\n -r Read-only mount" 43//usage: "\n -r Read-only mount"
40//usage: "\n -w Read-write mount (default)" 44//usage: "\n -w Read-write mount (default)"
41//usage: "\n -t FSTYPE[,...] Filesystem type(s)" 45//usage: "\n -t FSTYPE[,...] Filesystem type(s)"
@@ -224,7 +228,7 @@ static const int32_t mount_options[] = {
224 IF_DESKTOP(/* "user" */ MOUNT_USERS,) 228 IF_DESKTOP(/* "user" */ MOUNT_USERS,)
225 IF_DESKTOP(/* "users" */ MOUNT_USERS,) 229 IF_DESKTOP(/* "users" */ MOUNT_USERS,)
226 /* "_netdev" */ 0, 230 /* "_netdev" */ 0,
227 IF_DESKTOP(/* "comment" */ 0,) /* systemd uses this in fstab */ 231 IF_DESKTOP(/* "comment=" */ 0,) /* systemd uses this in fstab */
228 ) 232 )
229 233
230 IF_FEATURE_MOUNT_FLAGS( 234 IF_FEATURE_MOUNT_FLAGS(
@@ -283,7 +287,7 @@ static const char mount_option_str[] =
283 IF_DESKTOP("user\0") 287 IF_DESKTOP("user\0")
284 IF_DESKTOP("users\0") 288 IF_DESKTOP("users\0")
285 "_netdev\0" 289 "_netdev\0"
286 IF_DESKTOP("comment\0") /* systemd uses this in fstab */ 290 IF_DESKTOP("comment=\0") /* systemd uses this in fstab */
287 ) 291 )
288 IF_FEATURE_MOUNT_FLAGS( 292 IF_FEATURE_MOUNT_FLAGS(
289 // vfs flags 293 // vfs flags
@@ -475,10 +479,13 @@ static unsigned long parse_mount_options(char *options, char **unrecognized)
475// FIXME: use hasmntopt() 479// FIXME: use hasmntopt()
476 // Find this option in mount_options 480 // Find this option in mount_options
477 for (i = 0; i < ARRAY_SIZE(mount_options); i++) { 481 for (i = 0; i < ARRAY_SIZE(mount_options); i++) {
478 /* We support "option=" match for "comment=" thingy */
479 unsigned opt_len = strlen(option_str); 482 unsigned opt_len = strlen(option_str);
483
480 if (strncasecmp(option_str, options, opt_len) == 0 484 if (strncasecmp(option_str, options, opt_len) == 0
481 && (options[opt_len] == '\0' || options[opt_len] == '=') 485 && (options[opt_len] == '\0'
486 /* or is it "comment=" thingy in fstab? */
487 IF_FEATURE_MOUNT_FSTAB(IF_DESKTOP( || option_str[opt_len-1] == '=' ))
488 )
482 ) { 489 ) {
483 unsigned long fl = mount_options[i]; 490 unsigned long fl = mount_options[i];
484 if (fl & BB_MS_INVERTED_VALUE) 491 if (fl & BB_MS_INVERTED_VALUE)
@@ -927,7 +934,7 @@ static bool_t xdr_fhandle(XDR *xdrs, fhandle objp)
927static bool_t xdr_fhstatus(XDR *xdrs, fhstatus *objp) 934static bool_t xdr_fhstatus(XDR *xdrs, fhstatus *objp)
928{ 935{
929 if (!xdr_u_int(xdrs, &objp->fhs_status)) 936 if (!xdr_u_int(xdrs, &objp->fhs_status))
930 return FALSE; 937 return FALSE;
931 if (objp->fhs_status == 0) 938 if (objp->fhs_status == 0)
932 return xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle); 939 return xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle);
933 return TRUE; 940 return TRUE;
@@ -941,8 +948,8 @@ static bool_t xdr_dirpath(XDR *xdrs, dirpath *objp)
941static bool_t xdr_fhandle3(XDR *xdrs, fhandle3 *objp) 948static bool_t xdr_fhandle3(XDR *xdrs, fhandle3 *objp)
942{ 949{
943 return xdr_bytes(xdrs, (char **)&objp->fhandle3_val, 950 return xdr_bytes(xdrs, (char **)&objp->fhandle3_val,
944 (unsigned int *) &objp->fhandle3_len, 951 (unsigned int *) &objp->fhandle3_len,
945 FHSIZE3); 952 FHSIZE3);
946} 953}
947 954
948static bool_t xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp) 955static bool_t xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp)
@@ -950,10 +957,10 @@ static bool_t xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp)
950 if (!xdr_fhandle3(xdrs, &objp->fhandle)) 957 if (!xdr_fhandle3(xdrs, &objp->fhandle))
951 return FALSE; 958 return FALSE;
952 return xdr_array(xdrs, &(objp->auth_flavours.auth_flavours_val), 959 return xdr_array(xdrs, &(objp->auth_flavours.auth_flavours_val),
953 &(objp->auth_flavours.auth_flavours_len), 960 &(objp->auth_flavours.auth_flavours_len),
954 ~0, 961 ~0,
955 sizeof(int), 962 sizeof(int),
956 (xdrproc_t) xdr_int); 963 (xdrproc_t) xdr_int);
957} 964}
958 965
959static bool_t xdr_mountstat3(XDR *xdrs, mountstat3 *objp) 966static bool_t xdr_mountstat3(XDR *xdrs, mountstat3 *objp)
@@ -1522,19 +1529,19 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *fi
1522 switch (pm_mnt.pm_prot) { 1529 switch (pm_mnt.pm_prot) {
1523 case IPPROTO_UDP: 1530 case IPPROTO_UDP:
1524 mclient = clntudp_create(&mount_server_addr, 1531 mclient = clntudp_create(&mount_server_addr,
1525 pm_mnt.pm_prog, 1532 pm_mnt.pm_prog,
1526 pm_mnt.pm_vers, 1533 pm_mnt.pm_vers,
1527 retry_timeout, 1534 retry_timeout,
1528 &msock); 1535 &msock);
1529 if (mclient) 1536 if (mclient)
1530 break; 1537 break;
1531 mount_server_addr.sin_port = htons(pm_mnt.pm_port); 1538 mount_server_addr.sin_port = htons(pm_mnt.pm_port);
1532 msock = RPC_ANYSOCK; 1539 msock = RPC_ANYSOCK;
1533 case IPPROTO_TCP: 1540 case IPPROTO_TCP:
1534 mclient = clnttcp_create(&mount_server_addr, 1541 mclient = clnttcp_create(&mount_server_addr,
1535 pm_mnt.pm_prog, 1542 pm_mnt.pm_prog,
1536 pm_mnt.pm_vers, 1543 pm_mnt.pm_vers,
1537 &msock, 0, 0); 1544 &msock, 0, 0);
1538 break; 1545 break;
1539 default: 1546 default:
1540 mclient = NULL; 1547 mclient = NULL;
@@ -1555,18 +1562,18 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *fi
1555 1562
1556 if (pm_mnt.pm_vers == 3) 1563 if (pm_mnt.pm_vers == 3)
1557 clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT, 1564 clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
1558 (xdrproc_t) xdr_dirpath, 1565 (xdrproc_t) xdr_dirpath,
1559 (caddr_t) &pathname, 1566 (caddr_t) &pathname,
1560 (xdrproc_t) xdr_mountres3, 1567 (xdrproc_t) xdr_mountres3,
1561 (caddr_t) &status, 1568 (caddr_t) &status,
1562 total_timeout); 1569 total_timeout);
1563 else 1570 else
1564 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT, 1571 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
1565 (xdrproc_t) xdr_dirpath, 1572 (xdrproc_t) xdr_dirpath,
1566 (caddr_t) &pathname, 1573 (caddr_t) &pathname,
1567 (xdrproc_t) xdr_fhstatus, 1574 (xdrproc_t) xdr_fhstatus,
1568 (caddr_t) &status, 1575 (caddr_t) &status,
1569 total_timeout); 1576 total_timeout);
1570 1577
1571 if (clnt_stat == RPC_SUCCESS) 1578 if (clnt_stat == RPC_SUCCESS)
1572 goto prepare_kernel_data; /* we're done */ 1579 goto prepare_kernel_data; /* we're done */
@@ -1817,17 +1824,44 @@ static int singlemount(struct mntent *mp, int ignore_busy)
1817 ) { 1824 ) {
1818 int len; 1825 int len;
1819 char c; 1826 char c;
1827 char *hostname, *share;
1828 char *dotted, *ip;
1820 len_and_sockaddr *lsa; 1829 len_and_sockaddr *lsa;
1821 char *hostname, *dotted, *ip; 1830
1831 // Parse mp->mnt_fsname of the form "//hostname/share[/dir1/dir2]"
1822 1832
1823 hostname = mp->mnt_fsname + 2; 1833 hostname = mp->mnt_fsname + 2;
1824 len = strcspn(hostname, "/\\"); 1834 len = strcspn(hostname, "/\\");
1825 if (len == 0 || hostname[len] == '\0') 1835 share = hostname + len + 1;
1836 if (len == 0 // 3rd char is a [back]slash (IOW: empty hostname)
1837 || share[-1] == '\0' // no [back]slash after hostname
1838 || share[0] == '\0' // empty share name
1839 ) {
1826 goto report_error; 1840 goto report_error;
1827 c = hostname[len]; 1841 }
1828 hostname[len] = '\0'; 1842 c = share[-1];
1843 share[-1] = '\0';
1844 len = strcspn(share, "/\\");
1845
1846 // "unc=\\hostname\share" option is mandatory
1847 // after CIFS option parsing was rewritten in Linux 3.4.
1848 // Must use backslashes.
1849 // If /dir1/dir2 is present, also add "prefixpath=dir1/dir2"
1850 {
1851 char *unc = xasprintf(
1852 share[len] != '\0' /* "/dir1/dir2" exists? */
1853 ? "unc=\\\\%s\\%.*s,prefixpath=%s"
1854 : "unc=\\\\%s\\%.*s",
1855 hostname,
1856 len, share,
1857 share + len + 1 /* "dir1/dir2" */
1858 );
1859 parse_mount_options(unc, &filteropts);
1860 if (ENABLE_FEATURE_CLEAN_UP) free(unc);
1861 }
1862
1829 lsa = host2sockaddr(hostname, 0); 1863 lsa = host2sockaddr(hostname, 0);
1830 hostname[len] = c; 1864 share[-1] = c;
1831 if (!lsa) 1865 if (!lsa)
1832 goto report_error; 1866 goto report_error;
1833 1867
@@ -1839,8 +1873,6 @@ static int singlemount(struct mntent *mp, int ignore_busy)
1839 parse_mount_options(ip, &filteropts); 1873 parse_mount_options(ip, &filteropts);
1840 if (ENABLE_FEATURE_CLEAN_UP) free(ip); 1874 if (ENABLE_FEATURE_CLEAN_UP) free(ip);
1841 1875
1842 // "-o mand" is required [why?]
1843 vfsflags |= MS_MANDLOCK;
1844 mp->mnt_type = (char*)"cifs"; 1876 mp->mnt_type = (char*)"cifs";
1845 rc = mount_it_now(mp, vfsflags, filteropts); 1877 rc = mount_it_now(mp, vfsflags, filteropts);
1846 1878