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

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libzonecfg/common/libzonecfg.c
          +++ new/usr/src/lib/libzonecfg/common/libzonecfg.c
↓ open down ↓ 72 lines elided ↑ open up ↑
  73   73  #include <libbrand.h>
  74   74  
  75   75  #include <libzonecfg.h>
  76   76  #include "zonecfg_impl.h"
  77   77  
  78   78  #define _PATH_TMPFILE   "/zonecfg.XXXXXX"
  79   79  #define ZONE_CB_RETRY_COUNT             10
  80   80  #define ZONE_EVENT_PING_SUBCLASS        "ping"
  81   81  #define ZONE_EVENT_PING_PUBLISHER       "solaris"
  82   82  
       83 +#define DEBUGID_FILE    "/etc/zones/did.txt"
       84 +
  83   85  /* Hard-code the DTD element/attribute/entity names just once, here. */
  84   86  #define DTD_ELEM_ATTR           (const xmlChar *) "attr"
  85   87  #define DTD_ELEM_COMMENT        (const xmlChar *) "comment"
  86   88  #define DTD_ELEM_DEVICE         (const xmlChar *) "device"
  87   89  #define DTD_ELEM_FS             (const xmlChar *) "filesystem"
  88   90  #define DTD_ELEM_FSOPTION       (const xmlChar *) "fsoption"
  89   91  #define DTD_ELEM_NET            (const xmlChar *) "network"
  90   92  #define DTD_ELEM_RCTL           (const xmlChar *) "rctl"
  91   93  #define DTD_ELEM_RCTLVALUE      (const xmlChar *) "rctl-value"
  92   94  #define DTD_ELEM_ZONE           (const xmlChar *) "zone"
↓ open down ↓ 32 lines elided ↑ open up ↑
 125  127  #define DTD_ATTR_NCPU_MAX       (const xmlChar *) "ncpu_max"
 126  128  #define DTD_ATTR_IMPORTANCE     (const xmlChar *) "importance"
 127  129  #define DTD_ATTR_PHYSCAP        (const xmlChar *) "physcap"
 128  130  #define DTD_ATTR_VERSION        (const xmlChar *) "version"
 129  131  #define DTD_ATTR_ID             (const xmlChar *) "id"
 130  132  #define DTD_ATTR_UID            (const xmlChar *) "uid"
 131  133  #define DTD_ATTR_GID            (const xmlChar *) "gid"
 132  134  #define DTD_ATTR_MODE           (const xmlChar *) "mode"
 133  135  #define DTD_ATTR_ACL            (const xmlChar *) "acl"
 134  136  #define DTD_ATTR_BRAND          (const xmlChar *) "brand"
      137 +#define DTD_ATTR_DID            (const xmlChar *) "debugid"
 135  138  #define DTD_ATTR_HOSTID         (const xmlChar *) "hostid"
 136  139  #define DTD_ATTR_USER           (const xmlChar *) "user"
 137  140  #define DTD_ATTR_AUTHS          (const xmlChar *) "auths"
 138  141  #define DTD_ATTR_FS_ALLOWED     (const xmlChar *) "fs-allowed"
 139  142  #define DTD_ATTR_DEFAULT        (const xmlChar *) "default"
 140  143  #define DTD_ATTR_LOWER          (const xmlChar *) "lower"
 141  144  #define DTD_ATTR_UPPER          (const xmlChar *) "upper"
 142  145  
 143  146  
 144  147  #define DTD_ENTITY_BOOLEAN      "boolean"
↓ open down ↓ 5533 lines elided ↑ open up ↑
5678 5681                  return (Z_NOMEM);
5679 5682  
5680 5683          err = zonecfg_get_handle((char *)zone_name, handle);
5681 5684          if (err == Z_OK)
5682 5685                  err = zonecfg_get_brand(handle, brandname, rp_sz);
5683 5686  
5684 5687          zonecfg_fini_handle(handle);
5685 5688          return (err);
5686 5689  }
5687 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 +
5688 5856  /*
5689 5857   * Return the appropriate root for the active /dev.
5690 5858   * For normal zone, the path is $ZONEPATH/root;
5691 5859   * for scratch zone, the dev path is $ZONEPATH/lu.
5692 5860   */
5693 5861  int
5694 5862  zone_get_devroot(char *zone_name, char *devroot, size_t rp_sz)
5695 5863  {
5696 5864          int err;
5697 5865          char *suffix;
↓ open down ↓ 2584 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX