Print this page
OS-4335 ipadm_door_call should work in a branded zone without chroot
OS-4336 ipmgmtd should work in a branded zone without chroot
Reviewed by: Robert Mustacchi <rm@joyent.com>
        
*** 19,28 ****
--- 19,29 ----
   * CDDL HEADER END
   */
  
  /*
   * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+  * Copyright 2015 Joyent, Inc.
   * Copyright 2016 Argo Technologie SA.
   */
  
  /*
   * Contains DB walker functions, which are of type `db_wfunc_t';
*** 382,398 ****
  /* ARGSUSED */
  static void *
  ipmgmt_db_restore_thread(void *arg)
  {
          int err;
  
          for (;;) {
                  (void) sleep(5);
                  (void) pthread_rwlock_wrlock(&ipmgmt_dbconf_lock);
                  if (!ipmgmt_rdonly_root)
                          break;
!                 err = ipmgmt_cpfile(IPADM_VOL_DB_FILE, IPADM_DB_FILE, B_FALSE);
                  if (err == 0) {
                          ipmgmt_rdonly_root = B_FALSE;
                          break;
                  }
                  (void) pthread_rwlock_unlock(&ipmgmt_dbconf_lock);
--- 383,404 ----
  /* ARGSUSED */
  static void *
  ipmgmt_db_restore_thread(void *arg)
  {
          int err;
+         char confpath[MAXPATHLEN];
+         char tmpconfpath[MAXPATHLEN];
  
+         ipmgmt_path(IPADM_PATH_DB, confpath, sizeof (confpath));
+         ipmgmt_path(IPADM_PATH_VOL_DB, tmpconfpath, sizeof (tmpconfpath));
+ 
          for (;;) {
                  (void) sleep(5);
                  (void) pthread_rwlock_wrlock(&ipmgmt_dbconf_lock);
                  if (!ipmgmt_rdonly_root)
                          break;
!                 err = ipmgmt_cpfile(tmpconfpath, confpath, B_FALSE);
                  if (err == 0) {
                          ipmgmt_rdonly_root = B_FALSE;
                          break;
                  }
                  (void) pthread_rwlock_unlock(&ipmgmt_dbconf_lock);
*** 420,430 ****
--- 426,441 ----
          int             err;
          boolean_t       writeop;
          mode_t          mode;
          pthread_t       tid;
          pthread_attr_t  attr;
+         char            confpath[MAXPATHLEN];
+         char            tmpconfpath[MAXPATHLEN];
  
+         ipmgmt_path(IPADM_PATH_DB, confpath, sizeof (confpath));
+         ipmgmt_path(IPADM_PATH_VOL_DB, tmpconfpath, sizeof (tmpconfpath));
+ 
          writeop = (db_op != IPADM_DB_READ);
          if (writeop) {
                  (void) pthread_rwlock_wrlock(&ipmgmt_dbconf_lock);
                  mode = IPADM_FILE_MODE;
          } else {
*** 432,477 ****
                  mode = 0;
          }
  
          /*
           * Did a previous write attempt fail? If so, don't even try to
!          * read/write to IPADM_DB_FILE.
           */
          if (!ipmgmt_rdonly_root) {
!                 err = ipadm_rw_db(db_walk_func, db_warg, IPADM_DB_FILE,
!                     mode, db_op);
                  if (err != EROFS)
                          goto done;
          }
  
          /*
           * If we haven't already copied the file to the volatile
           * file system, do so. This should only happen on a failed
!          * writeop(i.e., we have acquired the write lock above).
           */
!         if (access(IPADM_VOL_DB_FILE, F_OK) != 0) {
                  assert(writeop);
!                 err = ipmgmt_cpfile(IPADM_DB_FILE, IPADM_VOL_DB_FILE, B_TRUE);
                  if (err != 0)
                          goto done;
                  (void) pthread_attr_init(&attr);
                  (void) pthread_attr_setdetachstate(&attr,
                      PTHREAD_CREATE_DETACHED);
                  err = pthread_create(&tid, &attr, ipmgmt_db_restore_thread,
                      NULL);
                  (void) pthread_attr_destroy(&attr);
                  if (err != 0) {
!                         (void) unlink(IPADM_VOL_DB_FILE);
                          goto done;
                  }
                  ipmgmt_rdonly_root = B_TRUE;
          }
  
          /*
           * Read/write from the volatile copy.
           */
!         err = ipadm_rw_db(db_walk_func, db_warg, IPADM_VOL_DB_FILE,
              mode, db_op);
  done:
          (void) pthread_rwlock_unlock(&ipmgmt_dbconf_lock);
          return (err);
  }
--- 443,487 ----
                  mode = 0;
          }
  
          /*
           * Did a previous write attempt fail? If so, don't even try to
!          * read/write to the permanent configuration file.
           */
          if (!ipmgmt_rdonly_root) {
!                 err = ipadm_rw_db(db_walk_func, db_warg, confpath, mode, db_op);
                  if (err != EROFS)
                          goto done;
          }
  
          /*
           * If we haven't already copied the file to the volatile
           * file system, do so. This should only happen on a failed
!          * writeop (i.e., we have acquired the write lock above).
           */
!         if (access(tmpconfpath, F_OK) != 0) {
                  assert(writeop);
!                 err = ipmgmt_cpfile(confpath, tmpconfpath, B_TRUE);
                  if (err != 0)
                          goto done;
                  (void) pthread_attr_init(&attr);
                  (void) pthread_attr_setdetachstate(&attr,
                      PTHREAD_CREATE_DETACHED);
                  err = pthread_create(&tid, &attr, ipmgmt_db_restore_thread,
                      NULL);
                  (void) pthread_attr_destroy(&attr);
                  if (err != 0) {
!                         (void) unlink(tmpconfpath);
                          goto done;
                  }
                  ipmgmt_rdonly_root = B_TRUE;
          }
  
          /*
           * Read/write from the volatile copy.
           */
!         err = ipadm_rw_db(db_walk_func, db_warg, tmpconfpath,
              mode, db_op);
  done:
          (void) pthread_rwlock_unlock(&ipmgmt_dbconf_lock);
          return (err);
  }
*** 1235,1262 ****
  ipmgmt_persist_aobjmap(ipmgmt_aobjmap_t *nodep, ipadm_db_op_t op)
  {
          int                     err;
          ipadm_dbwrite_cbarg_t   cb;
          nvlist_t                *nvl = NULL;
  
          if (op == IPADM_DB_WRITE) {
                  if ((err = i_ipmgmt_node2nvl(&nvl, nodep)) != 0)
                          return (err);
                  cb.dbw_nvl = nvl;
                  if (nodep->am_atype == IPADM_ADDR_IPV6_ADDRCONF)
                          cb.dbw_flags = IPMGMT_ATYPE_V6ACONF;
                  else
                          cb.dbw_flags = 0;
  
!                 err = ipadm_rw_db(ipmgmt_update_aobjmap, &cb,
!                     ADDROBJ_MAPPING_DB_FILE, IPADM_FILE_MODE, IPADM_DB_WRITE);
                  nvlist_free(nvl);
          } else {
                  assert(op == IPADM_DB_DELETE);
  
!                 err = ipadm_rw_db(ipmgmt_delete_aobjmap, nodep,
!                     ADDROBJ_MAPPING_DB_FILE, IPADM_FILE_MODE, IPADM_DB_DELETE);
          }
          return (err);
  }
  
  /*
--- 1245,1275 ----
  ipmgmt_persist_aobjmap(ipmgmt_aobjmap_t *nodep, ipadm_db_op_t op)
  {
          int                     err;
          ipadm_dbwrite_cbarg_t   cb;
          nvlist_t                *nvl = NULL;
+         char                    aobjpath[MAXPATHLEN];
  
+         ipmgmt_path(IPADM_PATH_ADDROBJ_MAP_DB, aobjpath, sizeof (aobjpath));
+ 
          if (op == IPADM_DB_WRITE) {
                  if ((err = i_ipmgmt_node2nvl(&nvl, nodep)) != 0)
                          return (err);
                  cb.dbw_nvl = nvl;
                  if (nodep->am_atype == IPADM_ADDR_IPV6_ADDRCONF)
                          cb.dbw_flags = IPMGMT_ATYPE_V6ACONF;
                  else
                          cb.dbw_flags = 0;
  
!                 err = ipadm_rw_db(ipmgmt_update_aobjmap, &cb, aobjpath,
!                     IPADM_FILE_MODE, IPADM_DB_WRITE);
                  nvlist_free(nvl);
          } else {
                  assert(op == IPADM_DB_DELETE);
  
!                 err = ipadm_rw_db(ipmgmt_delete_aobjmap, nodep, aobjpath,
!                     IPADM_FILE_MODE, IPADM_DB_DELETE);
          }
          return (err);
  }
  
  /*