diff options
author | aj <none@none> | 2007-06-21 10:39:47 -0700 |
---|---|---|
committer | aj <none@none> | 2007-06-21 10:39:47 -0700 |
commit | 10ddde3aee60d88fa580028fcf7642a87e80a2c6 (patch) | |
tree | d7d477bfb38c88169915ac216139ad9f3a669179 /usr/src | |
parent | f9aa3e1e897e74b50458e34d6c88abb9a7a08aed (diff) | |
download | illumos-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.c | 188 | ||||
-rw-r--r-- | usr/src/cmd/allocate/allocate.h | 45 | ||||
-rw-r--r-- | usr/src/cmd/allocate/allocate3.c | 234 | ||||
-rw-r--r-- | usr/src/lib/libbsm/common/devalloc.c | 45 | ||||
-rw-r--r-- | usr/src/lib/libbsm/common/devalloc.h | 11 | ||||
-rw-r--r-- | usr/src/lib/libbsm/common/devices.h | 11 |
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; |