Exemplo n.º 1
0
static int show_status(char **args, unsigned n) {
        char buf[64];
        struct boot_info *info;
        int err;

        err = boot_info_new(&info);
        if (err < 0)
                return -ENOMEM;

        err = boot_info_query(info);

        printf("    Machine ID: %s\n", sd_id128_to_string(info->machine_id, buf));
        printf("       Boot ID: %s\n", sd_id128_to_string(info->boot_id, buf));
        if (info->fw_type)
                printf("      Firmware: %s (%s)\n", info->fw_type, strna(info->fw_info));

        if (info->fw_entry_active >= 0) {
                printf("Firmware entry: %s\n", strna(info->fw_entries[info->fw_entry_active].title));
                if (info->fw_entries[info->fw_entry_active].path)
                        printf("                %s\n", info->fw_entries[info->fw_entry_active].path);
                if (!sd_id128_equal(info->fw_entries[info->fw_entry_active].part_uuid, SD_ID128_NULL))
                        printf("                /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
                               SD_ID128_FORMAT_VAL(info->fw_entries[info->fw_entry_active].part_uuid));
        }

        if (info->loader) {
                printf("        Loader: %s\n", info->loader);
                printf("                %s\n", strna(info->loader_image_path));
                if (!sd_id128_equal(info->loader_part_uuid, SD_ID128_NULL))
                        printf("                /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
                               SD_ID128_FORMAT_VAL(info->loader_part_uuid));

                if (info->loader_entry_active >= 0) {
                        printf("  Loader entry: %s\n", strna(info->loader_entries[info->loader_entry_active].title));
                        printf("                %s\n", info->loader_entries[info->loader_entry_active].path);
                }

                printf("Loader options: %s\n", strna(info->loader_options_added));
        } else
                printf("No suitable data is provided by the boot manager. See:\n"
                       "  http://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface\n"
                       "  http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec\n"
                       "for details.\n");
        printf("\n");

        boot_info_free(info);
        return err;
}
Exemplo n.º 2
0
int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync) {
        char buffer[36 + 2];
        size_t sz;
        int r;

        assert(fd >= 0);
        assert(f < _ID128_FORMAT_MAX);

        if (f != ID128_UUID) {
                sd_id128_to_string(id, buffer);
                buffer[32] = '\n';
                sz = 33;
        } else {
                id128_to_uuid_string(id, buffer);
                buffer[36] = '\n';
                sz = 37;
        }

        r = loop_write(fd, buffer, sz, false);
        if (r < 0)
                return r;

        if (do_sync) {
                if (fsync(fd) < 0)
                        return -errno;
        }

        return r;
}
Exemplo n.º 3
0
int main(int argc, char *argv[]) {
        sd_id128_t bid;
        char boot_id[SD_ID128_STRING_MAX];
        _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *zz = NULL;

        assert_se(sd_id128_get_boot(&bid) >= 0);
        sd_id128_to_string(bid, boot_id);

        x = strjoin("/tmp/systemd-private-", boot_id, "-abcd.service-", NULL);
        y = strjoin("/var/tmp/systemd-private-", boot_id, "-abcd.service-", NULL);
        assert_se(x && y);

        test_tmpdir("abcd.service", x, y);

        z = strjoin("/tmp/systemd-private-", boot_id, "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-", NULL);
        zz = strjoin("/var/tmp/systemd-private-", boot_id, "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-", NULL);

        assert_se(z && zz);

        test_tmpdir("sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device", z, zz);

        test_netns();

        return 0;
}
Exemplo n.º 4
0
static void test_condition_test_host(void) {
        Condition *condition;
        sd_id128_t id;
        int r;
        char sid[SD_ID128_STRING_MAX];
        _cleanup_free_ char *hostname = NULL;

        r = sd_id128_get_machine(&id);
        assert_se(r >= 0);
        assert_se(sd_id128_to_string(id, sid));

        condition = condition_new(CONDITION_HOST, sid, false, false);
        assert_se(condition_test(condition));
        condition_free(condition);

        condition = condition_new(CONDITION_HOST, "garbage value jjjjjjjjjjjjjj", false, false);
        assert_se(!condition_test(condition));
        condition_free(condition);

        condition = condition_new(CONDITION_HOST, sid, false, true);
        assert_se(!condition_test(condition));
        condition_free(condition);

        hostname = gethostname_malloc();
        assert_se(hostname);

        condition = condition_new(CONDITION_HOST, hostname, false, false);
        assert_se(condition_test(condition));
        condition_free(condition);
}
Exemplo n.º 5
0
int boot_info_query(struct boot_info *info) {
        char str[64];
        char buf[64];
        char *loader_active = NULL;

        info->fw_secure_boot = is_efi_secure_boot();
        info->fw_secure_boot_setup_mode = is_efi_secure_boot_setup_mode();

        efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderInfo", &info->loader);

        get_boot_entries(info);
        if (info->fw_entries_count > 0) {
                get_boot_order(info);
                qsort(info->fw_entries, info->fw_entries_count, sizeof(struct boot_info_entry), entry_cmp);
                find_active_entry(info);
        }

        efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderFirmwareType", &info->fw_type);
        efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderFirmwareInfo", &info->fw_info);
        efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderImageIdentifier", &info->loader_image_path);
        tilt_slashes(info->loader_image_path);
        efi_loader_get_device_part_uuid(&info->loader_part_uuid);

        boot_loader_read_entries(info);
        efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntrySelected", &loader_active);
        if (loader_active) {
                boot_loader_find_active_entry(info, loader_active);
                free(loader_active);
        }

        snprintf(str, sizeof(str), "LoaderEntryOptions-%s", sd_id128_to_string(info->machine_id, buf));
        efi_get_variable_string(EFI_VENDOR_LOADER, str, &info->loader_options_added);

        return 0;
}
Exemplo n.º 6
0
static int process_machine_id(void) {
        const char *etc_machine_id;
        char id[SD_ID128_STRING_MAX];
        int r;

        etc_machine_id = prefix_roota("/etc/machine-id");
        if (faccessat(AT_FDCWD, etc_machine_id, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
                return 0;

        if (!arg_root)
                return 0;

        if (sd_id128_equal(arg_machine_id, SD_ID128_NULL))
                return 0;

        mkdir_parents(etc_machine_id, 0755);
        r = write_string_file(etc_machine_id, sd_id128_to_string(arg_machine_id, id));
        if (r < 0) {
                log_error("Failed to write machine id: %s", strerror(-r));
                return r;
        }

        log_info("%s written.", etc_machine_id);
        return 0;
}
Exemplo n.º 7
0
gboolean
gl_util_can_read_user_journal (void)
{
    GFile *file;
    GFileInfo *info;
    gint ret;
    gchar *path;
    gchar ids[33];
    gchar *filename;
    gchar *uid;
    uid_t user_id;
    sd_id128_t machine;
    GError *error = NULL;
    GCredentials *credentials;

    credentials = g_credentials_new ();
    user_id = g_credentials_get_unix_user (credentials, &error);
    if (error != NULL)
    {
        g_debug ("Unable to get uid: %s", error->message);
        g_error_free (error);
    }
    uid = g_strdup_printf ("%d", user_id);
    filename = g_strconcat ("/user-", uid, ".journal", NULL);

    ret = sd_id128_get_machine (&machine);
    if (ret < 0)
    {
        g_critical ("Error getting machine id: %s", g_strerror (-ret));
    }
    sd_id128_to_string (machine, ids);

    path = g_build_filename ("/var/log/journal", ids, filename, NULL);

    file = g_file_new_for_path (path);
    info = g_file_query_info (file, G_FILE_ATTRIBUTE_ACCESS_CAN_READ,
                              G_FILE_QUERY_INFO_NONE, NULL, NULL);

    g_free (uid);
    g_free (path);
    g_free (filename);
    g_object_unref (file);
    g_object_unref (credentials);

    if (g_file_info_get_attribute_boolean (info,
                                           G_FILE_ATTRIBUTE_ACCESS_CAN_READ))
    {
        g_object_unref (info);

        return TRUE;
    }
    else
    {
        g_object_unref (info);

        return FALSE;
    }
}
Exemplo n.º 8
0
int main(int argc, char *argv[]) {
        sd_id128_t id, id2;
        char t[33];
        _cleanup_free_ char *b = NULL;

        assert_se(sd_id128_randomize(&id) == 0);
        printf("random: %s\n", sd_id128_to_string(id, t));

        assert_se(sd_id128_from_string(t, &id2) == 0);
        assert_se(sd_id128_equal(id, id2));

        if (sd_booted() > 0) {
                assert_se(sd_id128_get_machine(&id) == 0);
                printf("machine: %s\n", sd_id128_to_string(id, t));

                assert_se(sd_id128_get_boot(&id) == 0);
                printf("boot: %s\n", sd_id128_to_string(id, t));
        }

        printf("waldi: %s\n", sd_id128_to_string(ID128_WALDI, t));
        assert_se(streq(t, STR_WALDI));

        assert_se(asprintf(&b, SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(ID128_WALDI)) == 32);
        printf("waldi2: %s\n", b);
        assert_se(streq(t, b));

        assert_se(sd_id128_from_string(UUID_WALDI, &id) >= 0);
        assert_se(sd_id128_equal(id, ID128_WALDI));

        assert_se(sd_id128_from_string("", &id) < 0);
        assert_se(sd_id128_from_string("01020304-0506-0708-090a-0b0c0d0e0f101", &id) < 0);
        assert_se(sd_id128_from_string("01020304-0506-0708-090a-0b0c0d0e0f10-", &id) < 0);
        assert_se(sd_id128_from_string("01020304-0506-0708-090a0b0c0d0e0f10", &id) < 0);
        assert_se(sd_id128_from_string("010203040506-0708-090a-0b0c0d0e0f10", &id) < 0);

        assert_se(id128_is_valid(STR_WALDI));
        assert_se(id128_is_valid(UUID_WALDI));
        assert_se(!id128_is_valid(""));
        assert_se(!id128_is_valid("01020304-0506-0708-090a-0b0c0d0e0f101"));
        assert_se(!id128_is_valid("01020304-0506-0708-090a-0b0c0d0e0f10-"));
        assert_se(!id128_is_valid("01020304-0506-0708-090a0b0c0d0e0f10"));
        assert_se(!id128_is_valid("010203040506-0708-090a-0b0c0d0e0f10"));

        return 0;
}
Exemplo n.º 9
0
static int driver_get_id(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
        sd_id128_t server_id;
        char buf[SD_ID128_STRING_MAX];
        int r;

        r = sd_bus_get_server_id(bus, &server_id);
        if (r < 0)
                return r;

        return sd_bus_reply_method_return(m, "s", sd_id128_to_string(server_id, buf));
}
Exemplo n.º 10
0
gboolean
gl_util_can_read_system_journal (GlJournalStorage storage_type)
{
    GFile *file;
    GFileInfo *info;
    gint ret;
    gchar *path;
    gchar ids[33];
    sd_id128_t machine;

    ret = sd_id128_get_machine (&machine);
    if (ret < 0)
    {
        g_critical ("Error getting machine id: %s", g_strerror (-ret));
    }
    sd_id128_to_string (machine, ids);

    if (storage_type == GL_JOURNAL_STORAGE_PERSISTENT)
    {
        path = g_build_filename ("/var/log/journal", ids, "system.journal", NULL);
    }
    else if (storage_type == GL_JOURNAL_STORAGE_VOLATILE)
    {
        path = g_build_filename ("/run/log/journal", ids, "system.journal", NULL);
    }
    else
    {
        path = "/dev/null";
    }

    file = g_file_new_for_path (path);
    info = g_file_query_info (file, G_FILE_ATTRIBUTE_ACCESS_CAN_READ,
                              G_FILE_QUERY_INFO_NONE, NULL, NULL);

    g_free (path);
    g_object_unref (file);

    if (g_file_info_get_attribute_boolean (info,
                                           G_FILE_ATTRIBUTE_ACCESS_CAN_READ))
    {
        g_object_unref (info);

        return TRUE;
    }
    else
    {
        g_object_unref (info);

        return FALSE;
    }
}
Exemplo n.º 11
0
static int process_machine_id(void) {
        const char *etc_machine_id;
        char id[SD_ID128_STRING_MAX];
        int r;

        etc_machine_id = prefix_roota(arg_root, "/etc/machine-id");
        if (laccess(etc_machine_id, F_OK) >= 0)
                return 0;

        if (sd_id128_is_null(arg_machine_id))
                return 0;

        mkdir_parents(etc_machine_id, 0755);
        r = write_string_file(etc_machine_id, sd_id128_to_string(arg_machine_id, id),
                              WRITE_STRING_FILE_CREATE | WRITE_STRING_FILE_SYNC);
        if (r < 0)
                return log_error_errno(r, "Failed to write machine id: %m");

        log_info("%s written.", etc_machine_id);
        return 0;
}
Exemplo n.º 12
0
gboolean
gl_util_can_read_system_journal (void)
{
    GFile *file;
    GFileInfo *info;
    gint ret;
    gchar *path;
    gchar ids[33];
    sd_id128_t machine;

    ret = sd_id128_get_machine (&machine);
    if (ret < 0)
    {
        g_critical ("Error getting machine id: %s", g_strerror (-ret));
    }
    sd_id128_to_string (machine, ids);

    path = g_build_filename ("/var/log/journal", ids, "system.journal", NULL);

    file = g_file_new_for_path (path);
    info = g_file_query_info (file, G_FILE_ATTRIBUTE_ACCESS_CAN_READ,
                              G_FILE_QUERY_INFO_NONE, NULL, NULL);

    g_free (path);
    g_object_unref (file);

    if (g_file_info_get_attribute_boolean (info,
                                           G_FILE_ATTRIBUTE_ACCESS_CAN_READ))
    {
        g_object_unref (info);

        return TRUE;
    }
    else
    {
        g_object_unref (info);

        return FALSE;
    }
}
Exemplo n.º 13
0
static int add_this_boot(sd_journal *j) {
        char match[9+32+1] = "_BOOT_ID=";
        sd_id128_t boot_id;
        int r;

        if (!arg_this_boot)
                return 0;

        r = sd_id128_get_boot(&boot_id);
        if (r < 0) {
                log_error("Failed to get boot id: %s", strerror(-r));
                return r;
        }

        sd_id128_to_string(boot_id, match + 9);
        r = sd_journal_add_match(j, match, strlen(match));
        if (r < 0) {
                log_error("Failed to add match: %s", strerror(-r));
                return r;
        }

        return 0;
}
Exemplo n.º 14
0
/**
 * Write up to size bytes to buf. Return negative on error, and number of
 * bytes written otherwise. The last case is a kind of an error too.
 */
static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
    int r;
    size_t pos = 0;

    assert(size <= SSIZE_MAX);

    while (true) {

        switch(u->entry_state) {
        case ENTRY_CURSOR: {
            free(u->current_cursor);
            u->current_cursor = NULL;

            r = sd_journal_get_cursor(u->journal, &u->current_cursor);
            if (r < 0)
                return log_error_errno(r, "Failed to get cursor: %m");

            r = snprintf(buf + pos, size - pos,
                         "__CURSOR=%s\n", u->current_cursor);
            if (pos + r > size)
                /* not enough space */
                return pos;

            u->entry_state ++;

            if (pos + r == size) {
                /* exactly one character short, but we don't need it */
                buf[size - 1] = '\n';
                return size;
            }

            pos += r;
            }       /* fall through */

        case ENTRY_REALTIME: {
            usec_t realtime;

            r = sd_journal_get_realtime_usec(u->journal, &realtime);
            if (r < 0)
                return log_error_errno(r, "Failed to get realtime timestamp: %m");

            r = snprintf(buf + pos, size - pos,
                         "__REALTIME_TIMESTAMP="USEC_FMT"\n", realtime);
            if (r + pos > size)
                /* not enough space */
                return pos;

            u->entry_state ++;

            if (r + pos == size) {
                /* exactly one character short, but we don't need it */
                buf[size - 1] = '\n';
                return size;
            }

            pos += r;
            }       /* fall through */

        case ENTRY_MONOTONIC: {
            usec_t monotonic;
            sd_id128_t boot_id;

            r = sd_journal_get_monotonic_usec(u->journal, &monotonic, &boot_id);
            if (r < 0)
                return log_error_errno(r, "Failed to get monotonic timestamp: %m");

            r = snprintf(buf + pos, size - pos,
                         "__MONOTONIC_TIMESTAMP="USEC_FMT"\n", monotonic);
            if (r + pos > size)
                /* not enough space */
                return pos;

            u->entry_state ++;

            if (r + pos == size) {
                /* exactly one character short, but we don't need it */
                buf[size - 1] = '\n';
                return size;
            }

            pos += r;
            }       /* fall through */

        case ENTRY_BOOT_ID: {
            sd_id128_t boot_id;
            char sid[33];

            r = sd_journal_get_monotonic_usec(u->journal, NULL, &boot_id);
            if (r < 0)
                return log_error_errno(r, "Failed to get monotonic timestamp: %m");

            r = snprintf(buf + pos, size - pos,
                         "_BOOT_ID=%s\n", sd_id128_to_string(boot_id, sid));
            if (r + pos > size)
                /* not enough space */
                return pos;

            u->entry_state ++;

            if (r + pos == size) {
                /* exactly one character short, but we don't need it */
                buf[size - 1] = '\n';
                return size;
            }

            pos += r;
            }       /* fall through */

        case ENTRY_NEW_FIELD: {
            u->field_pos = 0;

            r = sd_journal_enumerate_data(u->journal,
                                          &u->field_data,
                                          &u->field_length);
            if (r < 0)
                return log_error_errno(r, "Failed to move to next field in entry: %m");
            else if (r == 0) {
                u->entry_state = ENTRY_OUTRO;
                continue;
            }

            if (!utf8_is_printable_newline(u->field_data,
                                           u->field_length, false)) {
                u->entry_state = ENTRY_BINARY_FIELD_START;
                continue;
            }

            u->entry_state ++;
            }       /* fall through */

        case ENTRY_TEXT_FIELD:
        case ENTRY_BINARY_FIELD: {
            bool done;
            size_t tocopy;

            done = size - pos > u->field_length - u->field_pos;
            if (done)
                tocopy = u->field_length - u->field_pos;
            else
                tocopy = size - pos;

            memcpy(buf + pos,
                   (char*) u->field_data + u->field_pos,
                   tocopy);

            if (done) {
                buf[pos + tocopy] = '\n';
                pos += tocopy + 1;
                u->entry_state = ENTRY_NEW_FIELD;
                continue;
            } else {
                u->field_pos += tocopy;
                return size;
            }
        }

        case ENTRY_BINARY_FIELD_START: {
            const char *c;
            size_t len;

            c = memchr(u->field_data, '=', u->field_length);
            if (!c || c == u->field_data) {
                log_error("Invalid field.");
                return -EINVAL;
            }

            len = c - (const char*)u->field_data;

            /* need space for label + '\n' */
            if (size - pos < len + 1)
                return pos;

            memcpy(buf + pos, u->field_data, len);
            buf[pos + len] = '\n';
            pos += len + 1;

            u->field_pos = len + 1;
            u->entry_state ++;
            }       /* fall through */

        case ENTRY_BINARY_FIELD_SIZE: {
            uint64_t le64;

            /* need space for uint64_t */
            if (size - pos < 8)
                return pos;

            le64 = htole64(u->field_length - u->field_pos);
            memcpy(buf + pos, &le64, 8);
            pos += 8;

            u->entry_state ++;
            continue;
        }

        case ENTRY_OUTRO:
            /* need space for '\n' */
            if (size - pos < 1)
                return pos;

            buf[pos++] = '\n';
            u->entry_state ++;
            u->entries_sent ++;

            return pos;

        default:
            assert_not_reached("WTF?");
        }
    }
    assert_not_reached("WTF?");
}
Exemplo n.º 15
0
int stub_pid1(sd_id128_t uuid) {
        enum {
                STATE_RUNNING,
                STATE_REBOOT,
                STATE_POWEROFF,
        } state = STATE_RUNNING;

        sigset_t fullmask, oldmask, waitmask;
        usec_t quit_usec = USEC_INFINITY;
        pid_t pid;
        int r;

        /* The new environment we set up, on the stack. */
        char new_environment[] =
                "container=systemd-nspawn\0"
                "container_uuid=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

        /* Implements a stub PID 1, that reaps all processes and processes a couple of standard signals. This is useful
         * for allowing arbitrary processes run in a container, and still have all zombies reaped. */

        assert_se(sigfillset(&fullmask) >= 0);
        assert_se(sigprocmask(SIG_BLOCK, &fullmask, &oldmask) >= 0);

        pid = fork();
        if (pid < 0)
                return log_error_errno(errno, "Failed to fork child pid: %m");

        if (pid == 0) {
                /* Return in the child */
                assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) >= 0);
                setsid();
                return 0;
        }

        reset_all_signal_handlers();

        log_close();
        close_all_fds(NULL, 0);
        log_open();

        /* Flush out /proc/self/environ, so that we don't leak the environment from the host into the container. Also,
         * set $container= and $container_uuid= so that clients in the container that query it from /proc/1/environ
         * find them set set. */
        sd_id128_to_string(uuid, new_environment + sizeof(new_environment) - SD_ID128_STRING_MAX);
        reset_environ(new_environment, sizeof(new_environment));

        rename_process("STUBINIT");

        assert_se(sigemptyset(&waitmask) >= 0);
        assert_se(sigset_add_many(&waitmask,
                                  SIGCHLD,          /* posix: process died */
                                  SIGINT,           /* sysv: ctrl-alt-del */
                                  SIGRTMIN+3,       /* systemd: halt */
                                  SIGRTMIN+4,       /* systemd: poweroff */
                                  SIGRTMIN+5,       /* systemd: reboot */
                                  SIGRTMIN+6,       /* systemd: kexec */
                                  SIGRTMIN+13,      /* systemd: halt */
                                  SIGRTMIN+14,      /* systemd: poweroff */
                                  SIGRTMIN+15,      /* systemd: reboot */
                                  SIGRTMIN+16,      /* systemd: kexec */
                                  -1) >= 0);

        /* Note that we ignore SIGTERM (sysv's reexec), SIGHUP (reload), and all other signals here, since we don't
         * support reexec/reloading in this stub process. */

        for (;;) {
                siginfo_t si;
                usec_t current_usec;

                si.si_pid = 0;
                r = waitid(P_ALL, 0, &si, WEXITED|WNOHANG);
                if (r < 0) {
                        r = log_error_errno(errno, "Failed to reap children: %m");
                        goto finish;
                }

                current_usec = now(CLOCK_MONOTONIC);

                if (si.si_pid == pid || current_usec >= quit_usec) {

                        /* The child we started ourselves died or we reached a timeout. */

                        if (state == STATE_REBOOT) { /* dispatch a queued reboot */
                                (void) reboot(RB_AUTOBOOT);
                                r = log_error_errno(errno, "Failed to reboot: %m");
                                goto finish;

                        } else if (state == STATE_POWEROFF)
                                (void) reboot(RB_POWER_OFF); /* if this fails, fall back to normal exit. */

                        if (si.si_pid == pid && si.si_code == CLD_EXITED)
                                r = si.si_status; /* pass on exit code */
                        else
                                r = 255; /* signal, coredump, timeout, … */

                        goto finish;
                }
                if (si.si_pid != 0)
                        /* We reaped something. Retry until there's nothing more to reap. */
                        continue;

                if (quit_usec == USEC_INFINITY)
                        r = sigwaitinfo(&waitmask, &si);
                else {
                        struct timespec ts;
                        r = sigtimedwait(&waitmask, &si, timespec_store(&ts, quit_usec - current_usec));
                }
                if (r < 0) {
                        if (errno == EINTR) /* strace -p attach can result in EINTR, let's handle this nicely. */
                                continue;
                        if (errno == EAGAIN) /* timeout reached */
                                continue;

                        r = log_error_errno(errno, "Failed to wait for signal: %m");
                        goto finish;
                }

                if (si.si_signo == SIGCHLD)
                        continue; /* Let's reap this */

                if (state != STATE_RUNNING)
                        continue;

                /* Would love to use a switch() statement here, but SIGRTMIN is actually a function call, not a
                 * constant… */

                if (si.si_signo == SIGRTMIN+3 ||
                    si.si_signo == SIGRTMIN+4 ||
                    si.si_signo == SIGRTMIN+13 ||
                    si.si_signo == SIGRTMIN+14)

                        state = STATE_POWEROFF;

                else if (si.si_signo == SIGINT ||
                         si.si_signo == SIGRTMIN+5 ||
                         si.si_signo == SIGRTMIN+6 ||
                         si.si_signo == SIGRTMIN+15 ||
                         si.si_signo == SIGRTMIN+16)

                        state = STATE_REBOOT;
                else
                        assert_not_reached("Got unexpected signal");

                /* (void) kill_and_sigcont(pid, SIGTERM); */
                quit_usec = now(CLOCK_MONOTONIC) + DEFAULT_TIMEOUT_USEC;
        }

finish:
        _exit(r < 0 ? EXIT_FAILURE : r);
}
Exemplo n.º 16
0
static int lldp_send_packet(
                int ifindex,
                const struct ether_addr *address,
                const void *packet,
                size_t packet_size) {

        union sockaddr_union sa = {
                .ll.sll_family = AF_PACKET,
                .ll.sll_protocol = htobe16(ETHERTYPE_LLDP),
                .ll.sll_ifindex = ifindex,
                .ll.sll_halen = ETH_ALEN,
        };

        _cleanup_close_ int fd = -1;
        ssize_t l;

        assert(ifindex > 0);
        assert(address);
        assert(packet || packet_size <= 0);

        memcpy(sa.ll.sll_addr, address, ETH_ALEN);

        fd = socket(PF_PACKET, SOCK_RAW|SOCK_CLOEXEC, IPPROTO_RAW);
        if (fd < 0)
                return -errno;

        l = sendto(fd, packet, packet_size, MSG_NOSIGNAL, &sa.sa, sizeof(sa.ll));
        if (l < 0)
                return -errno;

        if ((size_t) l != packet_size)
                return -EIO;

        return 0;
}

static int link_send_lldp(Link *link) {
        char machine_id_string[SD_ID128_STRING_MAX];
        _cleanup_free_ char *hostname = NULL, *pretty_hostname = NULL;
        _cleanup_free_ void *packet = NULL;
        size_t packet_size = 0;
        sd_id128_t machine_id;
        uint16_t caps;
        usec_t ttl;
        int r;

        assert(link);

        if (!link->network || link->network->lldp_emit == LLDP_EMIT_NO)
                return 0;

        assert(link->network->lldp_emit < _LLDP_EMIT_MAX);

        r = sd_id128_get_machine(&machine_id);
        if (r < 0)
                return r;

        (void) gethostname_strict(&hostname);
        (void) parse_env_file("/etc/machine-info", NEWLINE, "PRETTY_HOSTNAME", &pretty_hostname, NULL);

        assert_cc(LLDP_TX_INTERVAL_USEC * LLDP_TX_HOLD + 1 <= (UINT16_MAX - 1) * USEC_PER_SEC);
        ttl = DIV_ROUND_UP(LLDP_TX_INTERVAL_USEC * LLDP_TX_HOLD + 1, USEC_PER_SEC);

        caps = (link->network && link->network->ip_forward != ADDRESS_FAMILY_NO) ?
                SD_LLDP_SYSTEM_CAPABILITIES_ROUTER :
                SD_LLDP_SYSTEM_CAPABILITIES_STATION;

        r = lldp_make_packet(link->network->lldp_emit,
                             &link->mac,
                             sd_id128_to_string(machine_id, machine_id_string),
                             link->ifname,
                             (uint16_t) ttl,
                             link->network ? link->network->description : NULL,
                             hostname,
                             pretty_hostname,
                             SD_LLDP_SYSTEM_CAPABILITIES_STATION|SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE|SD_LLDP_SYSTEM_CAPABILITIES_ROUTER,
                             caps,
                             &packet, &packet_size);
        if (r < 0)
                return r;

        return lldp_send_packet(link->ifindex, lldp_multicast_addr + link->network->lldp_emit, packet, packet_size);
}
Exemplo n.º 17
0
int main(int argc, char *argv[]) {
        sd_id128_t id, id2;
        char t[33], q[37];
        _cleanup_free_ char *b = NULL;
        _cleanup_close_ int fd = -1;

        assert_se(sd_id128_randomize(&id) == 0);
        printf("random: %s\n", sd_id128_to_string(id, t));

        assert_se(sd_id128_from_string(t, &id2) == 0);
        assert_se(sd_id128_equal(id, id2));

        if (sd_booted() > 0) {
                assert_se(sd_id128_get_machine(&id) == 0);
                printf("machine: %s\n", sd_id128_to_string(id, t));

                assert_se(sd_id128_get_boot(&id) == 0);
                printf("boot: %s\n", sd_id128_to_string(id, t));
        }

        printf("waldi: %s\n", sd_id128_to_string(ID128_WALDI, t));
        assert_se(streq(t, STR_WALDI));

        assert_se(asprintf(&b, SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(ID128_WALDI)) == 32);
        printf("waldi2: %s\n", b);
        assert_se(streq(t, b));

        printf("waldi3: %s\n", id128_to_uuid_string(ID128_WALDI, q));
        assert_se(streq(q, UUID_WALDI));

        b = mfree(b);
        assert_se(asprintf(&b, ID128_UUID_FORMAT_STR, SD_ID128_FORMAT_VAL(ID128_WALDI)) == 36);
        printf("waldi4: %s\n", b);
        assert_se(streq(q, b));

        assert_se(sd_id128_from_string(STR_WALDI, &id) >= 0);
        assert_se(sd_id128_equal(id, ID128_WALDI));

        assert_se(sd_id128_from_string(UUID_WALDI, &id) >= 0);
        assert_se(sd_id128_equal(id, ID128_WALDI));

        assert_se(sd_id128_from_string("", &id) < 0);
        assert_se(sd_id128_from_string("01020304-0506-0708-090a-0b0c0d0e0f101", &id) < 0);
        assert_se(sd_id128_from_string("01020304-0506-0708-090a-0b0c0d0e0f10-", &id) < 0);
        assert_se(sd_id128_from_string("01020304-0506-0708-090a0b0c0d0e0f10", &id) < 0);
        assert_se(sd_id128_from_string("010203040506-0708-090a-0b0c0d0e0f10", &id) < 0);

        assert_se(id128_is_valid(STR_WALDI));
        assert_se(id128_is_valid(UUID_WALDI));
        assert_se(!id128_is_valid(""));
        assert_se(!id128_is_valid("01020304-0506-0708-090a-0b0c0d0e0f101"));
        assert_se(!id128_is_valid("01020304-0506-0708-090a-0b0c0d0e0f10-"));
        assert_se(!id128_is_valid("01020304-0506-0708-090a0b0c0d0e0f10"));
        assert_se(!id128_is_valid("010203040506-0708-090a-0b0c0d0e0f10"));

        fd = open_tmpfile_unlinkable(NULL, O_RDWR|O_CLOEXEC);
        assert_se(fd >= 0);

        /* First, write as UUID */
        assert_se(sd_id128_randomize(&id) >= 0);
        assert_se(id128_write_fd(fd, ID128_UUID, id, false) >= 0);

        assert_se(lseek(fd, 0, SEEK_SET) == 0);
        assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) == -EINVAL);

        assert_se(lseek(fd, 0, SEEK_SET) == 0);
        assert_se(id128_read_fd(fd, ID128_UUID, &id2) >= 0);
        assert_se(sd_id128_equal(id, id2));

        assert_se(lseek(fd, 0, SEEK_SET) == 0);
        assert_se(id128_read_fd(fd, ID128_ANY, &id2) >= 0);
        assert_se(sd_id128_equal(id, id2));

        /* Second, write as plain */
        assert_se(lseek(fd, 0, SEEK_SET) == 0);
        assert_se(ftruncate(fd, 0) >= 0);

        assert_se(sd_id128_randomize(&id) >= 0);
        assert_se(id128_write_fd(fd, ID128_PLAIN, id, false) >= 0);

        assert_se(lseek(fd, 0, SEEK_SET) == 0);
        assert_se(id128_read_fd(fd, ID128_UUID, &id2) == -EINVAL);

        assert_se(lseek(fd, 0, SEEK_SET) == 0);
        assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) >= 0);
        assert_se(sd_id128_equal(id, id2));

        assert_se(lseek(fd, 0, SEEK_SET) == 0);
        assert_se(id128_read_fd(fd, ID128_ANY, &id2) >= 0);
        assert_se(sd_id128_equal(id, id2));

        /* Third, write plain without trailing newline */
        assert_se(lseek(fd, 0, SEEK_SET) == 0);
        assert_se(ftruncate(fd, 0) >= 0);

        assert_se(sd_id128_randomize(&id) >= 0);
        assert_se(write(fd, sd_id128_to_string(id, t), 32) == 32);

        assert_se(lseek(fd, 0, SEEK_SET) == 0);
        assert_se(id128_read_fd(fd, ID128_UUID, &id2) == -EINVAL);

        assert_se(lseek(fd, 0, SEEK_SET) == 0);
        assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) >= 0);
        assert_se(sd_id128_equal(id, id2));

        /* Third, write UUID without trailing newline */
        assert_se(lseek(fd, 0, SEEK_SET) == 0);
        assert_se(ftruncate(fd, 0) >= 0);

        assert_se(sd_id128_randomize(&id) >= 0);
        assert_se(write(fd, id128_to_uuid_string(id, q), 36) == 36);

        assert_se(lseek(fd, 0, SEEK_SET) == 0);
        assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) == -EINVAL);

        assert_se(lseek(fd, 0, SEEK_SET) == 0);
        assert_se(id128_read_fd(fd, ID128_UUID, &id2) >= 0);
        assert_se(sd_id128_equal(id, id2));

        return 0;
}
Exemplo n.º 18
0
static int show_status(char **args, unsigned n) {
        char buf[64];
        struct boot_info *info;
        int err;

        err = boot_info_new(&info);
        if (err < 0)
                return -ENOMEM;

        err = boot_info_query(info);

        printf("System:\n");
        printf("   Machine ID: %s\n", sd_id128_to_string(info->machine_id, buf));
        printf("      Boot ID: %s\n", sd_id128_to_string(info->boot_id, buf));
        if (info->fw_type)
                printf("     Firmware: %s (%s)\n", info->fw_type, strna(info->fw_info));
        if (info->fw_secure_boot >= 0)
                printf("  Secure Boot: %s\n", info->fw_secure_boot ? "enabled" : "disabled");
        if (info->fw_secure_boot_setup_mode >= 0)
                printf("   Setup Mode: %s\n", info->fw_secure_boot_setup_mode ? "setup" : "user");
        printf("\n");

        if (info->fw_entry_active >= 0) {
                printf("Selected Firmware Entry:\n");
                printf("        Title: %s\n", strna(info->fw_entries[info->fw_entry_active].title));
                if (!sd_id128_equal(info->fw_entries[info->fw_entry_active].part_uuid, SD_ID128_NULL))
                        printf("    Partition: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
                               SD_ID128_FORMAT_VAL(info->fw_entries[info->fw_entry_active].part_uuid));
                else
                        printf("    Partition: n/a\n");
                if (info->fw_entries[info->fw_entry_active].path)
                        printf("         File: %s%s\n", draw_special_char(DRAW_TREE_RIGHT), info->fw_entries[info->fw_entry_active].path);
        }
        printf("\n");

        if (info->loader) {
                printf("Boot Loader:\n");
                printf("      Product: %s\n", info->loader);
                if (!sd_id128_equal(info->loader_part_uuid, SD_ID128_NULL))
                        printf("    Partition: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
                               SD_ID128_FORMAT_VAL(info->loader_part_uuid));
                        else
                                printf("    Partition: n/a\n");
                printf("         File: %s%s\n", draw_special_char(DRAW_TREE_RIGHT), strna(info->loader_image_path));
                printf("\n");

                if (info->loader_entry_active >= 0) {
                        printf("Selected Boot Loader Entry:\n");
                        printf("        Title: %s\n", strna(info->loader_entries[info->loader_entry_active].title));
                        printf("         File: %s\n", info->loader_entries[info->loader_entry_active].path);
                        if (info->loader_options_added)
                                printf("      Options: %s\n", info->loader_options_added);
                }
        } else
                printf("No suitable data is provided by the boot manager. See:\n"
                       "  http://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface\n"
                       "  http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec\n"
                       "for details.\n");
        printf("\n");

        boot_info_free(info);
        return err;
}