summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authoraj <none@none>2007-06-21 10:39:47 -0700
committeraj <none@none>2007-06-21 10:39:47 -0700
commit10ddde3aee60d88fa580028fcf7642a87e80a2c6 (patch)
treed7d477bfb38c88169915ac216139ad9f3a669179 /usr/src
parentf9aa3e1e897e74b50458e34d6c88abb9a7a08aed (diff)
downloadillumos-joyent-10ddde3aee60d88fa580028fcf7642a87e80a2c6.tar.gz
6535551 TX DA GUI behaves incorrectly if multiple rapid updates to TX DA database are done
6542809 TX: add_allocatable/remove_allocatable don't play well with other instances of themselves 6545689 device_clean scripts should be able to return a "CANCEL" return code 6549055 TX: deallocate(1), list_devices(1) should allow operation on classes of devices
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/allocate/allocate.c188
-rw-r--r--usr/src/cmd/allocate/allocate.h45
-rw-r--r--usr/src/cmd/allocate/allocate3.c234
-rw-r--r--usr/src/lib/libbsm/common/devalloc.c45
-rw-r--r--usr/src/lib/libbsm/common/devalloc.h11
-rw-r--r--usr/src/lib/libbsm/common/devices.h11
6 files changed, 351 insertions, 183 deletions
diff --git a/usr/src/cmd/allocate/allocate.c b/usr/src/cmd/allocate/allocate.c
index 496bea5274..36aab83ba1 100644
--- a/usr/src/cmd/allocate/allocate.c
+++ b/usr/src/cmd/allocate/allocate.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -63,73 +63,64 @@ static void
usage(int func)
{
if (system_labeled) {
- char *use[9];
+ char *use[6];
use[0] = gettext("allocate [-s] [-w] [-U uname] [-z zonename] "
- "[-F] device");
- use[1] = gettext("allocate [-s] [-w] [-U uname] [-z zonename] "
- "[-F] -g dev_type");
- use[2] = gettext("deallocate [-s] [-w] [-z zonename] "
- "[-F] device");
- use[3] = gettext("deallocate [-s] [-w] [-z zonename] "
- "[-F] -g dev_type");
- use[4] = gettext("deallocate [-s] [-w] [-z zonename] -I");
- use[5] = gettext("list_devices [-s] [-U uid] [-z zonename] "
- "[-a] -l [device]");
- use[6] = gettext("list_devices [-s] [-U uid] [-z zonename] "
- "[-a] -n [device]");
- use[7] = gettext("list_devices [-s] [-U uid] [-z zonename] "
- "[-a] -u [device]");
- use[8] = gettext("list_devices [-s] -d dev_type");
+ "[-F] device|-g dev-type");
+ use[1] = gettext("deallocate [-s] [-w] [-z zonename] "
+ "[-F] device|-c dev-class|-g dev-type");
+ use[2] = gettext("deallocate [-s] [-w] [-z zonename] -I");
+ use[3] = gettext("list_devices [-s] [-U uid] [-z zonename] "
+ "[-a [-w]] -l|-n|-u [device]");
+ use[4] = gettext("list_devices [-s] [-U uid] [-z zonename] "
+ "[-a [-w]] [-l|-n|-u] -c dev-class");
+ use[5] = gettext("list_devices [-s] -d [dev-type]");
switch (func) {
case 0:
- (void) fprintf(stderr, "%s\n%s\n",
- use[0], use[1]);
+ (void) fprintf(stderr, "%s\n", use[0]);
break;
case 1:
- (void) fprintf(stderr, "%s\n%s\n%s\n",
- use[2], use[3], use[4]);
+ (void) fprintf(stderr, "%s\n%s\n",
+ use[1], use[2]);
break;
case 2:
- (void) fprintf(stderr, "%s\n%s\n%s\n%s\n",
- use[5], use[6], use[7], use[8]);
+ (void) fprintf(stderr, "%s\n%s\n%s\n",
+ use[3], use[4], use[5]);
break;
default:
(void) fprintf(stderr,
- "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
+ "%s\n%s\n%s\n%s\n%s\n%s\n",
use[0], use[1], use[2], use[3], use[4],
- use[5], use[6], use[7], use[8]);
+ use[5]);
}
} else {
- char *use[7];
+ char *use[5];
- use[0] = gettext("allocate [-s] [-U uname] [-F] device");
- use[1] = gettext("allocate [-s] [-U uname] -g dev_type");
- use[2] = gettext("deallocate [-s] [-F] device");
- use[3] = gettext("deallocate [-s] -I");
- use[4] = gettext("list_devices [-s] [-U uid] -l [device]");
- use[5] = gettext("list_devices [-s] [-U uid] -n [device]");
- use[6] = gettext("list_devices [-s] [-U uid] -u [device]");
+ use[0] = gettext("allocate "
+ "[-s] [-U uname] [-F] device|-g dev-type");
+ use[1] = gettext("deallocate [-s] [-F] device|-c dev-class");
+ use[2] = gettext("deallocate [-s] -I");
+ use[3] = gettext("list_devices "
+ "[-s] [-U uid] -l|-n|-u [device]");
+ use[4] = gettext("list_devices "
+ "[-s] [-U uid] [-l|-n|-u] -c dev-class");
switch (func) {
case 0:
- (void) fprintf(stderr, "%s\n%s\n",
- use[0], use[1]);
+ (void) fprintf(stderr, "%s\n", use[0]);
break;
case 1:
(void) fprintf(stderr, "%s\n%s\n",
- use[2], use[3]);
+ use[1], use[2]);
break;
case 2:
- (void) fprintf(stderr, "%s\n%s\n%s\n",
- use[4], use[5], use[6]);
+ (void) fprintf(stderr, "%s\n%s\n",
+ use[3], use[4]);
break;
default:
- (void) fprintf(stderr,
- "%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
- use[0], use[1], use[2], use[3], use[4],
- use[5], use[6]);
+ (void) fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
+ use[0], use[1], use[2], use[3], use[4]);
}
}
exit(1);
@@ -352,10 +343,11 @@ main(int argc, char *argv[], char *envp[])
}
if (func == 0) { /* allocate */
- while ((c = getopt(argc, argv, "gswz:FU:")) != -1) {
+ while ((c = getopt(argc, argv, "g:swz:FU:")) != -1) {
switch (c) {
case 'g':
optflg |= TYPE;
+ device = optarg;
break;
case 's':
optflg |= SILENT;
@@ -392,21 +384,33 @@ main(int argc, char *argv[], char *envp[])
/*
* allocate(1) must be supplied with one device argument
*/
- if ((argc - optind) != 1) {
+ if (device && ((argc - optind) >= 1))
usage(func);
- } else {
+ if (device == NULL) {
+ if ((argc - optind) != 1)
+ usage(func);
device = argv[optind];
}
}
else if (func == 1) { /* deallocate */
- while ((c = getopt(argc, argv, "gswz:FI")) != -1) {
+ while ((c = getopt(argc, argv, "c:g:swz:FI")) != -1) {
switch (c) {
+ case 'c':
+ if (optflg & (TYPE | FORCE_ALL))
+ usage(func);
+ optflg |= CLASS;
+ device = optarg;
+ break;
case 'g':
- if (system_labeled)
+ if (system_labeled) {
+ if (optflg & (CLASS | FORCE_ALL))
+ usage(func);
optflg |= TYPE;
- else
+ device = optarg;
+ } else {
usage(func);
+ }
break;
case 's':
optflg |= SILENT;
@@ -428,9 +432,13 @@ main(int argc, char *argv[], char *envp[])
}
break;
case 'F':
+ if (optflg & FORCE_ALL)
+ usage(func);
optflg |= FORCE;
break;
case 'I':
+ if (optflg & (CLASS | TYPE | FORCE))
+ usage(func);
optflg |= FORCE_ALL;
break;
case '?':
@@ -439,31 +447,22 @@ main(int argc, char *argv[], char *envp[])
}
}
- if ((optflg & FORCE) && (optflg & FORCE_ALL))
- usage(func);
-
- if (system_labeled && ((optflg & FORCE_ALL) && (optflg & TYPE)))
- usage(func);
-
/*
* deallocate(1) must be supplied with one device
* argument unless the '-I' argument is supplied
*/
- if (!(optflg & FORCE_ALL)) {
- if ((argc - optind) != 1) {
+ if (device || (optflg & FORCE_ALL)) {
+ if ((argc - optind) >= 1)
usage(func);
- } else {
- device = argv[optind];
- }
- } else {
- if ((argc - optind) >= 1) {
+ } else if (device == NULL) {
+ if ((argc - optind) != 1)
usage(func);
- }
+ device = argv[optind];
}
}
else if (func == 2) { /* list_devices */
- while ((c = getopt(argc, argv, "adlnsuwz:U:")) != -1) {
+ while ((c = getopt(argc, argv, "ac:dlnsuwz:U:")) != -1) {
switch (c) {
case 'a':
if (system_labeled) {
@@ -471,39 +470,55 @@ main(int argc, char *argv[], char *envp[])
* list auths, cleaning programs,
* labels.
*/
+ if (optflg & LISTDEFS)
+ usage(func);
optflg |= LISTATTRS;
} else {
usage(func);
}
break;
+ case 'c':
+ optflg |= CLASS;
+ device = optarg;
+ break;
case 'd':
if (system_labeled) {
/*
- * list devalloc_defaults
+ * List devalloc_defaults
+ * This cannot used with anything other
+ * than -s.
*/
+ if (optflg & (LISTATTRS | CLASS |
+ LISTALL | LISTFREE | LISTALLOC |
+ WINDOWING | ZONENAME | USERID))
+ usage(func);
optflg |= LISTDEFS;
} else {
usage(func);
}
break;
case 'l':
+ if (optflg & (LISTFREE | LISTALLOC | LISTDEFS))
+ usage(func);
optflg |= LISTALL;
break;
case 'n':
+ if (optflg & (LISTALL | LISTALLOC | LISTDEFS))
+ usage(func);
optflg |= LISTFREE;
break;
case 's':
optflg |= SILENT;
break;
case 'u':
+ if (optflg & (LISTALL | LISTFREE | LISTDEFS))
+ usage(func);
optflg |= LISTALLOC;
break;
case 'w':
if (system_labeled) {
- /*
- * Private interface for use by
- * list_devices GUI
- */
+ if (optflg & LISTDEFS)
+ usage(func);
optflg |= WINDOWING;
} else {
usage(func);
@@ -511,6 +526,8 @@ main(int argc, char *argv[], char *envp[])
break;
case 'z':
if (system_labeled) {
+ if (optflg & LISTDEFS)
+ usage(func);
optflg |= ZONENAME;
zonename = optarg;
} else {
@@ -518,6 +535,8 @@ main(int argc, char *argv[], char *envp[])
}
break;
case 'U':
+ if (optflg & LISTDEFS)
+ usage(func);
optflg |= USERID;
uid = atoi(optarg);
break;
@@ -528,31 +547,26 @@ main(int argc, char *argv[], char *envp[])
}
if (system_labeled) {
- if (((optflg & LISTALL) && (optflg & LISTFREE)) ||
- ((optflg & LISTALL) && (optflg & LISTALLOC)) ||
- ((optflg & LISTFREE) && (optflg & LISTALLOC)) ||
- ((optflg & LISTDEFS) &&
- (optflg & (LISTATTRS | LISTALL | LISTFREE |
- LISTALLOC | USERID | WINDOWING | ZONENAME))) ||
- (!(optflg & (LISTALL | LISTFREE | LISTALLOC |
- LISTDEFS | WINDOWING))))
+ if (!(optflg & (LISTALL | LISTFREE | LISTALLOC |
+ LISTDEFS | WINDOWING))) {
+ if (!(optflg & CLASS))
+ usage(func);
+ }
+ } else if (!(optflg & (LISTALL | LISTFREE | LISTALLOC))) {
+ if (!(optflg & CLASS))
usage(func);
- } else if (((optflg & LISTALL) && (optflg & LISTFREE)) ||
- ((optflg & LISTALL) && (optflg & LISTALLOC)) ||
- ((optflg & LISTFREE) && (optflg & LISTALLOC)) ||
- (!(optflg & (LISTALL | LISTFREE | LISTALLOC)))) {
- usage(func);
}
/*
- * list_devices(1) takes an optional device argument
+ * list_devices(1) takes an optional device argument.
*/
- if ((argc - optind) == 1) {
- device = argv[optind];
- } else {
- if ((argc - optind) > 1) {
+ if (device && ((argc - optind) >= 1))
+ usage(func);
+ if (device == NULL) {
+ if ((argc - optind) == 1)
+ device = argv[optind];
+ else if ((argc - optind) > 1)
usage(func);
- }
}
}
diff --git a/usr/src/cmd/allocate/allocate.h b/usr/src/cmd/allocate/allocate.h
index f6a7956f85..57b47db9dc 100644
--- a/usr/src/cmd/allocate/allocate.h
+++ b/usr/src/cmd/allocate/allocate.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,27 +35,33 @@ extern "C" {
/* Option Flags */
#define LISTATTRS 0x00000001 /* -a */
-#define LISTDEFS 0x00000002 /* -d */
-#define TYPE 0x00000004 /* -g */
-#define LISTALL 0x00000008 /* -l */
-#define LISTFREE 0x00000010 /* -n */
-#define SILENT 0x00000020 /* -s */
-#define LISTALLOC 0x00000040 /* -u */
-#define WINDOWING 0x00000080 /* -w */
-#define ZONENAME 0x00000100 /* -z */
-#define BOOT 0x00000200 /* -B */
-#define FORCE 0x00000400 /* -F */
-#define FORCE_ALL 0x00000800 /* -I */
-#define USERID 0x00001000 /* -U for list_devices */
-#define USERNAME 0x00002000 /* -U for allocate */
+#define CLASS 0x00000002 /* -c */
+#define LISTDEFS 0x00000004 /* -d */
+#define TYPE 0x00000008 /* -g */
+#define LISTALL 0x00000010 /* -l */
+#define LISTFREE 0x00000020 /* -n */
+#define SILENT 0x00000040 /* -s */
+#define LISTALLOC 0x00000080 /* -u */
+#define WINDOWING 0x00000100 /* -w */
+#define ZONENAME 0x00000200 /* -z */
+#define BOOT 0x00000400 /* -B */
+#define FORCE 0x00000800 /* -F */
+#define FORCE_ALL 0x00001000 /* -I */
+#define USERID 0x00002000 /* -U for list_devices */
+#define USERNAME 0x00004000 /* -U for allocate */
-/* Misc. */
+/* Device clean program exit codes */
-#define CLEAN_MOUNT 11 /* Also defined in disk_clean.sh */
+#define DEVCLEAN_OK 0
+#define DEVCLEAN_ERROR 1
+#define DEVCLEAN_SYSERR 2
+#define DEVCLEAN_BADMOUNT 3
+#define DEVCLEAN_MOUNTOK 4
+/* Error/Exit codes */
#define ALLOCUERR 1
#define CHOWNERR 2
-#define CLEANERR 3
+/* Skip 3 to avoid conflict with DEVCLEAN_BADMOUNT */
#define CNTDEXECERR 4
#define CNTFRCERR 5
#define DACACCERR 6
@@ -78,9 +84,10 @@ extern "C" {
#define SETACLERR 23
#define UAUTHERR 24
#define ZONEERR 25
+#define CLEANERR 26
-#define ALLOC_ERR_MODE 0100
-#define ALLOC_INVALID 0700
+#define ALLOC_ERRID (uid_t)2 /* bin */
+#define ALLOC_ERR_MODE 0100
/* Functions */
extern int allocate(int optflg, uid_t uid, char *device, char *zonename);
diff --git a/usr/src/cmd/allocate/allocate3.c b/usr/src/cmd/allocate/allocate3.c
index d2879623c6..7db62883dc 100644
--- a/usr/src/cmd/allocate/allocate3.c
+++ b/usr/src/cmd/allocate/allocate3.c
@@ -76,10 +76,9 @@ extern void print_error(int, char *);
#endif /* DEBUG */
#define DEV_ERRORED(sbuf) (((sbuf).st_mode & ~S_IFMT) == ALLOC_ERR_MODE)
-#define DEV_INVALID(sbuf) (((sbuf).st_mode & ~S_IFMT) == ALLOC_INVALID)
-#define DEV_ALLOCATED(sbuf) ((sbuf).st_uid != ALLOC_UID || \
+#define DEV_ALLOCATED(sbuf) ((sbuf).st_uid != DA_UID || \
!(((sbuf).st_mode & ~S_IFMT) == DEALLOC_MODE || \
- DEV_ERRORED(sbuf) || DEV_INVALID(sbuf)))
+ DEV_ERRORED(sbuf)))
#define ALLOC_CLEAN "-A"
#define DEALLOC_CLEAN "-D"
@@ -120,7 +119,7 @@ struct dev_names {
};
static int _dev_file_name(struct state_file *, devmap_t *);
-static int lock_dev(char *);
+static int lock_dev(char *, struct stat *);
static int _check_label(devalloc_t *, char *, uid_t, int);
static int create_znode(char *, struct zone_path *, devmap_t *);
static int remove_znode(char *, devmap_t *);
@@ -271,9 +270,9 @@ print_dev_attrs(int optflag, devalloc_t *da, devmap_t *dm,
}
(void) printf("%s", KV_DELIMITER);
if (optflag & WINDOWING) {
- if (DEV_INVALID(fip->fi_stat))
- (void) printf("owner=/INVALID:%s%s", fip->fi_message,
- KV_DELIMITER);
+ if ((fip->fi_message != NULL) &&
+ (strcmp(fip->fi_message, DAOPT_CLASS) == 0))
+ (void) printf("owner=/FREE%s", KV_DELIMITER);
else if (DEV_ERRORED(fip->fi_stat))
(void) printf("owner=/ERROR%s", KV_DELIMITER);
else if (!DEV_ALLOCATED(fip->fi_stat))
@@ -315,6 +314,7 @@ _list_device(int optflag, uid_t uid, devalloc_t *da, char *zonename)
struct file_info fi;
struct state_file sf;
+ fi.fi_message = NULL;
setdmapent();
if ((dm = getdmapnam(da->da_devname)) == NULL) {
enddmapent();
@@ -323,6 +323,17 @@ _list_device(int optflag, uid_t uid, devalloc_t *da, char *zonename)
return (NODMAPERR);
}
enddmapent();
+
+ if ((optflag & CLASS) &&
+ (!(optflag & (LISTALL | LISTFREE | LISTALLOC)))) {
+ fi.fi_message = DAOPT_CLASS;
+ if (optflag & LISTATTRS)
+ print_dev_attrs(optflag, da, dm, &fi);
+ else
+ print_dev(dm);
+ goto out;
+ }
+
if (system_labeled) {
if ((error = _dev_file_name(&sf, dm)) != 0) {
freedmapent(dm);
@@ -483,6 +494,7 @@ int
list_devices(int optflag, uid_t uid, char *device, char *zonename)
{
int error = 0;
+ char *class = NULL;
da_defs_t *da_defs;
devalloc_t *da;
@@ -490,7 +502,6 @@ list_devices(int optflag, uid_t uid, char *device, char *zonename)
/*
* Private interface for GUI.
*/
- (void) lock_dev(NULL);
(void) puts(DA_DB_LOCK);
return (0);
}
@@ -539,17 +550,36 @@ list_devices(int optflag, uid_t uid, char *device, char *zonename)
return (error);
}
}
+ /*
+ * Lock the database to make sure no body writes to it while we are
+ * reading.
+ */
+ (void) lock_dev(NULL, NULL);
setdaent();
if (device) {
- /*
- * list this device
- */
- if ((da = getdanam(device)) == NULL) {
- enddaent();
- return (NODAERR);
+ if (optflag & CLASS) {
+ /*
+ * list all devices of this class.
+ */
+ while ((da = getdaent()) != NULL) {
+ class = kva_match(da->da_devopts, DAOPT_CLASS);
+ if (class && (strcmp(class, device) == 0)) {
+ (void) _list_device(optflag, uid, da,
+ zonename);
+ }
+ freedaent(da);
+ }
+ } else {
+ /*
+ * list this device
+ */
+ if ((da = getdanam(device)) == NULL) {
+ enddaent();
+ return (NODAERR);
+ }
+ error = _list_device(optflag, uid, da, zonename);
+ freedaent(da);
}
- error = _list_device(optflag, uid, da, zonename);
- freedaent(da);
} else {
/*
* list all devices
@@ -609,24 +639,63 @@ _newdac(char *file, uid_t owner, gid_t group, o_mode_t mode)
return (err);
}
+/*
+ * lock_dev -
+ * locks a section of DA_DB_LOCK.
+ * returns lock fd if successful, else -1 on error.
+ */
static int
-lock_dev(char *file)
+lock_dev(char *file, struct stat *statbuf)
{
- int lockfd = -1;
+ static int lockfd = -1;
+ int ret;
+ int count = 0;
+ int retry = 10;
+ off_t size = 0;
+ off_t offset;
+ char *lockfile;
- if ((file == NULL) || system_labeled)
- file = DA_DEV_LOCK;
- dprintf("locking %s\n", file);
- if ((lockfd = open(file, O_RDWR | O_CREAT, 0600)) == -1) {
+ if (system_labeled)
+ lockfile = DA_DB_LOCK;
+ else
+ lockfile = file;
+
+ if (statbuf) {
+ offset = statbuf->st_rdev;
+ dprintf("locking %s\n", file);
+ } else {
+ offset = 0;
+ dprintf("locking %s\n", lockfile);
+ }
+ if ((lockfd == -1) &&
+ (lockfd = open(lockfile, O_RDWR | O_CREAT, 0600)) == -1) {
dperror("lock_dev: cannot open lock file");
- return (DEVLKERR);
+ return (-1);
}
- if (lockf(lockfd, F_TLOCK, 0) == -1) {
- dperror("lock_dev: cannot set lock");
- return (DEVLKERR);
+ if (system_labeled) {
+ (void) _newdac(lockfile, DA_UID, DA_GID, 0600);
+ if (lseek(lockfd, offset, SEEK_SET) == -1) {
+ dperror("lock_dev: cannot position lock file");
+ return (-1);
+ }
+ size = 1;
+ }
+ errno = 0;
+ while (retry) {
+ count++;
+ ret = lockf(lockfd, F_TLOCK, size);
+ if (ret == 0)
+ return (lockfd);
+ if ((errno != EACCES) && (errno != EAGAIN)) {
+ dperror("lock_dev: cannot set lock");
+ return (-1);
+ }
+ retry--;
+ (void) sleep(count);
+ errno = 0;
}
- return (0);
+ return (-1);
}
int
@@ -644,7 +713,7 @@ mk_alloc(devmap_t *list, uid_t uid, struct zone_path *zpath)
for (; *file != NULL; file++) {
dprintf("Allocating %s\n", *file);
if ((error = _newdac(*file, uid, gid, mode)) != 0) {
- (void) _newdac(*file, ALLOC_ERRID, ALLOC_GID,
+ (void) _newdac(*file, ALLOC_ERRID, DA_GID,
ALLOC_ERR_MODE);
break;
}
@@ -659,7 +728,7 @@ mk_alloc(devmap_t *list, uid_t uid, struct zone_path *zpath)
if ((error = _newdac(zpath->path[i], uid, gid,
mode)) != 0) {
(void) _newdac(zpath->path[i], ALLOC_ERRID,
- ALLOC_GID, ALLOC_ERR_MODE);
+ DA_GID, ALLOC_ERR_MODE);
break;
}
}
@@ -791,7 +860,7 @@ mk_unalloc(int optflag, devmap_t *list)
dperror("");
error = CNTFRCERR;
}
- status = _newdac(*file, ALLOC_UID, ALLOC_GID, DEALLOC_MODE);
+ status = _newdac(*file, DA_UID, DA_GID, DEALLOC_MODE);
if (error == 0)
error = status;
@@ -812,7 +881,7 @@ mk_error(devmap_t *list)
return (NODMAPERR);
for (; *file != NULL; file++) {
dprintf("Putting %s in error state\n", *file);
- status = _newdac(*file, ALLOC_ERRID, ALLOC_GID, ALLOC_ERR_MODE);
+ status = _newdac(*file, ALLOC_ERRID, DA_GID, ALLOC_ERR_MODE);
}
return (status);
@@ -928,7 +997,7 @@ exec_clean(int optflag, char *devname, char *path, uid_t uid, char *zonename,
int
_deallocate_dev(int optflag, devalloc_t *da, devmap_t *dm_in, uid_t uid,
- char *zonename)
+ char *zonename, int *lock_fd)
{
int bytes = 0;
int error = 0;
@@ -1021,11 +1090,15 @@ _deallocate_dev(int optflag, devalloc_t *da, devmap_t *dm_in, uid_t uid,
}
}
/* All checks passed, time to lock and deallocate */
- if ((error = lock_dev(fname)) != 0)
+ if ((*lock_fd = lock_dev(fname, &stat_buf)) == -1) {
+ error = DEVLKERR;
goto out;
+ }
if (system_labeled) {
devzone = kva_match(da->da_devopts, DAOPT_ZONE);
- if (devzone && (strcmp(devzone, GLOBAL_ZONENAME) != 0)) {
+ if (devzone == NULL) {
+ devzone = GLOBAL_ZONENAME;
+ } else if (strcmp(devzone, GLOBAL_ZONENAME) != 0) {
if ((remove_znode(devzone, dm) != 0) &&
!(optflag & FORCE)) {
error = ZONEERR;
@@ -1038,9 +1111,9 @@ _deallocate_dev(int optflag, devalloc_t *da, devmap_t *dm_in, uid_t uid,
goto out;
}
if (system_labeled == 0) {
- if ((error = _newdac(fname, ALLOC_UID, ALLOC_GID,
+ if ((error = _newdac(fname, DA_UID, DA_GID,
DEALLOC_MODE)) != 0) {
- (void) _newdac(file_name, ALLOC_UID, ALLOC_GID,
+ (void) _newdac(file_name, DA_UID, DA_GID,
ALLOC_ERR_MODE);
goto out;
}
@@ -1068,7 +1141,8 @@ out:
}
int
-_allocate_dev(int optflag, uid_t uid, devalloc_t *da, char *zonename)
+_allocate_dev(int optflag, uid_t uid, devalloc_t *da, char *zonename,
+ int *lock_fd)
{
int i;
int bytes = 0;
@@ -1159,7 +1233,7 @@ _allocate_dev(int optflag, uid_t uid, devalloc_t *da, char *zonename)
else
dealloc_optflag = FORCE;
if (_deallocate_dev(dealloc_optflag, da, dm, uid,
- zonename)) {
+ zonename, lock_fd)) {
dprintf("Couldn't force deallocate device %s\n",
da->da_devname);
error = CNTFRCERR;
@@ -1174,8 +1248,10 @@ _allocate_dev(int optflag, uid_t uid, devalloc_t *da, char *zonename)
}
}
/* All checks passed, time to lock and allocate */
- if ((error = lock_dev(fname)) != 0)
+ if ((*lock_fd = lock_dev(fname, &stat_buf)) == -1) {
+ error = DEVLKERR;
goto out;
+ }
if (system_labeled) {
/*
* Run the cleaning program; it also mounts allocated
@@ -1183,17 +1259,33 @@ _allocate_dev(int optflag, uid_t uid, devalloc_t *da, char *zonename)
*/
error = exec_clean(optflag, da->da_devname, da->da_devexec, uid,
zonename, ALLOC_CLEAN);
- if ((error != 0) && (error != CLEAN_MOUNT)) {
- error = CLEANERR;
- (void) mk_error(dm);
- goto out;
+ if (error != DEVCLEAN_OK) {
+ switch (error) {
+ case DEVCLEAN_ERROR:
+ case DEVCLEAN_SYSERR:
+ dprintf("allocate: "
+ "Error in device clean program %s\n",
+ da->da_devexec);
+ error = CLEANERR;
+ (void) mk_error(dm);
+ goto out;
+ case DEVCLEAN_BADMOUNT:
+ dprintf("allocate: Failed to mount device %s\n",
+ da->da_devexec);
+ goto out;
+ case DEVCLEAN_MOUNTOK:
+ break;
+ default:
+ error = 0;
+ goto out;
+ }
}
/*
* If not mounted, create zonelinks, if this is not the
* global zone.
*/
if ((strcmp(zonename, GLOBAL_ZONENAME) != 0) &&
- (error != CLEAN_MOUNT)) {
+ (error != DEVCLEAN_MOUNTOK)) {
if (create_znode(zonename, &zpath, dm) != 0) {
error = ZONEERR;
goto out;
@@ -1211,7 +1303,7 @@ _allocate_dev(int optflag, uid_t uid, devalloc_t *da, char *zonename)
if (system_labeled == 0) {
if ((error = _newdac(file_name, uid, getgid(),
ALLOC_MODE)) != 0) {
- (void) _newdac(file_name, ALLOC_UID, ALLOC_GID,
+ (void) _newdac(file_name, DA_UID, DA_GID,
ALLOC_ERR_MODE);
goto out;
}
@@ -1257,6 +1349,7 @@ allocate(int optflag, uid_t uid, char *device, char *zonename)
{
int count = 0;
int error = 0;
+ int lock_fd = -1;
devalloc_t *da;
struct dev_names dnms;
@@ -1277,7 +1370,8 @@ allocate(int optflag, uid_t uid, char *device, char *zonename)
continue;
}
dprintf("trying to allocate %s\n", da->da_devname);
- error = _allocate_dev(optflag, uid, da, zonename);
+ error = _allocate_dev(optflag, uid, da, zonename,
+ &lock_fd);
if (system_labeled && (error == 0)) {
/*
* we need to record in device_allocate the
@@ -1302,7 +1396,7 @@ allocate(int optflag, uid_t uid, char *device, char *zonename)
return (LOGINDEVPERMERR);
}
dprintf("trying to allocate %s\n", da->da_devname);
- error = _allocate_dev(optflag, uid, da, zonename);
+ error = _allocate_dev(optflag, uid, da, zonename, &lock_fd);
/*
* we need to record in device_allocate the label (zone name)
* at which this device is being allocated. store this device
@@ -1311,8 +1405,12 @@ allocate(int optflag, uid_t uid, char *device, char *zonename)
if (system_labeled && (error == 0))
_store_devnames(&count, &dnms, zonename, da, 0);
freedaent(da);
+ if (error == DEVCLEAN_BADMOUNT)
+ error = 0;
}
enddaent();
+ if (lock_fd != -1)
+ (void) close(lock_fd);
/*
* add to device_allocate labels (zone names) for the devices we
* allocated.
@@ -1329,6 +1427,8 @@ deallocate(int optflag, uid_t uid, char *device, char *zonename)
{
int count = 0;
int error = 0;
+ int lock_fd = -1;
+ char *class = NULL;
devalloc_t *da;
struct dev_names dnms;
@@ -1352,7 +1452,7 @@ deallocate(int optflag, uid_t uid, char *device, char *zonename)
}
dprintf("trying to deallocate %s\n", da->da_devname);
error = _deallocate_dev(optflag, da, NULL, uid,
- zonename);
+ zonename, &lock_fd);
if (system_labeled && (error == 0)) {
/*
* we need to remove this device's allocation
@@ -1364,7 +1464,7 @@ deallocate(int optflag, uid_t uid, char *device, char *zonename)
freedaent(da);
error = 0;
}
- } else if (system_labeled && optflag & TYPE) {
+ } else if (system_labeled && (optflag & TYPE)) {
/*
* deallocate all devices of this type
*/
@@ -1375,7 +1475,7 @@ deallocate(int optflag, uid_t uid, char *device, char *zonename)
}
dprintf("trying to deallocate %s\n", da->da_devname);
error = _deallocate_dev(optflag, da, NULL, uid,
- zonename);
+ zonename, &lock_fd);
if (error == 0) {
/*
* we need to remove this device's allocation
@@ -1387,6 +1487,31 @@ deallocate(int optflag, uid_t uid, char *device, char *zonename)
freedaent(da);
error = 0;
}
+ } else if (system_labeled && (optflag & CLASS)) {
+ /*
+ * deallocate all devices of this class (for sunray)
+ */
+ while ((da = getdaent()) != NULL) {
+ class = kva_match(da->da_devopts, DAOPT_CLASS);
+ if (class && (strcmp(class, device) == 0)) {
+ dprintf("trying to deallocate %s\n",
+ da->da_devname);
+ error = _deallocate_dev(optflag, da, NULL, uid,
+ zonename, &lock_fd);
+ if (error == 0) {
+ /*
+ * we need to remove this device's
+ * allocation label (zone name) from
+ * device_allocate. store this device
+ * name.
+ */
+ _store_devnames(&count, &dnms, zonename,
+ da, 0);
+ }
+ error = 0;
+ }
+ freedaent(da);
+ }
} else if (!(optflag & TYPE)) {
/*
* deallocate this device
@@ -1400,7 +1525,8 @@ deallocate(int optflag, uid_t uid, char *device, char *zonename)
return (LOGINDEVPERMERR);
}
dprintf("trying to deallocate %s\n", da->da_devname);
- error = _deallocate_dev(optflag, da, NULL, uid, zonename);
+ error = _deallocate_dev(optflag, da, NULL, uid, zonename,
+ &lock_fd);
if (system_labeled && (error == 0)) {
/*
* we need to remove this device's allocation label
@@ -1410,8 +1536,12 @@ deallocate(int optflag, uid_t uid, char *device, char *zonename)
_store_devnames(&count, &dnms, zonename, da, 0);
}
freedaent(da);
+ if (error == DEVCLEAN_BADMOUNT)
+ error = 0;
}
enddaent();
+ if (lock_fd != -1)
+ (void) close(lock_fd);
/*
* remove from device_allocate labels (zone names) for the devices we
* deallocated.
@@ -1607,7 +1737,7 @@ create_znode(char *zonename, struct zone_path *zpath, devmap_t *list)
(void) strcpy(dstlinkdir, "/dev");
(void) strncat(dstlinkdir, linkdir, MAXPATHLEN);
(void) snprintf(srclinkdir, MAXPATHLEN, "%s/root%s",
- zonepath, tmpfile);
+ zonepath, tmpfile);
(void) symlink(dstlinkdir, srclinkdir);
*p = '/';
(void) strncat(dstlinkdir, p, MAXPATHLEN);
diff --git a/usr/src/lib/libbsm/common/devalloc.c b/usr/src/lib/libbsm/common/devalloc.c
index 08db0f0325..e39b57fa23 100644
--- a/usr/src/lib/libbsm/common/devalloc.c
+++ b/usr/src/lib/libbsm/common/devalloc.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -849,6 +849,11 @@ int
_da_lock_devdb(char *rootdir)
{
int lockfd = -1;
+ int ret;
+ int count = 0;
+ int retry = 10;
+ int retry_sleep;
+ uint_t seed;
char *lockfile;
char path[MAXPATHLEN];
int size = sizeof (path);
@@ -873,14 +878,27 @@ _da_lock_devdb(char *rootdir)
(void) close(lockfd);
return (-1);
}
- if (lockf(lockfd, F_TLOCK, 0) == -1) {
- /* cannot set lock */
- (void) close(lockfd);
- return (-1);
+ errno = 0;
+ while (retry > 0) {
+ count++;
+ seed = (uint_t)gethrtime();
+ ret = lockf(lockfd, F_TLOCK, 0);
+ if (ret == 0) {
+ (void) utime(lockfile, NULL);
+ return (lockfd);
+ }
+ if ((errno != EACCES) && (errno != EAGAIN)) {
+ /* cannot set lock */
+ (void) close(lockfd);
+ return (-1);
+ }
+ retry--;
+ retry_sleep = rand_r(&seed)/((RAND_MAX + 2)/3) + count;
+ (void) sleep(retry_sleep);
+ errno = 0;
}
- (void) utime(lockfile, NULL);
- return (lockfd);
+ return (-1);
}
/*
@@ -1160,10 +1178,10 @@ da_update_device(da_args *dargs)
int tafd = -1, tmfd = -1;
int lockfd = -1;
char *rootdir = NULL;
- char *apathp = NULL, *mpathp = NULL, *dapathp = NULL,
- *dmpathp = NULL;
- char apath[MAXPATHLEN], mpath[MAXPATHLEN],
- dapath[MAXPATHLEN], dmpath[MAXPATHLEN];
+ char *apathp = NULL, *mpathp = NULL;
+ char *dapathp = NULL, *dmpathp = NULL;
+ char apath[MAXPATHLEN], mpath[MAXPATHLEN];
+ char dapath[MAXPATHLEN], dmpath[MAXPATHLEN];
FILE *tafp = NULL, *tmfp = NULL, *dafp = NULL;
struct stat dastat;
devinfo_t *devinfo;
@@ -1620,12 +1638,11 @@ da_remove_list(devlist_t *dlist, char *link, int type, char *devname, int size)
if (plen == 0) {
slen =
snprintf(current->devinfo.devlist,
- nlen, "%s", lname);
+ nlen, "%s", lname);
} else {
slen =
snprintf(current->devinfo.devlist +
- plen, nlen - plen, " %s",
- lname);
+ plen, nlen - plen, " %s", lname);
}
plen = plen + slen + 1;
}
diff --git a/usr/src/lib/libbsm/common/devalloc.h b/usr/src/lib/libbsm/common/devalloc.h
index 7952a302f5..12ec8732d2 100644
--- a/usr/src/lib/libbsm/common/devalloc.h
+++ b/usr/src/lib/libbsm/common/devalloc.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -44,6 +44,9 @@ extern "C" {
#define DA_UID (uid_t)0 /* root */
#define DA_GID (gid_t)3 /* sys */
+#define ALLOC_MODE 0600
+#define DEALLOC_MODE 0000
+
#define LOGINDEVPERM "/etc/logindevperm"
#define DA_DB_LOCK "/etc/security/.da_db_lock"
#define DA_DEV_LOCK "/etc/security/.da_dev_lock"
@@ -79,12 +82,6 @@ extern "C" {
#define DA_ANYUSER "*"
#define DA_NOUSER "@"
-#define ALLOC_UID (uid_t)0 /* root */
-#define ALLOC_GID (gid_t)3 /* sys */
-#define ALLOC_ERRID (uid_t)2 /* bin */
-#define ALLOC_MODE 0600
-#define DEALLOC_MODE 0000
-
#define DA_SILENT 0x00000001
#define DA_VERBOSE 0x00000002
#define DA_ADD 0x00000004
diff --git a/usr/src/lib/libbsm/common/devices.h b/usr/src/lib/libbsm/common/devices.h
index 04a3edceea..7b413eaca8 100644
--- a/usr/src/lib/libbsm/common/devices.h
+++ b/usr/src/lib/libbsm/common/devices.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,17 +35,20 @@ extern "C" {
#include <stdio.h>
#include <secdb.h>
-/*
- * These are unsupported, SUN-private interfaces.
- */
#define DAOPT_AUTHS "auths"
+#define DAOPT_CLASS "class"
#define DAOPT_CSCRIPT "cleanscript"
#define DAOPT_MINLABEL "minlabel"
#define DAOPT_MAXLABEL "maxlabel"
+#define DAOPT_XDISPLAY "xdpy"
#define DAOPT_ZONE "zone"
#define DA_RESERVED "reserved"
+/*
+ * These are unsupported, SUN-private interfaces.
+ */
+
typedef struct {
char *da_devname;
char *da_devtype;