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 ---