Print this page
/etc/zones/did.txt should be alternate-root aware
OS-192 zone_create() warning on headnode


  63 
  64 #include <arpa/inet.h>
  65 #include <netdb.h>
  66 
  67 #include <libxml/xmlmemory.h>
  68 #include <libxml/parser.h>
  69 
  70 #include <libdevinfo.h>
  71 #include <uuid/uuid.h>
  72 #include <dirent.h>
  73 #include <libbrand.h>
  74 
  75 #include <libzonecfg.h>
  76 #include "zonecfg_impl.h"
  77 
  78 #define _PATH_TMPFILE   "/zonecfg.XXXXXX"
  79 #define ZONE_CB_RETRY_COUNT             10
  80 #define ZONE_EVENT_PING_SUBCLASS        "ping"
  81 #define ZONE_EVENT_PING_PUBLISHER       "solaris"
  82 


  83 /* Hard-code the DTD element/attribute/entity names just once, here. */
  84 #define DTD_ELEM_ATTR           (const xmlChar *) "attr"
  85 #define DTD_ELEM_COMMENT        (const xmlChar *) "comment"
  86 #define DTD_ELEM_DEVICE         (const xmlChar *) "device"
  87 #define DTD_ELEM_FS             (const xmlChar *) "filesystem"
  88 #define DTD_ELEM_FSOPTION       (const xmlChar *) "fsoption"
  89 #define DTD_ELEM_NET            (const xmlChar *) "network"
  90 #define DTD_ELEM_RCTL           (const xmlChar *) "rctl"
  91 #define DTD_ELEM_RCTLVALUE      (const xmlChar *) "rctl-value"
  92 #define DTD_ELEM_ZONE           (const xmlChar *) "zone"
  93 #define DTD_ELEM_DATASET        (const xmlChar *) "dataset"
  94 #define DTD_ELEM_TMPPOOL        (const xmlChar *) "tmp_pool"
  95 #define DTD_ELEM_PSET           (const xmlChar *) "pset"
  96 #define DTD_ELEM_MCAP           (const xmlChar *) "mcap"
  97 #define DTD_ELEM_PACKAGE        (const xmlChar *) "package"
  98 #define DTD_ELEM_OBSOLETES      (const xmlChar *) "obsoletes"
  99 #define DTD_ELEM_DEV_PERM       (const xmlChar *) "dev-perm"
 100 #define DTD_ELEM_ADMIN          (const xmlChar *) "admin"
 101 #define DTD_ELEM_SECFLAGS       (const xmlChar *) "security-flags"
 102 


 115 #define DTD_ATTR_NAME           (const xmlChar *) "name"
 116 #define DTD_ATTR_PHYSICAL       (const xmlChar *) "physical"
 117 #define DTD_ATTR_POOL           (const xmlChar *) "pool"
 118 #define DTD_ATTR_PRIV           (const xmlChar *) "priv"
 119 #define DTD_ATTR_RAW            (const xmlChar *) "raw"
 120 #define DTD_ATTR_SPECIAL        (const xmlChar *) "special"
 121 #define DTD_ATTR_TYPE           (const xmlChar *) "type"
 122 #define DTD_ATTR_VALUE          (const xmlChar *) "value"
 123 #define DTD_ATTR_ZONEPATH       (const xmlChar *) "zonepath"
 124 #define DTD_ATTR_NCPU_MIN       (const xmlChar *) "ncpu_min"
 125 #define DTD_ATTR_NCPU_MAX       (const xmlChar *) "ncpu_max"
 126 #define DTD_ATTR_IMPORTANCE     (const xmlChar *) "importance"
 127 #define DTD_ATTR_PHYSCAP        (const xmlChar *) "physcap"
 128 #define DTD_ATTR_VERSION        (const xmlChar *) "version"
 129 #define DTD_ATTR_ID             (const xmlChar *) "id"
 130 #define DTD_ATTR_UID            (const xmlChar *) "uid"
 131 #define DTD_ATTR_GID            (const xmlChar *) "gid"
 132 #define DTD_ATTR_MODE           (const xmlChar *) "mode"
 133 #define DTD_ATTR_ACL            (const xmlChar *) "acl"
 134 #define DTD_ATTR_BRAND          (const xmlChar *) "brand"

 135 #define DTD_ATTR_HOSTID         (const xmlChar *) "hostid"
 136 #define DTD_ATTR_USER           (const xmlChar *) "user"
 137 #define DTD_ATTR_AUTHS          (const xmlChar *) "auths"
 138 #define DTD_ATTR_FS_ALLOWED     (const xmlChar *) "fs-allowed"
 139 #define DTD_ATTR_DEFAULT        (const xmlChar *) "default"
 140 #define DTD_ATTR_LOWER          (const xmlChar *) "lower"
 141 #define DTD_ATTR_UPPER          (const xmlChar *) "upper"
 142 
 143 
 144 #define DTD_ENTITY_BOOLEAN      "boolean"
 145 #define DTD_ENTITY_DEVPATH      "devpath"
 146 #define DTD_ENTITY_DRIVER       "driver"
 147 #define DTD_ENTITY_DRVMIN       "drv_min"
 148 #define DTD_ENTITY_FALSE        "false"
 149 #define DTD_ENTITY_INT          "int"
 150 #define DTD_ENTITY_STRING       "string"
 151 #define DTD_ENTITY_TRUE         "true"
 152 #define DTD_ENTITY_UINT         "uint"
 153 
 154 #define DTD_ENTITY_BOOL_LEN     6       /* "false" */


5668                 if (err < 0)
5669                         return ((errno == EFAULT) ? Z_TOO_BIG : Z_INVAL);
5670 
5671                 return (Z_OK);
5672         }
5673 
5674         if (strcmp(zone_name, "global") == 0)
5675                 return (zonecfg_default_brand(brandname, rp_sz));
5676 
5677         if ((handle = zonecfg_init_handle()) == NULL)
5678                 return (Z_NOMEM);
5679 
5680         err = zonecfg_get_handle((char *)zone_name, handle);
5681         if (err == Z_OK)
5682                 err = zonecfg_get_brand(handle, brandname, rp_sz);
5683 
5684         zonecfg_fini_handle(handle);
5685         return (err);
5686 }
5687 





































































































































































5688 /*
5689  * Return the appropriate root for the active /dev.
5690  * For normal zone, the path is $ZONEPATH/root;
5691  * for scratch zone, the dev path is $ZONEPATH/lu.
5692  */
5693 int
5694 zone_get_devroot(char *zone_name, char *devroot, size_t rp_sz)
5695 {
5696         int err;
5697         char *suffix;
5698         zone_state_t state;
5699 
5700         /* This function makes sense for non-global zones only. */
5701         if (strcmp(zone_name, GLOBAL_ZONENAME) == 0)
5702                 return (Z_BOGUS_ZONE_NAME);
5703         if ((err = zone_get_zonepath(zone_name, devroot, rp_sz)) != Z_OK)
5704                 return (err);
5705 
5706         if (zone_get_state(zone_name, &state) == Z_OK &&
5707             state == ZONE_STATE_MOUNTED)




  63 
  64 #include <arpa/inet.h>
  65 #include <netdb.h>
  66 
  67 #include <libxml/xmlmemory.h>
  68 #include <libxml/parser.h>
  69 
  70 #include <libdevinfo.h>
  71 #include <uuid/uuid.h>
  72 #include <dirent.h>
  73 #include <libbrand.h>
  74 
  75 #include <libzonecfg.h>
  76 #include "zonecfg_impl.h"
  77 
  78 #define _PATH_TMPFILE   "/zonecfg.XXXXXX"
  79 #define ZONE_CB_RETRY_COUNT             10
  80 #define ZONE_EVENT_PING_SUBCLASS        "ping"
  81 #define ZONE_EVENT_PING_PUBLISHER       "solaris"
  82 
  83 #define DEBUGID_FILE    "/etc/zones/did.txt"
  84 
  85 /* Hard-code the DTD element/attribute/entity names just once, here. */
  86 #define DTD_ELEM_ATTR           (const xmlChar *) "attr"
  87 #define DTD_ELEM_COMMENT        (const xmlChar *) "comment"
  88 #define DTD_ELEM_DEVICE         (const xmlChar *) "device"
  89 #define DTD_ELEM_FS             (const xmlChar *) "filesystem"
  90 #define DTD_ELEM_FSOPTION       (const xmlChar *) "fsoption"
  91 #define DTD_ELEM_NET            (const xmlChar *) "network"
  92 #define DTD_ELEM_RCTL           (const xmlChar *) "rctl"
  93 #define DTD_ELEM_RCTLVALUE      (const xmlChar *) "rctl-value"
  94 #define DTD_ELEM_ZONE           (const xmlChar *) "zone"
  95 #define DTD_ELEM_DATASET        (const xmlChar *) "dataset"
  96 #define DTD_ELEM_TMPPOOL        (const xmlChar *) "tmp_pool"
  97 #define DTD_ELEM_PSET           (const xmlChar *) "pset"
  98 #define DTD_ELEM_MCAP           (const xmlChar *) "mcap"
  99 #define DTD_ELEM_PACKAGE        (const xmlChar *) "package"
 100 #define DTD_ELEM_OBSOLETES      (const xmlChar *) "obsoletes"
 101 #define DTD_ELEM_DEV_PERM       (const xmlChar *) "dev-perm"
 102 #define DTD_ELEM_ADMIN          (const xmlChar *) "admin"
 103 #define DTD_ELEM_SECFLAGS       (const xmlChar *) "security-flags"
 104 


 117 #define DTD_ATTR_NAME           (const xmlChar *) "name"
 118 #define DTD_ATTR_PHYSICAL       (const xmlChar *) "physical"
 119 #define DTD_ATTR_POOL           (const xmlChar *) "pool"
 120 #define DTD_ATTR_PRIV           (const xmlChar *) "priv"
 121 #define DTD_ATTR_RAW            (const xmlChar *) "raw"
 122 #define DTD_ATTR_SPECIAL        (const xmlChar *) "special"
 123 #define DTD_ATTR_TYPE           (const xmlChar *) "type"
 124 #define DTD_ATTR_VALUE          (const xmlChar *) "value"
 125 #define DTD_ATTR_ZONEPATH       (const xmlChar *) "zonepath"
 126 #define DTD_ATTR_NCPU_MIN       (const xmlChar *) "ncpu_min"
 127 #define DTD_ATTR_NCPU_MAX       (const xmlChar *) "ncpu_max"
 128 #define DTD_ATTR_IMPORTANCE     (const xmlChar *) "importance"
 129 #define DTD_ATTR_PHYSCAP        (const xmlChar *) "physcap"
 130 #define DTD_ATTR_VERSION        (const xmlChar *) "version"
 131 #define DTD_ATTR_ID             (const xmlChar *) "id"
 132 #define DTD_ATTR_UID            (const xmlChar *) "uid"
 133 #define DTD_ATTR_GID            (const xmlChar *) "gid"
 134 #define DTD_ATTR_MODE           (const xmlChar *) "mode"
 135 #define DTD_ATTR_ACL            (const xmlChar *) "acl"
 136 #define DTD_ATTR_BRAND          (const xmlChar *) "brand"
 137 #define DTD_ATTR_DID            (const xmlChar *) "debugid"
 138 #define DTD_ATTR_HOSTID         (const xmlChar *) "hostid"
 139 #define DTD_ATTR_USER           (const xmlChar *) "user"
 140 #define DTD_ATTR_AUTHS          (const xmlChar *) "auths"
 141 #define DTD_ATTR_FS_ALLOWED     (const xmlChar *) "fs-allowed"
 142 #define DTD_ATTR_DEFAULT        (const xmlChar *) "default"
 143 #define DTD_ATTR_LOWER          (const xmlChar *) "lower"
 144 #define DTD_ATTR_UPPER          (const xmlChar *) "upper"
 145 
 146 
 147 #define DTD_ENTITY_BOOLEAN      "boolean"
 148 #define DTD_ENTITY_DEVPATH      "devpath"
 149 #define DTD_ENTITY_DRIVER       "driver"
 150 #define DTD_ENTITY_DRVMIN       "drv_min"
 151 #define DTD_ENTITY_FALSE        "false"
 152 #define DTD_ENTITY_INT          "int"
 153 #define DTD_ENTITY_STRING       "string"
 154 #define DTD_ENTITY_TRUE         "true"
 155 #define DTD_ENTITY_UINT         "uint"
 156 
 157 #define DTD_ENTITY_BOOL_LEN     6       /* "false" */


5671                 if (err < 0)
5672                         return ((errno == EFAULT) ? Z_TOO_BIG : Z_INVAL);
5673 
5674                 return (Z_OK);
5675         }
5676 
5677         if (strcmp(zone_name, "global") == 0)
5678                 return (zonecfg_default_brand(brandname, rp_sz));
5679 
5680         if ((handle = zonecfg_init_handle()) == NULL)
5681                 return (Z_NOMEM);
5682 
5683         err = zonecfg_get_handle((char *)zone_name, handle);
5684         if (err == Z_OK)
5685                 err = zonecfg_get_brand(handle, brandname, rp_sz);
5686 
5687         zonecfg_fini_handle(handle);
5688         return (err);
5689 }
5690 
5691 /*
5692  * Atomically get a new zone_did value.  The currently allocated value
5693  * is stored in /etc/zones/did.txt.  Lock the file, read the current value,
5694  * increment, save the new value and unlock the file.  Return the new value
5695  * or -1 if there was an error.  The ID namespace is large enough that we
5696  * don't worry about recycling an ID when a zone is deleted.
5697  */
5698 static zoneid_t
5699 new_zone_did()
5700 {
5701         int fd;
5702         int len;
5703         int val;
5704         struct flock lck;
5705         char pathbuf[PATH_MAX];
5706         char buf[80];
5707 
5708         if (snprintf(pathbuf, sizeof (pathbuf), "%s%s", zonecfg_get_root(),
5709             DEBUGID_FILE) >= sizeof (pathbuf)) {
5710                 printf(gettext("alternate root path is too long"));
5711                 return (-1);
5712         }
5713 
5714         if ((fd = open(pathbuf, O_RDWR | O_CREAT,
5715             S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
5716                 perror("new_zone_did open failed");
5717                 return (-1);
5718         }
5719 
5720         /* Initialize the lock. */
5721         lck.l_whence = SEEK_SET;
5722         lck.l_start = 0;
5723         lck.l_len = 0;
5724 
5725         /* Wait until we acquire an exclusive lock on the file. */
5726         lck.l_type = F_WRLCK;
5727         if (fcntl(fd, F_SETLKW, &lck) == -1) {
5728                 perror("new_zone_did lock failed");
5729                 (void) close(fd);
5730                 return (-1);
5731         }
5732 
5733         /* Get currently allocated value */
5734         len = read(fd, buf, sizeof (buf));
5735         if (len == -1) {
5736                 perror("new_zone_did read failed");
5737                 val = -1;
5738         } else {
5739                 if (lseek(fd, 0L, SEEK_SET) == -1) {
5740                         perror("new_zone_did seek failed");
5741                         val = -1;
5742                 } else {
5743                         if (len == 0) {
5744                                 /* Just created the file, initialize at 1 */
5745                                 val = 1;
5746                         } else {
5747                                 val = atoi(buf);
5748                                 val++;
5749                         }
5750 
5751                         (void) snprintf(buf, sizeof (buf), "%d\n", val);
5752                         len = strlen(buf);
5753 
5754                         /* Save newly allocated value */
5755                         if (write(fd, buf, len) == -1) {
5756                                 perror("new_zone_did write failed");
5757                                 val = -1;
5758                         }
5759                 }
5760         }
5761 
5762         /* Release the file lock. */
5763         lck.l_type = F_UNLCK;
5764         if (fcntl(fd, F_SETLK, &lck) == -1) {
5765                 perror("new_zone_did unlock failed");
5766                 val = -1;
5767         }
5768 
5769         if (close(fd) != 0)
5770                 perror("new_zone_did close failed");
5771 
5772         return (val);
5773 }
5774 
5775 /*
5776  * Called by zoneadmd to get the zone's debug ID.
5777  * If the zone doesn't already have an ID, a new one is generated and
5778  * persistently saved onto the zone.  Normally either zoneadm or zonecfg
5779  * will assign a new ID for the zone, so zoneadmd should never have to
5780  * generate one, but we also handle that here just to be paranoid.
5781  */
5782 zoneid_t
5783 zone_get_did(char *zone_name)
5784 {
5785         int res;
5786         zoneid_t new_did;
5787         zone_dochandle_t handle;
5788         char did_str[80];
5789 
5790         if ((handle = zonecfg_init_handle()) == NULL)
5791                 return (getpid());
5792 
5793         if (zonecfg_get_handle((char *)zone_name, handle) != Z_OK)
5794                 return (getpid());
5795 
5796         res = getrootattr(handle, DTD_ATTR_DID, did_str, sizeof (did_str));
5797 
5798         /* If the zone already has an assigned debug ID, return it. */
5799         if (res == Z_OK && did_str[0] != '\0') {
5800                 zonecfg_fini_handle(handle);
5801                 return (atoi(did_str));
5802         }
5803 
5804         /*
5805          * The zone doesn't have an assigned debug ID yet, generate one and
5806          * save it as part of the zone definition.
5807          */
5808         if ((new_did = new_zone_did()) == -1) {
5809                 /*
5810                  * We should really never hit this block of code.
5811                  * Generating a new ID failed for some reason.  Use the current
5812                  * pid as a temporary ID so that the zone can continue to boot
5813                  * but we don't persistently save this temporary ID on the zone.
5814                  */
5815                 zonecfg_fini_handle(handle);
5816                 return (getpid());
5817         }
5818 
5819         /* Now persistently save this new ID onto the zone. */
5820         (void) snprintf(did_str, sizeof (did_str), "%d", new_did);
5821         (void) setrootattr(handle, DTD_ATTR_DID, did_str);
5822         (void) zonecfg_save(handle);
5823 
5824         zonecfg_fini_handle(handle);
5825         return (new_did);
5826 }
5827 
5828 zoneid_t
5829 zonecfg_get_did(zone_dochandle_t handle)
5830 {
5831         char did_str[80];
5832         int err;
5833         zoneid_t did;
5834 
5835         err = getrootattr(handle, DTD_ATTR_DID, did_str, sizeof (did_str));
5836         if (err == Z_OK && did_str[0] != '\0')
5837                 did = atoi(did_str);
5838         else
5839                 did = -1;
5840 
5841         return (did);
5842 }
5843 
5844 void
5845 zonecfg_set_did(zone_dochandle_t handle)
5846 {
5847         zoneid_t new_did;
5848         char did_str[80];
5849 
5850         if ((new_did = new_zone_did()) == -1)
5851                 return;
5852         (void) snprintf(did_str, sizeof (did_str), "%d", new_did);
5853         (void) setrootattr(handle, DTD_ATTR_DID, did_str);
5854 }
5855 
5856 /*
5857  * Return the appropriate root for the active /dev.
5858  * For normal zone, the path is $ZONEPATH/root;
5859  * for scratch zone, the dev path is $ZONEPATH/lu.
5860  */
5861 int
5862 zone_get_devroot(char *zone_name, char *devroot, size_t rp_sz)
5863 {
5864         int err;
5865         char *suffix;
5866         zone_state_t state;
5867 
5868         /* This function makes sense for non-global zones only. */
5869         if (strcmp(zone_name, GLOBAL_ZONENAME) == 0)
5870                 return (Z_BOGUS_ZONE_NAME);
5871         if ((err = zone_get_zonepath(zone_name, devroot, rp_sz)) != Z_OK)
5872                 return (err);
5873 
5874         if (zone_get_state(zone_name, &state) == Z_OK &&
5875             state == ZONE_STATE_MOUNTED)