summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd')
-rw-r--r--usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c2
-rw-r--r--usr/src/cmd/fs.d/smbclnt/mount/mntopts.h110
-rw-r--r--usr/src/cmd/fs.d/smbclnt/mount/mount.c400
-rw-r--r--usr/src/cmd/mdb/common/modules/smbfs/smbfs.c176
4 files changed, 284 insertions, 404 deletions
diff --git a/usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c b/usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c
index 1285251898..afce3a64fd 100644
--- a/usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c
+++ b/usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c
@@ -61,7 +61,7 @@ main(int argc, char **argv)
uid_t uid;
gid_t gid;
int error, fd;
- i_ntsd_t *sd;
+ struct i_ntsd *sd;
progname = argv[0];
diff --git a/usr/src/cmd/fs.d/smbclnt/mount/mntopts.h b/usr/src/cmd/fs.d/smbclnt/mount/mntopts.h
deleted file mode 100644
index 6b908f3c7f..0000000000
--- a/usr/src/cmd/fs.d/smbclnt/mount/mntopts.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)mntopts.h 8.7 (Berkeley) 3/29/95
- * $Id: mntopts.h,v 1.4 2004/03/19 01:49:47 lindak Exp $
- */
-
-/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _CIFS_MNTOPTS_H
-#define _CIFS_MNTOPTS_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/vfs.h>
-#ifdef UNPORTED
-/* In solaris this is defined in proto/root_i386/usr/include/sys/vfs.h */
-struct mntopt {
- const char *m_option; /* option name */
- int m_inverse; /* if a negative option, e.g. "dev" */
- int m_flag; /* bit to set, e.g. MNT_RDONLY */
- int m_altloc; /* 1 => set bit in altflags */
-};
-#endif /* UNPORTED */
-
-/* User-visible MNT_ flags. */
-#define MOPT_ASYNC { "async", 0, MNT_ASYNC, 0 }
-#define MOPT_NODEV { "dev", 1, MNT_NODEV, 0 }
-#define MOPT_NOEXEC { "exec", 1, MNT_NOEXEC, 0 }
-#define MOPT_NOSUID { "suid", 1, MNT_NOSUID, 0 }
-#define MOPT_RDONLY { "rdonly", 0, MNT_RDONLY, 0 }
-#define MOPT_SYNC { "sync", 0, MNT_SYNCHRONOUS, 0 }
-#define MOPT_UNION { "union", 0, MNT_UNION, 0 }
-#define MOPT_USERQUOTA { "userquota", 0, 0, 0 }
-#define MOPT_GROUPQUOTA { "groupquota", 0, 0, 0 }
-#define MOPT_BROWSE { "browse", 1, MNT_DONTBROWSE, 0 }
-#define MOPT_AUTOMOUNTED { "automounted", 0, MNT_AUTOMOUNTED, 0 }
-
-/* Control flags. */
-#define MOPT_FORCE { "force", 0, MNT_FORCE, 0 }
-#define MOPT_UPDATE { "update", 0, MNT_UPDATE, 0 }
-#define MOPT_RO { "ro", 0, MNT_RDONLY, 0 }
-#define MOPT_RW { "rw", 1, MNT_RDONLY, 0 }
-
-/* This is parsed by mount(1m), but is ignored by specific mount_*(1m)s. */
-#define MOPT_AUTO { "auto", 0, 0, 0 }
-
-#define MOPT_FSTAB_COMPAT \
- MOPT_RO, \
- MOPT_RW, \
- MOPT_AUTO
-
-/* Standard options which all mounts can understand. */
-#define MOPT_STDOPTS \
- MOPT_USERQUOTA, \
- MOPT_GROUPQUOTA, \
- MOPT_FSTAB_COMPAT, \
- MOPT_NODEV, \
- MOPT_NOEXEC, \
- MOPT_NOSUID, \
- MOPT_RDONLY, \
- MOPT_UNION, \
- MOPT_BROWSE, \
- MOPT_AUTOMOUNTED
-
-void getmntopts(const char *, const mntopt_t *, int *, int *);
-
-extern int getmnt_silent;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CIFS_MNTOPTS_H */
diff --git a/usr/src/cmd/fs.d/smbclnt/mount/mount.c b/usr/src/cmd/fs.d/smbclnt/mount/mount.c
index 9068d093b6..5b2cac4ee7 100644
--- a/usr/src/cmd/fs.d/smbclnt/mount/mount.c
+++ b/usr/src/cmd/fs.d/smbclnt/mount/mount.c
@@ -47,7 +47,6 @@
#include <stdlib.h>
#include <errno.h>
#include <err.h>
-#include <sysexits.h>
#include <libintl.h>
#include <locale.h>
#include <libscf.h>
@@ -59,93 +58,110 @@
#include <sys/mntent.h>
#include <sys/mnttab.h>
-/* This needs to know ctx->ct_dev_fd, etc. */
-#include <netsmb/smb_lib.h>
-
#include <sys/fs/smbfs_mount.h>
-#include "mntopts.h"
+/* This needs to know ctx->ct_dev_fd, etc. */
+#include <netsmb/smb_lib.h>
extern char *optarg;
extern int optind;
static char mount_point[MAXPATHLEN + 1];
static void usage(void);
-static int setsubopt(smb_ctx_t *, struct smbfs_args *, int, char *);
-
-/* smbfs options */
-#define MNTOPT_DOMAIN "domain"
-#define MNTOPT_USER "user"
-#define MNTOPT_DIRPERMS "dirperms"
-#define MNTOPT_FILEPERMS "fileperms"
-#define MNTOPT_GID "gid"
-#define MNTOPT_UID "uid"
-#define MNTOPT_NOPROMPT "noprompt"
-
-#define OPT_DOMAIN 1
-#define OPT_USER 2
-#define OPT_DIRPERMS 3
-#define OPT_FILEPERMS 4
-#define OPT_GID 5
-#define OPT_UID 6
-#define OPT_NOPROMPT 7
-
-/* generic VFS options */
-#define OPT_RO 10
-#define OPT_RW 11
-#define OPT_SUID 12
-#define OPT_NOSUID 13
-#define OPT_DEVICES 14
-#define OPT_NODEVICES 15
-#define OPT_SETUID 16
-#define OPT_NOSETUID 17
-#define OPT_EXEC 18
-#define OPT_NOEXEC 19
-
-struct smbfsopts {
- char *name;
- int index;
-};
-
-struct smbfsopts opts[] = {
- {MNTOPT_DOMAIN, OPT_DOMAIN},
- {MNTOPT_USER, OPT_USER},
- {MNTOPT_DIRPERMS, OPT_DIRPERMS},
- {MNTOPT_FILEPERMS, OPT_FILEPERMS},
- {MNTOPT_GID, OPT_GID},
- {MNTOPT_UID, OPT_UID},
- {MNTOPT_NOPROMPT, OPT_NOPROMPT},
- {MNTOPT_RO, OPT_RO},
- {MNTOPT_RW, OPT_RW},
- {MNTOPT_SUID, OPT_SUID},
- {MNTOPT_NOSUID, OPT_NOSUID},
- {MNTOPT_DEVICES, OPT_DEVICES},
- {MNTOPT_NODEVICES, OPT_NODEVICES},
- {MNTOPT_SETUID, OPT_SETUID},
- {MNTOPT_NOSETUID, OPT_NOSETUID},
- {MNTOPT_EXEC, OPT_EXEC},
- {MNTOPT_NOEXEC, OPT_NOEXEC},
- {NULL, 0}
+static int setsubopt(smb_ctx_t *, struct smbfs_args *, char *);
+
+const char * const optlist[] = {
+
+ /* Generic VFS options. */
+#define OPT_RO 0
+ MNTOPT_RO,
+#define OPT_RW 1
+ MNTOPT_RW,
+#define OPT_SUID 2
+ MNTOPT_SUID,
+#define OPT_NOSUID 3
+ MNTOPT_NOSUID,
+#define OPT_DEVICES 4
+ MNTOPT_DEVICES,
+#define OPT_NODEVICES 5
+ MNTOPT_NODEVICES,
+#define OPT_SETUID 6
+ MNTOPT_SETUID,
+#define OPT_NOSETUID 7
+ MNTOPT_NOSETUID,
+#define OPT_EXEC 8
+ MNTOPT_EXEC,
+#define OPT_NOEXEC 9
+ MNTOPT_NOEXEC,
+#define OPT_XATTR 10
+ MNTOPT_XATTR,
+#define OPT_NOXATTR 11
+ MNTOPT_NOXATTR,
+
+ /* Sort of generic (from NFS) */
+#define OPT_NOAC 12
+ MNTOPT_NOAC,
+#define OPT_ACTIMEO 13
+ MNTOPT_ACTIMEO,
+#define OPT_ACREGMIN 14
+ MNTOPT_ACREGMIN,
+#define OPT_ACREGMAX 15
+ MNTOPT_ACREGMAX,
+#define OPT_ACDIRMIN 16
+ MNTOPT_ACDIRMIN,
+#define OPT_ACDIRMAX 17
+ MNTOPT_ACDIRMAX,
+
+ /* smbfs-specifis options */
+#define OPT_DOMAIN 18
+ "domain",
+#define OPT_USER 19
+ "user",
+#define OPT_UID 20
+ "uid",
+#define OPT_GID 21
+ "gid",
+#define OPT_DIRPERMS 22
+ "dirperms",
+#define OPT_FILEPERMS 23
+ "fileperms",
+#define OPT_NOPROMPT 24
+ "noprompt",
+
+ NULL
};
static int Oflg = 0; /* Overlay mounts */
static int qflg = 0; /* quiet - don't print warnings on bad options */
-static int ro = 0; /* read-only mount */
static int noprompt = 0; /* don't prompt for password */
-#define RET_ERR 33
+/* Note: smbfs uses _both_ kinds of options. */
+static int mntflags = MS_DATA | MS_OPTIONSTR;
+
+#define EX_OK 0 /* normal */
+#define EX_OPT 1 /* bad options, usage, etc */
+#define EX_MNT 2 /* mount point problems, etc */
+#define RET_ERR 3 /* later errors */
+
#define SERVICE "svc:/network/smb/client:default"
struct smbfs_args mdata;
struct mnttab mnt;
-char optbuf[MAX_MNTOPT_STR];
+
+/*
+ * Initialize this with "rw" just to have something there,
+ * so we don't have to decide whether to add a comma when
+ * we strcat another option. Note the "rw" may be changed
+ * to an "ro" by option processing.
+ */
+char optbuf[MAX_MNTOPT_STR] = "rw";
int
main(int argc, char *argv[])
{
struct smb_ctx *ctx = NULL;
struct stat st;
- int opt, error, err2, mntflags;
+ int opt, error, err2;
static char *fstype = MNTTYPE_SMBFS;
char *env, *state;
@@ -188,13 +204,11 @@ main(int argc, char *argv[])
exit(RET_ERR);
mnt.mnt_mntopts = optbuf;
- mntflags = MS_DATA;
bzero(&mdata, sizeof (mdata));
mdata.version = SMBFS_VERSION; /* smbfs mount version */
mdata.uid = (uid_t)-1;
mdata.gid = (gid_t)-1;
- mdata.caseopt = SMB_CS_NONE;
error = smb_ctx_alloc(&ctx);
if (error)
@@ -209,11 +223,11 @@ main(int argc, char *argv[])
error = smb_ctx_parseunc(ctx, argv[argc - 2],
SMBL_SHARE, SMBL_SHARE, USE_DISKDEV, NULL);
if (error)
- exit(RET_ERR);
+ exit(EX_OPT);
error = smb_ctx_readrc(ctx);
if (error)
- exit(RET_ERR);
+ exit(EX_OPT);
while ((opt = getopt(argc, argv, "ro:Oq")) != -1) {
switch (opt) {
@@ -226,19 +240,13 @@ main(int argc, char *argv[])
break;
case 'r':
- ro++;
+ mntflags |= MS_RDONLY;
break;
case 'o': {
- char *nextopt, *comma, *equals, *sopt, *soptval;
- int i, ret;
-
- if (strlen(optarg) >= MAX_MNTOPT_STR) {
- if (!qflg)
- warnx(gettext(
- "option string too long"));
- exit(RET_ERR);
- }
+ char *nextopt, *comma, *sopt;
+ int ret;
+
for (sopt = optarg; sopt != NULL; sopt = nextopt) {
comma = strchr(sopt, ',');
if (comma) {
@@ -246,33 +254,10 @@ main(int argc, char *argv[])
*comma = '\0';
} else
nextopt = NULL;
- equals = strchr(sopt, '=');
- if (equals) {
- soptval = equals + 1;
- *equals = '\0';
- } else
- soptval = NULL;
- for (i = 0; opts[i].name != NULL; i++) {
- if (strcmp(sopt, opts[i].name) == 0)
- break;
- }
- if (opts[i].name == NULL) {
- if (equals)
- *equals = '=';
- if (!qflg)
- errx(RET_ERR, gettext(
- "Bad option '%s'"), sopt);
- if (comma)
- *comma = ',';
- continue;
- }
- ret = setsubopt(ctx, &mdata,
- opts[i].index, soptval);
+ ret = setsubopt(ctx, &mdata, sopt);
if (ret != 0)
- exit(RET_ERR);
- if (equals)
- *equals = '=';
- (void) strcat(mnt.mnt_mntopts, sopt);
+ exit(EX_OPT);
+ /* undo changes to optarg */
if (comma)
*comma = ',';
}
@@ -288,12 +273,10 @@ main(int argc, char *argv[])
if (Oflg)
mntflags |= MS_OVERLAY;
- if (ro) {
+ if (mntflags & MS_RDONLY) {
char *p;
-
- mntflags |= MS_RDONLY;
/* convert "rw"->"ro" */
- if (p = strstr(mnt.mnt_mntopts, "rw")) {
+ if (p = strstr(optbuf, "rw")) {
if (*(p+2) == ',' || *(p+2) == '\0')
*(p+1) = 'o';
}
@@ -307,11 +290,11 @@ main(int argc, char *argv[])
realpath(argv[optind+1], mount_point);
if (stat(mount_point, &st) == -1)
- err(EX_OSERR, gettext("could not find mount point %s"),
+ err(EX_MNT, gettext("could not find mount point %s"),
mount_point);
if (!S_ISDIR(st.st_mode)) {
errno = ENOTDIR;
- err(EX_OSERR, gettext("can't mount on %s"), mount_point);
+ err(EX_MNT, gettext("can't mount on %s"), mount_point);
}
/*
@@ -379,40 +362,57 @@ again:
mntflags, fstype, &mdata, sizeof (mdata),
mnt.mnt_mntopts, MAX_MNTOPT_STR) < 0) {
if (errno != ENOENT) {
- err(EX_OSERR, gettext("mount_smbfs: %s"),
+ err(EX_MNT, gettext("mount_smbfs: %s"),
mnt.mnt_mountp);
} else {
struct stat sb;
if (stat(mnt.mnt_mountp, &sb) < 0 &&
errno == ENOENT)
- err(EX_OSERR, gettext("mount_smbfs: %s"),
+ err(EX_MNT, gettext("mount_smbfs: %s"),
mnt.mnt_mountp);
else
- err(EX_OSERR, gettext("mount_smbfs: %s"),
+ err(EX_MNT, gettext("mount_smbfs: %s"),
mnt.mnt_special);
}
}
smb_ctx_free(ctx);
- if (error) {
- smb_error(gettext("mount error: %s"), error, mount_point);
- exit(RET_ERR);
- }
return (0);
}
+#define bad(val) (val == NULL || !isdigit(*val))
+
int
-setsubopt(smb_ctx_t *ctx, struct smbfs_args *mdatap, int index, char *optarg)
+setsubopt(smb_ctx_t *ctx, struct smbfs_args *mdatap, char *subopt)
{
+ char *equals, *optarg;
struct passwd *pwd;
struct group *grp;
- long l;
- int err = 0;
- char *next;
+ long val;
+ int rc = EX_OK;
+ int index;
+ char *p;
+
+ equals = strchr(subopt, '=');
+ if (equals) {
+ *equals = '\0';
+ optarg = equals + 1;
+ } else
+ optarg = NULL;
+
+ for (index = 0; optlist[index] != NULL; index++) {
+ if (strcmp(subopt, optlist[index]) == 0)
+ break;
+ }
+
+ /*
+ * Note: if the option was unknown, index will
+ * point to the NULL at the end of optlist[],
+ * and we'll take the switch default.
+ */
switch (index) {
- case OPT_RO:
- case OPT_RW:
+
case OPT_SUID:
case OPT_NOSUID:
case OPT_DEVICES:
@@ -421,15 +421,106 @@ setsubopt(smb_ctx_t *ctx, struct smbfs_args *mdatap, int index, char *optarg)
case OPT_NOSETUID:
case OPT_EXEC:
case OPT_NOEXEC:
- /* We don't have to handle generic options here */
- return (0);
+ case OPT_XATTR:
+ case OPT_NOXATTR:
+ /*
+ * These options are handled via the
+ * generic option string mechanism.
+ * None of these take an optarg.
+ */
+ if (optarg != NULL)
+ goto badval;
+ (void) strlcat(optbuf, ",", sizeof (optbuf));
+ if (strlcat(optbuf, subopt, sizeof (optbuf)) >=
+ sizeof (optbuf)) {
+ if (!qflg)
+ warnx(gettext("option string too long"));
+ rc = EX_OPT;
+ }
+ break;
+
+ /*
+ * OPT_RO, OPT_RW, are actually generic too,
+ * but we use the mntflags for these, and
+ * then update the options string later.
+ */
+ case OPT_RO:
+ mntflags |= MS_RDONLY;
+ break;
+ case OPT_RW:
+ mntflags &= ~MS_RDONLY;
+ break;
+
+ /*
+ * NFS-derived options for attribute cache
+ * handling (disable, set min/max timeouts)
+ */
+ case OPT_NOAC:
+ mdatap->flags |= SMBFS_MF_NOAC;
+ break;
+
+ case OPT_ACTIMEO:
+ errno = 0;
+ val = strtol(optarg, &p, 10);
+ if (errno || *p != 0)
+ goto badval;
+ mdatap->acdirmin = mdatap->acregmin = val;
+ mdatap->acdirmax = mdatap->acregmax = val;
+ mdatap->flags |= SMBFS_MF_ACDIRMAX;
+ mdatap->flags |= SMBFS_MF_ACREGMAX;
+ mdatap->flags |= SMBFS_MF_ACDIRMIN;
+ mdatap->flags |= SMBFS_MF_ACREGMIN;
+ break;
+
+ case OPT_ACREGMIN:
+ errno = 0;
+ val = strtol(optarg, &p, 10);
+ if (errno || *p != 0)
+ goto badval;
+ mdatap->acregmin = val;
+ mdatap->flags |= SMBFS_MF_ACREGMIN;
+ break;
+
+ case OPT_ACREGMAX:
+ errno = 0;
+ val = strtol(optarg, &p, 10);
+ if (errno || *p != 0)
+ goto badval;
+ mdatap->acregmax = val;
+ mdatap->flags |= SMBFS_MF_ACREGMAX;
+ break;
+
+ case OPT_ACDIRMIN:
+ errno = 0;
+ val = strtol(optarg, &p, 10);
+ if (errno || *p != 0)
+ goto badval;
+ mdatap->acdirmin = val;
+ mdatap->flags |= SMBFS_MF_ACDIRMIN;
+ break;
+
+ case OPT_ACDIRMAX:
+ errno = 0;
+ val = strtol(optarg, &p, 10);
+ if (errno || *p != 0)
+ goto badval;
+ mdatap->acdirmax = val;
+ mdatap->flags |= SMBFS_MF_ACDIRMAX;
+ break;
+ /*
+ * SMBFS-specific options. Some of these
+ * don't go through the mount system call,
+ * but just set libsmbfs options.
+ */
case OPT_DOMAIN:
- err = smb_ctx_setdomain(ctx, optarg, B_TRUE);
+ if (smb_ctx_setdomain(ctx, optarg, B_TRUE) != 0)
+ rc = EX_OPT;
break;
case OPT_USER:
- err = smb_ctx_setuser(ctx, optarg, B_TRUE);
+ if (smb_ctx_setuser(ctx, optarg, B_TRUE) != 0)
+ rc = EX_OPT;
break;
case OPT_UID:
@@ -438,49 +529,62 @@ setsubopt(smb_ctx_t *ctx, struct smbfs_args *mdatap, int index, char *optarg)
if (pwd == NULL) {
if (!qflg)
warnx(gettext("unknown user '%s'"), optarg);
- err = -1;
+ rc = EX_OPT;
} else {
mdatap->uid = pwd->pw_uid;
}
break;
+
case OPT_GID:
grp = isdigit(optarg[0]) ?
getgrgid(atoi(optarg)) : getgrnam(optarg);
if (grp == NULL) {
if (!qflg)
warnx(gettext("unknown group '%s'"), optarg);
- err = -1;
+ rc = EX_OPT;
} else {
mdatap->gid = grp->gr_gid;
}
break;
+
case OPT_DIRPERMS:
errno = 0;
- l = strtol(optarg, &next, 8);
- if (errno || *next != 0) {
- if (!qflg)
- warnx(gettext(
- "invalid value for directory mode"));
- err = -1;
- } else {
- mdatap->dir_mode = l;
- }
+ val = strtol(optarg, &p, 8);
+ if (errno || *p != 0)
+ goto badval;
+ mdatap->dir_mode = val;
break;
+
case OPT_FILEPERMS:
errno = 0;
- l = strtol(optarg, &next, 8);
- if (errno || *next != 0) {
- if (!qflg)
- warnx(gettext("invalid value for file mode"));
- err = -1;
- } else {
- mdatap->file_mode = l;
- }
+ val = strtol(optarg, &p, 8);
+ if (errno || *p != 0)
+ goto badval;
+ mdatap->file_mode = val;
break;
+
case OPT_NOPROMPT:
noprompt++;
+ break;
+
+ default:
+ if (!qflg)
+ warnx(gettext("unknown option %s"), subopt);
+ rc = EX_OPT;
+ break;
+
+ badval:
+ if (!qflg)
+ warnx(gettext("invalid value for %s"), subopt);
+ rc = EX_OPT;
+ break;
}
- return (err);
+
+ /* Undo changes made to subopt */
+ if (equals)
+ *equals = '=';
+
+ return (rc);
}
static void
@@ -490,5 +594,5 @@ usage(void)
gettext("usage: mount -F smbfs [-Orq] [-o option[,option]]"
" //[workgroup;][user[:password]@]server[/share] path"));
- exit(EX_USAGE);
+ exit(EX_OPT);
}
diff --git a/usr/src/cmd/mdb/common/modules/smbfs/smbfs.c b/usr/src/cmd/mdb/common/modules/smbfs/smbfs.c
index 11aeb9f081..4841a41cd8 100644
--- a/usr/src/cmd/mdb/common/modules/smbfs/smbfs.c
+++ b/usr/src/cmd/mdb/common/modules/smbfs/smbfs.c
@@ -20,13 +20,10 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/mdb_modapi.h>
#include <sys/types.h>
#include <sys/refstr_impl.h>
@@ -176,138 +173,29 @@ smbfs_vfs_help(void)
}
/*
- * Walker for the smbnode hash table.
- */
-
-typedef struct smbnode_walk_data {
- rhashq_t *smbtab; /* (our copy of) the smbtable */
- int tabsize; /* size of table */
- int nextidx; /* next bucket index */
- uintptr_t buckptr; /* target addr of current bucket */
- uintptr_t nodeptr; /* target addr of current smbnode */
- smbnode_t node; /* scratch space for _step */
-} smbnode_walk_data_t;
-
-int
-smbnode_walk_init(mdb_walk_state_t *wsp)
-{
- size_t tabsz_bytes;
- int tabsize;
- uintptr_t smbtab;
- smbnode_walk_data_t *smbw;
-
- if (wsp->walk_addr != NULL) {
- mdb_warn("smbnode only supports global walks\n");
- return (WALK_ERR);
- }
-
- if (mdb_readvar(&tabsize, "smbtablesize") == -1) {
- mdb_warn("failed to read `smbtablesize'\n");
- return (WALK_ERR);
- }
-
- if (tabsize == 0) {
- return (WALK_DONE);
- }
-
- if (mdb_readvar(&smbtab, "smbtable") == -1) {
- mdb_warn("failed to read `smbtable'\n");
- return (WALK_ERR);
- }
-
- smbw = mdb_alloc(sizeof (*smbw), UM_SLEEP | UM_GC);
-
- tabsz_bytes = tabsize * sizeof (rhashq_t);
- smbw->smbtab = mdb_alloc(tabsz_bytes, UM_SLEEP | UM_GC);
- if (mdb_vread(smbw->smbtab, tabsz_bytes, smbtab) != tabsz_bytes) {
- mdb_warn("failed to read in smbtable from %p", smbtab);
- return (WALK_ERR);
- }
- smbw->tabsize = tabsize;
- smbw->nextidx = 1;
- smbw->buckptr = smbtab;
- smbw->nodeptr = (uintptr_t)smbw->smbtab[0].r_hashf;
- wsp->walk_data = smbw;
-
- return (WALK_NEXT);
-}
-
-int
-smbnode_walk_step(mdb_walk_state_t *wsp)
-{
- smbnode_walk_data_t *smbw = wsp->walk_data;
- int status;
-
-next_bucket:
- while (smbw->nodeptr == smbw->buckptr &&
- smbw->nextidx < smbw->tabsize) {
-
- /* Skip an empty bucket */
- rhashq_t *h = &smbw->smbtab[smbw->nextidx];
- smbw->nodeptr = (uintptr_t)h->r_hashf;
- smbw->nextidx++;
- smbw->buckptr += sizeof (rhashq_t);
- }
-
- if (smbw->nodeptr == smbw->buckptr)
- return (WALK_DONE);
-
- if (mdb_vread(&smbw->node, sizeof (smbw->node),
- smbw->nodeptr) != sizeof (smbw->node)) {
- mdb_warn("failed to read smbnode at %p in bucket %p\n",
- smbw->nodeptr, smbw->buckptr);
- /* Proceed with next bucket. */
- smbw->nodeptr = smbw->buckptr;
- goto next_bucket;
- }
-
- status = wsp->walk_callback(smbw->nodeptr,
- &smbw->node, wsp->walk_cbdata);
-
- /* Move to next node in this bucket */
- smbw->nodeptr = (uintptr_t)smbw->node.r_hashf;
-
- return (status);
-}
-
-/*ARGSUSED*/
-void
-smbnode_walk_fini(mdb_walk_state_t *wsp)
-{
- /* UM_GC takes care of it all. */
-}
-
-/*
* Dcmd (and callback function) to print a summary of
- * all smbnodes in the node hash table.
+ * all smbnodes in the node "hash" (cache) AVL tree.
*/
-typedef struct smbnode_cbdata {
+typedef struct smbfs_node_cbdata {
int flags;
int printed_header;
- uintptr_t smi; /* optional filtering by VFS */
- /* TODO: only nodes with a given [-h]ash */
- vnode_t vn; /* scratch space for smbnode_cb */
-} smbnode_cbdata_t;
+ vnode_t vn;
+} smbfs_node_cbdata_t;
int
-smbnode_cb(uintptr_t addr, const void *data, void *arg)
+smbfs_node_cb(uintptr_t addr, const void *data, void *arg)
{
const smbnode_t *np = data;
- smbnode_cbdata_t *cbd = arg;
-
- /* Optional filtering by mount point. */
- if (cbd->smi && cbd->smi != (uintptr_t)np->n_mount) {
- return (WALK_NEXT);
- }
+ smbfs_node_cbdata_t *cbd = arg;
if (cbd->printed_header == 0) {
cbd->printed_header = 1;
- mdb_printf("// smbnode vnode rpath\n");
+ mdb_printf("// vnode smbnode rpath\n");
}
- mdb_printf(" %-p", addr); /* smbnode */
mdb_printf(" %-p", (uintptr_t)np->r_vnode);
+ mdb_printf(" %-p", addr); /* smbnode */
print_str((uintptr_t)np->n_rpath);
mdb_printf("\n");
@@ -320,9 +208,8 @@ smbnode_cb(uintptr_t addr, const void *data, void *arg)
(uintptr_t)np->r_vnode);
} else {
/* Interesting parts of vnode_t */
- mdb_printf("v_type: %d v_path:",
- cbd->vn.v_type);
- print_str((uintptr_t)cbd->vn.v_path);
+ mdb_printf("v_type=%d v_count=%d",
+ cbd->vn.v_type, cbd->vn.v_count);
mdb_printf("\n");
}
mdb_dec_indent(2);
@@ -332,55 +219,54 @@ smbnode_cb(uintptr_t addr, const void *data, void *arg)
}
int
-smbnode_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+smbfs_node_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
- smbnode_cbdata_t *cbd;
- smbnode_t *np;
+ smbfs_node_cbdata_t *cbd;
cbd = mdb_zalloc(sizeof (*cbd), UM_SLEEP | UM_GC);
if (mdb_getopts(argc, argv,
'v', MDB_OPT_SETBITS, OPT_VERBOSE, &cbd->flags,
- 'm', MDB_OPT_UINTPTR, &cbd->smi, NULL) != argc) {
+ NULL) != argc) {
return (DCMD_USAGE);
}
if (!(flags & DCMD_ADDRSPEC)) {
- if (mdb_walk("smbnode", smbnode_cb, cbd)
- == -1) {
- mdb_warn("cannot walk smbnodes");
- return (DCMD_ERR);
- }
- return (DCMD_OK);
+ mdb_warn("expect an smbmntinfo_t addr");
+ return (DCMD_USAGE);
}
+ addr += OFFSETOF(smbmntinfo_t, smi_hash_avl);
- np = mdb_alloc(sizeof (*np), UM_SLEEP | UM_GC);
- SMBFS_OBJ_FETCH(addr, smbnode_t, np, DCMD_ERR);
- smbnode_cb(addr, np, cbd);
+ if (mdb_pwalk("genunix`avl", smbfs_node_cb, cbd, addr) == -1) {
+ mdb_warn("cannot walk smbfs nodes");
+ return (DCMD_ERR);
+ }
return (DCMD_OK);
}
void
-smbnode_help(void)
+smbfs_node_help(void)
{
mdb_printf("Options:\n"
- " -m mntinfo only show smbnodes belonging to mntinfo\n"
" -v be verbose when displaying smbnodes\n");
}
static const mdb_dcmd_t dcmds[] = {
- { "smbfs_vfs", "?[-v]",
+ {
+ "smbfs_vfs", "?[-v]",
"show smbfs-mounted vfs structs",
- smbfs_vfs_dcmd, smbfs_vfs_help },
- { "smbnode", "?[-v] [-m mntinfo]",
- "show smbnodes", smbnode_dcmd, smbnode_help },
+ smbfs_vfs_dcmd, smbfs_vfs_help
+ },
+ {
+ "smbfs_node", "?[-v]",
+ "given an smbmntinfo_t, list smbnodes",
+ smbfs_node_dcmd, smbfs_node_help
+ },
{NULL}
};
static const mdb_walker_t walkers[] = {
- { "smbnode", "walk smbnode hash table",
- smbnode_walk_init, smbnode_walk_step, smbnode_walk_fini },
{NULL}
};