[ipoib,core] Improve support for partitioning.
[mirror/winof/.git] / tools / part_man / user / part_man.c
1 \r
2 #include "stdio.h"\r
3 #include "string.h"\r
4 #include "stdlib.h"\r
5 #include <windows.h>\r
6 #include <iba/ib_types.h>\r
7 #include <iba/ib_al.h>\r
8 #include "al_dev.h"\r
9 \r
10 \r
11 typedef enum\r
12 {\r
13         pkey_show = 0,\r
14         pkey_add,\r
15         pkey_rem\r
16 }Pkey_action;\r
17 \r
18 /* common query parameters */\r
19 typedef struct _REQUEST_IN\r
20 {\r
21         union\r
22         {\r
23                 struct\r
24                 {\r
25                         net64_t                    port_guid;\r
26                         unsigned short     pkey_num;\r
27                         unsigned __int16   pkeys[MAX_NUM_PKEY];\r
28                         Pkey_action                action;\r
29                 }guid_pkey;\r
30                 }u;\r
31 }REQUEST_IN;\r
32 \r
33 #define DEFAULT_BUFER_SIZE      1024\r
34 static const char IBBUS_SERV_KEY[] = {"SYSTEM\\CurrentControlSet\\Services\\ibbus\\Parameters"};\r
35 \r
36 void show_help()\r
37 {\r
38         printf("Usage : part_man.exe <show|add|rem> <port_guid> <pkey1, pkey2, ...>\n");\r
39 }\r
40 \r
41 /********************************************************************\r
42 * name  :       reg_ibbus_pkey_show\r
43 *                       read registry pkey and optionally prints it\r
44 * input :       show - whether to print\r
45 * output:       partKey - contains read pkeys, reg_handle\r
46 * return:   number of characters read\r
47 ********************************************************************/\r
48 static int reg_ibbus_pkey_show(IN BOOLEAN show,OUT char *partKey, OUT HKEY *reg_handle)\r
49 {\r
50         LONG   ret;\r
51         int retval;\r
52         DWORD  read_length = DEFAULT_BUFER_SIZE;\r
53 \r
54         ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,IBBUS_SERV_KEY,0,KEY_SET_VALUE | KEY_QUERY_VALUE ,reg_handle);\r
55         if (ERROR_SUCCESS != ret)\r
56         {\r
57                 printf("reg_ibbus_pkey_show error = %d\n",GetLastError());\r
58                 return 0;\r
59         }       \r
60 \r
61         do\r
62         {\r
63                 ret = RegQueryValueEx(*reg_handle,"PartitionKey",NULL,NULL,(LPBYTE)partKey,&read_length);\r
64                 if (ERROR_MORE_DATA == ret)\r
65                 {\r
66                         printf("reg_ibbus_pkey_show : more buffer space required\n");\r
67                         retval = 0;\r
68                         break;\r
69                 }\r
70 \r
71                 if (ERROR_SUCCESS != ret)\r
72                 {\r
73                         printf("RegQueryValueEx : Error %d\n",ret);\r
74                         retval = 0;\r
75                         break;\r
76                 }\r
77                 retval = (int)read_length;\r
78                 if(retval > 4)\r
79                 {\r
80                         if(show)\r
81                                 printf("Existing Pkey(s): %s\n",partKey);\r
82                 }\r
83                 else\r
84                         retval = 0;\r
85         }\r
86         while(FALSE);\r
87         return retval;\r
88 }\r
89 \r
90 static int reg_ibbus_print_pkey()\r
91 {\r
92         int result;\r
93         char pkeyBuf[DEFAULT_BUFER_SIZE];\r
94         HKEY hreg = NULL;\r
95 \r
96         result = reg_ibbus_pkey_show(TRUE,(char*)pkeyBuf,&hreg);\r
97         if(hreg)\r
98                 RegCloseKey( hreg );\r
99 \r
100         if (result < 4)\r
101         {\r
102                 printf("No configured pkey found\n");\r
103                 return 1;\r
104         }\r
105         return 0;\r
106 }\r
107 \r
108 static int reg_ibbus_pkey_add(const uint16_t *pkeys, uint16_t pkey_num,OUT pkey_array_t *pkey, OUT char **final_reg_string, OUT DWORD *reg_length)\r
109 {\r
110         static char partKey[DEFAULT_BUFER_SIZE];\r
111         char tmp[20];\r
112         char *guid_string, *p;\r
113         HKEY reg_handle;\r
114         LONG   ret;\r
115         char *tmpbuff = NULL;\r
116         int cnt;\r
117         int retval = 0;\r
118         uint16_t i = 0;\r
119         DWORD  read_length;\r
120 \r
121         *final_reg_string = NULL;\r
122         read_length = reg_ibbus_pkey_show(FALSE,(char*)partKey,&reg_handle);\r
123         p = NULL;\r
124         guid_string = NULL;\r
125         if (read_length < 4)\r
126         {\r
127                 /* empty string read, simply write to registry */\r
128                 cnt = sprintf(partKey,"0x%I64X:",pkey->port_guid);\r
129         }\r
130         else\r
131         {\r
132                 /* update the existed registry list */\r
133                 sprintf(tmp,"0x%I64X",pkey->port_guid);\r
134                 guid_string = strstr(partKey,tmp);\r
135                 if(guid_string)\r
136                 {\r
137                         p = strstr(guid_string,";");\r
138                         tmpbuff = (char*)malloc(strlen(p) + 1);\r
139                         if(!tmpbuff)\r
140                         {\r
141                                 printf("Failed memory allocation\n");\r
142                                 return 1;\r
143                         }\r
144                         /* save the rest of the string */\r
145                         strcpy(tmpbuff,p);\r
146                         cnt = (int)(p - partKey);\r
147                 }\r
148                 else\r
149                 {\r
150                         cnt = strlen(partKey) + sprintf(partKey + strlen(partKey),"%s:",tmp);\r
151                 }\r
152         }       \r
153 \r
154         for (i = 0 ;i < pkey_num; i++)\r
155         {\r
156                 char *same_pkey;\r
157                 sprintf(tmp,"0x%04X",pkeys[i]);\r
158                 if ( guid_string )\r
159                 {\r
160                         same_pkey = strstr(guid_string,tmp);\r
161                         if( same_pkey && (same_pkey < p) )\r
162                                 continue;\r
163                 }\r
164                 pkey->pkey_array[pkey->pkey_num] = pkeys[i];\r
165                 pkey->pkey_num++;\r
166                 if( (i == 0) && (!guid_string))\r
167                         cnt += sprintf(partKey + cnt,"0x%04X",pkeys[i]);\r
168                 else\r
169                         cnt += sprintf(partKey + cnt,",0x%04X",pkeys[i]);\r
170         }\r
171         if(tmpbuff)\r
172         {\r
173                 cnt += sprintf(partKey + cnt,"%s",tmpbuff);\r
174                 free(tmpbuff);\r
175         }\r
176         else\r
177                 cnt += sprintf(partKey + cnt,";\0");\r
178 \r
179         if(pkey->pkey_num)\r
180         {                       \r
181                         *final_reg_string = partKey;\r
182                         *reg_length = (DWORD)cnt;\r
183         }\r
184         else\r
185         {\r
186                 printf("No pkey to add\n");\r
187                 retval = 1;\r
188         }\r
189         RegCloseKey( reg_handle );\r
190         return retval;\r
191 }\r
192 \r
193 static int reg_ibbus_pkey_rem(const unsigned __int16 *pkeys, unsigned short pkey_num,OUT pkey_array_t *pkey)\r
194 {\r
195         static char partKey[DEFAULT_BUFER_SIZE];\r
196         static char newKey[DEFAULT_BUFER_SIZE] = {'\0'};\r
197 \r
198         HKEY reg_handle;\r
199         LONG   ret;\r
200         DWORD  read_length;\r
201         int converted,cnt;\r
202         unsigned __int16 cur_pkey;\r
203         int retval = 0;\r
204         unsigned short i = 0;\r
205         char pkey_sep[] = ",";\r
206         char *pfrom, *pto;\r
207         char *guid_string;\r
208         char tmp[20];\r
209         char *token;\r
210         char *pafter = NULL;\r
211         boolean_t found2remove;\r
212         boolean_t pkey_not_written = TRUE;\r
213 \r
214         read_length = reg_ibbus_pkey_show(FALSE,(char*)partKey,&reg_handle);\r
215         do\r
216         {\r
217                 if (read_length < 4)\r
218                 {\r
219                         /* empty string read, nothing to delete */\r
220                         printf("No pkey configured - nothing to remove\n");\r
221                         retval = 1;\r
222                         break;\r
223                 }\r
224 \r
225                 sprintf(tmp,"0x%I64X\0",pkey->port_guid);\r
226                 guid_string = strstr(partKey,tmp);\r
227                 if (! guid_string)\r
228                 {\r
229                         printf("No guid configured - nothing to remove\n");\r
230                         retval = 1;\r
231                         break;\r
232                 }\r
233                 pfrom = strstr(guid_string,":");\r
234                 pto   = strstr(guid_string,";");\r
235                 if ( (!pfrom) || (!pto))\r
236                 {\r
237                         printf("Error configuration\n");\r
238                         retval = 1;\r
239                         break;\r
240                 }\r
241 \r
242                 pfrom++;\r
243                 pafter  = (char*)malloc(strlen(pto) + 1);\r
244 \r
245                 if(!pafter)\r
246                 {\r
247                         printf("Allocation failed\n");\r
248                         retval = 1;\r
249                         break;\r
250                 }\r
251                 _snprintf(newKey,(int)(pfrom - partKey),"%s",partKey);\r
252                 cnt = (int)(pfrom - partKey);\r
253                 strcpy(pafter,pto);\r
254                 pto[0] = '\0';\r
255                 strcpy(partKey,pfrom);\r
256                 token = strtok(partKey,pkey_sep);\r
257                 while(token)\r
258                 {\r
259                         found2remove = FALSE;\r
260                         converted = sscanf(token,"0x%X",&cur_pkey);\r
261                         if(!converted || (converted == EOF))\r
262                         {\r
263                                 printf("invalid registry format\n");\r
264                                 retval = 1;\r
265                                 break;\r
266                         }\r
267 \r
268                         for (i = 0; i < pkey_num; i++)\r
269                         {\r
270                                 found2remove = (boolean_t)(cur_pkey == pkeys[i]);\r
271                                 if(found2remove)\r
272                                 {\r
273                                         pkey->pkey_array[pkey->pkey_num] = pkeys[i];\r
274                                         break;\r
275                                 }\r
276                         }\r
277                         \r
278                         if(found2remove)\r
279                         {\r
280                                 pkey->pkey_num++;\r
281                         }\r
282                         else\r
283                         {\r
284                                 if(pkey_not_written)\r
285                                 {\r
286                                         cnt += sprintf(newKey + cnt,"0x%04X",cur_pkey);\r
287                                         pkey_not_written = FALSE;\r
288                                 }\r
289                                 else\r
290                                         cnt += sprintf(newKey + cnt,",0x%04X",cur_pkey);\r
291                         }\r
292                         token = strtok(NULL,pkey_sep);\r
293                 }\r
294 \r
295                 if(! pkey->pkey_num)\r
296                 {\r
297                         /* nothing to delete */\r
298                         printf("No pkey found to remove\n");\r
299                         retval = 1;\r
300                         break;\r
301                 }\r
302 \r
303                 if(pkey_not_written)\r
304                         cnt -= (2 + strlen(tmp));\r
305                 \r
306                 strcpy(newKey + cnt,pafter);\r
307                 ret = RegSetValueEx(reg_handle,"PartitionKey",0,REG_SZ,(BYTE*)newKey, (DWORD)strlen(newKey));\r
308                 if (ERROR_SUCCESS != ret)\r
309                 {\r
310                         printf("reg_ibbus_pkey_add RegSetValueEx error = %d\n",GetLastError());\r
311                         retval = 1;\r
312                         break;\r
313                 }\r
314         }\r
315         while(FALSE);\r
316         if(pafter)\r
317                 free(pafter);\r
318 \r
319         RegCloseKey( reg_handle );\r
320         return retval;\r
321 }\r
322 \r
323 static int send_pdo_req(pkey_array_t *pkeys,DWORD iocode)\r
324 {\r
325         HANDLE hKernelLib;\r
326         DWORD           bytesReturned;\r
327 \r
328         hKernelLib =\r
329                 CreateFile(\r
330                 "\\\\.\\ibal",\r
331                 GENERIC_READ | GENERIC_WRITE,\r
332                 FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode none\r
333                 NULL,                               // no security\r
334                 OPEN_EXISTING,\r
335                 FILE_ATTRIBUTE_NORMAL,\r
336                 NULL                                // no template\r
337                 );\r
338 \r
339         if (hKernelLib == INVALID_HANDLE_VALUE)\r
340         {\r
341                 printf("failed to open the kernel device : error = %d\n",GetLastError());\r
342                 return 1;\r
343         }\r
344 \r
345         if (! DeviceIoControl(hKernelLib,\r
346                                                   iocode,\r
347                                                   pkeys,sizeof(pkey_array_t),\r
348                                                   NULL,0,\r
349                                                   &bytesReturned,\r
350                                                   NULL))\r
351         {\r
352                 DWORD err = GetLastError();\r
353                 if (err == 1168)\r
354                         printf("No matched port guid (0x%I64X) found\n",pkeys->port_guid);\r
355                 else if (err == 1117)\r
356                         printf("operation failed - internal driver error\n");\r
357                 else if(err == 87)\r
358                         printf("operation failed - invalid input to driver\n");\r
359                 else\r
360                         printf("operation failed with error %d\n",err);\r
361 \r
362                 CloseHandle(hKernelLib);\r
363                 return 1;\r
364         }\r
365         CloseHandle(hKernelLib);\r
366         return 0;\r
367 }\r
368 \r
369 \r
370 boolean_t reg_pkey_operation(const REQUEST_IN *input)\r
371 {\r
372         pkey_array_t pkeys;\r
373         HKEY reg_handle;\r
374         char *p_reg_string;\r
375         DWORD reg_length = 0;\r
376         int result;\r
377         int i;\r
378         LONG   ret;\r
379         if(!input)\r
380         {\r
381                 printf("create_ipoib_pdo : invalid input parameter\n");\r
382                 return FALSE;\r
383         }\r
384 \r
385         RtlZeroMemory(&pkeys,sizeof(pkeys));\r
386         pkeys.port_guid = input->u.guid_pkey.port_guid;\r
387 \r
388         if(input->u.guid_pkey.action == pkey_add)\r
389                 result = reg_ibbus_pkey_add((unsigned __int16*)input->u.guid_pkey.pkeys, input->u.guid_pkey.pkey_num, &pkeys,&p_reg_string,&reg_length);\r
390         else if(input->u.guid_pkey.action == pkey_rem)\r
391                 result = reg_ibbus_pkey_rem((unsigned __int16*)input->u.guid_pkey.pkeys, input->u.guid_pkey.pkey_num, &pkeys);\r
392         else if(input->u.guid_pkey.action == pkey_show)\r
393                 result =  reg_ibbus_print_pkey();\r
394         else\r
395                 printf("Invalid command to part_man.exe\n");\r
396 \r
397         if( 0 != result)\r
398                 return FALSE;\r
399 \r
400         if(pkeys.pkey_num)\r
401         {\r
402                 if(input->u.guid_pkey.action == pkey_add)\r
403                 {\r
404                         if( 0 == send_pdo_req(&pkeys,UAL_REQ_CREATE_PDO))\r
405                         {\r
406                                 ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,IBBUS_SERV_KEY,0,KEY_SET_VALUE | KEY_QUERY_VALUE ,&reg_handle);\r
407 \r
408                                 ret = RegSetValueEx(reg_handle,"PartitionKey",0,REG_SZ,(BYTE*)p_reg_string,reg_length);\r
409                                 RegCloseKey( reg_handle );\r
410                                 if (ERROR_SUCCESS == ret)\r
411                                 {\r
412                                         return TRUE;\r
413                                 }\r
414                                 else\r
415                                 {\r
416                                         printf("reg_ibbus_pkey_add RegSetValueEx error = %d\n",GetLastError());\r
417                                 }\r
418                         }\r
419                 }\r
420                 else if(input->u.guid_pkey.action == pkey_rem)\r
421                 {\r
422                         return (boolean_t)( 0 == send_pdo_req(&pkeys,UAL_REQ_REMOVE_PDO));\r
423                 }\r
424         }\r
425         return FALSE;\r
426 }\r
427 \r
428 int prepare_reg_pkey_input(OUT REQUEST_IN *input,char* cmd[],int num)\r
429 {\r
430         int i;\r
431         input->u.guid_pkey.pkey_num = 0;\r
432 \r
433         if(strstr(cmd[1],"add"))\r
434                 input->u.guid_pkey.action = pkey_add;\r
435         else if(strstr(cmd[1],"rem"))\r
436                 input->u.guid_pkey.action = pkey_rem;\r
437         else if(strstr(cmd[1],"show"))\r
438         {\r
439                 input->u.guid_pkey.action = pkey_show;\r
440                 return 1;\r
441         }\r
442         else\r
443         {\r
444                 printf("invalid command %s\n",cmd[1]);\r
445                 return 0;\r
446         }\r
447 \r
448         if(num < 4)\r
449         {\r
450                 printf("invalid command %s\n",cmd[1]);\r
451                 return 0;\r
452         }\r
453 \r
454     /* vstat output format 0008:f104:0397:7ccc \r
455            For port guid add 1 for each port \r
456          */\r
457         if (strstr(cmd[2],":"))\r
458         {\r
459                 int i;\r
460                 unsigned short *guid_vstat;\r
461                 guid_vstat = (unsigned short*)&input->u.guid_pkey.port_guid;\r
462                 sscanf(cmd[2],"%x:%x:%x:%x",&guid_vstat[0],&guid_vstat[1],&guid_vstat[2],&guid_vstat[3]);\r
463                 for( i = 0; i < 4; i++)\r
464                         guid_vstat[i] = (guid_vstat[i] << 8) | (guid_vstat[i] >> 8);\r
465         }\r
466         else\r
467         {\r
468                 printf("port guid %s - illegal string format\n",cmd[2]);\r
469                 return 0;\r
470         }\r
471         \r
472         for( i = 3; i < num; i++)\r
473         {\r
474                 if((strstr(cmd[i],"ffff")) || (strstr(cmd[i],"FFFF")))\r
475                         continue;\r
476                 if (strstr(cmd[i],"0x") || strstr(cmd[i],"0X"))\r
477                         sscanf(cmd[i],"0x%x",&input->u.guid_pkey.pkeys[input->u.guid_pkey.pkey_num]);\r
478                 else\r
479                         sscanf(cmd[i],"%x",&input->u.guid_pkey.pkeys[input->u.guid_pkey.pkey_num]);\r
480                 input->u.guid_pkey.pkey_num++;\r
481         }\r
482         return 1;\r
483 }\r
484 \r
485 void partition_operation(char* cmd[],int num)\r
486 {\r
487         REQUEST_IN input;\r
488 \r
489         if (! prepare_reg_pkey_input(&input, cmd, num))\r
490                 return;\r
491 \r
492         if(! reg_pkey_operation(&input))\r
493                 printf("Pkey operation failed\n");      \r
494         else\r
495                 printf("Done...\n");\r
496 }\r
497 \r
498 int32_t __cdecl\r
499 main(\r
500         int32_t argc,\r
501         char* argv[])\r
502 {\r
503         BOOLEAN showHelp = FALSE;\r
504         if (argc < 2)\r
505         {\r
506                 showHelp = TRUE;\r
507         }\r
508         else\r
509         {\r
510                 if(!_stricmp(argv[1], "-h") || !_stricmp(argv[1], "-help"))\r
511                 {\r
512                         showHelp = TRUE;\r
513                 }\r
514                 else\r
515                         partition_operation(argv,argc);\r
516         }\r
517         if (showHelp)\r
518                 show_help();\r
519 }\r
520 \r
521 \r