Print this page
12505 Answer KEBE question about cred in unexport()
        
*** 83,93 ****
  static int exi_id_next;
  static bool_t exi_id_overflow;
  avl_tree_t exi_id_tree;
  kmutex_t nfs_exi_id_lock;
  
! static int      unexport(nfs_export_t *, exportinfo_t *);
  static void     exportfree(exportinfo_t *);
  static int      loadindex(exportdata_t *);
  
  extern void     nfsauth_cache_free(exportinfo_t *);
  extern int      sec_svc_loadrootnames(int, int, caddr_t **, model_t);
--- 83,93 ----
  static int exi_id_next;
  static bool_t exi_id_overflow;
  avl_tree_t exi_id_tree;
  kmutex_t nfs_exi_id_lock;
  
! static int      unexport(nfs_export_t *, exportinfo_t *, cred_t *);
  static void     exportfree(exportinfo_t *);
  static int      loadindex(exportdata_t *);
  
  extern void     nfsauth_cache_free(exportinfo_t *);
  extern int      sec_svc_loadrootnames(int, int, caddr_t **, model_t);
*** 973,983 ****
--- 973,991 ----
  nfs_export_zone_shutdown(nfs_globals_t *ng)
  {
          nfs_export_t *ne = ng->nfs_export;
          struct exportinfo *exi, *nexi;
          int i, errors;
+         zoneid_t zoneid = ng->nfs_zoneid;
+         cred_t *cr;
  
+         /*
+          * Use the zone's credential.  Since this is a zone shutdown method,
+          * the zone_t should still be around for a zone_get_kcred() call.
+          */
+         cr = zone_get_kcred(zoneid);
+         VERIFY(cr != NULL);
          rw_enter(&ne->exported_lock, RW_READER);
  
          errors = 0;
          for (i = 0; i < EXPTABLESIZE; i++) {
  
*** 984,994 ****
                  exi = ne->exptable[i];
                  if (exi != NULL)
                          exi_hold(exi);
  
                  while (exi != NULL) {
! 
                          /*
                           * Get and hold next export before
                           * dropping the rwlock and unexport
                           */
                          nexi = exi->fid_hash.next;
--- 992,1002 ----
                  exi = ne->exptable[i];
                  if (exi != NULL)
                          exi_hold(exi);
  
                  while (exi != NULL) {
!                         ASSERT3U(zoneid, ==, exi->exi_zoneid);
                          /*
                           * Get and hold next export before
                           * dropping the rwlock and unexport
                           */
                          nexi = exi->fid_hash.next;
*** 1000,1010 ****
                          /*
                           * Skip ne->exi_root which gets special
                           * create/destroy handling.
                           */
                          if (exi != ne->exi_root &&
!                             unexport(ne, exi) != 0)
                                  errors++;
                          exi_rele(exi);
  
                          rw_enter(&ne->exported_lock, RW_READER);
                          exi = nexi;
--- 1008,1018 ----
                          /*
                           * Skip ne->exi_root which gets special
                           * create/destroy handling.
                           */
                          if (exi != ne->exi_root &&
!                             unexport(ne, exi, cr) != 0)
                                  errors++;
                          exi_rele(exi);
  
                          rw_enter(&ne->exported_lock, RW_READER);
                          exi = nexi;
*** 1014,1023 ****
--- 1022,1032 ----
                  cmn_err(CE_NOTE, "NFS: failed un-exports in zone %d",
                      (int)ng->nfs_zoneid);
          }
  
          rw_exit(&ne->exported_lock);
+         crfree(cr);
  }
  
  void
  nfs_export_zone_fini(nfs_globals_t *ng)
  {
*** 1284,1294 ****
          /* Is this an unshare? */
          if (STRUCT_FGETP(uap, uex) == NULL) {
                  pn_free(&lookpn);
                  if (ex1 == NULL)
                          return (EINVAL);
!                 error = unexport(ne, ex1);
                  exi_rele(ex1);
                  return (error);
          }
  
          /* It is a share or a re-share */
--- 1293,1303 ----
          /* Is this an unshare? */
          if (STRUCT_FGETP(uap, uex) == NULL) {
                  pn_free(&lookpn);
                  if (ex1 == NULL)
                          return (EINVAL);
!                 error = unexport(ne, ex1, cr);
                  exi_rele(ex1);
                  return (error);
          }
  
          /* It is a share or a re-share */
*** 1884,1894 ****
  
  /*
   * Unexport an exported filesystem
   */
  static int
! unexport(nfs_export_t *ne, struct exportinfo *exi)
  {
          struct secinfo cursec[MAX_FLAVORS];
          int curcnt;
  
          rw_enter(&ne->exported_lock, RW_WRITER);
--- 1893,1903 ----
  
  /*
   * Unexport an exported filesystem
   */
  static int
! unexport(nfs_export_t *ne, struct exportinfo *exi, cred_t *cr)
  {
          struct secinfo cursec[MAX_FLAVORS];
          int curcnt;
  
          rw_enter(&ne->exported_lock, RW_WRITER);
*** 1952,1973 ****
          /*
           * If this was a public export, restore
           * the public filehandle to the root.
           */
  
-         /*
-          * XXX KEBE ASKS --> Should CRED() instead be
-          * exi->exi_zone->zone_kcred?
-          */
          if (exi == ne->exi_public) {
                  ne->exi_public = ne->exi_root;
  
!                 nfslog_share_record(ne->exi_public, CRED());
          }
  
          if (exi->exi_export.ex_flags & EX_LOG)
!                 nfslog_unshare_record(exi, CRED());
  
          exi_rele(exi);
          return (0);
  }
  
--- 1961,1978 ----
          /*
           * If this was a public export, restore
           * the public filehandle to the root.
           */
  
          if (exi == ne->exi_public) {
                  ne->exi_public = ne->exi_root;
  
!                 nfslog_share_record(ne->exi_public, cr);
          }
  
          if (exi->exi_export.ex_flags & EX_LOG)
!                 nfslog_unshare_record(exi, cr);
  
          exi_rele(exi);
          return (0);
  }