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, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2003 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 "Solaris_NFSMount.h"
30#include "nfs_keys.h"
31#include "nfs_providers_msgstrings.h"
32#include "messageStrings.h"
33#include "nfs_provider_names.h"
34#include "libfsmgt.h"
35#include "cmdgen.h"
36#include "util.h"
37#include "nfsprov_methods.h"
38#include "mountprov_methods.h"
39#include "createprop_methods.h"
40#include <sys/types.h>
41#include <string.h>
42#include <errno.h>
43
44/*
45 * Constants
46 */
47#define	DELETE_VFSTAB_ENT_METHOD "deleteVfstabEntry"
48#define	GET_DEF_SECMODE_METHOD "getDefaultNfsSecMode"
49#define	GET_NET_CFG_LIST_METHOD "getNetCfgList"
50#define	GET_NFS_SEC_LIST_METHOD "getNfsSecList"
51#define	SHOW_EXPORTS_METHOD "showExports"
52/*
53 * Private method declarations
54 */
55
56static CCIMInstanceList * create_nfsMount_associations(nfs_mntlist_t *mountList,
57				int *errp);
58static CCIMInstanceList * enumerate_mounts();
59static CCIMObjectPath * get_Antecedent(cimchar *mount_point);
60static CCIMInstanceList * get_associated_instances(nfs_mntlist_t *mountList,
61				boolean_t resultIsAnt);
62static nfs_mntlist_t *get_associated_nfs_mntlist(boolean_t isAntecedent,
63			char *nameKeyValue);
64static CCIMObjectPath * get_Dependent(nfs_mntlist_t *nfs_mount);
65static char *get_devid(char *keyValue, int *errp);
66static char *get_resource(char *keyValue, int *errp);
67static CCIMPropertyList * populate_property_list(nfs_mntlist_t *nfs_mount);
68static CIMBool populate_property_values(nfs_mntlist_t *nfs_mount,
69		cimchar **propValues);
70
71/*
72 * Public methods
73 */
74
75/*
76 * Instance provider methods
77 */
78
79/*
80 * Method: cp_enumInstances_Solaris_NFSMount
81 *
82 * Description: Enumerates all of the nfs mounts on the host.  NFS mounts with
83 * "ignore" in the option string are ignored.
84 *
85 * Parameters:
86 *	- CCIMObjectPath* mountOP - The object path containing the name of the
87 *	class to which the instance to be enumerated belongs.
88 *
89 * Returns:
90 *	- A pointer to a list of Solaris_NFSMount instances.
91 *	- NULL if an error occurred or if there are no NFS mounts on the host.
92 *	In the case of an error, the error will be logged.
93 */
94CCIMInstanceList *
95cp_enumInstances_Solaris_NFSMount(CCIMObjectPath* mountOP) {
96	CCIMInstanceList *instList;
97	int	err = 0;
98
99	/*
100	 * First check if the CCIMObjectPath passed in is null.
101	 */
102	if (mountOP == NULL) {
103		util_handleError(
104			"SOLARIS_NFSMOUNT::ENUM_INSTANCES",
105			CIM_ERR_INVALID_PARAMETER, NULL,
106			NULL, &err);
107		return ((CCIMInstanceList *)NULL);
108	}
109
110	instList = enumerate_mounts();
111	if (instList == NULL) {
112		return ((CCIMInstanceList *)NULL);
113	}
114
115	return (instList);
116} /* cp_enumInstances_Solaris_NFSMount */
117
118/*
119 * Method: cp_getInstance_Solaris_NFSMount
120 *
121 * Description: Gets the instance corresponding to the Solaris_NFSMount
122 * object path passed in.
123 *
124 * Parameters:
125 *	- CCIMObjectPath* mountOP - An object path containing all the keys of
126 *	the instance that is supposed to be returned.
127 *
128 * Returns:
129 *	- A pointer to the Solaris_NFSMount instance corresponding to the object
130 *	path parameter.
131 *	- NULL if an error occurred or if the instance doesn't exist.  In the
132 *	case of an error, the error will be logged.
133 */
134CCIMInstance *
135cp_getInstance_Solaris_NFSMount(CCIMObjectPath* mountOP) {
136	CCIMInstanceList	*instList;
137	CCIMInstance		*inst;
138	CCIMPropertyList	*mountPropList;
139	CCIMObjectPath		*antOP, *depOP;
140	int			err;
141
142	if (mountOP == NULL || mountOP->mKeyProperties == NULL) {
143		util_handleError("SOLARIS_NFSMOUNT::GET_INSTANCE",
144			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
145		return ((CCIMInstance *)NULL);
146	}
147
148	mountPropList = mountOP->mKeyProperties;
149	depOP = util_getKeyValue(mountPropList, nfsMountProps[DEP].type,
150		nfsMountProps[DEP].name, &err);
151	antOP = util_getKeyValue(mountPropList, nfsMountProps[ANT].type,
152		nfsMountProps[ANT].name, &err);
153
154	if (depOP == NULL || antOP == NULL ||
155		depOP->mKeyProperties == NULL ||
156		antOP->mKeyProperties == NULL) {
157
158		util_handleError("SOLARIS_NFSMOUNT::GET_INSTANCE",
159			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
160		return ((CCIMInstance *)NULL);
161	}
162
163	instList = cp_enumInstances_Solaris_NFSMount(mountOP);
164	if (instList == NULL) {
165		/*
166		 * Either an error occurred or we simply don't have any
167		 * instances of Solaris_NFSMount on the system.  In the case,
168		 * that an error occurred, it will be handled in
169		 * cp_enumInstances_Solaris_NFSMount.
170		 */
171		return ((CCIMInstance *)NULL);
172	}
173
174	inst = cim_getInstance(instList, mountOP);
175
176	cim_freeInstanceList(instList);
177	return (inst);
178} /* cp_getInstance_Solaris_NFSMount */
179
180/*
181 * Method: cp_createInstance_Solaris_NFSMount
182 *
183 * Description:
184 * Creates an instance of the Solaris_NFSMount class.
185 * A create instance will actually mount a file system on the current host by
186 * calling the cmd interface's cmd_execute_command_and_retrieve_string function.
187 *
188 * Parameters:
189 *	- CCIMObjectPath* nfsOP - An object path containing the information
190 *	needed about the class of which to have an instance created.
191 *	- CCIMInstance* nfsInst - The instance to be created.
192 *
193 * Returns:
194 *	- A pointer to a Solaris_NFSMount CCIMObjectPath which corresponds to
195 *	the mount that was created.
196 *	- Upon error, NULL is returned and the error will be logged.
197 */
198CCIMObjectPath *
199cp_createInstance_Solaris_NFSMount(CCIMObjectPath* nfsOP,
200	CCIMInstance* nfsInst) {
201
202	char			*cmd_return = NULL;
203	char			*cmd;
204	char			*resource;
205	char			*mountp;
206	char			*mntoptsParam, *timeParam;
207	boolean_t		findOverlayParam;
208	int			err = 0;
209	nfs_mntlist_t		*mount;
210	CCIMObjectPath		*nfsMountOP = NULL;
211	CCIMObjectPath		*opParam;
212	CCIMPropertyList	*propListParam;
213	CCIMInstanceList	*nfsMountInstList;
214	CCIMInstanceList	*currentInst;
215	CCIMProperty		*mnt_prop;
216	CCIMException		*ex;
217
218	/*
219	 * First check if the CCIMInstance or CCIMObjectPath is null.
220	 */
221	if (nfsOP == NULL || nfsInst == NULL) {
222		util_handleError(
223			"SOLARIS_NFSMOUNT::CREATE_INSTANCE",
224			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
225		return ((CCIMObjectPath *)NULL);
226	}
227
228	/*
229	 * Get the properties from the instance parameter in order to create
230	 * an instance as defined. The properties will be used to create a
231	 * mount command to execute.
232	 */
233
234	/*
235	 * The only properties required are resource and mount point.
236	 * All other properties are not needed.  The defaults will be used.
237	 */
238	err = 0;
239	opParam = NULL;
240	propListParam = NULL;
241	cmd = cmdgen_generate_command(CMDGEN_NFS_MOUNT, nfsInst, opParam,
242		propListParam, &err);
243	if (cmd == NULL || err != 0) {
244		util_handleError("SOLARIS_NFSMOUNT::CREATE_INSTANCE",
245			CIM_ERR_FAILED, CMDGEN_GEN_CMD_FAILURE, NULL, &err);
246		return ((CCIMObjectPath *)NULL);
247	}
248
249	cim_logDebug("cp_createInstance_Solaris_NFSMount",
250		"cmd =%s", cmd);
251	err = 0;
252	cmd_return = cmd_execute_command_and_retrieve_string(cmd, &err);
253	if (err != 0) {
254		cim_logDebug("cp_createInstance_Solaris_NFSMount",
255			"cmd_return =%s", cmd_return);
256		/*
257		 * An error occurred in executing the command.
258		 */
259		if (cmd_return != NULL) {
260			util_handleError("SOLARIS_NFSMOUNT::CREATE_INSTANCE",
261				CIM_ERR_FAILED, CMD_EXEC_RETR_STR_FAILURE,
262				NULL, &err);
263			free(cmd);
264			free(cmd_return);
265			return ((CCIMObjectPath *)NULL);
266		} else {
267			util_handleError("SOLARIS_NFSMOUNT::CREATE_INSTANCE",
268				CIM_ERR_FAILED, CMD_EXEC_RETR_STR_FAILURE,
269				NULL, &err);
270			free(cmd);
271			return ((CCIMObjectPath *)NULL);
272		}
273	}
274
275	free(cmd);
276	if (cmd_return != NULL) {
277		free(cmd_return);
278	}
279
280	/*
281	 * It should be certain that the mount got created if the
282	 * cmd_execute_command_and_retrieve_string function succeded, but we
283	 * will do a second check to make sure it did and to get the devid.
284	 * We can determine if the mount exists by checking for a mount having
285	 * the same resource/mount point as the instance passed in.
286	 */
287	mnt_prop = cim_getProperty(nfsInst, nfsMountProps[ANT].name);
288	if (mnt_prop != NULL) {
289		CCIMPropertyList	*antPropList;
290
291		antPropList = mnt_prop->mObjPathValue->mKeyProperties;
292
293		mountp = util_getKeyValue(antPropList, string, NAME, &err);
294		if (mountp == NULL || err != 0) {
295			util_handleError("SOLARIS_NFSMOUNT::CREATE_INSTANCE",
296				CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
297			return ((CCIMObjectPath *)NULL);
298		}
299
300		cim_freeProperty(mnt_prop);
301
302	}
303
304	mnt_prop = cim_getProperty(nfsInst, nfsMountProps[DEP].name);
305	if (mnt_prop != NULL) {
306		CCIMPropertyList	*depPropList;
307
308		depPropList = mnt_prop->mObjPathValue->mKeyProperties;
309
310		resource = util_getKeyValue(depPropList, string, NAME, &err);
311		if (resource == NULL || err != 0) {
312			util_handleError("SOLARIS_NFSMOUNT::CREATE_INSTANCE",
313				CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
314			return ((CCIMObjectPath *)NULL);
315		}
316
317		cim_freeProperty(mnt_prop);
318	}
319
320	err = 0;
321	mntoptsParam = NULL;
322	timeParam = NULL;
323	findOverlayParam = B_TRUE;
324	mount = nfs_get_filtered_mount_list(resource, mountp, mntoptsParam,
325		timeParam, findOverlayParam, &err);
326	if (mount == NULL) {
327		if (err != 0) {
328			util_handleError("SOLARIS_NFSMOUNT::CREATE_INSTANCE",
329				CIM_ERR_FAILED, NFS_GET_FILTERED_MOUNTS_FAILURE,
330				NULL, &err);
331		}
332		cim_logDebug("cp_createInstance_Solaris_NFSMount",
333			"Mount was not found w/ resource/mount point combo");
334		/*
335		 * There were no mounts found with the resource and mount point.
336		 * We can assume that the mount wasn't created so return NULL.
337		 */
338		return ((CCIMObjectPath *)NULL);
339	}
340
341	nfsMountInstList = create_nfsMount_associations(mount, &err);
342	if (nfsMountInstList == NULL) {
343		if (err != 0) {
344			nfs_free_mntinfo_list(mount);
345			util_handleError("SOLARIS_NFSMOUNT::CREATE_INSTANCE",
346				CIM_ERR_FAILED, CREATE_NFSMOUNT_ASSOC_FAILURE,
347				NULL, &err);
348		}
349		return ((CCIMObjectPath *)NULL);
350	}
351
352	nfs_free_mntinfo_list(mount);
353
354	for (currentInst = nfsMountInstList; currentInst != NULL;
355		currentInst = currentInst->mNext) {
356
357		/*
358		 * Ideally there is only one instance, but with being able to
359		 * overlay file systems there is a possibility that there may
360		 * be multiple file systems with the same resource/mount point.
361		 * If there are multiple instances in this list the last one
362		 * returned will be used to create the return object path.
363		 * That should be the most recently created mount.
364		 */
365		if (nfsMountOP != NULL) {
366			cim_logDebug("cp_createInstance_Solaris_NFSMount",
367				"More than one mount found.");
368			cim_freeObjectPath(nfsMountOP);
369		}
370		nfsMountOP = cim_createObjectPath(currentInst->mDataObject);
371		if (nfsMountOP == NULL) {
372			ex = cim_getLastError();
373			util_handleError("SOLARIS_NFSMOUNT::CREATE_INSTANCE",
374				CIM_ERR_FAILED, CREATE_OBJECT_PATH_FAILURE,
375				ex, &err);
376			cim_freeInstanceList(nfsMountInstList);
377			return ((CCIMObjectPath *)NULL);
378		}
379	}
380
381	cim_freeInstanceList(nfsMountInstList);
382	return (nfsMountOP);
383} /* cp_createInstance_Solaris_NFSMount */
384
385/*
386 * Method: cp_deleteInstance_Solaris_NFSMount
387 *
388 * Description: Deletes a Solaris_NFSMount instance.
389 * A delete instance will actually unmount a file system on the current host by
390 * calling the cmd interface's cmd_execute_command_and_retrieve_string function.
391 *
392 * Parameters:
393 *	- CCIMObjectPath* nfsOP - The object path containing all information
394 *	needed to delete the appropriate instance.
395 *
396 * Returns:
397 *	- A CIMBool value corresponding to whether or not the instance was
398 *	deleted.  cim_true will be returned if the delete was successful,
399 *	cim_false will be returned if the delete failed.
400 */
401CIMBool
402cp_deleteInstance_Solaris_NFSMount(CCIMObjectPath* nfsOP) {
403
404	CCIMInstance		*instParam;
405	CCIMPropertyList	*propListParam;
406	char			*cmd;
407	char			*cmd_return = NULL;
408	int			err = 0;
409
410	if (nfsOP == NULL) {
411		util_handleError("SOLARIS_NFSMOUNT::DELETE_INSTANCE",
412			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
413		return (cim_false);
414	}
415
416	/*
417	 * Get the mount that is to be deleted and generate the command.
418	 */
419	instParam = NULL;
420	propListParam = NULL;
421	cmd = cmdgen_generate_command(CMDGEN_NFS_UMOUNT, instParam, nfsOP,
422		propListParam, &err);
423	if (cmd == NULL || err != 0) {
424		util_handleError("SOLARIS_NFSMOUNT::DELETE_INSTANCE",
425			CIM_ERR_FAILED, CMDGEN_GEN_CMD_FAILURE, NULL, &err);
426		return (cim_false);
427	}
428
429	/*
430	 * Execute the umount command
431	 */
432	err = 0;
433	cmd_return = cmd_execute_command_and_retrieve_string(cmd, &err);
434	if (err != 0) {
435		/*
436		 * The command execution failed.
437		 */
438		if (cmd_return != NULL) {
439			util_handleError("SOLARIS_NFSMOUNT::DELETE_INSTANCE",
440				CIM_ERR_FAILED, CMD_EXEC_RETR_STR_FAILURE,
441				NULL, &err);
442			free(cmd);
443			free(cmd_return);
444			return (cim_false);
445		} else {
446			util_handleError("SOLARIS_NFSMOUNT::DELETE_INSTANCE",
447				CIM_ERR_FAILED, CMD_EXEC_RETR_STR_FAILURE,
448				NULL, &err);
449			free(cmd);
450			return (cim_false);
451		}
452	}
453
454	free(cmd);
455	if (cmd_return != NULL)
456		free(cmd_return);
457
458	return (cim_true);
459} /* cp_deleteInstance_Solaris_NFSMount */
460
461/*
462 * Method: cp_enumInstanceNames_Solaris_NFSMount
463 *
464 * Description: Enumerates all of the nfs mounts on the host.  NFS mounts with
465 * "ignore" in the option string are ignored.
466 *
467 * Parameters:
468 *	- CCIMObjectPath* mountOP - An object path containing the name of the
469 *	class of which to enumerate instances of.
470 *
471 * Returns:
472 *	- A pointer to a list of Solaris_NFSMount object paths.
473 *	- NULL if an error occurred or if there are no NFS mounts on the host.
474 *	In the case of an error, the error will be logged.
475 */
476CCIMObjectPathList *
477cp_enumInstanceNames_Solaris_NFSMount(CCIMObjectPath* mountOP) {
478	CCIMInstanceList	*instList;
479	CCIMObjectPathList	*OPList;
480	int			err = 0;
481	/*
482	 * First check if the CCIMObjectPath parameter is null.
483	 */
484	if (mountOP == NULL) {
485		util_handleError("SOLARIS_NFSMOUNT::ENUM_INSTANCENAMES",
486			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
487		return ((CCIMObjectPathList *)NULL);
488	}
489
490	instList = cp_enumInstances_Solaris_NFSMount(mountOP);
491	if (instList == NULL)
492	{
493		/*
494		 * Failure...or there are no NFS mount instances.
495		 */
496		return ((CCIMObjectPathList *)NULL);
497	}
498
499	OPList = cim_createObjectPathList(instList);
500
501	cim_freeInstanceList(instList);
502	/*
503	 * If an error occurred in cim_createObjectPathList it will be handled
504	 * there.
505	 */
506	return (OPList);
507} /* cp_enumInstanceNames_Solaris_NFSMount */
508
509/*
510 * Method: cp_execQuery_Solaris_NFSMount
511 *
512 * Description: Queries the nfs mounts on the host to find those that meet the
513 * search criteria.
514 *
515 * Parameters:
516 *	- CCIMObjectPath *hostedShareOP - An object path containing the name of
517 *	the class to query.
518 *	- char *selectClause - Not used.
519 *	- char *nonJoinExp - Not used.
520 *	- char *queryExp - Not used.
521 *	- char *queryLang - Not used.
522 *
523 * Returns:
524 *	- A pointer to a list of Solaris_NFSMount instances that match the
525 *	criteria.
526 *	- NULL if an error occurred or if there are no Solaris_NFSMount
527 *	instances that match the criteria.  In the case of an error, the error
528 *	will be logged.
529 *
530 * NOTE: Currently, there is no WQL parser for the C providers. As a result,
531 * what is returned to the CIMOM is a list of instances with
532 * a NULL value at the beginning of the list. This NULL value indicates
533 * to the CIMOM that it must do the filtering for the client.
534 */
535/* ARGSUSED */
536CCIMInstanceList *
537cp_execQuery_Solaris_NFSMount(CCIMObjectPath *mountOP, char *selectClause,
538	char *nonJoinExp, char *queryExp, char *queryLang) {
539
540	CCIMInstance		*emptyInst;
541	CCIMInstanceList	*nfsMountInstList;
542	CCIMException		*ex;
543	int			err = 0;
544
545	if (mountOP == NULL) {
546		util_handleError("SOLARIS_NFSMOUNT::EXEC_QUERY",
547			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
548		return ((CCIMInstanceList *)NULL);
549	}
550
551	nfsMountInstList = cp_enumInstances_Solaris_NFSMount(mountOP);
552
553	if (nfsMountInstList == NULL) {
554		return ((CCIMInstanceList *)NULL);
555	}
556
557	emptyInst = cim_createInstance("");
558	if (emptyInst == NULL) {
559		ex = cim_getLastError();
560		util_handleError("SOLARIS_NFSMOUNT::EXEC_QUERY",
561			CIM_ERR_FAILED, CREATE_INSTANCE_FAILURE, ex, &err);
562		return ((CCIMInstanceList *)NULL);
563	}
564
565	nfsMountInstList = cim_prependInstance(nfsMountInstList, emptyInst);
566	if (nfsMountInstList == NULL) {
567		ex = cim_getLastError();
568		util_handleError("SOLARIS_NFSMOUNT::EXEC_QUERY",
569			CIM_ERR_FAILED, PREPEND_INSTANCE_FAILURE, ex, &err);
570		cim_freeInstance(emptyInst);
571		return ((CCIMInstanceList *)NULL);
572	}
573
574	return (nfsMountInstList);
575} /* cp_execQuery_Solaris_NFSMount */
576
577/*
578 * Method: cp_setInstance_Solaris_NFSMount
579 *
580 * Description: This method is not supported.  This is not allowed because in
581 * order to change the properties of a mount on the host, the mount must be
582 * unmounted and mounted with the new properties.  This behavior is not
583 * appropriate for the set instance.  If the client wants to change the
584 * properties of a mount they must delete the old instance and create a
585 * new one with the desired properties.
586 *
587 * Parameters:
588 *	- CCIMObjectPath *pOP - An object path containing the name of the class
589 *	of which to set the instance.
590 *	- CCIMInstance *pInst - Not used.
591 *
592 * Returns:
593 *	- cim_false is returned every time since the method is not supported.
594 */
595/* ARGSUSED */
596CIMBool
597cp_setInstance_Solaris_NFSMount(CCIMObjectPath* pOP, CCIMInstance* pInst) {
598	int	err = 0;
599
600	util_handleError("SOLARIS_NFSMOUNT::SET_INSTANCE",
601		CIM_ERR_NOT_SUPPORTED, NULL, NULL, &err);
602
603	return (cim_false);
604} /* cp_setInstance_Solaris_NFSMount */
605
606/*
607 * Method: cp_setInstanceWithList_Solaris_NFSMount
608 *
609 * Description: This method is not supported.  This is not allowed because in
610 * order to change the properties of a mount on the host, the mount must be
611 * unmounted and mounted with the new properties.  This behavior is not
612 * appropriate for the set instance.  If the client wants to change the
613 * properties of a mount they must delete the old instance and create a
614 * new one with the desired properties.
615 *
616 * Parameters:
617 *	- CCIMObjectPath *hostedShareOP - The object path containing the name
618 *	of the class of which to set the instance.
619 *	- CCIMInstance *hostedShareInst - Not used.
620 *	- char **props - Not used.
621 *	- int num_props - Not used.
622 *
623 * Returns:
624 *	- cim_false is returned every time since the method is not supported.
625 */
626/* ARGSUSED */
627CIMBool
628cp_setInstanceWithList_Solaris_NFSMount(CCIMObjectPath* mountOP,
629					CCIMInstance* mountInst,
630					char **props, int num_props) {
631	int	err = 0;
632
633	util_handleError("SOLARIS_NFSMOUNT::SET_INSTANCE",
634		CIM_ERR_NOT_SUPPORTED, NULL, NULL, &err);
635
636	return (cim_false);
637
638} /* cp_setInstanceWithList_Solaris_NFSMount */
639
640/*
641 * Associator provider methods
642 */
643
644/*
645 * Method: cp_associators_Solaris_NFSMount
646 *
647 * Description: Returns the instances associated, via the Solaris_NFSMount
648 * association, to the pObjectName parameter.
649 *
650 * Parameters:
651 *	- CCIMObjectPath *pAssocName - An object path containing the name of
652 *	the association that the caller is trying to reach.
653 *	- CCIMObjectPath *pObjectName - The object path containing information
654 *	(Class Name, Key Properties) about the object whose associated objects
655 *	are to be returned.
656 *	- char *pResultClass - If specified, only return instances that are of
657 *	this class type.
658 *	- char *pRole - If specified, this is the role of the pObjectName
659 *	object path passed in.  If this is not valid, NULL is returned.
660 *	- char *pResultRole - If specified, only return instances that are
661 *	playing this role in the association.
662 *
663 * Returns:
664 *	- A pointer to a list of Solaris_NFS (if pRole == Antecedent &&
665 *	pObjectName is a Solaris_Directory object path) or Solaris_Directory
666 *	(if pRole == DEPENDENT && pObjectName is a Solaris_NFS object path)
667 *	instances which are associated to the pObjectName parameter.
668 *	- NULL if an error occurred or if there are no instances associated to
669 *	the pObjectName passed in.  In the case of an error, the error will be
670 *	logged.
671 */
672/* ARGSUSED */
673CCIMInstanceList *
674cp_associators_Solaris_NFSMount(CCIMObjectPath *pAssocName,
675	CCIMObjectPath *pObjectName, char *pResultClass, char *pRole,
676	char *pResultRole) {
677
678	CCIMInstanceList	*returnInstList;
679	CCIMPropertyList	*propList;
680	nfs_mntlist_t		*mountList;
681	cimchar			*name;
682	boolean_t		isAntecedent = B_FALSE;
683	int			err = 0;
684
685	/*
686	 * Check if the needed parameters are null.
687	 */
688	if (pObjectName == NULL || pObjectName->mKeyProperties == NULL) {
689		util_handleError("SOLARIS_NFSMOUNT::ASSOCIATORS",
690			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
691		return ((CCIMInstanceList *)NULL);
692	}
693
694	/*
695	 * The Name key property is the defining property for each the
696	 * Antecedent (Solaris_Directory) and the Dependent (Solaris_NFS)
697	 * so retrieve that property.
698	 */
699	propList = pObjectName->mKeyProperties;
700	name = (cimchar *)util_getKeyValue(propList, string, NAME, &err);
701
702	if (name == NULL || err != 0) {
703		util_handleError("SOLARIS_NFSMOUNT::ASSOCIATORS",
704			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
705		return ((CCIMInstanceList *)NULL);
706	}
707
708	/*
709	 * Determine whether pObjectName is the Antecedent or the Dependent
710	 * of the association.  Antecedent = Solaris_Directory,
711	 * Dependent = Solaris_NFS
712	 */
713	if ((strcasecmp(pObjectName->mName, SOLARIS_DIR) == 0)) {
714		isAntecedent = B_TRUE;
715		/*
716		 * If a value was passed in with pRole and it does not match
717		 * the role that pObjectName actually is then log an invalid
718		 * param error.
719		 */
720		if (pRole != NULL && (strcasecmp(pRole, ANTECEDENT) != 0)) {
721			util_handleError("SOLARIS_NFSMOUNT::ASSOCIATORS",
722				CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
723			return ((CCIMInstanceList *)NULL);
724		}
725	} else {
726		isAntecedent = B_FALSE;
727		if (pRole != NULL && (strcasecmp(pRole, DEPENDENT) != 0)) {
728			util_handleError("SOLARIS_NFSMOUNT::ASSOCIATORS",
729				CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
730			return ((CCIMInstanceList *)NULL);
731		}
732	}
733
734	mountList = get_associated_nfs_mntlist(isAntecedent, name);
735	if (mountList == NULL)
736		return ((CCIMInstanceList *)NULL);
737	returnInstList = get_associated_instances(mountList, (!isAntecedent));
738	nfs_free_mntinfo_list(mountList);
739
740	return (returnInstList);
741} /* cp_associators_Solaris_NFSMount */
742
743/*
744 * Method: cp_associatorNames_Solaris_NFSMount
745 *
746 * Description: Returns the object paths of the instances on the other side of
747 * the association which are associated via the Solaris_NFSMount association
748 * and having the passed in parameter, pObjectName, as the opposite key.
749 *
750 * Parameters:
751 *	- CCIMObjectPath *pAssocName - An object path containing information
752 *	about the association that the caller is trying to reach.
753 *	- CCIMObjectPath *pObjectName - The object path which contains the
754 *	information on whose associated objects are to be returned.
755 *	- char *pResultClass - If specified, only return instances that are of
756 *	this class type.
757 *	- char *pRole - If specified, this is the role of the pObjectName
758 *	object path passed in.  If this is not valid, NULL is returned.
759 *	- char *pResultRole - If specified, only return instances that are
760 *	playing this role in the association.
761 *
762 * Returns:
763 *	- A pointer to a list of Solaris_NFS (if pRole == Antecedent &&
764 *	pObjectName is a Solaris_Directory object path) or Solaris_Directory
765 *	(if pRole == DEPENDENT && pObjectName is a Solaris_NFS object path)
766 *	object paths which are associated to the pObjectName parameter.
767 *	- NULL if an error occurred or if there are no instances associated to
768 *	the pObjectName passed in.  In the case of an error, the error will be
769 *	logged.
770 */
771CCIMObjectPathList *
772cp_associatorNames_Solaris_NFSMount(CCIMObjectPath *pAssocName,
773	CCIMObjectPath *pObjectName, char *pResultClass, char *pRole,
774	char *pResultRole) {
775
776	CCIMInstanceList	*instList;
777	CCIMObjectPathList	*objPathList;
778	int			err = 0;
779
780	if (pObjectName == NULL || pObjectName->mKeyProperties == NULL) {
781		util_handleError("SOLARIS_NFSMOUNT::ASSOCIATOR_NAMES",
782			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
783		return ((CCIMObjectPathList *)NULL);
784	}
785
786	instList = cp_associators_Solaris_NFSMount(pAssocName, pObjectName,
787		pResultClass, pRole, pResultRole);
788
789	if (instList != NULL) {
790		objPathList = cim_createObjectPathList(instList);
791		cim_freeInstanceList(instList);
792	}
793
794	return (objPathList);
795} /* cp_associatorNames_Solaris_NFSMount */
796
797/*
798 * Method: cp_references_Solaris_NFSMount
799 *
800 * Description: Returns the Solaris_NFSMount instances that have the passed in
801 * parameter, pObjectName, as one of it's keys.
802 *
803 * Parameters:
804 *	- CCIMObjectPath *pAssocName - An object path containing information
805 *	about the association that the caller is trying to reach.
806 *	- CCIMObjectPath *pObjectName - The object path which contains the
807 *	information on whose associated objects are to be returned.
808 *	- char *pRole - If specified, this is the role of the pObjectName
809 *	object path passed in.  If this is not valid, NULL is returned.
810 *
811 * Returns:
812 *	- A pointer to a list of Solaris_NFSMount instances.
813 *	- NULL if an error occurred or if there are no Solaris_NFSMount
814 *	instances having pObjectName as one of it's keys.
815 */
816/* ARGSUSED */
817CCIMInstanceList *
818cp_references_Solaris_NFSMount(CCIMObjectPath *pAssocName,
819	CCIMObjectPath *pObjectName, char *pRole) {
820
821	CCIMInstanceList	*instList;
822	CCIMPropertyList	*propList;
823	nfs_mntlist_t		*mountList;
824	char			*name;
825	boolean_t		isAntecedent = B_FALSE;
826	int			err = 0;
827
828	if (pObjectName == NULL || pObjectName->mKeyProperties == NULL) {
829		util_handleError("SOLARIS_NFSMOUNT::REFERENCES",
830			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
831		return ((CCIMInstanceList *)NULL);
832	}
833
834	/*
835	 * The Name key property is the defining property for each the
836	 * Antecedent (Solaris_Directory) and the Dependent (Solaris_NFS)
837	 * so retrieve that property.
838	 */
839	propList = pObjectName->mKeyProperties;
840	name = (cimchar *)util_getKeyValue(propList, string, NAME, &err);
841
842	if (name == NULL || err != 0) {
843		/*
844		 * The object path passed in does not have the appropriate
845		 * information.
846		 */
847		util_handleError("SOLARIS_NFSMOUNT::ASSOCIATORS",
848			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
849		return ((CCIMInstanceList *)NULL);
850	}
851
852	if ((strcasecmp(pObjectName->mName, SOLARIS_DIR) == 0)) {
853		isAntecedent = B_TRUE;
854		/*
855		 * If a value was passed in with pRole and it does not match
856		 * the role that pObjectName actually is then log an invalid
857		 * param error.
858		 */
859		if (pRole != NULL && (strcasecmp(pRole, ANTECEDENT) != 0)) {
860			util_handleError("SOLARIS_NFSMOUNT::REFERENCES",
861				CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
862			return ((CCIMInstanceList *)NULL);
863		}
864	} else {
865		isAntecedent = B_FALSE;
866		if (pRole != NULL && (strcasecmp(pRole, DEPENDENT) != 0)) {
867			util_handleError("SOLARIS_NFSMOUNT::REFERENCES",
868				CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
869			return ((CCIMInstanceList *)NULL);
870		}
871	}
872
873	mountList = get_associated_nfs_mntlist(isAntecedent, name);
874	if (mountList == NULL)
875		return ((CCIMInstanceList *)NULL);
876	instList = create_nfsMount_associations(mountList, &err);
877
878	nfs_free_mntinfo_list(mountList);
879
880	return (instList);
881} /* cp_references_Solaris_NFSMount */
882
883/*
884 * Method: cp_referenceNames_Solaris_NFSMount
885 *
886 * Description: Returns the Solaris_NFSMount object paths of the instances
887 * that have the passed in parameter, pObjectName, as one of it's keys.
888 *
889 * Parameters:
890 *	- CCIMObjectPath *pAssocName - An object path containing information
891 *	about the association that the caller is trying to reach.
892 *	- CCIMObjectPath *pObjectName - The object path which contains the
893 *	information on whose associated objects are to be returned.
894 *	- char *pRole - If specified, this is the role of the pObjectName
895 *	object path passed in.  If this is not valid, NULL is returned.
896 *
897 * Returns:
898 *	- A pointer to a list of Solaris_NFSMount object paths.
899 *	- NULL if an error occurred or if there are no Solaris_NFSMount
900 *	instances having pObjectName as one of it's keys.
901 */
902CCIMObjectPathList *
903cp_referenceNames_Solaris_NFSMount(CCIMObjectPath *pAssocName,
904	CCIMObjectPath *pObjectName, char *pRole) {
905
906	CCIMInstanceList	*nfsMountInstList;
907	CCIMObjectPathList	*nfsMountOPList;
908	CCIMException		*ex;
909	int			err = 0;
910
911	if (pObjectName == NULL || pObjectName->mKeyProperties == NULL) {
912		util_handleError("SOLARIS_NFSMOUNT::REFERENCES_NAMES",
913			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
914		return ((CCIMObjectPathList *)NULL);
915	}
916
917	nfsMountInstList = cp_references_Solaris_NFSMount(pAssocName,
918		pObjectName, pRole);
919
920	if (nfsMountInstList == NULL) {
921		return ((CCIMObjectPathList *)NULL);
922	}
923
924	nfsMountOPList = cim_createObjectPathList(nfsMountInstList);
925	if (nfsMountOPList == NULL) {
926		ex = cim_getLastError();
927		util_handleError("SOLARIS_NFSMOUNT::REFERENCE_NAMES",
928			CIM_ERR_FAILED, CREATE_OBJECT_LIST_FAILURE, ex, &err);
929		cim_freeInstanceList(nfsMountInstList);
930		return ((CCIMObjectPathList *)NULL);
931	}
932
933	cim_freeInstanceList(nfsMountInstList);
934
935	return (nfsMountOPList);
936} /* cp_referenceNames_Solaris_NFSMount */
937
938/*
939 * Property provider methods
940 */
941
942/*
943 * Method: cp_getProperty_Solaris_NFSMount
944 *
945 * Description: Retrieves a certain property from the instance of
946 * Solaris_NFSMount on the host that is described by the parameter pOP.
947 *
948 * Parameters:
949 *	- CCIMObjectPath *pOP - The object path containing all the
950 *	information needed to find the instance in which the property is to
951 *	be returned.
952 *	- cimchar *pPropName - The name of the property to be found.
953 *
954 * Returns:
955 *	- A pointer to the property corresponding to the name passed in with
956 *	pPropName.
957 *	- NULL if an error occurred or if the property doesn't exist.  In the
958 *	case of an error, the error will be logged.
959 */
960CCIMProperty *
961cp_getProperty_Solaris_NFSMount(CCIMObjectPath *pOP, cimchar *pPropName) {
962	CCIMInstance	*nfsMountInst;
963	CCIMProperty	*nfsMountProp;
964	int		err = 0;
965
966	if (pOP == NULL || pPropName == NULL) {
967		util_handleError("SOLARIS_NFSMOUNT::GET_PROPERTY",
968			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
969		return ((CCIMProperty *)NULL);
970	}
971
972	nfsMountInst = cp_getInstance_Solaris_NFSMount(pOP);
973	if (nfsMountInst == NULL) {
974		return ((CCIMProperty *)NULL);
975	}
976
977	nfsMountProp = cim_getProperty(nfsMountInst, pPropName);
978
979	cim_freeInstance(nfsMountInst);
980	/*
981	 * If an error occurred in cim_getProperty it will be handled there.
982	 */
983	return (nfsMountProp);
984} /* cp_getProperty_Solaris_NFSMount */
985
986/*
987 * Method: cp_setProperty_Solaris_NFSMount
988 *
989 * Description: This method is not supported.  This is not allowed because in
990 * order to change the properties of a mount on the host, the mount must be
991 * unmounted and mounted with the new properties.  This behavior is not
992 * appropriate for the set property.  If the client wants to change the
993 * properties of a mount they must delete the old instance and create a
994 * new one with the desired properties.
995 *
996 * Parameters:
997 *	- CCIMObjectPath *pOP - Not used.
998 *	- CCIMProperty *pProp - Not used.
999 *
1000 * Returns:
1001 *	- cim_false is returned every time since the method is not supported.
1002 */
1003/* ARGSUSED */
1004CIMBool
1005cp_setProperty_Solaris_NFSMount(CCIMObjectPath *pOP, CCIMProperty *pProp) {
1006	int	err = 0;
1007
1008	util_handleError("SOLARIS_NFSMOUNT::SET_PROPERTY",
1009		CIM_ERR_NOT_SUPPORTED, NULL, NULL, &err);
1010
1011	return (cim_false);
1012} /* cp_setProperty_Solaris_NFSMount */
1013
1014/*
1015 * Method provider methods
1016 */
1017
1018/*
1019 * Method: cp_invokeMethod_Solaris_NFSMount
1020 *
1021 * Description: Routes the cp_invokeMethod_Solaris_NFSMount calls to the
1022 * correct Solaris_NFSMount methods.
1023 *
1024 * Parameters:
1025 *	- CCIMObjectPath *pOP - The object path containing needed information
1026 *	about the class that is to getting methods invoked.
1027 *	- cimchar *functionName - The name of the function to be invoked.
1028 *	- CCIMPropertyList *inParams - The input parameters to the function.
1029 *	- CCIMPropertyList *outParams - The output parameters from the function.
1030 *
1031 * Returns:
1032 *	- A pointer to a property which indicates success or failure of the
1033 *	function.  1 for success, 0 for failure.
1034 *	- Upon error, NULL is returned and the error is logged.
1035 */
1036/* ARGSUSED */
1037CCIMProperty *
1038cp_invokeMethod_Solaris_NFSMount(CCIMObjectPath *pOP, cimchar *functionName,
1039	CCIMPropertyList *inParams, CCIMPropertyList *outParams) {
1040
1041	int		err = 0;
1042	CCIMProperty	*retVal;
1043
1044	if (pOP == NULL || functionName == NULL) {
1045		util_handleError("SOLARIS_NFSMOUNT::INVOKE_METHOD",
1046			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &err);
1047		return ((CCIMProperty *)NULL);
1048	}
1049	cim_logDebug("cp_invokeMethod_Solaris_NFSMount",
1050		"Invoking %s", functionName);
1051	/*
1052	 * Determine what method is being called.
1053	 */
1054	if (strcasecmp(functionName, GET_NET_CFG_LIST_METHOD) == 0) {
1055		retVal = get_netconfig_list(outParams);
1056	} else if (strcasecmp(functionName, GET_NFS_SEC_LIST_METHOD) == 0) {
1057		retVal = get_nfssec_list(outParams);
1058	} else if (strcasecmp(functionName, GET_DEF_SECMODE_METHOD) == 0) {
1059		retVal = get_default_secmode(outParams);
1060	} else if (strcasecmp(functionName, SHOW_EXPORTS_METHOD) == 0) {
1061		retVal = show_exports(inParams, outParams);
1062	} else if (strcasecmp(functionName, DELETE_VFSTAB_ENT_METHOD) == 0) {
1063		retVal = delete_vfstab_entry(inParams);
1064	} else {
1065		/*
1066		 * No such method name.
1067		 */
1068		util_handleError("SOLARIS_NFSMOUNT::INVOKE_METHOD",
1069			CIM_ERR_FAILED, NO_SUCH_METHOD, NULL, &err);
1070		return ((CCIMProperty *)NULL);
1071	}
1072
1073	return (retVal);
1074} /* cp_invokeMethod_Solaris_NFSMount */
1075
1076/*
1077 * Private Methods
1078 */
1079
1080/*
1081 * Method: create_nfsMount_associations
1082 *
1083 * Description: Creates Solaris_NFSMount associations out of the information
1084 * gathered from all the NFS mounts on the host.
1085 *
1086 * Parameters:
1087 *	- nfs_mntlist_t *mountList - The list of nfs mounts on the host.
1088 *	- int *errp - The error pointer.  If an error occurs, this will be a
1089 * 	non-zero number.
1090 *
1091 * Returns:
1092 *	- A pointer to a list of all the Solaris_NFSMount instances on the host.
1093 *	- NULL if an error occurred or if there aren't any NFS mounts on the
1094 *	host.  In the case of an error, the error will be logged.
1095 */
1096static CCIMInstanceList *
1097create_nfsMount_associations(nfs_mntlist_t *mountList, int *errp) {
1098	nfs_mntlist_t		*currentMnt;
1099	CCIMInstanceList	*nfsMountInstList;
1100	CCIMException		*ex;
1101
1102	nfsMountInstList = cim_createInstanceList();
1103	if (nfsMountInstList == NULL) {
1104		ex = cim_getLastError();
1105		util_handleError("SOLARIS_NFSMOUNT::CREATE_NFSMOUNT_ASSOC",
1106			CIM_ERR_FAILED, CREATE_INSTANCE_LIST_FAILURE, ex,
1107			errp);
1108		return ((CCIMInstanceList *)NULL);
1109	}
1110
1111	for (currentMnt = mountList; currentMnt != NULL;
1112		currentMnt = currentMnt->next) {
1113
1114		CCIMInstance		*nfsMountInst;
1115		CCIMPropertyList	*nfsMountPropList;
1116
1117		/*
1118		 * Create the Solaris_NFSMount instance and add the properties
1119		 * to the instance.
1120		 */
1121		nfsMountInst = cim_createInstance(SOLARIS_NFSMOUNT);
1122		if (nfsMountInst == NULL) {
1123			ex = cim_getLastError();
1124			util_handleError(
1125				"SOLARIS_NFSMOUNT::CREATE_NFSMOUNT_ASSOC",
1126				CIM_ERR_FAILED, CREATE_INSTANCE_FAILURE,
1127				ex, errp);
1128			cim_freeInstanceList(nfsMountInstList);
1129			return ((CCIMInstanceList *)NULL);
1130		}
1131
1132		nfsMountPropList = populate_property_list(currentMnt);
1133		if (nfsMountPropList == NULL) {
1134			/*
1135			 * An error was encountered, but it was logged in
1136			 * populate_property_list so just return null.
1137			 */
1138			cim_freeInstanceList(nfsMountInstList);
1139			cim_freeInstance(nfsMountInst);
1140			return ((CCIMInstanceList *)NULL);
1141		}
1142
1143		/*
1144		 * Add the returned property list to the instance.
1145		 */
1146		nfsMountInst = cim_addPropertyListToInstance(nfsMountInst,
1147			nfsMountPropList);
1148		if (nfsMountInst == NULL) {
1149			ex = cim_getLastError();
1150			util_handleError(
1151				"SOLARIS_NFSMOUNT::CREATE_NFSMOUNT_ASSOC",
1152				CIM_ERR_FAILED, PROPLIST_TO_INSTANCE_FAILURE,
1153				ex, errp);
1154			cim_freeInstanceList(nfsMountInstList);
1155			cim_freePropertyList(nfsMountPropList);
1156			return ((CCIMInstanceList *)NULL);
1157		}
1158
1159		/*
1160		 * Add the instance to the instance list.
1161		 */
1162		nfsMountInstList = cim_addInstance(nfsMountInstList,
1163			nfsMountInst);
1164		if (nfsMountInstList == NULL) {
1165			ex = cim_getLastError();
1166			util_handleError(
1167				"SOLARIS_NFSMOUNT::CREATE_NFSMOUNT_ASSOC",
1168				CIM_ERR_FAILED, ADD_INSTANCE_FAILURE,
1169				ex, errp);
1170			/*
1171			 * Freeing the instance will free the property list
1172			 * that was added to it.  There is no need to free
1173			 * the property list separately.
1174			 */
1175			cim_freeInstance(nfsMountInst);
1176			return ((CCIMInstanceList *)NULL);
1177		}
1178	}
1179
1180	return (nfsMountInstList);
1181} /* create_nfsMount_associations */
1182
1183/*
1184 * Method: enumerate_mounts
1185 *
1186 * Description: Enumerates the NFS mounts on the host by using the
1187 * nfs_mntinfo nfs_get_mount_list method.
1188 *
1189 * Parameters:
1190 *	- NONE
1191 *
1192 * Returns:
1193 *	- A pointer to a list of all the Solaris_NFSMount instances on the host.
1194 *	- NULL if an error occurred or if there are no NFS mounts on the system.
1195 *	In the case of an error, the error will be logged.
1196 */
1197static CCIMInstanceList *
1198enumerate_mounts() {
1199	int get_mntlist_err = 0;
1200	int err = 0;
1201	nfs_mntlist_t 	*nfs_mount_list;
1202
1203	nfs_mount_list = nfs_get_mount_list(&get_mntlist_err);
1204	if (nfs_mount_list == NULL) {
1205		/*
1206		 * Check whether an error was returned or if we simply don't
1207		 * have any nfs file systems on the system. If
1208		 * get_mntlist_err is not equal to 0, an error was encountered.
1209		 */
1210		if (get_mntlist_err != 0) {
1211			/*
1212			 * Determine the error and log it.
1213			 */
1214			if (get_mntlist_err == ENOMEM ||
1215				get_mntlist_err == EAGAIN) {
1216				util_handleError(
1217					"SOLARIS_NFSMOUNT::ENUM_MOUNTS",
1218					CIM_ERR_LOW_ON_MEMORY,
1219					NFS_GET_MNTLIST_FAILURE,
1220					NULL, &err);
1221
1222				return ((CCIMInstanceList *)NULL);
1223			} else {
1224				/*
1225				 * If any other errors were encountered it
1226				 * can be handled as a general error.  We may
1227				 * not know exactly what the error is.
1228				 */
1229				util_handleError(
1230					"SOLARIS_NFSMOUNT::ENUM_MOUNTS",
1231					CIM_ERR_FAILED,
1232					NFS_GET_MNTLIST_FAILURE,
1233					NULL, &err);
1234
1235				return ((CCIMInstanceList *)NULL);
1236			}
1237		}
1238		/*
1239		 * We simply don't have any nfs mounts on the host.
1240		 */
1241		return ((CCIMInstanceList *)NULL);
1242
1243	} else {
1244		/*
1245		 * At this point, one or more nfs mounts were found on the
1246		 * system, create the instance list from the nfs_mount_list.
1247		 */
1248		CCIMInstanceList	*nfsMountInstList;
1249
1250		nfsMountInstList = create_nfsMount_associations(nfs_mount_list,
1251			&err);
1252
1253		nfs_free_mntinfo_list(nfs_mount_list);
1254		return (nfsMountInstList);
1255	} /* if (nfs_mount_list == NULL) */
1256
1257} /* enumerate_mounts */
1258
1259/*
1260 * Method: get_Antecedent
1261 *
1262 * Description: Creates the Antecedent object path of the Solaris_NFSMount
1263 * class.
1264 *
1265 * Parameters:
1266 *	- cimchar *mount_point - the mount point of the nfs mount which is
1267 *	used as the Name Key property of the Antecedent, Solaris_Directory.
1268 *
1269 * Returns:
1270 *	- The corresponding Solaris_Directory CCIMObjectPath* is returned.
1271 *	- Upon error NULL is returned.
1272 *	The returned CCIMObjectPath* must be freed by the calling function.
1273 */
1274static CCIMObjectPath *
1275get_Antecedent(cimchar *mount_point) {
1276	CCIMInstance	*solarisDirInst;
1277	CCIMObjectPath	*solarisDirOP;
1278	CCIMException	*ex;
1279	int		err;
1280	char		*hostname;
1281
1282	solarisDirInst = cim_createInstance(SOLARIS_DIR);
1283	if (solarisDirInst == NULL) {
1284		ex = cim_getLastError();
1285		util_handleError("SOLARIS_NFSMOUNT::GET_ANT",
1286			CIM_ERR_FAILED, CREATE_INSTANCE_FAILURE, ex, &err);
1287		return ((CCIMObjectPath *)NULL);
1288	}
1289
1290	/*
1291	 * Create the key properties on the Solaris_Directory instance.
1292	 *
1293	 * The Solaris_Directory keys are as follows:
1294	 * CSCreationClassName = "Solaris_ComputerSystem"
1295	 * CSName = < hostname >
1296	 * FSCreationClassName = "Solaris_NFS"
1297	 * FSName = "NFS"
1298	 * CreationClassName = "Solaris_Directory"
1299	 * Name = < full pathname of mount point >
1300	 */
1301	if (add_property_to_instance(CS_CREATION_CLASS, string,
1302		SOLARIS_CS, NULL, cim_true, solarisDirInst) == cim_false) {
1303
1304		cim_freeInstance(solarisDirInst);
1305		return ((CCIMObjectPath *)NULL);
1306	}
1307
1308	hostname = sys_get_hostname(&err);
1309	if (hostname == NULL) {
1310		util_handleError("SOLARIS_NFSMOUNT::GET_ANT)", CIM_ERR_FAILED,
1311			GET_HOSTNAME_FAILURE, NULL, &err);
1312		return ((CCIMObjectPath *)NULL);
1313	}
1314
1315	if (add_property_to_instance(CSNAME, string, hostname,
1316		NULL, cim_true, solarisDirInst) == cim_false) {
1317
1318		free(hostname);
1319		cim_freeInstance(solarisDirInst);
1320		return ((CCIMObjectPath *)NULL);
1321	}
1322	free(hostname);
1323
1324	if (add_property_to_instance(FS_CREATION_CLASS, string,
1325		SOLARIS_NFS, NULL, cim_true, solarisDirInst) == cim_false) {
1326
1327		cim_freeInstance(solarisDirInst);
1328		return ((CCIMObjectPath *)NULL);
1329	}
1330
1331	if (add_property_to_instance(FSNAME, string,
1332		NFS, NULL, cim_true, solarisDirInst) == cim_false) {
1333
1334		cim_freeInstance(solarisDirInst);
1335		return ((CCIMObjectPath *)NULL);
1336	}
1337
1338	if (add_property_to_instance(CREATION_CLASS, string,
1339		SOLARIS_DIR, NULL, cim_true, solarisDirInst) == cim_false) {
1340
1341		cim_freeInstance(solarisDirInst);
1342		return ((CCIMObjectPath *)NULL);
1343	}
1344
1345	if (add_property_to_instance(NAME, string, mount_point,
1346		NULL, cim_true, solarisDirInst) == cim_false) {
1347
1348		cim_freeInstance(solarisDirInst);
1349		return ((CCIMObjectPath *)NULL);
1350	}
1351
1352	solarisDirOP = cim_createObjectPath(solarisDirInst);
1353	if (solarisDirOP == NULL) {
1354		ex = cim_getLastError();
1355		util_handleError("SOLARIS_NFSMOUNT::GET_ANT",
1356			CIM_ERR_FAILED, CREATE_OBJECT_PATH_FAILURE,
1357			ex, &err);
1358		cim_freeInstance(solarisDirInst);
1359		return ((CCIMObjectPath *)NULL);
1360	}
1361
1362	cim_freeInstance(solarisDirInst);
1363	return (solarisDirOP);
1364} /* get_Antecedent */
1365
1366/*
1367 * Method: get_associated_instances
1368 *
1369 * Description: Gets instances associated to the mounts passed in with
1370 * mountList.
1371 *
1372 * Parameters:
1373 *	- nfs_mntlist_t *mountList - The nfs mount list from which to get the
1374 *	associated instances.
1375 *	- boolean_t resultIsAnt - Whether or not the role that the instance
1376 *	returned plays in the association is the Antecedent.
1377 *
1378 * Returns:
1379 *	- A pointer to a list of Solaris_NFS or Solaris_Directory instances that
1380 *	are associated to the mount passed in with mountList.
1381 *	- NULL if an error occurred or if there are no instances that are
1382 *	associated to mountList.
1383 */
1384static CCIMInstanceList *
1385get_associated_instances(nfs_mntlist_t *mountList, boolean_t resultIsAnt) {
1386	CCIMInstanceList	*returnInstList;
1387	CCIMException		*ex;
1388	nfs_mntlist_t		*currentMnt;
1389	int			err = 0;
1390
1391	returnInstList = cim_createInstanceList();
1392	if (returnInstList == NULL) {
1393		ex = cim_getLastError();
1394		util_handleError("SOLARIS_NFSMOUNT::GET_ASSOC_INST",
1395			CIM_ERR_FAILED, CREATE_INSTANCE_LIST_FAILURE, ex, &err);
1396		return ((CCIMInstanceList *)NULL);
1397	}
1398
1399	for (currentMnt = mountList; currentMnt != NULL;
1400		currentMnt = currentMnt->next) {
1401		/*
1402		 * Determine if we are supposed to form the Antecedent or
1403		 * Dependent instances by checking the value of resultIsAnt.
1404		 */
1405		if (resultIsAnt == B_FALSE) {
1406			CCIMObjectPath	*nfsOP;
1407			CCIMInstance	*nfsInst;
1408
1409			nfsOP = get_Dependent(currentMnt);
1410			if (nfsOP == NULL) {
1411				/*
1412				 * An error occurred in get_Dependent and was
1413				 * handled there so just return NULL.
1414				 */
1415				cim_freeInstanceList(returnInstList);
1416				return ((CCIMInstanceList *)NULL);
1417			}
1418
1419			nfsInst = cimom_getInstance(nfsOP, cim_false,
1420				cim_false, cim_false, cim_false, NULL, 0);
1421
1422			/*
1423			 * A NULL return value indicates an error, an empty
1424			 * list does not.
1425			 */
1426			if (nfsInst == NULL) {
1427				ex = cim_getLastError();
1428				util_handleError(
1429					"SOLARIS_NFSMOUNT::GET_ASSOC_INST",
1430					CIM_ERR_FAILED, CIMOM_GET_INST_FAILURE,
1431					ex, &err);
1432				cim_freeObjectPath(nfsOP);
1433				cim_freeInstanceList(returnInstList);
1434				return ((CCIMInstanceList *)NULL);
1435			}
1436
1437			cim_freeObjectPath(nfsOP);
1438
1439			if (nfsInst->mProperties == NULL) {
1440				cim_freeInstanceList(returnInstList);
1441				return ((CCIMInstanceList *)NULL);
1442			}
1443
1444			/*
1445			 * Add the Solaris_NFS instance to the instance
1446			 * list to be returned.
1447			 */
1448			returnInstList = cim_addInstance(returnInstList,
1449				nfsInst);
1450			if (returnInstList == NULL) {
1451				ex = cim_getLastError();
1452				util_handleError(
1453					"SOLARIS_NFSMOUNT::GET_ASSOC_INST",
1454					CIM_ERR_FAILED, ADD_INSTANCE_FAILURE,
1455					ex, &err);
1456				cim_freeInstance(nfsInst);
1457				return ((CCIMInstanceList *)NULL);
1458			}
1459		} else {
1460			CCIMObjectPath	*dirOP;
1461			CCIMInstance	*dirInst;
1462
1463			dirOP = (CCIMObjectPath *)get_Antecedent(
1464				currentMnt->nml_mountp);
1465
1466			if (dirOP == NULL) {
1467				/*
1468				 * An error occurred in get_Antecedent and was
1469				 * handled there so just return NULL.
1470				 */
1471				cim_freeInstanceList(returnInstList);
1472				return ((CCIMInstanceList *)NULL);
1473			}
1474			cim_logDebug("get_associated_instances",
1475				"dirOP =%s", dirOP->mName);
1476
1477			dirInst = cimom_getInstance(dirOP, cim_false,
1478				cim_false, cim_false, cim_false, NULL, 0);
1479
1480			/*
1481			 * A NULL return value means error, an empty list
1482			 * does not.
1483			 */
1484			if (dirInst == NULL) {
1485				ex = cim_getLastError();
1486				util_handleError(
1487					"SOLARIS_NFSMOUNT::GET_ASSOC_INST",
1488					CIM_ERR_FAILED, CIMOM_GET_INST_FAILURE,
1489					ex, &err);
1490				cim_freeObjectPath(dirOP);
1491				cim_freeInstanceList(returnInstList);
1492				return ((CCIMInstanceList *)NULL);
1493			}
1494
1495			cim_freeObjectPath(dirOP);
1496
1497			if (dirInst->mProperties == NULL) {
1498				cim_freeInstance(dirInst);
1499				cim_freeInstanceList(returnInstList);
1500				return ((CCIMInstanceList *)NULL);
1501			}
1502
1503			/*
1504			 * Work around for cimom bug 4649100.
1505			 */
1506			if (!set_dir_keyProperties_to_true(dirInst)) {
1507				cim_freeInstance(dirInst);
1508				cim_freeInstanceList(returnInstList);
1509				return ((CCIMInstanceList *)NULL);
1510			}
1511
1512			/*
1513			 * Add the Solaris_Directory instance to the
1514			 * instance list to be returned.
1515			 */
1516			returnInstList = cim_addInstance(returnInstList,
1517				dirInst);
1518			if (returnInstList == NULL) {
1519				ex = cim_getLastError();
1520				util_handleError(
1521					"SOLARIS_NFSMOUNT::GET_ASSOC_INST",
1522					CIM_ERR_FAILED, ADD_INSTANCE_FAILURE,
1523					ex, &err);
1524				cim_freeInstance(dirInst);
1525				return ((CCIMInstanceList *)NULL);
1526			}
1527		}
1528	}
1529
1530	return (returnInstList);
1531} /* get_associated_instances */
1532
1533/*
1534 * Method: get_associated_nfs_mntlist
1535 *
1536 * Description: Gets a list of mounts, including their information, that have
1537 * the same value as nameKeyValue for the Name property.
1538 *
1539 * Parameters:
1540 *	- boolean_t isAntecedent - A boolean value representing whether the
1541 *	key value passed in with nameKeyVal is the Antecedent or not.
1542 *	- char *nameKeyVal - The value of the Name key.
1543 *
1544 * Returns:
1545 *	- A pointer to a list of nfs mounts.
1546 *	- NULL if an error occurred or if there are no mounts having the same
1547 *	information as passed in with nameKeyVal.
1548 */
1549static nfs_mntlist_t *
1550get_associated_nfs_mntlist(boolean_t isAntecedent, char *nameKeyVal) {
1551	nfs_mntlist_t	*mountList;
1552	int		err = 0;
1553
1554	if (isAntecedent) {
1555		/*
1556		 * The nameKeyValue is that of the Antecedent,
1557		 * Solaris_Directory.
1558		 */
1559		/*
1560		 * The Name property is populated with the mount point of the
1561		 * nfs file system so we need to determine if the mount point
1562		 * exists.
1563		 */
1564		mountList = nfs_get_filtered_mount_list(NULL, nameKeyVal, NULL,
1565			NULL, B_TRUE, &err);
1566		if (mountList == NULL) {
1567			/*
1568			 * Check if an error occurred and if it did handle it.
1569			 */
1570			if (err != 0) {
1571				util_handleError(
1572					"SOLARIS_NFSMOUNT::GET_ASSOC_NFSMNTS",
1573					CIM_ERR_FAILED,
1574					NFS_GET_FILTERED_MOUNTS_FAILURE,
1575					NULL, &err);
1576				return (NULL);
1577			}
1578			/*
1579			 * If no error occurred then we know that the mount
1580			 * point doesn't exist so return NULL.
1581			 */
1582			return (NULL);
1583		}
1584	} else {
1585		char	*resource;
1586		char	*devid;
1587		char	*devMntOpt = "dev=";
1588		char	*searchOpt;
1589		int	searchOptLen;
1590
1591		/*
1592		 * The nameKeyValue is that of the Dependent, Solaris_NFS.
1593		 */
1594		/*
1595		 * Get the resource and devid from the Name key property
1596		 * which should be in the form:
1597		 * "resource:=< resource > devid:=< devid >"
1598		 */
1599		err = 0;
1600		devid = get_devid(nameKeyVal, &err);
1601		if (devid == NULL) {
1602			util_handleError(
1603				"SOLARIS_NFSMOUNT::GET_ASSOC_NFSMNTS",
1604				CIM_ERR_FAILED, GET_DEVID_FAILURE, NULL, &err);
1605			return (NULL);
1606		}
1607
1608		cim_logDebug("get_associated_nfs_mntlist",
1609			"isDependent: devid =%s", devid);
1610		err = 0;
1611		resource = get_resource(nameKeyVal, &err);
1612		if (resource == NULL) {
1613			util_handleError(
1614				"SOLARIS_NFSMOUNT::GET_ASSOC_NFSMNTS",
1615				CIM_ERR_FAILED, GET_RESOURCE_FAILURE, NULL,
1616				&err);
1617			free(devid);
1618			return (NULL);
1619		}
1620
1621		cim_logDebug("get_associated_nfs_mntlist",
1622			"isDependent: resource =%s", resource);
1623		/*
1624		 * The devid is unique per file system so we will search for
1625		 * the mount that has the corresponding devid.  Obviously,
1626		 * we only expect to get one file system.
1627		 */
1628		searchOptLen = (strlen(devMntOpt) + strlen(devid) + 1);
1629
1630		searchOpt = (char *)calloc((size_t)searchOptLen,
1631			(size_t)sizeof (char));
1632
1633		if (searchOpt == NULL) {
1634			/*
1635			 * Out of memory
1636			 */
1637			free(devid);
1638			free(resource);
1639			return (NULL);
1640		}
1641
1642		(void) snprintf(searchOpt, (size_t)searchOptLen, "%s%s",
1643			devMntOpt, devid);
1644		cim_logDebug("get_associated_nfs_mntlist",
1645			"isDependent: searchOpt =%s", searchOpt);
1646
1647		free(devid);
1648
1649		mountList = nfs_get_mounts_by_mntopt(searchOpt, B_FALSE, &err);
1650		if (mountList == NULL) {
1651			free(resource);
1652			free(searchOpt);
1653			if (err != 0) {
1654				util_handleError(
1655					"SOLARIS_NFSMOUNT::GET_ASSOC_NFSMNTS",
1656					CIM_ERR_FAILED,
1657					NFS_GET_MNTS_BY_MNTOPT_FAILURE,
1658					NULL, &err);
1659				return (NULL);
1660			}
1661			return (NULL);
1662		}
1663
1664		free(searchOpt);
1665
1666		/*
1667		 * Check that the resource from the pObjectName is the same as
1668		 * the one in the mountList.  If it is not, return null.
1669		 */
1670		if ((strcmp(resource, mountList->nml_resource) != 0)) {
1671			free(resource);
1672			return (NULL);
1673		}
1674		free(resource);
1675	}
1676
1677	return (mountList);
1678} /* get_associated_nfs_mntlist */
1679
1680/*
1681 * Method: get_Dependent
1682 *
1683 * Description: Creates the Dependent object path of the Solaris_NFSMount class
1684 *
1685 * Parameters:
1686 *	- nfs_mntlist_t *nfs_mount - The nfs mount to be used for filling in
1687 *	the properties of the Dependent, Solaris_NFS.
1688 *
1689 * Returns:
1690 *	- A Solaris_NFS CCIMObjectPath* is returned.
1691 *	- Upon error, NULL is returned.
1692 */
1693static CCIMObjectPath *
1694get_Dependent(nfs_mntlist_t *nfs_mount) {
1695	CCIMInstance	*solarisNFSInst;
1696	CCIMObjectPath	*solarisNFSOp;
1697	CCIMException	*ex;
1698	char		*name_val;
1699	char		*devid;
1700	char		*resourceStr = "resource:=";
1701	char		*devidStr = "devid:=";
1702	char		*hostname;
1703	int		err = 0;
1704	int		name_val_len;
1705
1706	solarisNFSInst = cim_createInstance(SOLARIS_NFS);
1707	if (solarisNFSInst == NULL) {
1708		ex = cim_getLastError();
1709		util_handleError("SOLARIS_NFSMOUNT::GET_DEP",
1710			CIM_ERR_FAILED, CREATE_INSTANCE_FAILURE, ex, &err);
1711		return (NULL);
1712	}
1713
1714	/*
1715	 * Create the key properties on the Solaris_NFS instance.
1716	 *
1717	 * The Solaris_Directory keys are as follows:
1718	 * CSCreationClassName = "Solaris_ComputerSystem"
1719	 * CSName = < hostname >
1720	 * CreationClassName = "Solaris_NFS"
1721	 * Name = resource:=< resource > devid:= < devid >
1722	 */
1723	if (add_property_to_instance(CS_CREATION_CLASS, string,
1724		SOLARIS_CS, NULL, cim_true, solarisNFSInst) == cim_false) {
1725
1726		cim_freeInstance(solarisNFSInst);
1727		return ((CCIMObjectPath *)NULL);
1728	}
1729
1730	hostname = sys_get_hostname(&err);
1731	if (hostname == NULL) {
1732		util_handleError("SOLARIS_NFSMOUNT::GET_DEP", CIM_ERR_FAILED,
1733			GET_HOSTNAME_FAILURE, NULL, &err);
1734		cim_freeInstance(solarisNFSInst);
1735		return ((CCIMObjectPath *)NULL);
1736	}
1737
1738	if (add_property_to_instance(CSNAME, string, hostname, NULL, cim_true,
1739		solarisNFSInst) == cim_false) {
1740
1741		free(hostname);
1742		cim_freeInstance(solarisNFSInst);
1743		return ((CCIMObjectPath *)NULL);
1744	}
1745	free(hostname);
1746
1747	if (add_property_to_instance(CREATION_CLASS, string,
1748		SOLARIS_NFS, NULL, cim_true, solarisNFSInst) == cim_false) {
1749
1750		cim_freeInstance(solarisNFSInst);
1751		return ((CCIMObjectPath *)NULL);
1752	}
1753
1754	if (nfs_mount != NULL) {
1755		err = 0;
1756		devid = fs_parse_optlist_for_option(
1757			nfs_mount->nml_mntopts, "dev=", &err);
1758		if (devid == NULL) {
1759			util_handleError("SOLARIS_NFSMOUNT::GET_DEP",
1760				CIM_ERR_FAILED, FS_PARSE_OPTLIST_FAILURE,
1761				NULL, &err);
1762			cim_freeInstance(solarisNFSInst);
1763			return ((CCIMObjectPath *)NULL);
1764		}
1765
1766		name_val_len = strlen(resourceStr) +
1767			strlen(nfs_mount->nml_resource) + strlen(devidStr) +
1768			strlen(devid) + 2;
1769
1770		name_val = (char *)calloc((size_t)name_val_len,
1771			(size_t)(sizeof (char)));
1772		if (name_val == NULL) {
1773			util_handleError("SOLARIS_NFSMOUNT::GET_DEP",
1774				CIM_ERR_LOW_ON_MEMORY, LOW_MEMORY, NULL, NULL);
1775			cim_freeInstance(solarisNFSInst);
1776			return ((CCIMObjectPath *)NULL);
1777		}
1778
1779		(void) snprintf(name_val, (size_t)name_val_len,
1780			"%s%s%s%s%s", resourceStr, nfs_mount->nml_resource, " ",
1781			devidStr, devid);
1782	}
1783
1784	free(devid);
1785
1786	if (add_property_to_instance(NAME, string, name_val, NULL,
1787		cim_true, solarisNFSInst) == cim_false) {
1788
1789		cim_freeInstance(solarisNFSInst);
1790		return ((CCIMObjectPath *)NULL);
1791	}
1792
1793	free(name_val);
1794
1795	solarisNFSOp = cim_createObjectPath(solarisNFSInst);
1796
1797	if (solarisNFSOp == NULL) {
1798		ex = cim_getLastError();
1799		util_handleError("SOLARIS_NFSMOUNT::GET_DEP",
1800			CIM_ERR_FAILED, CREATE_OBJECT_PATH_FAILURE,
1801			ex, &err);
1802		cim_freeInstance(solarisNFSInst);
1803		return (NULL);
1804	}
1805
1806	cim_freeInstance(solarisNFSInst);
1807
1808	return (solarisNFSOp);
1809} /* get_Dependent */
1810
1811/*
1812 * Method: get_devid
1813 *
1814 * Description:
1815 * Parses the Solaris_NFS.Name key property, which is in the
1816 * "resource:=<resource> devid:=<devid>" format, for the devid.
1817 *
1818 * Parameters:
1819 *	- char *keyValue - The string which is in the
1820 *	"resource:=<resource> devid:=<devid>" format to parse the devid from.
1821 *	- int *errp - The error pointer.  This will be set to a non-zero number
1822 *	if an error is encountered.
1823 *
1824 * Returns:
1825 *	- A pointer to a string which is the value of the devid.
1826 *	- NULL if the devid is not found or if an error occurred.  In the case
1827 *	of an error, errp will be set to a non-zero number.
1828 *
1829 * NOTE:
1830 * The caller must free the memory allocated for the return string.
1831 */
1832char *
1833get_devid(char *keyValue, int *errp) {
1834	char	*devidMarker = "devid:=";
1835	char	*devidMarkerStart;
1836	char	*devidStart;
1837	char	*devid;
1838
1839	devidMarkerStart = strstr(keyValue, devidMarker);
1840	if (devidMarkerStart == NULL) {
1841		return (NULL);
1842	}
1843
1844	devidStart = devidMarkerStart + strlen(devidMarker);
1845	devid = strdup(devidStart);
1846	if (devid == NULL) {
1847		*errp = errno;
1848		return (NULL);
1849	}
1850
1851	return (devid);
1852} /* get_devid */
1853
1854/*
1855 * Method: get_resource
1856 *
1857 * Description:
1858 * Parses the Solaris_NFS.Name key property, which is in the
1859 * "resource:=<resource> devid:=<devid>" format, for the resource.
1860 *
1861 * Parameters:
1862 *	- char *keyValue - The string which is in the
1863 *      "resource:=<resource> devid:=<devid>" format to parse the resource from.
1864 *	- int *errp - The error pointer.  This will be set to a non-zero number
1865 *	if an error is encountered.
1866 *
1867 * Returns:
1868 *	- A pointer to a string which is the value of the resource.
1869 *	- NULL if the resource is not for or if an error occurred.  In the case
1870 *	of an error, errp will be set to a non-zero number.
1871 * NOTE:
1872 * The caller must free the memory allocated for the return string.
1873 */
1874static char *
1875get_resource(char *keyValue, int *errp) {
1876	char	*devid;
1877	char	*devidStr = "devid:=";
1878	char	*resource;
1879	char	*resourceStr = "resource:=";
1880	int	totalDevidLen = 0, keyValueLen = 0, resourceLen = 0,
1881		resourceStrLen = 0, i = 0;
1882	int	err = 0;
1883
1884	/*
1885	 * First we need to get the devid string portion of the Solaris_NFS.Name
1886	 * key value in order to figure out how long that portion is.
1887	 */
1888	devid = get_devid(keyValue, &err);
1889	if (devid == NULL) {
1890		*errp = err;
1891		return (NULL);
1892	}
1893
1894	totalDevidLen = strlen(devidStr) + strlen(devid);
1895
1896	keyValueLen = strlen(keyValue);
1897	resourceStrLen = strlen(resourceStr);
1898
1899	/*
1900	 * The length of the space character between the resource and devid
1901	 * is not taken out here for the fact that we will use that space in
1902	 * order to allocate enough space for the null terminating character.
1903	 */
1904	resourceLen = keyValueLen - totalDevidLen - resourceStrLen;
1905	resourceLen = strlen(keyValue) - (strlen(devidStr) + strlen(devid)) -
1906		strlen(resourceStr);
1907
1908	resource = (char *)calloc((size_t)resourceLen, (size_t)sizeof (char));
1909	if (resource == NULL) {
1910		*errp = errno;
1911		return (NULL);
1912	}
1913
1914	for (i = 0; i < (resourceLen - 1); i++) {
1915		resource[i] = keyValue[resourceStrLen+i];
1916	}
1917
1918	/*
1919	 * Make sure to put the null terminating character at the end.
1920	 */
1921	resource[resourceLen-1] = '\0';
1922
1923	free(devid);
1924	return (resource);
1925} /* get_resource */
1926
1927/*
1928 * Method: populate_property_list
1929 *
1930 * Description: Populates all the properties of the passed in mount into a
1931 * property list.
1932 *
1933 * Parameters:
1934 *	- nfs_mntlist_t *nfs_mount - The nfs mount to retrieve the properties
1935 *	from.
1936 *
1937 * Returns:
1938 *	- A pointer to a list of properties that correspond to the properties of
1939 *	nfs_mount.
1940 *	- Upon error, NULL is returned and the error is logged.
1941 */
1942static CCIMPropertyList *
1943populate_property_list(nfs_mntlist_t *nfs_mount) {
1944	CCIMException		*ex;
1945	CCIMPropertyList	*nfsMountPropList;
1946	CCIMObjectPath		*antOP;
1947	CCIMObjectPath		*depOP;
1948	cimchar			**propValues;
1949	int			i = 0;
1950	int			err = 0;
1951
1952	nfsMountPropList = cim_createPropertyList();
1953	if (nfsMountPropList == NULL) {
1954		ex = cim_getLastError();
1955		util_handleError("SOLARIS_NFSMOUNT::POPULATE_PROPLIST",
1956			CIM_ERR_FAILED, CREATE_PROPLIST_FAILURE, ex, &err);
1957		return ((CCIMPropertyList *)NULL);
1958	}
1959
1960	/*
1961	 * Create the CCIMProperties for this instance
1962	 */
1963
1964	/*
1965	 * Antecedent
1966	 */
1967	antOP = get_Antecedent(nfs_mount->nml_mountp);
1968	if (antOP == NULL) {
1969		cim_freePropertyList(nfsMountPropList);
1970		return ((CCIMPropertyList *)NULL);
1971	}
1972	nfsMountPropList = add_property_to_list(nfsMountProps[ANT].name,
1973		nfsMountProps[ANT].type, NULL, antOP, nfsMountProps[ANT].isKey,
1974		nfsMountPropList);
1975
1976	/*
1977	 * Dependent
1978	 */
1979	depOP = get_Dependent(nfs_mount);
1980	if (depOP == NULL) {
1981		cim_freePropertyList(nfsMountPropList);
1982		return ((CCIMPropertyList *)NULL);
1983	}
1984	nfsMountPropList = add_property_to_list(nfsMountProps[DEP].name,
1985		nfsMountProps[DEP].type, NULL, depOP, nfsMountProps[DEP].isKey,
1986		nfsMountPropList);
1987
1988	propValues = calloc((size_t)PROPCOUNT, (size_t)sizeof (cimchar *));
1989	if (propValues == NULL) {
1990		util_handleError("SOLARIS_NFSMOUNT::POPULATE_PROPLIST",
1991			CIM_ERR_LOW_ON_MEMORY, LOW_MEMORY, NULL, &err);
1992		return ((CCIMPropertyList *)NULL);
1993	}
1994
1995	if (populate_property_values(nfs_mount, propValues) == cim_false) {
1996		fileutil_free_string_array(propValues, PROPCOUNT);
1997		cim_freePropertyList(nfsMountPropList);
1998		return ((CCIMPropertyList *)NULL);
1999	}
2000
2001	for (i = 0; i < PROPCOUNT; i++) {
2002		if (i == ANT || i == DEP) {
2003			continue;
2004		}
2005		nfsMountPropList = add_property_to_list(nfsMountProps[i].name,
2006			nfsMountProps[i].type, propValues[i], NULL,
2007			nfsMountProps[i].isKey, nfsMountPropList);
2008		if (nfsMountPropList == NULL) {
2009			fileutil_free_string_array(propValues, PROPCOUNT);
2010			return ((CCIMPropertyList *)NULL);
2011		}
2012	}
2013
2014	fileutil_free_string_array(propValues, PROPCOUNT);
2015	return (nfsMountPropList);
2016} /* populate_property_list */
2017
2018static CIMBool
2019populate_property_values(nfs_mntlist_t *nfs_mount,
2020	cimchar **propValues) {
2021
2022	fs_mntdefaults_t	vfstab_filter;
2023	fs_mntdefaults_t	*vfstab_entry;
2024	boolean_t		readonly;
2025	boolean_t		optHasEquals;
2026	char			*enableQuota, *failoverList, *noSuid,
2027				*posix, *public, *port;
2028	cimchar			propValue[MAXSIZE];
2029	int			defaultValue = 0;
2030	int			err = 0;
2031
2032	/*
2033	 * AttributeCaching
2034	 */
2035	(void) snprintf(propValue, MAXSIZE, "%d", !(nfs_mount->nml_noac));
2036	propValues[ATTRCACHE] = strdup(propValue);
2037	if (propValues[ATTRCACHE] == NULL) {
2038		return (cim_false);
2039	}
2040
2041	/*
2042	 * AttributeCachingForDirectoriesMax
2043	 */
2044	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_acdirmax);
2045	propValues[ATTRCACHEDIRMAX] = strdup(propValue);
2046	if (propValues[ATTRCACHEDIRMAX] == NULL) {
2047		return (cim_false);
2048	}
2049
2050	/*
2051	 * AttributeCachingForDirectoriesMin
2052	 */
2053	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_acdirmin);
2054	propValues[ATTRCACHEDIRMIN] = strdup(propValue);
2055	if (propValues[ATTRCACHEDIRMIN] == NULL) {
2056		return (cim_false);
2057	}
2058
2059	/*
2060	 * AttributeCachingForRegularFilesMax
2061	 */
2062	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_acregmax);
2063	propValues[ATTRCACHEFILESMAX] = strdup(propValue);
2064	if (propValues[ATTRCACHEFILESMAX] == NULL) {
2065		return (cim_false);
2066	}
2067
2068	/*
2069	 * AttributeCachingForRegularFilesMin
2070	 */
2071	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_acregmin);
2072	propValues[ATTRCACHEFILESMIN] = strdup(propValue);
2073	if (propValues[ATTRCACHEFILESMIN] == NULL) {
2074		return (cim_false);
2075	}
2076
2077	/*
2078	 * EnableQuotaChecking
2079	 */
2080	optHasEquals = B_FALSE;
2081	enableQuota = get_property_from_opt_string(nfs_mount->nml_mntopts,
2082		"quota", optHasEquals, defaultValue);
2083	if (enableQuota == NULL) {
2084		return (cim_false);
2085	}
2086	propValues[ENABLEQUOTA] = strdup(enableQuota);
2087	if (propValues[ENABLEQUOTA] == NULL) {
2088		return (cim_false);
2089	}
2090	free(enableQuota);
2091
2092	/*
2093	 * FailoverList
2094	 */
2095	failoverList = cim_encodeStringArray(nfs_mount->nml_failoverlist,
2096		nfs_mount->nml_failovercount);
2097	if (failoverList == NULL) {
2098		cim_logDebug("populate_property_values", "encoding FAILED");
2099		return (cim_false);
2100	}
2101	propValues[FAILOVER] = strdup(failoverList);
2102	if (propValues[FAILOVER] == NULL) {
2103		return (cim_false);
2104	}
2105
2106	/*
2107	 * ForceDirectIO
2108	 */
2109	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_directio);
2110	propValues[FORCEDIRECTIO] = strdup(propValue);
2111	if (propValues[FORCEDIRECTIO] == NULL) {
2112		return (cim_false);
2113	}
2114
2115	/*
2116	 * FsType
2117	 */
2118	propValues[FSTYPE] = strdup(nfs_mount->nml_fstype);
2119	if (propValues[FSTYPE] == NULL) {
2120		return (cim_false);
2121	}
2122
2123	/*
2124	 * GroupId
2125	 */
2126	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_grpid);
2127	propValues[GRPID] = strdup(propValue);
2128	if (propValues[GRPID] == NULL) {
2129		return (cim_false);
2130	}
2131
2132	/*
2133	 * HardMount
2134	 */
2135	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_hard);
2136	propValues[HARDMNT] = strdup(propValue);
2137	if (propValues[HARDMNT] == NULL) {
2138		return (cim_false);
2139	}
2140
2141	/*
2142	 * Interrupt
2143	 */
2144	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_intr);
2145	propValues[INTR] = strdup(propValue);
2146	if (propValues[INTR] == NULL) {
2147		return (cim_false);
2148	}
2149
2150	/*
2151	 * MaxRetransmissionAttempts
2152	 */
2153	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_retrans);
2154	propValues[MAXRETRANSATTEMPTS] = strdup(propValue);
2155	if (propValues[MAXRETRANSATTEMPTS] == NULL) {
2156		return (cim_false);
2157	}
2158
2159	/*
2160	 * MountAtBootEntry - Deprecated
2161	 */
2162	vfstab_filter.resource = nfs_mount->nml_resource;
2163	vfstab_filter.fsckdevice = NULL;
2164	vfstab_filter.mountp = nfs_mount->nml_mountp;
2165	vfstab_filter.fstype = nfs_mount->nml_fstype;
2166	vfstab_filter.fsckpass = NULL;
2167	vfstab_filter.mountatboot = NULL;
2168	vfstab_filter.mntopts = NULL;
2169
2170	err = 0;
2171	/*
2172	 * The space allocated for the value returned by
2173	 * fs_get_filtered_mount_defaults is freed later in this function
2174	 * because it is needed to set the value of the VfstabEntry property.
2175	 */
2176	vfstab_entry = fs_get_filtered_mount_defaults(&vfstab_filter, &err);
2177	if (vfstab_entry == NULL) {
2178		if (err != 0) {
2179			util_handleError("SOLARIS_NFSMOUNT::POPULATE_PROPLIST",
2180				CIM_ERR_FAILED,
2181				FS_GET_FILTERED_MNTDEFAULTS_FAILURE, NULL,
2182				&err);
2183			return (cim_false);
2184		}
2185		(void) snprintf(propValue, (size_t)MAXSIZE, "%d", B_FALSE);
2186	} else {
2187		/*
2188		 * The possible values in the mount at boot field are "yes",
2189		 * "no" and "-".  The "-" character, although it is not likely
2190		 * to be used, will be interpretted as the mount is to not be
2191		 * mounted at boot.  "-" is used when a field does not apply to
2192		 * the resource being mounted.
2193		 */
2194		if (strcasecmp(vfstab_entry->mountatboot, "yes") == 0) {
2195			(void) snprintf(propValue, (size_t)MAXSIZE, "%d",
2196			    B_TRUE);
2197		} else {
2198			(void) snprintf(propValue, (size_t)MAXSIZE, "%d",
2199			    B_FALSE);
2200		}
2201	}
2202	propValues[MNTATBOOTENTRY] = strdup(propValue);
2203	if (propValues[MNTATBOOTENTRY] == NULL) {
2204		return (cim_false);
2205	}
2206
2207	/*
2208	 * MountOptions
2209	 */
2210	propValues[MNTOPTS] = strdup(nfs_mount->nml_mntopts);
2211	if (propValues[MNTOPTS] == NULL) {
2212		return (cim_false);
2213	}
2214
2215	/*
2216	 * MountFailureRetries - This value is only valid upon creation of an
2217	 * instance of Solaris_NFSMount.  This is actually a mount _process_
2218	 * option and not a mount option.
2219	 */
2220
2221	/*
2222	 * NoCloseToOpenConsistency
2223	 */
2224	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_nocto);
2225	propValues[NOCTO] = strdup(propValue);
2226	if (propValues[NOCTO] == NULL) {
2227		return (cim_false);
2228	}
2229
2230	/*
2231	 * NoMnttabEntry - This will always be false for every nfs mount that
2232	 * is shown in the CIM/WBEM interface because there is no way to
2233	 * programatically determine a file system that is mounted if it is not
2234	 * in /etc/mnttab.  If it is not in /etc/mnttab, it is like that for a
2235	 * reason and is also an argument for not showing the existense of
2236	 * those file systems.
2237	 */
2238	(void) snprintf(propValue, (size_t)MAXSIZE, "%d", B_FALSE);
2239	propValues[NOMNTTABENT] = strdup(propValue);
2240	if (propValues[NOMNTTABENT] == NULL) {
2241		return (cim_false);
2242	}
2243
2244	/*
2245	 * NoSuid
2246	 */
2247	optHasEquals = B_FALSE;
2248	noSuid = get_property_from_opt_string(nfs_mount->nml_mntopts,
2249		"nosuid", optHasEquals, defaultValue);
2250	if (noSuid == NULL) {
2251		return (cim_false);
2252	}
2253	propValues[NOSUID] = strdup(noSuid);
2254	if (propValues[NOSUID] == NULL) {
2255		return (cim_false);
2256	}
2257	free(noSuid);
2258
2259	/*
2260	 * Overlay - This is a property which is only valid upon creation of a
2261	 * Solaris_NFSMount instance.  It specifies that the file system to be
2262	 * mounted should be mounted on top of another existing mounted file
2263	 * system.
2264	 */
2265
2266	/*
2267	 * Overlayed
2268	 */
2269	/*
2270	 * We must do some magic here with determining an overlayed file system.
2271	 * We must check for mounts with the same mount point and determine
2272	 * which is further down in the mnttab list to determine the top most
2273	 * file system.  This is all done in the fs_mounts interface.
2274	 */
2275	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_overlayed);
2276	propValues[OVERLAYED] = strdup(propValue);
2277	if (propValues[OVERLAYED] == NULL) {
2278		return (cim_false);
2279	}
2280
2281	/*
2282	 * Posix
2283	 */
2284	optHasEquals = B_FALSE;
2285	posix = get_property_from_opt_string(nfs_mount->nml_mntopts, "posix",
2286		optHasEquals, defaultValue);
2287	if (posix == NULL) {
2288		return (cim_false);
2289	}
2290	propValues[POSIX] = strdup(posix);
2291	if (propValues[POSIX] == NULL) {
2292		return (cim_false);
2293	}
2294	free(posix);
2295
2296	/*
2297	 * Protocol
2298	 */
2299	propValues[PROTO] = strdup(nfs_mount->nml_proto);
2300	if (propValues[PROTO] == NULL) {
2301		return (cim_false);
2302	}
2303
2304	/*
2305	 * Public
2306	 */
2307	optHasEquals = B_FALSE;
2308	public = get_property_from_opt_string(nfs_mount->nml_mntopts,
2309		"public", optHasEquals, defaultValue);
2310	if (public == NULL) {
2311		return (cim_false);
2312	}
2313	propValues[PUBLIC] = strdup(public);
2314	if (propValues[PUBLIC] == NULL) {
2315		return (cim_false);
2316	}
2317	free(public);
2318
2319	/*
2320	 * ReadBufferSize
2321	 */
2322	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_curread);
2323	propValues[READBUFFSIZE] = strdup(propValue);
2324	if (propValues[READBUFFSIZE] == NULL) {
2325		return (cim_false);
2326	}
2327
2328	/*
2329	 * ReadOnly
2330	 */
2331	readonly = fs_is_readonly(nfs_mount->nml_mountp, &err);
2332	if (err != 0) {
2333		return (cim_false);
2334	}
2335	(void) snprintf(propValue, (size_t)MAXSIZE, "%d", readonly);
2336	propValues[READONLY] = strdup(propValue);
2337	if (propValues[READONLY] == NULL) {
2338		return (cim_false);
2339	}
2340
2341	/*
2342	 * ReplicatedResources - Deprecated.
2343	 */
2344	/*
2345	 * This is the same as the FailoverList so we can use the value used
2346	 * to create that property (failoverList).
2347	 */
2348	propValues[REPLRESOURCES] = strdup(failoverList);
2349	if (propValues[REPLRESOURCES] == NULL) {
2350		free(failoverList);
2351		return (cim_false);
2352	}
2353	free(failoverList);
2354
2355	/*
2356	 * RetransmissionTimeout
2357	 */
2358	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_timeo);
2359	propValues[RETRANSTIMEO] = strdup(propValue);
2360	if (propValues[RETRANSTIMEO] == NULL) {
2361		return (cim_false);
2362	}
2363
2364	/*
2365	 * RetryInForeground - This value is only valid upon creation of an
2366	 * instance of Solaris_NFSMount.  This is actually a mount _process_
2367	 * option and not a mount option.
2368	 */
2369
2370	/*
2371	 * SecurityMode
2372	 */
2373	if (nfs_mount->nml_securitymode == NULL) {
2374		cim_logDebug("populate_property_value", "secmode == NULL");
2375	} else {
2376		cim_logDebug("populate_property_value", "secmode =%s",
2377			nfs_mount->nml_securitymode);
2378	}
2379
2380	if (nfs_mount->nml_securitymode != NULL) {
2381		propValues[SECMODE] = strdup(nfs_mount->nml_securitymode);
2382		if (propValues[SECMODE] == NULL) {
2383			return (cim_false);
2384		}
2385	}
2386
2387	/*
2388	 * ServerCommunicationPort
2389	 */
2390	optHasEquals = B_TRUE;
2391	defaultValue = NFS_PORT;
2392	port = get_property_from_opt_string(nfs_mount->nml_mntopts, "port=",
2393		optHasEquals, defaultValue);
2394	if (port == NULL) {
2395		return (cim_false);
2396	}
2397	propValues[SERVERCOMMPORT] = strdup(port);
2398	if (propValues[SERVERCOMMPORT] == NULL) {
2399		return (cim_false);
2400	}
2401	free(port);
2402
2403	/*
2404	 * ServerName
2405	 */
2406	propValues[SERVERNAME] = strdup(nfs_mount->nml_curserver);
2407	if (propValues[SERVERNAME] == NULL) {
2408		return (cim_false);
2409	}
2410
2411	/*
2412	 * ServerPath
2413	 */
2414	propValues[SERVERPATH] = strdup(nfs_mount->nml_curpath);
2415	if (propValues[SERVERPATH] == NULL) {
2416		return (cim_false);
2417	}
2418
2419	/*
2420	 * Version
2421	 */
2422	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_vers);
2423	propValues[VERS] = strdup(propValue);
2424	if (propValues[VERS] == NULL) {
2425		return (cim_false);
2426	}
2427
2428	/*
2429	 * VfstabEntry
2430	 */
2431	/*
2432	 * The vfstab_entry variable is retrieved from the
2433	 * fs_get_filtered_mount_defaults call when populating the
2434	 * MountAtBootEntry property.
2435	 */
2436	if (vfstab_entry == NULL) {
2437		(void) snprintf(propValue, MAXSIZE, "%d", B_FALSE);
2438	} else {
2439		(void) snprintf(propValue, MAXSIZE, "%d", B_TRUE);
2440		fs_free_mntdefaults_list(vfstab_entry);
2441	}
2442	propValues[VFSTABENTRY] = strdup(propValue);
2443	if (propValues[VFSTABENTRY] == NULL) {
2444		return (cim_false);
2445	}
2446
2447	/*
2448	 * WriteBufferSize
2449	 */
2450	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_curwrite);
2451	propValues[WRITEBUFFSIZE] = strdup(propValue);
2452	if (propValues[WRITEBUFFSIZE] == NULL) {
2453		return (cim_false);
2454	}
2455
2456	/*
2457	 * Xattr
2458	 */
2459	(void) snprintf(propValue, MAXSIZE, "%d", nfs_mount->nml_xattr);
2460	propValues[XATTR] = strdup(propValue);
2461	if (propValues[XATTR] == NULL) {
2462		return (cim_false);
2463	}
2464
2465	cim_logDebug("populate_property_values", "returning cim_true");
2466	return (cim_true);
2467} /* populate_property_values */
2468