libzonecfg.c (4229:1adcbd8dd1f0) | libzonecfg.c (5829:20241b1ccadc) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 6 unchanged lines hidden (view full) --- 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 6 unchanged lines hidden (view full) --- 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* |
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. | 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. |
24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29#include <libsysevent.h> 30#include <pthread.h> 31#include <stdlib.h> --- 52 unchanged lines hidden (view full) --- 84#define DTD_ELEM_RCTLVALUE (const xmlChar *) "rctl-value" 85#define DTD_ELEM_ZONE (const xmlChar *) "zone" 86#define DTD_ELEM_DATASET (const xmlChar *) "dataset" 87#define DTD_ELEM_TMPPOOL (const xmlChar *) "tmp_pool" 88#define DTD_ELEM_PSET (const xmlChar *) "pset" 89#define DTD_ELEM_MCAP (const xmlChar *) "mcap" 90#define DTD_ELEM_PACKAGE (const xmlChar *) "package" 91#define DTD_ELEM_PATCH (const xmlChar *) "patch" | 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29#include <libsysevent.h> 30#include <pthread.h> 31#include <stdlib.h> --- 52 unchanged lines hidden (view full) --- 84#define DTD_ELEM_RCTLVALUE (const xmlChar *) "rctl-value" 85#define DTD_ELEM_ZONE (const xmlChar *) "zone" 86#define DTD_ELEM_DATASET (const xmlChar *) "dataset" 87#define DTD_ELEM_TMPPOOL (const xmlChar *) "tmp_pool" 88#define DTD_ELEM_PSET (const xmlChar *) "pset" 89#define DTD_ELEM_MCAP (const xmlChar *) "mcap" 90#define DTD_ELEM_PACKAGE (const xmlChar *) "package" 91#define DTD_ELEM_PATCH (const xmlChar *) "patch" |
92#define DTD_ELEM_OBSOLETES (const xmlChar *) "obsoletes" |
|
92#define DTD_ELEM_DEV_PERM (const xmlChar *) "dev-perm" 93 94#define DTD_ATTR_ACTION (const xmlChar *) "action" 95#define DTD_ATTR_ADDRESS (const xmlChar *) "address" 96#define DTD_ATTR_AUTOBOOT (const xmlChar *) "autoboot" 97#define DTD_ATTR_IPTYPE (const xmlChar *) "ip-type" 98#define DTD_ATTR_DIR (const xmlChar *) "directory" 99#define DTD_ATTR_LIMIT (const xmlChar *) "limit" --- 121 unchanged lines hidden (view full) --- 221 char *zpi_version; 222 char **zpi_patchinfo; 223}; 224 225typedef struct { 226 uu_avl_node_t patch_node; 227 char *patch_num; 228 char *patch_vers; | 93#define DTD_ELEM_DEV_PERM (const xmlChar *) "dev-perm" 94 95#define DTD_ATTR_ACTION (const xmlChar *) "action" 96#define DTD_ATTR_ADDRESS (const xmlChar *) "address" 97#define DTD_ATTR_AUTOBOOT (const xmlChar *) "autoboot" 98#define DTD_ATTR_IPTYPE (const xmlChar *) "ip-type" 99#define DTD_ATTR_DIR (const xmlChar *) "directory" 100#define DTD_ATTR_LIMIT (const xmlChar *) "limit" --- 121 unchanged lines hidden (view full) --- 222 char *zpi_version; 223 char **zpi_patchinfo; 224}; 225 226typedef struct { 227 uu_avl_node_t patch_node; 228 char *patch_num; 229 char *patch_vers; |
230 uu_list_t *obs_patches; |
|
229} patch_node_t; 230 231typedef struct { | 231} patch_node_t; 232 233typedef struct { |
234 uu_list_node_t link; 235 char *patch_num; 236} obs_patch_node_t; 237 238typedef struct { |
|
232 uu_avl_t *obs_patches_avl; 233 zone_dochandle_t handle; 234 int res; 235} patch_parms_t; 236 237char *zonecfg_root = ""; 238 239/* --- 6259 unchanged lines hidden (view full) --- 6499 6500 err = getmcapent_core(handle, tabptr); 6501 6502 (void) zonecfg_endent(handle); 6503 6504 return (err); 6505} 6506 | 239 uu_avl_t *obs_patches_avl; 240 zone_dochandle_t handle; 241 int res; 242} patch_parms_t; 243 244char *zonecfg_root = ""; 245 246/* --- 6259 unchanged lines hidden (view full) --- 6506 6507 err = getmcapent_core(handle, tabptr); 6508 6509 (void) zonecfg_endent(handle); 6510 6511 return (err); 6512} 6513 |
6514/* 6515 * Get the full tree of pkg/patch metadata in a set of nested AVL trees. 6516 * pkgs_avl is an AVL tree of pkgs. Each pkg element contains a 6517 * zpe_patches_avl member which holds an AVL tree of patches for that pkg. 6518 * The patch elements have the same zpe_patches_avl member, each of which can 6519 * hold an AVL tree of patches that are obsoleted by the patch. 6520 * 6521 * The zone xml data contains DTD_ELEM_PACKAGE elements, followed by 6522 * DTD_ELEM_PATCH elements. The DTD_ELEM_PATCH patch element applies to the 6523 * DTD_ELEM_PACKAGE that precedes it. The DTD_ELEM_PATCH element may have 6524 * child DTD_ELEM_OBSOLETES nodes associated with it. The DTD_ELEM_PACKAGE 6525 * really should have had the DTD_ELEM_PATCH elements as children but it 6526 * was not defined that way initially so we are stuck with the DTD definition 6527 * now. However, we can safely assume the ordering for compatibility. 6528 */ |
|
6507int | 6529int |
6508zonecfg_setpkgent(zone_dochandle_t handle) | 6530zonecfg_getpkgdata(zone_dochandle_t handle, uu_avl_pool_t *pkg_pool, 6531 uu_avl_t *pkgs_avl) |
6509{ | 6532{ |
6510 return (zonecfg_setent(handle)); 6511} 6512 6513int 6514zonecfg_getpkgent(zone_dochandle_t handle, struct zone_pkgtab *tabptr) 6515{ | |
6516 xmlNodePtr cur; | 6533 xmlNodePtr cur; |
6517 int err; | 6534 int res; 6535 zone_pkg_entry_t *pkg; 6536 char name[MAXNAMELEN]; 6537 char version[ZONE_PKG_VERSMAX]; |
6518 6519 if (handle == NULL) 6520 return (Z_INVAL); 6521 | 6538 6539 if (handle == NULL) 6540 return (Z_INVAL); 6541 |
6522 if ((cur = handle->zone_dh_cur) == NULL) 6523 return (Z_NO_ENTRY); | 6542 if ((res = zonecfg_setent(handle)) != Z_OK) 6543 return (res); |
6524 | 6544 |
6525 for (; cur != NULL; cur = cur->next) 6526 if (!xmlStrcmp(cur->name, DTD_ELEM_PACKAGE)) 6527 break; 6528 if (cur == NULL) { 6529 handle->zone_dh_cur = handle->zone_dh_top; 6530 return (Z_NO_ENTRY); | 6545 if ((cur = handle->zone_dh_cur) == NULL) { 6546 res = Z_NO_ENTRY; 6547 goto done; |
6531 } 6532 | 6548 } 6549 |
6533 if ((err = fetchprop(cur, DTD_ATTR_NAME, tabptr->zone_pkg_name, 6534 sizeof (tabptr->zone_pkg_name))) != Z_OK) { 6535 handle->zone_dh_cur = handle->zone_dh_top; 6536 return (err); 6537 } | 6550 for (; cur != NULL; cur = cur->next) { 6551 if (xmlStrcmp(cur->name, DTD_ELEM_PACKAGE) == 0) { 6552 uu_avl_index_t where; |
6538 | 6553 |
6539 if ((err = fetchprop(cur, DTD_ATTR_VERSION, tabptr->zone_pkg_version, 6540 sizeof (tabptr->zone_pkg_version))) != Z_OK) { 6541 handle->zone_dh_cur = handle->zone_dh_top; 6542 return (err); 6543 } | 6554 if ((res = fetchprop(cur, DTD_ATTR_NAME, name, 6555 sizeof (name))) != Z_OK) 6556 goto done; |
6544 | 6557 |
6545 handle->zone_dh_cur = cur->next; 6546 return (Z_OK); 6547} | 6558 if ((res = fetchprop(cur, DTD_ATTR_VERSION, version, 6559 sizeof (version))) != Z_OK) 6560 goto done; |
6548 | 6561 |
6549int 6550zonecfg_endpkgent(zone_dochandle_t handle) 6551{ 6552 return (zonecfg_endent(handle)); 6553} | 6562 if ((pkg = (zone_pkg_entry_t *) 6563 malloc(sizeof (zone_pkg_entry_t))) == NULL) { 6564 res = Z_NOMEM; 6565 goto done; 6566 } |
6554 | 6567 |
6555int 6556zonecfg_setpatchent(zone_dochandle_t handle) 6557{ 6558 return (zonecfg_setent(handle)); 6559} | 6568 if ((pkg->zpe_name = strdup(name)) == NULL) { 6569 free(pkg); 6570 res = Z_NOMEM; 6571 goto done; 6572 } |
6560 | 6573 |
6561int 6562zonecfg_getpatchent(zone_dochandle_t handle, struct zone_patchtab *tabptr) 6563{ 6564 xmlNodePtr cur; 6565 int err; | 6574 if ((pkg->zpe_vers = strdup(version)) == NULL) { 6575 free(pkg->zpe_name); 6576 free(pkg); 6577 res = Z_NOMEM; 6578 goto done; 6579 } |
6566 | 6580 |
6567 if (handle == NULL) 6568 return (Z_INVAL); | 6581 pkg->zpe_patches_avl = NULL; |
6569 | 6582 |
6570 if ((cur = handle->zone_dh_cur) == NULL) 6571 return (Z_NO_ENTRY); | 6583 uu_avl_node_init(pkg, &pkg->zpe_entry, pkg_pool); 6584 if (uu_avl_find(pkgs_avl, pkg, NULL, &where) != NULL) { 6585 free(pkg->zpe_name); 6586 free(pkg->zpe_vers); 6587 free(pkg); 6588 } else { 6589 uu_avl_insert(pkgs_avl, pkg, where); 6590 } |
6572 | 6591 |
6573 for (; cur != NULL; cur = cur->next) 6574 if (!xmlStrcmp(cur->name, DTD_ELEM_PATCH)) 6575 break; 6576 if (cur == NULL) { 6577 handle->zone_dh_cur = handle->zone_dh_top; 6578 return (Z_NO_ENTRY); 6579 } | 6592 } else if (xmlStrcmp(cur->name, DTD_ELEM_PATCH) == 0) { 6593 zone_pkg_entry_t *patch; 6594 uu_avl_index_t where; 6595 char *p; 6596 char *dashp = NULL; 6597 xmlNodePtr child; |
6580 | 6598 |
6581 if ((err = fetchprop(cur, DTD_ATTR_ID, tabptr->zone_patch_id, 6582 sizeof (tabptr->zone_patch_id))) != Z_OK) { 6583 handle->zone_dh_cur = handle->zone_dh_top; 6584 return (err); | 6599 if ((res = fetchprop(cur, DTD_ATTR_ID, name, 6600 sizeof (name))) != Z_OK) 6601 goto done; 6602 6603 if ((patch = (zone_pkg_entry_t *) 6604 malloc(sizeof (zone_pkg_entry_t))) == NULL) { 6605 res = Z_NOMEM; 6606 goto done; 6607 } 6608 6609 if ((p = strchr(name, '-')) != NULL) { 6610 dashp = p; 6611 *p++ = '\0'; 6612 } else { 6613 p = ""; 6614 } 6615 6616 if ((patch->zpe_name = strdup(name)) == NULL) { 6617 free(patch); 6618 res = Z_NOMEM; 6619 goto done; 6620 } 6621 6622 if ((patch->zpe_vers = strdup(p)) == NULL) { 6623 free(patch->zpe_name); 6624 free(patch); 6625 res = Z_NOMEM; 6626 goto done; 6627 } 6628 6629 if (dashp != NULL) 6630 *dashp = '-'; 6631 6632 patch->zpe_patches_avl = NULL; 6633 6634 if (pkg->zpe_patches_avl == NULL) { 6635 pkg->zpe_patches_avl = uu_avl_create(pkg_pool, 6636 NULL, UU_DEFAULT); 6637 if (pkg->zpe_patches_avl == NULL) { 6638 free(patch->zpe_name); 6639 free(patch->zpe_vers); 6640 free(patch); 6641 res = Z_NOMEM; 6642 goto done; 6643 } 6644 } 6645 6646 uu_avl_node_init(patch, &patch->zpe_entry, pkg_pool); 6647 if (uu_avl_find(pkg->zpe_patches_avl, patch, NULL, 6648 &where) != NULL) { 6649 free(patch->zpe_name); 6650 free(patch->zpe_vers); 6651 free(patch); 6652 } else { 6653 uu_avl_insert(pkg->zpe_patches_avl, patch, 6654 where); 6655 } 6656 6657 /* Add any patches this patch obsoletes. */ 6658 for (child = cur->xmlChildrenNode; child != NULL; 6659 child = child->next) { 6660 zone_pkg_entry_t *obs; 6661 6662 if (xmlStrcmp(child->name, DTD_ELEM_OBSOLETES) 6663 != 0) 6664 continue; 6665 6666 if ((res = fetchprop(child, DTD_ATTR_ID, 6667 name, sizeof (name))) != Z_OK) 6668 goto done; 6669 6670 if ((obs = (zone_pkg_entry_t *)malloc( 6671 sizeof (zone_pkg_entry_t))) == NULL) { 6672 res = Z_NOMEM; 6673 goto done; 6674 } 6675 6676 if ((obs->zpe_name = strdup(name)) == NULL) { 6677 free(obs); 6678 res = Z_NOMEM; 6679 goto done; 6680 } 6681 /* 6682 * The version doesn't matter for obsoleted 6683 * patches. 6684 */ 6685 obs->zpe_vers = NULL; 6686 obs->zpe_patches_avl = NULL; 6687 6688 /* 6689 * If this is the first obsolete patch, add an 6690 * AVL tree to the parent patch element. 6691 */ 6692 if (patch->zpe_patches_avl == NULL) { 6693 patch->zpe_patches_avl = 6694 uu_avl_create(pkg_pool, NULL, 6695 UU_DEFAULT); 6696 if (patch->zpe_patches_avl == NULL) { 6697 free(obs->zpe_name); 6698 free(obs); 6699 res = Z_NOMEM; 6700 goto done; 6701 } 6702 } 6703 6704 /* Insert obsolete patch into the AVL tree. */ 6705 uu_avl_node_init(obs, &obs->zpe_entry, 6706 pkg_pool); 6707 if (uu_avl_find(patch->zpe_patches_avl, obs, 6708 NULL, &where) != NULL) { 6709 free(obs->zpe_name); 6710 free(obs); 6711 } else { 6712 uu_avl_insert(patch->zpe_patches_avl, 6713 obs, where); 6714 } 6715 } 6716 } |
6585 } 6586 | 6717 } 6718 |
6587 handle->zone_dh_cur = cur->next; 6588 return (Z_OK); | 6719done: 6720 (void) zonecfg_endent(handle); 6721 return (res); |
6589} 6590 6591int | 6722} 6723 6724int |
6592zonecfg_endpatchent(zone_dochandle_t handle) 6593{ 6594 return (zonecfg_endent(handle)); 6595} 6596 6597int | |
6598zonecfg_setdevperment(zone_dochandle_t handle) 6599{ 6600 return (zonecfg_setent(handle)); 6601} 6602 6603int 6604zonecfg_getdevperment(zone_dochandle_t handle, struct zone_devpermtab *tabptr) 6605{ --- 454 unchanged lines hidden (view full) --- 7060 if (strcmp(pkg_name, pkg_list[i]) == 0) 7061 return (B_TRUE); 7062 } 7063 7064 return (B_FALSE); 7065} 7066 7067/* | 6725zonecfg_setdevperment(zone_dochandle_t handle) 6726{ 6727 return (zonecfg_setent(handle)); 6728} 6729 6730int 6731zonecfg_getdevperment(zone_dochandle_t handle, struct zone_devpermtab *tabptr) 6732{ --- 454 unchanged lines hidden (view full) --- 7187 if (strcmp(pkg_name, pkg_list[i]) == 0) 7188 return (B_TRUE); 7189 } 7190 7191 return (B_FALSE); 7192} 7193 7194/* |
7195 * Keep track of obsoleted patches for this specific patch. We don't need to 7196 * keep track of the patch version since once a patch is obsoleted, all prior 7197 * versions are also obsolete and there won't be any new versions. 7198 */ 7199static int 7200add_obs_patch(patch_node_t *patch, char *num, uu_list_pool_t *patches_pool) 7201{ 7202 obs_patch_node_t *obs; 7203 7204 if (patch->obs_patches == NULL) { 7205 if ((patch->obs_patches = uu_list_create(patches_pool, NULL, 7206 0)) == NULL) 7207 return (Z_NOMEM); 7208 } 7209 7210 if ((obs = (obs_patch_node_t *)malloc(sizeof (obs_patch_node_t))) 7211 == NULL) 7212 return (Z_NOMEM); 7213 7214 if ((obs->patch_num = strdup(num)) == NULL) { 7215 free(obs); 7216 return (Z_NOMEM); 7217 } 7218 7219 uu_list_node_init(obs, &obs->link, patches_pool); 7220 (void) uu_list_insert_before(patch->obs_patches, NULL, obs); 7221 7222 return (Z_OK); 7223} 7224 7225/* |
|
7068 * Keep track of obsoleted patches. We don't need to keep track of the patch 7069 * version since once a patch is obsoleted, all prior versions are also 7070 * obsolete and there won't be any new versions. 7071 */ 7072static int | 7226 * Keep track of obsoleted patches. We don't need to keep track of the patch 7227 * version since once a patch is obsoleted, all prior versions are also 7228 * obsolete and there won't be any new versions. 7229 */ 7230static int |
7073save_obs_patch(char *num, uu_avl_pool_t *patches_pool, 7074 uu_avl_t *obs_patches_avl) | 7231save_obs_patch(char *num, uu_avl_pool_t *patches_pool, uu_avl_t *obs_patches) |
7075{ 7076 patch_node_t *patch; 7077 uu_avl_index_t where; 7078 7079 if ((patch = (patch_node_t *)malloc(sizeof (patch_node_t))) == NULL) 7080 return (Z_NOMEM); 7081 7082 if ((patch->patch_num = strdup(num)) == NULL) { 7083 free(patch); 7084 return (Z_NOMEM); 7085 } 7086 7087 patch->patch_vers = NULL; | 7232{ 7233 patch_node_t *patch; 7234 uu_avl_index_t where; 7235 7236 if ((patch = (patch_node_t *)malloc(sizeof (patch_node_t))) == NULL) 7237 return (Z_NOMEM); 7238 7239 if ((patch->patch_num = strdup(num)) == NULL) { 7240 free(patch); 7241 return (Z_NOMEM); 7242 } 7243 7244 patch->patch_vers = NULL; |
7245 patch->obs_patches = NULL; 7246 |
|
7088 uu_avl_node_init(patch, &patch->patch_node, patches_pool); 7089 | 7247 uu_avl_node_init(patch, &patch->patch_node, patches_pool); 7248 |
7090 if (uu_avl_find(obs_patches_avl, patch, NULL, &where) != NULL) { | 7249 if (uu_avl_find(obs_patches, patch, NULL, &where) != NULL) { |
7091 free(patch->patch_num); 7092 free(patch); 7093 return (Z_OK); 7094 } 7095 | 7250 free(patch->patch_num); 7251 free(patch); 7252 return (Z_OK); 7253 } 7254 |
7096 uu_avl_insert(obs_patches_avl, patch, where); | 7255 uu_avl_insert(obs_patches, patch, where); |
7097 return (Z_OK); 7098} 7099 7100/* 7101 * Keep a list of patches for a pkg. If we see a newer version of a patch, 7102 * we only keep track of the newer version. 7103 */ 7104static void --- 24 unchanged lines hidden (view full) --- 7129} 7130 7131/* 7132 * Check if a patch is on the list of obsoleted patches. We don't need to 7133 * check the patch version since once a patch is obsoleted, all prior versions 7134 * are also obsolete and there won't be any new versions. 7135 */ 7136static boolean_t | 7256 return (Z_OK); 7257} 7258 7259/* 7260 * Keep a list of patches for a pkg. If we see a newer version of a patch, 7261 * we only keep track of the newer version. 7262 */ 7263static void --- 24 unchanged lines hidden (view full) --- 7288} 7289 7290/* 7291 * Check if a patch is on the list of obsoleted patches. We don't need to 7292 * check the patch version since once a patch is obsoleted, all prior versions 7293 * are also obsolete and there won't be any new versions. 7294 */ 7295static boolean_t |
7137obsolete_patch(patch_node_t *patch, uu_avl_t *obs_patches_avl) | 7296obsolete_patch(patch_node_t *patch, uu_avl_t *obs_patches) |
7138{ 7139 uu_avl_index_t where; 7140 | 7297{ 7298 uu_avl_index_t where; 7299 |
7141 if (uu_avl_find(obs_patches_avl, patch, NULL, &where) != NULL) | 7300 if (uu_avl_find(obs_patches, patch, NULL, &where) != NULL) |
7142 return (B_TRUE); 7143 7144 return (B_FALSE); 7145} 7146 7147/* ARGSUSED */ 7148static int 7149patch_node_compare(const void *l_arg, const void *r_arg, void *private) --- 17 unchanged lines hidden (view full) --- 7167 * Parse the patchinfo string for the patch. 7168 * 7169 * We are parsing entries of the form: 7170 * PATCH_INFO_121454-02=Installed: Wed Dec 7 07:13:51 PST 2005 From: mum \ 7171 * Obsoletes: 120777-03 121087-02 119108-07 Requires: 119575-02 \ 7172 * 119255-06 Incompatibles: 7173 * 7174 * A backed out patch will have "backed out\n" as the status. We should | 7301 return (B_TRUE); 7302 7303 return (B_FALSE); 7304} 7305 7306/* ARGSUSED */ 7307static int 7308patch_node_compare(const void *l_arg, const void *r_arg, void *private) --- 17 unchanged lines hidden (view full) --- 7326 * Parse the patchinfo string for the patch. 7327 * 7328 * We are parsing entries of the form: 7329 * PATCH_INFO_121454-02=Installed: Wed Dec 7 07:13:51 PST 2005 From: mum \ 7330 * Obsoletes: 120777-03 121087-02 119108-07 Requires: 119575-02 \ 7331 * 119255-06 Incompatibles: 7332 * 7333 * A backed out patch will have "backed out\n" as the status. We should |
7175 * skip these patches. We also also ignore any entries that seem to be 7176 * corrupted. | 7334 * skip these patches. We also ignore any entries that seem to be 7335 * corrupted. Obsolete patches are saved in the obs_patches parameter 7336 * AVL list. |
7177 */ 7178static int 7179parse_info(char *patchinfo, uu_avl_pool_t *patches_pool, uu_avl_t *patches_avl, | 7337 */ 7338static int 7339parse_info(char *patchinfo, uu_avl_pool_t *patches_pool, uu_avl_t *patches_avl, |
7180 uu_avl_t *obs_patches_avl) | 7340 uu_avl_t *obs_patches, uu_list_pool_t *list_pool) |
7181{ 7182 char *p; 7183 char *lastp; 7184 char *ep; 7185 char *pvers; 7186 boolean_t add_info = B_FALSE; 7187 patch_node_t *patch; 7188 --- 28 unchanged lines hidden (view full) --- 7217 free(patch); 7218 return (Z_NOMEM); 7219 } 7220 if ((patch->patch_vers = strdup(pvers)) == NULL) { 7221 free(patch->patch_num); 7222 free(patch); 7223 return (Z_NOMEM); 7224 } | 7341{ 7342 char *p; 7343 char *lastp; 7344 char *ep; 7345 char *pvers; 7346 boolean_t add_info = B_FALSE; 7347 patch_node_t *patch; 7348 --- 28 unchanged lines hidden (view full) --- 7377 free(patch); 7378 return (Z_NOMEM); 7379 } 7380 if ((patch->patch_vers = strdup(pvers)) == NULL) { 7381 free(patch->patch_num); 7382 free(patch); 7383 return (Z_NOMEM); 7384 } |
7385 patch->obs_patches = NULL; |
|
7225 7226 uu_avl_node_init(patch, &patch->patch_node, patches_pool); 7227 save_patch(patch, patches_avl); 7228 7229 /* 7230 * Start with the first token. This will probably be "Installed:". 7231 * If we can't tokenize this entry, just return. 7232 */ --- 13 unchanged lines hidden (view full) --- 7246 } 7247 7248 if (!add_info) 7249 continue; 7250 7251 if ((pvers = strchr(p, '-')) != NULL) 7252 *pvers = '\0'; 7253 | 7386 7387 uu_avl_node_init(patch, &patch->patch_node, patches_pool); 7388 save_patch(patch, patches_avl); 7389 7390 /* 7391 * Start with the first token. This will probably be "Installed:". 7392 * If we can't tokenize this entry, just return. 7393 */ --- 13 unchanged lines hidden (view full) --- 7407 } 7408 7409 if (!add_info) 7410 continue; 7411 7412 if ((pvers = strchr(p, '-')) != NULL) 7413 *pvers = '\0'; 7414 |
7254 if (save_obs_patch(p, patches_pool, obs_patches_avl) != Z_OK) | 7415 /* 7416 * We save all of the obsolete patches in one big list in the 7417 * obs_patches AVL tree so that we know not to output those as 7418 * part of the sw dependencies. However, we also need to save 7419 * the obsolete patch information for this sepcific patch so 7420 * so that we can do the cross manifest patch checking 7421 * correctly. 7422 */ 7423 if (save_obs_patch(p, patches_pool, obs_patches) != Z_OK) |
7255 return (Z_NOMEM); | 7424 return (Z_NOMEM); |
7425 if (add_obs_patch(patch, p, list_pool) != Z_OK) 7426 return (Z_NOMEM); |
|
7256 } while ((p = strtok_r(NULL, " ", &lastp)) != NULL); 7257 7258 return (Z_OK); 7259} 7260 7261/* 7262 * AVL walker callback used to add patch to XML manifest. 7263 * --- 25 unchanged lines hidden (view full) --- 7289 if ((args->res = operation_prep(args->handle)) != Z_OK) 7290 return (UU_WALK_DONE); 7291 7292 cur = args->handle->zone_dh_cur; 7293 node = xmlNewTextChild(cur, NULL, DTD_ELEM_PATCH, NULL); 7294 if ((args->res = newprop(node, DTD_ATTR_ID, id)) != Z_OK) 7295 return (UU_WALK_DONE); 7296 | 7427 } while ((p = strtok_r(NULL, " ", &lastp)) != NULL); 7428 7429 return (Z_OK); 7430} 7431 7432/* 7433 * AVL walker callback used to add patch to XML manifest. 7434 * --- 25 unchanged lines hidden (view full) --- 7460 if ((args->res = operation_prep(args->handle)) != Z_OK) 7461 return (UU_WALK_DONE); 7462 7463 cur = args->handle->zone_dh_cur; 7464 node = xmlNewTextChild(cur, NULL, DTD_ELEM_PATCH, NULL); 7465 if ((args->res = newprop(node, DTD_ATTR_ID, id)) != Z_OK) 7466 return (UU_WALK_DONE); 7467 |
7468 if (patch->obs_patches != NULL) { 7469 obs_patch_node_t *op; 7470 xmlNodePtr node2; 7471 7472 for (op = uu_list_first(patch->obs_patches); op != NULL; 7473 op = uu_list_next(patch->obs_patches, op)) { 7474 (void) snprintf(id, sizeof (id), "%s", op->patch_num); 7475 node2 = xmlNewTextChild(node, NULL, DTD_ELEM_OBSOLETES, 7476 NULL); 7477 if ((args->res = newprop(node2, DTD_ATTR_ID, id)) 7478 != Z_OK) 7479 return (UU_WALK_DONE); 7480 } 7481 } 7482 |
|
7297 return (UU_WALK_NEXT); 7298} 7299 7300static void 7301patch_avl_delete(uu_avl_t *patches_avl) 7302{ 7303 if (patches_avl != NULL) { 7304 patch_node_t *p; 7305 void *cookie = NULL; 7306 7307 while ((p = (patch_node_t *)uu_avl_teardown(patches_avl, 7308 &cookie)) != NULL) { 7309 free(p->patch_num); 7310 free(p->patch_vers); | 7483 return (UU_WALK_NEXT); 7484} 7485 7486static void 7487patch_avl_delete(uu_avl_t *patches_avl) 7488{ 7489 if (patches_avl != NULL) { 7490 patch_node_t *p; 7491 void *cookie = NULL; 7492 7493 while ((p = (patch_node_t *)uu_avl_teardown(patches_avl, 7494 &cookie)) != NULL) { 7495 free(p->patch_num); 7496 free(p->patch_vers); |
7497 7498 if (p->obs_patches != NULL) { 7499 obs_patch_node_t *op; 7500 void *cookie2 = NULL; 7501 7502 while ((op = uu_list_teardown(p->obs_patches, 7503 &cookie2)) != NULL) { 7504 free(op->patch_num); 7505 free(op); 7506 } 7507 uu_list_destroy(p->obs_patches); 7508 } 7509 |
|
7311 free(p); 7312 } 7313 7314 uu_avl_destroy(patches_avl); 7315 } 7316} 7317 7318/* 7319 * Add the unique, highest version patches that are associated with this pkg 7320 * to the sw inventory on the handle. 7321 */ 7322static int 7323add_patches(zone_dochandle_t handle, struct zone_pkginfo *infop, | 7510 free(p); 7511 } 7512 7513 uu_avl_destroy(patches_avl); 7514 } 7515} 7516 7517/* 7518 * Add the unique, highest version patches that are associated with this pkg 7519 * to the sw inventory on the handle. 7520 */ 7521static int 7522add_patches(zone_dochandle_t handle, struct zone_pkginfo *infop, |
7324 uu_avl_pool_t *patches_pool, uu_avl_t *obs_patches_avl) | 7523 uu_avl_pool_t *patches_pool, uu_avl_t *obs_patches, 7524 uu_list_pool_t *list_pool) |
7325{ 7326 int i; 7327 int res; 7328 uu_avl_t *patches_avl; 7329 patch_parms_t args; 7330 7331 if ((patches_avl = uu_avl_create(patches_pool, NULL, UU_DEFAULT)) 7332 == NULL) 7333 return (Z_NOMEM); 7334 7335 for (i = 0; i < infop->zpi_patch_cnt; i++) { 7336 if ((res = parse_info(infop->zpi_patchinfo[i], patches_pool, | 7525{ 7526 int i; 7527 int res; 7528 uu_avl_t *patches_avl; 7529 patch_parms_t args; 7530 7531 if ((patches_avl = uu_avl_create(patches_pool, NULL, UU_DEFAULT)) 7532 == NULL) 7533 return (Z_NOMEM); 7534 7535 for (i = 0; i < infop->zpi_patch_cnt; i++) { 7536 if ((res = parse_info(infop->zpi_patchinfo[i], patches_pool, |
7337 patches_avl, obs_patches_avl)) != Z_OK) { | 7537 patches_avl, obs_patches, list_pool)) != Z_OK) { |
7338 patch_avl_delete(patches_avl); 7339 return (res); 7340 } 7341 } 7342 | 7538 patch_avl_delete(patches_avl); 7539 return (res); 7540 } 7541 } 7542 |
7343 args.obs_patches_avl = obs_patches_avl; | 7543 args.obs_patches_avl = obs_patches; |
7344 args.handle = handle; 7345 args.res = Z_OK; 7346 7347 (void) uu_avl_walk(patches_avl, add_patch, &args, 0); 7348 7349 patch_avl_delete(patches_avl); 7350 return (args.res); 7351} 7352 7353/* | 7544 args.handle = handle; 7545 args.res = Z_OK; 7546 7547 (void) uu_avl_walk(patches_avl, add_patch, &args, 0); 7548 7549 patch_avl_delete(patches_avl); 7550 return (args.res); 7551} 7552 7553/* |
7554 * Keep track of the pkgs we have already processed so that we can quickly 7555 * skip those pkgs while recursively doing dependents. 7556 */ 7557static boolean_t 7558pkg_in_manifest(uu_avl_t *saw_pkgs, char *pname, uu_avl_pool_t *pkgs_pool) 7559{ 7560 uu_avl_index_t where; 7561 7562 if (uu_avl_find(saw_pkgs, pname, NULL, &where) == NULL) { 7563 zone_pkg_entry_t *pkg; 7564 7565 /* 7566 * We need to add it. If we don't have memory we just skip 7567 * this pkg since this routine improves performance but the 7568 * algorithm is still correct without it. 7569 */ 7570 if ((pkg = (zone_pkg_entry_t *) 7571 malloc(sizeof (zone_pkg_entry_t))) == NULL) 7572 return (B_FALSE); 7573 7574 if ((pkg->zpe_name = strdup(pname)) == NULL) { 7575 free(pkg); 7576 return (B_FALSE); 7577 } 7578 7579 pkg->zpe_vers = NULL; 7580 pkg->zpe_patches_avl = NULL; 7581 7582 /* Insert pkg into the AVL tree. */ 7583 uu_avl_node_init(pkg, &pkg->zpe_entry, pkgs_pool); 7584 uu_avl_insert(saw_pkgs, pkg, where); 7585 return (B_FALSE); 7586 } 7587 7588 return (B_TRUE); 7589} 7590 7591/* |
|
7354 * Add the pkg to the sw inventory on the handle. 7355 */ 7356static int 7357add_pkg(zone_dochandle_t handle, char *name, char *version) 7358{ 7359 xmlNodePtr newnode; 7360 xmlNodePtr cur; 7361 int err; --- 95 unchanged lines hidden (view full) --- 7457 } 7458 7459 (void) fclose(fp); 7460 7461 return (err); 7462} 7463 7464/* | 7592 * Add the pkg to the sw inventory on the handle. 7593 */ 7594static int 7595add_pkg(zone_dochandle_t handle, char *name, char *version) 7596{ 7597 xmlNodePtr newnode; 7598 xmlNodePtr cur; 7599 int err; --- 95 unchanged lines hidden (view full) --- 7695 } 7696 7697 (void) fclose(fp); 7698 7699 return (err); 7700} 7701 7702/* |
7703 * Add any dependent pkgs to the list. The pkg depend file lists pkg 7704 * dependencies, one per line with an entry that looks like: 7705 * P SUNWcar Core Architecture, (Root) 7706 * See the depend(4) man page. 7707 */ 7708static int 7709add_dependents(zone_dochandle_t handle, char *pname, 7710 uu_avl_pool_t *patches_pool, uu_avl_t *obs_patches, 7711 uu_list_pool_t *list_pool, uu_avl_t *saw_pkgs, uu_avl_pool_t *pkgs_pool) 7712{ 7713 int res = Z_OK; 7714 FILE *fp; 7715 char depend[MAXPATHLEN]; 7716 char *buf; 7717 struct stat sbuf; 7718 7719 (void) snprintf(depend, sizeof (depend), "%s/%s/install/depend", 7720 PKG_PATH, pname); 7721 7722 if (stat(depend, &sbuf) == -1 || !S_ISREG(sbuf.st_mode)) 7723 return (Z_OK); 7724 7725 if ((fp = fopen(depend, "r")) == NULL) 7726 return (Z_OK); 7727 7728 while ((buf = read_pkg_data(fp)) != NULL) { 7729 char *deppkg; 7730 char *delims = " \t"; 7731 char pkginfo[MAXPATHLEN]; 7732 struct zone_pkginfo info; 7733 7734 if (*buf != 'P') { 7735 free(buf); 7736 continue; 7737 } 7738 7739 /* Skip past the leading 'P '. */ 7740 if ((deppkg = strtok(buf + 2, delims)) == NULL) { 7741 free(buf); 7742 continue; 7743 } 7744 7745 /* If the pkg is already in the manifest don't add it again. */ 7746 if (pkg_in_manifest(saw_pkgs, deppkg, pkgs_pool)) { 7747 free(buf); 7748 continue; 7749 } 7750 7751 (void) snprintf(pkginfo, sizeof (pkginfo), "%s/%s/pkginfo", 7752 PKG_PATH, deppkg); 7753 7754 if (stat(pkginfo, &sbuf) == -1 || !S_ISREG(sbuf.st_mode)) { 7755 free(buf); 7756 continue; 7757 } 7758 7759 if (get_pkginfo(pkginfo, &info) != 0) { 7760 res = Z_NOMEM; 7761 free(buf); 7762 break; 7763 } 7764 7765 if ((res = add_dependents(handle, deppkg, patches_pool, 7766 obs_patches, list_pool, saw_pkgs, pkgs_pool)) == Z_OK && 7767 (res = add_pkg(handle, deppkg, info.zpi_version)) == Z_OK) { 7768 if (info.zpi_patch_cnt > 0) 7769 res = add_patches(handle, &info, patches_pool, 7770 obs_patches, list_pool); 7771 } 7772 7773 free(buf); 7774 free_pkginfo(&info); 7775 7776 if (res != Z_OK) 7777 break; 7778 } 7779 7780 (void) fclose(fp); 7781 return (res); 7782} 7783 7784/* ARGSUSED */ 7785static int 7786pkg_entry_compare(const void *l_arg, const void *r_arg, void *private) 7787{ 7788 zone_pkg_entry_t *pkg = (zone_pkg_entry_t *)l_arg; 7789 char *name = (char *)r_arg; 7790 7791 return (strcmp(pkg->zpe_name, name)); 7792} 7793 7794static void 7795pkg_avl_delete(uu_avl_t *pavl) 7796{ 7797 if (pavl != NULL) { 7798 zone_pkg_entry_t *p; 7799 void *cookie = NULL; 7800 7801 while ((p = uu_avl_teardown(pavl, &cookie)) != NULL) { 7802 free(p->zpe_name); 7803 free(p); 7804 } 7805 7806 uu_avl_destroy(pavl); 7807 } 7808} 7809 7810/* |
|
7465 * Take a software inventory of the global zone. We need to get the set of 7466 * packages and patches that are on the global zone that the specified 7467 * non-global zone depends on. The packages we need in the inventory are: 7468 * 7469 * - skip the package if SUNW_PKG_THISZONE is 'true' 7470 * otherwise, 7471 * - add the package if 7472 * a) SUNW_PKG_ALLZONES is 'true', 7473 * or 7474 * b) any file delivered by the package is in a file system that is inherited 7475 * from the global zone. 7476 * If the zone does not inherit any file systems (whole root) 7477 * then (b) will be skipped. 7478 * 7479 * For each of the packages that is being added to the inventory, we will also | 7811 * Take a software inventory of the global zone. We need to get the set of 7812 * packages and patches that are on the global zone that the specified 7813 * non-global zone depends on. The packages we need in the inventory are: 7814 * 7815 * - skip the package if SUNW_PKG_THISZONE is 'true' 7816 * otherwise, 7817 * - add the package if 7818 * a) SUNW_PKG_ALLZONES is 'true', 7819 * or 7820 * b) any file delivered by the package is in a file system that is inherited 7821 * from the global zone. 7822 * If the zone does not inherit any file systems (whole root) 7823 * then (b) will be skipped. 7824 * 7825 * For each of the packages that is being added to the inventory, we will also |
7826 * add its dependent packages to the inventory. 7827 * 7828 * For each of the packages that is being added to the inventory, we will also |
|
7480 * add all of the associated, unique patches to the inventory. | 7829 * add all of the associated, unique patches to the inventory. |
7830 * 7831 * See the comment for zonecfg_getpkgdata() for compatability restrictions on 7832 * how we must save the XML representation of the software inventory. |
|
7481 */ 7482static int 7483zonecfg_sw_inventory(zone_dochandle_t handle) 7484{ 7485 char pkginfo[MAXPATHLEN]; 7486 int res; 7487 struct dirent *dp; 7488 DIR *dirp; 7489 struct stat buf; 7490 struct zone_pkginfo info; 7491 int pkg_cnt = 0; 7492 char **pkgs = NULL; | 7833 */ 7834static int 7835zonecfg_sw_inventory(zone_dochandle_t handle) 7836{ 7837 char pkginfo[MAXPATHLEN]; 7838 int res; 7839 struct dirent *dp; 7840 DIR *dirp; 7841 struct stat buf; 7842 struct zone_pkginfo info; 7843 int pkg_cnt = 0; 7844 char **pkgs = NULL; |
7493 uu_avl_pool_t *patches_pool; 7494 uu_avl_t *obs_patches_avl; | 7845 uu_avl_pool_t *pkgs_pool = NULL; 7846 uu_avl_pool_t *patches_pool = NULL; 7847 uu_list_pool_t *list_pool = NULL; 7848 uu_avl_t *saw_pkgs = NULL; 7849 uu_avl_t *obs_patches = NULL; |
7495 | 7850 |
7851 if ((pkgs_pool = uu_avl_pool_create("pkgs_pool", 7852 sizeof (zone_pkg_entry_t), offsetof(zone_pkg_entry_t, zpe_entry), 7853 pkg_entry_compare, UU_DEFAULT)) == NULL) { 7854 res = Z_NOMEM; 7855 goto done; 7856 } 7857 7858 if ((saw_pkgs = uu_avl_create(pkgs_pool, NULL, UU_DEFAULT)) == NULL) { 7859 res = Z_NOMEM; 7860 goto done; 7861 } 7862 |
|
7496 if ((patches_pool = uu_avl_pool_create("patches_pool", 7497 sizeof (patch_node_t), offsetof(patch_node_t, patch_node), 7498 patch_node_compare, UU_DEFAULT)) == NULL) { | 7863 if ((patches_pool = uu_avl_pool_create("patches_pool", 7864 sizeof (patch_node_t), offsetof(patch_node_t, patch_node), 7865 patch_node_compare, UU_DEFAULT)) == NULL) { |
7499 return (Z_NOMEM); | 7866 res = Z_NOMEM; 7867 goto done; |
7500 } 7501 | 7868 } 7869 |
7502 if ((obs_patches_avl = uu_avl_create(patches_pool, NULL, UU_DEFAULT)) | 7870 if ((list_pool = uu_list_pool_create("list_pool", 7871 sizeof (obs_patch_node_t), offsetof(obs_patch_node_t, link), NULL, 7872 UU_DEFAULT)) == NULL) { 7873 res = Z_NOMEM; 7874 goto done; 7875 } 7876 7877 /* 7878 * The obs_patches AVL tree saves all of the obsolete patches so 7879 * that we know not to output those as part of the sw dependencies. 7880 */ 7881 if ((obs_patches = uu_avl_create(patches_pool, NULL, UU_DEFAULT)) |
7503 == NULL) { | 7882 == NULL) { |
7504 uu_avl_pool_destroy(patches_pool); 7505 return (Z_NOMEM); | 7883 res = Z_NOMEM; 7884 goto done; |
7506 } 7507 7508 if ((res = get_ipd_pkgs(handle, &pkgs, &pkg_cnt)) != Z_OK) { | 7885 } 7886 7887 if ((res = get_ipd_pkgs(handle, &pkgs, &pkg_cnt)) != Z_OK) { |
7509 patch_avl_delete(obs_patches_avl); 7510 uu_avl_pool_destroy(patches_pool); 7511 return (res); | 7888 res = Z_NOMEM; 7889 goto done; |
7512 } 7513 7514 if ((dirp = opendir(PKG_PATH)) == NULL) { | 7890 } 7891 7892 if ((dirp = opendir(PKG_PATH)) == NULL) { |
7515 patch_avl_delete(obs_patches_avl); 7516 uu_avl_pool_destroy(patches_pool); 7517 free_ipd_pkgs(pkgs, pkg_cnt); 7518 return (Z_OK); | 7893 res = Z_NOMEM; 7894 goto done; |
7519 } 7520 7521 while ((dp = readdir(dirp)) != (struct dirent *)0) { 7522 if (strcmp(dp->d_name, ".") == 0 || 7523 strcmp(dp->d_name, "..") == 0) 7524 continue; 7525 7526 (void) snprintf(pkginfo, sizeof (pkginfo), "%s/%s/pkginfo", --- 4 unchanged lines hidden (view full) --- 7531 7532 if (get_pkginfo(pkginfo, &info) != 0) { 7533 res = Z_NOMEM; 7534 break; 7535 } 7536 7537 if (!info.zpi_this_zone && 7538 (info.zpi_all_zones || | 7895 } 7896 7897 while ((dp = readdir(dirp)) != (struct dirent *)0) { 7898 if (strcmp(dp->d_name, ".") == 0 || 7899 strcmp(dp->d_name, "..") == 0) 7900 continue; 7901 7902 (void) snprintf(pkginfo, sizeof (pkginfo), "%s/%s/pkginfo", --- 4 unchanged lines hidden (view full) --- 7907 7908 if (get_pkginfo(pkginfo, &info) != 0) { 7909 res = Z_NOMEM; 7910 break; 7911 } 7912 7913 if (!info.zpi_this_zone && 7914 (info.zpi_all_zones || |
7539 dir_pkg(dp->d_name, pkgs, pkg_cnt))) { 7540 if ((res = add_pkg(handle, dp->d_name, | 7915 dir_pkg(dp->d_name, pkgs, pkg_cnt)) && 7916 !pkg_in_manifest(saw_pkgs, dp->d_name, pkgs_pool)) { 7917 /* 7918 * Add dependents first so any patches will get 7919 * associated with the right pkg in the xml file. 7920 */ 7921 if ((res = add_dependents(handle, dp->d_name, 7922 patches_pool, obs_patches, list_pool, saw_pkgs, 7923 pkgs_pool)) == Z_OK && 7924 (res = add_pkg(handle, dp->d_name, |
7541 info.zpi_version)) == Z_OK) { 7542 if (info.zpi_patch_cnt > 0) 7543 res = add_patches(handle, &info, | 7925 info.zpi_version)) == Z_OK) { 7926 if (info.zpi_patch_cnt > 0) 7927 res = add_patches(handle, &info, |
7544 patches_pool, obs_patches_avl); | 7928 patches_pool, obs_patches, 7929 list_pool); |
7545 } 7546 } 7547 7548 free_pkginfo(&info); 7549 7550 if (res != Z_OK) 7551 break; 7552 } 7553 7554 (void) closedir(dirp); 7555 | 7930 } 7931 } 7932 7933 free_pkginfo(&info); 7934 7935 if (res != Z_OK) 7936 break; 7937 } 7938 7939 (void) closedir(dirp); 7940 |
7556 patch_avl_delete(obs_patches_avl); 7557 uu_avl_pool_destroy(patches_pool); | 7941done: 7942 pkg_avl_delete(saw_pkgs); 7943 patch_avl_delete(obs_patches); 7944 if (pkgs_pool != NULL) 7945 uu_avl_pool_destroy(pkgs_pool); 7946 if (patches_pool != NULL) 7947 uu_avl_pool_destroy(patches_pool); 7948 if (list_pool != NULL) 7949 uu_list_pool_destroy(list_pool); |
7558 free_ipd_pkgs(pkgs, pkg_cnt); 7559 7560 if (res == Z_OK) 7561 handle->zone_dh_sw_inv = B_TRUE; 7562 7563 return (res); 7564} 7565 --- 60 unchanged lines hidden --- | 7950 free_ipd_pkgs(pkgs, pkg_cnt); 7951 7952 if (res == Z_OK) 7953 handle->zone_dh_sw_inv = B_TRUE; 7954 7955 return (res); 7956} 7957 --- 60 unchanged lines hidden --- |