309 }
310
311 (void) di_walk_node(root, DI_WALK_CLDFIRST, (void *)&cb, destroy_cb);
312 if (cb.found > 1) {
313 zerror(zlogp, B_FALSE, "WARNING: multiple zone console "
314 "instances detected for zone '%s'; %d of %d "
315 "successfully removed.",
316 zone_name, cb.killed, cb.found);
317 }
318
319 di_fini(root);
320 return (0);
321 }
322
323 /*
324 * init_console_dev() drives the device-tree configuration of the zone
325 * console device. The general strategy is to use the libdevice (devctl)
326 * interfaces to instantiate a new zone console node. We do a lot of
327 * sanity checking, and are careful to reuse a console if one exists.
328 *
329 * Once the device is in the device tree, we kick devfsadm via di_devlink_init()
330 * to ensure that the appropriate symlinks (to the master and slave console
331 * devices) are placed in /dev in the global zone.
332 */
333 static int
334 init_console_dev(zlog_t *zlogp)
335 {
336 char conspath[MAXPATHLEN];
337 devctl_hdl_t bus_hdl = NULL;
338 devctl_hdl_t dev_hdl = NULL;
339 devctl_ddef_t ddef_hdl = NULL;
340 di_devlink_handle_t dl = NULL;
341 int rv = -1;
342 int ndevs;
343 int masterfd;
344 int slavefd;
345 int i;
346
347 /*
348 * Don't re-setup console if it is working and ready already; just
349 * skip ahead to making devlinks, which we do for sanity's sake.
403 devlinks:
404 if ((dl = di_devlink_init("zcons", DI_MAKE_LINK)) != NULL) {
405 (void) di_devlink_fini(&dl);
406 } else {
407 zerror(zlogp, B_TRUE, "failed to create devlinks");
408 goto error;
409 }
410
411 /*
412 * Open the master side of the console and issue the ZC_HOLDSLAVE ioctl,
413 * which will cause the master to retain a reference to the slave.
414 * This prevents ttymon from blowing through the slave's STREAMS anchor.
415 *
416 * In very rare cases the open returns ENOENT if devfs doesn't have
417 * everything setup yet due to heavy zone startup load. Wait for
418 * 1 sec. and retry a few times. Even if we can't setup the zone's
419 * console, we still go ahead and boot the zone.
420 */
421 (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
422 zone_name, ZCONS_MASTER_NAME);
423 for (i = 0; i < ZCONS_RETRY; i++) {
424 masterfd = open(conspath, O_RDWR | O_NOCTTY);
425 if (masterfd >= 0 || errno != ENOENT)
426 break;
427 (void) sleep(1);
428 }
429 if (masterfd == -1) {
430 zerror(zlogp, B_TRUE, "ERROR: could not open master side of "
431 "zone console for %s to acquire slave handle", zone_name);
432 master_zcons_failed = B_TRUE;
433 }
434
435 (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
436 zone_name, ZCONS_SLAVE_NAME);
437 for (i = 0; i < ZCONS_RETRY; i++) {
438 slavefd = open(conspath, O_RDWR | O_NOCTTY);
439 if (slavefd >= 0 || errno != ENOENT)
440 break;
441 (void) sleep(1);
442 }
443 if (slavefd == -1)
444 zerror(zlogp, B_TRUE, "ERROR: could not open slave side of zone"
445 " console for %s to acquire slave handle", zone_name);
446
447 /*
448 * This ioctl can occasionally return ENXIO if devfs doesn't have
449 * everything plumbed up yet due to heavy zone startup load. Wait for
450 * 1 sec. and retry a few times before we fail to boot the zone.
451 */
452 if (masterfd != -1 && slavefd != -1) {
453 for (i = 0; i < ZCONS_RETRY; i++) {
454 if (ioctl(masterfd, ZC_HOLDSLAVE,
|
309 }
310
311 (void) di_walk_node(root, DI_WALK_CLDFIRST, (void *)&cb, destroy_cb);
312 if (cb.found > 1) {
313 zerror(zlogp, B_FALSE, "WARNING: multiple zone console "
314 "instances detected for zone '%s'; %d of %d "
315 "successfully removed.",
316 zone_name, cb.killed, cb.found);
317 }
318
319 di_fini(root);
320 return (0);
321 }
322
323 /*
324 * init_console_dev() drives the device-tree configuration of the zone
325 * console device. The general strategy is to use the libdevice (devctl)
326 * interfaces to instantiate a new zone console node. We do a lot of
327 * sanity checking, and are careful to reuse a console if one exists.
328 *
329 * Once the device is in the device tree, we kick devfsadm via di_init_devs()
330 * to ensure that the appropriate symlinks (to the master and slave console
331 * devices) are placed in /dev in the global zone.
332 */
333 static int
334 init_console_dev(zlog_t *zlogp)
335 {
336 char conspath[MAXPATHLEN];
337 devctl_hdl_t bus_hdl = NULL;
338 devctl_hdl_t dev_hdl = NULL;
339 devctl_ddef_t ddef_hdl = NULL;
340 di_devlink_handle_t dl = NULL;
341 int rv = -1;
342 int ndevs;
343 int masterfd;
344 int slavefd;
345 int i;
346
347 /*
348 * Don't re-setup console if it is working and ready already; just
349 * skip ahead to making devlinks, which we do for sanity's sake.
403 devlinks:
404 if ((dl = di_devlink_init("zcons", DI_MAKE_LINK)) != NULL) {
405 (void) di_devlink_fini(&dl);
406 } else {
407 zerror(zlogp, B_TRUE, "failed to create devlinks");
408 goto error;
409 }
410
411 /*
412 * Open the master side of the console and issue the ZC_HOLDSLAVE ioctl,
413 * which will cause the master to retain a reference to the slave.
414 * This prevents ttymon from blowing through the slave's STREAMS anchor.
415 *
416 * In very rare cases the open returns ENOENT if devfs doesn't have
417 * everything setup yet due to heavy zone startup load. Wait for
418 * 1 sec. and retry a few times. Even if we can't setup the zone's
419 * console, we still go ahead and boot the zone.
420 */
421 (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
422 zone_name, ZCONS_MASTER_NAME);
423 if ((masterfd = open(conspath, O_RDWR | O_NOCTTY)) == -1) {
424 zerror(zlogp, B_TRUE, "ERROR: could not open master side of "
425 "zone console for %s to acquire slave handle", zone_name);
426 master_zcons_failed = B_TRUE;
427 }
428 (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
429 zone_name, ZCONS_SLAVE_NAME);
430 for (i = 0; i < ZCONS_RETRY; i++) {
431 slavefd = open(conspath, O_RDWR | O_NOCTTY);
432 if (slavefd >= 0 || errno != ENOENT)
433 break;
434 (void) sleep(1);
435 }
436 if (slavefd == -1)
437 zerror(zlogp, B_TRUE, "ERROR: could not open slave side of zone"
438 " console for %s to acquire slave handle", zone_name);
439
440 /*
441 * This ioctl can occasionally return ENXIO if devfs doesn't have
442 * everything plumbed up yet due to heavy zone startup load. Wait for
443 * 1 sec. and retry a few times before we fail to boot the zone.
444 */
445 if (masterfd != -1 && slavefd != -1) {
446 for (i = 0; i < ZCONS_RETRY; i++) {
447 if (ioctl(masterfd, ZC_HOLDSLAVE,
|