Whamcloud - gitweb
land v0.9.1 on HEAD, in preparation for a 1.0.x branch
[fs/lustre-release.git] / lustre / utils / lustre_cfg.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (C) 2002 Cluster File Systems, Inc.
5  *   Author: Peter J. Braam <braam@clusterfs.com>
6  *   Author: Phil Schwan <phil@clusterfs.com>
7  *   Author: Andreas Dilger <adilger@clusterfs.com>
8  *   Author: Robert Read <rread@clusterfs.com>
9  *
10  *   This file is part of Lustre, http://www.lustre.org.
11  *
12  *   Lustre is free software; you can redistribute it and/or
13  *   modify it under the terms of version 2 of the GNU General Public
14  *   License as published by the Free Software Foundation.
15  *
16  *   Lustre is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *   GNU General Public License for more details.
20  *
21  *   You should have received a copy of the GNU General Public License
22  *   along with Lustre; if not, write to the Free Software
23  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  */
26
27
28 #include <stdlib.h>
29 #include <sys/ioctl.h>
30 #include <stdio.h>
31 #include <stdarg.h>
32
33 #ifndef __KERNEL__
34 #include <liblustre.h>
35 #endif
36 #include <linux/lustre_lib.h>
37 #include <linux/lustre_cfg.h>
38 #include <linux/lustre_idl.h>
39 #include <linux/lustre_dlm.h>
40 #include <linux/obd.h>          /* for struct lov_stripe_md */
41 #include <linux/lustre_build_version.h>
42
43 #include <unistd.h>
44 #include <sys/un.h>
45 #include <time.h>
46 #include <sys/time.h>
47 #include <errno.h>
48 #include <string.h>
49
50
51 #include "obdctl.h"
52 #include <portals/ptlctl.h>
53 #include "parser.h"
54 #include <stdio.h>
55
56 static char * lcfg_devname;
57
58 void lcfg_set_devname(char *name)
59 {
60         if (lcfg_devname)
61                 free(lcfg_devname);
62         lcfg_devname = strdup(name);
63 }
64
65
66 int jt_lcfg_device(int argc, char **argv)
67 {
68         char *name;
69
70         if (argc == 1) {
71                 printf("current device is %s\n", lcfg_devname? : "not set");
72                 return 0;
73         } else if (argc != 2) {
74                 return CMD_HELP;
75         }
76
77         name = argv[1];
78
79         /* quietly strip the unnecessary '$' */
80         if (*name == '$')
81                 name++;
82
83         lcfg_set_devname(name);
84
85         return 0;
86 }
87
88 /* NOOP */
89 int jt_lcfg_newdev(int argc, char **argv)
90 {
91         return 0;
92 }
93
94 int jt_lcfg_attach(int argc, char **argv)
95 {
96         struct lustre_cfg lcfg;
97         int rc;
98
99         LCFG_INIT(lcfg, LCFG_ATTACH, lcfg_devname);
100
101         if (argc != 2 && argc != 3 && argc != 4)
102                 return CMD_HELP;
103
104         lcfg.lcfg_inllen1 = strlen(argv[1]) + 1;
105         lcfg.lcfg_inlbuf1 = argv[1];
106         if (argc >= 3) {
107                 lcfg.lcfg_dev_namelen = strlen(argv[2]) + 1;
108                 lcfg.lcfg_dev_name = argv[2];
109         } else {
110                 fprintf(stderr, "error: %s: LCFG_ATTACH requires a name\n",
111                         jt_cmdname(argv[0])); 
112                 return -EINVAL;
113         }
114
115         if (argc == 4) {
116                 lcfg.lcfg_inllen2 = strlen(argv[3]) + 1;
117                 lcfg.lcfg_inlbuf2 = argv[3];
118         }
119
120         rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
121         if (rc < 0) {
122                 fprintf(stderr, "error: %s: LCFG_ATTACH %s\n",
123                         jt_cmdname(argv[0]), strerror(rc = errno));
124         } else if (argc == 3) {
125                 char name[1024];
126
127                 lcfg_set_devname(argv[2]);
128                 if (strlen(argv[2]) > 128) {
129                         printf("Name too long to set environment\n");
130                         return -EINVAL;
131                 }
132                 snprintf(name, 512, "LUSTRE_DEV_%s", argv[2]);
133                 rc = setenv(name, argv[1], 1);
134                 if (rc) {
135                         printf("error setting env variable %s\n", name);
136                 }
137         } else {
138                 lcfg_set_devname(argv[2]);
139         }
140
141         return rc;
142 }
143
144 int jt_lcfg_setup(int argc, char **argv)
145 {
146         struct lustre_cfg lcfg;
147         int rc;
148
149         if (lcfg_devname == NULL) {
150                 fprintf(stderr, "%s: please use 'cfg_device name' to set the "
151                         "device name for config commands.\n", 
152                         jt_cmdname(argv[0])); 
153                 return -EINVAL;
154         }
155
156         LCFG_INIT(lcfg, LCFG_SETUP, lcfg_devname);
157
158         if (argc > 5)
159                 return CMD_HELP;
160
161         if (argc > 1) {
162                 lcfg.lcfg_inllen1 = strlen(argv[1]) + 1;
163                 lcfg.lcfg_inlbuf1 = argv[1];
164         }
165         if (argc > 2) {
166                 lcfg.lcfg_inllen2 = strlen(argv[2]) + 1;
167                 lcfg.lcfg_inlbuf2 = argv[2];
168         }
169         if (argc > 3) {
170                 lcfg.lcfg_inllen3 = strlen(argv[3]) + 1;
171                 lcfg.lcfg_inlbuf3 = argv[3];
172         }
173         if (argc > 4) {
174                 lcfg.lcfg_inllen4 = strlen(argv[4]) + 1;
175                 lcfg.lcfg_inlbuf4 = argv[4];
176         }
177
178         rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
179         if (rc < 0)
180                 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
181                         strerror(rc = errno));
182
183         return rc;
184 }
185
186 int jt_obd_detach(int argc, char **argv)
187 {
188         struct lustre_cfg lcfg;
189         int rc;
190
191         if (lcfg_devname == NULL) {
192                 fprintf(stderr, "%s: please use 'cfg_device name' to set the "
193                         "device name for config commands.\n", 
194                         jt_cmdname(argv[0])); 
195                 return -EINVAL;
196         }
197
198         LCFG_INIT(lcfg, LCFG_DETACH, lcfg_devname);
199
200         if (argc != 1)
201                 return CMD_HELP;
202
203         rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
204         if (rc < 0)
205                 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
206                         strerror(rc = errno));
207
208         return rc;
209 }
210
211 int jt_obd_cleanup(int argc, char **argv)
212 {
213         struct lustre_cfg lcfg;
214         char force = 'F';
215         char failover = 'A';
216         char flags[3];
217         int flag_cnt = 0, n;
218         int rc;
219
220         if (lcfg_devname == NULL) {
221                 fprintf(stderr, "%s: please use 'cfg_device name' to set the "
222                         "device name for config commands.\n", 
223                         jt_cmdname(argv[0])); 
224                 return -EINVAL;
225         }
226
227         LCFG_INIT(lcfg, LCFG_CLEANUP, lcfg_devname);
228
229         if (argc < 1 || argc > 3)
230                 return CMD_HELP;
231
232         for (n = 1; n < argc; n++) 
233                 if (strcmp(argv[n], "force") == 0) {
234                         flags[flag_cnt++] = force;
235                 } else if (strcmp(argv[n], "failover") == 0) {
236                         flags[flag_cnt++] = failover;
237                 } else {
238                         fprintf(stderr, "unknown option: %s", argv[n]);
239                         return CMD_HELP;
240                 }
241
242         lcfg.lcfg_inllen1 = flag_cnt;
243         if (flag_cnt)
244                 lcfg.lcfg_inlbuf1 = flags;
245
246         rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
247         if (rc < 0)
248                 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
249                         strerror(rc = errno));
250
251         return rc;
252 }
253
254 static 
255 int do_add_uuid(char * func, char *uuid, ptl_nid_t nid, int nal) 
256 {
257         char tmp[64];
258         int rc;
259         struct lustre_cfg lcfg;
260
261         LCFG_INIT(lcfg, LCFG_ADD_UUID, lcfg_devname);
262         lcfg.lcfg_nid = nid;
263         lcfg.lcfg_inllen1 = strlen(uuid) + 1;
264         lcfg.lcfg_inlbuf1 = uuid;
265         lcfg.lcfg_nal = nal;
266
267         rc = lcfg_ioctl(func, OBD_DEV_ID, &lcfg);
268         if (rc) {
269                 fprintf(stderr, "IOC_PORTAL_ADD_UUID failed: %s\n",
270                         strerror(errno));
271                 return -1;
272         }
273
274         printf ("Added uuid %s: %s\n", uuid, ptl_nid2str (tmp, nid));
275         return 0;
276 }
277
278 int jt_lcfg_add_uuid(int argc, char **argv)
279 {
280         ptl_nid_t nid = 0;
281         int nal;
282         
283         if (argc != 4) {                
284                 return CMD_HELP;
285         }
286
287         if (ptl_parse_nid (&nid, argv[2]) != 0) {
288                 fprintf (stderr, "Can't parse NID %s\n", argv[2]);
289                         return (-1);
290         }
291
292         nal = ptl_name2nal(argv[3]);
293
294         if (nal <= 0) {
295                 fprintf (stderr, "Can't parse NAL %s\n", argv[3]);
296                 return -1;
297         }
298
299         return do_add_uuid(argv[0], argv[1], nid, nal);
300 }
301
302 int obd_add_uuid(char *uuid, ptl_nid_t nid, int nal)
303 {
304         return do_add_uuid("obd_add_uuid", uuid, nid, nal);
305 }
306
307 int jt_lcfg_del_uuid(int argc, char **argv)
308 {
309         int rc;
310         struct lustre_cfg lcfg;
311
312         if (argc != 2) {
313                 fprintf(stderr, "usage: %s <uuid>\n", argv[0]);
314                 return 0;
315         }
316
317         LCFG_INIT(lcfg, LCFG_DEL_UUID, lcfg_devname);
318
319         if (strcmp (argv[1], "_all_"))
320         {
321                 lcfg.lcfg_inllen1 = strlen(argv[1]) + 1;
322                 lcfg.lcfg_inlbuf1 = argv[1];
323         }
324         
325         rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
326         if (rc) {
327                 fprintf(stderr, "IOC_PORTAL_DEL_UUID failed: %s\n",
328                         strerror(errno));
329                 return -1;
330         }
331         return 0;
332 }
333
334 int jt_lcfg_lov_setup(int argc, char **argv)
335 {
336         struct lustre_cfg lcfg;
337         struct lov_desc desc;
338         struct obd_uuid *uuidarray, *ptr;
339         int rc, i;
340         char *end;
341
342         LCFG_INIT(lcfg, LCFG_SETUP, lcfg_devname);
343
344         if (argc <= 6)
345                 return CMD_HELP;
346
347         if (strlen(argv[1]) > sizeof(desc.ld_uuid) - 1) {
348                 fprintf(stderr,
349                         "error: %s: LOV uuid '%s' longer than "LPSZ" chars\n",
350                         jt_cmdname(argv[0]), argv[1], sizeof(desc.ld_uuid) - 1);
351                 return -EINVAL;
352         }
353
354         memset(&desc, 0, sizeof(desc));
355         obd_str2uuid(&desc.ld_uuid, argv[1]);
356         desc.ld_tgt_count = argc - 6;
357         desc.ld_default_stripe_count = strtoul(argv[2], &end, 0);
358         if (*end) {
359                 fprintf(stderr, "error: %s: bad default stripe count '%s'\n",
360                         jt_cmdname(argv[0]), argv[2]);
361                 return CMD_HELP;
362         }
363         if (desc.ld_default_stripe_count > desc.ld_tgt_count) {
364                 fprintf(stderr,
365                         "error: %s: default stripe count %u > OST count %u\n",
366                         jt_cmdname(argv[0]), desc.ld_default_stripe_count,
367                         desc.ld_tgt_count);
368                 return -EINVAL;
369         }
370
371         desc.ld_default_stripe_size = strtoull(argv[3], &end, 0);
372         if (*end) {
373                 fprintf(stderr, "error: %s: bad default stripe size '%s'\n",
374                         jt_cmdname(argv[0]), argv[3]);
375                 return CMD_HELP;
376         }
377         if (desc.ld_default_stripe_size < 4096) {
378                 fprintf(stderr,
379                         "error: %s: default stripe size "LPU64" too small\n",
380                         jt_cmdname(argv[0]), desc.ld_default_stripe_size);
381                 return -EINVAL;
382         } else if ((long)desc.ld_default_stripe_size <
383                    desc.ld_default_stripe_size) {
384                 fprintf(stderr,
385                         "error: %s: default stripe size "LPU64" too large\n",
386                         jt_cmdname(argv[0]), desc.ld_default_stripe_size);
387                 return -EINVAL;
388         }
389         desc.ld_default_stripe_offset = strtoull(argv[4], &end, 0);
390         if (*end) {
391                 fprintf(stderr, "error: %s: bad default stripe offset '%s'\n",
392                         jt_cmdname(argv[0]), argv[4]);
393                 return CMD_HELP;
394         }
395         desc.ld_pattern = strtoul(argv[5], &end, 0);
396         if (*end) {
397                 fprintf(stderr, "error: %s: bad stripe pattern '%s'\n",
398                         jt_cmdname(argv[0]), argv[5]);
399                 return CMD_HELP;
400         }
401
402         /* NOTE: it is possible to overwrite the default striping parameters,
403          *       but EXTREME care must be taken when saving the OST UUID list.
404          *       It must be EXACTLY the same, or have only additions at the
405          *       end of the list, or only overwrite individual OST entries
406          *       that are restored from backups of the previous OST.
407          */
408         uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray));
409         if (!uuidarray) {
410                 fprintf(stderr, "error: %s: no memory for %d UUIDs\n",
411                         jt_cmdname(argv[0]), desc.ld_tgt_count);
412                 rc = -ENOMEM;
413                 goto out;
414         }
415         for (i = 6, ptr = uuidarray; i < argc; i++, ptr++) {
416                 if (strlen(argv[i]) >= sizeof(*ptr)) {
417                         fprintf(stderr, "error: %s: arg %d (%s) too long\n",
418                                 jt_cmdname(argv[0]), i, argv[i]);
419                         rc = -EINVAL;
420                         goto out;
421                 }
422                 strcpy((char *)ptr, argv[i]);
423         }
424
425         lcfg.lcfg_inllen1 = sizeof(desc);
426         lcfg.lcfg_inlbuf1 = (char *)&desc;
427         lcfg.lcfg_inllen2 = desc.ld_tgt_count * sizeof(*uuidarray);
428         lcfg.lcfg_inlbuf2 = (char *)uuidarray;
429
430         rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
431         if (rc)
432                 fprintf(stderr, "error: %s: ioctl error: %s\n",
433                         jt_cmdname(argv[0]), strerror(rc = errno));
434 out:
435         free(uuidarray);
436         return rc;
437 }
438
439 int jt_lcfg_mount_option(int argc, char **argv)
440 {
441         int rc;
442         struct lustre_cfg lcfg;
443
444         LCFG_INIT(lcfg, LCFG_MOUNTOPT, lcfg_devname);
445
446         if (argc < 3 || argc > 4)
447                 return CMD_HELP;
448
449         /* profile name */
450         lcfg.lcfg_inllen1 = strlen(argv[1]) + 1;
451         lcfg.lcfg_inlbuf1 = argv[1];
452         /* osc name */
453         lcfg.lcfg_inllen2 = strlen(argv[2]) + 1;
454         lcfg.lcfg_inlbuf2 = argv[2];
455         if (argc == 4) {
456                 /* mdc name */
457                 lcfg.lcfg_inllen3 = strlen(argv[3]) + 1;
458                 lcfg.lcfg_inlbuf3 = argv[3];
459         }
460         rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
461         if (rc < 0) {
462                 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
463                         strerror(rc = errno));
464         }
465
466         return rc;
467 }
468
469 int jt_lcfg_del_mount_option(int argc, char **argv)
470 {
471         int rc;
472         struct lustre_cfg lcfg;
473
474         LCFG_INIT(lcfg, LCFG_DEL_MOUNTOPT, lcfg_devname);
475
476         if (argc != 2)
477                 return CMD_HELP;
478
479         /* profile name */
480         lcfg.lcfg_inllen1 = strlen(argv[1]) + 1;
481         lcfg.lcfg_inlbuf1 = argv[1];
482
483         rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
484         if (rc < 0) {
485                 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
486                         strerror(rc = errno));
487         }
488
489         return rc;
490 }
491
492 int jt_lcfg_set_timeout(int argc, char **argv)
493 {
494         int rc;
495         struct lustre_cfg lcfg;
496
497         LCFG_INIT(lcfg, LCFG_SET_TIMEOUT, lcfg_devname);
498
499         if (argc != 2)
500                 return CMD_HELP;
501
502         lcfg.lcfg_num = atoi(argv[1]);
503         
504         rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
505         if (rc < 0) {
506                 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
507                         strerror(rc = errno));
508         }
509
510         return rc;
511 }
512
513
514 int jt_lcfg_set_lustre_upcall(int argc, char **argv)
515 {
516         int rc;
517         struct lustre_cfg lcfg;
518
519         LCFG_INIT(lcfg, LCFG_SET_UPCALL, lcfg_devname);
520
521         if (argc != 2)
522                 return CMD_HELP;
523
524         /* profile name */
525         lcfg.lcfg_inllen1 = strlen(argv[1]) + 1;
526         lcfg.lcfg_inlbuf1 = argv[1];
527
528         rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
529         if (rc < 0) {
530                 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
531                         strerror(rc = errno));
532         }
533
534         return rc;
535 }
536