6873318 zoneadm attach -u ignores /var/sadm/install/gz-only-packages
authorphaniram rampura krishnamurthy - Sun Microsystems - Bangalore India <Phaniram.Krishnamurthy@Sun.COM>
Tue, 10 Nov 2009 11:43:02 +0530
changeset 11025 96e66bda9446
parent 11024 16869afd5fb1
child 11026 e8e10df16a8f
6873318 zoneadm attach -u ignores /var/sadm/install/gz-only-packages
usr/src/lib/brand/native/zone/sw_support.c
--- a/usr/src/lib/brand/native/zone/sw_support.c	Mon Nov 09 21:09:22 2009 -0800
+++ b/usr/src/lib/brand/native/zone/sw_support.c	Tue Nov 10 11:43:02 2009 +0530
@@ -143,6 +143,9 @@
 static char *zonename;
 static char *zonepath;
 
+/* List of pkgs that should be only on GZ */
+static char **gz_only_pkgs_list = NULL;
+
 /* used in attach_func() and signal handler */
 static volatile boolean_t attach_interupted;
 
@@ -1286,6 +1289,97 @@
 	}
 }
 
+/* Memory allocation failure, free up allocated memory */
+static void
+destroy_gz_only_list()
+{
+	int i;
+
+	if (gz_only_pkgs_list != NULL) {
+		for (i = 0; gz_only_pkgs_list[i] != NULL; i++)
+			free(gz_only_pkgs_list[i]);
+		free(gz_only_pkgs_list);
+		gz_only_pkgs_list = NULL;
+	}
+}
+
+/*
+ * If a package is GZ only, it should not be installed in NGZ. This routine
+ * builds the list of GZ only packages
+ */
+static int
+load_gz_only_pkg_list()
+{
+	FILE *fp = NULL;
+	char buf[80];
+	int cnt = 0;
+
+	/* If file exists, do the open */
+	if ((fp = fopen("/var/sadm/install/gz-only-packages", "r")) == NULL)
+		return (ENOENT);
+
+	if ((gz_only_pkgs_list =
+	    (char **)malloc(sizeof (char *))) == NULL) {
+		(void) fclose(fp);
+		return (Z_NOMEM);
+	}
+
+	while (fgets(buf, 80, fp) != NULL) {
+		char **p = NULL;
+
+		/* Take care to skip comments lines */
+		if (buf[0] == '#' || buf[0] == '\n')
+			continue;
+
+		buf[strlen(buf) - 1] = '\0';
+
+		/*
+		 * Allocate memory for each entry in gz_only_pkgs_list.
+		 * If unable to get memory, return Z_NOMEM to indicate
+		 * allocation failure
+		 */
+		if ((gz_only_pkgs_list[cnt] = strdup(buf)) == NULL) {
+			destroy_gz_only_list();
+			(void) fclose(fp);
+			return (Z_NOMEM);
+		}
+		cnt++;
+
+		/* Allocate memory for the next pkg to be excluded */
+		if ((p = (char **)realloc(gz_only_pkgs_list,
+		    ((cnt + 1) * sizeof (char *)))) == NULL) {
+			free(gz_only_pkgs_list[cnt-1]);
+			gz_only_pkgs_list[cnt-1] = NULL;
+			destroy_gz_only_list();
+			(void) fclose(fp);
+			return (Z_NOMEM);
+		}
+		gz_only_pkgs_list = p;
+	}
+	gz_only_pkgs_list[cnt] = NULL;
+
+	(void) fclose(fp);
+
+	return (Z_OK);
+}
+
+/*
+ * Check if the package we are trying to install into a NGZ is a GZ only pkg.
+ * If so, skip it's installation in the NGZ
+ */
+static boolean_t
+is_gz_only_pkg(char *pkg)
+{
+	int i;
+
+	for (i = 0; gz_only_pkgs_list[i] != NULL; i++) {
+		if (strcmp(pkg, gz_only_pkgs_list[i]) == 0)
+			return (B_TRUE);
+	}
+	return (B_FALSE);
+}
+
+
 /*
  * Take a software inventory of the global zone.  We need to get the set of
  * packages and patches that are on the global zone that the specified
@@ -1315,6 +1409,7 @@
 {
 	char		pkginfo[MAXPATHLEN];
 	int		res;
+	int		gz_pkgs_loaded;
 	struct dirent	*dp;
 	DIR		*dirp;
 	struct stat	buf;
@@ -1327,6 +1422,16 @@
 	uu_avl_t	*saw_pkgs = NULL;
 	uu_avl_t 	*obs_patches = NULL;
 
+	/*
+	 * Get the list of GZ only packages from file gz-only-packages
+	 * into memory
+	 */
+	if ((gz_pkgs_loaded = load_gz_only_pkg_list())
+	    == Z_NOMEM) {
+		res = Z_NOMEM;
+		goto done;
+	}
+
 	if ((pkgs_pool = uu_avl_pool_create("pkgs_pool",
 	    sizeof (zone_pkg_entry_t), offsetof(zone_pkg_entry_t, zpe_entry),
 	    pkg_entry_nm_compare, UU_DEFAULT)) == NULL) {
@@ -1378,6 +1483,16 @@
 		    strcmp(dp->d_name, "..") == 0)
 			continue;
 
+		/*
+		 * If only gz-only-packages file exists and read
+		 * into memory, check for a possible match
+		 * If there is a match, skip over. Such a package is
+		 * meant for GZ only installation.
+		 */
+		if ((gz_pkgs_loaded == Z_OK) &&
+		    (is_gz_only_pkg(dp->d_name) == B_TRUE))
+			continue;
+
 		(void) snprintf(pkginfo, sizeof (pkginfo), "%s/%s/pkginfo",
 		    PKG_PATH, dp->d_name);
 
@@ -1418,6 +1533,11 @@
 	(void) closedir(dirp);
 
 done:
+	/*
+	 * Free up the heap memory that has been allocated for
+	 * gz-only-packages
+	 */
+	destroy_gz_only_list();
 	pkg_avl_delete(saw_pkgs);
 	patch_avl_delete(obs_patches);
 	if (pkgs_pool != NULL)