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 2002 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 <errno.h>
30#include <sys/wait.h>
31#include "cimKeys.h"
32#include "util.h"
33#include "Solaris_DiskPartition.h"
34#include "partition_descriptors.h"
35#include "methods.h"
36#include "providerNames.h"
37#include "messageStrings.h"
38
39#define	DISK_GETINSTANCE	"DISK_PARTITION,GET_INSTANCE"
40#define	DISK_ENUMINSTANCES	"DISK_PARTITION,ENUM_INSTANCES"
41#define	DISK_ENUMINSTANCENAMES	"DISK_PARTITION,ENUM_INSTANCENAMES"
42#define	DISK_CREATEINSTANCE	"DISK_PARTITION,CREATE_INSTANCE"
43#define	DISK_DELETEINSTANCE	"DISK_PARTITION,DELETE_INSTANCE"
44#define	DISK_SETINSTANCE	"DISK_PARTITION,SET_INSTANCE"
45#define	DISK_GETPROPERTY	"DISK_PARTITION,GET_PROPERTY"
46#define	DISK_SETPROPERTY	"DISK_PARTITION,SET_PROPERTY"
47#define	DISK_INVOKEMETHOD	"DISK_PARTITION,INVOKE_METHOD"
48#define	DISK_EXECQUERY		"DISK_PARTITION,EXEC_QUERY"
49
50/*
51 * Name: cp_getInstance_Solaris_DiskPartition
52 *
53 * Description: Returns an instance which matches the passed in object path
54 * if found.
55 *
56 * Parameters:
57 *      pOP - An CCIMObjectPath * which contains the information on
58 *      the class for which to find the instance.
59 * Returns:
60 *      CCIMInstance * if matched instance is found. Otherwise, NULL.
61 */
62
63/* ARGSUSED */
64CCIMInstance *
65cp_getInstance_Solaris_DiskPartition(CCIMObjectPath *pOP)
66{
67
68	CCIMInstance*		inst = NULL;
69	CCIMPropertyList*	pCurPropList;
70	CCIMException*		ex;
71	dm_descriptor_t		dp_descriptor;
72	char			*name;
73	int			error;
74
75	if (pOP == NULL ||
76	    pOP->mKeyProperties == NULL) {
77	    util_handleError(DISK_GETINSTANCE, CIM_ERR_INVALID_PARAMETER, NULL,
78		NULL, &error);
79	    return ((CCIMInstance *)NULL);
80	}
81
82	pCurPropList = pOP->mKeyProperties;
83	name = (cimchar *)util_getKeyValue(pCurPropList, string, DEVICEID,
84	    &error);
85
86	if (error != 0 || name == NULL) {
87	    util_handleError(DISK_GETINSTANCE, CIM_ERR_INVALID_PARAMETER, NULL,
88		NULL, &error);
89	    return ((CCIMInstance*)NULL);
90	}
91
92	dp_descriptor = dm_get_descriptor_by_name(DM_SLICE, name, &error);
93
94	/*
95	 * If not found, could be an fdisk partition.
96	 */
97
98	if (error == ENODEV) {
99	    dp_descriptor = dm_get_descriptor_by_name(DM_PARTITION, name,
100		&error);
101	    if (error == ENODEV) {
102		return ((CCIMInstance *)NULL);
103	    } else if (error != 0) {
104		util_handleError(DISK_GETINSTANCE, CIM_ERR_FAILED,
105		    DM_GET_DESC_BYNAME_FAILURE, NULL, &error);
106		return ((CCIMInstance*)NULL);
107	    }
108	} else if (error != 0) {
109	    util_handleError(DISK_GETINSTANCE, CIM_ERR_FAILED,
110		DM_GET_DESC_BYNAME_FAILURE, NULL, &error);
111	    return ((CCIMInstance*)NULL);
112	}
113
114	/* Turn this descriptor in to a disk partition instance */
115
116	inst = partition_descriptor_toCCIMInstance(
117	    hostName, dp_descriptor, DISK_PARTITION, &error);
118	dm_free_descriptor(dp_descriptor);
119
120	if (error != 0) {
121	    ex = cim_getLastError();
122	    util_handleError(DISK_GETINSTANCE, CIM_ERR_FAILED,
123		PART_DESC_TO_INSTANCE_FAILURE, ex, &error);
124	    return ((CCIMInstance*)NULL);
125	}
126
127	return (inst);
128}
129
130/*
131 * Name: cp_enumInstances_Solaris_DiskPartition
132 *
133 * Description: Returns a list of instances if found.
134 *
135 * Parameters:
136 *      pOP - An CCIMObjectPath * which contains the information on
137 *      the class for which to find the instance.
138 * Returns:
139 *      CCIMInstance * if matched instance is found. Otherwise, NULL.
140 */
141
142/* ARGSUSED */
143CCIMInstanceList*
144cp_enumInstances_Solaris_DiskPartition(CCIMObjectPath* pOP)
145{
146
147	CCIMInstanceList*	instList = NULL;
148	dm_descriptor_t		*dsolpart_descriptorp = NULL;
149	dm_descriptor_t		*dfdiskpart_descriptorp = NULL;
150	int			error;
151	int			filter[2];
152
153	filter[0] = DM_MT_FIXED;
154	filter[1] = DM_FILTER_END;
155
156	dsolpart_descriptorp = dm_get_descriptors(DM_SLICE, filter, &error);
157
158	if (error != 0) {
159	    util_handleError(DISK_ENUMINSTANCES, CIM_ERR_FAILED,
160		DM_GET_DESCRIPTORS, NULL, &error);
161	    return ((CCIMInstanceList *)NULL);
162	}
163
164	dfdiskpart_descriptorp =
165	    dm_get_descriptors(DM_PARTITION, filter, &error);
166
167	if (error != 0) {
168	    if (dsolpart_descriptorp != NULL) {
169		dm_free_descriptors(dsolpart_descriptorp);
170	    }
171	    util_handleError(DISK_ENUMINSTANCES, CIM_ERR_FAILED,
172		DM_GET_DESCRIPTORS, NULL, &error);
173	    return ((CCIMInstanceList *)NULL);
174	}
175
176
177	/*
178	 * If both descriptor lists are null, then there is nothing to return.
179	 * otherwise, call the conversion function and return what is found.
180	 */
181
182	if (dsolpart_descriptorp == NULL && dfdiskpart_descriptorp == NULL) {
183	    return ((CCIMInstanceList *)NULL);
184	}
185
186	/* Convert the slice descriptors to a CCIMInstanceList */
187
188	instList = partition_descriptors_toCCIMInstanceList(DISK_PARTITION,
189	    dsolpart_descriptorp, dfdiskpart_descriptorp, &error);
190
191	if (dsolpart_descriptorp != NULL) {
192	    dm_free_descriptors(dsolpart_descriptorp);
193	}
194
195	if (dfdiskpart_descriptorp != NULL) {
196	    dm_free_descriptors(dfdiskpart_descriptorp);
197	}
198
199	return (instList);
200}
201
202/*
203 * Name: cp_enumInstanceNames_Solaris_DiskPartition
204 *
205 * Description: Returns a list of instances if found.
206 *
207 * Parameters:
208 *      pOP - An CCIMObjectPath * which contains the information on
209 *      the class for which to find the instance.
210 * Returns:
211 *      CCIMObjectPathList * if found. Otherwise, NULL.
212 */
213
214/* ARGSUSED */
215CCIMObjectPathList *
216cp_enumInstanceNames_Solaris_DiskPartition(CCIMObjectPath *pOP) {
217
218	CCIMInstanceList	*instList = NULL;
219	CCIMObjectPathList	*objList = NULL;
220	int			error = 0;
221
222	if (pOP == NULL) {
223	    util_handleError(DISK_ENUMINSTANCENAMES, CIM_ERR_INVALID_PARAMETER,
224		NULL, NULL, &error);
225	    return ((CCIMObjectPathList *)NULL);
226	}
227
228	/*
229	 * Call to enumInstances and then convert instance list to a list
230	 * of object list.
231	 */
232
233	instList = cp_enumInstances_Solaris_DiskPartition(pOP);
234	if (instList != NULL) {
235	    objList = cim_createObjectPathList(instList);
236	    cim_freeInstanceList(instList);
237	}
238
239	return (objList);
240}
241
242/*
243 * Creating an instance of a Solaris_DiskPartition is not supported.
244 */
245
246/* ARGSUSED */
247CCIMObjectPath*
248cp_createInstance_Solaris_DiskPartition(CCIMObjectPath* pOP,
249    CCIMInstance* pInst)
250{
251	int	error;
252
253	util_handleError(DISK_CREATEINSTANCE, CIM_ERR_NOT_SUPPORTED,
254	    NULL, NULL, &error);
255	return ((CCIMObjectPath*)NULL);
256}
257
258/*
259 * Deleting an instance of a Solaris_DiskPartition is not supported.
260 */
261
262/* ARGSUSED */
263CIMBool
264cp_deleteInstance_Solaris_DiskPartition(CCIMObjectPath* pInst)
265{
266	int	error;
267
268	util_handleError(DISK_DELETEINSTANCE, CIM_ERR_NOT_SUPPORTED,
269	    NULL, NULL, &error);
270	return (cim_false);
271}
272
273/*
274 * Name: cp_getProperty_Solaris_DiskPartition
275 *
276 * Description: Returns the property requested, if found.
277 *
278 * Parameters:
279 *	pOP - An CCIMObjectPath * which contains the information on
280 *	the class for which to find the instances.
281 * Returns:
282 *	CCIMProperty * if found.
283 */
284
285/* ARGSUSED */
286CCIMProperty	*
287cp_getProperty_Solaris_DiskPartition(CCIMObjectPath *pOP,
288    char *pPropName)
289{
290
291	CCIMProperty	*prop = NULL;
292	CCIMInstance	*inst = NULL;
293	int		error = 0;
294
295	if (pOP == NULL) {
296	    util_handleError(DISK_GETPROPERTY, CIM_ERR_INVALID_PARAMETER, NULL,
297		NULL, &error);
298	    return ((CCIMProperty *)NULL);
299	}
300
301	inst = cp_getInstance_Solaris_DiskPartition(pOP);
302	if (inst == NULL) {
303	    return ((CCIMProperty *)NULL);
304	}
305
306	prop = cim_getProperty(inst, pPropName);
307	cim_freeInstance(inst);
308	return (prop);
309}
310/*
311 * Deleting an instance of a Solaris_DiskPartition is not supported.
312 */
313
314/* ARGSUSED */
315CIMBool
316cp_setInstance_Solaris_DiskPartition(CCIMObjectPath* pOP, CCIMInstance* pInst)
317{
318	int		error;
319
320	util_handleError(DISK_DELETEINSTANCE, CIM_ERR_NOT_SUPPORTED,
321	    NULL, NULL, &error);
322	return (cim_false);
323}
324
325/*
326 * Setting a property on an instance of a Solaris_DiskPartition is not
327 * supported.
328 */
329
330/* ARGSUSED */
331CIMBool
332cp_setProperty_Solaris_DiskPartition(CCIMObjectPath* pOP, CCIMProperty* pProp)
333{
334	int error;
335
336	util_handleError(DISK_SETPROPERTY, CIM_ERR_NOT_SUPPORTED,
337	    NULL, NULL, &error);
338	return (cim_false);
339}
340
341/* invokeMethod function dispatches to the various method implementations */
342
343/* ARGSUSED */
344CCIMProperty*
345cp_invokeMethod_Solaris_DiskPartition(CCIMObjectPath* op, cimchar* methodName,
346    CCIMPropertyList* inParams, CCIMPropertyList* outParams)
347{
348	CCIMProperty	*retVal = (CCIMProperty*)NULL;
349	int		error = 0;
350
351
352	/* dispatch code for various methods */
353	if (strcasecmp("CreatePartitions", methodName) == 0) {
354	    retVal = create_partitions(inParams, op);
355	    return (retVal);
356	} else if (strcasecmp("CreateFileSystem", methodName) == 0) {
357	    retVal = create_filesystem(op);
358	    return (retVal);
359	}
360
361	/*
362	 * We fell through the dispatch logic.  There is no function
363	 * that matches 'methodName'.
364	 */
365
366	util_handleError(DISK_INVOKEMETHOD, CIM_ERR_FAILED,
367	    NO_SUCH_METHOD, NULL, &error);
368	return ((CCIMProperty*)NULL);
369}
370
371/*
372 * Name: cp_execQuery_Solaris_DiskPartition
373 *
374 * Description:
375 * Returns an instance list which matches the query if any are found.
376 *
377 * Parameters:
378 *      CCIMObjectPath *op - An CCIMObjectPath * which contains the
379 *      information on the class for which to find the instances.
380 *
381 *      selectList - Not used
382 *      nonJoinExp - Not used
383 *
384 * Returns:
385 *      CCIMInstance * if matched instance is found. Otherwise, NULL.
386 */
387
388/*
389 * Currently, there is no WQL parser for the C providers. As a result,
390 * what is returned to the CIMOM is a list of instances with
391 * a NULL value at the beginning of the list. This NULL value indicates
392 * to the CIMOM that it must do the filtering for the client.
393 */
394
395/* ARGSUSED */
396CCIMInstanceList*
397cp_execQuery_Solaris_DiskPartition(CCIMObjectPath *op, cimchar *selectList,
398    cimchar *nonJoinExp, cimchar *queryExp, int queryType)
399{
400	CCIMInstanceList	*instList = NULL;
401	CCIMInstanceList	*result;
402	CCIMInstance		*emptyInst;
403	CCIMException		*ex;
404	int			error;
405
406	if (op == NULL) {
407	    util_handleError(DISK_EXECQUERY, CIM_ERR_INVALID_PARAMETER, NULL,
408		NULL, &error);
409	    return ((CCIMInstanceList *)NULL);
410	}
411
412	/* Enumerate all instances */
413	instList = cp_enumInstances_Solaris_DiskPartition(op);
414
415	if (instList == NULL) {
416	    return ((CCIMInstanceList *)NULL);
417	}
418
419	/*
420	 * Create a null instance and add it to the beginning
421	 * of the list to indicate to the CIMOM that no filtering
422	 * was done.
423	 */
424
425	emptyInst = cim_createInstance("");
426	if (emptyInst == NULL) {
427	    ex = cim_getLastError();
428	    util_handleError(DISK_EXECQUERY, CIM_ERR_FAILED,
429		CREATE_INSTANCE_FAILURE, ex, &error);
430	    cim_freeInstanceList(instList);
431	    return ((CCIMInstanceList *)NULL);
432	}
433
434	result = cim_createInstanceList();
435	if (result == NULL) {
436	    ex = cim_getLastError();
437	    util_handleError(DISK_EXECQUERY, CIM_ERR_FAILED,
438		CREATE_INSTANCE_LIST_FAILURE, ex, &error);
439	    cim_freeInstance(emptyInst);
440	    cim_freeInstanceList(instList);
441	    return ((CCIMInstanceList *)NULL);
442	}
443
444	result = cim_addInstance(result, emptyInst);
445	if (result == NULL) {
446	    ex = cim_getLastError();
447	    util_handleError(DISK_EXECQUERY, CIM_ERR_FAILED,
448		ADD_INSTANCE_FAILURE, ex, &error);
449	    cim_freeInstance(emptyInst);
450	    cim_freeInstanceList(instList);
451	    return ((CCIMInstanceList *)NULL);
452	}
453	/*
454	 * Since copying the original list to the new list will
455	 * leave no way to free the original list, manually
456	 * concatenate the original list to the new one.
457	 */
458
459	result->mNext = instList;
460	return (result);
461}
462