538 return (req);
539 }
540
541 /*
542 * Update the db entry with name "entryname" using information from "linkp".
543 */
544 static int
545 dlmgmt_db_update(dlmgmt_db_op_t op, const char *entryname, dlmgmt_link_t *linkp,
546 uint32_t flags)
547 {
548 dlmgmt_db_req_t *req;
549 int err;
550
551 /* It is either a persistent request or an active request, not both. */
552 assert((flags == DLMGMT_PERSIST) || (flags == DLMGMT_ACTIVE));
553
554 if ((req = dlmgmt_db_req_alloc(op, entryname, linkp->ll_linkid,
555 linkp->ll_zoneid, flags, &err)) == NULL)
556 return (err);
557
558 /* If transient op and onloan, use the global zone cache file. */
559 if (flags == DLMGMT_ACTIVE && linkp->ll_onloan)
560 req->ls_zoneid = GLOBAL_ZONEID;
561
562 /*
563 * If the return error is EINPROGRESS, this request is handled
564 * asynchronously; return success.
565 */
566 err = dlmgmt_process_db_req(req);
567 if (err != EINPROGRESS)
568 free(req);
569 else
570 err = 0;
571 return (err);
572 }
573
574 #define DLMGMT_DB_OP_STR(op) \
575 (((op) == DLMGMT_DB_OP_READ) ? "read" : \
576 (((op) == DLMGMT_DB_OP_WRITE) ? "write" : "delete"))
577
578 #define DLMGMT_DB_CONF_STR(flag) \
579 (((flag) == DLMGMT_ACTIVE) ? "active" : \
580 (((flag) == DLMGMT_PERSIST) ? "persistent" : ""))
581
710 dlmgmt_table_unlock();
711 return (NULL);
712 }
713
714 static int
715 parse_linkprops(char *buf, dlmgmt_link_t *linkp)
716 {
717 boolean_t found_type = B_FALSE;
718 dladm_datatype_t type = DLADM_TYPE_STR;
719 int i, len;
720 char *curr;
721 char attr_name[MAXLINKATTRLEN];
722 size_t attr_buf_len = 0;
723 void *attr_buf = NULL;
724 boolean_t rename;
725
726 curr = buf;
727 len = strlen(buf);
728 attr_name[0] = '\0';
729 for (i = 0; i < len; i++) {
730 rename = B_FALSE;
731 char c = buf[i];
732 boolean_t match = (c == '=' ||
733 (c == ',' && !found_type) || c == ';');
734
735 /*
736 * Move to the next character if there is no match and
737 * if we have not reached the last character.
738 */
739 if (!match && i != len - 1)
740 continue;
741
742 if (match) {
743 /*
744 * NUL-terminate the string pointed to by 'curr'.
745 */
746 buf[i] = '\0';
747 if (*curr == '\0')
748 goto parse_fail;
749 }
750
751 if (attr_name[0] != '\0' && found_type) {
752 /*
753 * We get here after we have processed the "<prop>="
754 * pattern. The pattern we are now interested in is
1482 (void) snprintf(tdir, sizeof (tdir), "/native%s", cachefile);
1483 path = tdir;
1484 }
1485
1486 if (zone_file_exists(zoneroot, path)) {
1487 if ((err = dlmgmt_process_db_req(req)) != 0) {
1488 /*
1489 * If we get back ENOENT, that means that the active
1490 * configuration file doesn't exist yet, and is not an
1491 * error. We'll create it down below after we've
1492 * loaded the persistent configuration.
1493 */
1494 if (err != ENOENT)
1495 goto done;
1496 boot = B_TRUE;
1497 }
1498 } else {
1499 boot = B_TRUE;
1500 }
1501
1502 if (zone_file_exists(zoneroot, DLMGMT_PERSISTENT_DB_PATH)) {
1503 req->ls_flags = DLMGMT_PERSIST;
1504 err = dlmgmt_process_db_req(req);
1505 if (err != 0 && err != ENOENT)
1506 goto done;
1507 }
1508 err = 0;
1509 if (rewrite_needed) {
1510 /*
1511 * First update links in memory, then dump the entire db to
1512 * disk.
1513 */
1514 dlmgmt_db_walk(zoneid, DATALINK_CLASS_ALL, dlmgmt_db_upgrade);
1515 req->ls_op = DLMGMT_DB_OP_WRITE;
1516 req->ls_linkid = DATALINK_ALL_LINKID;
1517 if ((err = dlmgmt_process_db_req(req)) != 0 &&
1518 err != EINPROGRESS)
1519 goto done;
1520 }
1521 if (boot) {
1522 dlmgmt_db_walk(zoneid, DATALINK_CLASS_PHYS,
1523 dlmgmt_db_phys_activate);
1524 }
1525
1526 done:
1527 if (err == EINPROGRESS)
1545 dlmgmt_link_t *linkp = avl_first(&dlmgmt_name_avl), *next_linkp;
1546
1547 while (linkp != NULL) {
1548 next_linkp = AVL_NEXT(&dlmgmt_name_avl, linkp);
1549 if (linkp->ll_zoneid == zoneid) {
1550 boolean_t onloan = linkp->ll_onloan;
1551
1552 /*
1553 * Cleanup any VNICs that were loaned to the zone
1554 * before the zone goes away and we can no longer
1555 * refer to the VNIC by the name/zoneid.
1556 */
1557 if (onloan) {
1558 (void) dlmgmt_delete_db_entry(linkp,
1559 DLMGMT_ACTIVE);
1560 linkp->ll_tomb = B_TRUE;
1561 } else {
1562 (void) dlmgmt_destroy_common(linkp,
1563 DLMGMT_ACTIVE | DLMGMT_PERSIST);
1564 }
1565
1566 }
1567 linkp = next_linkp;
1568 }
1569
1570 again:
1571 linkp = avl_first(&dlmgmt_name_avl);
1572 while (linkp != NULL) {
1573 vnic_ioc_delete_t ioc;
1574
1575 next_linkp = AVL_NEXT(&dlmgmt_name_avl, linkp);
1576
1577 if (linkp->ll_zoneid != zoneid) {
1578 linkp = next_linkp;
1579 continue;
1580 }
1581 ioc.vd_vnic_id = linkp->ll_linkid;
1582 if (linkp->ll_tomb != B_TRUE)
1583 abort();
1584
1585 /*
|
538 return (req);
539 }
540
541 /*
542 * Update the db entry with name "entryname" using information from "linkp".
543 */
544 static int
545 dlmgmt_db_update(dlmgmt_db_op_t op, const char *entryname, dlmgmt_link_t *linkp,
546 uint32_t flags)
547 {
548 dlmgmt_db_req_t *req;
549 int err;
550
551 /* It is either a persistent request or an active request, not both. */
552 assert((flags == DLMGMT_PERSIST) || (flags == DLMGMT_ACTIVE));
553
554 if ((req = dlmgmt_db_req_alloc(op, entryname, linkp->ll_linkid,
555 linkp->ll_zoneid, flags, &err)) == NULL)
556 return (err);
557
558 /*
559 * If the return error is EINPROGRESS, this request is handled
560 * asynchronously; return success.
561 */
562 err = dlmgmt_process_db_req(req);
563 if (err != EINPROGRESS)
564 free(req);
565 else
566 err = 0;
567 return (err);
568 }
569
570 #define DLMGMT_DB_OP_STR(op) \
571 (((op) == DLMGMT_DB_OP_READ) ? "read" : \
572 (((op) == DLMGMT_DB_OP_WRITE) ? "write" : "delete"))
573
574 #define DLMGMT_DB_CONF_STR(flag) \
575 (((flag) == DLMGMT_ACTIVE) ? "active" : \
576 (((flag) == DLMGMT_PERSIST) ? "persistent" : ""))
577
706 dlmgmt_table_unlock();
707 return (NULL);
708 }
709
710 static int
711 parse_linkprops(char *buf, dlmgmt_link_t *linkp)
712 {
713 boolean_t found_type = B_FALSE;
714 dladm_datatype_t type = DLADM_TYPE_STR;
715 int i, len;
716 char *curr;
717 char attr_name[MAXLINKATTRLEN];
718 size_t attr_buf_len = 0;
719 void *attr_buf = NULL;
720 boolean_t rename;
721
722 curr = buf;
723 len = strlen(buf);
724 attr_name[0] = '\0';
725 for (i = 0; i < len; i++) {
726 char c = buf[i];
727 boolean_t match = (c == '=' ||
728 (c == ',' && !found_type) || c == ';');
729
730 rename = B_FALSE;
731 /*
732 * Move to the next character if there is no match and
733 * if we have not reached the last character.
734 */
735 if (!match && i != len - 1)
736 continue;
737
738 if (match) {
739 /*
740 * NUL-terminate the string pointed to by 'curr'.
741 */
742 buf[i] = '\0';
743 if (*curr == '\0')
744 goto parse_fail;
745 }
746
747 if (attr_name[0] != '\0' && found_type) {
748 /*
749 * We get here after we have processed the "<prop>="
750 * pattern. The pattern we are now interested in is
1478 (void) snprintf(tdir, sizeof (tdir), "/native%s", cachefile);
1479 path = tdir;
1480 }
1481
1482 if (zone_file_exists(zoneroot, path)) {
1483 if ((err = dlmgmt_process_db_req(req)) != 0) {
1484 /*
1485 * If we get back ENOENT, that means that the active
1486 * configuration file doesn't exist yet, and is not an
1487 * error. We'll create it down below after we've
1488 * loaded the persistent configuration.
1489 */
1490 if (err != ENOENT)
1491 goto done;
1492 boot = B_TRUE;
1493 }
1494 } else {
1495 boot = B_TRUE;
1496 }
1497
1498 req->ls_flags = DLMGMT_PERSIST;
1499 err = dlmgmt_process_db_req(req);
1500 if (err != 0 && err != ENOENT)
1501 goto done;
1502 err = 0;
1503 if (rewrite_needed) {
1504 /*
1505 * First update links in memory, then dump the entire db to
1506 * disk.
1507 */
1508 dlmgmt_db_walk(zoneid, DATALINK_CLASS_ALL, dlmgmt_db_upgrade);
1509 req->ls_op = DLMGMT_DB_OP_WRITE;
1510 req->ls_linkid = DATALINK_ALL_LINKID;
1511 if ((err = dlmgmt_process_db_req(req)) != 0 &&
1512 err != EINPROGRESS)
1513 goto done;
1514 }
1515 if (boot) {
1516 dlmgmt_db_walk(zoneid, DATALINK_CLASS_PHYS,
1517 dlmgmt_db_phys_activate);
1518 }
1519
1520 done:
1521 if (err == EINPROGRESS)
1539 dlmgmt_link_t *linkp = avl_first(&dlmgmt_name_avl), *next_linkp;
1540
1541 while (linkp != NULL) {
1542 next_linkp = AVL_NEXT(&dlmgmt_name_avl, linkp);
1543 if (linkp->ll_zoneid == zoneid) {
1544 boolean_t onloan = linkp->ll_onloan;
1545
1546 /*
1547 * Cleanup any VNICs that were loaned to the zone
1548 * before the zone goes away and we can no longer
1549 * refer to the VNIC by the name/zoneid.
1550 */
1551 if (onloan) {
1552 (void) dlmgmt_delete_db_entry(linkp,
1553 DLMGMT_ACTIVE);
1554 linkp->ll_tomb = B_TRUE;
1555 } else {
1556 (void) dlmgmt_destroy_common(linkp,
1557 DLMGMT_ACTIVE | DLMGMT_PERSIST);
1558 }
1559 }
1560 linkp = next_linkp;
1561 }
1562
1563 again:
1564 linkp = avl_first(&dlmgmt_name_avl);
1565 while (linkp != NULL) {
1566 vnic_ioc_delete_t ioc;
1567
1568 next_linkp = AVL_NEXT(&dlmgmt_name_avl, linkp);
1569
1570 if (linkp->ll_zoneid != zoneid) {
1571 linkp = next_linkp;
1572 continue;
1573 }
1574 ioc.vd_vnic_id = linkp->ll_linkid;
1575 if (linkp->ll_tomb != B_TRUE)
1576 abort();
1577
1578 /*
|