Mercurial > illumos > illumos-gate
changeset 10638:5d19a597329d
6809128 freeware packages cannot be installed in sparse non global zone with patch 119254-63
6865412 pkgadm not communicating with dryrun pkgserv instances
6853789 pkgrm errors during zone upgrade to s10u8_01
author | Jan Kryl <Jan.Kryl@Sun.COM> |
---|---|
date | Thu, 24 Sep 2009 15:16:32 +0200 |
parents | f6eac4af74a8 |
children | 368f1335a058 |
files | usr/src/cmd/svr4pkg/libinst/mntinfo.c usr/src/cmd/svr4pkg/pkgadm/main.c usr/src/lib/libinstzones/common/zones_paths.c |
diffstat | 3 files changed, 89 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/svr4pkg/libinst/mntinfo.c Thu Sep 24 05:17:17 2009 -0700 +++ b/usr/src/cmd/svr4pkg/libinst/mntinfo.c Thu Sep 24 15:16:32 2009 +0200 @@ -34,6 +34,7 @@ #include <errno.h> #include <stdlib.h> #include <unistd.h> +#include <libgen.h> #include <string.h> #include <wait.h> #include <signal.h> @@ -952,7 +953,7 @@ */ if (strcmp(vfs->vfs_mountp, "/") == 0) { (void) strcpy(client_mountp, - install_root); + install_root); } else { (void) snprintf(client_mountp, sizeof (client_mountp), "%s%s", @@ -1004,7 +1005,7 @@ qsort(fs_tab, fs_tab_used, sizeof (struct fstable *), fs_tab_ent_comp); if (strcmp(fs_tab[fs_tab_used-1]->name, rn) != 0) { progerr(ERR_MNT_NOROOT, fs_tab[fs_tab_used-1]->name, rn, errno, - strerror(errno)); + strerror(errno)); return (1); } else { return (0); @@ -1055,21 +1056,33 @@ { register int i; char real_path[PATH_MAX]; - char *path2use = NULL; - char *cp = NULL; + char path_copy[PATH_MAX]; + char *path2use; + char *cp; int pathlen; - - path2use = path; - - real_path[0] = '\0'; + boolean_t found = B_FALSE; - (void) realpath(path, real_path); - - if (real_path[0]) { - cp = strstr(path, real_path); - if (cp != path || cp == NULL) - path2use = real_path; + /* + * The loop below represents our best effort to identify real path of + * a file, which doesn't need to exist. realpath() returns error for + * nonexistent path, therefore we need to cut off trailing components + * of path until we get path which exists and can be resolved by + * realpath(). Lookup of "/dir/symlink/nonexistent-file" would fail + * to resolve symlink without this. + */ + (void) strlcpy(path_copy, path, PATH_MAX); + for (cp = dirname(path_copy); strlen(cp) > 1; cp = dirname(cp)) { + if (realpath(cp, real_path) != NULL) { + found = B_TRUE; + break; + } else if (errno != ENOENT) + break; } + if (found) + path2use = real_path; + else + /* fall back to original path in case of unexpected failure */ + path2use = path; pathlen = strlen(path2use);
--- a/usr/src/cmd/svr4pkg/pkgadm/main.c Thu Sep 24 05:17:17 2009 -0700 +++ b/usr/src/cmd/svr4pkg/pkgadm/main.c Thu Sep 24 15:16:32 2009 +0200 @@ -262,10 +262,27 @@ { int c; char *root = NULL; + char *dryrundir = NULL; boolean_t quit = B_FALSE; - while ((c = getopt(argc, argv, "R:q")) != EOF) { + /* + * Options: + * -q: Tell pkgserv daemon to quit. + * -R: Alternate root specification. + * -D: Dryrun directory specification. + * + * -R and -D help pkgadm to locate IPC files used for communication + * with pkgserv daemon. They should not be used together, though + * nothing prevents you from doing so. If you use both at once + * then IPC files will be searched in $ROOTDIR/$DRYRUNDIR directory. + * So if you want to terminate dryrun pkgserv process, you should + * always use only -D option. + */ + while ((c = getopt(argc, argv, "D:R:q")) != EOF) { switch (c) { + case 'D': + dryrundir = optarg; + break; case 'R': root = optarg; break; @@ -277,15 +294,15 @@ } } - if (!pkgsync_needed(root, NULL, quit)) + if (!pkgsync_needed(root, dryrundir, quit)) return (0); set_PKGpaths(root); - set_cfdir(NULL); + set_cfdir(dryrundir); if (pkgWlock(1) == 1) { /* Flush the log file */ - (void) pkgsync(root, NULL, quit); + (void) pkgsync(root, dryrundir, quit); (void) relslock(); return (0); }
--- a/usr/src/lib/libinstzones/common/zones_paths.c Thu Sep 24 05:17:17 2009 -0700 +++ b/usr/src/lib/libinstzones/common/zones_paths.c Thu Sep 24 15:16:32 2009 +0200 @@ -34,6 +34,8 @@ #include <limits.h> #include <stdlib.h> #include <unistd.h> +#include <libgen.h> +#include <errno.h> #include <string.h> #include <fcntl.h> #include <sys/types.h> @@ -242,7 +244,11 @@ boolean_t z_path_is_inherited(char *a_path, char a_ftype, char *a_rootDir) { - int n; + int n; + char *cp, *path2use; + char real_path[PATH_MAX]; + char path_copy[PATH_MAX]; + boolean_t found = B_FALSE; /* entry assertions */ @@ -263,11 +269,38 @@ } /* - * if a_path resides on an inherited filesystem then + * The loop below represents our best effort to identify real path of + * a file, which doesn't need to exist. realpath() returns error for + * nonexistent path, therefore we need to cut off trailing components + * of path until we get path which exists and can be resolved by + * realpath(). Lookup of "/dir/symlink/nonexistent-file" would fail + * to resolve symlink without this. + */ + (void) strlcpy(path_copy, a_path, PATH_MAX); + for (cp = dirname(path_copy); strlen(cp) > 1; cp = dirname(cp)) { + if (realpath(cp, real_path) != NULL) { + found = B_TRUE; + break; + } else if (errno != ENOENT) + break; + } + if (found) { + /* + * In the loop above we always strip trailing path component, + * so the type of real_path is always 'd'. + */ + a_ftype = 'd'; + path2use = real_path; + } else { + path2use = a_path; + } + + /* + * if path resides on an inherited filesystem then * it must be read-only. */ - if (z_isPathWritable(a_path) != 0) { + if (z_isPathWritable(path2use) != 0) { return (B_FALSE); } @@ -286,22 +319,22 @@ /* advance past given root directory if path begins with it */ n = strlen(a_rootDir); - if (strncmp(a_rootDir, a_path, n) == 0) { + if (strncmp(a_rootDir, path2use, n) == 0) { char *p; /* advance past the root path */ - p = a_path + n; + p = path2use + n; /* go back to the first occurance of the path separator */ - while ((*p != '/') && (p > a_path)) { + while ((*p != '/') && (p > path2use)) { p--; } /* use this location in the path to compare */ - a_path = p; + path2use = p; } /* @@ -326,7 +359,7 @@ fslen--; } - if (strncmp(a_path, inheritedFileSystems[n], fslen) == 0) { + if (strncmp(path2use, inheritedFileSystems[n], fslen) == 0) { _z_echoDebug(DBG_PATHS_IS_INHERITED, a_path, inheritedFileSystems[n]); return (B_TRUE);