diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/devfsadm/devfsadm.c | 25 | ||||
-rw-r--r-- | usr/src/cmd/devfsadm/devfsadm.h | 3 | ||||
-rw-r--r-- | usr/src/cmd/devfsadm/disk_link.c | 29 | ||||
-rw-r--r-- | usr/src/cmd/truss/print.c | 1 | ||||
-rw-r--r-- | usr/src/lib/libdevinfo/devinfo_finddev.c | 61 | ||||
-rw-r--r-- | usr/src/lib/libdevinfo/libdevinfo.h | 3 | ||||
-rw-r--r-- | usr/src/lib/libdevinfo/mapfile-vers | 5 | ||||
-rw-r--r-- | usr/src/uts/common/fs/dev/sdev_subr.c | 21 | ||||
-rw-r--r-- | usr/src/uts/common/fs/devfs/devfs_vnops.c | 37 | ||||
-rw-r--r-- | usr/src/uts/common/os/devcfg.c | 17 | ||||
-rw-r--r-- | usr/src/uts/common/os/modctl.c | 45 | ||||
-rw-r--r-- | usr/src/uts/common/sys/fs/sdev_impl.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/sys/modctl.h | 3 |
13 files changed, 176 insertions, 76 deletions
diff --git a/usr/src/cmd/devfsadm/devfsadm.c b/usr/src/cmd/devfsadm/devfsadm.c index c7ccb7826c..a06fac3e02 100644 --- a/usr/src/cmd/devfsadm/devfsadm.c +++ b/usr/src/cmd/devfsadm/devfsadm.c @@ -3153,9 +3153,6 @@ rm_parent_dir_if_empty(char *pathname) { char *ptr, path[PATH_MAX + 1]; char *fcn = "rm_parent_dir_if_empty: "; - finddevhdl_t fhandle; - const char *f; - int rv; vprint(REMOVE_MID, "%schecking %s if empty\n", fcn, pathname); @@ -3173,17 +3170,8 @@ rm_parent_dir_if_empty(char *pathname) *ptr = '\0'; - if ((rv = finddev_readdir(path, &fhandle)) != 0) { - err_print(OPENDIR_FAILED, path, strerror(rv)); - return; - } - - /* - * An empty pathlist implies an empty directory - */ - f = finddev_next(fhandle); - finddev_close(fhandle); - if (f == NULL) { + if (finddev_emptydir(path)) { + /* directory is empty */ if (s_rmdir(path) == 0) { vprint(REMOVE_MID, "%sremoving empty dir %s\n", fcn, path); @@ -8970,6 +8958,15 @@ bad_re: } /* + * Return 1 if we have reserved links. + */ +int +devfsadm_have_reserved() +{ + return (enumerate_reserved ? 1 : 0); +} + +/* * This functions errs on the side of caution. If there is any error * we assume that the devlink is *not* reserved */ diff --git a/usr/src/cmd/devfsadm/devfsadm.h b/usr/src/cmd/devfsadm/devfsadm.h index c77341fd6c..5d540ce78d 100644 --- a/usr/src/cmd/devfsadm/devfsadm.h +++ b/usr/src/cmd/devfsadm/devfsadm.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -250,6 +250,7 @@ int devfsadm_read_link(char *link, char **devfs_path); char *s_strdup(const char *ptr); /* Private interface between reserve subsystm and disks link generator */ +int devfsadm_have_reserved(void); int devfsadm_is_reserved(devlink_re_t re_array[], char *devlink); int devfsadm_reserve_id_cache(devlink_re_t re_array[], enumerate_file_t *head); diff --git a/usr/src/cmd/devfsadm/disk_link.c b/usr/src/cmd/devfsadm/disk_link.c index 05504ba2bb..bc0ea1fab4 100644 --- a/usr/src/cmd/devfsadm/disk_link.c +++ b/usr/src/cmd/devfsadm/disk_link.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -150,16 +150,14 @@ disk_callback_wwn(di_minor_t minor, di_node_t node) int targ; int *intp; - if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, - "target", &intp) <= 0) { + if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "target", &intp) <= 0) { return (DEVFSADM_CONTINUE); } targ = *intp; - if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, - "lun", &intp) <= 0) { - lun = 0; + if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "lun", &intp) <= 0) { + lun = 0; } else { - lun = *intp; + lun = *intp; } (void) sprintf(disk, "t%dd%d", targ, lun); @@ -181,10 +179,10 @@ disk_callback_fabric(di_minor_t minor, di_node_t node) if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "client-guid", (char **)&wwn) > 0) { - if (strlcpy((char *)ascii_wwn, (char *)wwn, sizeof (ascii_wwn)) - >= sizeof (ascii_wwn)) { + if (strlcpy((char *)ascii_wwn, (char *)wwn, + sizeof (ascii_wwn)) >= sizeof (ascii_wwn)) { devfsadm_errprint("SUNW_disk_link: GUID too long:%d", - strlen((char *)wwn)); + strlen((char *)wwn)); return (DEVFSADM_CONTINUE); } lun = 0; @@ -468,7 +466,6 @@ reserved_links_exist(di_node_t node, di_minor_t minor, int nflags) char *s; char l[PATH_MAX]; int switch_link = 0; - struct stat sb; char *mn = di_minor_name(minor); if (dvlink_cache == NULL || mn == NULL) { @@ -476,10 +473,8 @@ reserved_links_exist(di_node_t node, di_minor_t minor, int nflags) return (DEVFSADM_FAILURE); } - if (stat(ENUMERATE_RESERVED, &sb) == -1) { - devfsadm_print(disk_mid, "%s: No reserved file: %s. Will " - "not bypass new link creation\n", - modname, ENUMERATE_RESERVED); + if (!devfsadm_have_reserved()) { + devfsadm_print(disk_mid, "%s: No reserved links\n", modname); return (DEVFSADM_FAILURE); } @@ -512,8 +507,8 @@ reserved_links_exist(di_node_t node, di_minor_t minor, int nflags) return (DEVFSADM_FAILURE); } (void) snprintf(s+1, sizeof (phys_path) - (s + 1 - phys_path), - "%s%s", *mn == *(MN_SMI) ? MN_EFI : MN_SMI, - strstr(s, ",raw") ? ",raw" : ""); + "%s%s", *mn == *(MN_SMI) ? MN_EFI : MN_SMI, + strstr(s, ",raw") ? ",raw" : ""); (void) di_devlink_cache_walk(dvlink_cache, DISK_LINK_RE, phys_path, DI_PRIMARY_LINK, &head, dvlink_cb); } diff --git a/usr/src/cmd/truss/print.c b/usr/src/cmd/truss/print.c index 8e9225493d..6dc5efc8fd 100644 --- a/usr/src/cmd/truss/print.c +++ b/usr/src/cmd/truss/print.c @@ -1113,6 +1113,7 @@ prt_mod(private_t *pri, int raw, long val) /* print modctl() code */ case MODREMDRVCLEANUP: s = "MODREMDRVCLEANUP"; break; case MODDEVEXISTS: s = "MODDEVEXISTS"; break; case MODDEVREADDIR: s = "MODDEVREADDIR"; break; + case MODDEVEMPTYDIR: s = "MODDEVEMPTYDIR"; break; case MODDEVNAME: s = "MODDEVNAME"; break; case MODGETDEVFSPATH_MI_LEN: s = "MODGETDEVFSPATH_MI_LEN"; break; diff --git a/usr/src/lib/libdevinfo/devinfo_finddev.c b/usr/src/lib/libdevinfo/devinfo_finddev.c index 3dfb4467c9..eea252358f 100644 --- a/usr/src/lib/libdevinfo/devinfo_finddev.c +++ b/usr/src/lib/libdevinfo/devinfo_finddev.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -256,6 +256,65 @@ finddev_readdir(const char *path, finddevhdl_t *handlep) return (finddev_readdir_alt(path, handlep)); } +/* + * Return true if a directory is empty + * Use the standard library readdir to determine if a directory is + * empty. + */ +static int +finddev_emptydir_alt(const char *path) +{ + DIR *dir; + struct dirent *dp; + + if ((dir = opendir(path)) == NULL) + return (ENOENT); + + while ((dp = readdir(dir)) != NULL) { + if ((strcmp(dp->d_name, ".") == 0) || + (strcmp(dp->d_name, "..") == 0)) + continue; + (void) closedir(dir); + return (0); /* not empty */ + } + (void) closedir(dir); + return (1); /* empty */ +} + +/* + * Use of the dev filesystem's private readdir does (not trigger + * the implicit device reconfiguration) to determine if a directory + * is empty. + * + * Note: only useable with paths mounted on an instance of the + * dev filesystem. + * + * Does not return the . and .. entries. + * Empty directories are returned as an zero-length list. + * ENOENT is returned as a NULL list pointer. + */ +static int +finddev_emptydir_devfs(const char *path) +{ + int rv; + int empty; + + rv = modctl(MODDEVEMPTYDIR, path, strlen(path), &empty); + if (rv == 0) { + return (empty); + } + return (0); +} + +int +finddev_emptydir(const char *path) +{ + if (GLOBAL_DEV_PATH(path)) { + return (finddev_emptydir_devfs(path)); + } + return (finddev_emptydir_alt(path)); +} + void finddev_close(finddevhdl_t arg) { diff --git a/usr/src/lib/libdevinfo/libdevinfo.h b/usr/src/lib/libdevinfo/libdevinfo.h index 7672b83a7c..2314ee1c9c 100644 --- a/usr/src/lib/libdevinfo/libdevinfo.h +++ b/usr/src/lib/libdevinfo/libdevinfo.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -473,6 +473,7 @@ typedef struct __finddevhdl *finddevhdl_t; extern int device_exists(const char *); extern int finddev_readdir(const char *, finddevhdl_t *); +extern int finddev_emptydir(const char *); extern void finddev_close(finddevhdl_t); extern const char *finddev_next(finddevhdl_t); diff --git a/usr/src/lib/libdevinfo/mapfile-vers b/usr/src/lib/libdevinfo/mapfile-vers index 90afb14386..aa49121009 100644 --- a/usr/src/lib/libdevinfo/mapfile-vers +++ b/usr/src/lib/libdevinfo/mapfile-vers @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -207,9 +207,10 @@ SUNWprivate_1.1 { di_prom_prop_lookup_slot_names; di_prop_find; device_exists; - finddev_readdir; finddev_close; + finddev_emptydir; finddev_next; + finddev_readdir; di_flags; di_retire_device; di_unretire_device; diff --git a/usr/src/uts/common/fs/dev/sdev_subr.c b/usr/src/uts/common/fs/dev/sdev_subr.c index 0159fc568e..77f47f4535 100644 --- a/usr/src/uts/common/fs/dev/sdev_subr.c +++ b/usr/src/uts/common/fs/dev/sdev_subr.c @@ -521,7 +521,7 @@ sdev_get_moduleops(struct sdev_node *dv) if (map->dir_invalid) { if (map->dir_module && map->dir_newmodule && (strcmp(map->dir_module, - map->dir_newmodule) == 0)) { + map->dir_newmodule) == 0)) { load = 0; } sdev_replace_nsmap(map, map->dir_newmodule, @@ -1230,7 +1230,7 @@ sdev_rnmnode(struct sdev_node *oddv, struct sdev_node *odv, (void) sdev_dirdelete(nddv, *ndvp); *ndvp = NULL; error = VOP_RMDIR(nddv->sdev_attrvp, nnm, - nddv->sdev_attrvp, cred, NULL, 0); + nddv->sdev_attrvp, cred, NULL, 0); if (error) goto err_out; } else { @@ -1254,7 +1254,7 @@ sdev_rnmnode(struct sdev_node *oddv, struct sdev_node *odv, error = VOP_REMOVE(nddv->sdev_attrvp, nnm, cred, NULL, 0); if (error) - goto err_out; + goto err_out; } } } @@ -1811,7 +1811,7 @@ sdev_call_devfsadmd(struct sdev_node *ddv, struct sdev_node *dv, char *nm) error = 0; } else if (!DEVNAME_DEVFSADM_HAS_RUN(devfsadm_state)) { sdcmn_err6(("lookup %s/%s starting devfsadm, 0x%x\n", - ddv->sdev_name, nm, devfsadm_state)); + ddv->sdev_name, nm, devfsadm_state)); sdev_devfsadmd_thread(ddv, dv, kcred); mutex_enter(&dv->sdev_lookup_lock); @@ -3026,7 +3026,7 @@ sdev_modctl_lookup(const char *path, vnode_t **r_vp) int sdev_modctl_readdir(const char *dir, char ***dirlistp, - int *npathsp, int *npathsp_alloc) + int *npathsp, int *npathsp_alloc, int checking_empty) { char **pathlist = NULL; char **newlist = NULL; @@ -3081,18 +3081,17 @@ sdev_modctl_readdir(const char *dir, char ***dirlistp, break; for (dp = dbuf; ((intptr_t)dp < (intptr_t)dbuf + dbuflen); - dp = (dirent64_t *)((intptr_t)dp + dp->d_reclen)) { + dp = (dirent64_t *)((intptr_t)dp + dp->d_reclen)) { nm = dp->d_name; if (strcmp(nm, ".") == 0 || strcmp(nm, "..") == 0) continue; - if (npaths == npaths_alloc) { npaths_alloc += 64; newlist = (char **) kmem_zalloc((npaths_alloc + 1) * - sizeof (char *), KM_SLEEP); + sizeof (char *), KM_SLEEP); if (pathlist) { bcopy(pathlist, newlist, npaths * sizeof (char *)); @@ -3106,6 +3105,12 @@ sdev_modctl_readdir(const char *dir, char ***dirlistp, bcopy(nm, s, n); pathlist[npaths++] = s; sdcmn_err11((" %s/%s\n", dir, s)); + + /* if checking empty, one entry is as good as many */ + if (checking_empty) { + eof = 1; + break; + } } } diff --git a/usr/src/uts/common/fs/devfs/devfs_vnops.c b/usr/src/uts/common/fs/devfs/devfs_vnops.c index d459929000..5361b7e00d 100644 --- a/usr/src/uts/common/fs/devfs/devfs_vnops.c +++ b/usr/src/uts/common/fs/devfs/devfs_vnops.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -180,6 +180,7 @@ devfs_getattr(struct vnode *vp, struct vattr *vap, int flags, struct cred *cr, return (ENOENT); } + rw_enter(&dv->dv_contents, RW_READER); if (dv->dv_attr) { /* * obtain from the memory version of attribute. @@ -195,6 +196,7 @@ devfs_getattr(struct vnode *vp, struct vattr *vap, int flags, struct cred *cr, dsysdebug(error, ("vop_getattr %s %d\n", dv->dv_name, error)); dv_vattr_merge(dv, vap); } + rw_exit(&dv->dv_contents); /* * Restrict the permissions of the node fronting the console @@ -241,7 +243,7 @@ devfs_setattr_dir( again: if (dv->dv_attr) { error = secpolicy_vnode_setattr(cr, vp, vap, - dv->dv_attr, flags, devfs_unlocked_access, dv); + dv->dv_attr, flags, devfs_unlocked_access, dv); if (error) goto out; @@ -281,9 +283,9 @@ again: if (dv->dv_attr) { if (vap->va_mask & (AT_MODE|AT_UID|AT_GID|AT_ATIME|AT_MTIME)) { /* Set the attributes */ error = VOP_SETATTR(dv->dv_attrvp, - vap, flags, cr, NULL); + vap, flags, cr, NULL); dsysdebug(error, - ("vop_setattr %s %d\n", dv->dv_name, error)); + ("vop_setattr %s %d\n", dv->dv_name, error)); /* * Some file systems may return EROFS for a setattr @@ -459,8 +461,7 @@ devfs_setattr( ASSERT(vp->v_type != VDIR); *vattrp = dv_vattr_file; error = VOP_GETATTR(dv->dv_attrvp, vattrp, 0, cr, ct); - dsysdebug(error, ("vop_getattr %s %d\n", - dv->dv_name, error)); + dsysdebug(error, ("vop_getattr %s %d\n", dv->dv_name, error)); if (error) goto out; dv->dv_attr = vattrp; @@ -469,10 +470,10 @@ devfs_setattr( } error = secpolicy_vnode_setattr(cr, vp, vap, dv->dv_attr, - flags, devfs_unlocked_access, dv); + flags, devfs_unlocked_access, dv); if (error) { dsysdebug(error, ("devfs_setattr %s secpolicy error %d\n", - dv->dv_name, error)); + dv->dv_name, error)); goto out; } @@ -530,13 +531,13 @@ devfs_setattr( } else { if (mask & AT_MODE) dcmn_err5(("%s persisting mode 0%o\n", - dv->dv_name, vap->va_mode)); + dv->dv_name, vap->va_mode)); if (mask & AT_UID) dcmn_err5(("%s persisting uid %d\n", - dv->dv_name, vap->va_uid)); + dv->dv_name, vap->va_uid)); if (mask & AT_GID) dcmn_err5(("%s persisting gid %d\n", - dv->dv_name, vap->va_gid)); + dv->dv_name, vap->va_gid)); if (dv->dv_attrvp == NULL) { dvp = DVTOV(dv->dv_dotdot); @@ -734,16 +735,14 @@ devfs_access(struct vnode *vp, int mode, int flags, struct cred *cr, return (EACCES); } + rw_enter(&dv->dv_contents, RW_READER); if (dv->dv_attr && ((dv->dv_flags & DV_ACL) == 0)) { - rw_enter(&dv->dv_contents, RW_READER); - if (dv->dv_attr) { - res = devfs_unlocked_access(dv, mode, cr); - rw_exit(&dv->dv_contents); - return (res); - } - rw_exit(&dv->dv_contents); + res = devfs_unlocked_access(dv, mode, cr); + } else { + res = VOP_ACCESS(dv->dv_attrvp, mode, flags, cr, ct); } - return (VOP_ACCESS(dv->dv_attrvp, mode, flags, cr, ct)); + rw_exit(&dv->dv_contents); + return (res); } /* diff --git a/usr/src/uts/common/os/devcfg.c b/usr/src/uts/common/os/devcfg.c index bfc829934f..ff837895fb 100644 --- a/usr/src/uts/common/os/devcfg.c +++ b/usr/src/uts/common/os/devcfg.c @@ -7314,7 +7314,7 @@ i_ddi_di_cache_free(struct di_cache *cache) void i_ddi_di_cache_invalidate(int kmflag) { - uint_t flag; + int cache_valid; if (!modrootloaded || !i_ddi_io_initialized()) { if (di_cache_debug) @@ -7322,16 +7322,15 @@ i_ddi_di_cache_invalidate(int kmflag) return; } - /* - * Invalidate the in-core cache and - * increment devtree generation number - */ - atomic_and_32(&di_cache.cache_valid, 0); + /* Increment devtree generation number. */ atomic_inc_ulong(&devtree_gen); - flag = (kmflag == KM_SLEEP) ? TQ_SLEEP : TQ_NOSLEEP; - - (void) taskq_dispatch(system_taskq, free_cache_task, NULL, flag); + /* Invalidate the in-core cache and dispatch free on valid->invalid */ + cache_valid = atomic_swap_uint(&di_cache.cache_valid, 0); + if (cache_valid) { + (void) taskq_dispatch(system_taskq, free_cache_task, NULL, + (kmflag == KM_SLEEP) ? TQ_SLEEP : TQ_NOSLEEP); + } if (di_cache_debug) { cmn_err(CE_NOTE, "invalidation with km_flag: %s", diff --git a/usr/src/uts/common/os/modctl.c b/usr/src/uts/common/os/modctl.c index b4b0751d23..501cb7ba09 100644 --- a/usr/src/uts/common/os/modctl.c +++ b/usr/src/uts/common/os/modctl.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -2046,7 +2046,7 @@ modctl_devreaddir(const char *udir, int udirlen, goto err; if ((ret = sdev_modctl_readdir(dir, &dirlist, - &npaths, &npaths_alloc)) != 0) { + &npaths, &npaths_alloc, 0)) != 0) { ASSERT(dirlist == NULL); goto err; } @@ -2093,6 +2093,42 @@ err: return (ret); } +static int +modctl_devemptydir(const char *udir, int udirlen, int *uempty) +{ + char *dir; + int ret; + char **dirlist = NULL; + int npaths; + int npaths_alloc; + int empty; + + /* + * copyin the /dev path including terminating null + */ + udirlen++; + if (udirlen <= 1 || udirlen > MAXPATHLEN) + return (EINVAL); + dir = kmem_zalloc(udirlen + 1, KM_SLEEP); + if ((ret = copyinstr(udir, dir, udirlen, NULL)) != 0) + goto err; + + if ((ret = sdev_modctl_readdir(dir, &dirlist, + &npaths, &npaths_alloc, 1)) != 0) { + goto err; + } + + empty = npaths ? 0 : 1; + if (copyout(&empty, uempty, sizeof (empty))) + ret = EFAULT; + +err: + if (dirlist) + sdev_modctl_readdir_free(dirlist, npaths, npaths_alloc); + kmem_free(dir, udirlen + 1); + return (ret); +} + int modctl_moddevname(int subcmd, uintptr_t a1, uintptr_t a2) { @@ -2347,6 +2383,11 @@ modctl(int cmd, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, (char *)a3, (int64_t *)a4); break; + case MODDEVEMPTYDIR: /* non-reconfiguring /dev emptydir */ + error = modctl_devemptydir((const char *)a1, (size_t)a2, + (int *)a3); + break; + case MODDEVNAME: error = modctl_moddevname((int)a1, a2, a3); break; diff --git a/usr/src/uts/common/sys/fs/sdev_impl.h b/usr/src/uts/common/sys/fs/sdev_impl.h index 7e5f75d7f7..33142fe703 100644 --- a/usr/src/uts/common/sys/fs/sdev_impl.h +++ b/usr/src/uts/common/sys/fs/sdev_impl.h @@ -624,7 +624,7 @@ extern void *sdev_get_vtor(struct sdev_node *dv); /* * devinfo helpers */ -extern int sdev_modctl_readdir(const char *, char ***, int *, int *); +extern int sdev_modctl_readdir(const char *, char ***, int *, int *, int); extern void sdev_modctl_readdir_free(char **, int, int); extern int sdev_modctl_devexists(const char *); diff --git a/usr/src/uts/common/sys/modctl.h b/usr/src/uts/common/sys/modctl.h index 818572a94d..0ff7ddc42c 100644 --- a/usr/src/uts/common/sys/modctl.h +++ b/usr/src/uts/common/sys/modctl.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -269,6 +269,7 @@ struct modlinkage { #define MODRETIRE 40 #define MODUNRETIRE 41 #define MODISRETIRED 42 +#define MODDEVEMPTYDIR 43 /* * sub cmds for MODEVENTS |