コード例 #1
0
ファイル: zfd.c プロジェクト: arekinath/illumos-joyent
/*
 * init_zfd_devs() drives the device-tree configuration of the zone fd devices.
 * The general strategy is to use the libdevice (devctl) interfaces to
 * instantiate 3 new zone fd nodes.  We do a lot of sanity checking, and
 * are careful to reuse a dev if one exists.
 *
 * Once the devices are in the device tree, we kick devfsadm via
 * di_devlink_init() to ensure that the appropriate symlinks (to the master and
 * slave fd devices) are placed in /dev in the global zone.
 */
static int
init_zfd_dev(zlog_t *zlogp, devctl_hdl_t bus_hdl, int id)
{
	int rv = -1;
	devctl_ddef_t ddef_hdl = NULL;
	devctl_hdl_t dev_hdl = NULL;

	if ((ddef_hdl = devctl_ddef_alloc("zfd", 0)) == NULL) {
		zerror(zlogp, B_TRUE, "failed to allocate ddef handle");
		goto error;
	}

	/*
	 * Set four properties on this node; the first is the name of the
	 * zone; the second is a flag which lets pseudo know that it is
	 * OK to automatically allocate an instance # for this device;
	 * the third tells the device framework not to auto-detach this
	 * node-- we need the node to still be there when we ask devfsadmd
	 * to make links, and when we need to open it.
	 */
	if (devctl_ddef_string(ddef_hdl, "zfd_zname", zone_name) == -1) {
		zerror(zlogp, B_TRUE, "failed to create zfd_zname property");
		goto error;
	}
	if (devctl_ddef_int(ddef_hdl, "zfd_id", id) == -1) {
		zerror(zlogp, B_TRUE, "failed to create zfd_id property");
		goto error;
	}
	if (devctl_ddef_int(ddef_hdl, "auto-assign-instance", 1) == -1) {
		zerror(zlogp, B_TRUE, "failed to create auto-assign-instance "
		    "property");
		goto error;
	}
	if (devctl_ddef_int(ddef_hdl, "ddi-no-autodetach", 1) == -1) {
		zerror(zlogp, B_TRUE, "failed to create ddi-no-auto-detach "
		    "property");
		goto error;
	}
	if (devctl_bus_dev_create(bus_hdl, ddef_hdl, 0, &dev_hdl) == -1) {
		zerror(zlogp, B_TRUE, "failed to create zfd node");
		goto error;
	}
	rv = 0;

error:
	if (ddef_hdl)
		devctl_ddef_free(ddef_hdl);
	if (dev_hdl)
		devctl_release(dev_hdl);
	return (rv);
}
コード例 #2
0
ファイル: zcons.c プロジェクト: maosi66/illumos-joyent
/*
 * init_console_dev() drives the device-tree configuration of the zone
 * console device.  The general strategy is to use the libdevice (devctl)
 * interfaces to instantiate a new zone console node.  We do a lot of
 * sanity checking, and are careful to reuse a console if one exists.
 *
 * Once the device is in the device tree, we kick devfsadm via di_devlink_init()
 * to ensure that the appropriate symlinks (to the master and slave console
 * devices) are placed in /dev in the global zone.
 */
static int
init_console_dev(zlog_t *zlogp)
{
	char conspath[MAXPATHLEN];
	devctl_hdl_t bus_hdl = NULL;
	devctl_hdl_t dev_hdl = NULL;
	devctl_ddef_t ddef_hdl = NULL;
	di_devlink_handle_t dl = NULL;
	int rv = -1;
	int ndevs;
	int masterfd;
	int slavefd;
	int i;

	/*
	 * Don't re-setup console if it is working and ready already; just
	 * skip ahead to making devlinks, which we do for sanity's sake.
	 */
	ndevs = count_console_devs(zlogp);
	if (ndevs == 1) {
		goto devlinks;
	} else if (ndevs > 1 || ndevs == -1) {
		/*
		 * For now, this seems like a reasonable but harsh punishment.
		 * If needed, we could try to get clever and delete all but
		 * the console which is pointed at by the current symlink.
		 */
		if (destroy_console_devs(zlogp) == -1) {
			goto error;
		}
	}

	/*
	 * Time to make the consoles!
	 */
	if ((bus_hdl = devctl_bus_acquire(ZCONSNEX_FILEPATH, 0)) == NULL) {
		zerror(zlogp, B_TRUE, "%s failed", "devctl_bus_acquire");
		goto error;
	}
	if ((ddef_hdl = devctl_ddef_alloc("zcons", 0)) == NULL) {
		zerror(zlogp, B_TRUE, "failed to allocate ddef handle");
		goto error;
	}
	/*
	 * Set three properties on this node; the first is the name of the
	 * zone; the second is a flag which lets pseudo know that it is
	 * OK to automatically allocate an instance # for this device;
	 * the third tells the device framework not to auto-detach this
	 * node-- we need the node to still be there when we ask devfsadmd
	 * to make links, and when we need to open it.
	 */
	if (devctl_ddef_string(ddef_hdl, "zonename", zone_name) == -1) {
		zerror(zlogp, B_TRUE, "failed to create zonename property");
		goto error;
	}
	if (devctl_ddef_int(ddef_hdl, "auto-assign-instance", 1) == -1) {
		zerror(zlogp, B_TRUE, "failed to create auto-assign-instance "
		    "property");
		goto error;
	}
	if (devctl_ddef_int(ddef_hdl, "ddi-no-autodetach", 1) == -1) {
		zerror(zlogp, B_TRUE, "failed to create ddi-no-auto-detach "
		    "property");
		goto error;
	}
	if (devctl_bus_dev_create(bus_hdl, ddef_hdl, 0, &dev_hdl) == -1) {
		zerror(zlogp, B_TRUE, "failed to create console node");
		goto error;
	}

devlinks:
	if ((dl = di_devlink_init("zcons", DI_MAKE_LINK)) != NULL) {
		(void) di_devlink_fini(&dl);
	} else {
		zerror(zlogp, B_TRUE, "failed to create devlinks");
		goto error;
	}

	/*
	 * Open the master side of the console and issue the ZC_HOLDSLAVE ioctl,
	 * which will cause the master to retain a reference to the slave.
	 * This prevents ttymon from blowing through the slave's STREAMS anchor.
	 *
	 * In very rare cases the open returns ENOENT if devfs doesn't have
	 * everything setup yet due to heavy zone startup load. Wait for
	 * 1 sec. and retry a few times. Even if we can't setup the zone's
	 * console, we still go ahead and boot the zone.
	 */
	(void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
	    zone_name, ZCONS_MASTER_NAME);
	for (i = 0; i < ZCONS_RETRY; i++) {
		masterfd = open(conspath, O_RDWR | O_NOCTTY);
		if (masterfd >= 0 || errno != ENOENT)
			break;
		(void) sleep(1);
	}
	if (masterfd == -1) {
		zerror(zlogp, B_TRUE, "ERROR: could not open master side of "
		    "zone console for %s to acquire slave handle", zone_name);
		master_zcons_failed = B_TRUE;
	}

	(void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
	    zone_name, ZCONS_SLAVE_NAME);
	for (i = 0; i < ZCONS_RETRY; i++) {
		slavefd = open(conspath, O_RDWR | O_NOCTTY);
		if (slavefd >= 0 || errno != ENOENT)
			break;
		(void) sleep(1);
	}
	if (slavefd == -1)
		zerror(zlogp, B_TRUE, "ERROR: could not open slave side of zone"
		    " console for %s to acquire slave handle", zone_name);

	/*
	 * This ioctl can occasionally return ENXIO if devfs doesn't have
	 * everything plumbed up yet due to heavy zone startup load. Wait for
	 * 1 sec. and retry a few times before we fail to boot the zone.
	 */
	if (masterfd != -1 && slavefd != -1) {
		for (i = 0; i < ZCONS_RETRY; i++) {
			if (ioctl(masterfd, ZC_HOLDSLAVE,
			    (caddr_t)(intptr_t)slavefd) == 0) {
				rv = 0;
				break;
			} else if (errno != ENXIO) {
				break;
			}
			(void) sleep(1);
		}
		if (rv != 0)
			zerror(zlogp, B_TRUE, "ERROR: error while acquiring "
			    "slave handle of zone console for %s", zone_name);
	}

	if (slavefd != -1)
		(void) close(slavefd);
	if (masterfd != -1)
		(void) close(masterfd);

error:
	if (ddef_hdl)
		devctl_ddef_free(ddef_hdl);
	if (bus_hdl)
		devctl_release(bus_hdl);
	if (dev_hdl)
		devctl_release(dev_hdl);
	return (rv);
}