7 #include <sys/sysmacros.h>
9 #include <sys/utsname.h>
27 for (i=strlen(str)-1; i >=0 && isspace(str[i]); --i) ;
33 basenamecpy (const char * str1, char * str2, int str2len)
37 if (!str1 || !strlen(str1))
40 if (strlen(str1) >= str2len)
46 p = str1 + (strlen(str1) - 1);
48 while (*--p != '/' && p != str1)
54 strncpy(str2, p, str2len);
55 str2[str2len - 1] = '\0';
60 filepresent (char * run) {
68 char *get_next_string(char **temp, char *split_char)
71 token = strsep(temp, split_char);
72 while (token != NULL && !strcmp(token, ""))
73 token = strsep(temp, split_char);
78 get_word (char * sentence, char ** word)
87 while (*sentence == ' ') {
91 if (*sentence == '\0')
96 while (*p != ' ' && *p != '\0')
99 len = (int) (p - sentence);
104 *word = MALLOC(len + 1);
107 condlog(0, "get_word : oom");
110 strncpy(*word, sentence, len);
112 condlog(4, "*word = %s, len = %i", *word, len);
120 size_t strlcpy(char *dst, const char *src, size_t size)
127 while ((ch = *p++)) {
133 /* If size == 0 there is no space for a final null... */
139 size_t strlcat(char *dst, const char *src, size_t size)
146 while (bytes < size && *q) {
151 return (bytes + strlen(src));
153 while ((ch = *p++)) {
163 int devt2devname(char *devname, int devname_len, char *devt)
166 unsigned int tmpmaj, tmpmin, major, minor;
167 char dev[FILE_NAME_SIZE];
168 char block_path[PATH_SIZE];
171 memset(block_path, 0, sizeof(block_path));
172 memset(dev, 0, sizeof(dev));
173 if (sscanf(devt, "%u:%u", &major, &minor) != 2) {
174 condlog(0, "Invalid device number %s", devt);
178 if (devname_len > FILE_NAME_SIZE)
179 devname_len = FILE_NAME_SIZE;
181 if (stat("/sys/dev/block", &statbuf) == 0) {
182 /* Newer kernels have /sys/dev/block */
183 sprintf(block_path,"/sys/dev/block/%u:%u", major, minor);
184 if (lstat(block_path, &statbuf) == 0) {
185 if (S_ISLNK(statbuf.st_mode) &&
186 readlink(block_path, dev, FILE_NAME_SIZE-1) > 0) {
187 char *p = strrchr(dev, '/');
190 condlog(0, "No sysfs entry for %s",
195 strncpy(devname, p, devname_len);
201 memset(block_path, 0, sizeof(block_path));
203 if (!(fd = fopen("/proc/partitions", "r"))) {
204 condlog(0, "Cannot open /proc/partitions");
209 int r = fscanf(fd,"%u %u %*d %s",&tmpmaj, &tmpmin, dev);
211 r = fscanf(fd,"%*s\n");
217 if ((major == tmpmaj) && (minor == tmpmin)) {
218 if (snprintf(block_path, sizeof(block_path),
219 "/sys/block/%s", dev) >= sizeof(block_path)) {
220 condlog(0, "device name %s is too long", dev);
229 if (strncmp(block_path,"/sys/block", 10)) {
230 condlog(3, "No device found for %u:%u", major, minor);
234 if (stat(block_path, &statbuf) < 0) {
235 condlog(0, "No sysfs entry for %s", block_path);
239 if (S_ISDIR(statbuf.st_mode) == 0) {
240 condlog(0, "sysfs entry %s is not a directory", block_path);
243 basenamecpy((const char *)block_path, devname, devname_len);
247 /* This function returns a pointer inside of the supplied pathname string.
248 * If is_path_device is true, it may also modify the supplied string */
249 char *convert_dev(char *name, int is_path_device)
255 if (is_path_device) {
256 ptr = strstr(name, "cciss/");
262 if (!strncmp(name, "/dev/", 5) && strlen(name) > 5)
269 dev_t parse_devt(const char *dev_t)
273 if (sscanf(dev_t,"%d:%d", &maj, &min) != 2)
276 return makedev(maj, min);
279 char *parse_uid_attribute_by_attrs(char *uid_attrs, char *path_dev)
282 char *uid_attr_record;
288 if(!uid_attrs || !path_dev)
291 count = get_word(uid_attrs, &uid_attr_record);
292 while (uid_attr_record) {
293 tmp = strrchr(uid_attr_record, ':');
295 free(uid_attr_record);
299 count = get_word(uid_attrs, &uid_attr_record);
302 dev = uid_attr_record;
306 if(!strncmp(path_dev, dev, strlen(dev))) {
307 uid_attribute = STRDUP(attr);
308 free(uid_attr_record);
309 return uid_attribute;
312 free(uid_attr_record);
316 count = get_word(uid_attrs, &uid_attr_record);
322 setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached)
326 ret = pthread_attr_init(attr);
328 if (stacksize < PTHREAD_STACK_MIN)
329 stacksize = PTHREAD_STACK_MIN;
330 ret = pthread_attr_setstacksize(attr, stacksize);
333 ret = pthread_attr_setdetachstate(attr,
334 PTHREAD_CREATE_DETACHED);
339 int systemd_service_enabled_in(const char *dev, const char *prefix)
341 char path[PATH_SIZE], file[PATH_SIZE], service[PATH_SIZE];
346 snprintf(service, PATH_SIZE, "multipathd.service");
347 snprintf(path, PATH_SIZE, "%s/systemd/system", prefix);
348 condlog(3, "%s: checking for %s in %s", dev, service, path);
350 dirfd = opendir(path);
354 while ((d = readdir(dirfd)) != NULL) {
358 if ((strcmp(d->d_name,".") == 0) ||
359 (strcmp(d->d_name,"..") == 0))
362 if (strlen(d->d_name) < 6)
365 p = d->d_name + strlen(d->d_name) - 6;
366 if (strcmp(p, ".wants"))
368 snprintf(file, PATH_SIZE, "%s/%s/%s",
369 path, d->d_name, service);
370 if (stat(file, &stbuf) == 0) {
371 condlog(3, "%s: found %s", dev, file);
381 int systemd_service_enabled(const char *dev)
385 found = systemd_service_enabled_in(dev, "/etc");
387 found = systemd_service_enabled_in(dev, "/usr/lib");
389 found = systemd_service_enabled_in(dev, "/lib");
391 found = systemd_service_enabled_in(dev, "/run");
395 static int _linux_version_code;
396 static pthread_once_t _lvc_initialized = PTHREAD_ONCE_INIT;
398 /* Returns current kernel version encoded as major*65536 + minor*256 + patch,
399 * so, for example, to check if the kernel is greater than 2.2.11:
401 * if (get_linux_version_code() > KERNEL_VERSION(2,2,11)) { <stuff> }
403 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
404 * Code copied from busybox (GPLv2 or later)
407 _set_linux_version_code(void)
413 uname(&name); /* never fails */
416 for (i = 0; i < 3; i++) {
418 r = r * 256 + (t ? atoi(t) : 0);
421 _linux_version_code = r;
424 int get_linux_version_code(void)
426 pthread_once(&_lvc_initialized, _set_linux_version_code);
427 return _linux_version_code;
430 int parse_prkey(char *ptr, uint64_t *prkey)
436 if (*ptr == 'x' || *ptr == 'X')
438 if (*ptr == '\0' || strlen(ptr) > 16)
440 if (strlen(ptr) != strspn(ptr, "0123456789aAbBcCdDeEfF"))
442 if (sscanf(ptr, "%" SCNx64 "", prkey) != 1)
447 int safe_write(int fd, const void *buf, size_t count)
450 ssize_t r = write(fd, buf, count);
457 buf = (const char *)buf + r;