2 * tickadj - read, and possibly modify, the kernel `tick' and
3 * `tickadj' variables, as well as `dosynctodr'. Note that
4 * this operates on the running kernel only. I'd like to be
5 * able to read and write the binary as well, but haven't
8 * HMS: The #includes here are different from those in xntpd/ntp_unixclock.c
16 #include "ntp_types.h"
22 #endif /* HAVE_UNISTD_H */
24 #ifdef HAVE_SYS_TIMEX_H
25 # include <sys/timex.h>
28 #ifdef HAVE_ADJTIMEX /* Linux */
43 extern int ntp_optind;
44 extern char *ntp_optarg;
47 if (argc==2 && argv[1][0] != '-') { /* old Linux format, for compatability */
48 if ((i = atoi(argv[1])) > 0) {
50 txc.modes = ADJ_TIMETICK;
52 fprintf(stderr, "Silly value for tick: %s\n", argv[1]);
56 while ((c = ntp_getopt(argc, argv, "a:qt:")) != EOF) {
59 if ((i=atoi(ntp_optarg)) > 0) {
61 txc.modes |= ADJ_TICKADJ;
64 "%s: unlikely value for tickadj: %s\n",
65 progname, ntp_optarg);
75 if ((i=atoi(ntp_optarg)) > 0) {
77 txc.modes |= ADJ_TIMETICK;
79 (void) fprintf(stderr,
80 "%s: unlikely value for tick: %s\n",
81 progname, ntp_optarg);
88 "Usage: %s [tick_value]\n-or- %s [ -q ] [ -t tick ] [ -a tickadj ]\n",
97 if (adjtimex(&txc) < 0)
100 printf("tick = %ld\ntick_adj = %d\n",
101 txc.time_tick, txc.tickadj);
104 exit(errflg ? 1 : 0);
115 fprintf(stderr, "Usage: %s [tick_value]\n", argv[0]);
121 if ( (txc.time_tick = atoi(argv[1])) < 1 )
123 if ( (txc.tick = atoi(argv[1])) < 1 )
126 fprintf(stderr, "Silly value for tick: %s\n", argv[1]);
130 txc.modes = ADJ_TIMETICK;
133 txc.modes = ADJ_TICK;
152 if (adjtimex(&txc) < 0)
159 printf("tick = %ld\ntick_adj = %ld\n", txc.time_tick, txc.tickadj);
161 printf("tick = %ld\n", txc.tick);
169 #else /* not Linux... kmem tweaking: */
171 #ifdef HAVE_SYS_FILE_H
172 # include <sys/file.h>
174 #include <sys/stat.h>
176 #ifdef HAVE_SYS_PARAM_H
177 # include <sys/param.h>
182 #else /* not NLIST_STRUCT */ /* was defined(SYS_AUX3) || defined(SYS_AUX2) */
183 # include <sys/resource.h>
184 # include <sys/file.h>
186 # ifdef HAVE_SYS_VAR_H
187 # include <sys/var.h>
191 #include "ntp_stdlib.h"
194 #ifdef hz /* Was: RS6000 */
203 /* vxWorks needs mode flag -casey*/
204 #define open(name, flags) open(name, flags, 0777)
207 #ifndef L_SET /* Was: defined(SYS_PTX) || defined(SYS_IX86OSF1) */
208 # define L_SET SEEK_SET
212 # define HZ DEFAULT_HZ
215 #define KMEM "/dev/kmem"
216 #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
221 int writetickadj = 0;
222 int writeopttickadj = 0;
228 const char *kmem = KMEM;
229 const char *file = NULL;
232 static void getoffsets (off_t *, off_t *, off_t *, off_t *);
233 static int openfile (const char *, int);
234 static void writevar (int, off_t, int);
235 static void readvar (int, off_t, int *);
238 * main - parse arguments and handle options
248 off_t tickadj_offset;
251 off_t noprintf_offset;
252 int tickadj, ktickadj; /* HMS: Why isn't this u_long? */
253 int tick, ktick; /* HMS: Why isn't this u_long? */
257 int hz_int, hz_hundredths;
258 int recommend_tickadj;
264 while ((c = ntp_getopt(argc, argv, "a:Adkpqst:")) != EOF)
269 writetickadj = atoi(ntp_optarg);
270 if (writetickadj <= 0)
272 (void) fprintf(stderr,
273 "%s: unlikely value for tickadj: %s\n",
274 progname, ntp_optarg);
278 #if defined SCO5_CLOCK
279 if (writetickadj % HZ)
281 writetickadj = (writetickadj / HZ) * HZ;
282 (void) fprintf(stderr,
283 "tickadj truncated to: %d\n", writetickadj);
285 #endif /* SCO5_CLOCK */
307 writetick = atoi(ntp_optarg);
310 (void) fprintf(stderr,
311 "%s: unlikely value for tick: %s\n",
312 progname, ntp_optarg);
321 if (errflg || ntp_optind != argc)
323 (void) fprintf(stderr,
324 "usage: %s [-Adkpqs] [-a newadj] [-t newtick]\n", progname);
328 getoffsets(&tick_offset, &tickadj_offset, &dosync_offset, &noprintf_offset);
332 (void) printf("tick offset = %lu\n", (unsigned long)tick_offset);
333 (void) printf("tickadj offset = %lu\n", (unsigned long)tickadj_offset);
334 (void) printf("dosynctodr offset = %lu\n", (unsigned long)dosync_offset);
335 (void) printf("noprintf offset = %lu\n", (unsigned long)noprintf_offset);
338 if (writetick && (tick_offset == 0))
340 (void) fprintf(stderr,
341 "No tick kernel variable\n");
345 if (writeopttickadj && (tickadj_offset == 0))
347 (void) fprintf(stderr,
348 "No tickadj kernel variable\n");
352 if (unsetdosync && (dosync_offset == 0))
354 (void) fprintf(stderr,
355 "No dosynctodr kernel variable\n");
359 if (setnoprintf && (noprintf_offset == 0))
361 (void) fprintf(stderr,
362 "No noprintf kernel variable\n");
366 if (tick_offset != 0)
368 readvar(fd, tick_offset, &tick);
369 #if defined(TICK_NANO) && defined(K_TICK_NAME)
371 (void) printf("KERNEL %s = %d nsec\n", K_TICK_NAME, tick);
372 #endif /* TICK_NANO && K_TICK_NAME */
383 if (tickadj_offset != 0)
385 readvar(fd, tickadj_offset, &tickadj);
388 /* scale from nsec/sec to usec/tick */
389 tickadj /= (1000L * HZ);
390 #endif /*SCO5_CLOCK */
392 #if defined(TICKADJ_NANO) && defined(K_TICKADJ_NAME)
394 (void) printf("KERNEL %s = %d nsec\n", K_TICKADJ_NAME, tickadj);
395 #endif /* TICKADJ_NANO && K_TICKADJ_NAME */
407 if (dosync_offset != 0)
409 readvar(fd, dosync_offset, &dosynctodr);
412 if (noprintf_offset != 0)
414 readvar(fd, noprintf_offset, &noprintf);
419 if (unsetdosync && dosync_offset == 0)
421 (void) fprintf(stderr,
422 "%s: can't find %s in namelist\n",
424 #ifdef K_DOSYNCTODR_NAME
426 #else /* not K_DOSYNCTODR_NAME */
428 #endif /* not K_DOSYNCTODR_NAME */
434 #if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
435 hz = (int) sysconf (_SC_CLK_TCK);
436 #endif /* not HAVE_SYSCONF && _SC_CLK_TCK */
443 #endif /* PRESET_TICK */
450 #ifdef PRESET_TICKADJ
451 tickadj = (PRESET_TICKADJ) ? PRESET_TICKADJ : 1;
452 #endif /* PRESET_TICKADJ */
456 if (tick_offset != 0)
458 (void) printf("KERNEL tick = %d usec (from %s kernel variable)\n",
463 "<this can't happen>"
468 (void) printf("PRESET tick = %d usec\n", tick);
469 #endif /* PRESET_TICK */
470 if (tickadj_offset != 0)
472 (void) printf("KERNEL tickadj = %d usec (from %s kernel variable)\n",
474 #ifdef K_TICKADJ_NAME
477 "<this can't happen>"
481 #ifdef PRESET_TICKADJ
482 (void) printf("PRESET tickadj = %d usec\n", tickadj);
483 #endif /* PRESET_TICKADJ */
484 if (dosync_offset != 0)
486 (void) printf("dosynctodr is %s\n", dosynctodr ? "on" : "off");
488 if (noprintf_offset != 0)
490 (void) printf("kernel level printf's: %s\n",
491 noprintf ? "off" : "on");
497 (void) fprintf(stderr, "%s: the value of tick is silly!\n",
502 hz_int = (int)(1000000L / (long)tick);
503 hz_hundredths = (int)((100000000L / (long)tick) - ((long)hz_int * 100L));
506 (void) printf("KERNEL hz = %d\n", hz);
507 (void) printf("calculated hz = %d.%02d Hz\n", hz_int,
511 #if defined SCO5_CLOCK
512 recommend_tickadj = 100;
513 #else /* SCO5_CLOCK */
514 tmp = (long) tick * 500L;
515 recommend_tickadj = (int)(tmp / 1000000L);
516 if (tmp % 1000000L > 0)
521 #ifdef MIN_REC_TICKADJ
522 if (recommend_tickadj < MIN_REC_TICKADJ)
524 recommend_tickadj = MIN_REC_TICKADJ;
526 #endif /* MIN_REC_TICKADJ */
527 #endif /* SCO5_CLOCK */
530 if ((!quiet) && (tickadj_offset != 0))
532 (void) printf("recommended value of tickadj = %d us\n",
536 if ( writetickadj == 0
542 exit(errflg ? 1 : 0);
545 if (writetickadj == 0 && writeopttickadj)
547 writetickadj = recommend_tickadj;
550 fd = openfile(file, O_WRONLY);
552 if (setnoprintf && (noprintf_offset != 0))
556 (void) fprintf(stderr, "setting noprintf: ");
557 (void) fflush(stderr);
559 writevar(fd, noprintf_offset, 1);
562 (void) fprintf(stderr, "done!\n");
566 if ((writetick > 0) && (tick_offset != 0))
570 (void) fprintf(stderr, "writing tick, value %d: ",
572 (void) fflush(stderr);
574 writevar(fd, tick_offset, writetick);
577 (void) fprintf(stderr, "done!\n");
581 if ((writetickadj > 0) && (tickadj_offset != 0))
585 (void) fprintf(stderr, "writing tickadj, value %d: ",
587 (void) fflush(stderr);
591 /* scale from usec/tick to nsec/sec */
592 writetickadj *= (1000L * HZ);
593 #endif /* SCO5_CLOCK */
595 writevar(fd, tickadj_offset, writetickadj);
598 (void) fprintf(stderr, "done!\n");
602 if (unsetdosync && (dosync_offset != 0))
606 (void) fprintf(stderr, "zeroing dosynctodr: ");
607 (void) fflush(stderr);
609 writevar(fd, dosync_offset, 0);
612 (void) fprintf(stderr, "done!\n");
616 return(errflg ? 1 : 0);
620 * getoffsets - read the magic offsets from the specified file
632 # ifndef HAVE_KVM_OPEN
638 # ifdef NLIST_NAME_UNION
647 #define K_FILLER_NAME "DavidLetterman"
649 #ifdef NLIST_EXTRA_INDIRECTION
654 static struct nlist nl[] =
657 #ifdef K_TICKADJ_NAME
673 #ifdef K_DOSYNCTODR_NAME
681 #ifdef K_NOPRINTF_NAME
691 #ifndef HAVE_KVM_OPEN
692 static const char *kernels[] =
694 #ifdef HAVE_GETBOOTFILE
695 NULL, /* *** SEE BELOW! *** */
709 #endif /* not HAVE_KVM_OPEN */
713 * Solaris > 2.5 doesn't have a kernel file. Use the kvm_* interface
714 * to read the kernel name list. -- stolcke 3/4/96
716 kvm_t *kvm_handle = kvm_open(NULL, NULL, NULL, O_RDONLY, progname);
718 if (kvm_handle == NULL)
720 (void) fprintf(stderr,
721 "%s: kvm_open failed\n",
725 if (kvm_nlist(kvm_handle, nl) == -1)
727 (void) fprintf(stderr,
728 "%s: kvm_nlist failed\n",
732 kvm_close(kvm_handle);
733 #else /* not HAVE_KVM_OPEN */
734 #ifdef HAVE_GETBOOTFILE /* *** SEE HERE! *** */
735 if (kernels[0] == NULL)
737 char * cp = (char *)getbootfile();
745 kernels[0] = "/Placeholder";
748 #endif /* HAVE_GETBOOTFILE */
749 for (kname = kernels; *kname != NULL; kname++)
753 if (stat(*kname, &stbuf) == -1)
757 if (nlist(*kname, nl) >= 0)
763 (void) fprintf(stderr,
764 "%s: nlist didn't find needed symbols from <%s>: %s\n",
765 progname, *kname, strerror(errno));
770 (void) fprintf(stderr,
771 "%s: Couldn't find the kernel\n",
775 #endif /* HAVE_KVM_OPEN */
781 fd = openfile(file, O_RDONLY);
782 #ifdef NLIST_EXTRA_INDIRECTION
784 * Go one more round of indirection.
786 for (i = 0; i < (sizeof(nl) / sizeof(struct nlist)); i++)
788 if ((nl[i].n_value) && (nl[i].n_sclass == 0x6b))
790 readvar(fd, nl[i].n_value, &nl[i].n_value);
793 #endif /* NLIST_EXTRA_INDIRECTION */
795 #endif /* not NOKMEM */
802 #if defined(N_TICKADJ)
803 *tickadj_off = nl[N_TICKADJ].n_value;
807 *tick_off = nl[N_TICK].n_value;
810 #if defined(N_DOSYNC)
811 *dosync_off = nl[N_DOSYNC].n_value;
814 #if defined(N_NOPRINTF)
815 *noprintf_off = nl[N_NOPRINTF].n_value;
827 * openfile - open the file, check for errors
837 ifd = open(name, mode);
840 (void) fprintf(stderr, "%s: open %s: ", progname, name);
849 * writevar - write a variable into the file
859 if (lseek(ofd, off, L_SET) == -1)
861 (void) fprintf(stderr, "%s: lseek fails: ", progname);
865 if (write(ofd, (char *)&var, sizeof(int)) != sizeof(int))
867 (void) fprintf(stderr, "%s: write fails: ", progname);
876 * readvar - read a variable from the file
887 if (lseek(ifd, off, L_SET) == -1)
889 (void) fprintf(stderr, "%s: lseek fails: ", progname);
893 i = read(ifd, (char *)var, sizeof(int));
896 (void) fprintf(stderr, "%s: read fails: ", progname);
900 if (i != sizeof(int))
902 (void) fprintf(stderr, "%s: read expected %d, got %d\n",
903 progname, (int)sizeof(int), i);
908 #endif /* not Linux */