Пример #1
0
/*
 * get_mount_point - given a filesystem table index, return the
 *	path of the mount point.  Otherwise,
 *	return NULL if it's a local filesystem.
 */
char *
get_mount_point(uint32_t n)
{
	if (!is_remote_fs_n(n))
		return (NULL); 	/* local */
	return (fs_tab[n]->name);
}
Пример #2
0
/*
 * is_remote_fs - given a cfent entry, return 1
 *	if it's a remote filesystem, 0 if local.
 *
 *	Also Note: Upon exit, a valid fsys() is guaranteed. This is
 *	an interface requirement.
 */
int
is_remote_fs(char *path, uint32_t *fsys_value)
{
	if (*fsys_value == BADFSYS)
		*fsys_value = fsys(path);

	return (is_remote_fs_n(*fsys_value));
}
Пример #3
0
static int
readspace(char *spacefile, int *error)
{
	FILE	*fp;
	char	line[LSIZE];
	long	blocks, nodes;
	int	n;

	if (spacefile == NULL)
		return (0);

	if ((fp = fopen(spacefile, "r")) == NULL) {
		progerr(gettext("unable to open spacefile %s"), spacefile);
		return (-1);
	}

	while (fgets(line, LSIZE, fp)) {
		struct fstable *fs_tab;
		char *pt, path[PATH_MAX];

		blocks = nodes = 0;
		for (pt = line; isspace(*pt); /* void */)
			pt++;
		if (*pt == '#' || *pt == '\0')
			continue;

		(void) sscanf(line, "%s %ld %ld", path, &blocks, &nodes);
		mappath(2, path);
		basepath(path, get_basedir(), get_inst_root());
		canonize(path);

		n = resolved_fsys(path);
		if (fsys_stat(n)) {
			(*error)++;
			continue;
		}

		/*
		 * Don't accumulate space requirements on read-only
		 * remote filesystems. NOTE: For some reason, this
		 * used to check for !remote && read only. If this
		 * blows up later, then maybe that was correct -- JST
		 */
		if (is_remote_fs_n(n) && !is_fs_writeable_n(n))
			continue;

		fs_tab = get_fs_entry(n);

		fs_tab->bused += blocks;
		fs_tab->fused += nodes;
	}
	(void) fclose(fp);
	return (0);
}
Пример #4
0
/*
 * get_remote_path - given a filesystem table index, return the
 *	path of the filesystem on the remote system.  Otherwise,
 *	return NULL if it's a local filesystem.
 */
char *
get_remote_path(uint32_t n)
{
	char	*p;

	if (!is_remote_fs_n(n))
		return (NULL); 	/* local */
	p = strchr(fs_tab[n]->remote_name, ':');
	if (!p)
		p = fs_tab[n]->remote_name; 	/* Loopback */
	else
		p++; 	/* remote */
	return (p);
}
Пример #5
0
/*
 * This function reads all of the package objects, maps them to their target
 * filesystems and adds up the amount of space used on each. Wherever you see
 * "fsys_value", that's the apparent filesystem which could be a temporary
 * loopback mount for the purpose of constructing the client filesystem. It
 * isn't necessarily the real target filesystem. Where you see "fsys_base"
 * that's the real filesystem to which fsys_value may just refer. If this is
 * installing to a standalone or a server, fsys_value will almost always be
 * the same as fsys_base.
 */
static int
readmap(int *error)
{
	struct fstable *fs_tab;
	struct cfextra *ext;
	struct cfent *ept;
	struct stat statbuf;
	char	tpath[PATH_MAX];
	fsblkcnt_t	blk;
	int	i, n;

	/*
	 * Handle the installation files (ftype i) that are in the
	 * pkgmap/eptlist.
	 */
	for (i = 0; (ext = extlist[i]) != NULL; i++) {
		ept = &(ext->cf_ent);

		if (ept->ftype != 'i')
			continue;

		/*
		 * These paths are treated differently from the others
		 * since their full pathnames are not included in the
		 * pkgmap.
		 */
		if (strcmp(ept->path, "pkginfo") == 0)
			(void) sprintf(tpath, "%s/%s", pkgloc, ept->path);
		else
			(void) sprintf(tpath, "%s/install/%s", pkgloc,
			    ept->path);

		/* If we haven't done an fsys() series, do one */
		if (ext->fsys_value == BADFSYS)
			ext->fsys_value = fsys(tpath);

		/*
		 * Now check if this is a base or apparent filesystem. If
		 * it's just apparent, get the resolved filesystem entry,
		 * otherwise, base and value are the same.
		 */
		if (use_srvr_map_n(ext->fsys_value))
			ext->fsys_base = resolved_fsys(tpath);
		else
			ext->fsys_base = ext->fsys_value;

		if (fsys_stat(ext->fsys_base)) {
			(*error)++;
			continue;
		}

		/*
		 * Don't accumulate space requirements on read-only
		 * remote filesystems.
		 */
		if (is_remote_fs_n(ext->fsys_value) &&
		    !is_fs_writeable_n(ext->fsys_value))
			continue;

		fs_tab = get_fs_entry(ext->fsys_base);

		fs_tab->fused++;
		if (ept->cinfo.size != BADCONT)
			blk = nblk(ept->cinfo.size,
			    fs_tab->bsize,
			    fs_tab->frsize);
		else
			blk = 0;
		fs_tab->bused += blk;
	}

	/*
	 * Handle the other files in the eptlist.
	 */
	for (i = 0; (ext = extlist[i]) != NULL; i++) {
		ept = &(extlist[i]->cf_ent);

		if (ept->ftype == 'i')
			continue;

		/*
		 * Don't recalculate package objects that are already in the
		 * table.
		 */
		if (ext->mstat.preloaded)
			continue;

		/*
		 * Don't accumulate space requirements on read-only
		 * remote filesystems.
		 */
		if (is_remote_fs(ept->path, &(ext->fsys_value)) &&
		    !is_fs_writeable(ept->path, &(ext->fsys_value)))
			continue;

		/*
		 * Now check if this is a base or apparent filesystem. If
		 * it's just apparent, get the resolved filesystem entry,
		 * otherwise, base and value are the same.
		 */
		if (use_srvr_map_n(ext->fsys_value))
			ext->fsys_base = resolved_fsys(tpath);
		else
			ext->fsys_base = ext->fsys_value;

		/* At this point we know we have a good fsys_base. */
		if (fsys_stat(ext->fsys_base)) {
			(*error)++;
			continue;
		}

		/*
		 * We have to stat this path based upon it's real location.
		 * If this is a server-remap, ept->path isn't the real
		 * location.
		 */
		if (use_srvr_map_n(ext->fsys_value))
			strcpy(tpath, server_map(ept->path, ext->fsys_value));
		else
			strcpy(tpath, ept->path);

		fs_tab = get_fs_entry(ext->fsys_base);
		if (stat(tpath, &statbuf)) {
			/* path cannot be accessed */
			fs_tab->fused++;
			if (strchr("dxs", ept->ftype))
				blk =
				    nblk(fs_tab->bsize,
				    fs_tab->bsize,
				    fs_tab->frsize);
			else if (ept->cinfo.size != BADCONT)
				blk = nblk(ept->cinfo.size,
				    fs_tab->bsize,
				    fs_tab->frsize);
			else
				blk = 0;
		} else {
			/* path already exists */
			if (strchr("dxs", ept->ftype))
				blk = 0;
			else if (ept->cinfo.size != BADCONT) {
				fsblkcnt_t new_size, old_size;
				new_size = nblk(ept->cinfo.size,
				    fs_tab->bsize,
				    fs_tab->frsize);
				old_size = nblk(statbuf.st_size,
				    fs_tab->bsize,
				    fs_tab->frsize);
				/*
				 * negative blocks show room freed, but since
				 * order of installation is uncertain show
				 * 0 blocks usage
				 */
				if (new_size < old_size)
					blk = 0;
				else
					blk = new_size - old_size;
			} else
				blk = 0;
		}
		fs_tab->bused += blk;
	}
	return (0);
}
Пример #6
0
static char *
check_db_entry(VFP_T *vfpo, struct cfextra *entry, int rmflag, char *myclass,
		int *dbchg)
{
	struct pinfo *pinfo;
	int	fs_entry;
	char	*save_path = NULL;
	char	*tp;

	/* write this entry to the contents file */

	if (myclass && strcmp(myclass, entry->cf_ent.pkg_class)) {
		if (putcvfpfile(&entry->cf_ent, vfpo)) {
			progerr(gettext(ERR_WRITE));
			quit(99);
		}
		return (NULL);
	}

	/*
	 * Now scan each package instance holding this file or
	 * directory and see if it matches the package we are
	 * updating here.
	 */
	pinfo = entry->cf_ent.pinfo;
	while (pinfo) {
		if (strcmp(pkginst, pinfo->pkg) == 0)
			break;
		pinfo = pinfo->next;
	}

	/*
	 * If pinfo == NULL at this point, then this file or
	 * directory isn't part of the package of interest.
	 * So the loop below executes only on files in the package
	 * of interest.
	 */

	save_path = NULL;

	if (pinfo) {
		if (rmflag && (pinfo->status == RM_RDY)) {
			*dbchg = 1;

			(void) eptstat(&(entry->cf_ent), pkginst, '@');

			if (entry->cf_ent.npkgs) {
				if (putcvfpfile(&(entry->cf_ent), vfpo)) {
					progerr(gettext(ERR_WRITE));
					quit(99);
				}
			}
			return (NULL);

		} else if (!rmflag && (pinfo->status == INST_RDY)) {
			*dbchg = 1;

			/* tp is the server-relative path */
			tp = fixpath(entry->cf_ent.path);
			/* save_path is the cmd line path */
			save_path = entry->cf_ent.path;
			/* entry has the server-relative path */
			entry->cf_ent.path = tp;

			/*
			 * The next if statement figures out how
			 * the contents file entry should be
			 * annotated.
			 *
			 * Don't install or verify objects for
			 * remote, read-only filesystems.  We
			 * need only verify their presence and
			 * flag them appropriately from some
			 * server. Otherwise, ok to do final
			 * check.
			 */
			fs_entry = fsys(entry->cf_ent.path);

			if (is_remote_fs_n(fs_entry) &&
				!is_fs_writeable_n(fs_entry)) {
				/*
				 * Mark it shared whether it's present
				 * or not. life's too funny for me
				 * to explain.
				 */
				pinfo->status = SERVED_FILE;

				/*
				 * restore for now. This may
				 * chg soon.
				 */
				entry->cf_ent.path = save_path;
			} else {
				/*
				 * If the object is accessible, check
				 * the new entry for existence and
				 * attributes. If there's a problem,
				 * mark it NOT_FND; otherwise,
				 * ENTRY_OK.
				 */
				if (is_mounted_n(fs_entry)) {
					int	n;

					n = finalck((&entry->cf_ent), 1, 1,
							B_FALSE);

					pinfo->status = ENTRY_OK;
					if (n != 0) {
						pinfo->status = NOT_FND;
					}
				}

				/*
				 * It's not remote, read-only but it
				 * may look that way to the client.
				 * If it does, overwrite the above
				 * result - mark it shared.
				 */
				if (is_served_n(fs_entry))
					pinfo->status = SERVED_FILE;

				/* restore original path */
				entry->cf_ent.path = save_path;
				/*   and clear save_path */
				save_path = NULL;
			}
		}
	}

	/* Output entry to contents file. */
	if (putcvfpfile(&(entry->cf_ent), vfpo)) {
		progerr(gettext(ERR_WRITE));
		quit(99);
	}

	return (save_path);
}